Index: aclocal.m4 =================================================================== RCS file: /cvs/privman/privman/clients/wu-ftpd/aclocal.m4,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 Index: config.h.in =================================================================== RCS file: /cvs/privman/privman/clients/wu-ftpd/config.h.in,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- config.h.in 2002/07/10 20:12:29 1.1 +++ config.h.in 2002/07/30 06:01:20 1.2 @@ -353,3 +353,8 @@ * line FTP client users. */ #undef NLST_SHOWS_DIRS + +/* + * Define this to use the "Privman" priviledge seperation library. + */ +#undef HAVE_LIBPRIVMAN Index: configure.in =================================================================== RCS file: /cvs/privman/privman/clients/wu-ftpd/configure.in,v retrieving revision 1.1 retrieving revision 1.5 diff -u -r1.1 -r1.5 --- configure.in 2002/07/10 20:12:29 1.1 +++ configure.in 2002/10/31 21:34:07 1.5 @@ -136,6 +136,13 @@ [ --enable-opie add OPIE support (needs OPIE libraries)], [ opie=$enableval ], [ opie=no ]) +AC_ARG_ENABLE(privman, + [ --enable-privman add PRIVMAN support (needs PRIVMAN libraries)], + [ privman=$enableval ], [ privman=no ]) + +if test $privman = "yes"; then + pam = yes +fi if test $skey = "yes" -o $skey = "y" then if test $opie = "yes" -o $skey = "y" @@ -214,7 +221,7 @@ syslog.h sys/syslog.h fcntl.h mntent.h stdlib.h unistd.h glob.h grp.h \ ndir.h sys/dir.h sys/ndir.h string.h vmsdir.h sys/systeminfo.h \ bsd/bsd.h sys/param.h values.h limits.h sys/types.h sys/mntent.h \ - sys/mnttab.h paths.h) + sys/mnttab.h paths.h privman.h) AC_CHECK_FUNCS(dirfd fchdir flock ftw getcwd getdtablesize pstat lstat \ vprintf snprintf regexec regex fgetspent usercmp getusershell setuid vsnprintf \ snprintf strcasestr strdup strerror strsep strstr syslog glob strcasecmp \ @@ -223,6 +230,16 @@ AC_CHECK_FUNCS(seteuid setreuid setresuid, break) AC_CHECK_FUNCS(setegid setregid setresgid, break) +if test $privman = "yes"; then + AC_CHECK_LIB(privman, priv_init, result=yes, result=no,-lstdc++ -lpam) + if test $result = yes; then + # Some PAM implementations require -ldl... + LIBS="$LIBS -lprivman -lpam -lstdc++" + AC_DEFINE(HAVE_LIBPRIVMAN) + fi + +fi + AC_CHECK_LIB(crypt, crypt, result=yes, result=no) if test $result = yes; then LIBS="$LIBS -lcrypt" @@ -807,6 +824,10 @@ if test $pam = yes; then AC_MSG_WARN(You don\'t have PAM libraries, or you\'re using an incompatible PAM implementation. PAM support disabled.) pam=no + if test $privman = yes; then + AC_MSG_WARN(You need PAM libraries for PRIVMAN support.) + privman=no + fi fi fi if test $pam = yes; then Index: src/access.c =================================================================== RCS file: /cvs/privman/privman/clients/wu-ftpd/src/access.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- src/access.c 2002/07/10 20:12:30 1.1 +++ src/access.c 2002/07/26 18:21:09 1.2 @@ -56,6 +56,13 @@ #include #include +#ifdef HAVE_LIBPRIVMAN +#include +#else +#define priv_fopen(a,b) fopen((a),(b)) +#define priv_open(a,b,c) open((a),(b),(c)) +#endif + #ifdef HAVE_PATHS_H #include #endif @@ -1157,7 +1164,7 @@ if (pidfd < 0) { mode_t oldmask; oldmask = umask(0); - pidfd = open(pidfile, O_RDWR | O_CREAT, 0644); + pidfd = priv_open(pidfile, O_RDWR | O_CREAT, 0644); (void) umask(oldmask); } @@ -1230,7 +1237,7 @@ if (pidfd < 0) { mode_t oldmask; oldmask = umask(0); - pidfd = open(pidfile, O_RDWR | O_CREAT, 0644); + pidfd = priv_open(pidfile, O_RDWR | O_CREAT, 0644); (void) umask(oldmask); } @@ -1330,7 +1337,7 @@ if (pidfd < 0) { mode_t oldmask; oldmask = umask(0); - pidfd = open(pidfile, O_RDWR | O_CREAT, 0644); + pidfd = priv_open(pidfile, O_RDWR | O_CREAT, 0644); (void) umask(oldmask); } Index: src/acl.c =================================================================== RCS file: /cvs/privman/privman/clients/wu-ftpd/src/acl.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- src/acl.c 2002/07/10 20:12:30 1.1 +++ src/acl.c 2002/07/26 18:21:09 1.2 @@ -40,6 +40,12 @@ #include #include +#ifdef HAVE_LIBPRIVMAN +#include +#else +#define priv_fopen(p,m) fopen((p),(m)) +#endif + #ifdef HAVE_PATHS_H #include #endif @@ -145,7 +151,7 @@ if (!use_accessfile) return (0); - if ((aclfile = fopen(aclpath, "r")) == NULL) { + if ((aclfile = priv_fopen(aclpath, "r")) == NULL) { syslog(LOG_ERR, "cannot open access file %s: %s", aclpath, strerror(errno)); return (0); Index: src/config.h.in =================================================================== RCS file: /cvs/privman/privman/clients/wu-ftpd/src/config.h.in,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- src/config.h.in 2002/07/10 20:12:30 1.1 +++ src/config.h.in 2002/07/26 18:21:09 1.2 @@ -130,6 +130,8 @@ #undef HAVE_UT_UT_HOST #undef HAVE_UT_UT_EXIT_E_TERMINATION +#undef HAVE_LIBPRIVMAN + /* Here instead of everywhere: */ #include #include Index: src/conversions.c =================================================================== RCS file: /cvs/privman/privman/clients/wu-ftpd/src/conversions.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- src/conversions.c 2002/07/10 20:12:30 1.1 +++ src/conversions.c 2002/07/26 18:21:09 1.2 @@ -35,6 +35,13 @@ #include #endif +#ifdef HAVE_LIBPRIVMAN +#include +#else +#define priv_fopen(a,b) fopen((a),(b)) +#endif + + extern char *strsep(char **, const char *); #include @@ -90,7 +97,7 @@ FILE *convfile; struct stat finfo; - if ((convfile = fopen(convpath, "r")) == NULL) { + if ((convfile = priv_fopen(convpath, "r")) == NULL) { if (errno != ENOENT) syslog(LOG_ERR, "cannot open conversion file %s: %s", convpath, strerror(errno)); Index: src/ftpd.c =================================================================== RCS file: /cvs/privman/privman/clients/wu-ftpd/src/ftpd.c,v retrieving revision 1.1 retrieving revision 1.6 diff -u -r1.1 -r1.6 --- src/ftpd.c 2002/07/10 20:12:30 1.1 +++ src/ftpd.c 2002/10/31 21:34:07 1.6 @@ -35,6 +35,21 @@ #include #include +#ifdef HAVE_LIBPRIVMAN +#include +#else +#define priv_bind(s,a,l) bind((s),(a),(l)) +#define priv_fopen(p,m) fopen((p),(m)) +#define priv_open(f,m,p) open((f),(m),(p)) +#define priv_fork() fork() +#define priv_pam_start(a,b,c,d) pam_start((a),(b),(c),(d)) +#define priv_pam_set_item(a,b,c) pam_set_item((a),(b),(c)) +#define priv_pam_authenticate(a,b) pam_authenticate((a),(b)) +#define priv_pam_acct_mgmt(a,b) pam_acct_mgmt((a),(b)) +#define priv_pam_setcred(a,b) pam_setcred((a),(b)) +#define priv_pam_end(a,b) pam_end((a),(b)) +#endif + #ifdef AIX #include #include @@ -190,6 +205,10 @@ #define FALSE !TRUE #endif +#ifndef PATH_FTPD_STAGE2 +#define PATH_FTPD_STAGE2 "/usr/sbin/in.ftpd" +#endif + #ifdef MAIL_ADMIN #define MAILSERVERS 10 #define INCMAILS 10 @@ -596,6 +615,10 @@ struct servent *serv; #endif +#ifdef HAVE_LIBPRIVMAN + priv_init("wuftp"); +#endif + #ifdef AUX setcompat(COMPAT_POSIX | COMPAT_BSDSETUGID); #endif @@ -1311,7 +1334,7 @@ mailfrom = strdup("wu-ftpd"); } #endif /* MAIL_ADMIN */ - { + if (!logged_in) { #define OUTPUT_LEN 1024 int version_option = 0; char output_text[OUTPUT_LEN + 1]; @@ -2461,6 +2484,56 @@ } #endif +#ifdef HAVE_LIBPRIVMAN +void run_as_user(char * const arg[]) +{ + const char *s_name, *s_uid, *s_gid, *s_dir, *s_shell; + int uid; + + logged_in = 1; + /* Arg of format "name:*:uid:gid::dir:/bin/false" + * Extract the uid. If I can look that up, do so. + * Else, create a fake pw entry instead. + */ + + s_name = arg[0]; + s_uid = index(s_name, ':') + 3; /* skip ":*:" */ + + uid = atoi(s_uid); + pw = getpwuid(uid); + + if (pw == NULL) { + size_t len; + + syslog(LOG_INFO, "making up pwent info."); + + s_gid = index(s_uid, ':') + 1; + s_dir = index(s_gid, ':') + 2; + pw = (struct passwd *)malloc(sizeof(struct passwd)); + + len = s_uid - s_name - 3; + pw->pw_name = (char *)malloc(len + 1); + memcpy(pw->pw_name, s_name, len); + pw->pw_name[len] = '\0'; + + pw->pw_passwd = 0; + pw->pw_uid = uid; + pw->pw_gid = atoi(s_gid); + pw->pw_gecos = 0; + + len = s_shell - s_dir - 1; + pw->pw_dir = (char *)malloc(len + 1); + memcpy(pw->pw_dir, s_dir, len); + pw->pw_dir[len] = '\0'; + + pw->pw_shell = "/bin/false"; + } + + home = pw->pw_dir; + chdir(home); +} +#endif + void pass(char *passwd) { @@ -2471,6 +2544,9 @@ int passwarn = 0; int rval = 1; +#ifdef HAVE_LIBPRIVMAN + char *new_root = 0; +#endif #ifdef SECUREOSF struct pr_passwd *pr; int crypt_alg = 0; @@ -2574,7 +2650,7 @@ if ((salt = check_auth(the_user, passwd))) { reply(530, "%s", salt); #ifdef LOG_FAILED /* 27-Apr-93 EHK/BM */ - syslog(LOG_INFO, "failed login from %s", + syslog(LOG_INFO, "1 failed login from %s", remoteident); #endif /* LOG_FAILED */ acl_remove(); @@ -2697,6 +2773,7 @@ #endif /* DCE_AUTH */ } #ifdef USE_PAM + syslog(LOG_NOTICE, "exiting USE_PAM block"); } #endif #endif /* !USE_PAM || (USE_PAM && OTHER_PASSWD) */ @@ -2711,7 +2788,7 @@ syslog(LOG_NOTICE, "REFUSED \"NULL\" from %s, %s", remoteident, the_user); else - syslog(LOG_INFO, "failed login from %s", + syslog(LOG_INFO, "2 failed login from %s", remoteident); #endif acl_remove(); @@ -2817,7 +2894,7 @@ if ((log_outbound_xfers || log_incoming_xfers) && (syslogmsg != 1)) { mode_t oldmask; oldmask = umask(0); - xferlog = open(logfile, O_WRONLY | O_APPEND | O_CREAT, 0640); + xferlog = priv_open(logfile, O_WRONLY | O_APPEND | O_CREAT, 0640); (void) umask(oldmask); if (xferlog < 0) { syslog(LOG_ERR, "cannot open logfile %s: %s", logfile, @@ -3041,6 +3118,9 @@ (void) strncpy(chroot_path, root_path, sizeof(chroot_path)); chroot_path[sizeof(chroot_path) - 1] = '\0'; pw->pw_dir = sgetsave(chroot_path); +#ifdef HAVE_LIBPRIVMAN + new_root = chroot_path; +#else if (chroot(root_path) < 0 || chdir("/") < 0) { #ifdef VERBOSE_ERROR_LOGING syslog(LOG_NOTICE, "FTP LOGIN FAILED (cannot set guest privileges) for %s, %s", @@ -3049,6 +3129,7 @@ reply(530, "Can't set guest privileges."); goto bad; } +#endif /* HAVE_LIBPRIVMAN */ #ifdef OTHER_PASSWD if ((chroot_pw = bero_getpwuid(pw->pw_uid, _path_passwd)) != NULL) #else @@ -3079,6 +3160,9 @@ goto bad; } #endif +#ifdef HAVE_LIBPRIVMAN + new_root = pw->pw_dir; +#else if (chroot(pw->pw_dir) < 0 || chdir("/") < 0) { #ifdef VERBOSE_ERROR_LOGING syslog(LOG_NOTICE, "FTP LOGIN FAILED (cannot set guest privileges) for %s, %s", @@ -3087,6 +3171,7 @@ reply(530, "Can't set guest privileges."); goto bad; } +#endif /* HAVE_LIBPRIVMAN */ } else { *sp++ = '\0'; @@ -3106,6 +3191,9 @@ goto bad; } #endif +#ifdef HAVE_LIBPRIVMAN + new_root = pw->pw_dir; +#else if (chroot(pw->pw_dir) < 0 || chdir(++sp) < 0) { #ifdef VERBOSE_ERROR_LOGING syslog(LOG_NOTICE, "FTP LOGIN FAILED (cannot set guest privileges) for %s, %s", @@ -3114,6 +3202,7 @@ reply(550, "Can't set guest privileges."); goto bad; } +#endif /* HAVE_LIBPRIVMAN */ #ifdef ALTERNATE_CD home = sp; #endif @@ -3164,7 +3253,7 @@ lreply(230, "rgid=%d, egid=%d, sgid=%d, lgid=%d", getgidx(ID_REAL), getgidx(ID_EFFECTIVE), getgidx(ID_SAVED), getgidx(ID_LOGIN)); #endif -#else +#elif !defined(HAVE_LIBPRIVMAN) #ifdef HAVE_SETREUID if (setreuid(-1, (uid_t) pw->pw_uid) < 0) { #else @@ -3177,7 +3266,8 @@ reply(530, "Can't set uid."); goto bad; } -#endif +#endif /* HAVE_LIBPRIVMAN || AIX */ +#ifndef HAVE_LIBPRIVMAN if (!anonymous && !guest) { if (chdir(pw->pw_dir) < 0) { #ifdef PARANOID @@ -3199,7 +3289,8 @@ goto bad; } else { - lreply(230, "No directory! Logging in with home=/"); + lreply(230, "No directory %s! Logging in with home=/", + pw->pw_dir); #ifdef ALTERNATE_CD home = defhome; #endif @@ -3207,6 +3298,7 @@ #endif } } +#endif /* Will chdir in -Z handling. */ if (passwarn) { lreply(230, "The response '%s' is not valid", passwd); @@ -3272,6 +3364,32 @@ || ((guest | anonymous) && strcmp(ARG0, "*") == 0)) limit_time = strtoul(ARG1, NULL, 0); } + +#ifdef HAVE_LIBPRIVMAN + { + char *args[2]; + args[0] = malloc(1024); + args[1] = NULL; + + /* Hack: + * restart execution from "priv_init". The function listed + * below will run first, allowing us to muck with the global + * environment. + */ + syslog(LOG_INFO, "rerunning. user = %s, root = %s", + pw->pw_name, new_root); + snprintf(args[0], 1024-1, "%s:*:%d:%d::%s:/bin/false", + pw->pw_name, pw->pw_uid, pw->pw_gid, pw->pw_dir); + if (priv_rerunas(run_as_user, args, pw->pw_name, new_root, 0) < 0) { + syslog(LOG_ERR, "call to \"priv_execve\" failed."); + reply(530, "Can't set privileges."); + goto bad; + } else { + _exit(0); + } + } +#endif + return; bad: /* Forget all about it... */ @@ -4697,7 +4815,7 @@ data_source.sin_addr.s_addr = htonl(INADDR_ANY); #endif for (tries = 1;; tries++) { - if (bind(s, (struct sockaddr *) &data_source, + if (priv_bind(s, (struct sockaddr *) &data_source, sizeof(data_source)) >= 0) break; if (errno != EADDRINUSE || tries > 10) @@ -6925,7 +7043,9 @@ * flexibility here. :-( */ +#ifndef HAVE_LIBPRIVMAN #include +#endif /* Static variables used to communicate between the conversation function * and the server_login function */ @@ -6991,22 +7111,22 @@ * function within a server speaking this protocol, we can't be as * verbose as would otherwise make sense. */ -#define PAM_BAIL if (pam_error != PAM_SUCCESS) { pam_end(pamh, 0); return 0; } +#define PAM_BAIL if (pam_error != PAM_SUCCESS) { priv_pam_end(pamh, 0); return 0; } PAM_password = passwd; - pam_error = pam_start("ftp", user, &PAM_conversation, &pamh); - pam_set_item(pamh, PAM_RHOST, remotehost); + pam_error = priv_pam_start("ftp", user, &PAM_conversation, &pamh); + priv_pam_set_item(pamh, PAM_RHOST, remotehost); PAM_BAIL; - pam_error = pam_authenticate(pamh, 0); + pam_error = priv_pam_authenticate(pamh, 0); PAM_BAIL; - pam_error = pam_acct_mgmt(pamh, 0); + pam_error = priv_pam_acct_mgmt(pamh, 0); PAM_BAIL; #ifdef PAM_ESTABLISH_CRED - pam_error = pam_setcred(pamh, PAM_ESTABLISH_CRED); + pam_error = priv_pam_setcred(pamh, PAM_ESTABLISH_CRED); #else - pam_error = pam_setcred(pamh, PAM_CRED_ESTABLISH); + pam_error = priv_pam_setcred(pamh, PAM_CRED_ESTABLISH); #endif PAM_BAIL; - pam_end(pamh, PAM_SUCCESS); + priv_pam_end(pamh, PAM_SUCCESS); /* If this point is reached, the user has been authenticated. */ return 1; } @@ -7040,6 +7160,9 @@ /* Some of this is "borrowed" from inn - lots of it isn't */ +#ifdef HAVE_LIBPRIVMAN + priv_daemon(0, 1); +#else if (be_daemon == 2) { /* Fork - so I'm not the owner of the process group any more */ i = fork(); @@ -7061,9 +7184,10 @@ exit(1); } } +#endif if (!Bypass_PID_Files) - if ((pidfile = fopen(_PATH_FTPD_PID, "w"))) { + if ((pidfile = priv_fopen(_PATH_FTPD_PID, "w"))) { fprintf(pidfile, "%ld\n", (long) getpid()); fclose(pidfile); } @@ -7095,9 +7219,13 @@ #endif closelog(); + +#ifndef HAVE_LIBPRIVMAN + /* This would close the privman fd, so skipping it out of simplicity. */ for (i = 0; i <= fds; i++) { close(i); } +#endif #ifdef FACILITY openlog("ftpd", LOG_PID | LOG_NDELAY, FACILITY); #else @@ -7108,6 +7236,8 @@ (void) freopen(_PATH_DEVNULL, "w", stderr); } +#ifndef HAVE_LIBPRIVMAN + /* Not supported with privman yet. Yet. */ if (RootDirectory != NULL) { if ((chroot(RootDirectory) < 0) || (chdir("/") < 0)) { @@ -7117,6 +7247,7 @@ free(RootDirectory); RootDirectory = NULL; } +#endif if (!use_accessfile) syslog(LOG_WARNING, "FTP server started without ftpaccess file"); @@ -7149,7 +7280,7 @@ else server.sin_port = htons(daemon_port); - if (bind(lsock, (struct sockaddr *) &server, sizeof(server)) < 0) { + if (priv_bind(lsock, (struct sockaddr *) &server, sizeof(server)) < 0) { syslog(LOG_ERR, "Cannot bind socket: %m"); exit(1); } @@ -7173,7 +7304,7 @@ (void) setsockopt(msgsock, SOL_SOCKET, SO_KEEPALIVE, (char *) &one, sizeof(one)); /* Fork off a handler */ - pid = fork(); + pid = priv_fork(); if (pid < 0) { syslog(LOG_ERR, "failed to fork: %m"); sleep(1); Index: src/hostacc.c =================================================================== RCS file: /cvs/privman/privman/clients/wu-ftpd/src/hostacc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- src/hostacc.c 2002/07/10 20:12:30 1.1 +++ src/hostacc.c 2002/07/26 18:21:09 1.2 @@ -41,6 +41,12 @@ */ #include "config.h" +#ifdef HAVE_LIBPRIVMAN +#include +#else +#define priv_fopen(a,b) fopen((a),(b)) +#endif + #ifdef HOST_ACCESS #include "proto.h" @@ -153,7 +159,7 @@ iHaInd = 0; iFirstTim = 1; /* Open config file */ - if ((ptFp = fopen(_path_ftphosts, "r")) == NULL) { + if ((ptFp = priv_fopen(_path_ftphosts, "r")) == NULL) { if (errno == ENOENT) return (1); else { Index: src/logwtmp.c =================================================================== RCS file: /cvs/privman/privman/clients/wu-ftpd/src/logwtmp.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- src/logwtmp.c 2002/07/10 20:12:30 1.1 +++ src/logwtmp.c 2002/07/26 18:21:09 1.2 @@ -66,6 +66,15 @@ #include #endif +#ifdef HAVE_LIBPRIVMAN +#include +#else +#define priv_fopen(a,b) fopen((a),(b)) +#define priv_open(a,b,c) open((a),(b),(c)) +#endif + + + #include "pathnames.h" #include "proto.h" @@ -107,7 +116,7 @@ */ struct utmpx utx; - if (fdx < 0 && (fdx = open(WTMPX_FILE, O_WRONLY | O_APPEND, 0)) < 0) { + if (fdx < 0 && (fdx = priv_open(WTMPX_FILE, O_WRONLY | O_APPEND, 0)) < 0) { syslog(LOG_ERR, "wtmpx %s %m", WTMPX_FILE); return; } @@ -151,7 +160,7 @@ } #endif - if (fd < 0 && (fd = open(_PATH_WTMP, O_WRONLY | O_APPEND, 0)) < 0) { + if (fd < 0 && (fd = priv_open(_PATH_WTMP, O_WRONLY | O_APPEND, 0)) < 0) { syslog(LOG_ERR, "wtmp %s %m", _PATH_WTMP); return; } Index: src/paths.c =================================================================== RCS file: /cvs/privman/privman/clients/wu-ftpd/src/paths.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- src/paths.c 2002/07/10 20:12:30 1.1 +++ src/paths.c 2002/07/26 18:21:09 1.2 @@ -37,6 +37,14 @@ #include #include +#ifdef HAVE_LIBPRIVMAN +#include +#else +#define priv_fopen(p,m) fopen((p),(m)) +#define priv_open(p,m) open((p),(m)) +#endif + + #include "pathnames.h" #ifdef VIRTUAL @@ -145,7 +153,7 @@ ** exist then revert to using the standard _PATH_* path defines. */ - if ((svrfp = fopen(_PATH_FTPSERVERS, "r")) != NULL) { + if ((svrfp = priv_fopen(_PATH_FTPSERVERS, "r")) != NULL) { /* ** OK. The ftpservers file exists and is open. ** Index: src/proto.h =================================================================== RCS file: /cvs/privman/privman/clients/wu-ftpd/src/proto.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- src/proto.h 2002/07/10 20:12:30 1.1 +++ src/proto.h 2002/07/30 21:34:08 1.2 @@ -292,4 +292,4 @@ /* ** support/strcasestr.c */ -char *strcasestr(register char *s, register char *find); +char *strcasestr(const register char *s, const register char *find); Index: support/wuftp-privmanconf =================================================================== RCS file: wuftp-privmanconf diff -N wuftp-privmanconf --- /dev/null Fri Mar 23 23:37:44 2001 +++ /tmp/cvsqSdezO Wed Nov 13 11:33:44 2002 @@ -0,0 +1,38 @@ +# Privman configuration file for wuftpd. + +open_ro { + /etc/ftpaccess + /etc/ftpusers + /etc/ftpconversions + /etc/ftpgroups + /etc/ftpservers + /etc/ftphosts +} + +open_ao { + /var/log/wtmp + /var/log/xferlog +} + +open_rw { + /var/run/* +} + +bind { + ftp-data + ftp +} + +# users that don't need to authenticate with the system. +runas { + ftp +} + +allow_rerun true +# PAM authenticateion +auth true +# Allow any user that PAM authenticated to be a rerun target +auth_allow_rerun true + +fork true +