summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/smbd/password.c53
1 files changed, 45 insertions, 8 deletions
diff --git a/source3/smbd/password.c b/source3/smbd/password.c
index ca588c6681..e7f7f2c039 100644
--- a/source3/smbd/password.c
+++ b/source3/smbd/password.c
@@ -618,24 +618,61 @@ static char *validate_group(char *group,char *password,int pwlen,int snum)
#ifdef HAVE_GETGRENT
{
struct group *gptr;
- char **member;
setgrent();
while ((gptr = (struct group *)getgrent())) {
- if (!strequal(gptr->gr_name,group))
- continue;
- member = gptr->gr_mem;
- while (member && *member) {
+ if (strequal(gptr->gr_name,group))
+ break;
+ }
+
+ /*
+ * As user_ok can recurse doing a getgrent(), we must
+ * copy the member list into a pstring on the stack before
+ * use. Bug pointed out by leon@eatworms.swmed.edu.
+ */
+
+ if (gptr) {
+ pstring member_list;
+ char *member;
+ size_t copied_len = 0;
+ int i;
+
+ *member_list = '\0';
+ member = member_list;
+
+ for(i = 0; gptr->gr_mem && gptr->gr_mem[i]; i++) {
+ size_t member_len = strlen(gptr->gr_mem[i]) + 1;
+ if( copied_len + member_len < sizeof(pstring)) {
+
+ DEBUG(10,("validate_group: = gr_mem = %s\n", gptr->gr_mem[i]));
+
+ safe_strcpy(member, gptr->gr_mem[i], sizeof(pstring) - copied_len - 1);
+ copied_len += member_len;
+ member += copied_len;
+ } else {
+ *member = '\0';
+ }
+ }
+
+ endgrent();
+
+ member = member_list;
+ while (*member) {
static fstring name;
- fstrcpy(name,*member);
+ fstrcpy(name,member);
if (user_ok(name,snum) &&
password_ok(name,password,pwlen,NULL)) {
endgrent();
return(&name[0]);
}
- member++;
+
+ DEBUG(10,("validate_group = member = %s\n", member));
+
+ member += strlen(member) + 1;
}
+ } else {
+ endgrent();
+ return NULL;
}
- endgrent();
}
#endif
return(NULL);