Fix build break
[jra/samba/.git] / source3 / winbindd / winbindd_ads.c
index 3f3f06e3fd5577ae9693d98d9669c9baa7c1480e..1febddf110b422bcc29e959847130bb4eca30ab7 100644 (file)
@@ -40,7 +40,7 @@ static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain)
        ADS_STRUCT *ads;
        ADS_STATUS status;
        fstring dc_name;
-       struct in_addr dc_ip;   
+       struct sockaddr_storage dc_ss;
 
        DEBUG(10,("ads_cached_connection\n"));
 
@@ -66,7 +66,7 @@ static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain)
                        ads_destroy( &ads );
                        ads_kdestroy("MEMORY:winbind_ccache");
                        domain->private_data = NULL;
-               }       
+               }
        }
 
        /* we don't want this to affect the users ccache */
@@ -99,7 +99,7 @@ static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain)
 
                ads->auth.password = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL);
 
-               /* always give preference to the alt_name in our 
+               /* always give preference to the alt_name in our
                   primary domain if possible */
 
                if ( !domain->primary )
@@ -116,14 +116,14 @@ static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain)
        ads->auth.renewable = WINBINDD_PAM_AUTH_KRB5_RENEW_TIME;
 
        /* Setup the server affinity cache.  We don't reaally care
-          about the name.  Just setup affinity and the KRB5_CONFIG 
+          about the name.  Just setup affinity and the KRB5_CONFIG
           file. */
 
-       get_dc_name( ads->server.workgroup, ads->server.realm, dc_name, &dc_ip );
-       
+       get_dc_name( ads->server.workgroup, ads->server.realm, dc_name, &dc_ss );
+
        status = ads_connect(ads);
        if (!ADS_ERR_OK(status) || !ads->config.realm) {
-               DEBUG(1,("ads_connect for domain %s failed: %s\n", 
+               DEBUG(1,("ads_connect for domain %s failed: %s\n",
                         domain->name, ads_errstr(status)));
                ads_destroy(&ads);
 
@@ -138,8 +138,8 @@ static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain)
                return NULL;
        }
 
-       /* set the flag that says we don't own the memory even 
-          though we do so that ads_destroy() won't destroy the 
+       /* set the flag that says we don't own the memory even
+          though we do so that ads_destroy() won't destroy the
           structure we pass back by reference */
 
        ads->is_mine = False;
@@ -393,7 +393,7 @@ static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
         * using LDAP.
         *
         * if we ever need to enumerate domain local groups separately, 
-        * then this the optimization in enum_dom_groups() will need 
+        * then this optimization in enum_dom_groups() will need
         * to be split out
         */
        *num_entries = 0;
@@ -421,7 +421,7 @@ static NTSTATUS query_user(struct winbindd_domain *domain,
        char *sidstr;
        uint32 group_rid;
        NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
-       NET_USER_INFO_3 *user;
+       struct netr_SamInfo3 *user = NULL;
 
        DEBUG(3,("ads: query_user\n"));
 
@@ -435,13 +435,13 @@ static NTSTATUS query_user(struct winbindd_domain *domain,
        {
                                
                DEBUG(5,("query_user: Cache lookup succeeded for %s\n", 
-                       sid_string_static(sid)));
+                        sid_string_dbg(sid)));
 
-               sid_compose(&info->user_sid, &domain->sid, user->user_rid);
-               sid_compose(&info->group_sid, &domain->sid, user->group_rid);
+               sid_compose(&info->user_sid, &domain->sid, user->base.rid);
+               sid_compose(&info->group_sid, &domain->sid, user->base.primary_gid);
                                
-               info->acct_name = unistr2_tdup(mem_ctx, &user->uni_user_name);
-               info->full_name = unistr2_tdup(mem_ctx, &user->uni_full_name);
+               info->acct_name = talloc_strdup(mem_ctx, user->base.account_name.string);
+               info->full_name = talloc_strdup(mem_ctx, user->base.full_name.string);
                
                nss_get_info_cached( domain, sid, mem_ctx, NULL, NULL, 
                              &info->homedir, &info->shell, &info->full_name, 
@@ -490,14 +490,14 @@ static NTSTATUS query_user(struct winbindd_domain *domain,
        free(sidstr);
        if (!ADS_ERR_OK(rc) || !msg) {
                DEBUG(1,("query_user(sid=%s) ads_search: %s\n",
-                        sid_string_static(sid), ads_errstr(rc)));
+                        sid_string_dbg(sid), ads_errstr(rc)));
                goto done;
        }
 
        count = ads_count_replies(ads, msg);
        if (count != 1) {
                DEBUG(1,("query_user(sid=%s): Not found\n",
-                        sid_string_static(sid)));
+                        sid_string_dbg(sid)));
                goto done;
        }
 
