summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/password.c113
-rw-r--r--source3/smbd/process.c3
-rw-r--r--source3/smbd/sec_ctx.c34
-rw-r--r--source3/smbd/service.c4
-rw-r--r--source3/smbd/uid.c23
-rw-r--r--source3/smbd/unix_acls.c8
6 files changed, 91 insertions, 94 deletions
diff --git a/source3/smbd/password.c b/source3/smbd/password.c
index f9291b8705..0372e7a0f9 100644
--- a/source3/smbd/password.c
+++ b/source3/smbd/password.c
@@ -113,6 +113,16 @@ user_struct *get_valid_user_struct(uint16 vuid)
}
/****************************************************************************
+ Delete the SID list for this user.
+****************************************************************************/
+
+static void delete_nt_token(NT_USER_TOKEN *token)
+{
+ safe_free( token->user_sids );
+ ZERO_STRUCTP(token);
+}
+
+/****************************************************************************
invalidate a uid
****************************************************************************/
void invalidate_vuid(uint16 vuid)
@@ -133,8 +143,7 @@ void invalidate_vuid(uint16 vuid)
vuser->groups = NULL;
- if (vuser->group_sids != NULL)
- free (vuser->group_sids);
+ delete_nt_token(&vuser->nt_user_token);
}
@@ -162,61 +171,54 @@ char *validated_domain(uint16 vuid)
/****************************************************************************
-Setup the groups a user belongs to.
+ Initialize the groups a user belongs to.
****************************************************************************/
-int setup_groups(char *user, char *domain,
- uid_t uid, gid_t gid, int *p_ngroups, gid_t **p_groups)
-{
- int i,ngroups;
- gid_t grp = 0;
- gid_t *groups = NULL;
- if (-1 == initgroups(user,gid))
- {
+int initialize_groups(char *user, uid_t uid, gid_t gid)
+{
+ if (initgroups(user,gid) == -1) {
DEBUG(0,("Unable to initgroups. Error was %s\n", strerror(errno) ));
- if (getuid() == 0)
- {
- if (gid < 0 || gid > 32767 || uid < 0 || uid > 32767)
- {
+ if (getuid() == 0) {
+ if (gid < 0 || gid > 32767 || uid < 0 || uid > 32767) {
DEBUG(0,("This is probably a problem with the account %s\n", user));
}
}
return -1;
}
+ return 0;
+}
- ngroups = sys_getgroups(0,&grp);
- if (ngroups <= 0)
- {
- ngroups = groups_max();
- }
+/****************************************************************************
+ Create the SID list for this user.
+****************************************************************************/
- if((groups = (gid_t *)malloc(sizeof(gid_t)*ngroups)) == NULL)
- {
- DEBUG(0,("setup_groups malloc fail !\n"));
- return -1;
- }
+void setup_nt_token(NT_USER_TOKEN *token, uid_t uid, gid_t gid, int ngroups, gid_t *groups)
+{
+ DOM_SID *psids;
+ int i;
- ngroups = sys_getgroups(ngroups,groups);
+ ZERO_STRUCTP(token);
- (*p_ngroups) = ngroups;
- (*p_groups) = groups;
+ if ((token->user_sids = (DOM_SID *)malloc( (ngroups + 2)*sizeof(DOM_SID))) == NULL)
+ return;
- DEBUG( 3, ( "%s is in %d groups: ", user, ngroups ) );
- for (i = 0; i < ngroups; i++ )
- {
- DEBUG( 3, ( "%s%d", (i ? ", " : ""), (int)groups[i] ) );
- }
- DEBUG( 3, ( "\n" ) );
+ psids = token->user_sids;
- return 0;
-}
+ token->num_sids = ngroups + 2;
+
+ uid_to_sid( &psids[0], uid);
+ gid_to_sid( &psids[1], gid);
+ for (i = 0; i < ngroups; i++)
+ gid_to_sid( &psids[i+2], groups[i]);
+}
/****************************************************************************
register a uid/name pair as being valid and that a valid password
has been given. vuid is biased by an offset. This allows us to
tell random client vuid's (normally zero) from valid vuids.
****************************************************************************/
+
uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name,
char *domain,BOOL guest)
{
@@ -227,37 +229,15 @@ uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name,
if(lp_security() == SEC_SHARE)
return UID_FIELD_INVALID;
-#if 0
- /*
- * After observing MS-Exchange services writing to a Samba share
- * I belive this code is incorrect. Each service does its own
- * sessionsetup_and_X for the same user, and as each service shuts
- * down, it does a user_logoff_and_X. As we are consolidating multiple
- * sessionsetup_and_X's onto the same vuid here, when the first service
- * shuts down, it invalidates all the open files for the other services.
- * Hence I am removing this code and forcing each sessionsetup_and_X
- * to get a new vuid.
- * Jeremy Allison. (jallison@whistle.com).
- */
-
- int i;
- for(i = 0; i < num_validated_users; i++) {
- vuser = &validated_users[i];
- if ( vuser->uid == uid )
- return (uint16)(i + VUID_OFFSET); /* User already validated */
- }
-#endif
-
validated_users = (user_struct *)Realloc(validated_users,
sizeof(user_struct)*
(num_validated_users+1));
- if (!validated_users)
- {
+ if (!validated_users) {
DEBUG(0,("Failed to realloc users struct!\n"));
num_validated_users = 0;
return UID_FIELD_INVALID;
- }
+ }
vuser = &validated_users[num_validated_users];
num_validated_users++;
@@ -274,22 +254,21 @@ uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name,
/* Find all the groups this uid is in and store them.
Used by become_user() */
- setup_groups(unix_name,domain,uid,gid,
- &vuser->n_groups,
- &vuser->groups);
+ initialize_groups(unix_name, uid, gid);
+ get_current_groups( &vuser->n_groups, &vuser->groups);
- setup_user_sids(vuser);
+ /* Create an NT_USER_TOKEN struct for this user. */
+ setup_nt_token(&vuser->nt_user_token, uid,gid, vuser->n_groups, vuser->groups);
DEBUG(3,("uid %d registered to name %s\n",(int)uid,unix_name));
DEBUG(3, ("Clearing default real name\n"));
fstrcpy(vuser->user.full_name, "<Full Name>");
if (lp_unix_realname()) {
- if ((pwfile=sys_getpwnam(vuser->user.unix_name))!= NULL)
- {
+ if ((pwfile=sys_getpwnam(vuser->user.unix_name))!= NULL) {
DEBUG(3, ("User name: %s\tReal name: %s\n",vuser->user.unix_name,pwfile->pw_gecos));
fstrcpy(vuser->user.full_name, pwfile->pw_gecos);
- }
+ }
}
memset(&vuser->dc, '\0', sizeof(vuser->dc));
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index 2662db5896..37d8f8dd73 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -561,8 +561,7 @@ static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize
}
/* load service specific parameters */
- if (conn &&
- !become_service(conn,(flags & AS_USER)?True:False)) {
+ if (conn && !become_service(conn,(flags & AS_USER)?True:False)) {
return(ERROR(ERRSRV,ERRaccess));
}
diff --git a/source3/smbd/sec_ctx.c b/source3/smbd/sec_ctx.c
index f7ea1e2d86..432cb223e2 100644
--- a/source3/smbd/sec_ctx.c
+++ b/source3/smbd/sec_ctx.c
@@ -125,17 +125,37 @@ static void gain_root(void)
/* Get the list of current groups */
-static void get_current_groups(int *ngroups, gid_t **groups)
+int get_current_groups(int *p_ngroups, gid_t **p_groups)
{
- *ngroups = getgroups(0, NULL);
- *groups = (gid_t *)malloc(*ngroups * sizeof(gid_t));
+ int i;
+ gid_t grp;
+ int ngroups = sys_getgroups(0,&grp);
+ gid_t *groups;
+
+ (*p_ngroups) = 0;
+ (*p_groups) = NULL;
+
+ if (ngroups <= 0)
+ return -1;
+
+ if((groups = (gid_t *)malloc(sizeof(gid_t)*ngroups)) == NULL) {
+ DEBUG(0,("setup_groups malloc fail !\n"));
+ return -1;
+ }
+
+ if ((ngroups = sys_getgroups(ngroups,groups)) == -1)
+ return -1;
+
+ (*p_ngroups) = ngroups;
+ (*p_groups) = groups;
- if (!groups) {
- DEBUG(0, ("Out of memory in get_current_groups\n"));
- return;
+ DEBUG( 3, ( "get_current_groups: uid %u is in %u groups: ", (unsigned int)getuid() , ngroups ) );
+ for (i = 0; i < ngroups; i++ ) {
+ DEBUG( 3, ( "%s%d", (i ? ", " : ""), (int)groups[i] ) );
}
+ DEBUG( 3, ( "\n" ) );
- getgroups(*ngroups, *groups);
+ return ngroups;
}
/* Create a new security context on the stack. It is the same as the old
diff --git a/source3/smbd/service.c b/source3/smbd/service.c
index 2eab50c482..d4760ca92d 100644
--- a/source3/smbd/service.c
+++ b/source3/smbd/service.c
@@ -511,8 +511,8 @@ connection_struct *make_connection(char *service,char *user,char *password, int
if (!IS_IPC(conn)) {
/* Find all the groups this uid is in and
store them. Used by become_user() */
- setup_groups(conn->user,validated_domain(vuid),conn->uid,conn->gid,
- &conn->ngroups,&conn->groups);
+ initialize_groups(conn->user, conn->uid, conn->gid);
+ get_current_groups(&conn->ngroups,&conn->groups);
/* check number of connections */
if (!claim_connection(conn,
diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c
index 172e872020..4cb2c512b6 100644
--- a/source3/smbd/uid.c
+++ b/source3/smbd/uid.c
@@ -38,7 +38,8 @@ BOOL become_guest(void)
if (!pass)
pass = Get_Pwnam(lp_guestaccount(-1),True);
- if (!pass) return(False);
+ if (!pass)
+ return(False);
#ifdef AIX
/* MWW: From AIX FAQ patch to WU-ftpd: call initgroups before
@@ -60,19 +61,21 @@ BOOL become_guest(void)
static BOOL check_user_ok(connection_struct *conn, user_struct *vuser,int snum)
{
- int i;
- for (i=0;i<conn->uid_cache.entries;i++)
- if (conn->uid_cache.list[i] == vuser->uid) return(True);
+ int i;
+ for (i=0;i<conn->uid_cache.entries;i++)
+ if (conn->uid_cache.list[i] == vuser->uid)
+ return(True);
- if (!user_ok(vuser->user.unix_name,snum)) return(False);
+ if (!user_ok(vuser->user.unix_name,snum))
+ return(False);
- i = conn->uid_cache.entries % UID_CACHE_SIZE;
- conn->uid_cache.list[i] = vuser->uid;
+ i = conn->uid_cache.entries % UID_CACHE_SIZE;
+ conn->uid_cache.list[i] = vuser->uid;
- if (conn->uid_cache.entries < UID_CACHE_SIZE)
- conn->uid_cache.entries++;
+ if (conn->uid_cache.entries < UID_CACHE_SIZE)
+ conn->uid_cache.entries++;
- return(True);
+ return(True);
}
/****************************************************************************
diff --git a/source3/smbd/unix_acls.c b/source3/smbd/unix_acls.c
index 7a2dc6ab6e..46c57af5de 100644
--- a/source3/smbd/unix_acls.c
+++ b/source3/smbd/unix_acls.c
@@ -28,12 +28,8 @@
static void create_file_sids(SMB_STRUCT_STAT *psbuf, DOM_SID *powner_sid, DOM_SID *pgroup_sid)
{
- extern DOM_SID global_sam_sid;
-
- sid_copy(powner_sid, &global_sam_sid);
- sid_copy(pgroup_sid, &global_sam_sid);
- sid_append_rid(powner_sid, pdb_uid_to_user_rid(psbuf->st_uid));
- sid_append_rid(pgroup_sid, pdb_gid_to_group_rid(psbuf->st_gid));
+ uid_to_sid( powner_sid, psbuf->st_uid );
+ gid_to_sid( pgroup_sid, psbuf->st_gid );
}
/****************************************************************************