summaryrefslogtreecommitdiffstats
path: root/source/smbd/uid.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/smbd/uid.c')
-rw-r--r--source/smbd/uid.c219
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;
}
-