The Samba-Bugzilla – Attachment 235 Details for
Bug 680
Winbindd and idmap backend without LDAP instead local files.
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
allow winbindd to match SIDs to local user and groups
winbind_uid2sid.patch (text/plain), 30.12 KB, created by
Gerald (Jerry) Carter (dead mail address)
on 2003-11-04 09:01:38 UTC
(
hide
)
Description:
allow winbindd to match SIDs to local user and groups
Filename:
MIME Type:
Creator:
Gerald (Jerry) Carter (dead mail address)
Created:
2003-11-04 09:01:38 UTC
Size:
30.12 KB
patch
obsolete
>? 1 >? ChangeLog >? build-me >? look >? pchdir >? share_sec_admin_users.patch >? test-build >? update-samba >? intl/libgettext.h >Index: nsswitch/winbindd_sid.c >=================================================================== >RCS file: /data/cvs/samba/source/nsswitch/winbindd_sid.c,v >retrieving revision 1.12.2.10 >diff -u -r1.12.2.10 winbindd_sid.c >--- nsswitch/winbindd_sid.c 13 Aug 2003 00:08:28 -0000 1.12.2.10 >+++ nsswitch/winbindd_sid.c 4 Nov 2003 16:59:42 -0000 >@@ -130,16 +130,75 @@ > DEBUG(3, ("[%5lu]: sid to uid %s\n", (unsigned long)state->pid, > state->request.data.sid)); > >- /* Split sid into domain sid and user rid */ > if (!string_to_sid(&sid, state->request.data.sid)) { > DEBUG(1, ("Could not get convert sid %s from string\n", state->request.data.sid)); > return WINBINDD_ERROR; > } > >+ /* This gets a little tricky. If we assume that usernames are syncd between >+ /etc/passwd and the windows domain (such as a member of a Samba domain), >+ the we need to get the uid from the OS and not alocate one ourselves */ >+ >+ if ( lp_winbind_trusted_domains_only() ) { >+ struct winbindd_domain *domain = NULL; >+ DOM_SID sid2; >+ uint32 rid; >+ >+ domain = find_domain_from_name( lp_workgroup() ); >+ if ( !domain ) { >+ DEBUG(0,("winbindd_sid_to_uid: can't find my own domain!\n")); >+ return WINBINDD_ERROR; >+ } >+ >+ sid_copy( &sid2, &sid ); >+ sid_split_rid( &sid2, &rid ); >+ >+ if ( sid_equal( &sid2, &domain->sid ) ) { >+ >+ fstring domain_name; >+ fstring user; >+ enum SID_NAME_USE type; >+ struct passwd *pw = NULL; >+ unid_t id; >+ >+ /* ok...here's we know that we are dealing with our >+ own domain (the one to which we are joined). And >+ we know that there must be a UNIX account for this user. >+ So we lookup the sid and the call getpwnam().*/ >+ >+ >+ /* But first check and see if we don't already have a mapping */ >+ >+ flags = ID_QUERY_ONLY; >+ if ( NT_STATUS_IS_OK(idmap_sid_to_uid(&sid, &(state->response.data.uid), flags)) ) >+ return WINBINDD_OK; >+ >+ /* now fall back to the hard way */ >+ >+ if ( !winbindd_lookup_name_by_sid(&sid, domain_name, user, &type) ) >+ return WINBINDD_ERROR; >+ >+ if ( !(pw = getpwnam(user)) ) { >+ DEBUG(0,("winbindd_sid_to_uid: 'winbind trusted domains only' is " >+ "set but this user [%s] doesn't exist!\n", user)); >+ return WINBINDD_ERROR; >+ } >+ >+ state->response.data.uid = pw->pw_uid; >+ >+ id.uid = pw->pw_uid; >+ idmap_set_mapping( &sid, id, ID_USERID ); >+ >+ return WINBINDD_OK; >+ } >+ >+ } >+ > if ( state->request.flags & WBFLAG_QUERY_ONLY ) > flags = ID_QUERY_ONLY; > > /* Find uid for this sid and return it */ >+ > if ( !NT_STATUS_IS_OK(idmap_sid_to_uid(&sid, &(state->response.data.uid), flags)) ) { > DEBUG(1, ("Could not get uid for sid %s\n", state->request.data.sid)); > return WINBINDD_ERROR; >@@ -167,6 +226,64 @@ > return WINBINDD_ERROR; > } > >+ /* This gets a little tricky. If we assume that usernames are syncd between >+ /etc/passwd and the windows domain (such as a member of a Samba domain), >+ the we need to get the uid from the OS and not alocate one ourselves */ >+ >+ if ( lp_winbind_trusted_domains_only() ) { >+ struct winbindd_domain *domain = NULL; >+ DOM_SID sid2; >+ uint32 rid; >+ unid_t id; >+ >+ domain = find_domain_from_name( lp_workgroup() ); >+ if ( !domain ) { >+ DEBUG(0,("winbindd_sid_to_uid: can't find my own domain!\n")); >+ return WINBINDD_ERROR; >+ } >+ >+ sid_copy( &sid2, &sid ); >+ sid_split_rid( &sid2, &rid ); >+ >+ if ( sid_equal( &sid2, &domain->sid ) ) { >+ >+ fstring domain_name; >+ fstring group; >+ enum SID_NAME_USE type; >+ struct group *grp = NULL; >+ >+ /* ok...here's we know that we are dealing with our >+ own domain (the one to which we are joined). And >+ we know that there must be a UNIX account for this group. >+ So we lookup the sid and the call getpwnam().*/ >+ >+ /* But first check and see if we don't already have a mapping */ >+ >+ flags = ID_QUERY_ONLY; >+ if ( NT_STATUS_IS_OK(idmap_sid_to_gid(&sid, &(state->response.data.gid), flags)) ) >+ return WINBINDD_OK; >+ >+ /* now fall back to the hard way */ >+ >+ if ( !winbindd_lookup_name_by_sid(&sid, domain_name, group, &type) ) >+ return WINBINDD_ERROR; >+ >+ if ( !(grp = getgrnam(group)) ) { >+ DEBUG(0,("winbindd_sid_to_uid: 'winbind trusted domains only' is " >+ "set but this group [%s] doesn't exist!\n", group)); >+ return WINBINDD_ERROR; >+ } >+ >+ state->response.data.gid = grp->gr_gid; >+ >+ id.gid = grp->gr_gid; >+ idmap_set_mapping( &sid, id, ID_GROUPID ); >+ >+ return WINBINDD_OK; >+ } >+ >+ } >+ > if ( state->request.flags & WBFLAG_QUERY_ONLY ) > flags = ID_QUERY_ONLY; > >@@ -185,28 +302,65 @@ > { > DOM_SID sid; > >-#if 0 /* JERRY */ >- /* we cannot do this check this anymore since a domain member of >- a Samba domain may share unix accounts via NIS or LDAP. In this >- case the uid/gid will be out of winbindd's range but still might >- be resolved to a SID via an ldap idmap backend */ >- >- if ((state->request.data.uid < server_state.uid_low ) || >- (state->request.data.uid > server_state.uid_high)) { >- return WINBINDD_ERROR; >- } >-#endif >- > DEBUG(3, ("[%5lu]: uid to sid %lu\n", (unsigned long)state->pid, > (unsigned long)state->request.data.uid)); > >+ if ( (state->request.data.uid < server_state.uid_low ) >+ || (state->request.data.uid > server_state.uid_high) ) >+ { >+ struct passwd *pw = NULL; >+ enum SID_NAME_USE type; >+ unid_t id; >+ struct winbindd_domain *domain; >+ >+ /* SPECIAL CASE FOR MEMBERS OF SAMBA DOMAINS */ >+ >+ /* if we don't trust /etc/password then when can't know >+ anything about this uid */ >+ >+ if ( !lp_winbind_trusted_domains_only() ) >+ return WINBINDD_ERROR; >+ >+ >+ /* look for an idmap entry first */ >+ >+ if ( NT_STATUS_IS_OK(idmap_uid_to_sid(&sid, state->request.data.uid)) ) >+ goto done; >+ >+ /* if users exist in /etc/passwd, we should try to >+ use that uid. Get the username and the lookup the SID */ >+ >+ if ( !(pw = getpwuid(state->request.data.uid)) ) >+ return WINBINDD_ERROR; >+ >+ if ( !(domain = find_domain_from_name(lp_workgroup())) ) { >+ DEBUG(0,("winbindd_uid_to_sid: can't find my own domain!\n")); >+ return WINBINDD_ERROR; >+ } >+ >+ if ( !winbindd_lookup_sid_by_name(domain, pw->pw_name, &sid, &type) ) >+ return WINBINDD_ERROR; >+ >+ if ( type != SID_NAME_USER ) >+ return WINBINDD_ERROR; >+ >+ /* don't fail if we can't store it */ >+ >+ id.uid = pw->pw_uid; >+ idmap_set_mapping( &sid, id, ID_USERID ); >+ >+ goto done; >+ } >+ > /* Lookup rid for this uid */ >+ > if (!NT_STATUS_IS_OK(idmap_uid_to_sid(&sid, state->request.data.uid))) { > DEBUG(1, ("Could not convert uid %lu to rid\n", > (unsigned long)state->request.data.uid)); > return WINBINDD_ERROR; > } > >+done: > sid_to_string(state->response.data.sid.sid, &sid); > state->response.data.sid.type = SID_NAME_USER; > >@@ -219,28 +373,64 @@ > { > DOM_SID sid; > >-#if 0 /* JERRY */ >- /* we cannot do this check this anymore since a domain member of >- a Samba domain may share unix accounts via NIS or LDAP. In this >- case the uid/gid will be out of winbindd's range but still might >- be resolved to a SID via an ldap idmap backend */ >- >- if ((state->request.data.gid < server_state.gid_low) || >- (state->request.data.gid > server_state.gid_high)) { >- return WINBINDD_ERROR; >- } >-#endif >- > DEBUG(3, ("[%5lu]: gid to sid %lu\n", (unsigned long)state->pid, > (unsigned long)state->request.data.gid)); >+ >+ if ( (state->request.data.gid < server_state.gid_low) >+ || (state->request.data.gid > server_state.gid_high) ) >+ { >+ struct group *grp = NULL; >+ enum SID_NAME_USE type; >+ unid_t id; >+ struct winbindd_domain *domain; >+ >+ /* SPECIAL CASE FOR MEMBERS OF SAMBA DOMAINS */ >+ >+ /* if we don't trust /etc/group then when can't know >+ anything about this gid */ >+ >+ if ( !lp_winbind_trusted_domains_only() ) >+ return WINBINDD_ERROR; >+ >+ /* look for an idmap entry first */ >+ >+ if ( NT_STATUS_IS_OK(idmap_gid_to_sid(&sid, state->request.data.gid)) ) >+ goto done; >+ >+ /* if users exist in /etc/group, we should try to >+ use that gid. Get the username and the lookup the SID */ >+ >+ if ( !(grp = getgrgid(state->request.data.gid)) ) >+ return WINBINDD_ERROR; >+ >+ if ( !(domain = find_domain_from_name(lp_workgroup())) ) { >+ DEBUG(0,("winbindd_uid_to_sid: can't find my own domain!\n")); >+ return WINBINDD_ERROR; >+ } >+ >+ if ( !winbindd_lookup_sid_by_name(domain, grp->gr_name, &sid, &type) ) >+ return WINBINDD_ERROR; >+ >+ if ( type!=SID_NAME_DOM_GRP && type!=SID_NAME_ALIAS ) >+ return WINBINDD_ERROR; >+ >+ /* don't fail if we can't store it */ >+ >+ id.gid = grp->gr_gid; >+ idmap_set_mapping( &sid, id, ID_GROUPID ); >+ >+ goto done; >+ } > > /* Lookup sid for this uid */ >+ > if (!NT_STATUS_IS_OK(idmap_gid_to_sid(&sid, state->request.data.gid))) { > DEBUG(1, ("Could not convert gid %lu to sid\n", > (unsigned long)state->request.data.gid)); > return WINBINDD_ERROR; > } > >+done: > /* Construct sid and return it */ > sid_to_string(state->response.data.sid.sid, &sid); > state->response.data.sid.type = SID_NAME_DOM_GRP; >Index: passdb/lookup_sid.c >=================================================================== >RCS file: /data/cvs/samba/source/passdb/lookup_sid.c,v >retrieving revision 1.1.2.1 >diff -u -r1.1.2.1 lookup_sid.c >--- passdb/lookup_sid.c 27 Aug 2003 20:52:56 -0000 1.1.2.1 >+++ passdb/lookup_sid.c 4 Nov 2003 16:59:43 -0000 >@@ -299,15 +299,20 @@ > > NTSTATUS uid_to_sid(DOM_SID *psid, uid_t uid) > { >- uid_t low, high; > fstring sid; >+ uid_t low, high; > > ZERO_STRUCTP(psid); > > if (fetch_sid_from_uid_cache(psid, uid)) > return ( psid ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL ); > >- if (lp_idmap_uid(&low, &high) && uid >= low && uid <= high) { >+ /* DC's never use winbindd to resolve users outside the >+ defined idmap range */ >+ >+ if ( lp_server_role()==ROLE_DOMAIN_MEMBER >+ || (lp_idmap_uid(&low, &high) && uid >= low && uid <= high) ) >+ { > if (winbind_uid_to_sid(psid, uid)) { > > DEBUG(10,("uid_to_sid: winbindd %u -> %s\n", >@@ -336,15 +341,20 @@ > > NTSTATUS gid_to_sid(DOM_SID *psid, gid_t gid) > { >- gid_t low, high; > fstring sid; >+ gid_t low, high; > > ZERO_STRUCTP(psid); > > if (fetch_sid_from_gid_cache(psid, gid)) > return ( psid ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL ); > >- if (lp_idmap_gid(&low, &high) && gid >= low && gid <= high) { >+ /* DC's never use winbindd to resolve groups outside the >+ defined idmap range */ >+ >+ if ( lp_server_role()==ROLE_DOMAIN_MEMBER >+ || (lp_idmap_gid(&low, &high) && gid >= low && gid <= high) ) >+ { > if (winbind_gid_to_sid(psid, gid)) { > > DEBUG(10,("gid_to_sid: winbindd %u -> %s\n", >@@ -458,7 +468,9 @@ > > /* winbindd knows it; Ensure this is a group sid */ > >- if ((name_type != SID_NAME_DOM_GRP) && (name_type != SID_NAME_ALIAS) && (name_type != SID_NAME_WKN_GRP)) { >+ 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 known group (%u)\n", > (unsigned int)name_type )); > >Index: sam/idmap_ldap.c >=================================================================== >RCS file: /data/cvs/samba/source/sam/idmap_ldap.c,v >retrieving revision 1.1.2.17 >diff -u -r1.1.2.17 idmap_ldap.c >--- sam/idmap_ldap.c 10 Sep 2003 23:49:23 -0000 1.1.2.17 >+++ sam/idmap_ldap.c 4 Nov 2003 16:59:45 -0000 >@@ -1,4 +1,4 @@ >-/* >+/* > Unix SMB/CIFS implementation. > > idmap LDAP backend >@@ -7,17 +7,17 @@ > Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003 > Copyright (C) Simo Sorce 2003 > Copyright (C) Gerald Carter 2003 >- >+ > This program is free software; you can redistribute it and/or modify > it under the terms of the GNU General Public License as published by > the Free Software Foundation; either version 2 of the License, or > (at your option) any later version. >- >+ > This program is distributed in the hope that it will be useful, > but WITHOUT ANY WARRANTY; without even the implied warranty of > MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > GNU General Public License for more details. >- >+ > You should have received a copy of the GNU General Public License > along with this program; if not, write to the Free Software > Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. >@@ -34,25 +34,84 @@ > > #include "smbldap.h" > >-#define IDMAP_GROUP_SUFFIX "ou=idmap group" >-#define IDMAP_USER_SUFFIX "ou=idmap people" >- >- > struct ldap_idmap_state { > struct smbldap_state *smbldap_state; > TALLOC_CTX *mem_ctx; > }; > >-#define LDAP_MAX_ALLOC_ID 128 /* number tries while allocating >- new id */ >- > static struct ldap_idmap_state ldap_state; > >-static NTSTATUS ldap_set_mapping(const DOM_SID *sid, unid_t id, int id_type); >-static NTSTATUS ldap_set_mapping_internals(const DOM_SID *sid, unid_t id, int id_type, >- const char *ldap_dn, LDAPMessage *entry); >-static NTSTATUS ldap_idmap_close(void); >+/* number tries while allocating new id */ >+#define LDAP_MAX_ALLOC_ID 128 >+ >+ >+/*********************************************************************** >+ This function cannot be called to modify a mapping, only set a new one >+***********************************************************************/ >+ >+static NTSTATUS ldap_set_mapping(const DOM_SID *sid, unid_t id, int id_type) >+{ >+ pstring dn; >+ pstring id_str; >+ fstring type; >+ LDAPMod **mods = NULL; >+ int rc = -1; >+ int ldap_op; >+ fstring sid_string; >+ LDAPMessage *entry = NULL; >+ >+ sid_to_string( sid_string, sid ); >+ >+ ldap_op = LDAP_MOD_ADD; >+ pstr_sprintf(dn, "%s=%s,%s", get_attr_key2string( sidmap_attr_list, LDAP_ATTR_SID), >+ sid_string, lp_ldap_idmap_suffix()); >+ >+ if ( id_type & ID_USERID ) >+ fstrcpy( type, get_attr_key2string( sidmap_attr_list, LDAP_ATTR_UIDNUMBER ) ); >+ else >+ fstrcpy( type, get_attr_key2string( sidmap_attr_list, LDAP_ATTR_GIDNUMBER ) ); >+ >+ pstr_sprintf(id_str, "%lu", ((id_type & ID_USERID) ? (unsigned long)id.uid : >+ (unsigned long)id.gid)); >+ >+ smbldap_set_mod( &mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_IDMAP_ENTRY ); >+ >+ smbldap_make_mod( ldap_state.smbldap_state->ldap_struct, >+ entry, &mods, type, id_str ); >+ >+ smbldap_make_mod( ldap_state.smbldap_state->ldap_struct, >+ entry, &mods, >+ get_attr_key2string(sidmap_attr_list, LDAP_ATTR_SID), >+ sid_string ); >+ >+ /* There may well be nothing at all to do */ >+ >+ if (mods) { >+ smbldap_set_mod( &mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_SID_ENTRY ); >+ rc = smbldap_add(ldap_state.smbldap_state, dn, mods); >+ ldap_mods_free( mods, True ); >+ } else { >+ rc = LDAP_SUCCESS; >+ } >+ >+ if (rc != LDAP_SUCCESS) { >+ char *ld_error = NULL; >+ ldap_get_option(ldap_state.smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, >+ &ld_error); >+ DEBUG(0,("ldap_set_mapping_internals: Failed to %s mapping from %s to %lu [%s]\n", >+ (ldap_op == LDAP_MOD_ADD) ? "add" : "replace", >+ sid_string, (unsigned long)((id_type & ID_USERID) ? id.uid : id.gid), type)); >+ DEBUG(0, ("ldap_set_mapping_internals: Error was: %s (%s)\n", >+ ld_error ? ld_error : "(NULL)", ldap_err2string (rc))); >+ return NT_STATUS_UNSUCCESSFUL; >+ } >+ >+ DEBUG(10,("ldap_set_mapping: Successfully created mapping from %s to %lu [%s]\n", >+ sid_string, ((id_type & ID_USERID) ? (unsigned long)id.uid : >+ (unsigned long)id.gid), type)); > >+ return NT_STATUS_OK; >+} > > /********************************************************************** > Even if the sambaDomain attribute in LDAP tells us that this RID is >@@ -77,7 +136,7 @@ > if (rc != LDAP_SUCCESS) { > char *ld_error = NULL; > ldap_get_option(state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error); >- DEBUG(2, ("Failed to check if sid %s is alredy in use: %s\n", >+ DEBUG(2, ("Failed to check if sid %s is alredy in use: %s\n", > sid_string, ld_error)); > SAFE_FREE(ld_error); > >@@ -142,7 +201,7 @@ > } > > /* yes, we keep 3 seperate counters, one for rids between 1000 (BASE_RID) and >- algorithmic_rid_base. The other two are to avoid stomping on the >+ algorithmic_rid_base. The other two are to avoid stomping on the > different sets of algorithmic RIDs */ > > if (smbldap_get_single_attribute(state->smbldap_state->ldap_struct, entry, >@@ -337,7 +396,7 @@ > pstr_sprintf(filter, "(objectClass=%s)", LDAP_OBJ_IDPOOL); > > attr_list = get_attr_list( idpool_attr_list ); >- >+ > rc = smbldap_search(ldap_state.smbldap_state, lp_ldap_idmap_suffix(), > LDAP_SCOPE_SUBTREE, filter, > attr_list, 0, &result); >@@ -421,86 +480,45 @@ > { > LDAPMessage *result = NULL; > LDAPMessage *entry = NULL; >- fstring id_str; > pstring sid_str; > pstring filter; > pstring suffix; > const char *type; >- const char *obj_class; > int rc; > int count; > NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; > char **attr_list; > >- /* first we try for a samba user or group mapping */ >- >- if ( id_type & ID_USERID ) { >+ if ( id_type & ID_USERID ) > type = get_attr_key2string( idpool_attr_list, LDAP_ATTR_UIDNUMBER ); >- obj_class = LDAP_OBJ_SAMBASAMACCOUNT; >- fstr_sprintf(id_str, "%lu", (unsigned long)id.uid ); >- pstrcpy( suffix, lp_ldap_suffix()); >- } >- else { >+ else > type = get_attr_key2string( idpool_attr_list, LDAP_ATTR_GIDNUMBER ); >- obj_class = LDAP_OBJ_GROUPMAP; >- fstr_sprintf(id_str, "%lu", (unsigned long)id.gid ); >- pstrcpy( suffix, lp_ldap_group_suffix() ); >- } >+ >+ pstrcpy( suffix, lp_ldap_idmap_suffix() ); >+ pstr_sprintf(filter, "(&(objectClass=%s)(%s=%lu))", >+ LDAP_OBJ_IDMAP_ENTRY, type, >+ ((id_type & ID_USERID) ? (unsigned long)id.uid : (unsigned long)id.gid)); >+ > > DEBUG(5,("ldap_get_sid_from_id: Searching \"%s\"\n", filter )); > > attr_list = get_attr_list( sidmap_attr_list ); >- pstr_sprintf(filter, "(&(|(objectClass=%s)(objectClass=%s))(%s=%s))", >- LDAP_OBJ_IDMAP_ENTRY, obj_class, type, id_str); >- > rc = smbldap_search(ldap_state.smbldap_state, suffix, LDAP_SCOPE_SUBTREE, >- filter, attr_list, 0, &result); >- >+ filter, attr_list, 0, &result); >+ > if (rc != LDAP_SUCCESS) { > DEBUG(3,("ldap_get_isd_from_id: Failure looking up entry (%s)\n", > ldap_err2string(rc) )); > goto out; > } >- >- count = ldap_count_entries(ldap_state.smbldap_state->ldap_struct, result); >- >- if (count > 1) { >- DEBUG(0,("ldap_get_sid_from_id: mapping returned [%d] entries!\n", >- count)); >- goto out; >- } >- >- /* fall back to looking up an idmap entry if we didn't find and >- actual user or group */ >- >- if (count == 0) { >- ldap_msgfree(result); >- result = NULL; >- >- pstr_sprintf(filter, "(&(objectClass=%s)(%s=%lu))", >- LDAP_OBJ_IDMAP_ENTRY, type, >- ((id_type & ID_USERID) ? (unsigned long)id.uid : >- (unsigned long)id.gid)); >- >- pstrcpy( suffix, lp_ldap_idmap_suffix() ); >- >- rc = smbldap_search(ldap_state.smbldap_state, suffix, LDAP_SCOPE_SUBTREE, >- filter, attr_list, 0, &result); >- >- if (rc != LDAP_SUCCESS) { >- DEBUG(3,("ldap_get_isd_from_id: Failure looking up entry (%s)\n", >- ldap_err2string(rc) )); >- goto out; >- } > >- count = ldap_count_entries(ldap_state.smbldap_state->ldap_struct, result); >+ count = ldap_count_entries(ldap_state.smbldap_state->ldap_struct, result); > >- if (count != 1) { >- DEBUG(0,("ldap_get_sid_from_id: mapping not found for %s: %lu\n", >- type, ((id_type & ID_USERID) ? (unsigned long)id.uid : >- (unsigned long)id.gid))); >- goto out; >- } >+ if (count != 1) { >+ DEBUG(0,("ldap_get_sid_from_id: mapping not found for %s: %lu\n", >+ type, ((id_type & ID_USERID) ? (unsigned long)id.uid : >+ (unsigned long)id.gid))); >+ goto out; > } > > entry = ldap_first_entry(ldap_state.smbldap_state->ldap_struct, result); >@@ -508,7 +526,7 @@ > if ( !smbldap_get_single_attribute(ldap_state.smbldap_state->ldap_struct, entry, LDAP_ATTRIBUTE_SID, sid_str) ) > goto out; > >- if (!string_to_sid(sid, sid_str)) >+ if (!string_to_sid(sid, sid_str)) > goto out; > > ret = NT_STATUS_OK; >@@ -545,29 +563,14 @@ > DEBUG(8,("ldap_get_id_from_sid: %s (%s)\n", sid_str, > (*id_type & ID_GROUPID ? "group" : "user") )); > >- /* ahhh.... ok. We have to check users and groups in places other >- than idmap (hint: we're a domain member of a Samba domain) */ >- >- if ( *id_type & ID_GROUPID ) { >- >+ suffix = lp_ldap_idmap_suffix(); >+ pstr_sprintf(filter, "(&(objectClass=%s)(%s=%s))", >+ LDAP_OBJ_IDMAP_ENTRY, LDAP_ATTRIBUTE_SID, sid_str); >+ >+ if ( *id_type & ID_GROUPID ) > type = get_attr_key2string( sidmap_attr_list, LDAP_ATTR_GIDNUMBER ); >- suffix = lp_ldap_group_suffix(); >- pstr_sprintf(filter, "(&(|(objectClass=%s)(objectClass=%s))(%s=%s))", >- LDAP_OBJ_GROUPMAP, LDAP_OBJ_IDMAP_ENTRY, >- get_attr_key2string( sidmap_attr_list, LDAP_ATTR_SID ), >- sid_str); >- >- } >- else { >- >+ else > type = get_attr_key2string( sidmap_attr_list, LDAP_ATTR_UIDNUMBER ); >- suffix = lp_ldap_suffix(); >- pstr_sprintf(filter, "(&(|(&(objectClass=%s)(objectClass=%s))(objectClass=%s))(%s=%s))", >- LDAP_OBJ_SAMBASAMACCOUNT, LDAP_OBJ_POSIXACCOUNT, LDAP_OBJ_IDMAP_ENTRY, >- get_attr_key2string( sidmap_attr_list, LDAP_ATTR_SID ), >- sid_str); >- >- } > > DEBUG(10,("ldap_get_id_from_sid: Searching for \"%s\"\n", filter)); > >@@ -575,84 +578,55 @@ > > attr_list = get_attr_list( sidmap_attr_list ); > rc = smbldap_search(ldap_state.smbldap_state, suffix, LDAP_SCOPE_SUBTREE, >- filter, attr_list, 0, &result); >- >- if ( rc != LDAP_SUCCESS ) { >- DEBUG(3,("ldap_get_id_from_sid: Failure looking up group mapping (%s)\n", >+ filter, attr_list, 0, &result); >+ >+ if (rc != LDAP_SUCCESS) { >+ DEBUG(3,("ldap_get_id_from_sid: Failure looking up idmap entry (%s)\n", > ldap_err2string(rc) )); > goto out; > } >+ >+ /* check for the number of entries returned */ > > count = ldap_count_entries(ldap_state.smbldap_state->ldap_struct, result); >- >+ > if ( count > 1 ) { >- DEBUG(3,("ldap_get_id_from_sid: search \"%s\" returned [%d] entries. Bailing...\n", >+ DEBUG(0, ("ldap_get_id_from_sid: (2nd) search %s returned [%d] entries!\n", > filter, count)); > goto out; > } >+ >+ /* try to allocate a new id if we still haven't found one */ > >- /* see if we need to do a search here */ >- >- if ( count == 0 ) { >- >- if ( result ) { >- ldap_msgfree(result); >- result = NULL; >- } >- >- /* look in idmap suffix */ >- >- suffix = lp_ldap_idmap_suffix(); >- pstr_sprintf(filter, "(&(objectClass=%s)(%s=%s))", >- LDAP_OBJ_IDMAP_ENTRY, LDAP_ATTRIBUTE_SID, sid_str); >+ if ( !count ) { >+ int i; > >- rc = smbldap_search(ldap_state.smbldap_state, suffix, LDAP_SCOPE_SUBTREE, >- filter, attr_list, 0, &result); >- >- if (rc != LDAP_SUCCESS) { >- DEBUG(3,("ldap_get_id_from_sid: Failure looking up idmap entry (%s)\n", >- ldap_err2string(rc) )); >+ if (*id_type & ID_QUERY_ONLY) { >+ DEBUG(5,("ldap_get_id_from_sid: No matching entry found and QUERY_ONLY flag set\n")); > goto out; > } >- >- /* check for the number of entries returned */ > >- count = ldap_count_entries(ldap_state.smbldap_state->ldap_struct, result); >- >- if ( count > 1 ) { >- DEBUG(0, ("ldap_get_id_from_sid: (2nd) search %s returned [%d] entries!\n", >- filter, count)); >- goto out; >- } >- >- >- /* try to allocate a new id if we still haven't found one */ >- >- if ( (count==0) && !(*id_type & ID_QUERY_ONLY) ) { >- int i; >- >- DEBUG(8,("ldap_get_id_from_sid: Allocating new id\n")); >+ DEBUG(8,("ldap_get_id_from_sid: Allocating new id\n")); > >- for (i = 0; i < LDAP_MAX_ALLOC_ID; i++) { >- ret = ldap_allocate_id(id, *id_type); >- if ( NT_STATUS_IS_OK(ret) ) >- break; >- } >+ for (i = 0; i < LDAP_MAX_ALLOC_ID; i++) { >+ ret = ldap_allocate_id(id, *id_type); >+ if ( NT_STATUS_IS_OK(ret) ) >+ break; >+ } > >- if ( !NT_STATUS_IS_OK(ret) ) { >- DEBUG(0,("ldap_allocate_id: cannot acquire id lock!\n")); >- goto out; >- } >+ if ( !NT_STATUS_IS_OK(ret) ) { >+ DEBUG(0,("ldap_allocate_id: cannot acquire id lock!\n")); >+ goto out; >+ } > >- DEBUG(10,("ldap_get_id_from_sid: Allocated new %cid [%ul]\n", >- (*id_type & ID_GROUPID ? 'g' : 'u'), (uint32)id->uid )); >+ DEBUG(10,("ldap_get_id_from_sid: Allocated new %cid [%ul]\n", >+ (*id_type & ID_GROUPID ? 'g' : 'u'), (uint32)id->uid )); > >- ret = ldap_set_mapping(sid, *id, *id_type); >+ ret = ldap_set_mapping(sid, *id, *id_type); > >- /* all done */ >+ /* all done */ > >- goto out; >- } >+ goto out; > } > > DEBUG(10,("ldap_get_id_from_sid: success\n")); >@@ -683,206 +657,6 @@ > > return ret; > } >- >-/*********************************************************************** >- This function cannot be called to modify a mapping, only set a new one >- >- This takes a possible pointer to the existing entry for the UID or SID >- involved. >-***********************************************************************/ >- >-static NTSTATUS ldap_set_mapping_internals(const DOM_SID *sid, unid_t id, >- int id_type, const char *ldap_dn, >- LDAPMessage *entry) >-{ >- pstring dn; >- pstring id_str; >- fstring type; >- LDAPMod **mods = NULL; >- int rc = -1; >- int ldap_op; >- fstring sid_string; >- char **values = NULL; >- int i; >- >- sid_to_string( sid_string, sid ); >- >- if (ldap_dn) { >- DEBUG(10, ("Adding new IDMAP mapping on DN: %s", ldap_dn)); >- ldap_op = LDAP_MOD_REPLACE; >- pstrcpy( dn, ldap_dn ); >- } else { >- ldap_op = LDAP_MOD_ADD; >- pstr_sprintf(dn, "%s=%s,%s", get_attr_key2string( sidmap_attr_list, LDAP_ATTR_SID), >- sid_string, lp_ldap_idmap_suffix()); >- } >- >- if ( id_type & ID_USERID ) >- fstrcpy( type, get_attr_key2string( sidmap_attr_list, LDAP_ATTR_UIDNUMBER ) ); >- else >- fstrcpy( type, get_attr_key2string( sidmap_attr_list, LDAP_ATTR_GIDNUMBER ) ); >- >- pstr_sprintf(id_str, "%lu", ((id_type & ID_USERID) ? (unsigned long)id.uid : >- (unsigned long)id.gid)); >- >- if (entry) >- values = ldap_get_values(ldap_state.smbldap_state->ldap_struct, entry, "objectClass"); >- >- if (values) { >- BOOL found_idmap = False; >- for (i=0; values[i]; i++) { >- if (StrCaseCmp(values[i], LDAP_OBJ_IDMAP_ENTRY) == 0) { >- found_idmap = True; >- break; >- } >- } >- if (!found_idmap) >- smbldap_set_mod( &mods, LDAP_MOD_ADD, >- "objectClass", LDAP_OBJ_IDMAP_ENTRY ); >- } else { >- smbldap_set_mod( &mods, LDAP_MOD_ADD, >- "objectClass", LDAP_OBJ_IDMAP_ENTRY ); >- } >- >- smbldap_make_mod( ldap_state.smbldap_state->ldap_struct, >- entry, &mods, type, id_str ); >- >- smbldap_make_mod( ldap_state.smbldap_state->ldap_struct, >- entry, &mods, >- get_attr_key2string(sidmap_attr_list, LDAP_ATTR_SID), >- sid_string ); >- >- /* There may well be nothing at all to do */ >- if (mods) { >- switch(ldap_op) >- { >- case LDAP_MOD_ADD: >- smbldap_set_mod( &mods, LDAP_MOD_ADD, >- "objectClass", LDAP_OBJ_SID_ENTRY ); >- rc = smbldap_add(ldap_state.smbldap_state, dn, mods); >- break; >- case LDAP_MOD_REPLACE: >- rc = smbldap_modify(ldap_state.smbldap_state, dn, mods); >- break; >- } >- >- ldap_mods_free( mods, True ); >- } else { >- rc = LDAP_SUCCESS; >- } >- >- if (rc != LDAP_SUCCESS) { >- char *ld_error = NULL; >- ldap_get_option(ldap_state.smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, >- &ld_error); >- DEBUG(0,("ldap_set_mapping_internals: Failed to %s mapping from %s to %lu [%s]\n", >- (ldap_op == LDAP_MOD_ADD) ? "add" : "replace", >- sid_string, (unsigned long)((id_type & ID_USERID) ? id.uid : id.gid), type)); >- DEBUG(0, ("ldap_set_mapping_internals: Error was: %s (%s)\n", ld_error ? ld_error : "(NULL)", ldap_err2string (rc))); >- return NT_STATUS_UNSUCCESSFUL; >- } >- >- DEBUG(10,("ldap_set_mapping: Successfully created mapping from %s to %lu [%s]\n", >- sid_string, ((id_type & ID_USERID) ? (unsigned long)id.uid : >- (unsigned long)id.gid), type)); >- >- return NT_STATUS_OK; >-} >- >-/*********************************************************************** >- This function cannot be called to modify a mapping, only set a new one >-***********************************************************************/ >- >-static NTSTATUS ldap_set_mapping(const DOM_SID *sid, unid_t id, int id_type) >-{ >- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; >- char *dn = NULL; >- LDAPMessage *result = NULL; >- LDAPMessage *entry = NULL; >- const char *type; >- const char *obj_class; >- const char *posix_obj_class; >- const char *suffix; >- fstring sid_str; >- fstring id_str; >- pstring filter; >- char **attr_list; >- int rc; >- int count; >- >- /* try for a samba user or group mapping (looking for an entry with a SID) */ >- if ( id_type & ID_USERID ) { >- obj_class = LDAP_OBJ_SAMBASAMACCOUNT; >- suffix = lp_ldap_suffix(); >- type = get_attr_key2string( idpool_attr_list, LDAP_ATTR_UIDNUMBER ); >- posix_obj_class = LDAP_OBJ_POSIXACCOUNT; >- fstr_sprintf(id_str, "%lu", (unsigned long)id.uid ); >- } >- else { >- obj_class = LDAP_OBJ_GROUPMAP; >- suffix = lp_ldap_group_suffix(); >- type = get_attr_key2string( idpool_attr_list, LDAP_ATTR_GIDNUMBER ); >- posix_obj_class = LDAP_OBJ_POSIXGROUP; >- fstr_sprintf(id_str, "%lu", (unsigned long)id.gid ); >- } >- >- sid_to_string(sid_str, sid); >- pstr_sprintf(filter, >- "(|" >- "(&(|(objectClass=%s)(|(objectClass=%s)(objectClass=%s)))(%s=%s))" >- "(&(objectClass=%s)(%s=%s))" >- ")", >- /* objectClasses that might contain a SID */ >- LDAP_OBJ_SID_ENTRY, LDAP_OBJ_IDMAP_ENTRY, obj_class, >- get_attr_key2string( sidmap_attr_list, LDAP_ATTR_SID ), >- sid_str, >- >- /* objectClasses that might contain a Unix UID/GID */ >- posix_obj_class, >- /* Unix UID/GID specifier*/ >- type, >- /* actual ID */ >- id_str); >- >- attr_list = get_attr_list( sidmap_attr_list ); >- rc = smbldap_search(ldap_state.smbldap_state, suffix, LDAP_SCOPE_SUBTREE, >- filter, attr_list, 0, &result); >- free_attr_list( attr_list ); >- >- if (rc != LDAP_SUCCESS) >- goto out; >- >- count = ldap_count_entries(ldap_state.smbldap_state->ldap_struct, result); >- >- /* fall back to looking up an idmap entry if we didn't find anything under the idmap >- user or group suffix */ >- >- if (count == 1) { >- entry = ldap_first_entry(ldap_state.smbldap_state->ldap_struct, result); >- >- dn = smbldap_get_dn(ldap_state.smbldap_state->ldap_struct, result); >- if (!dn) >- goto out; >- DEBUG(10, ("Found partial mapping entry at dn=%s, looking for %s\n", dn, type)); >- >- ret = ldap_set_mapping_internals(sid, id, id_type, dn, entry); >- >- goto out; >- } else if (count > 1) { >- DEBUG(0, ("Too many entries trying to find DN to attach ldap \n")); >- goto out; >- } >- >- ret = ldap_set_mapping_internals(sid, id, id_type, NULL, NULL); >- >-out: >- if (result) >- ldap_msgfree(result); >- SAFE_FREE(dn); >- >- return ret; >-} >- > > /********************************************************************** > Verify the sambaUnixIdPool entry in the directiry.
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 680
: 235