@@ -513,7 +513,7 @@ static NTSTATUS query_user(struct winbindd_domain *domain,
 
        if (!ads_pull_uint32(ads, msg, "primaryGroupID", &group_rid)) {
                DEBUG(1,("No primary group for %s !?\n",
-                        sid_string_static(sid)));
+                        sid_string_dbg(sid)));
                goto done;
        }
 
@@ -596,8 +596,9 @@ static NTSTATUS lookup_usergroups_member(struct winbindd_domain *domain,
        num_groups = 0;
 
        /* always add the primary group to the sid array */
-       if (!add_sid_to_array(mem_ctx, primary_group, user_sids, &num_groups)) {
-               status = NT_STATUS_NO_MEMORY;
+       status = add_sid_to_array(mem_ctx, primary_group, user_sids,
+                                 &num_groups);
+       if (!NT_STATUS_IS_OK(status)) {
                goto done;
        }
 
@@ -615,10 +616,10 @@ static NTSTATUS lookup_usergroups_member(struct winbindd_domain *domain,
                        if (sid_check_is_in_builtin(&group_sid)) {
                                continue;
                        }
-                              
-                       if (!add_sid_to_array(mem_ctx, &group_sid, user_sids,
-                                        &num_groups)) {
-                               status = NT_STATUS_NO_MEMORY;
+
+                       status = add_sid_to_array(mem_ctx, &group_sid,
+                                                 user_sids, &num_groups);
+                       if (!NT_STATUS_IS_OK(status)) {
                                goto done;
                        }
                }
@@ -684,8 +685,9 @@ static NTSTATUS lookup_usergroups_memberof(struct winbindd_domain *domain,
        num_groups = 0;
 
        /* always add the primary group to the sid array */
-       if (!add_sid_to_array(mem_ctx, primary_group, user_sids, &num_groups)) {
-               status = NT_STATUS_NO_MEMORY;
+       status = add_sid_to_array(mem_ctx, primary_group, user_sids,
+                                 &num_groups);
+       if (!NT_STATUS_IS_OK(status)) {
                goto done;
        }
 
@@ -720,10 +722,10 @@ static NTSTATUS lookup_usergroups_memberof(struct winbindd_domain *domain,
                if (sid_check_is_in_builtin(&group_sids[i])) {
                        continue;
                }
-                      
-               if (!add_sid_to_array(mem_ctx, &group_sids[i], user_sids,
-                                &num_groups)) {
-                       status = NT_STATUS_NO_MEMORY;
+
+               status = add_sid_to_array(mem_ctx, &group_sids[i], user_sids,
+                                         &num_groups);
+               if (!NT_STATUS_IS_OK(status)) {
                        goto done;
                }
        
@@ -756,7 +758,6 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
        int i;
        DOM_SID primary_group;
        uint32 primary_group_rid;
-       fstring sid_string;
        NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
        size_t num_groups = 0;
 
@@ -790,8 +791,8 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
 
        if (!ADS_ERR_OK(rc)) {
                status = ads_ntstatus(rc);
-               DEBUG(1,("lookup_usergroups(sid=%s) ads_search tokenGroups: %s\n", 
-                        sid_to_string(sid_string, sid), ads_errstr(rc)));
+               DEBUG(1, ("lookup_usergroups(sid=%s) ads_search tokenGroups: "
+                         "%s\n", sid_string_dbg(sid), ads_errstr(rc)));
                goto done;
        }
        
@@ -800,13 +801,13 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
                status = NT_STATUS_UNSUCCESSFUL;
                DEBUG(1,("lookup_usergroups(sid=%s) ads_search tokenGroups: "
                         "invalid number of results (count=%d)\n", 
-                        sid_to_string(sid_string, sid), count));
+                        sid_string_dbg(sid), count));
                goto done;
        }
 
        if (!msg) {
                DEBUG(1,("lookup_usergroups(sid=%s) ads_search tokenGroups: NULL msg\n", 
-                        sid_to_string(sid_string, sid)));
+                        sid_string_dbg(sid)));
                status = NT_STATUS_UNSUCCESSFUL;
                goto done;
        }
@@ -819,7 +820,7 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
 
        if (!ads_pull_uint32(ads, msg, "primaryGroupID", &primary_group_rid)) {
                DEBUG(1,("%s: No primary group for sid=%s !?\n", 
-                        domain->name, sid_to_string(sid_string, sid)));
+                        domain->name, sid_string_dbg(sid)));
                goto done;
        }
 
