diff options
author | rbb <rbb@13f79535-47bb-0310-9956-ffa450edef68> | 2000-04-22 05:14:02 +0000 |
---|---|---|
committer | rbb <rbb@13f79535-47bb-0310-9956-ffa450edef68> | 2000-04-22 05:14:02 +0000 |
commit | a87661e1c15d5758620a152d09d01074196562b8 (patch) | |
tree | 28378ce6fe6d3671af63d9599a6942e87cd8ba6f /test | |
parent | c2365ea6569e27fb3c4e6dbb8cf0379147b5e92a (diff) | |
download | libapr-a87661e1c15d5758620a152d09d01074196562b8.tar.gz |
Remove all the test programs that were never ported. These are still in
Apache's src/support, and should be ported there. Also removed the deps
from the Makefile.
git-svn-id: http://svn.apache.org/repos/asf/apr/apr/trunk@59922 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'test')
-rw-r--r-- | test/Makefile.in | 126 | ||||
-rw-r--r-- | test/htpasswd.c | 535 | ||||
-rw-r--r-- | test/logresolve.c | 345 | ||||
-rw-r--r-- | test/rotatelogs.c | 136 | ||||
-rw-r--r-- | test/suexec.c | 560 |
5 files changed, 62 insertions, 1640 deletions
diff --git a/test/Makefile.in b/test/Makefile.in index 54e4a0489..a9c57f1ed 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -118,68 +118,66 @@ depend: && rm Makefile.new # DO NOT REMOVE -ab_apr.o: ab_apr.c ../include/apr_network_io.h \ - ../include/apr_general.h ../include/apr.h ../include/apr_errno.h \ - ../include/apr_file_io.h ../include/apr_time.h \ - ../include/apr_getopt.h -abc.o: abc.c ../include/apr_file_io.h ../include/apr_general.h \ - ../include/apr.h ../include/apr_errno.h ../include/apr_time.h -client.o: client.c ../include/apr_network_io.h \ - ../include/apr_general.h ../include/apr.h ../include/apr_errno.h \ - ../include/apr_file_io.h ../include/apr_time.h /usr/include/errno.h -htdigest.o: htdigest.c ../include/apr_lib.h ../include/apr_general.h \ - ../include/apr.h ../include/apr_errno.h ../include/apr_file_io.h \ - ../include/apr_time.h ../include/apr_thread_proc.h \ - ../include/apr_md5.h -htpasswd.o: htpasswd.c ../include/apr_signal.h \ - ../include/apr_general.h ../include/apr.h ../include/apr_errno.h \ - ../include/apr_lib.h ../include/apr_file_io.h ../include/apr_time.h \ - ../include/apr_thread_proc.h -logresolve.o: logresolve.c ../include/apr_config.h +ab_apr.o: ab_apr.c $(INCDIR)/apr_network_io.h \ + $(INCDIR)/apr_general.h $(INCDIR)/apr.h $(INCDIR)/apr_errno.h \ + $(INCDIR)/apr_file_io.h $(INCDIR)/apr_time.h \ + $(INCDIR)/apr_getopt.h +abc.o: abc.c $(INCDIR)/apr_file_io.h $(INCDIR)/apr_general.h \ + $(INCDIR)/apr.h $(INCDIR)/apr_errno.h $(INCDIR)/apr_time.h +client.o: client.c $(INCDIR)/apr_network_io.h \ + $(INCDIR)/apr_general.h $(INCDIR)/apr.h $(INCDIR)/apr_errno.h \ + $(INCDIR)/apr_file_io.h $(INCDIR)/apr_time.h $(OSDIR)/usr/include/errno.h +htdigest.o: htdigest.c $(INCDIR)/apr_lib.h $(INCDIR)/apr_general.h \ + $(INCDIR)/apr.h $(INCDIR)/apr_errno.h $(INCDIR)/apr_file_io.h \ + $(INCDIR)/apr_time.h $(INCDIR)/apr_thread_proc.h \ + $(INCDIR)/apr_md5.h $(INCDIR)/apr_config.h mod_test.o: mod_test.c -rotatelogs.o: rotatelogs.c ../include/apr_config.h -server.o: server.c ../include/apr_network_io.h \ - ../include/apr_general.h ../include/apr.h ../include/apr_errno.h \ - ../include/apr_file_io.h ../include/apr_time.h -testargs.o: testargs.c ../include/apr_file_io.h \ - ../include/apr_general.h ../include/apr.h ../include/apr_errno.h \ - ../include/apr_time.h ../include/apr_lib.h \ - ../include/apr_thread_proc.h ../include/apr_getopt.h -testcontext.o: testcontext.c ../include/apr_file_io.h \ - ../include/apr_general.h ../include/apr.h ../include/apr_errno.h \ - ../include/apr_time.h ../include/apr_lib.h \ - ../include/apr_thread_proc.h -testdso.o: testdso.c ../include/apr_config.h ../include/apr_general.h \ - ../include/apr.h ../include/apr_errno.h ../include/apr_pools.h \ - ../include/apr_lib.h ../include/apr_file_io.h ../include/apr_time.h \ - ../include/apr_thread_proc.h ../include/apr_dso.h -testfile.o: testfile.c ../include/apr_file_io.h \ - ../include/apr_general.h ../include/apr.h ../include/apr_errno.h \ - ../include/apr_time.h ../include/apr_lib.h \ - ../include/apr_thread_proc.h -testmmap.o: testmmap.c ../include/apr_mmap.h ../include/apr_general.h \ - ../include/apr.h ../include/apr_errno.h ../include/apr_network_io.h \ - ../include/apr_file_io.h ../include/apr_time.h \ - ../include/apr_portable.h ../include/apr_thread_proc.h \ - ../include/apr_lock.h ../include/apr_lib.h -testpipe.o: testpipe.c ../include/apr_file_io.h \ - ../include/apr_general.h ../include/apr.h ../include/apr_errno.h \ - ../include/apr_time.h ../include/apr_lib.h \ - ../include/apr_thread_proc.h -testproc.o: testproc.c ../include/apr_thread_proc.h \ - ../include/apr_file_io.h ../include/apr_general.h ../include/apr.h \ - ../include/apr_errno.h ../include/apr_time.h ../include/apr_lib.h \ - /usr/include/errno.h -testshmem.o: testshmem.c ../include/apr_shmem.h ../include/apr.h \ - ../include/apr_general.h ../include/apr_errno.h ../include/apr_lock.h \ - ../include/apr_lib.h ../include/apr_file_io.h ../include/apr_time.h \ - ../include/apr_thread_proc.h /usr/include/errno.h -testsock.o: testsock.c ../include/apr_thread_proc.h \ - ../include/apr_file_io.h ../include/apr_general.h ../include/apr.h \ - ../include/apr_errno.h ../include/apr_time.h ../include/apr_lib.h -testthread.o: testthread.c ../include/apr_thread_proc.h \ - ../include/apr_file_io.h ../include/apr_general.h ../include/apr.h \ - ../include/apr_errno.h ../include/apr_time.h ../include/apr_lock.h \ - /usr/include/errno.h -testtime.o: testtime.c ../include/apr_time.h ../include/apr_general.h \ - ../include/apr.h ../include/apr_errno.h /usr/include/errno.h +server.o: server.c $(INCDIR)/apr_network_io.h \ + $(INCDIR)/apr_general.h $(INCDIR)/apr.h $(INCDIR)/apr_errno.h \ + $(INCDIR)/apr_file_io.h $(INCDIR)/apr_time.h +testargs.o: testargs.c $(INCDIR)/apr_file_io.h \ + $(INCDIR)/apr_general.h $(INCDIR)/apr.h $(INCDIR)/apr_errno.h \ + $(INCDIR)/apr_time.h $(INCDIR)/apr_lib.h \ + $(INCDIR)/apr_thread_proc.h $(INCDIR)/apr_getopt.h +testcontext.o: testcontext.c $(INCDIR)/apr_file_io.h \ + $(INCDIR)/apr_general.h $(INCDIR)/apr.h $(INCDIR)/apr_errno.h \ + $(INCDIR)/apr_time.h $(INCDIR)/apr_lib.h \ + $(INCDIR)/apr_thread_proc.h +testdso.o: testdso.c $(INCDIR)/apr_general.h $(INCDIR)/apr.h \ + $(INCDIR)/apr_errno.h $(INCDIR)/apr_pools.h $(INCDIR)/apr_lib.h \ + $(INCDIR)/apr_file_io.h $(INCDIR)/apr_time.h \ + $(INCDIR)/apr_thread_proc.h $(INCDIR)/apr_dso.h +testfile.o: testfile.c $(INCDIR)/apr_file_io.h \ + $(INCDIR)/apr_general.h $(INCDIR)/apr.h $(INCDIR)/apr_errno.h \ + $(INCDIR)/apr_time.h $(INCDIR)/apr_lib.h \ + $(INCDIR)/apr_thread_proc.h +testmmap.o: testmmap.c $(INCDIR)/apr_mmap.h $(INCDIR)/apr_general.h \ + $(INCDIR)/apr.h $(INCDIR)/apr_errno.h $(INCDIR)/apr_network_io.h \ + $(INCDIR)/apr_file_io.h $(INCDIR)/apr_time.h \ + $(INCDIR)/apr_portable.h $(INCDIR)/apr_thread_proc.h \ + $(INCDIR)/apr_lock.h $(INCDIR)/apr_lib.h +testoc.o: testoc.c $(INCDIR)/apr_thread_proc.h \ + $(INCDIR)/apr_file_io.h $(INCDIR)/apr_general.h $(INCDIR)/apr.h \ + $(INCDIR)/apr_errno.h $(INCDIR)/apr_time.h $(INCDIR)/apr_lib.h \ + $(OSDIR)/usr/include/errno.h +testpipe.o: testpipe.c $(INCDIR)/apr_file_io.h \ + $(INCDIR)/apr_general.h $(INCDIR)/apr.h $(INCDIR)/apr_errno.h \ + $(INCDIR)/apr_time.h $(INCDIR)/apr_lib.h \ + $(INCDIR)/apr_thread_proc.h +testproc.o: testproc.c $(INCDIR)/apr_thread_proc.h \ + $(INCDIR)/apr_file_io.h $(INCDIR)/apr_general.h $(INCDIR)/apr.h \ + $(INCDIR)/apr_errno.h $(INCDIR)/apr_time.h $(INCDIR)/apr_lib.h \ + $(OSDIR)/usr/include/errno.h +testshmem.o: testshmem.c $(INCDIR)/apr_shmem.h $(INCDIR)/apr.h \ + $(INCDIR)/apr_general.h $(INCDIR)/apr_errno.h $(INCDIR)/apr_lock.h \ + $(INCDIR)/apr_lib.h $(INCDIR)/apr_file_io.h $(INCDIR)/apr_time.h \ + $(INCDIR)/apr_thread_proc.h $(OSDIR)/usr/include/errno.h +testsock.o: testsock.c $(INCDIR)/apr_thread_proc.h \ + $(INCDIR)/apr_file_io.h $(INCDIR)/apr_general.h $(INCDIR)/apr.h \ + $(INCDIR)/apr_errno.h $(INCDIR)/apr_time.h $(INCDIR)/apr_lib.h +testthread.o: testthread.c $(INCDIR)/apr_thread_proc.h \ + $(INCDIR)/apr_file_io.h $(INCDIR)/apr_general.h $(INCDIR)/apr.h \ + $(INCDIR)/apr_errno.h $(INCDIR)/apr_time.h $(INCDIR)/apr_lock.h \ + $(OSDIR)/usr/include/errno.h +testtime.o: testtime.c $(INCDIR)/apr_time.h $(INCDIR)/apr_general.h \ + $(INCDIR)/apr.h $(INCDIR)/apr_errno.h $(OSDIR)/usr/include/errno.h diff --git a/test/htpasswd.c b/test/htpasswd.c deleted file mode 100644 index 7dd9025ea..000000000 --- a/test/htpasswd.c +++ /dev/null @@ -1,535 +0,0 @@ -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2000 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" must - * not be used to endorse or promote products derived from this - * software without prior written permission. For written - * permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * nor may "Apache" appear in their name, without prior written - * permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * <http://www.apache.org/>. - */ - -/****************************************************************************** - ****************************************************************************** - * NOTE! This program is not safe as a setuid executable! Do not make it - * setuid! - ****************************************************************************** - *****************************************************************************/ -/* - * htpasswd.c: simple program for manipulating password file for - * the Apache HTTP server - * - * Originally by Rob McCool - * - * Exit values: - * 0: Success - * 1: Failure; file access/permission problem - * 2: Failure; command line syntax problem (usage message issued) - * 3: Failure; password verification failure - * 4: Failure; operation interrupted (such as with CTRL/C) - * 5: Failure; buffer would overflow (username, filename, or computed - * record too long) - * 6: Failure; username contains illegal or reserved characters - */ - -#include "apr_signal.h" -#include "apr_errno.h" -#include "apr_lib.h" -#include <sys/types.h> -#include <errno.h> - -#ifdef WIN32 -#include <conio.h> -#include "../os/win32/getopt.h" -#define unlink _unlink -#endif - -#ifndef CHARSET_EBCDIC -#define LF 10 -#define CR 13 -#else /*CHARSET_EBCDIC*/ -#define LF '\n' -#define CR '\r' -#endif /*CHARSET_EBCDIC*/ - -#define MAX_STRING_LEN 256 -#define ALG_CRYPT 1 -#define ALG_APMD5 2 - -#define ERR_FILEPERM 1 -#define ERR_SYNTAX 2 -#define ERR_PWMISMATCH 3 -#define ERR_INTERRUPTED 4 -#define ERR_OVERFLOW 5 -#define ERR_BADUSER 6 - -/* - * This needs to be declared statically so the signal handler can - * access it. - */ -static char *tempfilename; - -/* - * Get a line of input from the user, not including any terminating - * newline. - */ -static int getline(char *s, int n, FILE *f) -{ - register int i = 0; - - while (1) { - s[i] = (char) fgetc(f); - - if (s[i] == CR) { - s[i] = fgetc(f); - } - - if ((s[i] == 0x4) || (s[i] == LF) || (i == (n - 1))) { - s[i] = '\0'; - return (feof(f) ? 1 : 0); - } - ++i; - } -} - -static void putline(FILE *f, char *l) -{ - int x; - - for (x = 0; l[x]; x++) { - fputc(l[x], f); - } - fputc('\n', f); -} - - -/* From local_passwd.c (C) Regents of Univ. of California blah blah */ -static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */ - "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; - -static void to64(register char *s, register long v, register int n) -{ - while (--n >= 0) { - *s++ = itoa64[v & 0x3f]; - v >>= 6; - } -} - -/* - * Make a password record from the given information. A zero return - * indicates success; failure means that the output buffer contains an - * error message instead. - */ -static int mkrecord(char *user, char *record, size_t rlen, char *passwd, - int alg) -{ - char *pw; - char cpw[120]; - char salt[9]; - char pwin[MAX_STRING_LEN]; - char pwv[MAX_STRING_LEN]; - - if (passwd != NULL) { - pw = passwd; - } - else { - if (ap_getpass("New password: ", pwin, sizeof(pwin)) != 0) { - ap_snprintf(record, (rlen - 1), "password too long (>%d)", - sizeof(pwin) - 1); - return ERR_OVERFLOW; - } - ap_getpass("Re-type new password: ", pwv, sizeof(pwv)); - if (strcmp(pwin, pwv) != 0) { - ap_cpystrn(record, "password verification error", (rlen - 1)); - return ERR_PWMISMATCH; - } - pw = pwin; - } - (void) srand((int) time((time_t *) NULL)); - to64(&salt[0], rand(), 8); - salt[8] = '\0'; - - switch (alg) { - case ALG_APMD5: - ap_MD5Encode((const unsigned char *)pw, (const unsigned char *)salt, - cpw, sizeof(cpw)); - break; - case ALG_CRYPT: - ap_cpystrn(cpw, (char *)crypt(pw, salt), sizeof(cpw) - 1); - break; - } - - /* - * Check to see if the buffer is large enough to hold the username, - * hash, and delimiters. - */ - if ((strlen(user) + 1 + strlen(cpw)) > (rlen - 1)) { - ap_cpystrn(record, "resultant record too long", (rlen - 1)); - return ERR_OVERFLOW; - } - strcpy(record, user); - strcat(record, ":"); - strcat(record, cpw); - return 0; -} - -static int usage(void) -{ - fprintf(stderr, "Usage:\n"); - fprintf(stderr, "\thtpasswd [-cm] passwordfile username\n"); - fprintf(stderr, "\thtpasswd -b[cm] passwordfile username password\n\n"); - fprintf(stderr, " -c Create a new file.\n"); - fprintf(stderr, " -m Force MD5 encryption of the password.\n"); - fprintf(stderr, " -b Use the password from the command line rather "); - fprintf(stderr, "than prompting for it.\n"); - fprintf(stderr, "On Windows systems the -m flag is used by default.\n"); - return ERR_SYNTAX; -} - -static void interrupted(void) -{ - fprintf(stderr, "Interrupted.\n"); - if (tempfilename != NULL) { - unlink(tempfilename); - } - exit(ERR_INTERRUPTED); -} - -/* - * Check to see if the specified file can be opened for the given - * access. - */ -static int accessible(char *fname, char *mode) -{ - FILE *s; - - s = fopen(fname, mode); - if (s == NULL) { - return 0; - } - fclose(s); - return 1; -} - -/* - * Return true if a file is readable. - */ -static int readable(char *fname) -{ - return accessible(fname, "r"); -} - -/* - * Return true if the specified file can be opened for write access. - */ -static int writable(char *fname) -{ - return accessible(fname, "a"); -} - -/* - * Return true if the named file exists, regardless of permissions. - */ -static int exists(char *fname) -{ -#ifdef WIN32 - struct _stat sbuf; -#else - struct stat sbuf; -#endif - int check; - -#ifdef WIN32 - check = _stat(fname, &sbuf); -#else - check = stat(fname, &sbuf); -#endif - return ((check == -1) && (errno == ENOENT)) ? 0 : 1; -} - -/* - * Copy from the current position of one file to the current position - * of another. - */ -static void copy_file(FILE *target, FILE *source) -{ - static char line[MAX_STRING_LEN]; - - while (fgets(line, sizeof(line), source) != NULL) { - fputs(line, target); - } -} - -/* - * 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. - */ -int main(int argc, char *argv[]) -{ - FILE *ftemp = NULL; - FILE *fpw = NULL; - char user[MAX_STRING_LEN]; - char password[MAX_STRING_LEN]; - char record[MAX_STRING_LEN]; - char line[MAX_STRING_LEN]; - char pwfilename[MAX_STRING_LEN]; - char *arg; - int found = 0; - int alg = ALG_CRYPT; - int newfile = 0; - int noninteractive = 0; - int i; - int args_left = 2; - - tempfilename = NULL; - ap_signal(SIGINT, (void (*)(int)) interrupted); - - /* - * Preliminary check to make sure they provided at least - * three arguments, we'll do better argument checking as - * we parse the command line. - */ - if (argc < 3) { - return usage(); - } - - /* - * Go through the argument list and pick out any options. They - * have to precede any other arguments. - */ - for (i = 1; i < argc; i++) { - arg = argv[i]; - if (*arg != '-') { - break; - } - while (*++arg != '\0') { - if (*arg == 'c') { - newfile++; - } - else if (*arg == 'm') { - alg = ALG_APMD5; - } - else if (*arg == 'b') { - noninteractive++; - args_left++; - } - else { - return usage(); - } - } - } - - /* - * Make sure we still have exactly the right number of arguments left - * (the filename, the username, and possibly the password if -b was - * specified). - */ - if ((argc - i) != args_left) { - return usage(); - } - if (strlen(argv[i]) > (sizeof(pwfilename) - 1)) { - fprintf(stderr, "%s: filename too long\n", argv[0]); - return ERR_OVERFLOW; - } - strcpy(pwfilename, argv[i]); - if (strlen(argv[i + 1]) > (sizeof(user) - 1)) { - fprintf(stderr, "%s: username too long (>%d)\n", argv[0], - sizeof(user) - 1); - return ERR_OVERFLOW; - } - strcpy(user, argv[i + 1]); - if ((arg = strchr(user, ':')) != NULL) { - fprintf(stderr, "%s: username contains illegal character '%c'\n", - argv[0], *arg); - return ERR_BADUSER; - } - if (noninteractive) { - if (strlen(argv[i + 2]) > (sizeof(password) - 1)) { - fprintf(stderr, "%s: password too long (>%d)\n", argv[0], - sizeof(password) - 1); - return ERR_OVERFLOW; - } - strcpy(password, argv[i + 2]); - } - -#ifdef WIN32 - if (alg == ALG_CRYPT) { - alg = ALG_APMD5; - fprintf(stderr, "Automatically using MD5 format on Windows.\n"); - } -#endif - - /* - * Verify that the file exists if -c was omitted. We give a special - * message if it doesn't. - */ - if ((! newfile) && (! exists(pwfilename))) { - fprintf(stderr, "%s: cannot modify file %s; use '-c' to create it\n", - argv[0], pwfilename); - perror("fopen"); - exit(ERR_FILEPERM); - } - /* - * Verify that we can read the existing file in the case of an update - * to it (rather than creation of a new one). - */ - if ((! newfile) && (! readable(pwfilename))) { - fprintf(stderr, "%s: cannot open file %s for read access\n", - argv[0], pwfilename); - perror("fopen"); - exit(ERR_FILEPERM); - } - /* - * Now check to see if we can preserve an existing file in case - * of password verification errors on a -c operation. - */ - if (newfile && exists(pwfilename) && (! readable(pwfilename))) { - fprintf(stderr, "%s: cannot open file %s for read access\n" - "%s: existing auth data would be lost on password mismatch", - argv[0], pwfilename, argv[0]); - perror("fopen"); - exit(ERR_FILEPERM); - } - /* - * Now verify that the file is writable! - */ - if (! writable(pwfilename)) { - fprintf(stderr, "%s: cannot open file %s for write access\n", - argv[0], pwfilename); - perror("fopen"); - exit(ERR_FILEPERM); - } - - /* - * All the file access checks have been made. Time to go to work; - * try to create the record for the username in question. If that - * fails, there's no need to waste any time on file manipulations. - * Any error message text is returned in the record buffer, since - * the mkrecord() routine doesn't have access to argv[]. - */ - i = mkrecord(user, record, sizeof(record) - 1, - noninteractive ? password : NULL, - alg); - if (i != 0) { - fprintf(stderr, "%s: %s\n", argv[0], record); - exit(i); - } - - /* - * We can access the files the right way, and we have a record - * to add or update. Let's do it.. - */ - tempfilename = tmpnam(NULL); - ftemp = fopen(tempfilename, "w+"); - if (ftemp == NULL) { - fprintf(stderr, "%s: unable to create temporary file\n", argv[0]); - perror("fopen"); - exit(ERR_FILEPERM); - } - /* - * If we're not creating a new file, copy records from the existing - * one to the temporary file until we find the specified user. - */ - if (! newfile) { - char scratch[MAX_STRING_LEN]; - - fpw = fopen(pwfilename, "r"); - while (! (getline(line, sizeof(line), fpw))) { - char *colon; - - if ((line[0] == '#') || (line[0] == '\0')) { - putline(ftemp, line); - continue; - } - strcpy(scratch, line); - /* - * See if this is our user. - */ - colon = strchr(scratch, ':'); - if (colon != NULL) { - *colon = '\0'; - } - if (strcmp(user, scratch) != 0) { - putline(ftemp, line); - continue; - } - found++; - break; - } - } - if (found) { - fprintf(stderr, "Updating "); - } - else { - fprintf(stderr, "Adding "); - } - fprintf(stderr, "password for user %s\n", user); - /* - * Now add the user record we created. - */ - putline(ftemp, record); - /* - * If we're updating an existing file, there may be additional - * records beyond the one we're updating, so copy them. - */ - if (! newfile) { - copy_file(ftemp, fpw); - fclose(fpw); - } - /* - * The temporary file now contains the information that should be - * in the actual password file. Close the open files, re-open them - * in the appropriate mode, and copy them file to the real one. - */ - fclose(ftemp); - fpw = fopen(pwfilename, "w+"); - ftemp = fopen(tempfilename, "r"); - copy_file(fpw, ftemp); - fclose(fpw); - fclose(ftemp); - unlink(tempfilename); - return 0; -} diff --git a/test/logresolve.c b/test/logresolve.c deleted file mode 100644 index 8358dea7c..000000000 --- a/test/logresolve.c +++ /dev/null @@ -1,345 +0,0 @@ -/* - * logresolve 1.1 - * - * Tom Rathborne - tomr@uunet.ca - http://www.uunet.ca/~tomr/ - * UUNET Canada, April 16, 1995 - * - * Rewritten by David Robinson. (drtr@ast.cam.ac.uk) - * - * Usage: logresolve [-s filename] [-c] < access_log > new_log - * - * Arguments: - * -s filename name of a file to record statistics - * -c check the DNS for a matching A record for the host. - * - * Notes: - * - * To generate meaningful statistics from an HTTPD log file, it's good - * to have the domain name of each machine that accessed your site, but - * doing this on the fly can slow HTTPD down. - * - * Compiling NCSA HTTPD with the -DMINIMAL_DNS flag turns IP#->hostname - * resolution off. Before running your stats program, just run your log - * file through this program (logresolve) and all of your IP numbers will - * be resolved into hostnames (where possible). - * - * logresolve takes an HTTPD access log (in the COMMON log file format, - * or any other format that has the IP number/domain name as the first - * field for that matter), and outputs the same file with all of the - * domain names looked up. Where no domain name can be found, the IP - * number is left in. - * - * To minimize impact on your nameserver, logresolve has its very own - * internal hash-table cache. This means that each IP number will only - * be looked up the first time it is found in the log file. - * - * The -c option causes logresolve to apply the same check as httpd - * compiled with -DMAXIMUM_DNS; after finding the hostname from the IP - * address, it looks up the IP addresses for the hostname and checks - * that one of these matches the original address. - */ - -#include "apr_config.h" -#include <sys/types.h> - -#include <ctype.h> - -#ifndef MPE -#include <arpa/inet.h> -#endif - -static void cgethost(struct in_addr ipnum, char *string, int check); -static int getline(char *s, int n); -static void stats(FILE *output); - - -/* maximum line length */ -#define MAXLINE 1024 - -/* maximum length of a domain name */ -#ifndef MAXDNAME -#define MAXDNAME 256 -#endif - -/* number of buckets in cache hash ap_table_t */ -#define BUCKETS 256 - -#if defined(NEED_STRDUP) -char *strdup (const char *str) -{ - char *dup; - - if (!(dup = (char *) malloc(strlen(str) + 1))) - return NULL; - dup = strcpy(dup, str); - - return dup; -} -#endif - -/* - * struct nsrec - record of nameservice for cache linked list - * - * ipnum - IP number hostname - hostname noname - nonzero if IP number has no - * hostname, i.e. hostname=IP number - */ - -struct nsrec { - struct in_addr ipnum; - char *hostname; - int noname; - struct nsrec *next; -} *nscache[BUCKETS]; - -/* - * statistics - obvious - */ - -#ifndef h_errno -extern int h_errno; /* some machines don't have this in their headers */ -#endif - -/* largeste value for h_errno */ -#define MAX_ERR (NO_ADDRESS) -#define UNKNOWN_ERR (MAX_ERR+1) -#define NO_REVERSE (MAX_ERR+2) - -static int cachehits = 0; -static int cachesize = 0; -static int entries = 0; -static int resolves = 0; -static int withname = 0; -static int errors[MAX_ERR + 3]; - -/* - * cgethost - gets hostname by IP address, caching, and adding unresolvable - * IP numbers with their IP number as hostname, setting noname flag - */ - -static void cgethost (struct in_addr ipnum, char *string, int check) -{ - struct nsrec **current, *new; - struct hostent *hostdata; - char *name; - - current = &nscache[((ipnum.s_addr + (ipnum.s_addr >> 8) + - (ipnum.s_addr >> 16) + (ipnum.s_addr >> 24)) % BUCKETS)]; - - while (*current != NULL && ipnum.s_addr != (*current)->ipnum.s_addr) - current = &(*current)->next; - - if (*current == NULL) { - cachesize++; - new = (struct nsrec *) malloc(sizeof(struct nsrec)); - if (new == NULL) { - perror("malloc"); - fprintf(stderr, "Insufficient memory\n"); - exit(1); - } - *current = new; - new->next = NULL; - - new->ipnum = ipnum; - - hostdata = gethostbyaddr((const char *) &ipnum, sizeof(struct in_addr), - AF_INET); - if (hostdata == NULL) { - if (h_errno > MAX_ERR) - errors[UNKNOWN_ERR]++; - else - errors[h_errno]++; - new->noname = h_errno; - name = strdup(inet_ntoa(ipnum)); - } - else { - new->noname = 0; - name = strdup(hostdata->h_name); - if (check) { - if (name == NULL) { - perror("strdup"); - fprintf(stderr, "Insufficient memory\n"); - exit(1); - } - hostdata = gethostbyname(name); - if (hostdata != NULL) { - char **hptr; - - for (hptr = hostdata->h_addr_list; *hptr != NULL; hptr++) - if (((struct in_addr *) (*hptr))->s_addr == ipnum.s_addr) - break; - if (*hptr == NULL) - hostdata = NULL; - } - if (hostdata == NULL) { - fprintf(stderr, "Bad host: %s != %s\n", name, - inet_ntoa(ipnum)); - new->noname = NO_REVERSE; - free(name); - name = strdup(inet_ntoa(ipnum)); - errors[NO_REVERSE]++; - } - } - } - new->hostname = name; - if (new->hostname == NULL) { - perror("strdup"); - fprintf(stderr, "Insufficient memory\n"); - exit(1); - } - } - else - cachehits++; - - /* size of string == MAXDNAME +1 */ - strncpy(string, (*current)->hostname, MAXDNAME); - string[MAXDNAME] = '\0'; -} - -/* - * prints various statistics to output - */ - -static void stats (FILE *output) -{ - int i; - char *ipstring; - struct nsrec *current; - char *errstring[MAX_ERR + 3]; - - for (i = 0; i < MAX_ERR + 3; i++) - errstring[i] = "Unknown error"; - errstring[HOST_NOT_FOUND] = "Host not found"; - errstring[TRY_AGAIN] = "Try again"; - errstring[NO_RECOVERY] = "Non recoverable error"; - errstring[NO_DATA] = "No data record"; - errstring[NO_ADDRESS] = "No address"; - errstring[NO_REVERSE] = "No reverse entry"; - - fprintf(output, "logresolve Statistics:\n"); - - fprintf(output, "Entries: %d\n", entries); - fprintf(output, " With name : %d\n", withname); - fprintf(output, " Resolves : %d\n", resolves); - if (errors[HOST_NOT_FOUND]) - fprintf(output, " - Not found : %d\n", errors[HOST_NOT_FOUND]); - if (errors[TRY_AGAIN]) - fprintf(output, " - Try again : %d\n", errors[TRY_AGAIN]); - if (errors[NO_DATA]) - fprintf(output, " - No data : %d\n", errors[NO_DATA]); - if (errors[NO_ADDRESS]) - fprintf(output, " - No address: %d\n", errors[NO_ADDRESS]); - if (errors[NO_REVERSE]) - fprintf(output, " - No reverse: %d\n", errors[NO_REVERSE]); - fprintf(output, "Cache hits : %d\n", cachehits); - fprintf(output, "Cache size : %d\n", cachesize); - fprintf(output, "Cache buckets : IP number * hostname\n"); - - for (i = 0; i < BUCKETS; i++) - for (current = nscache[i]; current != NULL; current = current->next) { - ipstring = inet_ntoa(current->ipnum); - if (current->noname == 0) - fprintf(output, " %3d %15s - %s\n", i, ipstring, - current->hostname); - else { - if (current->noname > MAX_ERR + 2) - fprintf(output, " %3d %15s : Unknown error\n", i, - ipstring); - else - fprintf(output, " %3d %15s : %s\n", i, ipstring, - errstring[current->noname]); - } - } -} - - -/* - * gets a line from stdin - */ - -static int getline (char *s, int n) -{ - char *cp; - - if (!fgets(s, n, stdin)) - return (0); - cp = strchr(s, '\n'); - if (cp) - *cp = '\0'; - return (1); -} - -int main (int argc, char *argv[]) -{ - struct in_addr ipnum; - char *bar, hoststring[MAXDNAME + 1], line[MAXLINE], *statfile; - int i, check; - - check = 0; - statfile = NULL; - for (i = 1; i < argc; i++) { - if (strcmp(argv[i], "-c") == 0) - check = 1; - else if (strcmp(argv[i], "-s") == 0) { - if (i == argc - 1) { - fprintf(stderr, "logresolve: missing filename to -s\n"); - exit(1); - } - i++; - statfile = argv[i]; - } - else { - fprintf(stderr, "Usage: logresolve [-s statfile] [-c] < input > output\n"); - exit(0); - } - } - - - for (i = 0; i < BUCKETS; i++) - nscache[i] = NULL; - for (i = 0; i < MAX_ERR + 2; i++) - errors[i] = 0; - - while (getline(line, MAXLINE)) { - if (line[0] == '\0') - continue; - entries++; - if (!isdigit(line[0])) { /* short cut */ - puts(line); - withname++; - continue; - } - bar = strchr(line, ' '); - if (bar != NULL) - *bar = '\0'; - ipnum.s_addr = inet_addr(line); - if (ipnum.s_addr == 0xffffffffu) { - if (bar != NULL) - *bar = ' '; - puts(line); - withname++; - continue; - } - - resolves++; - - cgethost(ipnum, hoststring, check); - if (bar != NULL) - printf("%s %s\n", hoststring, bar + 1); - else - puts(hoststring); - } - - if (statfile != NULL) { - FILE *fp; - fp = fopen(statfile, "w"); - if (fp == NULL) { - fprintf(stderr, "logresolve: could not open statistics file '%s'\n" - ,statfile); - exit(1); - } - stats(fp); - fclose(fp); - } - - return (0); -} diff --git a/test/rotatelogs.c b/test/rotatelogs.c deleted file mode 100644 index f2e095259..000000000 --- a/test/rotatelogs.c +++ /dev/null @@ -1,136 +0,0 @@ -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2000 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" must - * not be used to endorse or promote products derived from this - * software without prior written permission. For written - * permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * nor may "Apache" appear in their name, without prior written - * permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * <http://www.apache.org/>. - */ - -/* - * Simple program to rotate Apache logs without having to kill the server. - * - * Contributed by Ben Laurie <ben@algroup.co.uk> - * - * 12 Mar 1996 - */ - - -#define BUFSIZE 65536 -#define MAX_PATH 1024 - -#include "apr_config.h" -#include <time.h> -#include <errno.h> -#include <fcntl.h> - -int main (int argc, char **argv) -{ - char buf[BUFSIZE], buf2[MAX_PATH]; - time_t tLogEnd = 0; - time_t tRotation; - int nLogFD = -1; - int nRead; - char *szLogRoot; - - if (argc != 3) { - fprintf(stderr, - "%s <logfile> <rotation time in seconds>\n\n", - argv[0]); -#ifdef OS2 - fprintf(stderr, - "Add this:\n\nTransferLog \"|%s.exe /some/where 86400\"\n\n", - argv[0]); -#else - fprintf(stderr, - "Add this:\n\nTransferLog \"|%s /some/where 86400\"\n\n", - argv[0]); -#endif - fprintf(stderr, - "to httpd.conf. The generated name will be /some/where.nnnn " - "where nnnn is the\nsystem time at which the log nominally " - "starts (N.B. this time will always be a\nmultiple of the " - "rotation time, so you can synchronize cron scripts with it).\n" - "At the end of each rotation time a new log is started.\n"); - exit(1); - } - - szLogRoot = argv[1]; - tRotation = atoi(argv[2]); - if (tRotation <= 0) { - fprintf(stderr, "Rotation time must be > 0\n"); - exit(6); - } - - for (;;) { - nRead = read(0, buf, sizeof buf); - if (nRead == 0) - exit(3); - if (nRead < 0) - if (errno != EINTR) - exit(4); - if (nLogFD >= 0 && (time(NULL) >= tLogEnd || nRead < 0)) { - close(nLogFD); - nLogFD = -1; - } - if (nLogFD < 0) { - time_t tLogStart = (time(NULL) / tRotation) * tRotation; - sprintf(buf2, "%s.%010d", szLogRoot, (int) tLogStart); - tLogEnd = tLogStart + tRotation; - nLogFD = open(buf2, O_WRONLY | O_CREAT | O_APPEND, 0666); - if (nLogFD < 0) { - perror(buf2); - exit(2); - } - } - if (write(nLogFD, buf, nRead) != nRead) { - perror(buf2); - exit(5); - } - } -} diff --git a/test/suexec.c b/test/suexec.c deleted file mode 100644 index 6a3731996..000000000 --- a/test/suexec.c +++ /dev/null @@ -1,560 +0,0 @@ -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2000 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" must - * not be used to endorse or promote products derived from this - * software without prior written permission. For written - * permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * nor may "Apache" appear in their name, without prior written - * permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * <http://www.apache.org/>. - */ - -/* - * suexec.c -- "Wrapper" support program for suEXEC behaviour for Apache - * - *********************************************************************** - * - * NOTE! : DO NOT edit this code!!! Unless you know what you are doing, - * editing this code might open up your system in unexpected - * ways to would-be crackers. Every precaution has been taken - * to make this code as safe as possible; alter it at your own - * risk. - * - *********************************************************************** - */ - -#include "apr_config.h" -#include <sys/param.h> -#include <sys/stat.h> -#include <sys/types.h> - -#include <stdarg.h> - -#include "suexec.h" - -/* - *********************************************************************** - * There is no initgroups() in QNX, so I believe this is safe :-) - * Use cc -osuexec -3 -O -mf -DQNX suexec.c to compile. - * - * May 17, 1997. - * Igor N. Kovalenko -- infoh@mail.wplus.net - *********************************************************************** - */ - -#if defined(NEED_INITGROUPS) -int initgroups(const char *name, gid_t basegid) -{ -/* QNX and MPE do not appear to support supplementary groups. */ - return 0; -} -#endif - -#if defined(PATH_MAX) -#define AP_MAXPATH PATH_MAX -#elif defined(MAXPATHLEN) -#define AP_MAXPATH MAXPATHLEN -#else -#define AP_MAXPATH 8192 -#endif - -#define AP_ENVBUF 256 - -extern char **environ; -static FILE *log = NULL; - -char *safe_env_lst[] = -{ - "AUTH_TYPE", - "CONTENT_LENGTH", - "CONTENT_TYPE", - "DATE_GMT", - "DATE_LOCAL", - "DOCUMENT_NAME", - "DOCUMENT_PATH_INFO", - "DOCUMENT_ROOT", - "DOCUMENT_URI", - "FILEPATH_INFO", - "GATEWAY_INTERFACE", - "LAST_MODIFIED", - "PATH_INFO", - "PATH_TRANSLATED", - "QUERY_STRING", - "QUERY_STRING_UNESCAPED", - "REMOTE_ADDR", - "REMOTE_HOST", - "REMOTE_IDENT", - "REMOTE_PORT", - "REMOTE_USER", - "REDIRECT_QUERY_STRING", - "REDIRECT_STATUS", - "REDIRECT_URL", - "REQUEST_METHOD", - "REQUEST_URI", - "SCRIPT_FILENAME", - "SCRIPT_NAME", - "SCRIPT_URI", - "SCRIPT_URL", - "SERVER_ADMIN", - "SERVER_NAME", - "SERVER_PORT", - "SERVER_PROTOCOL", - "SERVER_SOFTWARE", - "UNIQUE_ID", - "USER_NAME", - "TZ", - NULL -}; - - -static void err_output(const char *fmt, va_list ap) -{ -#ifdef LOG_EXEC - time_t timevar; - struct tm *lt; - - if (!log) { - if ((log = fopen(LOG_EXEC, "a")) == NULL) { - fprintf(stderr, "failed to open log file\n"); - perror("fopen"); - exit(1); - } - } - - time(&timevar); - lt = localtime(&timevar); - - fprintf(log, "[%d-%.2d-%.2d %.2d:%.2d:%.2d]: ", - lt->tm_year + 1900, lt->tm_mon + 1, lt->tm_mday, - lt->tm_hour, lt->tm_min, lt->tm_sec); - - vfprintf(log, fmt, ap); - - fflush(log); -#endif /* LOG_EXEC */ - return; -} - -static void log_err(const char *fmt,...) -{ -#ifdef LOG_EXEC - va_list ap; - - va_start(ap, fmt); - err_output(fmt, ap); - va_end(ap); -#endif /* LOG_EXEC */ - return; -} - -static void clean_env(void) -{ - char pathbuf[512]; - char **cleanenv; - char **ep; - int cidx = 0; - int idx; - - - if ((cleanenv = (char **) calloc(AP_ENVBUF, sizeof(char *))) == NULL) { - log_err("failed to malloc memory for environment\n"); - exit(120); - } - - sprintf(pathbuf, "PATH=%s", SAFE_PATH); - cleanenv[cidx] = strdup(pathbuf); - cidx++; - - for (ep = environ; *ep && cidx < AP_ENVBUF-1; ep++) { - if (!strncmp(*ep, "HTTP_", 5)) { - cleanenv[cidx] = *ep; - cidx++; - } - else { - for (idx = 0; safe_env_lst[idx]; idx++) { - if (!strncmp(*ep, safe_env_lst[idx], - strlen(safe_env_lst[idx]))) { - cleanenv[cidx] = *ep; - cidx++; - break; - } - } - } - } - - cleanenv[cidx] = NULL; - - environ = cleanenv; -} - -int main(int argc, char *argv[]) -{ - int userdir = 0; /* ~userdir flag */ - uid_t uid; /* user information */ - gid_t gid; /* target group placeholder */ - char *target_uname; /* target user name */ - char *target_gname; /* target group name */ - char *target_homedir; /* target home directory */ - char *actual_uname; /* actual user name */ - char *actual_gname; /* actual group name */ - char *prog; /* name of this program */ - char *cmd; /* command to be executed */ - char cwd[AP_MAXPATH]; /* current working directory */ - char dwd[AP_MAXPATH]; /* docroot working directory */ - struct passwd *pw; /* password entry holder */ - struct group *gr; /* group entry holder */ - struct stat dir_info; /* directory info holder */ - struct stat prg_info; /* program info holder */ - - /* - * If there are a proper number of arguments, set - * all of them to variables. Otherwise, error out. - */ - prog = argv[0]; - if (argc < 4) { - log_err("too few arguments\n"); - exit(101); - } - target_uname = argv[1]; - target_gname = argv[2]; - cmd = argv[3]; - - /* - * Check existence/validity of the UID of the user - * running this program. Error out if invalid. - */ - uid = getuid(); - if ((pw = getpwuid(uid)) == NULL) { - log_err("invalid uid: (%ld)\n", uid); - exit(102); - } - - /* - * Check to see if the user running this program - * is the user allowed to do so as defined in - * suexec.h. If not the allowed user, error out. - */ -#ifdef _OSD_POSIX - /* User name comparisons are case insensitive on BS2000/OSD */ - if (strcasecmp(HTTPD_USER, pw->pw_name)) { - log_err("user mismatch (%s instead of %s)\n", pw->pw_name, HTTPD_USER); - exit(103); - } -#else /*_OSD_POSIX*/ - if (strcmp(HTTPD_USER, pw->pw_name)) { - log_err("user mismatch (%s instead of %s)\n", pw->pw_name, HTTPD_USER); - exit(103); - } -#endif /*_OSD_POSIX*/ - - /* - * Check for a leading '/' (absolute path) in the command to be executed, - * or attempts to back up out of the current directory, - * to protect against attacks. If any are - * found, error out. Naughty naughty crackers. - */ - if ((cmd[0] == '/') || (!strncmp(cmd, "../", 3)) - || (strstr(cmd, "/../") != NULL)) { - log_err("invalid command (%s)\n", cmd); - exit(104); - } - - /* - * Check to see if this is a ~userdir request. If - * so, set the flag, and remove the '~' from the - * target username. - */ - if (!strncmp("~", target_uname, 1)) { - target_uname++; - userdir = 1; - } - - /* - * Error out if the target username is invalid. - */ - if ((pw = getpwnam(target_uname)) == NULL) { - log_err("invalid target user name: (%s)\n", target_uname); - exit(105); - } - - /* - * Error out if the target group name is invalid. - */ - if (strspn(target_gname, "1234567890") != strlen(target_gname)) { - if ((gr = getgrnam(target_gname)) == NULL) { - log_err("invalid target group name: (%s)\n", target_gname); - exit(106); - } - gid = gr->gr_gid; - actual_gname = strdup(gr->gr_name); - } - else { - gid = atoi(target_gname); - actual_gname = strdup(target_gname); - } - -#ifdef _OSD_POSIX - /* - * Initialize BS2000 user environment - */ - { - pid_t pid; - int status; - - switch (pid = ufork(target_uname)) - { - case -1: /* Error */ - log_err("failed to setup bs2000 environment for user %s: %s\n", - target_uname, strerror(errno)); - exit(150); - case 0: /* Child */ - break; - default: /* Father */ - while (pid != waitpid(pid, &status, 0)) - ; - /* @@@ FIXME: should we deal with STOP signals as well? */ - if (WIFSIGNALED(status)) - kill (getpid(), WTERMSIG(status)); - exit(WEXITSTATUS(status)); - } - } -#endif /*_OSD_POSIX*/ - - /* - * Save these for later since initgroups will hose the struct - */ - uid = pw->pw_uid; - actual_uname = strdup(pw->pw_name); - target_homedir = strdup(pw->pw_dir); - - /* - * Log the transaction here to be sure we have an open log - * before we setuid(). - */ - log_err("uid: (%s/%s) gid: (%s/%s) cmd: %s\n", - target_uname, actual_uname, - target_gname, actual_gname, - cmd); - - /* - * Error out if attempt is made to execute as root or as - * a UID less than UID_MIN. Tsk tsk. - */ - if ((uid == 0) || (uid < UID_MIN)) { - log_err("cannot run as forbidden uid (%d/%s)\n", uid, cmd); - exit(107); - } - - /* - * Error out if attempt is made to execute as root group - * or as a GID less than GID_MIN. Tsk tsk. - */ - if ((gid == 0) || (gid < GID_MIN)) { - log_err("cannot run as forbidden gid (%d/%s)\n", gid, cmd); - exit(108); - } - - /* - * Change UID/GID here so that the following tests work over NFS. - * - * Initialize the group access list for the target user, - * and setgid() to the target group. If unsuccessful, error out. - */ - if (((setgid(gid)) != 0) || (initgroups(actual_uname, gid) != 0)) { - log_err("failed to setgid (%ld: %s)\n", gid, cmd); - exit(109); - } - - /* - * setuid() to the target user. Error out on fail. - */ - if ((setuid(uid)) != 0) { - log_err("failed to setuid (%ld: %s)\n", uid, cmd); - exit(110); - } - - /* - * Get the current working directory, as well as the proper - * document root (dependant upon whether or not it is a - * ~userdir request). Error out if we cannot get either one, - * or if the current working directory is not in the docroot. - * Use chdir()s and getcwd()s to avoid problems with symlinked - * directories. Yuck. - */ - if (getcwd(cwd, AP_MAXPATH) == NULL) { - log_err("cannot get current working directory\n"); - exit(111); - } - - if (userdir) { - if (((chdir(target_homedir)) != 0) || - ((chdir(USERDIR_SUFFIX)) != 0) || - ((getcwd(dwd, AP_MAXPATH)) == NULL) || - ((chdir(cwd)) != 0)) { - log_err("cannot get docroot information (%s)\n", target_homedir); - exit(112); - } - } - else { - if (((chdir(DOC_ROOT)) != 0) || - ((getcwd(dwd, AP_MAXPATH)) == NULL) || - ((chdir(cwd)) != 0)) { - log_err("cannot get docroot information (%s)\n", DOC_ROOT); - exit(113); - } - } - - if ((strncmp(cwd, dwd, strlen(dwd))) != 0) { - log_err("command not in docroot (%s/%s)\n", cwd, cmd); - exit(114); - } - - /* - * Stat the cwd and verify it is a directory, or error out. - */ - if (((lstat(cwd, &dir_info)) != 0) || !(S_ISDIR(dir_info.st_mode))) { - log_err("cannot stat directory: (%s)\n", cwd); - exit(115); - } - - /* - * Error out if cwd is writable by others. - */ - if ((dir_info.st_mode & S_IWOTH) || (dir_info.st_mode & S_IWGRP)) { - log_err("directory is writable by others: (%s)\n", cwd); - exit(116); - } - - /* - * Error out if we cannot stat the program. - */ - if (((lstat(cmd, &prg_info)) != 0) || (S_ISLNK(prg_info.st_mode))) { - log_err("cannot stat program: (%s)\n", cmd); - exit(117); - } - - /* - * Error out if the program is writable by others. - */ - if ((prg_info.st_mode & S_IWOTH) || (prg_info.st_mode & S_IWGRP)) { - log_err("file is writable by others: (%s/%s)\n", cwd, cmd); - exit(118); - } - - /* - * Error out if the file is setuid or setgid. - */ - if ((prg_info.st_mode & S_ISUID) || (prg_info.st_mode & S_ISGID)) { - log_err("file is either setuid or setgid: (%s/%s)\n", cwd, cmd); - exit(119); - } - - /* - * Error out if the target name/group is different from - * the name/group of the cwd or the program. - */ - if ((uid != dir_info.st_uid) || - (gid != dir_info.st_gid) || - (uid != prg_info.st_uid) || - (gid != prg_info.st_gid)) { - log_err("target uid/gid (%ld/%ld) mismatch " - "with directory (%ld/%ld) or program (%ld/%ld)\n", - uid, gid, - dir_info.st_uid, dir_info.st_gid, - prg_info.st_uid, prg_info.st_gid); - exit(120); - } - /* - * Error out if the program is not executable for the user. - * Otherwise, she won't find any error in the logs except for - * "[error] Premature end of script headers: ..." - */ - if (!(prg_info.st_mode & S_IXUSR)) { - log_err("file has no execute permission: (%s/%s)\n", cwd, cmd); - exit(121); - } - - clean_env(); - - /* - * Be sure to close the log file so the CGI can't - * mess with it. If the exec fails, it will be reopened - * automatically when log_err is called. Note that the log - * might not actually be open if LOG_EXEC isn't defined. - * However, the "log" cell isn't ifdef'd so let's be defensive - * and assume someone might have done something with it - * outside an ifdef'd LOG_EXEC block. - */ - if (log != NULL) { - fclose(log); - log = NULL; - } - - /* - * Execute the command, replacing our image with its own. - */ -#ifdef NEED_HASHBANG_EMUL - /* We need the #! emulation when we want to execute scripts */ - { - extern char **environ; - - ap_execve(cmd, &argv[3], environ); - } -#else /*NEED_HASHBANG_EMUL*/ - execv(cmd, &argv[3]); -#endif /*NEED_HASHBANG_EMUL*/ - - /* - * (I can't help myself...sorry.) - * - * Uh oh. Still here. Where's the kaboom? There was supposed to be an - * EARTH-shattering kaboom! - * - * Oh well, log the failure and error out. - */ - log_err("(%d)%s: exec failed (%s)\n", errno, strerror(errno), cmd); - exit(255); -} |