fix for bug 680 (heads up). This gist is to map the
authorGerald Carter <jerry@samba.org>
Fri, 7 Nov 2003 14:39:47 +0000 (14:39 +0000)
committerGerald Carter <jerry@samba.org>
Fri, 7 Nov 2003 14:39:47 +0000 (14:39 +0000)
UNIX entity foo to DOMAIN\foo instead of SERVER\foo
on members of a Samba domain when all UNIX accounts
are shared via NIS, et. al.

  * allow winbindd to match local accounts to domain SID
    when 'winbind trusted domains only = yes'

  * remove code in idmap_ldap that searches the user
    suffix and group suffix.  It's not needed and
    provides inconsistent functionality from the tdb backend.

This has been tested.  I'm still waiting on some more feedback
but This needs to be in 3.0.1pre2 for widespread use.

source/nsswitch/winbindd_sid.c
source/passdb/lookup_sid.c
source/sam/idmap_ldap.c

index ac1ee1155546b364e453a69e4da2ee8a7ae47e05..0faeec56369bd025e1ba8e980623c06d900335ee 100644 (file)
@@ -130,16 +130,75 @@ enum winbindd_result winbindd_sid_to_uid(struct winbindd_cli_state *state)
        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 @@ enum winbindd_result winbindd_sid_to_gid(struct winbindd_cli_state *state)
                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 @@ enum winbindd_result winbindd_uid_to_sid(struct winbindd_cli_state *state)
 {
        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 @@ enum winbindd_result winbindd_gid_to_sid(struct winbindd_cli_state *state)
 {
        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 f84ff28db919c0407d510a85f9e9f3fc00ba1873..425c9b87f10d2a9ef435961c2c62a6828de4e2c5 100644 (file)
@@ -299,15 +299,20 @@ static void store_gid_sid_cache(const DOM_SID *psid, gid_t gid)
 
 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 uid_to_sid(DOM_SID *psid, uid_t uid)
 
 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 @@ NTSTATUS sid_to_gid(const DOM_SID *psid, gid_t *pgid)
 
        /* 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 72fcb47b039d24a07eb772c7b4d9848b1ef5416b..2a94de755ac1da1f9fb1ad740d290d9c12729a3d 100644 (file)
@@ -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.
 
 #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 @@ static BOOL sid_in_use(struct ldap_idmap_state *state,
        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 @@ static NTSTATUS ldap_next_rid(struct ldap_idmap_state *state, uint32 *rid,
                }
 
                /* 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 @@ static NTSTATUS ldap_allocate_id(unid_t *id, int id_type)
        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 @@ static NTSTATUS ldap_get_sid_from_id(DOM_SID *sid, unid_t id, int id_type)
 {
        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 @@ static NTSTATUS ldap_get_sid_from_id(DOM_SID *sid, unid_t id, int id_type)
        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 @@ static NTSTATUS ldap_get_id_from_sid(unid_t *id, int *id_type, const DOM_SID *si
        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 @@ static NTSTATUS ldap_get_id_from_sid(unid_t *id, int *id_type, const DOM_SID *si
 
        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"));
@@ -684,206 +658,6 @@ out:
        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.  
 **********************************************************************/