Allow for specifying the path to the group file. Make use of
authorhartwick <hartwick>
Mon, 1 Oct 2001 18:22:51 +0000 (18:22 +0000)
committerhartwick <hartwick>
Mon, 1 Oct 2001 18:22:51 +0000 (18:22 +0000)
fgetpwnam() and fgetgrnam() which is suboptimal, but is only used
when not running with the cache enabled.

Update the unix_buildpwcache() function to take the group_file as
an argument and cache based on that.

src/modules/rlm_unix/cache.c
src/modules/rlm_unix/cache.h
src/modules/rlm_unix/rlm_unix.c

index c2b6fb1..7e3eea6 100644 (file)
@@ -69,12 +69,14 @@ static int hashUserName(const char *s);
  * in memory.  Returns NULL on failure, pointer to the cache on success.
  */
 struct pwcache *unix_buildpwcache(const char *passwd_file,
-                                  const char *shadow_file)
+                                  const char *shadow_file,
+                                  const char *group_file)
 {
        FILE *passwd;
 #if HAVE_SHADOW_H
        FILE *shadow;
 #endif
+       FILE *group;
        char buffer[BUFSIZE];
        char idtmp[10];
        char username[256];
@@ -94,6 +96,11 @@ struct pwcache *unix_buildpwcache(const char *passwd_file,
                return NULL;
        }
 
+       if (!group_file) {
+               radlog(L_ERR, "rlm_unix:  You MUST specify a group file!");
+               return NULL;
+       }
+
 #if HAVE_SHADOW_H
        if (!shadow_file) {
                radlog(L_ERR, "rlm_unix:  You MUST specify a shadow password file!");
@@ -278,22 +285,25 @@ struct pwcache *unix_buildpwcache(const char *passwd_file,
        /* log how many entries we stored from the passwd file */
        radlog(L_INFO, "HASH:  Stored %d entries from %s", numread, passwd_file);
 
-       /* The remainder of this function caches the /etc/group file, so it's
-        * one less thing we have to lookup on disk.  it uses getgrent(),
-        * which is quite slow, but the group file is generally small enough
-        * that it won't matter
+       /* The remainder of this function caches the /etc/group or equivalent
+        * file, so it's one less thing we have to lookup on disk.  it uses
+        * fgetgrent(), which is quite slow, but the group file is generally
+        * small enough that it won't matter
         * As a side note, caching the user list per group was a major pain
         * in the ass, and I won't even need it.  I really hope that somebody
         * out there needs and appreciates it.
         */
 
-       /* Make sure to begin at beginning */
-       setgrent();
-
+       if ((group = fopen(group_file, "r")) == NULL) {
+               radlog(L_ERR, "rlm_unix:  Can't open file group file %s: %s",
+                   group_file, strerror(errno));
+               unix_freepwcache(cache);
+               return NULL;
+       }
        numread = 0;
 
        /* Get next entry from the group file */
-       while((grp = getgrent()) != NULL) {
+       while((grp = fgetgrent(group)) != NULL) {
 
                /* Make new mygroup structure in mem */
                g_new = (struct mygroup *)rad_malloc(sizeof(struct mygroup));
@@ -338,9 +348,9 @@ struct pwcache *unix_buildpwcache(const char *passwd_file,
        }
 
        /* End */
-       endgrent();
+       fclose(group);
 
-       radlog(L_INFO, "HASH:  Stored %d entries from /etc/group", numread);
+       radlog(L_INFO, "HASH:  Stored %d entries from %s", numread, group_file);
 
        return cache;
 }
index 46766ec..0feb04d 100644 (file)
@@ -36,7 +36,8 @@ struct pwcache {
 
 /* Function prototypes */
 struct pwcache *unix_buildpwcache(const char *passwd_file,
-                                  const char *shadow_file);
+                                  const char *shadow_file,
+                                  const char *group_file);
 int H_unix_pass(struct pwcache *cache, char *name, char *passwd,
                 VALUE_PAIR **reply_items);
 int H_groupcmp(struct pwcache *cache, VALUE_PAIR *check, char *username);
index 1f3bdbe..00c352d 100644 (file)
@@ -107,6 +107,37 @@ static struct unix_instance *group_inst;
  * file) or not ("Group=" was bound to the first instance of rlm_unix */
 static int group_inst_explicit;
 
+struct passwd *fgetpwnam(const char *fname, const char *name) {
+       FILE            *file = fopen(fname, "ro");
+       struct passwd   *pwd = NULL;
+
+       if(file == NULL) return NULL;
+       do {
+               pwd = fgetpwent(file);
+               if(pwd == NULL) {
+                       fclose(file);
+                       return NULL;
+               }
+       } while(strcmp(name, pwd->pw_name) != 0);
+       fclose(file);
+       return pwd;
+}
+
+struct passwd *fgetgrnam(const char *fname, const char *name) {
+       FILE            *file = fopen(fname, "ro");
+       struct group    *grp = NULL;
+       if(file == NULL) return NULL;
+       do {
+               grp = fgetgrent(file);
+               if(grp == NULL) {
+                       fclose(file);
+                       return NULL;
+               }
+       } while(strcmp(name, grp->gr_name) != 0);
+       fclose(file);
+       return grp;
+}
+
 /*
  *     The Group = handler.
  */
@@ -128,16 +159,18 @@ static int groupcmp(void *instance, VALUE_PAIR *request, VALUE_PAIR *check,
                return 1;
        }
 
+       radlog(L_ERR, "group = %s", group_inst->group_file);
+
        username = (char *)request->strvalue;
 
        if (group_inst->cache_passwd &&
            (retval = H_groupcmp(group_inst->cache, check, username)) != -2)
                return retval;
 
-       if ((pwd = getpwnam(username)) == NULL)
+       if ((pwd = fgetpwnam(group_inst->passwd_file, username)) == NULL)
                return -1;
 
-       if ((grp = getgrnam((char *)check->strvalue)) == NULL)
+       if ((grp = fgetgrnam(group_inst->group_file, (char *)check->strvalue)) == NULL)
                return -1;
 
        retval = (pwd->pw_gid == grp->gr_gid) ? 0 : -1;
@@ -187,7 +220,8 @@ static int unix_instantiate(CONF_SECTION *conf, void **instance)
                radlog(L_INFO, "HASH:  Reinitializing hash structures "
                        "and lists for caching...");
                if ((inst->cache = unix_buildpwcache(inst->passwd_file,
-                                                    inst->shadow_file))==NULL)
+                                                    inst->shadow_file,
+                                                    inst->group_file))==NULL)
                 {
                        radlog(L_ERR, "HASH:  unable to create user "
                                "hash table.  disable caching and run debugs");