From 4c0399915cde591cb06f99b50acd5e5bf48bc6cb Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 11 Apr 2002 23:43:40 +0000 Subject: Much better support for both non-algorithic RIDs (where the RID is stored in the passdb) and RIDs not in the passdb, due to being NIS users etc. The main fix here is to add become_root()/unbecome_root() at critical places. This (finally) fixes the bug where you could not see local users's names in a file's security properties as non-root. Tested. The similar bug in uid_to_sid is also fixed, but is not (yet) Tested. Andrew Bartlett (This used to be commit 79327a305e20d78ab5ca21d01c39b5f49dc0d632) --- source3/passdb/passdb.c | 265 +++++++++++++++++++-------------------- source3/rpc_server/srv_samr_nt.c | 15 --- source3/smbd/uid.c | 20 ++- 3 files changed, 145 insertions(+), 155 deletions(-) (limited to 'source3') diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c index 7eecbfd2cd..17aefe1159 100644 --- a/source3/passdb/passdb.c +++ b/source3/passdb/passdb.c @@ -514,121 +514,116 @@ BOOL local_lookup_sid(DOM_SID *sid, char *name, enum SID_NAME_USE *psid_name_use uint32 rid; BOOL is_user; SAM_ACCOUNT *sam_account = NULL; - BOOL found = False; + uid_t uid; + struct passwd *pass; + GROUP_MAP map; + sid_peek_rid(sid, &rid); - is_user = pdb_rid_is_user(rid); *psid_name_use = SID_NAME_UNKNOWN; - - DEBUG(5,("local_lookup_sid: looking up %s RID %u.\n", is_user ? "user" : - "group", (unsigned int)rid)); - - if(is_user) { - if(rid == DOMAIN_USER_RID_ADMIN) { - char **admin_list = lp_admin_users(-1); - *psid_name_use = SID_NAME_USER; - if (admin_list) { - char *p = *admin_list; - if(!next_token(&p, name, NULL, sizeof(fstring))) - fstrcpy(name, "Administrator"); - } else { - fstrcpy(name, "Administrator"); - } - } else if (rid == DOMAIN_USER_RID_GUEST) { - char *p = lp_guestaccount(); - *psid_name_use = SID_NAME_USER; + + DEBUG(5,("local_lookup_sid: looking up RID %u.\n", (unsigned int)rid)); + + if (rid == DOMAIN_USER_RID_ADMIN) { + char **admin_list = lp_admin_users(-1); + *psid_name_use = SID_NAME_USER; + if (admin_list) { + char *p = *admin_list; if(!next_token(&p, name, NULL, sizeof(fstring))) - fstrcpy(name, "Guest"); + fstrcpy(name, "Administrator"); } else { - uid_t uid; - struct passwd *pass; - - /* - * Don't try to convert the rid to a name if - * running in appliance mode - */ - if (lp_hide_local_users()) - return False; + fstrcpy(name, "Administrator"); + } + return True; - if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_account))) { - return False; - } - - if (pdb_getsampwrid(sam_account, rid)) { - fstrcpy(name, pdb_get_username(sam_account)); - *psid_name_use = SID_NAME_USER; - found = True; - } - - pdb_free_sam(&sam_account); + } else if (rid == DOMAIN_USER_RID_GUEST) { + char *p = lp_guestaccount(); + *psid_name_use = SID_NAME_USER; + if(!next_token(&p, name, NULL, sizeof(fstring))) + fstrcpy(name, "Guest"); + return True; + + } + + /* + * Don't try to convert the rid to a name if + * running in appliance mode + */ + + if (lp_hide_local_users()) + return False; + + if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_account))) { + return False; + } + + if (pdb_getsampwrid(sam_account, rid)) { + fstrcpy(name, pdb_get_username(sam_account)); + *psid_name_use = SID_NAME_USER; + + pdb_free_sam(&sam_account); - if (found) { - return True; - } + return True; + } + + pdb_free_sam(&sam_account); + + if (get_group_map_from_sid(*sid, &map, MAPPING_WITHOUT_PRIV)) { + if (map.gid!=-1) { + DEBUG(5,("local_lookup_sid: mapped group %s to gid %u\n", map.nt_name, (unsigned int)map.gid)); + fstrcpy(name, map.nt_name); + *psid_name_use = map.sid_name_use; + return True; + } + } + + is_user = pdb_rid_is_user(rid); + + DEBUG(5, ("assuming RID %u is a %s\n", (unsigned)rid, is_user ? "user" : "group")); + + if (pdb_rid_is_user(rid)) { + uid = fallback_pdb_user_rid_to_uid(rid); + pass = getpwuid_alloc(uid); - uid = fallback_pdb_user_rid_to_uid(rid); - pass = getpwuid_alloc(uid); + *psid_name_use = SID_NAME_USER; - *psid_name_use = SID_NAME_USER; + DEBUG(5,("local_lookup_sid: looking up uid %u %s\n", (unsigned int)uid, + pass ? "succeeded" : "failed" )); - DEBUG(5,("local_lookup_sid: looking up uid %u %s\n", (unsigned int)uid, - pass ? "succeeded" : "failed" )); + if(!pass) { + slprintf(name, sizeof(fstring)-1, "unix_user.%u", (unsigned int)uid); + return True; + } - if(!pass) { - slprintf(name, sizeof(fstring)-1, "unix_user.%u", (unsigned int)uid); - return True; - } + fstrcpy(name, pass->pw_name); - fstrcpy(name, pass->pw_name); + DEBUG(5,("local_lookup_sid: found user %s for rid %u\n", name, + (unsigned int)rid )); - DEBUG(5,("local_lookup_sid: found user %s for rid %u\n", name, - (unsigned int)rid )); + passwd_free(&pass); - passwd_free(&pass); - } - } else { gid_t gid; struct group *gr; - GROUP_MAP map; - - /* - * Don't try to convert the rid to a name if running - * in appliance mode - */ - - if (lp_hide_local_users()) - return False; - - /* check if it's a mapped group */ - if (get_group_map_from_sid(*sid, &map, MAPPING_WITHOUT_PRIV)) { - if (map.gid!=-1) { - DEBUG(5,("local_lookup_sid: mapped group %s to gid %u\n", map.nt_name, (unsigned int)map.gid)); - fstrcpy(name, map.nt_name); - *psid_name_use = map.sid_name_use; - return True; - } - } - + gid = pdb_group_rid_to_gid(rid); gr = getgrgid(gid); - + *psid_name_use = SID_NAME_ALIAS; - + DEBUG(5,("local_lookup_sid: looking up gid %u %s\n", (unsigned int)gid, - gr ? "succeeded" : "failed" )); - + gr ? "succeeded" : "failed" )); + if(!gr) { slprintf(name, sizeof(fstring)-1, "unix_group.%u", (unsigned int)gid); return False; } - + fstrcpy( name, gr->gr_name); - + DEBUG(5,("local_lookup_sid: found group %s for rid %u\n", name, - (unsigned int)rid )); + (unsigned int)rid )); } - return True; } @@ -643,7 +638,6 @@ BOOL local_lookup_name(const char *c_user, DOM_SID *psid, enum SID_NAME_USE *psi DOM_SID local_sid; fstring user; SAM_ACCOUNT *sam_account = NULL; - BOOL found = False; *psid_name_use = SID_NAME_UNKNOWN; @@ -684,25 +678,23 @@ BOOL local_lookup_name(const char *c_user, DOM_SID *psid, enum SID_NAME_USE *psi *psid_name_use = SID_NAME_USER; sid_copy( psid, &local_sid); - found = True; + pdb_free_sam(&sam_account); + return True; } pdb_free_sam(&sam_account); - if (!found && (pass = Get_Pwnam(user))) { + if ((pass = Get_Pwnam(user))) { sid_append_rid( &local_sid, fallback_pdb_uid_to_user_rid(pass->pw_uid)); *psid_name_use = SID_NAME_USER; - pdb_free_sam(&sam_account); - } else if (!found) { + } else { /* * Maybe it was a group ? */ struct group *grp; GROUP_MAP map; - pdb_free_sam(&sam_account); - /* check if it's a mapped group */ if (get_group_map_from_ntname(user, &map, MAPPING_WITHOUT_PRIV)) { if (map.gid!=-1) { @@ -754,27 +746,36 @@ DOM_SID *local_uid_to_sid(DOM_SID *psid, uid_t uid) extern DOM_SID global_sam_sid; struct passwd *pass; SAM_ACCOUNT *sam_user = NULL; + fstring str; /* sid string buffer */ sid_copy(psid, &global_sam_sid); - if(!(pass = getpwuid_alloc(uid))) - return NULL; + if((pass = getpwuid_alloc(uid))) { - if (NT_STATUS_IS_ERR(pdb_init_sam(&sam_user))) { - passwd_free(&pass); - return NULL; - } - - if (!pdb_getsampwnam(sam_user, pass->pw_name)) { - pdb_free_sam(&sam_user); - return NULL; - } + if (NT_STATUS_IS_ERR(pdb_init_sam(&sam_user))) { + passwd_free(&pass); + return NULL; + } + + if (pdb_getsampwnam(sam_user, pass->pw_name)) { + sid_append_rid(psid, pdb_get_user_rid(sam_user)); + } else { + sid_append_rid(psid, fallback_pdb_uid_to_user_rid(uid)); + } - passwd_free(&pass); + DEBUG(10,("local_uid_to_sid: uid %u -> SID (%s) (%s).\n", + (unsigned)uid, sid_to_string( str, psid), + pass->pw_name )); - sid_append_rid(psid, pdb_get_user_rid(sam_user)); + passwd_free(&pass); + pdb_free_sam(&sam_user); + + } else { + sid_append_rid(psid, fallback_pdb_uid_to_user_rid(uid)); - pdb_free_sam(&sam_user); + DEBUG(10,("local_uid_to_sid: uid %u -> SID (%s) (unknown user).\n", + (unsigned)uid, sid_to_string( str, psid))); + } return psid; } @@ -790,7 +791,6 @@ BOOL local_sid_to_uid(uid_t *puid, DOM_SID *psid, enum SID_NAME_USE *name_type) DOM_SID dom_sid; uint32 rid; fstring str; - struct passwd *pass; SAM_ACCOUNT *sam_user = NULL; *name_type = SID_NAME_UNKNOWN; @@ -798,9 +798,6 @@ BOOL local_sid_to_uid(uid_t *puid, DOM_SID *psid, enum SID_NAME_USE *name_type) sid_copy(&dom_sid, psid); sid_split_rid(&dom_sid, &rid); - if (!pdb_rid_is_user(rid)) - return False; - /* * We can only convert to a uid if this is our local * Domain SID (ie. we are the controling authority). @@ -811,28 +808,26 @@ BOOL local_sid_to_uid(uid_t *puid, DOM_SID *psid, enum SID_NAME_USE *name_type) if (NT_STATUS_IS_ERR(pdb_init_sam(&sam_user))) return False; - if (!pdb_getsampwrid(sam_user, rid)) { - pdb_free_sam(&sam_user); - return False; + if (pdb_getsampwrid(sam_user, rid)) { + *puid = pdb_get_uid(sam_user); + if (*puid == -1) { + pdb_free_sam(&sam_user); + return False; + } + DEBUG(10,("local_sid_to_uid: SID %s -> uid (%u) (%s).\n", sid_to_string( str, psid), + (unsigned int)*puid, pdb_get_username(sam_user))); + } else { + if (pdb_rid_is_user(rid)) { + *puid = fallback_pdb_user_rid_to_uid(rid); + DEBUG(10,("local_sid_to_uid: SID %s -> uid (%u) (non-passdb user).\n", sid_to_string( str, psid), + (unsigned int)*puid)); + } else { + pdb_free_sam(&sam_user); + return False; + } } - - *puid = pdb_get_uid(sam_user); - if (*puid == -1) - return False; - pdb_free_sam(&sam_user); - /* - * Ensure this uid really does exist. - */ - if(!(pass = getpwuid_alloc(*puid))) - return False; - - DEBUG(10,("local_sid_to_uid: SID %s -> uid (%u) (%s).\n", sid_to_string( str, psid), - (unsigned int)*puid, pass->pw_name )); - - passwd_free(&pass); - *name_type = SID_NAME_USER; return True; @@ -887,9 +882,6 @@ BOOL local_sid_to_gid(gid_t *pgid, DOM_SID *psid, enum SID_NAME_USE *name_type) if (!sid_equal(&global_sam_sid, &dom_sid)) return False; - if (pdb_rid_is_user(rid)) - return False; - if (get_group_map_from_sid(*psid, &map, MAPPING_WITHOUT_PRIV)) { /* the SID is in the mapping table but not mapped */ @@ -897,9 +889,12 @@ BOOL local_sid_to_gid(gid_t *pgid, DOM_SID *psid, enum SID_NAME_USE *name_type) return False; sid_peek_rid(&map.sid, &rid); - *pgid = rid; + *pgid = map.gid; *name_type = map.sid_name_use; } else { + if (pdb_rid_is_user(rid)) + return False; + *pgid = pdb_group_rid_to_gid(rid); *name_type = SID_NAME_ALIAS; } diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index c83f6b3d8d..106d7c1923 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -1443,11 +1443,6 @@ static BOOL get_user_info_10(SAM_USER_INFO_10 *id10, uint32 user_rid) SAM_ACCOUNT *smbpass=NULL; BOOL ret; - if (!pdb_rid_is_user(user_rid)) { - DEBUG(4,("RID 0x%x is not a user RID\n", user_rid)); - return False; - } - pdb_init_sam(&smbpass); become_root(); @@ -1524,11 +1519,6 @@ static BOOL get_user_info_20(SAM_USER_INFO_20 *id20, uint32 user_rid) SAM_ACCOUNT *sampass=NULL; BOOL ret; - if (!pdb_rid_is_user(user_rid)) { - DEBUG(4,("RID 0x%x is not a user RID\n", user_rid)); - return False; - } - pdb_init_sam(&sampass); become_root(); @@ -1562,11 +1552,6 @@ static BOOL get_user_info_21(SAM_USER_INFO_21 *id21, uint32 user_rid) SAM_ACCOUNT *sampass=NULL; BOOL ret; - if (!pdb_rid_is_user(user_rid)) { - DEBUG(4,("RID 0x%x is not a user RID\n", user_rid)); - return False; - } - pdb_init_sam(&sampass); become_root(); diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 864d3d6c66..ac0b535c13 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -546,9 +546,12 @@ DOM_SID *uid_to_sid(DOM_SID *psid, uid_t uid) return psid; } } + + /* Make sure we report failure, (when psid == NULL) */ + become_root(); + psid = local_uid_to_sid(psid, uid); + unbecome_root(); - local_uid_to_sid(psid, uid); - DEBUG(10,("uid_to_sid: local %u -> %s\n", (unsigned int)uid, sid_to_string(sid, psid))); return psid; @@ -611,10 +614,14 @@ BOOL sid_to_uid(DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype) */ if ( (!winbind_lookup_sid(psid, dom_name, name, &name_type)) || (name_type != SID_NAME_USER) ) { + BOOL result; DEBUG(10,("sid_to_uid: winbind lookup for sid %s failed - trying local.\n", sid_to_string(sid_str, psid) )); - return local_sid_to_uid(puid, psid, sidtype); + become_root(); + result = local_sid_to_uid(puid, psid, sidtype); + unbecome_root(); + return result; } /* @@ -634,9 +641,13 @@ BOOL sid_to_uid(DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype) */ if (!winbind_sid_to_uid(puid, psid)) { + BOOL result; DEBUG(10,("sid_to_uid: winbind lookup for sid %s failed.\n", sid_to_string(sid_str, psid) )); - return local_sid_to_uid(puid, psid, sidtype); + become_root(); + result = local_sid_to_uid(puid, psid, sidtype); + unbecome_root(); + return result; } DEBUG(10,("sid_to_uid: winbindd %s -> %u\n", @@ -667,7 +678,6 @@ BOOL sid_to_gid(DOM_SID *psid, gid_t *pgid, enum SID_NAME_USE *sidtype) if (!winbind_lookup_sid(psid, dom_name, name, &name_type)) { DEBUG(10,("sid_to_gid: winbind lookup for sid %s failed - trying local.\n", sid_to_string(sid_str, psid) )); - if (!local_sid_to_gid(pgid, psid, sidtype)) { /* this was probably a foreign sid - assume its a group rid and continue */ -- cgit