summaryrefslogtreecommitdiff
path: root/source/smbd/service.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/smbd/service.c')
-rw-r--r--source/smbd/service.c100
1 files changed, 72 insertions, 28 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);
}