@@ -862,8 +863,9 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
        *user_sids = NULL;
        num_groups = 0;
 
-       if (!add_sid_to_array(mem_ctx, &primary_group, user_sids, &num_groups)) {
-               status = NT_STATUS_NO_MEMORY;
+       status = add_sid_to_array(mem_ctx, &primary_group, user_sids,
+                                 &num_groups);
+       if (!NT_STATUS_IS_OK(status)) {
                goto done;
        }
        
@@ -873,10 +875,10 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
                if (sid_check_is_in_builtin(&sids[i])) {
                        continue;
                }
-                              
-               if (!add_sid_to_array_unique(mem_ctx, &sids[i],
-                                       user_sids, &num_groups)) {
-                       status = NT_STATUS_NO_MEMORY;
+
+               status = add_sid_to_array_unique(mem_ctx, &sids[i],
+                                                user_sids, &num_groups);
+               if (!NT_STATUS_IS_OK(status)) {
                        goto done;
                }
        }
@@ -885,7 +887,7 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
        status = (*user_sids != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
 
        DEBUG(3,("ads lookup_usergroups (tokenGroups) succeeded for sid=%s\n",
-                sid_to_string(sid_string, sid)));
+                sid_string_dbg(sid)));
 done:
        ads_memfree(ads, user_dn);
        ads_msgfree(ads, msg);
@@ -920,7 +922,7 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
        TALLOC_CTX *tmp_ctx = NULL;
 
        DEBUG(10,("ads: lookup_groupmem %s sid=%s\n", domain->name, 
-                 sid_string_static(group_sid)));
+                 sid_string_dbg(group_sid)));
 
        *num_names = 0;
 
@@ -1018,20 +1020,21 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
                        goto done;
                }
                if (lookup_cached_sid(mem_ctx, &sid, &domain_name, &name, &name_type)) {
-                       DEBUG(10,("ads: lookup_groupmem: got sid %s from cache\n",
-                                sid_string_static(&sid)));
+                       DEBUG(10,("ads: lookup_groupmem: got sid %s from "
+                                 "cache\n", sid_string_dbg(&sid)));
                        sid_copy(&(*sid_mem)[*num_names], &sid);
-                       (*names)[*num_names] = talloc_asprintf(*names, "%s%c%s",
-                                                              domain_name,
-                                                              *lp_winbind_separator(),
-                                                              name );
+                       (*names)[*num_names] = fill_domain_username_talloc(
+                                                       *names,
+                                                       domain_name,
+                                                       name,
+                                                       true);
 
                        (*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)));
+                       DEBUG(10, ("ads: lookup_groupmem: sid %s not found in "
+                                  "cache\n", sid_string_dbg(&sid)));
                        sid_copy(&(sid_mem_nocache)[num_nocache], &sid);
                        num_nocache++;
                }
@@ -1069,11 +1072,12 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
                                {
                                        sid_copy(&(*sid_mem)[*num_names],
                                                 &sid_mem_nocache[i]);
-                                       (*names)[*num_names] = talloc_asprintf( *names, 
-                                                                               "%s%c%s",
-                                                                               domains_nocache[i],
-                                                                               *lp_winbind_separator(),
-                                                                               names_nocache[i] );
+                                       (*names)[*num_names] =
+                                               fill_domain_username_talloc(
+                                                       *names,
+                                                       domains_nocache[i],
+                                                       names_nocache[i],
+                                                       true);
                                        (*name_types)[*num_names] = name_types_nocache[i];
                                        (*num_names)++;
                                }
@@ -1096,7 +1100,7 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
 
        status = NT_STATUS_OK;
        DEBUG(3,("ads lookup_groupmem for sid=%s succeeded\n",
-                sid_string_static(group_sid)));
+                sid_string_dbg(group_sid)));
 
 done:
 
