diff options
-rw-r--r-- | source3/include/proto.h | 20 | ||||
-rw-r--r-- | source3/include/smb.h | 20 | ||||
-rw-r--r-- | source3/lib/util_seaccess.c | 46 | ||||
-rw-r--r-- | source3/nsswitch/wb_client.c | 106 | ||||
-rw-r--r-- | source3/passdb/passdb.c | 86 | ||||
-rw-r--r-- | source3/rpc_server/srv_lsa.c | 2 | ||||
-rw-r--r-- | source3/rpc_server/srv_samr.c | 4 | ||||
-rw-r--r-- | source3/smbd/password.c | 113 | ||||
-rw-r--r-- | source3/smbd/process.c | 3 | ||||
-rw-r--r-- | source3/smbd/sec_ctx.c | 34 | ||||
-rw-r--r-- | source3/smbd/service.c | 4 | ||||
-rw-r--r-- | source3/smbd/uid.c | 23 | ||||
-rw-r--r-- | source3/smbd/unix_acls.c | 8 |
13 files changed, 251 insertions, 218 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h index 85ea676736..321f3098e9 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -1278,8 +1278,12 @@ void expire_workgroups_and_servers(time_t t); BOOL winbind_lookup_name(char *name, DOM_SID *sid, uint8 *name_type); BOOL winbind_lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, uint8 *name_type); -BOOL winbind_uid_to_sid(uid_t uid, DOM_SID *sid); -BOOL winbind_gid_to_sid(gid_t gid, DOM_SID *sid); +BOOL winbind_uid_to_sid(DOM_SID *sid, uid_t uid); +BOOL winbind_gid_to_sid(DOM_SID *sid, gid_t gid); +BOOL lookup_name(char *name, DOM_SID *psid, uint8 *name_type); +BOOL lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, uint8 *name_type); +DOM_SID *uid_to_sid(DOM_SID *psid, uid_t uid); +DOM_SID *gid_to_sid(DOM_SID *psid, gid_t gid); /*The following definitions come from nsswitch/wb_common.c */ @@ -1622,9 +1626,10 @@ gid_t pdb_user_rid_to_gid(uint32 user_rid); uint32 pdb_uid_to_user_rid(uid_t uid); uint32 pdb_gid_to_group_rid(gid_t gid); BOOL pdb_rid_is_user(uint32 rid); -BOOL lookup_local_rid(uint32 rid, char *name, uint8 *psid_name_use); -BOOL lookup_local_name(char *domain, char *user, DOM_SID *psid, uint8 *psid_name_use); -BOOL setup_user_sids(user_struct *vuser); +BOOL local_lookup_rid(uint32 rid, char *name, uint8 *psid_name_use); +BOOL local_lookup_name(char *domain, char *user, DOM_SID *psid, uint8 *psid_name_use); +DOM_SID *local_uid_to_sid(DOM_SID *psid, uid_t uid); +DOM_SID *local_gid_to_sid(DOM_SID *psid, gid_t gid); /*The following definitions come from passdb/secrets.c */ @@ -3540,8 +3545,8 @@ user_struct *get_valid_user_struct(uint16 vuid); void invalidate_vuid(uint16 vuid); char *validated_username(uint16 vuid); char *validated_domain(uint16 vuid); -int setup_groups(char *user, char *domain, - uid_t uid, gid_t gid, int *p_ngroups, gid_t **p_groups); +int initialize_groups(char *user, uid_t uid, gid_t gid); +void setup_nt_token(NT_USER_TOKEN *token, uid_t uid, gid_t gid, int ngroups, gid_t *groups); uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, char *domain,BOOL guest); void add_session_user(char *user); @@ -3667,6 +3672,7 @@ int reply_getattrE(connection_struct *conn, char *inbuf,char *outbuf, int size, /*The following definitions come from smbd/sec_ctx.c */ +int get_current_groups(int *p_ngroups, gid_t **p_groups); BOOL push_sec_ctx(void); void set_sec_ctx(uid_t uid, gid_t gid, int ngroups, gid_t *groups); void set_root_sec_ctx(void); diff --git a/source3/include/smb.h b/source3/include/smb.h index bc9f17544c..aaebe56f33 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -399,6 +399,15 @@ typedef struct sid_info } DOM_SID; +/* + * The complete list of SIDS belonging to this user. + * Created when a vuid is registered. + */ + +typedef struct _nt_user_token { + size_t num_sids; + DOM_SID *user_sids; +} NT_USER_TOKEN; /*** query a local group, get a list of these: shows who is in that group ***/ @@ -556,8 +565,8 @@ typedef struct connection_struct char *connectpath; char *origpath; - struct vfs_ops vfs_ops; /* Filesystem operations */ - struct vfs_connection_struct *vfs_conn; /* VFS specific connection stuff */ + struct vfs_ops vfs_ops; /* Filesystem operations */ + struct vfs_connection_struct *vfs_conn; /* VFS specific connection stuff */ char *user; /* name of user who *opened* this connection */ uid_t uid; /* uid of user who *opened* this connection */ @@ -1663,12 +1672,7 @@ typedef struct int n_groups; gid_t *groups; -#if 0 - NET_USER_INFO_3 usr; /* This should not be here. */ -#else - DOM_SID user_sid; - DOM_SID *group_sids; -#endif + NT_USER_TOKEN nt_user_token; /* per-user authentication information on NT RPCs */ /* lkclXXXX - THIS SHOULD NOT BE HERE! */ diff --git a/source3/lib/util_seaccess.c b/source3/lib/util_seaccess.c index 05a7a30635..52696d2d30 100644 --- a/source3/lib/util_seaccess.c +++ b/source3/lib/util_seaccess.c @@ -99,12 +99,12 @@ static BOOL check_ace(SEC_ACE *ace, BOOL is_owner, DOM_SID *sid, sid_to_string(sid_str, sid); sid_to_string(ace_sid_str, &ace->sid); - if (!winbind_lookup_sid(sid, name_dom, name, &name_type)) { + if (!lookup_sid(sid, name_dom, name, &name_type)) { fstrcpy(name_dom, "UNKNOWN"); fstrcpy(name, "UNKNOWN"); } - if (!winbind_lookup_sid(&ace->sid, ace_name_dom, ace_name, + if (!lookup_sid(&ace->sid, ace_name_dom, ace_name, &name_type)) { fstrcpy(ace_name_dom, "UNKNOWN"); fstrcpy(ace_name, "UNKNOWN"); @@ -208,6 +208,7 @@ BOOL se_access_check(SEC_DESC *sd, struct current_user *user, uint32 acc_desired, uint32 *acc_granted, uint32 *status) { DOM_SID user_sid, group_sid; + DOM_SID owner_sid; DOM_SID **group_sids = NULL; int i, j; uint ngroup_sids = 0; @@ -215,25 +216,30 @@ BOOL se_access_check(SEC_DESC *sd, struct current_user *user, uint8 check_ace_type; fstring sid_str; - if (!status || !acc_granted) return False; + if (!status || !acc_granted) + return False; *status = NT_STATUS_ACCESS_DENIED; *acc_granted = 0; - /* No security descriptor allows all access */ + /* + * No security descriptor or security descriptor with no DACL + * present allows all access. + */ - if (!sd) { + if (!sd || (sd && (!(sd->type & SEC_DESC_DACL_PRESENT) || sd->dacl == NULL))) { *status = NT_STATUS_NOPROBLEMO; *acc_granted = acc_desired; acc_desired = 0; - DEBUG(3, ("no sd, access allowed\n")); - - goto done; + DEBUG(3, ("se_access_check: no sd or blank DACL, access allowed\n")); + goto done; } /* If desired access mask is empty then no access is allowed */ if (acc_desired == 0) { + *status = NT_STATUS_ACCESS_DENIED; + *acc_granted = 0; goto done; } @@ -246,12 +252,12 @@ BOOL se_access_check(SEC_DESC *sd, struct current_user *user, /* Create user sid */ - if (!winbind_uid_to_sid(user->uid, &user_sid)) { + if (!uid_to_sid(&user_sid, user->uid)) { DEBUG(3, ("could not lookup sid for uid %d\n", user->uid)); + goto done; } - sid_to_string(sid_str, &user_sid); - DEBUG(3, ("user sid is %s\n", sid_str)); + DEBUG(3, ("se_access_check: user sid is %s\n", sid_to_string(sid_str, &user_sid) )); /* If we're the owner, then we can do anything */ @@ -266,8 +272,9 @@ BOOL se_access_check(SEC_DESC *sd, struct current_user *user, /* Create group sid */ - if (!winbind_gid_to_sid(user->gid, &group_sid)) { + if (!gid_to_sid(&group_sid, user->gid)) { DEBUG(3, ("could not lookup sid for gid %d\n", user->gid)); + goto done; } sid_to_string(sid_str, &group_sid); @@ -279,7 +286,7 @@ BOOL se_access_check(SEC_DESC *sd, struct current_user *user, for (i = 0; i < user->ngroups; i++) { if (user->groups[i] != user->gid) { - if (winbind_gid_to_sid(user->groups[i], &group_sid)) { + if (gid_to_sid(&group_sid, user->groups[i])) { /* If we're a group member then we can also do anything */ @@ -310,18 +317,18 @@ BOOL se_access_check(SEC_DESC *sd, struct current_user *user, acl = sd->dacl; - if (acl == NULL || acl->ace == NULL || acl->num_aces == 0) { + if (acl == NULL || acl->ace == NULL || acl->num_aces == 0) { /* Checks against a NULL ACL succeed and return access - granted = access requested. */ + granted = access requested. */ *status = NT_STATUS_NOPROBLEMO; *acc_granted = acc_desired; acc_desired = 0; DEBUG(3, ("null ace, access allowed\n")); - goto done; - } + goto done; + } /* Check each ACE in ACL. We break out of the loop if an ACE is either explicitly denied or explicitly allowed by the @@ -370,7 +377,8 @@ BOOL se_access_check(SEC_DESC *sd, struct current_user *user, } done: - free_sid_array(ngroup_sids, group_sids); + + free_sid_array(ngroup_sids, group_sids); /* If any access desired bits are still on, return access denied and turn off any bits already granted. */ @@ -380,5 +388,5 @@ BOOL se_access_check(SEC_DESC *sd, struct current_user *user, *status = NT_STATUS_ACCESS_DENIED; } - return *status == NT_STATUS_NOPROBLEMO; + return *status == NT_STATUS_NOPROBLEMO; } diff --git a/source3/nsswitch/wb_client.c b/source3/nsswitch/wb_client.c index 78de466636..47f1520efa 100644 --- a/source3/nsswitch/wb_client.c +++ b/source3/nsswitch/wb_client.c @@ -29,7 +29,6 @@ BOOL winbind_lookup_name(char *name, DOM_SID *sid, uint8 *name_type) { - extern pstring global_myname; struct winbindd_request request; struct winbindd_response response; enum nss_status result; @@ -47,14 +46,6 @@ BOOL winbind_lookup_name(char *name, DOM_SID *sid, uint8 *name_type) &response)) == NSS_STATUS_SUCCESS) { string_to_sid(sid, response.data.sid.sid); *name_type = response.data.sid.type; - } else { - - /* - * Try a local lookup - winbindd may not - * be running. - */ - - return lookup_local_name(global_myname, name, sid, name_type); } return result == NSS_STATUS_SUCCESS; @@ -85,7 +76,7 @@ BOOL winbind_lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, if (sid_equal(&global_sam_sid, &tmp_sid)) { return map_domain_sid_to_name(&tmp_sid, dom_name) && - lookup_local_rid(rid, name, name_type); + local_lookup_rid(rid, name, name_type); } } @@ -106,15 +97,6 @@ BOOL winbind_lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, if (result == NSS_STATUS_SUCCESS) { parse_domain_user(response.data.name.name, dom_name, name); *name_type = response.data.name.type; - } else { - - DEBUG(10,("winbind_lookup_sid: winbind lookup for %s failed - trying builtin.\n", - sid_str)); - - sid_copy(&tmp_sid, sid); - sid_split_rid(&tmp_sid, &rid); - return map_domain_sid_to_name(&tmp_sid, dom_name) && - lookup_known_rid(&tmp_sid, rid, name, name_type); } return (result == NSS_STATUS_SUCCESS); @@ -122,13 +104,14 @@ BOOL winbind_lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, /* Call winbindd to convert uid to sid */ -BOOL winbind_uid_to_sid(uid_t uid, DOM_SID *sid) +BOOL winbind_uid_to_sid(DOM_SID *sid, uid_t uid) { struct winbindd_request request; struct winbindd_response response; int result; - if (!sid) return False; + if (!sid) + return False; /* Initialise request */ @@ -154,13 +137,14 @@ BOOL winbind_uid_to_sid(uid_t uid, DOM_SID *sid) /* Call winbindd to convert uid to sid */ -BOOL winbind_gid_to_sid(gid_t gid, DOM_SID *sid) +BOOL winbind_gid_to_sid(DOM_SID *sid, gid_t gid) { struct winbindd_request request; struct winbindd_response response; int result; - if (!sid) return False; + if (!sid) + return False; /* Initialise request */ @@ -183,3 +167,79 @@ BOOL winbind_gid_to_sid(gid_t gid, DOM_SID *sid) return (result == NSS_STATUS_SUCCESS); } + + + +/***************************************************************** + *THE CANNONICAL* convert name to SID function. + Tries winbind first - then uses local lookup. +*****************************************************************/ + +BOOL lookup_name(char *name, DOM_SID *psid, uint8 *name_type) +{ + extern pstring global_myname; + + if (!winbind_lookup_name(name, psid, name_type)) { + + DEBUG(10,("lookup_name: winbind lookup for %s failed - trying local\n", name )); + + return local_lookup_name(global_myname, name, psid, name_type); + } + return True; +} + +/***************************************************************** + *THE CANNONICAL* convert SID to name function. + Tries winbind first - then uses local lookup. +*****************************************************************/ + +BOOL lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, uint8 *name_type) +{ + if (!winbind_lookup_sid(sid, dom_name, name, name_type)) { + fstring sid_str; + DOM_SID tmp_sid; + uint32 rid; + + DEBUG(10,("lookup_sid: winbind lookup for SID %s failed - trying local.\n", sid_to_string(sid_str, sid) )); + + sid_copy(&tmp_sid, sid); + sid_split_rid(&tmp_sid, &rid); + return map_domain_sid_to_name(&tmp_sid, dom_name) && + lookup_known_rid(&tmp_sid, rid, name, name_type); + } + return True; +} + +/***************************************************************** + *THE CANNONICAL* convert uid_t to SID function. + Tries winbind first - then uses local lookup. + Returns SID pointer. +*****************************************************************/ + +DOM_SID *uid_to_sid(DOM_SID *psid, uid_t uid) +{ + if (!winbind_uid_to_sid(psid, uid)) { + DEBUG(10,("uid_to_sid: winbind lookup for uid %u failed - trying local.\n", (unsigned int)uid )); + + return local_uid_to_sid(psid, uid); + } + + return psid; +} + +/***************************************************************** + *THE CANNONICAL* convert gid_t to SID function. + Tries winbind first - then uses local lookup. + Returns SID pointer. +*****************************************************************/ + +DOM_SID *gid_to_sid(DOM_SID *psid, gid_t gid) +{ + if (!winbind_gid_to_sid(psid, gid)) { + DEBUG(10,("gid_to_sid: winbind lookup for gid %u failed - trying local.\n", (unsigned int)gid )); + + return local_gid_to_sid(psid, gid); + } + + return psid; +} diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c index 04f02e3704..f0fe2499df 100644 --- a/source3/passdb/passdb.c +++ b/source3/passdb/passdb.c @@ -1091,12 +1091,12 @@ BOOL pdb_rid_is_user(uint32 rid) Convert a rid into a name. Used in the lookup SID rpc. ********************************************************************/ -BOOL lookup_local_rid(uint32 rid, char *name, uint8 *psid_name_use) +BOOL local_lookup_rid(uint32 rid, char *name, uint8 *psid_name_use) { BOOL is_user = pdb_rid_is_user(rid); - DEBUG(5,("lookup_local_rid: looking up %s RID %u.\n", is_user ? "user" : + DEBUG(5,("local_lookup_rid: looking up %s RID %u.\n", is_user ? "user" : "group", (unsigned int)rid)); if(is_user) { @@ -1118,7 +1118,7 @@ BOOL lookup_local_rid(uint32 rid, char *name, uint8 *psid_name_use) *psid_name_use = SID_NAME_USER; - DEBUG(5,("lookup_local_rid: looking up uid %u %s\n", (unsigned int)uid, + DEBUG(5,("local_lookup_rid: looking up uid %u %s\n", (unsigned int)uid, pass ? "succeeded" : "failed" )); if(!pass) { @@ -1128,7 +1128,7 @@ BOOL lookup_local_rid(uint32 rid, char *name, uint8 *psid_name_use) fstrcpy(name, pass->pw_name); - DEBUG(5,("lookup_local_rid: found user %s for rid %u\n", name, + DEBUG(5,("local_lookup_rid: found user %s for rid %u\n", name, (unsigned int)rid )); } @@ -1138,7 +1138,7 @@ BOOL lookup_local_rid(uint32 rid, char *name, uint8 *psid_name_use) *psid_name_use = SID_NAME_ALIAS; - DEBUG(5,("lookup_local_rid: looking up gid %u %s\n", (unsigned int)gid, + DEBUG(5,("local_local_rid: looking up gid %u %s\n", (unsigned int)gid, gr ? "succeeded" : "failed" )); if(!gr) { @@ -1148,7 +1148,7 @@ BOOL lookup_local_rid(uint32 rid, char *name, uint8 *psid_name_use) fstrcpy( name, gr->gr_name); - DEBUG(5,("lookup_local_rid: found group %s for rid %u\n", name, + DEBUG(5,("local_lookup_rid: found group %s for rid %u\n", name, (unsigned int)rid )); } @@ -1159,7 +1159,7 @@ BOOL lookup_local_rid(uint32 rid, char *name, uint8 *psid_name_use) Convert a name into a SID. Used in the lookup name rpc. ********************************************************************/ -BOOL lookup_local_name(char *domain, char *user, DOM_SID *psid, uint8 *psid_name_use) +BOOL local_lookup_name(char *domain, char *user, DOM_SID *psid, uint8 *psid_name_use) { extern DOM_SID global_sid_World_Domain; struct passwd *pass = NULL; @@ -1206,71 +1206,29 @@ BOOL lookup_local_name(char *domain, char *user, DOM_SID *psid, uint8 *psid_name } /**************************************************************************** - Create a list of SIDS for a user - primary and group. - This is really the wrong way to do this and needs to go via winbind. JRA. + Convert a uid to SID - locally. ****************************************************************************/ -BOOL setup_user_sids(user_struct *vuser) +DOM_SID *local_uid_to_sid(DOM_SID *psid, uid_t uid) { extern DOM_SID global_sam_sid; - sid_copy(&vuser->user_sid, &global_sam_sid); - sid_append_rid( &vuser->user_sid, pdb_uid_to_user_rid(vuser->uid)); + sid_copy(psid, &global_sam_sid); + sid_append_rid(psid, pdb_uid_to_user_rid(uid)); - if (vuser->n_groups != 0) { - int i; + return psid; +} - vuser->group_sids = (DOM_SID *)malloc(sizeof(DOM_SID) * vuser->n_groups); +/**************************************************************************** + Convert a gid to SID - locally. +****************************************************************************/ - if (vuser->group_sids == NULL) - return False; +DOM_SID *local_gid_to_sid(DOM_SID *psid, gid_t gid) +{ + extern DOM_SID global_sam_sid; - for (i = 0; i < vuser->n_groups; i++) { - sid_copy(&vuser->group_sids[i], &global_sam_sid); - sid_append_rid( &vuser->group_sids[i], pdb_gid_to_group_rid(vuser->groups[i])); - } - } + sid_copy(psid, &global_sam_sid); + sid_append_rid(psid, pdb_gid_to_group_rid(gid)); - return True; -#if 0 - /* Luke's code. */ - if (usr == NULL) - { - int i; - extern DOM_SID global_sam_sid; - - DEBUG(0,("vuser struct usr being filled in with trash, today\n")); - DEBUG(0,("this needs to be replaced with a proper surs impl.\n")); - DEBUG(0,("e.g. the one used in winbindd. in fact, all\n")); - DEBUG(0,("occurrences of pdb_xxx_to_xxx should be replaced\n")); - DEBUG(0,("as soon as possible.\n")); - vuser->usr.user_id = pdb_uid_to_user_rid(uid); - vuser->usr.group_id = pdb_gid_to_group_rid(gid); - vuser->usr.num_groups = vuser->n_groups; - if (vuser->n_groups != 0) - { - vuser->usr.gids = g_new(DOM_GID, vuser->usr.num_groups); - if (vuser->usr.gids == NULL) - return UID_FIELD_INVALID; - } - - for (i = 0; i < vuser->usr.num_groups; i++) - { - DOM_GID *ntgid = &vuser->usr.gids[i]; - ntgid->attr = 0x7; - ntgid->g_rid = pdb_gid_to_group_rid(vuser->groups[i]); - } - - /* this is possibly the worst thing to do, ever. it assumes */ - /* that all users of this system are in the local SAM database */ - /* however, because there is no code to do anything otherwise, */ - /* we have no choice */ - - init_dom_sid2(&vuser->usr.dom_sid, &global_sam_sid); - } - else - { - vuser->usr = *usr; - } -#endif + return psid; } diff --git a/source3/rpc_server/srv_lsa.c b/source3/rpc_server/srv_lsa.c index bfb671d167..dc97d6db44 100644 --- a/source3/rpc_server/srv_lsa.c +++ b/source3/rpc_server/srv_lsa.c @@ -238,7 +238,7 @@ static void init_lsa_rid2s(DOM_R_REF *ref, DOM_RID2 *rid2, if (map_domain_name_to_sid(&dom_sid, dom_name)) { dom_idx = init_dom_ref(ref, dom_name, &dom_sid); - if (lookup_local_name(dom_name, user, &sid, &sid_name_use) && sid_split_rid(&sid, &rid)) + if (local_lookup_name(dom_name, user, &sid, &sid_name_use) && sid_split_rid(&sid, &rid)) status = True; } diff --git a/source3/rpc_server/srv_samr.c b/source3/rpc_server/srv_samr.c index 5a0f049ba7..e80175f71d 100644 --- a/source3/rpc_server/srv_samr.c +++ b/source3/rpc_server/srv_samr.c @@ -978,7 +978,7 @@ static BOOL samr_reply_query_aliasinfo(SAMR_Q_QUERY_ALIASINFO *q_u, if(alias_rid == 0xffffffff) r_e.status = 0xC0000000 | NT_STATUS_NO_SUCH_ALIAS; - if(!lookup_local_rid(alias_rid, alias, &type)) + if(!local_lookup_rid(alias_rid, alias, &type)) { r_e.status = 0xC0000000 | NT_STATUS_NO_SUCH_ALIAS; } @@ -1151,7 +1151,7 @@ static BOOL samr_reply_lookup_names(SAMR_Q_LOOKUP_NAMES *q_u, if(sid_equal(&pol_sid, &global_sam_sid)) { DOM_SID sid; - if(lookup_local_name(global_myname, name, + if(local_lookup_name(global_myname, name, &sid, &type[i])) { sid_split_rid( &sid, &rid[i]); 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 ); } /**************************************************************************** |