diff options
author | Jeremy Allison <jra@samba.org> | 2000-10-13 01:59:14 +0000 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2000-10-13 01:59:14 +0000 |
commit | 330d678fbad70fabd9712c56ad15bd215f950255 (patch) | |
tree | df834b65049fb3c675119cf6acfefa167cb96376 /source3/smbd | |
parent | a7f8d8b6362f4c2970fee63130963734528bcb6e (diff) | |
download | samba-330d678fbad70fabd9712c56ad15bd215f950255.tar.gz samba-330d678fbad70fabd9712c56ad15bd215f950255.tar.bz2 samba-330d678fbad70fabd9712c56ad15bd215f950255.zip |
Fix to allow smbd to call winbindd if it is running for all group enumeration,
falling back to the UNIX calls on error. This should fix all problems with
smbd enumerating all users in all groups in all trusted domains via winbindd.
Also changed GETDC to query 1C name rather than 1b name as only the PDC
registers 1b.
Jeremy.
(This used to be commit 5b0038a2afd8abbd6fd4a58f5477a40d1926d498)
Diffstat (limited to 'source3/smbd')
-rw-r--r-- | source3/smbd/groupname.c | 10 | ||||
-rw-r--r-- | source3/smbd/service.c | 16 | ||||
-rw-r--r-- | source3/smbd/uid.c | 226 |
3 files changed, 237 insertions, 15 deletions
diff --git a/source3/smbd/groupname.c b/source3/smbd/groupname.c index f0b11e1b36..d53fa56a44 100644 --- a/source3/smbd/groupname.c +++ b/source3/smbd/groupname.c @@ -119,7 +119,7 @@ void load_groupname_map(void) for (i=0; lines[i]; i++) { pstring unixname; pstring windows_name; - struct group *gptr; + gid_t gid; DOM_SID tmp_sid; char *s = lines[i]; @@ -150,8 +150,8 @@ void load_groupname_map(void) * Attempt to get the unix gid_t for this name. */ - if((gptr = (struct group *)getgrnam(unixname)) == NULL) { - DEBUG(0,("load_groupname_map: getgrnam for group %s failed.\ + if ((gid = nametogid(unixname)) == (gid_t)-1) + DEBUG(0,("load_groupname_map: nametogid for group %s failed.\ Error was %s.\n", unixname, strerror(errno) )); continue; } @@ -167,7 +167,7 @@ Error was %s.\n", unixname, strerror(errno) )); */ tmp_sid = global_sam_sid; tmp_sid.sub_auths[tmp_sid.num_auths++] = - pdb_gid_to_group_rid((gid_t)gptr->gr_gid); + pdb_gid_to_group_rid(gid); } /* @@ -180,7 +180,7 @@ Error was %s.\n", unixname, strerror(errno) )); return; } - new_ep->unix_gid = gptr->gr_gid; + new_ep->unix_gid = gid; new_ep->windows_sid = tmp_sid; new_ep->windows_name = strdup( windows_name ); new_ep->unix_name = strdup( unixname ); diff --git a/source3/smbd/service.c b/source3/smbd/service.c index 6d07562743..b86f3beadd 100644 --- a/source3/smbd/service.c +++ b/source3/smbd/service.c @@ -401,7 +401,7 @@ connection_struct *make_connection(char *service,char *user,char *password, int */ if (*lp_force_group(snum)) { - struct group *gptr; + gid_t gid; pstring gname; pstring tmp_gname; BOOL user_must_be_member = False; @@ -416,9 +416,9 @@ connection_struct *make_connection(char *service,char *user,char *password, int } /* default service may be a group name */ pstring_sub(gname,"%S",service); - gptr = (struct group *)getgrnam(gname); + gid = nametogid(gname); - if (gptr) { + if (gid != (gid_t)-1) { /* * If the user has been forced and the forced group starts * with a '+', then we only set the group to be the forced @@ -426,16 +426,12 @@ connection_struct *make_connection(char *service,char *user,char *password, int * Otherwise, the meaning of the '+' would be ignored. */ if (conn->force_user && user_must_be_member) { - int i; - for (i = 0; gptr->gr_mem[i] != NULL; i++) { - if (strcmp(user,gptr->gr_mem[i]) == 0) { - conn->gid = gptr->gr_gid; + if (user_in_group_list( user, gname )) { + conn->gid = gid; DEBUG(3,("Forced group %s for member %s\n",gname,user)); - break; - } } } else { - conn->gid = gptr->gr_gid; + conn->gid = gid; DEBUG(3,("Forced group %s\n",gname)); } } else { diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index b28f056a30..fb83e724b8 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -257,4 +257,230 @@ void unbecome_root(void) pop_sec_ctx(); } +/***************************************************************** + *THE CANONICAL* convert name to SID function. + Tries winbind first - then uses local lookup. +*****************************************************************/ + +BOOL lookup_name(char *name, DOM_SID *psid, enum SID_NAME_USE *name_type) +{ + extern pstring global_myname; + fstring sid; + + if (!winbind_lookup_name(name, psid, name_type)) { + BOOL ret; + + DEBUG(10,("lookup_name: winbind lookup for %s failed - trying local\n", name )); + + ret = local_lookup_name(global_myname, name, psid, name_type); + if (ret) + DEBUG(10,("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 (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 winbind first - then uses local lookup. +*****************************************************************/ + +BOOL lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, enum SID_NAME_USE *name_type) +{ + if (!name_type) + return False; + + /* Check if this is our own sid. This should perhaps be done by + winbind? For the moment handle it here. */ + + if (sid->num_auths == 5) { + DOM_SID tmp_sid; + uint32 rid; + + sid_copy(&tmp_sid, sid); + sid_split_rid(&tmp_sid, &rid); + + if (sid_equal(&global_sam_sid, &tmp_sid)) { + + return map_domain_sid_to_name(&tmp_sid, dom_name) && + local_lookup_rid(rid, name, 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 CANONICAL* 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) +{ + fstring sid; + + 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); + } + + DEBUG(10,("uid_to_sid: winbindd %u -> %s\n", + (unsigned int)uid, sid_to_string(sid, psid) )); + + return psid; +} + +/***************************************************************** + *THE CANONICAL* 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) +{ + fstring sid; + + 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); + } + + DEBUG(10,("gid_to_sid: winbindd %u -> %s\n", + (unsigned int)gid, sid_to_string(sid,psid) )); + + return psid; +} + +/***************************************************************** + *THE CANONICAL* convert SID to uid function. + Tries winbind first - then uses local lookup. + Returns True if this name is a user sid and the conversion + was done correctly, False if not. +*****************************************************************/ + +BOOL sid_to_uid(DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype) +{ + fstring dom_name, name, sid_str; + enum SID_NAME_USE name_type; + + *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)) { + 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); + } + + /* + * Ensure this is a user sid. + */ + + if (name_type != SID_NAME_USER) { + DEBUG(10,("sid_to_uid: winbind lookup succeeded but SID is not a uid (%u)\n", + (unsigned int)name_type )); + return False; + } + + *sidtype = SID_NAME_USER; + + /* + * Get the uid for this SID. + */ + + if (!winbind_sid_to_uid(puid, psid)) { + DEBUG(10,("sid_to_uid: winbind lookup for sid %s failed.\n", + sid_to_string(sid_str, psid) )); + return False; + } + + DEBUG(10,("sid_to_uid: winbindd %s -> %u\n", + sid_to_string(sid_str, psid), + (unsigned int)*puid )); + + return True; +} + +/***************************************************************** + *THE CANONICAL* convert SID to gid function. + Tries winbind first - then uses local lookup. + Returns True if this name is a user sid and the conversion + was done correctly, False if not. +*****************************************************************/ + +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; + + *sidtype = SID_NAME_UNKNOWN; + + /* + * First we must look up the name and decide if this is a group sid. + */ + + 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) )); + + return local_sid_to_gid(pgid, psid, sidtype); + } + + /* + * Ensure this is a group sid. + */ + + if ((name_type != SID_NAME_DOM_GRP) && (name_type != SID_NAME_ALIAS) && (name_type != SID_NAME_WKN_GRP)) { + DEBUG(10,("sid_to_gid: winbind lookup succeeded but SID is not a know group (%u)\n", + (unsigned int)name_type )); + + return local_sid_to_gid(pgid, psid, sidtype); + } + + *sidtype = name_type; + + /* + * Get the gid for this SID. + */ + + if (!winbind_sid_to_gid(pgid, psid)) { + DEBUG(10,("sid_to_gid: winbind lookup for sid %s failed.\n", + sid_to_string(sid_str, psid) )); + return False; + } + + DEBUG(10,("gid_to_uid: winbindd %s -> %u\n", + sid_to_string(sid_str, psid), + (unsigned int)*pgid )); + + return True; +} + #undef OLD_NTDOMAIN |