@@ -1155,12 +1159,11 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
                                DOM_SID **dom_sids)
 {
        NTSTATUS                result = NT_STATUS_UNSUCCESSFUL;
-       struct ds_domain_trust  *domains = NULL;
-       int                     count = 0;
+       struct netr_DomainTrustList trusts;
        int                     i;
        uint32                  flags;  
        struct rpc_pipe_client *cli;
-       uint32                 fr_flags = (DS_DOMAIN_IN_FOREST | DS_DOMAIN_TREE_ROOT);  
+       uint32                 fr_flags = (NETR_TRUST_FLAG_IN_FOREST | NETR_TRUST_FLAG_TREEROOT);
        int ret_count;
        
        DEBUG(3,("ads: trusted_domains\n"));
@@ -1177,11 +1180,11 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
        if ( domain->primary ||
                ((domain->domain_flags&fr_flags) == fr_flags) ) 
        {
-               flags = DS_DOMAIN_DIRECT_OUTBOUND | 
-                       DS_DOMAIN_DIRECT_INBOUND | 
-                       DS_DOMAIN_IN_FOREST;
+               flags = NETR_TRUST_FLAG_OUTBOUND |
+                       NETR_TRUST_FLAG_INBOUND |
+                       NETR_TRUST_FLAG_IN_FOREST;
        } else {
-               flags = DS_DOMAIN_IN_FOREST;
+               flags = NETR_TRUST_FLAG_IN_FOREST;
        }       
 
        result = cm_connect_netlogon(domain, &cli);
@@ -1192,29 +1195,27 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
                          domain->name, nt_errstr(result)));
                return NT_STATUS_UNSUCCESSFUL;
        }
