Ignore:
Timestamp:
Nov 27, 2012, 4:43:17 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: updated trunk to 3.6.0

Location:
trunk/server
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/server

  • trunk/server/source3/winbindd/winbindd_ads.c

    r414 r745  
    2424#include "includes.h"
    2525#include "winbindd.h"
    26 #include "../librpc/gen_ndr/cli_netlogon.h"
     26#include "rpc_client/rpc_client.h"
     27#include "../librpc/gen_ndr/ndr_netlogon_c.h"
     28#include "../libds/common/flags.h"
     29#include "ads.h"
     30#include "secrets.h"
     31#include "../libcli/ldap/ldap_ndr.h"
     32#include "../libcli/security/security.h"
     33#include "../libds/common/flag_mapping.h"
     34#include "passdb.h"
    2735
    2836#ifdef HAVE_ADS
     
    153161                               TALLOC_CTX *mem_ctx,
    154162                               uint32 *num_entries,
    155                                struct wbint_userinfo **info)
     163                               struct wbint_userinfo **pinfo)
    156164{
    157165        ADS_STRUCT *ads = NULL;
     
    192200        }
    193201
    194         (*info) = TALLOC_ZERO_ARRAY(mem_ctx, struct wbint_userinfo, count);
    195         if (!*info) {
     202        (*pinfo) = TALLOC_ZERO_ARRAY(mem_ctx, struct wbint_userinfo, count);
     203        if (!*pinfo) {
    196204                status = NT_STATUS_NO_MEMORY;
    197205                goto done;
    198206        }
    199207
    200         i = 0;
     208        count = 0;
    201209
    202210        for (msg = ads_first_entry(ads, res); msg; msg = ads_next_entry(ads, msg)) {
    203                 const char *name;
    204                 const char *gecos = NULL;
    205                 const char *homedir = NULL;
    206                 const char *shell = NULL;
     211                struct wbint_userinfo *info = &((*pinfo)[count]);
    207212                uint32 group;
    208213                uint32 atype;
    209                 DOM_SID user_sid;
    210                 gid_t primary_gid = (gid_t)-1;
    211214
    212215                if (!ads_pull_uint32(ads, msg, "sAMAccountType", &atype) ||
     
    216219                }
    217220
    218                 name = ads_pull_username(ads, mem_ctx, msg);
    219 
    220                 if ( ads_pull_sid( ads, msg, "objectSid", &user_sid ) ) {
    221                         status = nss_get_info_cached( domain, &user_sid, mem_ctx,
    222                                                ads, msg, &homedir, &shell, &gecos,
    223                                                &primary_gid );
    224                 }
    225 
    226                 if (gecos == NULL) {
    227                         gecos = ads_pull_string(ads, mem_ctx, msg, "name");
    228                 }
     221                info->acct_name = ads_pull_username(ads, mem_ctx, msg);
     222                info->full_name = ads_pull_string(ads, mem_ctx, msg, "name");
     223                info->homedir = NULL;
     224                info->shell = NULL;
     225                info->primary_gid = (gid_t)-1;
    229226
    230227                if (!ads_pull_sid(ads, msg, "objectSid",
    231                                   &(*info)[i].user_sid)) {
    232                         DEBUG(1,("No sid for %s !?\n", name));
     228                                  &info->user_sid)) {
     229                        DEBUG(1, ("No sid for %s !?\n", info->acct_name));
    233230                        continue;
    234231                }
     232
    235233                if (!ads_pull_uint32(ads, msg, "primaryGroupID", &group)) {
    236                         DEBUG(1,("No primary group for %s !?\n", name));
     234                        DEBUG(1, ("No primary group for %s !?\n",
     235                                  info->acct_name));
    237236                        continue;
    238237                }
    239 
    240                 (*info)[i].acct_name = name;
    241                 (*info)[i].full_name = gecos;
    242                 (*info)[i].homedir = homedir;
    243                 (*info)[i].shell = shell;
    244                 (*info)[i].primary_gid = primary_gid;
    245                 sid_compose(&(*info)[i].group_sid, &domain->sid, group);
    246                 i++;
    247         }
    248 
    249         (*num_entries) = i;
     238                sid_compose(&info->group_sid, &domain->sid, group);
     239
     240                count += 1;
     241        }
     242
     243        (*num_entries) = count;
     244        ads_msgfree(ads, res);
     245
     246        for (i=0; i<count; i++) {
     247                struct wbint_userinfo *info = &((*pinfo)[i]);
     248                const char *gecos = NULL;
     249                gid_t primary_gid = (gid_t)-1;
     250
     251                status = nss_get_info_cached(domain, &info->user_sid, mem_ctx,
     252                                             &info->homedir, &info->shell,
     253                                             &gecos, &primary_gid);
     254                if (!NT_STATUS_IS_OK(status)) {
     255                        /*
     256                         * Deliberately ignore this error, there might be more
     257                         * users to fill
     258                         */
     259                        continue;
     260                }
     261
     262                if (gecos != NULL) {
     263                        info->full_name = gecos;
     264                }
     265                info->primary_gid = primary_gid;
     266        }
     267
    250268        status = NT_STATUS_OK;
    251269
     
    253271
    254272done:
    255         if (res)
    256                 ads_msgfree(ads, res);
    257 
    258273        return status;
    259274}
     
    263278                                TALLOC_CTX *mem_ctx,
    264279                                uint32 *num_entries,
    265                                 struct acct_info **info)
     280                                struct wb_acct_info **info)
    266281{
    267282        ADS_STRUCT *ads = NULL;
     
    337352        }
    338353
    339         (*info) = TALLOC_ZERO_ARRAY(mem_ctx, struct acct_info, count);
     354        (*info) = TALLOC_ZERO_ARRAY(mem_ctx, struct wb_acct_info, count);
    340355        if (!*info) {
    341356                status = NT_STATUS_NO_MEMORY;
     
    347362        for (msg = ads_first_entry(ads, res); msg; msg = ads_next_entry(ads, msg)) {
    348363                char *name, *gecos;
    349                 DOM_SID sid;
     364                struct dom_sid sid;
    350365                uint32 rid;
    351366
     
    385400                                TALLOC_CTX *mem_ctx,
    386401                                uint32 *num_entries,
    387                                 struct acct_info **info)
     402                                struct wb_acct_info **info)
    388403{
    389404        /*
     
    408423                            const char *name,
    409424                            uint32_t flags,
    410                             DOM_SID *sid,
     425                            struct dom_sid *sid,
    411426                            enum lsa_SidType *type)
    412427{
     
    419434static NTSTATUS sid_to_name(struct winbindd_domain *domain,
    420435                            TALLOC_CTX *mem_ctx,
    421                             const DOM_SID *sid,
     436                            const struct dom_sid *sid,
    422437                            char **domain_name,
    423438                            char **name,
     
    431446static NTSTATUS rids_to_names(struct winbindd_domain *domain,
    432447                              TALLOC_CTX *mem_ctx,
    433                               const DOM_SID *sid,
     448                              const struct dom_sid *sid,
    434449                              uint32 *rids,
    435450                              size_t num_rids,
     
    451466static NTSTATUS query_user(struct winbindd_domain *domain,
    452467                           TALLOC_CTX *mem_ctx,
    453                            const DOM_SID *sid,
     468                           const struct dom_sid *sid,
    454469                           struct wbint_userinfo *info)
    455470{
     
    464479        NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
    465480        struct netr_SamInfo3 *user = NULL;
    466         gid_t gid;
     481        gid_t gid = -1;
     482        int ret;
     483        char *ads_name;
    467484
    468485        DEBUG(3,("ads: query_user\n"));
     
    470487        info->homedir = NULL;
    471488        info->shell = NULL;
    472         info->primary_gid = (gid_t)-1;
    473489
    474490        /* try netsamlogon cache first */
     
    485501                info->full_name = talloc_strdup(mem_ctx, user->base.full_name.string);
    486502
    487                 nss_get_info_cached( domain, sid, mem_ctx, NULL, NULL,
     503                nss_get_info_cached( domain, sid, mem_ctx,
    488504                              &info->homedir, &info->shell, &info->full_name,
    489505                              &gid );
     
    507523                /* Assume "Domain Users" for the primary group */
    508524
    509                 sid_compose(&info->group_sid, &domain->sid, DOMAIN_GROUP_RID_USERS );
     525                sid_compose(&info->group_sid, &domain->sid, DOMAIN_RID_USERS );
    510526
    511527                /* Try to fill in what the nss_info backend can do */
    512528
    513                 nss_get_info_cached( domain, sid, mem_ctx, NULL, NULL,
     529                nss_get_info_cached( domain, sid, mem_ctx,
    514530                              &info->homedir, &info->shell, &info->full_name,
    515531                              &gid);
    516532                info->primary_gid = gid;
    517533
    518                 status = NT_STATUS_OK;
    519                 goto done;
     534                return NT_STATUS_OK;
    520535        }
    521536
     
    524539        if ( (ads = ads_cached_connection(domain)) == NULL ) {
    525540                domain->last_status = NT_STATUS_SERVER_DISABLED;
    526                 goto done;
    527         }
    528 
    529         sidstr = sid_binstring(talloc_tos(), sid);
    530         if (asprintf(&ldap_exp, "(objectSid=%s)", sidstr) == -1) {
    531                 status = NT_STATUS_NO_MEMORY;
    532                 goto done;
     541                return NT_STATUS_SERVER_DISABLED;
     542        }
     543
     544        sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), sid);
     545
     546        ret = asprintf(&ldap_exp, "(objectSid=%s)", sidstr);
     547        TALLOC_FREE(sidstr);
     548        if (ret == -1) {
     549                return NT_STATUS_NO_MEMORY;
    533550        }
    534551        rc = ads_search_retry(ads, &msg, ldap_exp, attrs);
    535         free(ldap_exp);
    536         TALLOC_FREE(sidstr);
     552        SAFE_FREE(ldap_exp);
    537553        if (!ADS_ERR_OK(rc) || !msg) {
    538554                DEBUG(1,("query_user(sid=%s) ads_search: %s\n",
    539555                         sid_string_dbg(sid), ads_errstr(rc)));
    540                 goto done;
     556                return ads_ntstatus(rc);
    541557        }
    542558
     
    545561                DEBUG(1,("query_user(sid=%s): Not found\n",
    546562                         sid_string_dbg(sid)));
    547                 goto done;
     563                ads_msgfree(ads, msg);
     564                return NT_STATUS_NO_SUCH_USER;
    548565        }
    549566
    550567        info->acct_name = ads_pull_username(ads, mem_ctx, msg);
    551568
    552         nss_get_info_cached( domain, sid, mem_ctx, ads, msg,
     569        if (!ads_pull_uint32(ads, msg, "primaryGroupID", &group_rid)) {
     570                DEBUG(1,("No primary group for %s !?\n",
     571                         sid_string_dbg(sid)));
     572                ads_msgfree(ads, msg);
     573                return NT_STATUS_NO_SUCH_USER;
     574        }
     575        sid_copy(&info->user_sid, sid);
     576        sid_compose(&info->group_sid, &domain->sid, group_rid);
     577
     578        /*
     579         * We have to fetch the "name" attribute before doing the
     580         * nss_get_info_cached call. nss_get_info_cached might destroy
     581         * the ads struct, potentially invalidating the ldap message.
     582         */
     583        ads_name = ads_pull_string(ads, mem_ctx, msg, "name");
     584
     585        ads_msgfree(ads, msg);
     586        msg = NULL;
     587
     588        status = nss_get_info_cached( domain, sid, mem_ctx,
    553589                      &info->homedir, &info->shell, &info->full_name,
    554590                      &gid);
    555591        info->primary_gid = gid;
     592        if (!NT_STATUS_IS_OK(status)) {
     593                DEBUG(1, ("nss_get_info_cached failed: %s\n",
     594                          nt_errstr(status)));
     595                return status;
     596        }
    556597
    557598        if (info->full_name == NULL) {
    558                 info->full_name = ads_pull_string(ads, mem_ctx, msg, "name");
    559         }
    560 
    561         if (!ads_pull_uint32(ads, msg, "primaryGroupID", &group_rid)) {
    562                 DEBUG(1,("No primary group for %s !?\n",
    563                          sid_string_dbg(sid)));
    564                 goto done;
    565         }
    566 
    567         sid_copy(&info->user_sid, sid);
    568         sid_compose(&info->group_sid, &domain->sid, group_rid);
     599                info->full_name = ads_name;
     600        } else {
     601                TALLOC_FREE(ads_name);
     602        }
    569603
    570604        status = NT_STATUS_OK;
    571605
    572606        DEBUG(3,("ads query_user gave %s\n", info->acct_name));
    573 done:
    574         if (msg)
    575                 ads_msgfree(ads, msg);
    576 
    577         return status;
     607        return NT_STATUS_OK;
    578608}
    579609
     
    583613                                         TALLOC_CTX *mem_ctx,
    584614                                         const char *user_dn,
    585                                          DOM_SID *primary_group,
    586                                          size_t *p_num_groups, DOM_SID **user_sids)
     615                                         struct dom_sid *primary_group,
     616                                         uint32_t *p_num_groups, struct dom_sid **user_sids)
    587617{
    588618        ADS_STATUS rc;
     
    595625        const char *group_attrs[] = {"objectSid", NULL};
    596626        char *escaped_dn;
    597         size_t num_groups = 0;
     627        uint32_t num_groups = 0;
    598628
    599629        DEBUG(3,("ads: lookup_usergroups_member\n"));
     
    653683                for (msg = ads_first_entry(ads, res); msg;
    654684                     msg = ads_next_entry(ads, msg)) {
    655                         DOM_SID group_sid;
     685                        struct dom_sid group_sid;
    656686
    657687                        if (!ads_pull_sid(ads, msg, "objectSid", &group_sid)) {
     
    690720                                           TALLOC_CTX *mem_ctx,
    691721                                           const char *user_dn,
    692                                            DOM_SID *primary_group,
    693                                            size_t *p_num_groups,
    694                                            DOM_SID **user_sids)
     722                                           struct dom_sid *primary_group,
     723                                           uint32_t *p_num_groups,
     724                                           struct dom_sid **user_sids)
    695725{
    696726        ADS_STATUS rc;
     
    698728        ADS_STRUCT *ads;
    699729        const char *attrs[] = {"memberOf", NULL};
    700         size_t num_groups = 0;
    701         DOM_SID *group_sids = NULL;
     730        uint32_t num_groups = 0;
     731        struct dom_sid *group_sids = NULL;
    702732        int i;
    703733        char **strings = NULL;
     
    740770        }
    741771
    742         group_sids = TALLOC_ZERO_ARRAY(mem_ctx, DOM_SID, num_strings + 1);
     772        group_sids = TALLOC_ZERO_ARRAY(mem_ctx, struct dom_sid, num_strings + 1);
    743773        if (!group_sids) {
    744774                status = NT_STATUS_NO_MEMORY;
     
    802832static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
    803833                                  TALLOC_CTX *mem_ctx,
    804                                   const DOM_SID *sid,
    805                                   uint32 *p_num_groups, DOM_SID **user_sids)
     834                                  const struct dom_sid *sid,
     835                                  uint32 *p_num_groups, struct dom_sid **user_sids)
    806836{
    807837        ADS_STRUCT *ads = NULL;
     
    811841        LDAPMessage *msg = NULL;
    812842        char *user_dn = NULL;
    813         DOM_SID *sids;
     843        struct dom_sid *sids;
    814844        int i;
    815         DOM_SID primary_group;
     845        struct dom_sid primary_group;
    816846        uint32 primary_group_rid;
    817847        NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
    818         size_t num_groups = 0;
     848        uint32_t num_groups = 0;
    819849
    820850        DEBUG(3,("ads: lookup_usergroups\n"));
     
    881911        }
    882912
    883         sid_copy(&primary_group, &domain->sid);
    884         sid_append_rid(&primary_group, primary_group_rid);
     913        sid_compose(&primary_group, &domain->sid, primary_group_rid);
    885914
    886915        count = ads_pull_sids(ads, mem_ctx, msg, "tokenGroups", &sids);
     
    902931                                                    &primary_group,
    903932                                                    &num_groups, user_sids);
    904                 *p_num_groups = (uint32)num_groups;
     933                *p_num_groups = num_groups;
    905934                if (NT_STATUS_IS_OK(status)) {
    906935                        goto done;
     
    913942                                                  &primary_group,
    914943                                                  &num_groups, user_sids);
    915                 *p_num_groups = (uint32)num_groups;
     944                *p_num_groups = num_groups;
    916945                goto done;
    917946        }
     
    954983static NTSTATUS lookup_useraliases(struct winbindd_domain *domain,
    955984                                   TALLOC_CTX *mem_ctx,
    956                                    uint32 num_sids, const DOM_SID *sids,
     985                                   uint32 num_sids, const struct dom_sid *sids,
    957986                                   uint32 *num_aliases, uint32 **alias_rids)
    958987{
     
    968997static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
    969998                                TALLOC_CTX *mem_ctx,
    970                                 const DOM_SID *group_sid,
     999                                const struct dom_sid *group_sid,
    9711000                                enum lsa_SidType type,
    9721001                                uint32 *num_names,
    973                                 DOM_SID **sid_mem, char ***names,
     1002                                struct dom_sid **sid_mem, char ***names,
    9741003                                uint32 **name_types)
    9751004{
     
    9831012        size_t num_members = 0;
    9841013        ads_control args;
    985         DOM_SID *sid_mem_nocache = NULL;
     1014        struct dom_sid *sid_mem_nocache = NULL;
    9861015        char **names_nocache = NULL;
    9871016        enum lsa_SidType *name_types_nocache = NULL;
     
    10151044        }
    10161045
    1017         if ((sidbinstr = sid_binstring(talloc_tos(), group_sid)) == NULL) {
     1046        if ((sidbinstr = ldap_encode_ndr_dom_sid(talloc_tos(), group_sid)) == NULL) {
    10181047                status = NT_STATUS_NO_MEMORY;
    10191048                goto done;
     
    10571086
    10581087        if (num_members) {
    1059                 (*sid_mem) = TALLOC_ZERO_ARRAY(mem_ctx, DOM_SID, num_members);
     1088                (*sid_mem) = TALLOC_ZERO_ARRAY(mem_ctx, struct dom_sid, num_members);
    10601089                (*names) = TALLOC_ZERO_ARRAY(mem_ctx, char *, num_members);
    10611090                (*name_types) = TALLOC_ZERO_ARRAY(mem_ctx, uint32, num_members);
    1062                 (sid_mem_nocache) = TALLOC_ZERO_ARRAY(tmp_ctx, DOM_SID, num_members);
     1091                (sid_mem_nocache) = TALLOC_ZERO_ARRAY(tmp_ctx, struct dom_sid, num_members);
    10631092
    10641093                if ((members == NULL) || (*sid_mem == NULL) ||
     
    10801109                enum lsa_SidType name_type;
    10811110                char *name, *domain_name;
    1082                 DOM_SID sid;
     1111                struct dom_sid sid;
    10831112
    10841113                rc = ads_get_sid_from_extended_dn(tmp_ctx, members[i], args.val,
     
    12611290{
    12621291        NTSTATUS                result = NT_STATUS_UNSUCCESSFUL;
     1292        WERROR werr;
    12631293        int                     i;
    12641294        uint32                  flags; 
    12651295        struct rpc_pipe_client *cli;
    1266         uint32                 fr_flags = (NETR_TRUST_FLAG_IN_FOREST | NETR_TRUST_FLAG_TREEROOT);
    12671296        int ret_count;
     1297        struct dcerpc_binding_handle *b;
    12681298
    12691299        DEBUG(3,("ads: trusted_domains\n"));
     
    12751305           trusts in the target forest */
    12761306
    1277         if ( domain->primary ||
    1278                 ((domain->domain_flags&fr_flags) == fr_flags) )
    1279         {
     1307        if (domain->primary || domain_is_forest_root(domain)) {
    12801308                flags = NETR_TRUST_FLAG_OUTBOUND |
    12811309                        NETR_TRUST_FLAG_INBOUND |
     
    12941322        }
    12951323
    1296         result = rpccli_netr_DsrEnumerateDomainTrusts(cli, mem_ctx,
     1324        b = cli->binding_handle;
     1325
     1326        result = dcerpc_netr_DsrEnumerateDomainTrusts(b, mem_ctx,
    12971327                                                      cli->desthost,
    12981328                                                      flags,
    12991329                                                      trusts,
    1300                                                       NULL);
     1330                                                      &werr);
    13011331        if (!NT_STATUS_IS_OK(result)) {
    13021332                return result;
     1333        }
     1334
     1335        if (!W_ERROR_IS_OK(werr)) {
     1336                return werror_to_ntstatus(werr);
    13031337        }
    13041338        if (trusts->count == 0) {
     
    13551389                        wcache_tdc_add_domain( &d );
    13561390                        ret_count++;
    1357                 } else if ( (domain->domain_flags&fr_flags) == fr_flags ) {
     1391                } else if (domain_is_forest_root(domain)) {
    13581392                        /* Check if we already have this record. If
    13591393                         * we are following our forest root that is not
Note: See TracChangeset for help on using the changeset viewer.