summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>1999-07-14 18:55:59 +0000
committerJeremy Allison <jra@samba.org>1999-07-14 18:55:59 +0000
commit51604c6161ab9efb46ce9fb278924e42bcb505e3 (patch)
tree0ff4dacbd8872c63a2694037cd1c43975561a6b5
parentffc9e0e2d22be19abb60fb24a904b5a25ac21481 (diff)
downloadsamba-51604c6161ab9efb46ce9fb278924e42bcb505e3.tar.gz
force_group and force_user fixes. Added '+' element to force_group.
Jeremy.
-rw-r--r--source/smbd/service.c100
-rw-r--r--source/smbd/uid.c36
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)) {