summaryrefslogtreecommitdiff
path: root/support
diff options
context:
space:
mode:
authorStefan Fritsch <sf@sfritsch.de>2013-07-20 22:21:25 +0200
committerStefan Fritsch <sf@sfritsch.de>2013-07-20 22:21:25 +0200
commit4a336a5b117419c33c29eadd6409c69df78cd586 (patch)
treec9787e4bd0f1be8f471e1883262a695a6c4e954f /support
parent717c182588f1eb0b7ef189a709f858b44e348489 (diff)
downloadapache2-4a336a5b117419c33c29eadd6409c69df78cd586.tar.gz
Imported Upstream version 2.4.6upstream/2.4.6
Diffstat (limited to 'support')
-rw-r--r--support/htdbm.c1
-rw-r--r--support/htdigest.c16
-rw-r--r--support/htpasswd.c147
-rw-r--r--support/httxt2dbm.c31
-rw-r--r--support/passwd_common.c68
-rw-r--r--support/passwd_common.h15
-rw-r--r--support/rotatelogs.c39
-rw-r--r--support/suexec.c15
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