r23784: use the GPLv3 boilerplate as recommended by the FSF and the license text
[abartlet/samba.git/.git] / source3 / nsswitch / winbindd_ads.c
index 6aa0947ffcd322458f8f7a2cb2175f9e87bb9a64..3f9308cb66affd4fd38766deee7a8b4560b6dc82 100644 (file)
@@ -9,7 +9,7 @@
    
    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
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
@@ -18,8 +18,7 @@
    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.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
@@ -570,7 +569,12 @@ static NTSTATUS lookup_usergroups_member(struct winbindd_domain *domain,
                goto done;
        }
 
-       if (!(ldap_exp = talloc_asprintf(mem_ctx, "(&(member=%s)(objectCategory=group))", escaped_dn))) {
+       ldap_exp = talloc_asprintf(mem_ctx,
+               "(&(member=%s)(objectCategory=group)(groupType:dn:%s:=%d))",
+               escaped_dn,
+               ADS_LDAP_MATCHING_RULE_BIT_AND,
+               GROUP_TYPE_SECURITY_ENABLED);
+       if (!ldap_exp) {
                DEBUG(1,("lookup_usergroups(dn=%s) asprintf failed!\n", user_dn));
                SAFE_FREE(escaped_dn);
                status = NT_STATUS_NO_MEMORY;
@@ -898,11 +902,10 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
                                uint32 **name_types)
 {
        ADS_STATUS rc;
-       LDAPMessage *res=NULL;
        ADS_STRUCT *ads = NULL;
        char *ldap_exp;
        NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
-       char *sidstr;
+       char *sidbinstr;
        char **members = NULL;
        int i;
        size_t num_members = 0;
@@ -914,13 +917,20 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
        uint32 *name_types_nocache = NULL;
        char **domains_nocache = NULL;     /* only needed for rpccli_lsa_lookup_sids */
        uint32 num_nocache = 0;
-
+       TALLOC_CTX *tmp_ctx = NULL;
 
        DEBUG(10,("ads: lookup_groupmem %s sid=%s\n", domain->name, 
                  sid_string_static(group_sid)));
 
        *num_names = 0;
 
+       tmp_ctx = talloc_new(mem_ctx);
+       if (!tmp_ctx) {
+               DEBUG(1, ("ads: lookup_groupmem: talloc failed\n"));
+               status = NT_STATUS_NO_MEMORY;
+               goto done;
+       }
+
        if ( !winbindd_can_contact_domain( domain ) ) {
                DEBUG(10,("lookup_groupmem: No incoming trust for domain %s\n",
                          domain->name));               
@@ -934,25 +944,27 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
                goto done;
        }
 
-       if ((sidstr = sid_binstring(group_sid)) == NULL) {
+       if ((sidbinstr = sid_binstring(group_sid)) == NULL) {
                status = NT_STATUS_NO_MEMORY;
                goto done;
        }
 
        /* search for all members of the group */
-       if (!(ldap_exp = talloc_asprintf(mem_ctx, "(objectSid=%s)",sidstr))) {
-               SAFE_FREE(sidstr);
-               DEBUG(1, ("ads: lookup_groupmem: tallloc_asprintf for ldap_exp failed!\n"));
+       if (!(ldap_exp = talloc_asprintf(tmp_ctx, "(objectSid=%s)", 
+                                        sidbinstr))) 
+       {
+               SAFE_FREE(sidbinstr);
+               DEBUG(1, ("ads: lookup_groupmem: talloc_asprintf for ldap_exp failed!\n"));
                status = NT_STATUS_NO_MEMORY;
                goto done;
        }
-       SAFE_FREE(sidstr);
+       SAFE_FREE(sidbinstr);
 
        args.control = ADS_EXTENDED_DN_OID;
        args.val = ADS_EXTENDED_DN_HEX_STRING;
        args.critical = True;
 
-       rc = ads_ranged_search(ads, mem_ctx, LDAP_SCOPE_SUBTREE, ads->config.bind_path, 
+       rc = ads_ranged_search(ads, tmp_ctx, LDAP_SCOPE_SUBTREE, ads->config.bind_path, 
                               ldap_exp, &args, "member", &members, &num_members);
 
        if (!ADS_ERR_OK(rc)) {
@@ -961,7 +973,7 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
                goto done;
        } 
        
-       DEBUG(10, ("ads lookup_groupmem: got %d sids via extended dn call\n", num_members));
+       DEBUG(10, ("ads lookup_groupmem: got %d sids via extended dn call\n", (int)num_members));
        
        /* Now that we have a list of sids, we need to get the
         * lists of names and name_types belonging to these sids.
@@ -975,17 +987,17 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
         * we try to resolve as many sids as possible from the
         * cache. Only the rest is passed to the lsa_lookup_sids call. */
        
-       if (num_names) {
+       if (num_members) {
                (*sid_mem) = TALLOC_ZERO_ARRAY(mem_ctx, DOM_SID, num_members);
                (*names) = TALLOC_ZERO_ARRAY(mem_ctx, char *, num_members);
                (*name_types) = TALLOC_ZERO_ARRAY(mem_ctx, uint32, num_members);
-               (sid_mem_nocache) = TALLOC_ZERO_ARRAY(mem_ctx, DOM_SID, num_members);
+               (sid_mem_nocache) = TALLOC_ZERO_ARRAY(tmp_ctx, DOM_SID, num_members);
 
                if ((members == NULL) || (*sid_mem == NULL) ||
                    (*names == NULL) || (*name_types == NULL) ||
                    (sid_mem_nocache == NULL))
                {
-                       DEBUG(1, ("talloc failed\n"));
+                       DEBUG(1, ("ads: lookup_groupmem: talloc failed\n"));
                        status = NT_STATUS_NO_MEMORY;
                        goto done;
                }
@@ -1001,7 +1013,7 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
                char *name, *domain_name;
                DOM_SID sid;
 
-               if (!ads_get_sid_from_extended_dn(mem_ctx, members[i], args.val, &sid)) {
+               if (!ads_get_sid_from_extended_dn(tmp_ctx, members[i], args.val, &sid)) {
                        status = NT_STATUS_INVALID_PARAMETER;
                        goto done;
                }
@@ -1009,26 +1021,35 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
                        DEBUG(10,("ads: lookup_groupmem: got sid %s from cache\n",
                                 sid_string_static(&sid)));
                        sid_copy(&(*sid_mem)[*num_names], &sid);
-                       (*names)[*num_names] = CONST_DISCARD(char *,name);
+                       (*names)[*num_names] = talloc_asprintf(*names, "%s%c%s",
+                                                              domain_name,
+                                                              *lp_winbind_separator(),
+                                                              name );
+
                        (*name_types)[*num_names] = name_type;
                        (*num_names)++;
                }
                else {
+                       DEBUG(10, ("ads: lookup_groupmem: sid %s not found in cache\n",
+                                 sid_string_static(&sid)));
                        sid_copy(&(sid_mem_nocache)[num_nocache], &sid);
                        num_nocache++;
                }
        }
-       
+
+       DEBUG(10, ("ads: lookup_groupmem: %d sids found in cache, "
+                 "%d left for lsa_lookupsids\n", *num_names, num_nocache));
+
        /* handle sids not resolved from cache by lsa_lookup_sids */
        if (num_nocache > 0) {
 
-               status = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
+               status = cm_connect_lsa(domain, tmp_ctx, &cli, &lsa_policy);
 
                if (!NT_STATUS_IS_OK(status)) {
                        goto done;
                }
 
-               status = rpccli_lsa_lookup_sids_all(cli, mem_ctx, 
+               status = rpccli_lsa_lookup_sids_all(cli, tmp_ctx, 
                                                    &lsa_policy,
                                                    num_nocache, 
                                                    sid_mem_nocache, 
@@ -1042,14 +1063,17 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
                        /* Copy the entries over from the "_nocache" arrays 
                         * to the result arrays, skipping the gaps the 
                         * lookup_sids call left. */
-                       *num_names = 0;
                        for (i=0; i < num_nocache; i++) {
                                if (((names_nocache)[i] != NULL) && 
                                    ((name_types_nocache)[i] != SID_NAME_UNKNOWN)) 
                                {
                                        sid_copy(&(*sid_mem)[*num_names],
                                                 &sid_mem_nocache[i]);
-                                       (*names)[*num_names] = names_nocache[i];
+                                       (*names)[*num_names] = talloc_asprintf( *names, 
+                                                                               "%s%c%s",
+                                                                               domains_nocache[i],
+                                                                               *lp_winbind_separator(),
+                                                                               names_nocache[i] );
                                        (*name_types)[*num_names] = name_types_nocache[i];
                                        (*num_names)++;
                                }
@@ -1065,7 +1089,7 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
                else if (!NT_STATUS_IS_OK(status)) {
                        DEBUG(10, ("lookup_groupmem: Error looking up %d "
                                   "sids via rpc_lsa_lookup_sids: %s\n",
-                                  num_members, nt_errstr(status)));
+                                  (int)num_members, nt_errstr(status)));
                        goto done;
                }
        }
@@ -1076,14 +1100,7 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
 
 done:
 
-       if (res) 
-               ads_msgfree(ads, res);
-
-       /* free intermediate lists. - a temp talloc ctx might be better. */
-       TALLOC_FREE(sid_mem_nocache);
-       TALLOC_FREE(names_nocache);
-       TALLOC_FREE(name_types_nocache);
-       TALLOC_FREE(domains_nocache);
+       TALLOC_FREE(tmp_ctx);
 
        return status;
 }