* 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];
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!");
/* 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));
}
/* 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;
}
/* 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);
* 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.
*/
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;
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");