diff options
author | Jeremy Allison <jra@samba.org> | 1999-07-14 18:55:59 +0000 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 1999-07-14 18:55:59 +0000 |
commit | 51604c6161ab9efb46ce9fb278924e42bcb505e3 (patch) | |
tree | 0ff4dacbd8872c63a2694037cd1c43975561a6b5 | |
parent | ffc9e0e2d22be19abb60fb24a904b5a25ac21481 (diff) | |
download | samba-51604c6161ab9efb46ce9fb278924e42bcb505e3.tar.gz |
force_group and force_user fixes. Added '+' element to force_group.
Jeremy.
-rw-r--r-- | source/smbd/service.c | 100 | ||||
-rw-r--r-- | source/smbd/uid.c | 36 |
2 files changed, 103 insertions, 33 deletions
diff --git a/source/smbd/service.c b/source/smbd/service.c index da6cfc7d40f..2c9fad8ac22 100644 --- a/source/smbd/service.c +++ b/source/smbd/service.c @@ -339,24 +339,11 @@ connection_struct *make_connection(char *service,char *user,char *password, int string_set(&conn->dirpath,""); string_set(&conn->user,user); -#ifdef HAVE_GETGRNAM - if (*lp_force_group(snum)) { - struct group *gptr; - pstring gname; - - StrnCpy(gname,lp_force_group(snum),sizeof(pstring)-1); - /* default service may be a group name */ - string_sub(gname,"%S",service); - gptr = (struct group *)getgrnam(gname); - - if (gptr) { - conn->gid = gptr->gr_gid; - DEBUG(3,("Forced group %s\n",gname)); - } else { - DEBUG(1,("Couldn't find group %s\n",gname)); - } - } -#endif + /* + * If force user is true, then store the + * given userid and also the primary groupid + * of the user we're forcing. + */ if (*lp_force_user(snum)) { struct passwd *pass2; @@ -369,6 +356,7 @@ connection_struct *make_connection(char *service,char *user,char *password, int pass2 = (struct passwd *)Get_Pwnam(fuser,True); if (pass2) { conn->uid = pass2->pw_uid; + conn->gid = pass2->pw_gid; string_set(&conn->user,fuser); fstrcpy(user,fuser); conn->force_user = True; @@ -378,6 +366,57 @@ connection_struct *make_connection(char *service,char *user,char *password, int } } +#ifdef HAVE_GETGRNAM + /* + * If force group is true, then override + * any groupid stored for the connecting user. + */ + + if (*lp_force_group(snum)) { + struct group *gptr; + pstring gname; + pstring tmp_gname; + BOOL user_must_be_member = False; + + StrnCpy(tmp_gname,lp_force_group(snum),sizeof(pstring)-1); + + if (tmp_gname[0] == '+') { + user_must_be_member = True; + StrnCpy(gname,&tmp_gname[1],sizeof(pstring)-2); + } else { + StrnCpy(gname,tmp_gname,sizeof(pstring)-1); + } + /* default service may be a group name */ + string_sub(gname,"%S",service); + gptr = (struct group *)getgrnam(gname); + + if (gptr) { + /* + * If the user has been forced and the forced group starts + * with a '+', then we only set the group to be the forced + * group if the forced user is a member of that group. + * Otherwise, the meaning of the '+' would be ignored. + */ + if (conn->force_user && user_must_be_member) { + int i; + for (i = 0; gptr->gr_mem[i] != NULL; i++) { + if (strcmp(user,gptr->gr_mem[i]) == 0) { + conn->gid = gptr->gr_gid; + DEBUG(3,("Forced group %s for member %s\n",gname,user)); + break; + } + } + } + else { + conn->gid = gptr->gr_gid; + } + DEBUG(3,("Forced group %s\n",gname)); + } else { + DEBUG(1,("Couldn't find group %s\n",gname)); + } + } +#endif /* HAVE_GETGRNAM */ + { pstring s; pstrcpy(s,lp_pathname(snum)); @@ -474,6 +513,21 @@ connection_struct *make_connection(char *service,char *user,char *password, int standard_sub(conn,cmd); smbrun(cmd,NULL,False); } + + /* + * Print out the 'connected as' stuff here as we need + * to know the effective uid and gid we will be using. + */ + + if( DEBUGLVL( IS_IPC(conn) ? 3 : 1 ) ) { + extern int Client; + + dbgtext( "%s (%s) ", remote_machine, client_addr(Client) ); + dbgtext( "connect to service %s ", lp_servicename(SNUM(conn)) ); + dbgtext( "as user %s ", user ); + dbgtext( "(uid=%d, gid=%d) ", (int)geteuid(), (int)getegid() ); + dbgtext( "(pid %d)\n", (int)getpid() ); + } /* we've finished with the sensitive stuff */ unbecome_user(); @@ -485,16 +539,6 @@ connection_struct *make_connection(char *service,char *user,char *password, int set_namearray( &conn->veto_oplock_list, lp_veto_oplocks(SNUM(conn))); } - if( DEBUGLVL( IS_IPC(conn) ? 3 : 1 ) ) { - extern int Client; - - dbgtext( "%s (%s) ", remote_machine, client_addr(Client) ); - dbgtext( "connect to service %s ", lp_servicename(SNUM(conn)) ); - dbgtext( "as user %s ", user ); - dbgtext( "(uid=%d, gid=%d) ", (int)conn->uid, (int)conn->gid ); - dbgtext( "(pid %d)\n", (int)getpid() ); - } - return(conn); } diff --git a/source/smbd/uid.c b/source/smbd/uid.c index 8eb9c4a5a1d..73d46096468 100644 --- a/source/smbd/uid.c +++ b/source/smbd/uid.c @@ -186,6 +186,7 @@ BOOL become_user(connection_struct *conn, uint16 vuid) int snum; gid_t gid; uid_t uid; + char group_c; if (!conn) { DEBUG(2,("Connection not open\n")); @@ -230,16 +231,41 @@ BOOL become_user(connection_struct *conn, uint16 vuid) return(False); } uid = vuser->uid; - if(!*lp_force_group(snum)) { - gid = vuser->gid; + gid = vuser->gid; + current_user.ngroups = vuser->n_groups; + current_user.groups = vuser->groups; + } + + /* + * See if we should force group for this service. + * If so this overrides any group set in the force + * user code. + */ + + if((group_c = *lp_force_group(snum))) { + if(group_c == '+') { + + /* + * Only force group if the user is a member of + * the service group. Check the group memberships for + * this user (we already have this) to + * see if we should force the group. + */ + + int i; + for (i = 0; i < current_user.ngroups; i++) { + if (current_user.groups[i] == conn->gid) { + gid = conn->gid; + break; + } + } } else { gid = conn->gid; } - current_user.ngroups = vuser->n_groups; - current_user.groups = vuser->groups; } - if (!become_gid(gid)) return(False); + if (!become_gid(gid)) + return(False); #ifdef HAVE_SETGROUPS if (!(conn && conn->ipc)) { |