diff options
Diffstat (limited to 'support')
-rw-r--r-- | support/htdbm.c | 1 | ||||
-rw-r--r-- | support/htdigest.c | 16 | ||||
-rw-r--r-- | support/htpasswd.c | 147 | ||||
-rw-r--r-- | support/httxt2dbm.c | 31 | ||||
-rw-r--r-- | support/passwd_common.c | 68 | ||||
-rw-r--r-- | support/passwd_common.h | 15 | ||||
-rw-r--r-- | support/rotatelogs.c | 39 | ||||
-rw-r--r-- | support/suexec.c | 15 |
8 files changed, 231 insertions, 101 deletions
diff --git a/support/htdbm.c b/support/htdbm.c index a99a2322..1452d7a0 100644 --- a/support/htdbm.c +++ b/support/htdbm.c @@ -110,6 +110,7 @@ static apr_status_t htdbm_init(apr_pool_t **pool, htdbm_t **hdbm) #endif apr_pool_create( pool, NULL); + apr_pool_abort_set(abort_on_oom, *pool); apr_file_open_stderr(&errfile, *pool); apr_signal(SIGINT, (void (*)(int)) htdbm_interrupted); diff --git a/support/htdigest.c b/support/htdigest.c index 6a0e26f1..f76036d7 100644 --- a/support/htdigest.c +++ b/support/htdigest.c @@ -96,12 +96,15 @@ static int get_line(char *s, int n, apr_file_t *f) char ch; apr_status_t rv = APR_EINVAL; - while (i < (n - 1) && + /* we need 2 remaining bytes in buffer */ + while (i < (n - 2) && ((rv = apr_file_getc(&ch, f)) == APR_SUCCESS) && (ch != '\n')) { s[i++] = ch; } + /* First remaining byte potentially used here */ if (ch == '\n') s[i++] = ch; + /* Second remaining byte used here */ s[i] = '\0'; if (rv != APR_SUCCESS) @@ -202,8 +205,8 @@ int main(int argc, const char * const argv[]) #if APR_CHARSET_EBCDIC rv = apr_xlate_open(&to_ascii, "ISO-8859-1", APR_DEFAULT_CHARSET, cntxt); if (rv) { - apr_file_printf(errfile, "apr_xlate_open(): %s (%d)\n", - apr_strerror(rv, line, sizeof(line)), rv); + apr_file_printf(errfile, "apr_xlate_open(): %pm (%d)\n", + &rv, rv); exit(1); } #endif @@ -215,11 +218,8 @@ int main(int argc, const char * const argv[]) rv = apr_file_open(&f, argv[2], APR_WRITE | APR_CREATE, APR_OS_DEFAULT, cntxt); if (rv != APR_SUCCESS) { - char errmsg[120]; - - apr_file_printf(errfile, "Could not open passwd file %s for writing: %s\n", - argv[2], - apr_strerror(rv, errmsg, sizeof errmsg)); + apr_file_printf(errfile, "Could not open passwd file %s for writing: %pm\n", + argv[2], &rv); exit(1); } apr_cpystrn(user, argv[4], sizeof(user)); diff --git a/support/htpasswd.c b/support/htpasswd.c index 51219c0d..11023499 100644 --- a/support/htpasswd.c +++ b/support/htpasswd.c @@ -67,6 +67,7 @@ #define APHTP_NEWFILE 1 #define APHTP_NOFILE 2 #define APHTP_DELUSER 4 +#define APHTP_VERIFY 8 apr_file_t *ftemp = NULL; @@ -92,8 +93,8 @@ static int mkrecord(struct passwd_ctx *ctx, char *user) static void usage(void) { apr_file_printf(errfile, "Usage:" NL - "\thtpasswd [-cimBdpsD] [-C cost] passwordfile username" NL - "\thtpasswd -b[cmBdpsD] [-C cost] passwordfile username password" NL + "\thtpasswd [-cimBdpsDv] [-C cost] passwordfile username" NL + "\thtpasswd -b[cmBdpsDv] [-C cost] passwordfile username password" NL NL "\thtpasswd -n[imBdps] [-C cost] username" NL "\thtpasswd -nb[mBdps] [-C cost] username password" NL @@ -110,6 +111,7 @@ static void usage(void) " -s Force SHA encryption of the password (insecure)." NL " -p Do not encrypt the password (plaintext, insecure)." NL " -D Delete the specified user." NL + " -v Verify password for the specified user." NL "On other systems than Windows and NetWare the '-p' flag will " "probably not work." NL "The SHA algorithm does not use a salt and is less secure than the " @@ -155,7 +157,7 @@ static void terminate(void) } static void check_args(int argc, const char *const argv[], - struct passwd_ctx *ctx, int *mask, char **user, + struct passwd_ctx *ctx, unsigned *mask, char **user, char **pwfilename) { const char *arg; @@ -171,7 +173,7 @@ static void check_args(int argc, const char *const argv[], if (rv != APR_SUCCESS) exit(ERR_SYNTAX); - while ((rv = apr_getopt(state, "cnmspdBbDiC:", &opt, &opt_arg)) == APR_SUCCESS) { + while ((rv = apr_getopt(state, "cnmspdBbDiC:v", &opt, &opt_arg)) == APR_SUCCESS) { switch (opt) { case 'c': *mask |= APHTP_NEWFILE; @@ -183,6 +185,9 @@ static void check_args(int argc, const char *const argv[], case 'D': *mask |= APHTP_DELUSER; break; + case 'v': + *mask |= APHTP_VERIFY; + break; default: ret = parse_common_options(ctx, opt, opt_arg); if (ret) { @@ -196,18 +201,15 @@ static void check_args(int argc, const char *const argv[], if (rv != APR_EOF) usage(); - if ((*mask & APHTP_NEWFILE) && (*mask & APHTP_NOFILE)) { - apr_file_printf(errfile, "%s: -c and -n options conflict" NL, argv[0]); - exit(ERR_SYNTAX); - } - if ((*mask & APHTP_NEWFILE) && (*mask & APHTP_DELUSER)) { - apr_file_printf(errfile, "%s: -c and -D options conflict" NL, argv[0]); - exit(ERR_SYNTAX); - } - if ((*mask & APHTP_NOFILE) && (*mask & APHTP_DELUSER)) { - apr_file_printf(errfile, "%s: -n and -D options conflict" NL, argv[0]); + if ((*mask) & (*mask - 1)) { + /* not a power of two, i.e. more than one flag specified */ + apr_file_printf(errfile, "%s: only one of -c -n -v -D may be specified" NL, + argv[0]); exit(ERR_SYNTAX); } + if ((*mask & APHTP_VERIFY) && ctx->passwd_src == PW_PROMPT) + ctx->passwd_src = PW_PROMPT_VERIFY; + /* * Make sure we still have exactly the right number of arguments left * (the filename, the username, and possibly the password if -b was @@ -246,6 +248,25 @@ static void check_args(int argc, const char *const argv[], } } +static int verify(struct passwd_ctx *ctx, const char *hash) +{ + apr_status_t rv; + int ret; + + if (ctx->passwd == NULL && (ret = get_password(ctx)) != 0) + return ret; + rv = apr_password_validate(ctx->passwd, hash); + if (rv == APR_SUCCESS) + return 0; + if (APR_STATUS_IS_EMISMATCH(rv)) { + ctx->errstr = "password verification failed"; + return ERR_PWMISMATCH; + } + ctx->errstr = apr_psprintf(ctx->pool, "Could not verify password: %pm", + &rv); + return ERR_GENERAL; +} + /* * Let's do it. We end up doing a lot of file opening and closing, * but what do we care? This application isn't run constantly. @@ -253,7 +274,6 @@ static void check_args(int argc, const char *const argv[], int main(int argc, const char * const argv[]) { apr_file_t *fpw = NULL; - const char *errstr = NULL; char line[MAX_STRING_LEN]; char *pwfilename = NULL; char *user = NULL; @@ -262,7 +282,7 @@ int main(int argc, const char * const argv[]) char *scratch, cp[MAX_STRING_LEN]; int found = 0; int i; - int mask = 0; + unsigned mask = 0; apr_pool_t *pool; int existing_file = 0; struct passwd_ctx ctx = { 0 }; @@ -274,6 +294,7 @@ int main(int argc, const char * const argv[]) apr_app_initialize(&argc, &argv, NULL); atexit(terminate); apr_pool_create(&pool, NULL); + apr_pool_abort_set(abort_on_oom, pool); apr_file_open_stderr(&errfile, pool); ctx.pool = pool; ctx.alg = ALG_APMD5; @@ -341,10 +362,10 @@ int main(int argc, const char * const argv[]) * Any error message text is returned in the record buffer, since * the mkrecord() routine doesn't have access to argv[]. */ - if (!(mask & APHTP_DELUSER)) { + if ((mask & (APHTP_DELUSER|APHTP_VERIFY)) == 0) { i = mkrecord(&ctx, user); if (i != 0) { - apr_file_printf(errfile, "%s: %s" NL, argv[0], errstr); + apr_file_printf(errfile, "%s: %s" NL, argv[0], ctx.errstr); exit(i); } if (mask & APHTP_NOFILE) { @@ -353,21 +374,23 @@ int main(int argc, const char * const argv[]) } } - /* - * We can access the files the right way, and we have a record - * to add or update. Let's do it.. - */ - if (apr_temp_dir_get((const char**)&dirname, pool) != APR_SUCCESS) { - apr_file_printf(errfile, "%s: could not determine temp dir" NL, - argv[0]); - exit(ERR_FILEPERM); - } - dirname = apr_psprintf(pool, "%s/%s", dirname, tn); + if ((mask & APHTP_VERIFY) == 0) { + /* + * We can access the files the right way, and we have a record + * to add or update. Let's do it.. + */ + if (apr_temp_dir_get((const char**)&dirname, pool) != APR_SUCCESS) { + apr_file_printf(errfile, "%s: could not determine temp dir" NL, + argv[0]); + exit(ERR_FILEPERM); + } + dirname = apr_psprintf(pool, "%s/%s", dirname, tn); - if (apr_file_mktemp(&ftemp, dirname, 0, pool) != APR_SUCCESS) { - apr_file_printf(errfile, "%s: unable to create temporary file %s" NL, - argv[0], dirname); - exit(ERR_FILEPERM); + if (apr_file_mktemp(&ftemp, dirname, 0, pool) != APR_SUCCESS) { + apr_file_printf(errfile, "%s: unable to create temporary file %s" NL, + argv[0], dirname); + exit(ERR_FILEPERM); + } } /* @@ -418,33 +441,59 @@ int main(int argc, const char * const argv[]) continue; } else { - if (!(mask & APHTP_DELUSER)) { - /* We found the user we were looking for. - * Add him to the file. - */ - apr_file_printf(errfile, "Updating "); - putline(ftemp, ctx.out); - found++; + /* We found the user we were looking for */ + found++; + if ((mask & APHTP_DELUSER)) { + /* Delete entry from the file */ + apr_file_printf(errfile, "Deleting "); + } + else if ((mask & APHTP_VERIFY)) { + /* Verify */ + char *hash = colon + 1; + size_t len; + + len = strcspn(hash, "\r\n"); + if (len == 0) { + apr_file_printf(errfile, "Empty hash for user %s" NL, + user); + exit(ERR_INVALID); + } + hash[len] = '\0'; + + i = verify(&ctx, hash); + if (i != 0) { + apr_file_printf(errfile, "%s" NL, ctx.errstr); + exit(i); + } } else { - /* We found the user we were looking for. - * Delete them from the file. - */ - apr_file_printf(errfile, "Deleting "); - found++; + /* Update entry */ + apr_file_printf(errfile, "Updating "); + putline(ftemp, ctx.out); } } } apr_file_close(fpw); } - if (!found && !(mask & APHTP_DELUSER)) { - apr_file_printf(errfile, "Adding "); - putline(ftemp, ctx.out); + if (!found) { + if (mask & APHTP_DELUSER) { + apr_file_printf(errfile, "User %s not found" NL, user); + exit(0); + } + else if (mask & APHTP_VERIFY) { + apr_file_printf(errfile, "User %s not found" NL, user); + exit(ERR_BADUSER); + } + else { + apr_file_printf(errfile, "Adding "); + putline(ftemp, ctx.out); + } } - else if (!found && (mask & APHTP_DELUSER)) { - apr_file_printf(errfile, "User %s not found" NL, user); + if (mask & APHTP_VERIFY) { + apr_file_printf(errfile, "Password for user %s correct." NL, user); exit(0); } + apr_file_printf(errfile, "password for user %s" NL, user); /* The temporary file has all the data, just copy it to the new location. diff --git a/support/httxt2dbm.c b/support/httxt2dbm.c index 12606c3a..387418bb 100644 --- a/support/httxt2dbm.c +++ b/support/httxt2dbm.c @@ -39,7 +39,6 @@ static const char *output; static const char *format; static const char *shortname; static apr_file_t *errfile; -static char errbuf[120]; static int verbose; /* From mod_rewrite.c */ @@ -85,11 +84,11 @@ static void usage(void) "Usage: %s [-v] [-f format] -i SOURCE_TXT -o OUTPUT_DBM" NL NL "Options: " NL - " -v More verbose output"NL + " -v More verbose output" NL NL - " -i Source Text File. If '-', use stdin."NL + " -i Source Text File. If '-', use stdin." NL NL - " -o Output DBM."NL + " -o Output DBM." NL NL " -f DBM Format. If not specified, will use the APR Default." NL " GDBM for GDBM files (%s)" NL @@ -138,7 +137,7 @@ static apr_status_t to_dbm(apr_dbm_t *dbm, apr_file_t *fp, apr_pool_t *pool) dbmkey.dptr = apr_pstrmemdup(p, line, c - line); dbmkey.dsize = (c - line); - while (*c && apr_isspace(*c)) { + while (apr_isspace(*c)) { ++c; } @@ -157,7 +156,7 @@ static apr_status_t to_dbm(apr_dbm_t *dbm, apr_file_t *fp, apr_pool_t *pool) dbmval.dsize = (c - value); if (verbose) { - apr_file_printf(errfile, " '%s' -> '%s'"NL, + apr_file_printf(errfile, " '%s' -> '%s'" NL, dbmkey.dptr, dbmval.dptr); } @@ -204,7 +203,7 @@ int main(int argc, const char *const argv[]) rv = apr_getopt_init(&opt, pool, argc, argv); if (rv != APR_SUCCESS) { - apr_file_printf(errfile, "Error: apr_getopt_init failed."NL NL); + apr_file_printf(errfile, "Error: apr_getopt_init failed." NL NL); return 1; } @@ -273,7 +272,7 @@ int main(int argc, const char *const argv[]) } if (verbose) { - apr_file_printf(errfile, "DBM Format: %s"NL, format); + apr_file_printf(errfile, "DBM Format: %s" NL, format); } if (!strcmp(input, "-")) { @@ -286,13 +285,13 @@ int main(int argc, const char *const argv[]) if (rv != APR_SUCCESS) { apr_file_printf(errfile, - "Error: Cannot open input file '%s': (%d) %s" NL NL, - input, rv, apr_strerror(rv, errbuf, sizeof(errbuf))); + "Error: Cannot open input file '%s': (%d) %pm" NL NL, + input, rv, &rv); return 1; } if (verbose) { - apr_file_printf(errfile, "Input File: %s"NL, input); + apr_file_printf(errfile, "Input File: %s" NL, input); } rv = apr_dbm_open_ex(&outdbm, format, output, APR_DBM_RWCREATE, @@ -307,21 +306,21 @@ int main(int argc, const char *const argv[]) if (rv != APR_SUCCESS) { apr_file_printf(errfile, - "Error: Cannot open output DBM '%s': (%d) %s" NL NL, - output, rv, apr_strerror(rv, errbuf, sizeof(errbuf))); + "Error: Cannot open output DBM '%s': (%d) %pm" NL NL, + output, rv, &rv); return 1; } if (verbose) { - apr_file_printf(errfile, "DBM File: %s"NL, output); + apr_file_printf(errfile, "DBM File: %s" NL, output); } rv = to_dbm(outdbm, infile, pool); if (rv != APR_SUCCESS) { apr_file_printf(errfile, - "Error: Converting to DBM: (%d) %s" NL NL, - rv, apr_strerror(rv, errbuf, sizeof(errbuf))); + "Error: Converting to DBM: (%d) %pm" NL NL, + rv, &rv); return 1; } diff --git a/support/passwd_common.c b/support/passwd_common.c index ab720279..343fa790 100644 --- a/support/passwd_common.c +++ b/support/passwd_common.c @@ -24,8 +24,10 @@ #include "apr_md5.h" #include "apr_sha1.h" -#include <time.h> +#if APR_HAVE_TIME_H +#include <time.h> +#endif #if APR_HAVE_CRYPT_H #include <crypt.h> #endif @@ -38,14 +40,34 @@ #if APR_HAVE_UNISTD_H #include <unistd.h> #endif +#if APR_HAVE_IO_H +#include <io.h> +#endif -#ifdef WIN32 -#include <conio.h> -#define unlink _unlink +#ifdef _MSC_VER +#define write _write #endif apr_file_t *errfile; +int abort_on_oom(int rc) +{ + const char *buf = "Error: out of memory\n"; + int written, count = strlen(buf); + do { + written = write(STDERR_FILENO, buf, count); + if (written == count) + break; + if (written > 0) { + buf += written; + count -= written; + } + } while (written >= 0 || errno == EINTR); + abort(); + /* NOTREACHED */ + return 0; +} + static int generate_salt(char *s, size_t size, const char **errstr, apr_pool_t *pool) { @@ -85,6 +107,8 @@ static int generate_salt(char *s, size_t size, const char **errstr, void putline(apr_file_t *f, const char *l) { apr_status_t rv; + if (f == NULL) + return; rv = apr_file_puts(l, f); if (rv != APR_SUCCESS) { apr_file_printf(errfile, "Error writing temp file: %pm", &rv); @@ -95,17 +119,17 @@ void putline(apr_file_t *f, const char *l) int get_password(struct passwd_ctx *ctx) { + char buf[MAX_STRING_LEN + 1]; if (ctx->passwd_src == PW_STDIN) { - char *buf = ctx->out; apr_file_t *file_stdin; apr_size_t nread; if (apr_file_open_stdin(&file_stdin, ctx->pool) != APR_SUCCESS) { ctx->errstr = "Unable to read from stdin."; return ERR_GENERAL; } - if (apr_file_read_full(file_stdin, buf, ctx->out_len - 1, + if (apr_file_read_full(file_stdin, buf, sizeof(buf) - 1, &nread) != APR_EOF - || nread == ctx->out_len - 1) { + || nread == sizeof(buf) - 1) { goto err_too_long; } buf[nread] = '\0'; @@ -115,21 +139,30 @@ int get_password(struct passwd_ctx *ctx) buf[nread-2] = '\0'; } apr_file_close(file_stdin); + ctx->passwd = apr_pstrdup(ctx->pool, buf); + } + else if (ctx->passwd_src == PW_PROMPT_VERIFY) { + apr_size_t bufsize = sizeof(buf); + if (apr_password_get("Enter password: ", buf, &bufsize) != 0) + goto err_too_long; + ctx->passwd = apr_pstrdup(ctx->pool, buf); } else { - char buf[MAX_STRING_LEN + 1]; apr_size_t bufsize = sizeof(buf); - if (apr_password_get("New password: ", ctx->out, &ctx->out_len) != 0) + if (apr_password_get("New password: ", buf, &bufsize) != 0) goto err_too_long; + ctx->passwd = apr_pstrdup(ctx->pool, buf); + bufsize = sizeof(buf); + buf[0] = '\0'; apr_password_get("Re-type new password: ", buf, &bufsize); - if (strcmp(ctx->out, buf) != 0) { + if (strcmp(ctx->passwd, buf) != 0) { ctx->errstr = "password verification error"; - memset(ctx->out, '\0', ctx->out_len); + memset(ctx->passwd, '\0', strlen(ctx->passwd)); memset(buf, '\0', sizeof(buf)); return ERR_PWMISMATCH; } - memset(buf, '\0', sizeof(buf)); } + memset(buf, '\0', sizeof(buf)); return 0; err_too_long: @@ -146,7 +179,6 @@ err_too_long: int mkhash(struct passwd_ctx *ctx) { char *pw; - char pwin[MAX_STRING_LEN]; char salt[16]; apr_status_t rv; int ret = 0; @@ -159,14 +191,11 @@ int mkhash(struct passwd_ctx *ctx) "Warning: Ignoring -C argument for this algorithm." NL); } - if (ctx->passwd != NULL) { - pw = ctx->passwd; - } - else { + if (ctx->passwd == NULL) { if ((ret = get_password(ctx)) != 0) return ret; - pw = pwin; } + pw = ctx->passwd; switch (ctx->alg) { case ALG_APSHA: @@ -206,14 +235,13 @@ int mkhash(struct passwd_ctx *ctx) apr_cpystrn(ctx->out, cbuf, ctx->out_len - 1); if (strlen(pw) > 8) { - char *truncpw = strdup(pw); + char *truncpw = apr_pstrdup(ctx->pool, pw); truncpw[8] = '\0'; if (!strcmp(ctx->out, crypt(truncpw, salt))) { apr_file_printf(errfile, "Warning: Password truncated to 8 " "characters by CRYPT algorithm." NL); } memset(truncpw, '\0', strlen(pw)); - free(truncpw); } break; #endif /* CRYPT_ALGO_SUPPORTED */ diff --git a/support/passwd_common.h b/support/passwd_common.h index 67b66da1..01d56520 100644 --- a/support/passwd_common.h +++ b/support/passwd_common.h @@ -14,6 +14,9 @@ * limitations under the License. */ +#ifndef _PASSWD_COMMON_H +#define _PASSWD_COMMON_H + #include "apr.h" #include "apr_lib.h" #include "apr_strings.h" @@ -80,10 +83,17 @@ struct passwd_ctx { enum { PW_PROMPT = 0, PW_ARG, - PW_STDIN + PW_STDIN, + PW_PROMPT_VERIFY, } passwd_src; }; + +/* + * To be used as apr_pool_abort_fn + */ +int abort_on_oom(int rc); + /* * Write a line to the file. On error, print a message and exit */ @@ -108,3 +118,6 @@ int get_password(struct passwd_ctx *ctx); * Make a password record from the given information. */ int mkhash(struct passwd_ctx *ctx); + +#endif /* _PASSWD_COMMON_H */ + diff --git a/support/rotatelogs.c b/support/rotatelogs.c index 9bc33285..3f32f3ca 100644 --- a/support/rotatelogs.c +++ b/support/rotatelogs.c @@ -99,6 +99,7 @@ struct rotate_config { #if APR_FILES_AS_SOCKETS int create_empty; #endif + int num_files; }; typedef struct rotate_status rotate_status_t; @@ -118,6 +119,7 @@ struct rotate_status { int rotateReason; int tLogEnd; int nMessCount; + int fileNum; }; static rotate_config_t config; @@ -130,9 +132,9 @@ static void usage(const char *argv0, const char *reason) } fprintf(stderr, #if APR_FILES_AS_SOCKETS - "Usage: %s [-v] [-l] [-L linkname] [-p prog] [-f] [-t] [-e] [-c] <logfile> " + "Usage: %s [-v] [-l] [-L linkname] [-p prog] [-f] [-t] [-e] [-c] [-n number] <logfile> " #else - "Usage: %s [-v] [-l] [-L linkname] [-p prog] [-f] [-t] [-e] <logfile> " + "Usage: %s [-v] [-l] [-L linkname] [-p prog] [-f] [-t] [-e] [-n number] <logfile> " #endif "{<rotation time in seconds>|<rotation size>(B|K|M|G)} " "[offset minutes from UTC]\n\n", @@ -374,6 +376,7 @@ static void doRotate(rotate_config_t *config, rotate_status_t *status) int tLogStart; apr_status_t rv; struct logfile newlog; + int thisLogNum = -1; status->rotateReason = ROTATE_NONE; @@ -407,6 +410,16 @@ static void doRotate(rotate_config_t *config, rotate_status_t *status) if (config->truncate) { apr_snprintf(newlog.name, sizeof(newlog.name), "%s", config->szLogRoot); } + else if (config->num_files > 0) { + if (status->fileNum == -1 || status->fileNum == (config->num_files - 1)) { + thisLogNum = 0; + apr_snprintf(newlog.name, sizeof(newlog.name), "%s", config->szLogRoot); + } + else { + thisLogNum = status->fileNum + 1; + apr_snprintf(newlog.name, sizeof(newlog.name), "%s.%d", config->szLogRoot, thisLogNum); + } + } else { apr_snprintf(newlog.name, sizeof(newlog.name), "%s.%010d", config->szLogRoot, tLogStart); @@ -417,11 +430,13 @@ static void doRotate(rotate_config_t *config, rotate_status_t *status) fprintf(stderr, "Opening file %s\n", newlog.name); } rv = apr_file_open(&newlog.fd, newlog.name, APR_WRITE | APR_CREATE | APR_APPEND - | (config->truncate ? APR_TRUNCATE : 0), APR_OS_DEFAULT, newlog.pool); + | (config->truncate || (config->num_files > 0 && status->current.fd) ? APR_TRUNCATE : 0), + APR_OS_DEFAULT, newlog.pool); if (rv == APR_SUCCESS) { /* Handle post-rotate processing. */ post_rotate(newlog.pool, &newlog, config, status); + status->fileNum = thisLogNum; /* Close out old (previously 'current') logfile, if any. */ if (status->current.fd) { close_logfile(config, &status->current); @@ -550,9 +565,9 @@ int main (int argc, const char * const argv[]) apr_pool_create(&status.pool, NULL); apr_getopt_init(&opt, status.pool, argc, argv); #if APR_FILES_AS_SOCKETS - while ((rv = apr_getopt(opt, "lL:p:ftvec", &c, &opt_arg)) == APR_SUCCESS) { + while ((rv = apr_getopt(opt, "lL:p:ftvecn:", &c, &opt_arg)) == APR_SUCCESS) { #else - while ((rv = apr_getopt(opt, "lL:p:ftve", &c, &opt_arg)) == APR_SUCCESS) { + while ((rv = apr_getopt(opt, "lL:p:ftven:", &c, &opt_arg)) == APR_SUCCESS) { #endif switch (c) { case 'l': @@ -581,6 +596,10 @@ int main (int argc, const char * const argv[]) config.create_empty = 1; break; #endif + case 'n': + config.num_files = atoi(opt_arg); + status.fileNum = -1; + break; } } @@ -609,6 +628,16 @@ int main (int argc, const char * const argv[]) config.use_strftime = (strchr(config.szLogRoot, '%') != NULL); + if (config.use_strftime && config.num_files > 0) { + fprintf(stderr, "Cannot use -n with %% in filename\n"); + exit(1); + } + + if (status.fileNum == -1 && config.num_files < 1) { + fprintf(stderr, "Invalid -n argument\n"); + exit(1); + } + if (apr_file_open_stdin(&f_stdin, status.pool) != APR_SUCCESS) { fprintf(stderr, "Unable to open stdin\n"); exit(1); diff --git a/support/suexec.c b/support/suexec.c index 2c4e2c3b..28171253 100644 --- a/support/suexec.c +++ b/support/suexec.c @@ -217,11 +217,15 @@ static void clean_env(void) if ((cleanenv = (char **) calloc(AP_ENVBUF, sizeof(char *))) == NULL) { log_err("failed to malloc memory for environment\n"); - exit(120); + exit(123); } sprintf(pathbuf, "PATH=%s", AP_SAFE_PATH); cleanenv[cidx] = strdup(pathbuf); + if (cleanenv[cidx] == NULL) { + log_err("failed to malloc memory for environment\n"); + exit(124); + } cidx++; for (ep = envp; *ep && cidx < AP_ENVBUF-1; ep++) { @@ -396,7 +400,10 @@ int main(int argc, char *argv[]) } } gid = gr->gr_gid; - actual_gname = strdup(gr->gr_name); + if ((actual_gname = strdup(gr->gr_name)) == NULL) { + log_err("failed to alloc memory\n"); + exit(125); + } #ifdef _OSD_POSIX /* @@ -431,6 +438,10 @@ int main(int argc, char *argv[]) uid = pw->pw_uid; actual_uname = strdup(pw->pw_name); target_homedir = strdup(pw->pw_dir); + if (actual_uname == NULL || target_homedir == NULL) { + log_err("failed to alloc memory\n"); + exit(126); + } /* * Log the transaction here to be sure we have an open log |