-       
-       if ( NT_STATUS_IS_OK(result) ) {
-               result = rpccli_ds_enum_domain_trusts(cli, mem_ctx,
-                                                     cli->cli->desthost, 
-                                                     flags, &domains,
-                                                     (unsigned int *)&count);
-       }
-       
-       if ( NT_STATUS_IS_OK(result) && count) {
+
+       result = rpccli_netr_DsrEnumerateDomainTrusts(cli, mem_ctx,
+                                                     cli->desthost,
+                                                     flags,
+                                                     &trusts,
+                                                     NULL);
+       if ( NT_STATUS_IS_OK(result) && trusts.count) {
 
                /* Allocate memory for trusted domain names and sids */
 
-               if ( !(*names = TALLOC_ARRAY(mem_ctx, char *, count)) ) {
+               if ( !(*names = TALLOC_ARRAY(mem_ctx, char *, trusts.count)) ) {
                        DEBUG(0, ("trusted_domains: out of memory\n"));
                        return NT_STATUS_NO_MEMORY;
                }
 
-               if ( !(*alt_names = TALLOC_ARRAY(mem_ctx, char *, count)) ) {
+               if ( !(*alt_names = TALLOC_ARRAY(mem_ctx, char *, trusts.count)) ) {
                        DEBUG(0, ("trusted_domains: out of memory\n"));
                        return NT_STATUS_NO_MEMORY;
                }
 
-               if ( !(*dom_sids = TALLOC_ARRAY(mem_ctx, DOM_SID, count)) ) {
+               if ( !(*dom_sids = TALLOC_ARRAY(mem_ctx, DOM_SID, trusts.count)) ) {
                        DEBUG(0, ("trusted_domains: out of memory\n"));
                        return NT_STATUS_NO_MEMORY;
                }
@@ -1223,65 +1224,108 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
 
 
                ret_count = 0;          
-               for (i = 0; i < count; i++) {
+               for (i = 0; i < trusts.count; i++) {
                        struct winbindd_domain d;
                        
+                       ZERO_STRUCT(d);
+
                        /* drop external trusts if this is not our primary 
                           domain.  This means that the returned number of 
                           domains may be less that the ones actually trusted
                           by the DC. */
 
-                       if ( (domains[i].trust_attributes == DS_DOMAIN_TRUST_ATTRIB_QUARANTINED_DOMAIN) && 
+                       if ( (trusts.array[i].trust_attributes == NETR_TRUST_ATTRIBUTE_QUARANTINED_DOMAIN) &&
                             !domain->primary ) 
                        {
                                DEBUG(10,("trusted_domains: Skipping external trusted domain "
                                          "%s because it is outside of our primary domain\n",
-                                         domains[i].netbios_domain));                          
+                                         trusts.array[i].netbios_name));
                                continue;                               
                        }
                        
-                       (*names)[ret_count] = domains[i].netbios_domain;
-                       (*alt_names)[ret_count] = domains[i].dns_domain;
-                       sid_copy(&(*dom_sids)[ret_count], &domains[i].sid);
+                       (*names)[ret_count] = CONST_DISCARD(char *, trusts.array[i].netbios_name);
+                       (*alt_names)[ret_count] = CONST_DISCARD(char *, trusts.array[i].dns_name);
+                       if (trusts.array[i].sid) {
+                               sid_copy(&(*dom_sids)[ret_count], trusts.array[i].sid);
+                       } else {
+                               sid_copy(&(*dom_sids)[ret_count], &global_sid_NULL);
+                       }
 
                        /* add to the trusted domain cache */
 
-                       fstrcpy( d.name,  domains[i].netbios_domain );
-                       fstrcpy( d.alt_name, domains[i].dns_domain );                   
-                       sid_copy( &d.sid, &domains[i].sid );
-
-                       /* This gets a little tricky.  If we are
-                          following a transitive forest trust, then
-                          innerit the flags, type, and attrins from
-                          the domain we queried to make sure we don't
-                          record the view of the trust from the wrong
-                          side.  Always view it from the side of our
-                          primary domain.   --jerry */
-                       if ( domain->primary ||
-                            ((domain->domain_flags&fr_flags) == fr_flags) ) 
-                       {
-                               DEBUG(10,("trusted_domains(ads):  Storing trust "
-                                         "flags for domain %s\n", d.alt_name));
-
-                               /* Look this up in cache to make sure
-                                  we have the current trust flags and
-                                  attributes */
-
-                               d.domain_flags = domains[i].flags;
-                               d.domain_type = domains[i].trust_type;
-                               d.domain_trust_attribs = domains[i].trust_attributes;
+                       fstrcpy( d.name,  trusts.array[i].netbios_name);
+                       fstrcpy( d.alt_name, trusts.array[i].dns_name);
+                       if (trusts.array[i].sid) {
+                               sid_copy( &d.sid, trusts.array[i].sid);
                        } else {
-                               DEBUG(10,("trusted_domains(ads):  Inheriting trust "
-                                         "flags for domain %s\n", d.alt_name));                                
-                               d.domain_flags = domain->domain_flags;                          
-                               d.domain_type  = domain->domain_type;
-                               d.domain_trust_attribs = domain->domain_trust_attribs;
+                               sid_copy(&d.sid, &global_sid_NULL);
                        }
 
-                       wcache_tdc_add_domain( &d );
-
-                       ret_count++;
-
+                       if ( domain->primary ) {
+                               DEBUG(10,("trusted_domains(ads):  Searching "
+                                         "trusted domain list of %s and storing "
+                                         "trust flags for domain %s\n", 
+                                         domain->name, d.alt_name));
+
+                               d.domain_flags = trusts.array[i].trust_flags;
+                               d.domain_type = trusts.array[i].trust_type;
+                               d.domain_trust_attribs = trusts.array[i].trust_attributes;
+
+                               wcache_tdc_add_domain( &d );
+                               ret_count++;
+                       } else if ( (domain->domain_flags&fr_flags) == fr_flags ) {
+                               /* Check if we already have this record. If
+                                * we are following our forest root that is not
+                                * our primary domain, we want to keep trust
+                                * flags from the perspective of our primary
+                                * domain not our forest root. */
+                               struct winbindd_tdc_domain *exist = NULL;
+
+                               exist = 
+                                   wcache_tdc_fetch_domain(NULL, trusts.array[i].netbios_name);
+                               if (!exist) {
+                                       DEBUG(10,("trusted_domains(ads):  Searching "
+                                                 "trusted domain list of %s and storing "
+                                                 "trust flags for domain %s\n", 
+                                                 domain->name, d.alt_name));
+                                       d.domain_flags = trusts.array[i].trust_flags;
+                                       d.domain_type = trusts.array[i].trust_type;
+                                       d.domain_trust_attribs = trusts.array[i].trust_attributes;
+
+                                       wcache_tdc_add_domain( &d );
+                                       ret_count++;
+                               }
+                               TALLOC_FREE(exist);
+                       } else {
+                               /* This gets a little tricky.  If we are
+                                  following a transitive forest trust, then
+                                  innerit the flags, type, and attribs from
+                                  the domain we queried to make sure we don't
+                                  record the view of the trust from the wrong
+                                  side.  Always view it from the side of our
+                                  primary domain.   --jerry */
+                               struct winbindd_tdc_domain *parent = NULL;
+
+                               DEBUG(10,("trusted_domains(ads):  Searching "
+                                         "trusted domain list of %s and inheriting "
+                                         "trust flags for domain %s\n", 
+                                         domain->name, d.alt_name));
+
+                               parent = wcache_tdc_fetch_domain(NULL, domain->name);
+                               if (parent) {
+                                       d.domain_flags = parent->trust_flags;
+                                       d.domain_type  = parent->trust_type;
+                                       d.domain_trust_attribs = parent->trust_attribs;
+                               } else {
+                                       d.domain_flags = domain->domain_flags;
+                                       d.domain_type  = domain->domain_type;
+                                       d.domain_trust_attribs = domain->domain_trust_attribs;
+                               }
+                               TALLOC_FREE(parent);
+                               
+                               wcache_tdc_add_domain( &d );
+                               ret_count++;
+                       }
                }
 
                *num_domains = ret_count;