diff options
Diffstat (limited to 'source/smbd/uid.c')
-rw-r--r-- | source/smbd/uid.c | 219 |
1 files changed, 100 insertions, 119 deletions
diff --git a/source/smbd/uid.c b/source/smbd/uid.c index 2bda26aa510..b94fc05875d 100644 --- a/source/smbd/uid.c +++ b/source/smbd/uid.c @@ -1,5 +1,6 @@ /* - Unix SMB/CIFS implementation. + Unix SMB/Netbios implementation. + Version 1.9. uid/user handling Copyright (C) Andrew Tridgell 1992-1998 @@ -30,21 +31,26 @@ extern struct current_user current_user; BOOL change_to_guest(void) { static struct passwd *pass=NULL; + static uid_t guest_uid = (uid_t)-1; + static gid_t guest_gid = (gid_t)-1; + static fstring guest_name; if (!pass) { - /* Don't need to free() this as its stored in a static */ - pass = getpwnam_alloc(lp_guestaccount()); + pass = Get_Pwnam(lp_guestaccount(-1),True); if (!pass) return(False); + guest_uid = pass->pw_uid; + guest_gid = pass->pw_gid; + fstrcpy(guest_name, pass->pw_name); } #ifdef AIX /* MWW: From AIX FAQ patch to WU-ftpd: call initgroups before setting IDs */ - initgroups(pass->pw_name, pass->pw_gid); + initgroups(guest_name, guest_gid); #endif - set_sec_ctx(pass->pw_uid, pass->pw_gid, 0, NULL, NULL); + set_sec_ctx(guest_uid, guest_gid, 0, NULL, NULL); current_user.conn = NULL; current_user.vuid = UID_FIELD_INVALID; @@ -59,26 +65,18 @@ BOOL change_to_guest(void) static BOOL check_user_ok(connection_struct *conn, user_struct *vuser,int snum) { int i; - for (i=0;i<conn->vuid_cache.entries && i< VUID_CACHE_SIZE;i++) - if (conn->vuid_cache.list[i] == vuser->vuid) + for (i=0;i<conn->uid_cache.entries;i++) + if (conn->uid_cache.list[i] == vuser->uid) return(True); - if ((conn->force_user || conn->force_group) - && (conn->vuid != vuser->vuid)) { - return False; - } - if (!user_ok(vuser->user.unix_name,snum)) return(False); - if (!share_access_check(conn, snum, vuser, conn->read_only ? FILE_READ_DATA : FILE_WRITE_DATA)) { - return False; - } - - i = conn->vuid_cache.entries % VUID_CACHE_SIZE; - conn->vuid_cache.list[i] = vuser->vuid; + i = conn->uid_cache.entries % UID_CACHE_SIZE; + conn->uid_cache.list[i] = vuser->uid; - conn->vuid_cache.entries++; + if (conn->uid_cache.entries < UID_CACHE_SIZE) + conn->uid_cache.entries++; return(True); } @@ -116,28 +114,35 @@ BOOL change_to_user(connection_struct *conn, uint16 vuid) return(True); } else if ((current_user.conn == conn) && (vuser != 0) && (current_user.vuid == vuid) && - (current_user.uid == vuser->uid)) { + (current_user.uid == vuser->uid)) + { DEBUG(4,("change_to_user: Skipping user change - already user\n")); - return(True); + return True; } snum = SNUM(conn); - if (conn->force_user) /* security = share sets this too */ { + if((vuser != NULL) && !check_user_ok(conn, vuser, snum)) + return False; + + if (conn->force_user || + conn->admin_user || + (lp_security() == SEC_SHARE)) { uid = conn->uid; gid = conn->gid; current_user.groups = conn->groups; current_user.ngroups = conn->ngroups; token = conn->nt_user_token; - } else if ((vuser) && check_user_ok(conn, vuser, snum)) { + } else { + if (!vuser) { + DEBUG(2,("change_to_user: Invalid vuid used %d\n",vuid)); + return(False); + } uid = vuser->uid; gid = vuser->gid; current_user.ngroups = vuser->n_groups; current_user.groups = vuser->groups; token = vuser->nt_user_token; - } else { - DEBUG(2,("change_to_user: Invalid vuid used %d or vuid not permitted access to share.\n",vuid)); - return False; } /* @@ -177,11 +182,7 @@ BOOL change_to_user(connection_struct *conn, uint16 vuid) if (vuser && vuser->guest) is_guest = True; - token = create_nt_token(uid, gid, current_user.ngroups, current_user.groups, is_guest); - if (!token) { - DEBUG(1, ("change_to_user: create_nt_token failed!\n")); - return False; - } + token = create_nt_token(uid, gid, current_user.ngroups, current_user.groups, is_guest, NULL); must_free_token = True; } @@ -438,58 +439,70 @@ void add_supplementary_nt_login_groups(int *n_groups, gid_t **pp_groups, NT_USER /***************************************************************** *THE CANONICAL* convert name to SID function. - Tries local lookup first - for local domains - then uses winbind. + Tries winbind first - then uses local lookup. *****************************************************************/ -BOOL lookup_name(const char *domain, const char *name, DOM_SID *psid, enum SID_NAME_USE *name_type) +BOOL lookup_name(const char *name, DOM_SID *psid, enum SID_NAME_USE *name_type) { extern pstring global_myname; extern fstring global_myworkgroup; fstring sid; - BOOL local_lookup = False; - + char *sep = lp_winbind_separator(); + *name_type = SID_NAME_UNKNOWN; - /* If we are looking up a domain user, make sure it is - for the local machine only */ - - if (strequal(global_myname, domain)) { - local_lookup = True; - } else if (lp_server_role() == ROLE_DOMAIN_PDC || - lp_server_role() == ROLE_DOMAIN_PDC) { - if (strequal(domain, global_myworkgroup)) { - local_lookup = True; + if (!winbind_lookup_name(NULL, name, psid, name_type) || (*name_type != SID_NAME_USER) ) { + BOOL ret = False; + + DEBUG(10, ("lookup_name: winbind lookup for %s failed - trying local\n", name)); + + /* If we are looking up a domain user, make sure it is + for the local machine only */ + + if (strchr(name, sep[0]) || strchr(name, '\\')) { + fstring domain, username; + + split_domain_name(name, domain, username); + + switch (lp_server_role()) { + case ROLE_DOMAIN_PDC: + case ROLE_DOMAIN_BDC: + if (strequal(domain, global_myworkgroup)) { + fstrcpy(domain, global_myname); + ret = local_lookup_name(domain, username, psid, name_type); + } + /* No break is deliberate here. JRA. */ + default: + if (strcasecmp(global_myname, domain) != 0) { + DEBUG(5, ("lookup_name: domain %s is not local\n", domain)); + ret = local_lookup_name(global_myname, username, psid, name_type); + } + } + } else { + ret = local_lookup_name(global_myname, name, psid, name_type); } - } - - if (local_lookup) { - if (local_lookup_name(name, psid, name_type)) { + + if (ret) { DEBUG(10, - ("lookup_name: (local) [%s]\\[%s] -> SID %s (type %s: %u)\n", - domain, name, sid_to_string(sid,psid), - sid_type_lookup(*name_type), (unsigned int)*name_type)); - return True; - } - } else { - /* Remote */ - if (winbind_lookup_name(domain, name, psid, name_type)) { - - DEBUG(10,("lookup_name (winbindd): [%s]\\[%s] -> SID %s (type %u)\n", - domain, name, sid_to_string(sid, psid), - (unsigned int)*name_type)); - return True; + ("lookup_name: (local) %s -> SID %s (type %u)\n", + name, sid_to_string(sid,psid), + (unsigned int)*name_type )); + } else { + DEBUG(10,("lookup name: (local) %s failed.\n", name)); } + + return ret; } - - DEBUG(10, ("lookup_name: %s lookup for [%s]\\[%s] failed\n", - local_lookup ? "local" : "winbind", domain, name)); - return False; + DEBUG(10,("lookup_name (winbindd): %s -> SID %s (type %u)\n", + name, sid_to_string(sid, psid), + (unsigned int)*name_type)); + return True; } /***************************************************************** *THE CANONICAL* convert SID to name function. - Tries local lookup first - for local sids, then tries winbind. + Tries winbind first - then uses local lookup. *****************************************************************/ BOOL lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, enum SID_NAME_USE *name_type) @@ -509,10 +522,10 @@ BOOL lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, enum SID_NAME_USE sid_copy(&tmp_sid, sid); sid_split_rid(&tmp_sid, &rid); - if (sid_equal(get_global_sam_sid(), &tmp_sid)) { + if (sid_equal(&global_sam_sid, &tmp_sid)) { return map_domain_sid_to_name(&tmp_sid, dom_name) && - local_lookup_sid(sid, name, name_type); + local_lookup_rid(rid, name, name_type); } } @@ -526,7 +539,7 @@ BOOL lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, enum SID_NAME_USE 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); + lookup_known_rid(&tmp_sid, rid, name, name_type); } return True; } @@ -551,12 +564,9 @@ 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; @@ -583,8 +593,7 @@ DOM_SID *gid_to_sid(DOM_SID *psid, gid_t gid) } } - /* Make sure we report failure, (when psid == NULL) */ - psid = local_gid_to_sid(psid, gid); + local_gid_to_sid(psid, gid); DEBUG(10,("gid_to_sid: local %u -> %s\n", (unsigned int)gid, sid_to_string(sid, psid))); @@ -598,40 +607,27 @@ DOM_SID *gid_to_sid(DOM_SID *psid, gid_t gid) was done correctly, False if not. sidtype is set by this function. *****************************************************************/ -BOOL sid_to_uid(const DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype) +BOOL sid_to_uid(DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype) { - fstring sid_str; + fstring dom_name, name, sid_str; + enum SID_NAME_USE name_type; - /* if we know its local then don't try winbindd */ - if (sid_compare_domain(get_global_sam_sid(), psid) == 0) { - BOOL result; - become_root(); - result = local_sid_to_uid(puid, psid, sidtype); - unbecome_root(); - return result; - } -/* (tridge) I commented out the slab of code below in order to support foreign SIDs - Do we really need to validate the type of SID we have in this case? -*/ -#if 0 - fstring dom_name, name; - enum SID_NAME_USE name_type; + /* if we know its local then don't try winbindd */ + if (sid_compare_domain(&global_sam_sid, psid) == 0) + return local_sid_to_uid(puid, psid, sidtype); *sidtype = SID_NAME_UNKNOWN; + /* * First we must look up the name and decide if this is a user sid. */ 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) )); - become_root(); - result = local_sid_to_uid(puid, psid, sidtype); - unbecome_root(); - return result; + return local_sid_to_uid(puid, psid, sidtype); } /* @@ -643,7 +639,7 @@ BOOL sid_to_uid(const DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype) (unsigned int)name_type )); return False; } -#endif + *sidtype = SID_NAME_USER; /* @@ -651,13 +647,9 @@ BOOL sid_to_uid(const 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) )); - become_root(); - result = local_sid_to_uid(puid, psid, sidtype); - unbecome_root(); - return result; + return local_sid_to_uid(puid, psid, sidtype);; } DEBUG(10,("sid_to_uid: winbindd %s -> %u\n", @@ -674,7 +666,7 @@ BOOL sid_to_uid(const DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype) was done correctly, False if not. *****************************************************************/ -BOOL sid_to_gid(const DOM_SID *psid, gid_t *pgid, enum SID_NAME_USE *sidtype) +BOOL sid_to_gid(DOM_SID *psid, gid_t *pgid, enum SID_NAME_USE *sidtype) { fstring dom_name, name, sid_str; enum SID_NAME_USE name_type; @@ -685,21 +677,11 @@ BOOL sid_to_gid(const DOM_SID *psid, gid_t *pgid, enum SID_NAME_USE *sidtype) * First we must look up the name and decide if this is a group sid. */ - /* if we know its local then don't try winbindd */ - if (sid_compare_domain(get_global_sam_sid(), psid) == 0) { - BOOL result; - become_root(); - result = local_sid_to_gid(pgid, psid, sidtype); - unbecome_root(); - return result; - } - if (!winbind_lookup_sid(psid, dom_name, name, &name_type)) { - DEBUG(10,("sid_to_gid: winbind lookup for sid %s failed.\n", + DEBUG(10,("sid_to_gid: winbind lookup for sid %s failed - trying local.\n", sid_to_string(sid_str, psid) )); - /* this was probably a foreign sid - assume its a group rid - and continue */ - name_type = SID_NAME_DOM_GRP; + + return local_sid_to_gid(pgid, psid, sidtype); } /* @@ -710,7 +692,7 @@ BOOL sid_to_gid(const DOM_SID *psid, gid_t *pgid, enum SID_NAME_USE *sidtype) DEBUG(10,("sid_to_gid: winbind lookup succeeded but SID is not a known group (%u)\n", (unsigned int)name_type )); - return False; + return local_sid_to_gid(pgid, psid, sidtype); } *sidtype = name_type; @@ -731,4 +713,3 @@ BOOL sid_to_gid(const DOM_SID *psid, gid_t *pgid, enum SID_NAME_USE *sidtype) return True; } - |