OpenPKG CVS Repository
http://cvs.openpkg.org/
____________________________________________________________________________
Server: cvs.openpkg.org Name: Ralf S. Engelschall
Root: /v/openpkg/cvs Email: [EMAIL PROTECTED]
Module: openpkg-src Date: 19-Jan-2007 13:49:16
Branch: HEAD Handle: 2007011912491600
Modified files:
openpkg-src/proftpd proftpd.patch
Log:
do people a favor and backport the mod_auth_file fixes to 1.3.0a
(although I'm wondering why I'm spending my time on this)
Summary:
Revision Changes Path
1.21 +951 -1 openpkg-src/proftpd/proftpd.patch
____________________________________________________________________________
patch -p0 <<'@@ .'
Index: openpkg-src/proftpd/proftpd.patch
============================================================================
$ cvs diff -u -r1.20 -r1.21 proftpd.patch
--- openpkg-src/proftpd/proftpd.patch 19 Jan 2007 11:56:27 -0000 1.20
+++ openpkg-src/proftpd/proftpd.patch 19 Jan 2007 12:49:16 -0000 1.21
@@ -280,9 +280,15 @@
-----------------------------------------------------------------------------
-Fix for Endless Loop
+Fix Endless Looping.
(backported from
http://proftp.cvs.sourceforge.net/proftp/proftpd/src/auth.c?r1=1.46&r2=1.47)
+"Make sure that dispatch_auth() does not loop endlessly, if there are
+never any ERROR or HANDLED returns from the auth module handlers. Simply
+keep track of the starting table, and watch the iterator table; when the
+two match, we have looped through the auth handlers, and will assume
+that the entire auth command has been DECLINED."
+
Index: src/auth.c
--- src/auth.c.orig 2005-06-14 20:11:12 +0200
+++ src/auth.c 2007-01-19 10:38:19 +0100
@@ -329,3 +335,947 @@
return mr;
}
+
+-----------------------------------------------------------------------------
+
+Fix Incorrect AuthUserFile iteration.
+(backported from
http://proftp.cvs.sourceforge.net/proftp/proftpd/modules/mod_auth_file.?r1=1.27&r2=1.28)
+
+"Bug#2803 - mod_auth_file does not properly iterate through AuthUserFile
+entries. The issue was one of rewinding an already open AuthUserFile,
+every time pr_auth_getpwent() was called. The mod_auth_file module
+has been restructured to avoid this. The code was also substantially
+changed, removing a lot of dead code for a never-used feature (that of
+supporting multiple AuthUserFiles within the same server context)."
+
+Index: modules/mod_auth_file.c
+--- modules/mod_auth_file.c.orig 2005-07-03 20:52:02 +0200
++++ modules/mod_auth_file.c 2007-01-19 13:10:40 +0100
+@@ -52,15 +52,7 @@
+
+ } authfile_id_t;
+
+-typedef struct entry_rec {
+- struct entry_rec *next, *prev;
+- char *name;
+-
+-} authfile_entry_t;
+-
+ typedef struct file_rec {
+- struct file_rec *af_next;
+-
+ char *af_path;
+ FILE *af_file;
+
+@@ -84,15 +76,14 @@
+
+ } authfile_file_t;
+
+-static unsigned char af_handle_pw = FALSE, af_handle_gr = FALSE;
++/* List of server-specific Authiles */
++static authfile_file_t *af_user_file = NULL;
++static authfile_file_t *af_group_file = NULL;
++
++extern unsigned char persistent_passwd;
+
+-/* List of server-specific AuthUserFiles */
+-static authfile_file_t *af_user_file_list = NULL;
+-static authfile_file_t *af_current_user_file = NULL;
+-
+-/* List of server-specific AuthGroupFiles */
+-static authfile_file_t *af_group_file_list = NULL;
+-static authfile_file_t *af_current_group_file = NULL;
++static int af_setpwent(void);
++static int af_setgrent(void);
+
+ /* Support routines. Move the passwd/group functions out of lib/ into here.
+ */
+@@ -179,7 +170,8 @@
+ {
+ char *new_buf;
+
+- if ((new_buf = realloc(*buf, *buflen)) == NULL)
++ new_buf = realloc(*buf, *buflen);
++ if (new_buf == NULL)
+ break;
+
+ *buf = new_buf;
+@@ -228,13 +220,15 @@
+
+ sstrncpy(grpbuf, buf, i);
+
+- if ((cp = strrchr(grpbuf, '\n')))
++ cp = strrchr(grpbuf, '\n');
++ if (cp)
+ *cp = '\0';
+
+ for (cp = grpbuf, i = 0; i < NGRPFIELDS && cp; i++) {
+ grpfields[i] = cp;
+
+- if ((cp = strchr(cp, ':')))
++ cp = strchr(cp, ':');
++ if (cp)
+ *cp++ = 0;
+ }
+
+@@ -255,84 +249,76 @@
+ }
+ #endif /* !HAVE_FGETGRENT */
+
+-static unsigned char af_close_file(authfile_file_t *file) {
+- if (file && file->af_file) {
+- fclose(file->af_file);
+- file->af_file = NULL;
++static int af_allow_grent(struct group *grp) {
++ if (!af_group_file) {
++ errno = EPERM;
++ return -1;
+ }
+
+- return TRUE;
+-}
+-
+-static unsigned char af_open_file(authfile_file_t *file) {
+- if (file) {
+-
+- /* If already opened, rewind */
+- if (file->af_file)
+- rewind(file->af_file);
+-
+- else if ((file->af_file = fopen(file->af_path, "r")) == NULL)
+- return FALSE;
+-
+- return TRUE;
+- }
+-
+- return FALSE;
+-}
+-
+-static unsigned char af_allow_grent(authfile_file_t *groupf,
+- struct group *grp) {
+-
+ /* Check that the grent is within the ID restrictions (if present). */
+- if (groupf->af_restricted_ids) {
++ if (af_group_file->af_restricted_ids) {
+
+- if (grp->gr_gid < groupf->af_min_id.gid) {
++ if (grp->gr_gid < af_group_file->af_min_id.gid) {
+ pr_log_debug(DEBUG3, MOD_AUTH_FILE_VERSION ": skipping group '%s': "
+ "GID (%u) below the minimum allowed (%u)", grp->gr_name,
+- (unsigned int) grp->gr_gid, (unsigned int) groupf->af_min_id.gid);
+- return FALSE;
++ (unsigned int) grp->gr_gid,
++ (unsigned int) af_group_file->af_min_id.gid);
++ errno = EINVAL;
++ return -1;
+ }
+
+- if (grp->gr_gid > groupf->af_max_id.gid) {
++ if (grp->gr_gid > af_group_file->af_max_id.gid) {
+ pr_log_debug(DEBUG3, MOD_AUTH_FILE_VERSION ": skipping group '%s': "
+ "GID (%u) above the maximum allowed (%u)", grp->gr_name,
+- (unsigned int) grp->gr_gid, (unsigned int) groupf->af_max_id.gid);
+- return FALSE;
++ (unsigned int) grp->gr_gid,
++ (unsigned int) af_group_file->af_max_id.gid);
++ errno = EINVAL;
++ return -1;
+ }
+ }
+
+ #if defined(HAVE_REGEX_H) && defined(HAVE_REGCOMP)
+ /* Check if the grent has an acceptable name. */
+- if (groupf->af_restricted_names) {
+- int res = regexec(groupf->af_name_regex, grp->gr_name, 0, NULL, 0);
++ if (af_group_file->af_restricted_names) {
++ int res = regexec(af_group_file->af_name_regex, grp->gr_name, 0, NULL,
0);
+
+- if ((res != 0 && !groupf->af_name_regex_inverted) ||
+- (res == 0 && groupf->af_name_regex_inverted)) {
++ if ((res != 0 && !af_group_file->af_name_regex_inverted) ||
++ (res == 0 && af_group_file->af_name_regex_inverted)) {
+ pr_log_debug(DEBUG3, MOD_AUTH_FILE_VERSION ": skipping group '%s': "
+ "name '%s' does not meet allowed filter '%s'", grp->gr_name,
+- grp->gr_name, groupf->af_name_filter);
+- return FALSE;
++ grp->gr_name, af_group_file->af_name_filter);
++ errno = EINVAL;
++ return -1;
+ }
+ }
+ #endif /* !HAVE_REGEX_H and !HAVE_REGCOMP */
+
+- return TRUE;
++ return 0;
+ }
+
+ static void af_endgrent(void) {
+- af_close_file(af_current_group_file);
+- af_current_group_file = NULL;
++ if (af_group_file &&
++ af_group_file->af_file) {
++ fclose(af_group_file->af_file);
++ af_group_file->af_file = NULL;
++ }
+
+ return;
+ }
+
+-static struct group *af_getgrent(authfile_file_t *groupf) {
++static struct group *af_getgrent(void) {
+ struct group *grp = NULL;
+
++ if (!af_group_file ||
++ !af_group_file->af_file) {
++ errno = EINVAL;
++ return NULL;
++ }
++
+ while (TRUE) {
+ #ifdef HAVE_FGETGRENT
+ pr_signals_handle();
+- grp = fgetgrent(groupf->af_file);
++ grp = fgetgrent(af_group_file->af_file);
+ #else
+ char *cp = NULL, *buf = NULL;
+ int buflen = BUFSIZ;
+@@ -343,13 +329,14 @@
+ if (!buf)
+ return NULL;
+
+- while (af_getgrentline(&buf, &buflen, groupf->af_file) != NULL) {
++ while (af_getgrentline(&buf, &buflen, af_group_file->af_file) != NULL) {
+
+ /* Ignore comment and empty lines */
+ if (buf[0] == '\0' || buf[0] == '#')
+ continue;
+
+- if ((cp = strchr(buf, '\n')) != NULL)
++ cp = strchr(buf, '\n');
++ if (cp != NULL)
+ *cp = '\0';
+
+ grp = af_getgrp(buf);
+@@ -363,7 +350,7 @@
+ if (!grp)
+ break;
+
+- if (!af_allow_grent(groupf, grp))
++ if (af_allow_grent(grp) < 0)
+ continue;
+
+ break;
+@@ -372,129 +359,156 @@
+ return grp;
+ }
+
+-static struct group *af_getgrnam(authfile_file_t *groupf, const char *name)
{
++static struct group *af_getgrnam(const char *name) {
+ struct group *grp = NULL;
+
+- while ((grp = af_getgrent(groupf)) != NULL)
+- if (!strcmp(name, grp->gr_name))
++ if (af_setgrent() < 0)
++ return NULL;
++
++ while ((grp = af_getgrent()) != NULL) {
++ if (strcmp(name, grp->gr_name) == 0) {
+
+ /* Found the requested group */
+ break;
++ }
++ }
+
+ return grp;
+ }
+
+-static struct group *af_getgrgid(authfile_file_t *groupf, gid_t gid) {
++static struct group *af_getgrgid(gid_t gid) {
+ struct group *grp = NULL;
+
+- while ((grp = af_getgrent(groupf)) != NULL)
+- if (grp->gr_gid == gid)
++ if (af_setgrent() < 0)
++ return NULL;
++
++ while ((grp = af_getgrent()) != NULL) {
++ if (grp->gr_gid == gid) {
+
+ /* Found the requested GID */
+ break;
++ }
++ }
+
+ return grp;
+ }
+
+-static unsigned char af_setgrent(void) {
+-
+- /* If not already present, start at the top of the list. */
+- if (!af_current_group_file)
+- af_current_group_file = af_group_file_list;
++static int af_setgrent(void) {
+
+- while (af_current_group_file) {
++ if (af_group_file) {
++ if (af_group_file->af_file) {
++ /* If already opened, rewind */
++ rewind(af_group_file->af_file);
++ return 0;
+
+- if (!af_open_file(af_current_group_file)) {
+- /* Log the error */
+- pr_log_pri(PR_LOG_ERR, "error: unable to open group file '%s': %s",
+- af_current_group_file->af_path, strerror(errno));
++ } else {
++pr_log_debug(DEBUG0, MOD_AUTH_FILE_VERSION ": af_setgrent: opening
AuthGroupFile");
+
+- /* Move to the next file in the list. */
+- af_current_group_file = af_current_group_file->af_next;
+- continue;
++ af_group_file->af_file = fopen(af_group_file->af_path, "r");
++ if (af_group_file->af_file == NULL) {
++ pr_log_pri(PR_LOG_ERR, "error: unable to open group file '%s': %s",
++ af_group_file->af_path, strerror(errno));
++ return -1;
++ }
+
+- } else {
+ pr_log_debug(DEBUG7, MOD_AUTH_FILE_VERSION ": using group file '%s'",
+- af_current_group_file->af_path);
+- return TRUE;
++ af_group_file->af_path);
++ return 0;
+ }
+ }
+
+- return FALSE;
++ errno = EPERM;
++ return -1;
+ }
+
+-static unsigned char af_allow_pwent(authfile_file_t *passwdf,
+- struct passwd *pwd) {
++static int af_allow_pwent(struct passwd *pwd) {
++ if (!af_user_file) {
++ errno = EPERM;
++ return -1;
++ }
+
+ /* Check that the pwent is within the ID restrictions (if present). */
+- if (passwdf->af_restricted_ids) {
++ if (af_user_file->af_restricted_ids) {
+
+- if (pwd->pw_uid < passwdf->af_min_id.uid) {
++ if (pwd->pw_uid < af_user_file->af_min_id.uid) {
+ pr_log_debug(DEBUG3, MOD_AUTH_FILE_VERSION ": skipping user '%s': "
+ "UID (%u) below the minimum allowed (%u)", pwd->pw_name,
+- (unsigned int) pwd->pw_uid, (unsigned int) passwdf->af_min_id.uid);
+- return FALSE;
++ (unsigned int) pwd->pw_uid, (unsigned int)
af_user_file->af_min_id.uid);
++ errno = EINVAL;
++ return -1;
+ }
+
+- if (pwd->pw_uid > passwdf->af_max_id.gid) {
++ if (pwd->pw_uid > af_user_file->af_max_id.gid) {
+ pr_log_debug(DEBUG3, MOD_AUTH_FILE_VERSION ": skipping user '%s': "
+ "UID (%u) above the maximum allowed (%u)", pwd->pw_name,
+- (unsigned int) pwd->pw_uid, (unsigned int) passwdf->af_max_id.uid);
+- return FALSE;
++ (unsigned int) pwd->pw_uid, (unsigned int)
af_user_file->af_max_id.uid);
++ errno = EINVAL;
++ return -1;
+ }
+ }
+
+ #if defined(HAVE_REGEX_H) && defined(HAVE_REGCOMP)
+ /* Check if the pwent has an acceptable name. */
+- if (passwdf->af_restricted_names) {
+- int res = regexec(passwdf->af_name_regex, pwd->pw_name, 0, NULL, 0);
++ if (af_user_file->af_restricted_names) {
++ int res = regexec(af_user_file->af_name_regex, pwd->pw_name, 0, NULL,
0);
+
+- if ((res != 0 && !passwdf->af_name_regex_inverted) ||
+- (res == 0 && passwdf->af_name_regex_inverted)) {
++ if ((res != 0 && !af_user_file->af_name_regex_inverted) ||
++ (res == 0 && af_user_file->af_name_regex_inverted)) {
+ pr_log_debug(DEBUG3, MOD_AUTH_FILE_VERSION ": skipping user '%s': "
+ "name '%s' does not meet allowed filter '%s'", pwd->pw_name,
+- pwd->pw_name, passwdf->af_name_filter);
+- return FALSE;
++ pwd->pw_name, af_user_file->af_name_filter);
++ errno = EINVAL;
++ return -1;
+ }
+ }
+
+ /* Check if the pwent has an acceptable home directory. */
+- if (passwdf->af_restricted_homes) {
++ if (af_user_file->af_restricted_homes) {
+
+- int res = regexec(passwdf->af_home_regex, pwd->pw_dir, 0, NULL, 0);
++ int res = regexec(af_user_file->af_home_regex, pwd->pw_dir, 0, NULL, 0);
+
+- if ((res != 0 && !passwdf->af_home_regex_inverted) ||
+- (res == 0 && passwdf->af_home_regex_inverted)) {
++ if ((res != 0 && !af_user_file->af_home_regex_inverted) ||
++ (res == 0 && af_user_file->af_home_regex_inverted)) {
+ pr_log_debug(DEBUG3, MOD_AUTH_FILE_VERSION ": skipping user '%s': "
+ "home '%s' does not meet allowed filter '%s'", pwd->pw_name,
+- pwd->pw_dir, passwdf->af_home_filter);
+- return FALSE;
++ pwd->pw_dir, af_user_file->af_home_filter);
++ errno = EINVAL;
++ return -1;
+ }
+ }
+ #endif /* !HAVE_REGEX_H and !HAVE_REGCOMP */
+
+- return TRUE;
++ return 0;
+ }
+
+ static void af_endpwent(void) {
+- af_close_file(af_current_user_file);
+- af_current_user_file = NULL;
++ if (af_user_file &&
++ af_user_file->af_file) {
++ fclose(af_user_file->af_file);
++ af_user_file->af_file = NULL;
++ }
+
+ return;
+ }
+
+-static struct passwd *af_getpwent(authfile_file_t *passwdf) {
++static struct passwd *af_getpwent(void) {
+ struct passwd *pwd = NULL;
+
++ if (!af_user_file ||
++ !af_user_file->af_file) {
++ errno = EINVAL;
++ return NULL;
++ }
++
+ while (TRUE) {
+ #ifdef HAVE_FGETPWENT
+ pr_signals_handle();
+- pwd = fgetpwent(passwdf->af_file);
++ pwd = fgetpwent(af_user_file->af_file);
+ #else
+ char buf[BUFSIZ] = {'\0'};
+
+ pr_signals_handle();
+- while (fgets(buf, sizeof(buf), passwdf->af_file) != (char*) 0) {
++ while (fgets(buf, sizeof(buf), af_user_file->af_file) != (char*) 0) {
+ pr_signals_handle();
+
+ /* Ignore empty and comment lines */
+@@ -511,7 +525,7 @@
+ if (!pwd)
+ break;
+
+- if (!af_allow_pwent(passwdf, pwd))
++ if (af_allow_pwent(pwd) < 0)
+ continue;
+
+ break;
+@@ -520,88 +534,84 @@
+ return pwd;
+ }
+
+-static struct passwd *af_getpwnam(authfile_file_t *passwdf, const char
*name) {
++static struct passwd *af_getpwnam(const char *name) {
+ struct passwd *pwd = NULL;
+
+- while ((pwd = af_getpwent(passwdf)) != NULL)
+- if (!strcmp(name, pwd->pw_name))
++ if (af_setpwent() < 0)
++ return NULL;
++
++ while ((pwd = af_getpwent()) != NULL) {
++ if (strcmp(name, pwd->pw_name) == 0) {
+
+ /* Found the requested user */
+ break;
++ }
++ }
+
+ return pwd;
+ }
+
+-static char *af_getpwpass(authfile_file_t *passwdf, const char *name) {
+- struct passwd *pwd = af_getpwnam(passwdf, name);
+-
++static char *af_getpwpass(const char *name) {
++ struct passwd *pwd = af_getpwnam(name);
+ return pwd ? pwd->pw_passwd : NULL;
+ }
+
+-static struct passwd *af_getpwuid(authfile_file_t *passwdf, uid_t uid) {
++static struct passwd *af_getpwuid(uid_t uid) {
+ struct passwd *pwd = NULL;
+
+- while ((pwd = af_getpwent(passwdf)) != NULL)
+- if (pwd->pw_uid == uid)
++ if (af_setpwent() < 0)
++ return NULL;
++
++ while ((pwd = af_getpwent()) != NULL) {
++ if (pwd->pw_uid == uid) {
+
+ /* Found the requested UID */
+ break;
++ }
++ }
+
+ return pwd;
+ }
+
+-static unsigned char af_setpwent(void) {
++static int af_setpwent(void) {
+
+- /* If not already present, start at the top of the list. */
+- if (!af_current_user_file)
+- af_current_user_file = af_user_file_list;
+-
+- while (af_current_user_file) {
+-
+- if (!af_open_file(af_current_user_file)) {
+- /* Log the error */
+- pr_log_pri(PR_LOG_ERR, "error: unable to open passwd file '%s': %s",
+- af_current_user_file->af_path, strerror(errno));
+-
+- /* Move to the next file in the list. */
+- af_current_user_file = af_current_user_file->af_next;
+- continue;
++ if (af_user_file) {
++ if (af_user_file->af_file) {
++ /* If already opened, rewind */
++ rewind(af_user_file->af_file);
++ return 0;
+
+ } else {
++pr_log_debug(DEBUG0, MOD_AUTH_FILE_VERSION ": af_setpwent: opening
AuthUserFile '%s'", af_user_file->af_path);
++ af_user_file->af_file = fopen(af_user_file->af_path, "r");
++ if (af_user_file->af_file == NULL) {
++ pr_log_pri(PR_LOG_ERR, "error: unable to open passwd file '%s': %s",
++ af_user_file->af_path, strerror(errno));
++ return -1;
++ }
++
+ pr_log_debug(DEBUG7, MOD_AUTH_FILE_VERSION ": using passwd file '%s'",
+- af_current_user_file->af_path);
+- return TRUE;
++ af_user_file->af_path);
++ return 0;
+ }
+ }
+
+- return FALSE;
++ errno = EPERM;
++ return -1;
+ }
+
+ /* Authentication handlers.
+ */
+
+ MODRET authfile_endpwent(cmd_rec *cmd) {
+-
+- /* Do not handle *pw* requests unless we can do so. */
+- if (!af_handle_pw)
+- return DECLINED(cmd);
+-
+ af_endpwent();
+-
+ return DECLINED(cmd);
+ }
+
+ MODRET authfile_getpwent(cmd_rec *cmd) {
+ struct passwd *pwd = NULL;
+
+- /* Do not handle *pw* requests unless we can do so. */
+- if (!af_handle_pw)
+- return DECLINED(cmd);
+-
+- if (!af_setpwent())
+- return DECLINED(cmd);
+-
+- pwd = af_getpwent(af_current_user_file);
++ pwd = af_getpwent();
+
+ return pwd ? mod_create_data(cmd, pwd) : DECLINED(cmd);
+ }
+@@ -610,15 +620,11 @@
+ struct passwd *pwd = NULL;
+ const char *name = cmd->argv[0];
+
+- /* Do not handle *pw* requests unless we can do so. */
+- if (!af_handle_pw)
+- return DECLINED(cmd);
+-
+- if (!af_setpwent())
++ if (af_setpwent() < 0)
+ return DECLINED(cmd);
+
+ /* Ugly -- we iterate through the file. Time-consuming. */
+- while ((pwd = af_getpwent(af_current_user_file)) != NULL)
++ while ((pwd = af_getpwent()) != NULL)
+ if (!strcmp(name, pwd->pw_name))
+
+ /* Found the requested name */
+@@ -631,14 +637,10 @@
+ struct passwd *pwd = NULL;
+ uid_t uid = *((uid_t *) cmd->argv[0]);
+
+- /* Do not handle *pw* requests unless we can do so. */
+- if (!af_handle_pw)
+- return DECLINED(cmd);
+-
+- if (!af_setpwent())
++ if (af_setpwent() < 0)
+ return DECLINED(cmd);
+
+- pwd = af_getpwuid(af_current_user_file, uid);
++ pwd = af_getpwuid(uid);
+
+ return pwd ? mod_create_data(cmd, pwd) : DECLINED(cmd);
+ }
+@@ -646,70 +648,41 @@
+ MODRET authfile_name2uid(cmd_rec *cmd) {
+ struct passwd *pwd = NULL;
+
+- /* Do not handle *pw* requests unless we can do so. */
+- if (!af_handle_pw)
++ if (af_setpwent() < 0)
+ return DECLINED(cmd);
+
+- if (!af_setpwent())
+- return DECLINED(cmd);
+-
+- pwd = af_getpwnam(af_current_user_file, cmd->argv[0]);
++ pwd = af_getpwnam(cmd->argv[0]);
+
+ return pwd ? mod_create_data(cmd, (void *) &pwd->pw_uid) : DECLINED(cmd);
+ }
+
+ MODRET authfile_setpwent(cmd_rec *cmd) {
+-
+- /* Do not handle *pw* requests unless we can do so. */
+- if (!af_handle_pw)
+- return DECLINED(cmd);
+-
+- if (af_setpwent())
++ if (af_setpwent() == 0)
+ return DECLINED(cmd);
+
+- pr_log_debug(DEBUG2,
+- MOD_AUTH_FILE_VERSION ": unable to find useable AuthUserFile");
+-
+ return DECLINED(cmd);
+ }
+
+ MODRET authfile_uid2name(cmd_rec *cmd) {
+ struct passwd *pwd = NULL;
+
+- /* Do not handle *pw* requests unless we can do so. */
+- if (!af_handle_pw)
+- return DECLINED(cmd);
+-
+- if (!af_setpwent())
++ if (af_setpwent() < 0)
+ return DECLINED(cmd);
+
+- pwd = af_getpwuid(af_current_user_file, *((uid_t *) cmd->argv[0]));
++ pwd = af_getpwuid(*((uid_t *) cmd->argv[0]));
+
+ return pwd ? mod_create_data(cmd, pwd->pw_name) : DECLINED(cmd);
+ }
+
+ MODRET authfile_endgrent(cmd_rec *cmd) {
+-
+- /* Do not handle *gr* requests unless we can do so. */
+- if (!af_handle_gr)
+- return DECLINED(cmd);
+-
+ af_endgrent();
+-
+ return DECLINED(cmd);
+ }
+
+ MODRET authfile_getgrent(cmd_rec *cmd) {
+ struct group *grp = NULL;
+
+- /* Do not handle *gr* requests unless we can do so. */
+- if (!af_handle_gr)
+- return DECLINED(cmd);
+-
+- if (!af_setgrent())
+- return DECLINED(cmd);
+-
+- grp = af_getgrent(af_current_group_file);
++ grp = af_getgrent();
+
+ return grp ? mod_create_data(cmd, grp) : DECLINED(cmd);
+ }
+@@ -718,14 +691,10 @@
+ struct group *grp = NULL;
+ gid_t gid = *((gid_t *) cmd->argv[0]);
+
+- /* Do not handle *gr* requests unless we can do so. */
+- if (!af_handle_gr)
++ if (af_setgrent() < 0)
+ return DECLINED(cmd);
+
+- if (!af_setgrent())
+- return DECLINED(cmd);
+-
+- grp = af_getgrgid(af_current_group_file, gid);
++ grp = af_getgrgid(gid);
+
+ return grp ? mod_create_data(cmd, grp) : DECLINED(cmd);
+ }
+@@ -734,14 +703,10 @@
+ struct group *grp = NULL;
+ const char *name = cmd->argv[0];
+
+- /* Do not handle *gr* requests unless we can do so. */
+- if (!af_handle_gr)
+- return DECLINED(cmd);
+-
+- if (!af_setgrent())
++ if (af_setgrent() < 0)
+ return DECLINED(cmd);
+
+- while ((grp = af_getgrent(af_current_group_file)) != NULL)
++ while ((grp = af_getgrent()) != NULL)
+ if (!strcmp(name, grp->gr_name))
+
+ /* Found the name requested */
+@@ -756,14 +721,10 @@
+ array_header *gids = NULL, *groups = NULL;
+ char *name = cmd->argv[0];
+
+- /* Do not handle *gr* requests unless we can do so. */
+- if (!af_handle_gr)
++ if (af_setpwent() < 0)
+ return DECLINED(cmd);
+
+- if (!af_setpwent())
+- return DECLINED(cmd);
+-
+- if (!af_setgrent())
++ if (af_setgrent() < 0)
+ return DECLINED(cmd);
+
+ /* Check for NULLs */
+@@ -774,7 +735,7 @@
+ groups = (array_header *) cmd->argv[2];
+
+ /* Retrieve the necessary info. */
+- if (!name || !(pwd = af_getpwnam(af_current_user_file, name)))
++ if (!name || !(pwd = af_getpwnam(name)))
+ return mod_create_error(cmd, -1);
+
+ /* Populate the first group ID and name. */
+@@ -782,25 +743,15 @@
+ *((gid_t *) push_array(gids)) = pwd->pw_gid;
+
+ if (groups &&
+- (grp = af_getgrgid(af_current_group_file, pwd->pw_gid)) != NULL)
++ (grp = af_getgrgid(pwd->pw_gid)) != NULL)
+ *((char **) push_array(groups)) = pstrdup(session.pool, grp->gr_name);
+
+- /* The above call to af_getgrgid() will position the file pointer in
+- * the AuthGroupFile just after the group with the primary GID.
+- * Subsequently, the below af_getgrent() starts from that position, and
+- * goes to the end of the file. The problem is that there may be groups
+- * before the primary GID for the current group. So, ideally, the
+- * getgrent() loop would continue until we're back to where we are now,
+- * rather than stopping at the end of the file. Conversely, we could
+- * just simply rewind to the start of the AuthGroupFile (which is easier).
+- * The core auth code will remove duplicate IDs as needed.
+- */
+- af_open_file(af_current_group_file);
++ af_setgrent();
+
+ /* This is where things get slow, expensive, and ugly. Loop through
+ * everything, checking to make sure we haven't already added it.
+ */
+- while ((grp = af_getgrent(af_current_group_file)) != NULL &&
++ while ((grp = af_getgrent()) != NULL &&
+ grp->gr_mem) {
+ char **gr_mems = NULL;
+
+@@ -832,14 +783,10 @@
+ MODRET authfile_gid2name(cmd_rec *cmd) {
+ struct group *grp = NULL;
+
+- /* Do not handle *gr* requests unless we can do so. */
+- if (!af_handle_gr)
++ if (af_setgrent() < 0)
+ return DECLINED(cmd);
+
+- if (!af_setgrent())
+- return DECLINED(cmd);
+-
+- grp = af_getgrgid(af_current_group_file, *((gid_t *) cmd->argv[0]));
++ grp = af_getgrgid(*((gid_t *) cmd->argv[0]));
+
+ return grp ? mod_create_data(cmd, grp->gr_name) : DECLINED(cmd);
+ }
+@@ -847,30 +794,18 @@
+ MODRET authfile_name2gid(cmd_rec *cmd) {
+ struct group *grp = NULL;
+
+- /* Do not handle *gr* requests unless we can do so. */
+- if (!af_handle_gr)
+- return DECLINED(cmd);
+-
+- if (!af_setgrent())
++ if (af_setgrent() < 0)
+ return DECLINED(cmd);
+
+- grp = af_getgrnam(af_current_group_file, cmd->argv[0]);
++ grp = af_getgrnam(cmd->argv[0]);
+
+ return grp ? mod_create_data(cmd, (void *) &grp->gr_gid) : DECLINED(cmd);
+ }
+
+ MODRET authfile_setgrent(cmd_rec *cmd) {
+-
+- /* Do not handle *gr* requests unless we can do so. */
+- if (!af_handle_gr)
+- return DECLINED(cmd);
+-
+- if (af_setgrent())
++ if (af_setgrent() == 0)
+ return DECLINED(cmd);
+
+- pr_log_debug(DEBUG2,
+- MOD_AUTH_FILE_VERSION ": unable to find useable AuthGroupFile");
+-
+ return DECLINED(cmd);
+ }
+
+@@ -879,15 +814,11 @@
+ char *tmp = NULL, *cleartxt_pass = NULL;
+ const char *name = cmd->argv[0];
+
+- /* Do not handle *pw* requests unless we can do so. */
+- if (!af_handle_pw)
+- return DECLINED(cmd);
+-
+- if (!af_setpwent())
++ if (af_setpwent() < 0)
+ return DECLINED(cmd);
+
+ /* Lookup the cleartxt password for this user. */
+- if ((tmp = af_getpwpass(af_current_user_file, name)) == NULL) {
++ if ((tmp = af_getpwpass(name)) == NULL) {
+
+ /* For now, return DECLINED. Ideally, we could stash an auth module
+ * identifier in the session structure, so that all auth modules could
+@@ -923,8 +854,12 @@
+ const char *ciphertxt_pass = cmd->argv[0];
+ const char *cleartxt_pass = cmd->argv[2];
+
+- /* Do not handle *pw* requests unless we can do so. */
+- if (!af_handle_pw)
++ /* Even though the AuthUserFile is not used here, there must be one
++ * configured before this function should attempt to check the password.
++ * Otherwise, it could be checking a password retrieved by some other
++ * auth module.
++ */
++ if (!af_user_file)
+ return DECLINED(cmd);
+
+ if (strcmp(crypt(cleartxt_pass, ciphertxt_pass), ciphertxt_pass) == 0) {
+@@ -938,13 +873,6 @@
+ /* Configuration handlers
+ */
+
+-/* NOTE: support multiple AuthUserFiles, AuthGroupFiles. Have optional
+- * parameter to restrict ID range in files, min and max, where max >= min.
+- *
+- * Future rev: incorporate AuthShadowFile into this, and add --shadow
+- * capabilities to ftpasswd.
+- */
+-
+ /* usage: AuthGroupFile path [id <min-max>] [name <regex>] */
+ MODRET set_authgroupfile(cmd_rec *cmd) {
+ config_rec *c = NULL;
+@@ -1180,54 +1108,18 @@
+ static int authfile_sess_init(void) {
+ config_rec *c = NULL;
+
+- af_user_file_list = af_group_file_list = NULL;
+-
+- /* Search for all relevant AuthUserFiles for this server. */
+ c = find_config(main_server->conf, CONF_PARAM, "AuthUserFile", FALSE);
+-
+- while (c) {
+- authfile_file_t *file = c->argv[0];
+-
+-/* NOTE: This is a hack, to prevent these config_recs from being handled by
+- * mod_unixpw. Only necessary until mod_unixpw is transformed into
+- * mod_auth_unix.
+- */
+-c->name = "";
+-
+- if (!af_user_file_list) {
+- file->af_next = af_user_file_list;
+- af_user_file_list = file;
+- }
+-
+- c = find_config_next(c, c->next, CONF_PARAM, "AuthUserFile", FALSE);
++ if (c) {
++ af_user_file = c->argv[0];
++ pr_log_debug(DEBUG0, MOD_AUTH_FILE_VERSION ": found AuthUserFile '%s'",
af_user_file->af_path);
+ }
+
+- /* Search for all relevant AuthGroupFiles for this server. */
+- c = find_config(main_server->conf, CONF_PARAM, "AuthGroupFile", FALSE);
+-
+- while (c) {
+- authfile_file_t *file = c->argv[0];
+-
+-/* NOTE: This is a hack, to prevent these config_recs from being handled by
+- * mod_unixpw. Only necessary until mod_unixpw is transformed into
+- * mod_auth_unix.
+- */
+-c->name = "";
+-
+- if (!af_group_file_list) {
+- file->af_next = af_group_file_list;
+- af_group_file_list = file;
+- }
+-
+- c = find_config_next(c, c->next, CONF_PARAM, "AuthGroupFile", FALSE);
++ c = find_config_next(c, c->next, CONF_PARAM, "AuthGroupFile", FALSE);
++ if (c) {
++ af_group_file = c->argv[0];
++ pr_log_debug(DEBUG0, MOD_AUTH_FILE_VERSION ": found AuthGroupFile
'%s'", af_group_file->af_path);
+ }
+
+- if (af_user_file_list)
+- af_handle_pw = TRUE;
+-
+- if (af_group_file_list)
+- af_handle_gr = TRUE;
+-
+ return 0;
+ }
+
+@@ -1291,6 +1183,9 @@
+ NULL,
+
+ /* Session initialization function */
+- authfile_sess_init
++ authfile_sess_init,
++
++ /* Module version */
++ MOD_AUTH_FILE_VERSION
+ };
+
@@ .
______________________________________________________________________
OpenPKG http://openpkg.org
CVS Repository Commit List [email protected]