Ignore:
Timestamp:
Nov 24, 2016, 1:14:11 PM (9 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: update vendor to version 4.4.3

Location:
vendor/current/source3/winbindd
Files:
11 added
4 deleted
74 edited

Legend:

Unmodified
Added
Removed
  • vendor/current/source3/winbindd/idmap.c

    r740 r988  
    2525#include "winbindd.h"
    2626#include "idmap.h"
    27 #include "passdb/machine_sid.h"
     27#include "lib/util_sid_passdb.h"
     28#include "passdb.h"
    2829
    2930#undef DBGC_CLASS
     
    3132
    3233static_decl_idmap;
    33 
    34 static void idmap_init(void)
    35 {
    36         static bool initialized;
    37 
    38         if (initialized) {
    39                 return;
    40         }
    41 
    42         DEBUG(10, ("idmap_init(): calling static_init_idmap\n"));
    43 
    44         static_init_idmap;
    45 
    46         initialized = true;
    47 }
    4834
    4935/**
     
    7864static struct idmap_domain **idmap_domains = NULL;
    7965static int num_domains = 0;
     66
     67static struct idmap_domain *idmap_init_named_domain(TALLOC_CTX *mem_ctx,
     68                                                    const char *domname);
     69static struct idmap_domain *idmap_init_domain(TALLOC_CTX *mem_ctx,
     70                                              const char *domainname,
     71                                              const char *modulename,
     72                                              bool check_range);
     73static bool idmap_found_domain_backend(
     74        const char *string, regmatch_t matches[], void *private_data);
     75
     76static bool idmap_init(void)
     77{
     78        static bool initialized;
     79        int ret;
     80
     81        if (initialized) {
     82                return true;
     83        }
     84
     85        DEBUG(10, ("idmap_init(): calling static_init_idmap\n"));
     86
     87        static_init_idmap;
     88
     89        initialized = true;
     90
     91        if (!pdb_is_responsible_for_everything_else()) {
     92                default_idmap_domain = idmap_init_named_domain(NULL, "*");
     93                if (default_idmap_domain == NULL) {
     94                        return false;
     95                }
     96        }
     97
     98        passdb_idmap_domain = idmap_init_domain(
     99                NULL, get_global_sam_name(), "passdb", false);
     100        if (passdb_idmap_domain == NULL) {
     101                TALLOC_FREE(default_idmap_domain);
     102                return false;
     103        }
     104
     105        idmap_domains = talloc_array(NULL, struct idmap_domain *, 0);
     106        if (idmap_domains == NULL) {
     107                TALLOC_FREE(passdb_idmap_domain);
     108                TALLOC_FREE(default_idmap_domain);
     109                return false;
     110        }
     111
     112        ret = lp_wi_scan_global_parametrics(
     113                "idmapconfig\\(.*\\):backend", 2,
     114                idmap_found_domain_backend, NULL);
     115        if (ret != 0) {
     116                DBG_WARNING("wi_scan_global_parametrics returned %d\n", ret);
     117                return false;
     118        }
     119
     120        return true;
     121}
     122
     123bool domain_has_idmap_config(const char *domname)
     124{
     125        int i;
     126        char *config_option;
     127        const char *range = NULL;
     128        const char *backend = NULL;
     129        bool ok;
     130
     131        ok = idmap_init();
     132        if (!ok) {
     133                return false;
     134        }
     135
     136        for (i=0; i<num_domains; i++) {
     137                if (strequal(idmap_domains[i]->name, domname)) {
     138                        return true;
     139                }
     140        }
     141
     142        /* fallback: also check loadparm */
     143
     144        config_option = talloc_asprintf(talloc_tos(), "idmap config %s",
     145                                        domname);
     146        if (config_option == NULL) {
     147                DEBUG(0, ("out of memory\n"));
     148                return false;
     149        }
     150
     151        range = lp_parm_const_string(-1, config_option, "range", NULL);
     152        backend = lp_parm_const_string(-1, config_option, "backend", NULL);
     153        if (range != NULL && backend != NULL) {
     154                DEBUG(5, ("idmap configuration specified for domain '%s'\n",
     155                        domname));
     156                TALLOC_FREE(config_option);
     157                return true;
     158        }
     159
     160        TALLOC_FREE(config_option);
     161        return false;
     162}
     163
     164static bool idmap_found_domain_backend(
     165        const char *string, regmatch_t matches[], void *private_data)
     166{
     167        if (matches[1].rm_so == -1) {
     168                DBG_WARNING("Found match, but no name??\n");
     169                return false;
     170        }
     171
     172        {
     173                struct idmap_domain *dom, **tmp;
     174                regoff_t len = matches[1].rm_eo - matches[1].rm_so;
     175                char domname[len+1];
     176
     177                memcpy(domname, string + matches[1].rm_so, len);
     178                domname[len] = '\0';
     179
     180                DBG_DEBUG("Found idmap domain \"%s\"\n", domname);
     181
     182                if (strcmp(domname, "*") == 0) {
     183                        return false;
     184                }
     185
     186                dom = idmap_init_named_domain(idmap_domains, domname);
     187                if (dom == NULL) {
     188                        DBG_NOTICE("Could not init idmap domain %s\n",
     189                                   domname);
     190                        return false;
     191                }
     192
     193                tmp = talloc_realloc(idmap_domains, idmap_domains,
     194                                     struct idmap_domain *, num_domains + 1);
     195                if (tmp == NULL) {
     196                        DBG_WARNING("talloc_realloc failed\n");
     197                        TALLOC_FREE(dom);
     198                        return false;
     199                }
     200                idmap_domains = tmp;
     201                idmap_domains[num_domains] = dom;
     202                num_domains += 1;
     203        }
     204
     205        return false;
     206}
    80207
    81208static struct idmap_methods *get_methods(const char *name)
     
    130257        for (entry = backends; entry != NULL; entry = entry->next) {
    131258                if (strequal(entry->name, name)) {
    132                         DEBUG(0,("Idmap module %s already registered!\n",
     259                        DEBUG(5,("Idmap module %s already registered!\n",
    133260                                 name));
    134261                        return NT_STATUS_OBJECT_NAME_COLLISION;
     
    172299        char *config_option = NULL;
    173300        const char *range;
     301        unsigned low_id = 0;
     302        unsigned high_id = 0;
    174303
    175304        result = talloc_zero(mem_ctx, struct idmap_domain);
     
    186315
    187316        /*
     317         * Check whether the requested backend module exists and
     318         * load the methods.
     319         */
     320
     321        result->methods = get_methods(modulename);
     322        if (result->methods == NULL) {
     323                DEBUG(3, ("idmap backend %s not found\n", modulename));
     324
     325                status = smb_probe_module("idmap", modulename);
     326                if (!NT_STATUS_IS_OK(status)) {
     327                        DEBUG(3, ("Could not probe idmap module %s\n",
     328                                  modulename));
     329                        goto fail;
     330                }
     331
     332                result->methods = get_methods(modulename);
     333        }
     334        if (result->methods == NULL) {
     335                DEBUG(1, ("idmap backend %s not found\n", modulename));
     336                goto fail;
     337        }
     338
     339        /*
    188340         * load ranges and read only information from the config
    189341         */
     
    196348        }
    197349
     350        result->read_only = lp_parm_bool(-1, config_option, "read only", false);
    198351        range = lp_parm_const_string(-1, config_option, "range", NULL);
     352
     353        talloc_free(config_option);
     354
    199355        if (range == NULL) {
    200                 DEBUG(1, ("idmap range not specified for domain %s\n",
    201                           result->name));
    202356                if (check_range) {
     357                        DEBUG(1, ("idmap range not specified for domain %s\n",
     358                                  result->name));
    203359                        goto fail;
    204360                }
    205         } else if (sscanf(range, "%u - %u", &result->low_id,
    206                           &result->high_id) != 2)
     361        } else if (sscanf(range, "%u - %u", &low_id, &high_id) != 2)
    207362        {
    208363                DEBUG(1, ("invalid range '%s' specified for domain "
     
    211366                        goto fail;
    212367                }
    213         }
    214 
    215         result->read_only = lp_parm_bool(-1, config_option, "read only", false);
    216 
    217         talloc_free(config_option);
    218 
    219         if (result->low_id > result->high_id) {
    220                 DEBUG(1, ("Error: invalid idmap range detected: %lu - %lu\n",
    221                           (unsigned long)result->low_id,
    222                           (unsigned long)result->high_id));
     368        } else if (low_id > high_id) {
     369                DEBUG(1, ("Error: invalid idmap range detected: %u - %u\n",
     370                          low_id, high_id));
    223371                if (check_range) {
    224372                        goto fail;
     
    226374        }
    227375
    228         result->methods = get_methods(modulename);
    229         if (result->methods == NULL) {
    230                 DEBUG(3, ("idmap backend %s not found\n", modulename));
    231 
    232                 status = smb_probe_module("idmap", modulename);
    233                 if (!NT_STATUS_IS_OK(status)) {
    234                         DEBUG(3, ("Could not probe idmap module %s\n",
    235                                   modulename));
    236                         goto fail;
    237                 }
    238 
    239                 result->methods = get_methods(modulename);
    240         }
    241         if (result->methods == NULL) {
    242                 DEBUG(1, ("idmap backend %s not found\n", modulename));
    243                 goto fail;
    244         }
     376        result->low_id = low_id;
     377        result->high_id = high_id;
    245378
    246379        status = result->methods->init(result);
     
    274407        char *config_option;
    275408        const char *backend;
    276 
    277         idmap_init();
     409        bool ok;
     410
     411        ok = idmap_init();
     412        if (!ok) {
     413                return NULL;
     414        }
    278415
    279416        config_option = talloc_asprintf(talloc_tos(), "idmap config %s",
     
    286423        backend = lp_parm_const_string(-1, config_option, "backend", NULL);
    287424        if (backend == NULL) {
    288                 DEBUG(1, ("no backend defined for %s\n", config_option));
     425                DEBUG(10, ("no idmap backend configured for domain '%s'\n",
     426                           domname));
    289427                goto fail;
    290428        }
     
    302440        TALLOC_FREE(result);
    303441        return NULL;
    304 }
    305 
    306 /**
    307  * Initialize the default domain structure
    308  * @param[in] mem_ctx           memory context for the result
    309  * @result The default domain structure
    310  *
    311  * This routine takes the module name from the "idmap backend" parameter,
    312  * passing a possible parameter like ldap:ldap://ldap-url/ to the module.
    313  */
    314 
    315 static struct idmap_domain *idmap_init_default_domain(TALLOC_CTX *mem_ctx)
    316 {
    317         return idmap_init_named_domain(mem_ctx, "*");
    318 }
    319 
    320 /**
    321  * Initialize the passdb domain structure
    322  * @param[in] mem_ctx           memory context for the result
    323  * @result The default domain structure
    324  *
    325  * No config, passdb has its own configuration.
    326  */
    327 
    328 static struct idmap_domain *idmap_init_passdb_domain(TALLOC_CTX *mem_ctx)
    329 {
    330         idmap_init();
    331 
    332         /*
    333          * Always init the default domain, we can't go without one
    334          */
    335         if (default_idmap_domain == NULL) {
    336                 default_idmap_domain = idmap_init_default_domain(NULL);
    337         }
    338         if (default_idmap_domain == NULL) {
    339                 return NULL;
    340         }
    341 
    342         if (passdb_idmap_domain != NULL) {
    343                 return passdb_idmap_domain;
    344         }
    345 
    346         passdb_idmap_domain = idmap_init_domain(NULL, get_global_sam_name(),
    347                                                 "passdb", false);
    348         if (passdb_idmap_domain == NULL) {
    349                 DEBUG(1, ("Could not init passdb idmap domain\n"));
    350         }
    351 
    352         return passdb_idmap_domain;
    353442}
    354443
     
    368457 */
    369458
    370 struct idmap_domain *idmap_find_domain(const char *domname)
    371 {
    372         struct idmap_domain *result;
     459static struct idmap_domain *idmap_find_domain(const char *domname)
     460{
     461        bool ok;
    373462        int i;
    374463
     
    376465                   domname?domname:"NULL"));
    377466
    378         idmap_init();
    379 
    380         /*
    381          * Always init the default domain, we can't go without one
    382          */
    383         if (default_idmap_domain == NULL) {
    384                 default_idmap_domain = idmap_init_default_domain(NULL);
    385         }
    386         if (default_idmap_domain == NULL) {
     467        ok = idmap_init();
     468        if (!ok) {
    387469                return NULL;
    388470        }
     
    398480        }
    399481
    400         if (idmap_domains == NULL) {
    401                 /*
    402                  * talloc context for all idmap domains
    403                  */
    404                 idmap_domains = TALLOC_ARRAY(NULL, struct idmap_domain *, 1);
    405         }
    406 
    407         if (idmap_domains == NULL) {
    408                 DEBUG(0, ("talloc failed\n"));
     482        return default_idmap_domain;
     483}
     484
     485struct idmap_domain *idmap_find_domain_with_sid(const char *domname,
     486                                                const struct dom_sid *sid)
     487{
     488        bool ok;
     489
     490        ok = idmap_init();
     491        if (!ok) {
    409492                return NULL;
    410493        }
    411494
    412         result = idmap_init_named_domain(idmap_domains, domname);
    413         if (result == NULL) {
    414                 /*
    415                  * Could not init that domain -- try the default one
    416                  */
    417                 return default_idmap_domain;
    418         }
    419 
    420         ADD_TO_ARRAY(idmap_domains, struct idmap_domain *, result,
    421                      &idmap_domains, &num_domains);
    422         return result;
     495        if (sid_check_is_for_passdb(sid)) {
     496                return passdb_idmap_domain;
     497        }
     498
     499        return idmap_find_domain(domname);
    423500}
    424501
     
    468545}
    469546
    470 NTSTATUS idmap_backends_unixid_to_sid(const char *domname, struct id_map *id)
     547NTSTATUS idmap_backends_unixid_to_sid(struct id_map *id)
    471548{
    472549        struct idmap_domain *dom;
    473550        struct id_map *maps[2];
    474 
    475          DEBUG(10, ("idmap_backend_unixid_to_sid: domain = '%s', xid = %d "
    476                     "(type %d)\n",
    477                     domname?domname:"NULL", id->xid.id, id->xid.type));
     551        bool ok;
     552        int i;
     553
     554        ok = idmap_init();
     555        if (!ok) {
     556                return NT_STATUS_NONE_MAPPED;
     557        }
     558
     559        DEBUG(10, ("idmap_backend_unixid_to_sid: xid = %d (type %d)\n",
     560                   id->xid.id, id->xid.type));
    478561
    479562        maps[0] = id;
     
    484567         */
    485568
    486         dom = idmap_init_passdb_domain(NULL);
     569        dom = passdb_idmap_domain;
    487570        if ((dom != NULL)
    488571            && NT_STATUS_IS_OK(dom->methods->unixids_to_sids(dom, maps))
     
    491574        }
    492575
    493         dom = idmap_find_domain(domname);
     576        dom = default_idmap_domain;
     577
     578        for (i=0; i<num_domains; i++) {
     579                if ((id->xid.id >= idmap_domains[i]->low_id) &&
     580                    (id->xid.id <= idmap_domains[i]->high_id)) {
     581                        dom = idmap_domains[i];
     582                        break;
     583                }
     584        }
     585
    494586        if (dom == NULL) {
    495587                return NT_STATUS_NONE_MAPPED;
     
    498590        return dom->methods->unixids_to_sids(dom, maps);
    499591}
    500 
    501 NTSTATUS idmap_backends_sid_to_unixid(const char *domain, struct id_map *id)
    502 {
    503         struct idmap_domain *dom;
    504         struct id_map *maps[2];
    505 
    506         DEBUG(10, ("idmap_backends_sid_to_unixid: domain = '%s', sid = [%s]\n",
    507                    domain?domain:"NULL", sid_string_dbg(id->sid)));
    508 
    509         maps[0] = id;
    510         maps[1] = NULL;
    511 
    512         if (sid_check_is_in_builtin(id->sid)
    513             || (sid_check_is_in_our_domain(id->sid)))
    514         {
    515                 NTSTATUS status;
    516 
    517                 DEBUG(10, ("asking passdb...\n"));
    518 
    519                 dom = idmap_init_passdb_domain(NULL);
    520                 if (dom == NULL) {
    521                         return NT_STATUS_NONE_MAPPED;
    522                 }
    523                 status = dom->methods->sids_to_unixids(dom, maps);
    524 
    525                 if (NT_STATUS_IS_OK(status) && id->status == ID_MAPPED) {
    526                         return status;
    527                 }
    528 
    529                 DEBUG(10, ("passdb could not map.\n"));
    530 
    531                 return NT_STATUS_NONE_MAPPED;
    532         }
    533 
    534         dom = idmap_find_domain(domain);
    535         if (dom == NULL) {
    536                 return NT_STATUS_NONE_MAPPED;
    537         }
    538 
    539         return dom->methods->sids_to_unixids(dom, maps);
    540 }
  • vendor/current/source3/winbindd/idmap_ad.c

    r860 r988  
    3232#include "libads/ldap_schema.h"
    3333#include "nss_info.h"
    34 #include "secrets.h"
    3534#include "idmap.h"
    3635#include "../libcli/ldap/ldap_ndr.h"
     
    4039#define DBGC_CLASS DBGC_IDMAP
    4140
    42 #define WINBIND_CCACHE_NAME "MEMORY:winbind_ccache"
    43 
    44 #define IDMAP_AD_MAX_IDS 30
    4541#define CHECK_ALLOC_DONE(mem) do { \
    4642     if (!mem) { \
     
    5753};
    5854
    59 NTSTATUS init_module(void);
    60 
    6155/************************************************************************
    6256 ***********************************************************************/
    6357
    64 static ADS_STATUS ad_idmap_cached_connection_internal(struct idmap_domain *dom)
    65 {
    66         ADS_STRUCT *ads;
     58static ADS_STATUS ad_idmap_cached_connection(struct idmap_domain *dom)
     59{
    6760        ADS_STATUS status;
    68         bool local = False;
    69         fstring dc_name;
    70         struct sockaddr_storage dc_ip;
    71         struct idmap_ad_context *ctx;
    72         char *ldap_server = NULL;
    73         char *realm = NULL;
    74         struct winbindd_domain *wb_dom;
     61        struct idmap_ad_context * ctx;
    7562
    7663        DEBUG(10, ("ad_idmap_cached_connection: called for domain '%s'\n",
     
    7966        ctx = talloc_get_type(dom->private_data, struct idmap_ad_context);
    8067
    81         if (ctx->ads != NULL) {
    82 
    83                 time_t expire;
    84                 time_t now = time(NULL);
    85 
    86                 ads = ctx->ads;
    87 
    88                 expire = MIN(ads->auth.tgt_expire, ads->auth.tgs_expire);
    89 
    90                 /* check for a valid structure */
    91                 DEBUG(7, ("Current tickets expire in %d seconds (at %d, time is now %d)\n",
    92                           (uint32)expire-(uint32)now, (uint32) expire, (uint32) now));
    93 
    94                 if ( ads->config.realm && (expire > time(NULL))) {
    95                         return ADS_SUCCESS;
    96                 } else {
    97                         /* we own this ADS_STRUCT so make sure it goes away */
    98                         DEBUG(7,("Deleting expired krb5 credential cache\n"));
    99                         ads->is_mine = True;
    100                         ads_destroy( &ads );
    101                         ads_kdestroy(WINBIND_CCACHE_NAME);
    102                         ctx->ads = NULL;
    103                 }
    104         }
    105 
    106         if (!local) {
    107                 /* we don't want this to affect the users ccache */
    108                 setenv("KRB5CCNAME", WINBIND_CCACHE_NAME, 1);
    109         }
    110 
    111         /*
    112          * At this point we only have the NetBIOS domain name.
    113          * Check if we can get server nam and realm from SAF cache
    114          * and the domain list.
    115          */
    116         ldap_server = saf_fetch(dom->name);
    117         DEBUG(10, ("ldap_server from saf cache: '%s'\n", ldap_server?ldap_server:""));
    118 
    119         wb_dom = find_domain_from_name_noinit(dom->name);
    120         if (wb_dom == NULL) {
    121                 DEBUG(10, ("find_domain_from_name_noinit did not find domain '%s'\n",
    122                            dom->name));
    123                 realm = NULL;
    124         } else {
    125                 DEBUG(10, ("find_domain_from_name_noinit found realm '%s' for "
    126                           " domain '%s'\n", wb_dom->alt_name, dom->name));
    127                 realm = wb_dom->alt_name;
    128         }
    129 
    130         if ( (ads = ads_init(realm, dom->name, ldap_server)) == NULL ) {
    131                 DEBUG(1,("ads_init failed\n"));
    132                 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
    133         }
    134 
    135         /* the machine acct password might have change - fetch it every time */
    136         SAFE_FREE(ads->auth.password);
    137         ads->auth.password = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL);
    138 
    139         SAFE_FREE(ads->auth.realm);
    140         ads->auth.realm = SMB_STRDUP(lp_realm());
    141 
    142         /* setup server affinity */
    143 
    144         get_dc_name(dom->name, realm, dc_name, &dc_ip );
    145 
    146         status = ads_connect(ads);
    147         if (!ADS_ERR_OK(status)) {
    148                 DEBUG(1, ("ad_idmap_cached_connection_internal: failed to "
    149                           "connect to AD\n"));
    150                 ads_destroy(&ads);
    151                 return status;
    152         }
    153 
    154         ads->is_mine = False;
    155 
    156         ctx->ads = ads;
    157 
    158         return ADS_SUCCESS;
    159 }
    160 
    161 /************************************************************************
    162  ***********************************************************************/
    163 
    164 static ADS_STATUS ad_idmap_cached_connection(struct idmap_domain *dom)
    165 {
    166         ADS_STATUS status;
    167         struct idmap_ad_context * ctx;
    168 
    169         status = ad_idmap_cached_connection_internal(dom);
     68        status = ads_idmap_cached_connection(&ctx->ads, dom->name);
    17069        if (!ADS_ERR_OK(status)) {
    17170                return status;
     
    217116        const char *schema_mode = NULL;
    218117
    219         ctx = TALLOC_ZERO_P(dom, struct idmap_ad_context);
     118        ctx = talloc_zero(dom, struct idmap_ad_context);
    220119        if (ctx == NULL) {
    221120                DEBUG(0, ("Out of memory!\n"));
     
    253152
    254153        return NT_STATUS_OK;
    255 }
    256 
    257 /************************************************************************
    258  Search up to IDMAP_AD_MAX_IDS entries in maps for a match.
    259  ***********************************************************************/
    260 
    261 static struct id_map *find_map_by_id(struct id_map **maps, enum id_type type, uint32_t id)
    262 {
    263         int i;
    264 
    265         for (i = 0; maps[i] && i<IDMAP_AD_MAX_IDS; i++) {
    266                 if ((maps[i]->xid.type == type) && (maps[i]->xid.id == id)) {
    267                         return maps[i];
    268                 }
    269         }
    270 
    271         return NULL;   
    272 }
    273 
    274 /************************************************************************
    275  Search up to IDMAP_AD_MAX_IDS entries in maps for a match
    276  ***********************************************************************/
    277 
    278 static struct id_map *find_map_by_sid(struct id_map **maps, struct dom_sid *sid)
    279 {
    280         int i;
    281 
    282         for (i = 0; maps[i] && i<IDMAP_AD_MAX_IDS; i++) {
    283                 if (dom_sid_equal(maps[i]->sid, sid)) {
    284                         return maps[i];
    285                 }
    286         }
    287 
    288         return NULL;   
    289154}
    290155
     
    343208again:
    344209        bidx = idx;
    345         for (i = 0; (i < IDMAP_AD_MAX_IDS) && ids[idx]; i++, idx++) {
     210        for (i = 0; (i < IDMAP_LDAP_MAX_IDS) && ids[idx]; i++, idx++) {
    346211                switch (ids[idx]->xid.type) {
    347212                case ID_TYPE_UID:     
     
    468333                }
    469334
    470                 map = find_map_by_id(&ids[bidx], type, id);
     335                map = idmap_find_map_by_id(&ids[bidx], type, id);
    471336                if (!map) {
    472337                        DEBUG(2, ("WARNING: couldn't match result with requested ID\n"));
     
    573438
    574439        bidx = idx;
    575         for (i = 0; (i < IDMAP_AD_MAX_IDS) && ids[idx]; i++, idx++) {
     440        for (i = 0; (i < IDMAP_LDAP_MAX_IDS) && ids[idx]; i++, idx++) {
    576441
    577442                ids[idx]->status = ID_UNKNOWN;
     
    623488                }
    624489
    625                 map = find_map_by_sid(&ids[bidx], &sid);
     490                map = idmap_find_map_by_sid(&ids[bidx], &sid);
    626491                if (!map) {
    627492                        DEBUG(2, ("WARNING: couldn't match result with requested SID\n"));
     
    738603                dom = talloc_get_type(e->state, struct idmap_domain);
    739604        } else {
    740                 dom = TALLOC_ZERO_P(e, struct idmap_domain);
     605                dom = talloc_zero(e, struct idmap_domain);
    741606                if (dom == NULL) {
    742607                        DEBUG(0, ("Out of memory!\n"));
     
    758623                                      struct idmap_ad_context);
    759624        } else {
    760                 ctx = TALLOC_ZERO_P(dom, struct idmap_ad_context);
     625                ctx = talloc_zero(dom, struct idmap_ad_context);
    761626                if (ctx == NULL) {
    762627                        DEBUG(0, ("Out of memory!\n"));
     
    808673                                  const char **shell,
    809674                                  const char **gecos,
    810                                   uint32 *gid )
     675                                  uint32_t *gid )
    811676{
    812677        const char *attrs[] = {NULL, /* attr_homedir */
     
    879744        if (gid) {
    880745                if (!ads_pull_uint32(ctx->ads, msg_internal, ctx->ad_schema->posix_gidnumber_attr, gid))
    881                         *gid = (uint32)-1;
     746                        *gid = (uint32_t)-1;
    882747        }
    883748
     
    1098963 ***********************************************************************/
    1099964
     965static_decl_idmap;
    1100966NTSTATUS idmap_ad_init(void)
    1101967{
  • vendor/current/source3/winbindd/idmap_autorid.c

    r746 r988  
    66 *  for the domains by automatically allocating a range for each domain
    77 *
    8  *  Copyright (C) Christian Ambach, 2010-2011
     8 *  Copyright (C) Christian Ambach, 2010-2012
    99 *
    1010 *  This program is free software; you can redistribute it and/or modify
     
    2323 */
    2424
    25 #include "includes.h"
    26 #include "system/filesys.h"
     25/*
     26 * This module allocates ranges for domains to be used in a
     27 * algorithmic mode like idmap_rid. Multiple ranges are supported
     28 * for a single domain: If a rid exceeds the range size, a matching
     29 * range is allocated to hold the rid's id.
     30 *
     31 * Here are the formulas applied:
     32 *
     33 *
     34 * For a sid of the form domain_sid-rid, we have
     35 *
     36 *   rid = reduced_rid + domain_range_index * range_size
     37 *
     38 * with
     39 *   reduced_rid := rid % range_size
     40 *   domain_range_index := rid / range_size
     41 *
     42 * And reduced_rid fits into a range.
     43 *
     44 * In the database, we associate a range_number to
     45 * the pair domain_sid,domain_range_index.
     46 *
     47 * Now the unix id for the given sid calculates as:
     48 *
     49 *   id = reduced_rid + range_low_id
     50 *
     51 * with
     52 *
     53 *   range_low_id = low_id + range_number * range_size
     54 *
     55 *
     56 * The inverse calculation goes like this:
     57 *
     58 * Given a unix id, let
     59 *
     60 *   normalized_id := id - low_id
     61 *   reduced_rid := normalized_id % range_size
     62 *   range_number = normalized_id / range_size
     63 *
     64 * Then we have
     65 *
     66 *   id = reduced_rid + low_id + range_number * range_size
     67 *
     68 * From the database, get the domain_sid,domain_range_index pair
     69 * belonging to the range_number (if there is already one).
     70 *
     71 * Then the rid for the unix id calculates as:
     72 *
     73 *   rid = reduced_rid + domain_range_index * range_size
     74 */
     75
     76#include "idmap_autorid_tdb.h"
    2777#include "winbindd.h"
    28 #include "dbwrap.h"
    2978#include "idmap.h"
     79#include "idmap_rw.h"
    3080#include "../libcli/security/dom_sid.h"
    31 #include "util_tdb.h"
    3281
    3382#undef DBGC_CLASS
    3483#define DBGC_CLASS DBGC_IDMAP
    3584
    36 #define HWM "NEXT RANGE"
    37 #define ALLOC_HWM_UID "NEXT ALLOC UID"
    38 #define ALLOC_HWM_GID "NEXT ALLOC GID"
    39 #define ALLOC_RANGE "ALLOC"
    40 #define CONFIGKEY "CONFIG"
    41 
    42 struct autorid_global_config {
    43         uint32_t minvalue;
    44         uint32_t rangesize;
    45         uint32_t maxranges;
    46 };
    47 
    48 struct autorid_domain_config {
    49         fstring sid;
    50         uint32_t domainnum;
    51         struct autorid_global_config *globalcfg;
    52 };
     85#define IDMAP_AUTORID_ALLOC_RESERVED 500
    5386
    5487/* handle to the tdb storing domain <-> range assignments */
    5588static struct db_context *autorid_db;
    5689
    57 static NTSTATUS idmap_autorid_get_domainrange(struct db_context *db,
    58                                               void *private_data)
    59 {
     90static bool ignore_builtin = false;
     91
     92static NTSTATUS idmap_autorid_get_alloc_range(struct idmap_domain *dom,
     93                                        struct autorid_range_config *range)
     94{
     95        NTSTATUS status;
     96
     97        ZERO_STRUCT(*range);
     98
     99        fstrcpy(range->domsid, ALLOC_RANGE);
     100
     101        status = idmap_autorid_get_domainrange(autorid_db,
     102                                               range,
     103                                               dom->read_only);
     104
     105        return status;
     106}
     107
     108static NTSTATUS idmap_autorid_allocate_id(struct idmap_domain *dom,
     109                                          struct unixid *xid) {
     110
    60111        NTSTATUS ret;
    61         uint32_t domainnum, hwm;
    62         char *numstr;
    63         struct autorid_domain_config *cfg;
    64 
    65         cfg = (struct autorid_domain_config *)private_data;
    66 
    67         if (!dbwrap_fetch_uint32(db, cfg->sid, &domainnum)) {
    68                 DEBUG(10, ("Acquiring new range for domain %s\n", cfg->sid));
    69 
    70                 /* fetch the current HWM */
    71                 if (!dbwrap_fetch_uint32(db, HWM, &hwm)) {
    72                         DEBUG(1, ("Fatal error while fetching current "
    73                                   "HWM value!\n"));
    74                         ret = NT_STATUS_INTERNAL_ERROR;
    75                         goto error;
    76                 }
    77 
    78                 /* do we have a range left? */
    79                 if (hwm >= cfg->globalcfg->maxranges) {
    80                         DEBUG(1, ("No more domain ranges available!\n"));
    81                         ret = NT_STATUS_NO_MEMORY;
    82                         goto error;
    83                 }
    84 
    85                 /* increase the HWM */
    86                 ret = dbwrap_change_uint32_atomic(db, HWM, &domainnum, 1);
    87                 if (!NT_STATUS_IS_OK(ret)) {
    88                         DEBUG(1, ("Fatal error while fetching a new "
    89                                   "domain range value!\n"));
    90                         goto error;
    91                 }
    92 
    93                 /* store away the new mapping in both directions */
    94                 ret = dbwrap_trans_store_uint32(db, cfg->sid, domainnum);
    95                 if (!NT_STATUS_IS_OK(ret)) {
    96                         DEBUG(1, ("Fatal error while storing new "
    97                                   "domain->range assignment!\n"));
    98                         goto error;
    99                 }
    100 
    101                 numstr = talloc_asprintf(db, "%u", domainnum);
    102                 if (!numstr) {
    103                         ret = NT_STATUS_NO_MEMORY;
    104                         goto error;
    105                 }
    106 
    107                 ret = dbwrap_trans_store_bystring(db, numstr,
    108                                 string_term_tdb_data(cfg->sid), TDB_INSERT);
    109 
    110                 talloc_free(numstr);
    111                 if (!NT_STATUS_IS_OK(ret)) {
    112                         DEBUG(1, ("Fatal error while storing "
    113                                   "new domain->range assignment!\n"));
    114                         goto error;
    115                 }
    116                 DEBUG(5, ("Acquired new range #%d for domain %s\n",
    117                           domainnum, cfg->sid));
    118         }
    119 
    120         DEBUG(10, ("Using range #%d for domain %s\n", domainnum, cfg->sid));
    121         cfg->domainnum = domainnum;
    122 
    123         return NT_STATUS_OK;
    124 
    125       error:
     112        struct autorid_range_config range;
     113
     114        if (dom->read_only) {
     115                DEBUG(3, ("Backend is read-only, refusing "
     116                          "new allocation request\n"));
     117                return NT_STATUS_UNSUCCESSFUL;
     118        }
     119
     120        /* fetch the range for the allocation pool */
     121
     122        ret = idmap_autorid_get_alloc_range(dom, &range);
     123        if (!NT_STATUS_IS_OK(ret)) {
     124                DEBUG(3, ("Could not determine range for allocation pool, "
     125                          "check previous messages for reason\n"));
     126                return ret;
     127        }
     128
     129        ret = idmap_tdb_common_get_new_id(dom, xid);
     130
     131        if (!NT_STATUS_IS_OK(ret)) {
     132                DEBUG(1, ("Fatal error while allocating new ID!\n"));
     133                return ret;
     134        }
     135
     136        xid->id = xid->id + range.low_id;
     137
     138        DEBUG(10, ("Returned new %s %d from allocation range\n",
     139                   (xid->type==ID_TYPE_UID)?"uid":"gid", xid->id));
     140
    126141        return ret;
    127 
     142}
     143
     144/*
     145 * map a SID to xid using the idmap_tdb like pool
     146 */
     147static NTSTATUS idmap_autorid_id_to_sid_alloc(struct idmap_domain *dom,
     148                                              struct id_map *map)
     149{
     150        NTSTATUS ret;
     151
     152        /* look out for the mapping */
     153        ret = idmap_tdb_common_unixid_to_sid(dom, map);
     154
     155        if (NT_STATUS_IS_OK(ret)) {
     156                map->status = ID_MAPPED;
     157                return ret;
     158        }
     159
     160        map->status = ID_UNKNOWN;
     161
     162        DEBUG(10, ("no ID->SID mapping for %d could be found\n", map->xid.id));
     163
     164        return ret;
    128165}
    129166
    130167static NTSTATUS idmap_autorid_id_to_sid(struct autorid_global_config *cfg,
     168                                        struct idmap_domain *dom,
    131169                                        struct id_map *map)
    132170{
    133         uint32_t range;
    134         TDB_DATA data;
     171        uint32_t range_number;
     172        uint32_t domain_range_index = 0;
     173        uint32_t normalized_id;
     174        uint32_t reduced_rid;
     175        uint32_t rid;
     176        TDB_DATA data = tdb_null;
    135177        char *keystr;
    136         struct dom_sid sid;
     178        struct dom_sid domsid;
     179        NTSTATUS status;
     180        bool ok;
     181        const char *q = NULL;
    137182
    138183        /* can this be one of our ids? */
     
    152197
    153198        /* determine the range of this uid */
    154         range = ((map->xid.id - cfg->minvalue) / cfg->rangesize);
    155 
    156         keystr = talloc_asprintf(talloc_tos(), "%u", range);
     199
     200        normalized_id = map->xid.id - cfg->minvalue;
     201        range_number = normalized_id / cfg->rangesize;
     202
     203        keystr = talloc_asprintf(talloc_tos(), "%u", range_number);
    157204        if (!keystr) {
    158205                return NT_STATUS_NO_MEMORY;
    159206        }
    160207
    161         data = dbwrap_fetch_bystring(autorid_db, talloc_tos(), keystr);
     208        status = dbwrap_fetch_bystring(autorid_db, talloc_tos(), keystr, &data);
    162209        TALLOC_FREE(keystr);
    163210
    164         if (!data.dptr) {
     211        if (!NT_STATUS_IS_OK(status)) {
    165212                DEBUG(4, ("id %d belongs to range %d which does not have "
    166213                          "domain mapping, ignoring mapping request\n",
    167                           map->xid.id, range));
     214                          map->xid.id, range_number));
    168215                TALLOC_FREE(data.dptr);
    169216                map->status = ID_UNKNOWN;
     
    174221                    ALLOC_RANGE,
    175222                    strlen(ALLOC_RANGE)) == 0) {
    176                 /* this is from the alloc range, there is no mapping back */
    177                 DEBUG(5, ("id %d belongs to alloc range, cannot map back\n",
     223                /*
     224                 * this is from the alloc range, check if there is a mapping
     225                 */
     226                DEBUG(5, ("id %d belongs to allocation range, "
     227                          "checking for mapping\n",
    178228                          map->xid.id));
    179229                TALLOC_FREE(data.dptr);
     230                return idmap_autorid_id_to_sid_alloc(dom, map);
     231        }
     232
     233        ok = dom_sid_parse_endp((const char *)data.dptr, &domsid, &q);
     234        TALLOC_FREE(data.dptr);
     235        if (!ok) {
    180236                map->status = ID_UNKNOWN;
    181237                return NT_STATUS_OK;
    182238        }
    183 
    184         string_to_sid(&sid, (const char *)data.dptr);
    185         TALLOC_FREE(data.dptr);
    186 
    187         sid_compose(map->sid, &sid,
    188                     (map->xid.id - cfg->minvalue -
    189                      range * cfg->rangesize));
     239        if ((q != NULL) && (*q != '\0'))
     240                if (sscanf(q+1, "%"SCNu32, &domain_range_index) != 1) {
     241                        DEBUG(10, ("Domain range index not found, "
     242                                   "ignoring mapping request\n"));
     243                        map->status = ID_UNKNOWN;
     244                        return NT_STATUS_OK;
     245                }
     246
     247        reduced_rid = normalized_id % cfg->rangesize;
     248        rid = reduced_rid + domain_range_index * cfg->rangesize;
     249
     250        sid_compose(map->sid, &domsid, rid);
    190251
    191252        /* We **really** should have some way of validating
     
    194255
    195256        map->status = ID_MAPPED;
     257        map->xid.type = ID_TYPE_BOTH;
     258
    196259        return NT_STATUS_OK;
    197260}
     
    201264**********************************/
    202265
    203 static NTSTATUS idmap_autorid_sid_to_id(struct autorid_global_config *global,
    204                                         struct autorid_domain_config *domain,
     266static NTSTATUS idmap_autorid_sid_to_id_rid(
     267                                        struct autorid_global_config *global,
     268                                        struct autorid_range_config *range,
    205269                                        struct id_map *map)
    206270{
    207271        uint32_t rid;
     272        uint32_t reduced_rid;
    208273
    209274        sid_peek_rid(map->sid, &rid);
    210275
    211         /* if the rid is higher than the size of the range, we cannot map it */
    212         if (rid >= global->rangesize) {
    213                 map->status = ID_UNKNOWN;
    214                 DEBUG(2, ("RID %d is larger then size of range (%d), "
    215                           "user cannot be mapped\n", rid, global->rangesize));
    216                 return NT_STATUS_UNSUCCESSFUL;
    217         }
    218         map->xid.id = global->minvalue +
    219             (global->rangesize * domain->domainnum)+rid;
    220 
    221         /* We **really** should have some way of validating
    222            the SID exists and is the correct type here.  But
    223            that is a deficiency in the idmap_rid design. */
    224 
     276        reduced_rid = rid % global->rangesize;
     277
     278        map->xid.id = reduced_rid + range->low_id;
     279        map->xid.type = ID_TYPE_BOTH;
    225280        map->status = ID_MAPPED;
    226281
     
    235290                                              struct id_map **ids)
    236291{
     292        struct idmap_tdb_common_context *commoncfg;
    237293        struct autorid_global_config *globalcfg;
    238294        NTSTATUS ret;
    239295        int i;
     296        int num_tomap = 0;
     297        int num_mapped = 0;
    240298
    241299        /* initialize the status to avoid surprise */
    242300        for (i = 0; ids[i]; i++) {
    243301                ids[i]->status = ID_UNKNOWN;
    244         }
    245 
    246         globalcfg = talloc_get_type(dom->private_data,
     302                num_tomap++;
     303        }
     304
     305        commoncfg =
     306            talloc_get_type_abort(dom->private_data,
     307                                  struct idmap_tdb_common_context);
     308
     309        globalcfg = talloc_get_type(commoncfg->private_data,
    247310                                    struct autorid_global_config);
    248311
    249312        for (i = 0; ids[i]; i++) {
    250313
    251                 ret = idmap_autorid_id_to_sid(globalcfg, ids[i]);
     314                ret = idmap_autorid_id_to_sid(globalcfg, dom, ids[i]);
    252315
    253316                if ((!NT_STATUS_IS_OK(ret)) &&
     
    258321                        goto failure;
    259322                }
    260         }
    261         return NT_STATUS_OK;
     323
     324                if (NT_STATUS_IS_OK(ret) && ids[i]->status == ID_MAPPED) {
     325                        num_mapped++;
     326                }
     327
     328        }
     329
     330        if (num_tomap == num_mapped) {
     331                return NT_STATUS_OK;
     332        } else if (num_mapped == 0) {
     333                return NT_STATUS_NONE_MAPPED;
     334        }
     335
     336        return STATUS_SOME_UNMAPPED;
     337
    262338
    263339      failure:
    264340        return ret;
     341}
     342
     343static bool idmap_autorid_sid_is_special(struct dom_sid *sid)
     344{
     345        bool match;
     346
     347        match = sid_check_is_in_wellknown_domain(sid);
     348        if (match) {
     349                return true;
     350        }
     351
     352        return false;
     353}
     354
     355static NTSTATUS idmap_autorid_sid_to_id_special(struct idmap_domain *dom,
     356                                                struct id_map *map)
     357{
     358        struct idmap_tdb_common_context *common =
     359                talloc_get_type_abort(dom->private_data,
     360                                      struct idmap_tdb_common_context);
     361        uint32_t count;
     362        struct autorid_range_config range;
     363        NTSTATUS status;
     364        uint32_t free_id;
     365
     366        status = idmap_autorid_get_alloc_range(dom, &range);
     367        if (!NT_STATUS_IS_OK(status)) {
     368                return status;
     369        }
     370
     371        /* Take the next free ID, counting from the top */
     372        free_id = 0;
     373        for (count = 0; count < IDMAP_AUTORID_ALLOC_RESERVED; count++) {
     374                struct id_map test_map;
     375                struct dom_sid sid;
     376
     377                test_map.sid = &sid;
     378                test_map.xid.type = map->xid.type;
     379                test_map.xid.id = range.high_id - count;
     380                test_map.status = ID_UNKNOWN;
     381
     382                status = idmap_tdb_common_unixid_to_sid(dom, &test_map);
     383                if (NT_STATUS_EQUAL(NT_STATUS_NONE_MAPPED, status)) {
     384                        free_id = test_map.xid.id;
     385                        break;
     386                }
     387
     388                if (!NT_STATUS_IS_OK(status)) {
     389                        /* error - get out */
     390                        return status;
     391                }
     392
     393                /* mapping exists - try next ID */
     394        }
     395
     396        if (free_id == 0) {
     397                return NT_STATUS_NONE_MAPPED;
     398        }
     399
     400        map->status = ID_MAPPED;
     401        map->xid.id = free_id;
     402
     403        status = common->rw_ops->set_mapping(dom, map);
     404        if (!NT_STATUS_IS_OK(status)) {
     405                DEBUG(2, ("Error storing new mapping: %s\n",
     406                          nt_errstr(status)));
     407                return status;
     408        }
     409
     410        return NT_STATUS_OK;
     411}
     412
     413struct idmap_autorid_sid_to_id_alloc_ctx {
     414        struct idmap_domain *dom;
     415        struct id_map *map;
     416};
     417
     418static NTSTATUS idmap_autorid_sid_to_id_alloc_action(
     419                                struct db_context *db,
     420                                void *private_data)
     421{
     422        struct idmap_autorid_sid_to_id_alloc_ctx *ctx;
     423
     424        ctx = (struct idmap_autorid_sid_to_id_alloc_ctx *)private_data;
     425
     426        if (idmap_autorid_sid_is_special(ctx->map->sid)) {
     427                NTSTATUS ret;
     428
     429                ret = idmap_autorid_sid_to_id_special(ctx->dom, ctx->map);
     430                if (NT_STATUS_IS_OK(ret)) {
     431                        return NT_STATUS_OK;
     432                }
     433                if (!NT_STATUS_EQUAL(NT_STATUS_NONE_MAPPED, ret)) {
     434                        return ret;
     435                }
     436
     437                DEBUG(10, ("Sepecial sid %s not mapped. falling back to "
     438                           "regular allocation\n",
     439                           sid_string_dbg(ctx->map->sid)));
     440        }
     441
     442        return idmap_tdb_common_new_mapping(ctx->dom, ctx->map);
     443}
     444
     445/*
     446 * map a SID to xid using the idmap_tdb like pool
     447 */
     448static NTSTATUS idmap_autorid_sid_to_id_alloc(
     449                                        struct idmap_tdb_common_context *ctx,
     450                                        struct idmap_domain *dom,
     451                                        struct id_map *map)
     452{
     453        NTSTATUS ret;
     454        struct idmap_autorid_sid_to_id_alloc_ctx alloc_ctx;
     455
     456        map->status = ID_UNKNOWN;
     457
     458        /* see if we already have a mapping */
     459        ret = idmap_tdb_common_sid_to_unixid(dom, map);
     460
     461        if (NT_STATUS_IS_OK(ret)) {
     462                map->status = ID_MAPPED;
     463                return ret;
     464        }
     465
     466        /* bad things happened */
     467        if (!NT_STATUS_EQUAL(ret, NT_STATUS_NONE_MAPPED)) {
     468                DEBUG(1, ("Looking up SID->ID mapping for %s failed: %s\n",
     469                          sid_string_dbg(map->sid), nt_errstr(ret)));
     470                return ret;
     471        }
     472
     473        if (dom->read_only) {
     474                DEBUG(3, ("Not allocating new mapping for %s, because backend "
     475                          "is read-only\n", sid_string_dbg(map->sid)));
     476                map->status = ID_UNMAPPED;
     477                return NT_STATUS_NONE_MAPPED;
     478        }
     479
     480        DEBUG(10, ("Creating new mapping in pool for %s\n",
     481                   sid_string_dbg(map->sid)));
     482
     483        alloc_ctx.dom = dom;
     484        alloc_ctx.map = map;
     485
     486        ret = dbwrap_trans_do(ctx->db, idmap_autorid_sid_to_id_alloc_action,
     487                              &alloc_ctx);
     488        if (!NT_STATUS_IS_OK(ret)) {
     489                DEBUG(1, ("Failed to create a new mapping in alloc range: %s\n",
     490                          nt_errstr(ret)));
     491                return NT_STATUS_INTERNAL_DB_CORRUPTION;
     492        }
     493
     494        map->status = ID_MAPPED;
     495        return NT_STATUS_OK;
     496}
     497
     498static bool idmap_autorid_domsid_is_for_alloc(struct dom_sid *sid)
     499{
     500        bool match;
     501
     502        match = sid_check_is_wellknown_domain(sid, NULL);
     503        if (match) {
     504                return true;
     505        }
     506
     507        return false;
     508}
     509
     510static NTSTATUS idmap_autorid_sid_to_id(struct idmap_tdb_common_context *common,
     511                                        struct idmap_domain *dom,
     512                                        struct id_map *map)
     513{
     514        struct autorid_global_config *global =
     515                talloc_get_type_abort(common->private_data,
     516                                      struct autorid_global_config);
     517        struct winbindd_tdc_domain *domain;
     518        struct autorid_range_config range;
     519        uint32_t rid;
     520        struct dom_sid domainsid;
     521        NTSTATUS ret;
     522
     523        ZERO_STRUCT(range);
     524        map->status = ID_UNKNOWN;
     525
     526        DEBUG(10, ("Trying to map %s\n", sid_string_dbg(map->sid)));
     527
     528        sid_copy(&domainsid, map->sid);
     529        if (!sid_split_rid(&domainsid, &rid)) {
     530                DEBUG(4, ("Could not determine domain SID from %s, "
     531                          "ignoring mapping request\n",
     532                          sid_string_dbg(map->sid)));
     533                map->status = ID_UNMAPPED;
     534                return NT_STATUS_NONE_MAPPED;
     535        }
     536
     537        if (idmap_autorid_domsid_is_for_alloc(&domainsid)) {
     538                DEBUG(10, ("SID %s is for ALLOC range.\n",
     539                           sid_string_dbg(map->sid)));
     540
     541                return idmap_autorid_sid_to_id_alloc(common, dom, map);
     542        }
     543
     544        if (dom_sid_equal(&domainsid, &global_sid_Builtin) && ignore_builtin) {
     545                DEBUG(10, ("Ignoring request for BUILTIN domain\n"));
     546                map->status = ID_UNMAPPED;
     547                return NT_STATUS_NONE_MAPPED;
     548        }
     549
     550        /*
     551         * Check if the domain is around
     552         */
     553        domain = wcache_tdc_fetch_domainbysid(talloc_tos(),
     554                                              &domainsid);
     555        if (domain == NULL) {
     556                DEBUG(10, ("Ignoring unknown domain sid %s\n",
     557                           sid_string_dbg(&domainsid)));
     558                map->status = ID_UNMAPPED;
     559                return NT_STATUS_NONE_MAPPED;
     560        }
     561        TALLOC_FREE(domain);
     562
     563        sid_to_fstring(range.domsid, &domainsid);
     564
     565        range.domain_range_index = rid / (global->rangesize);
     566
     567        ret = idmap_autorid_get_domainrange(autorid_db, &range, dom->read_only);
     568        if (NT_STATUS_EQUAL(ret, NT_STATUS_NOT_FOUND) && dom->read_only) {
     569                DEBUG(10, ("read-only is enabled, did not allocate "
     570                           "new range for domain %s\n",
     571                           sid_string_dbg(&domainsid)));
     572                map->status = ID_UNMAPPED;
     573                return NT_STATUS_NONE_MAPPED;
     574        }
     575        if (!NT_STATUS_IS_OK(ret)) {
     576                DEBUG(3, ("Could not determine range for domain, "
     577                          "check previous messages for reason\n"));
     578                return ret;
     579        }
     580
     581        return idmap_autorid_sid_to_id_rid(global, &range, map);
    265582}
    266583
     
    272589                                              struct id_map **ids)
    273590{
    274         struct autorid_global_config *global;
     591        struct idmap_tdb_common_context *commoncfg;
    275592        NTSTATUS ret;
    276593        int i;
     594        int num_tomap = 0;
     595        int num_mapped = 0;
    277596
    278597        /* initialize the status to avoid surprise */
    279598        for (i = 0; ids[i]; i++) {
    280599                ids[i]->status = ID_UNKNOWN;
    281         }
    282 
    283         global = talloc_get_type(dom->private_data,
    284                                  struct autorid_global_config);
     600                num_tomap++;
     601        }
     602
     603        commoncfg =
     604            talloc_get_type_abort(dom->private_data,
     605                                  struct idmap_tdb_common_context);
    285606
    286607        for (i = 0; ids[i]; i++) {
    287                 struct winbindd_tdc_domain *domain;
    288                 struct autorid_domain_config domaincfg;
    289                 uint32_t rid;
    290                 struct dom_sid domainsid;
    291 
    292                 ZERO_STRUCT(domaincfg);
    293 
    294                 sid_copy(&domainsid, ids[i]->sid);
    295                 if (!sid_split_rid(&domainsid, &rid)) {
    296                         DEBUG(4, ("Could not determine domain SID from %s, "
    297                                   "ignoring mapping request\n",
    298                                   sid_string_dbg(ids[i]->sid)));
    299                         continue;
    300                 }
    301 
    302                 /*
    303                  * Check if the domain is around
    304                  */
    305                 domain = wcache_tdc_fetch_domainbysid(talloc_tos(),
    306                                                       &domainsid);
    307                 if (domain == NULL) {
    308                         DEBUG(10, ("Ignoring unknown domain sid %s\n",
    309                                    sid_string_dbg(&domainsid)));
    310                         continue;
    311                 }
    312                 TALLOC_FREE(domain);
    313 
    314                 domaincfg.globalcfg = global;
    315                 sid_to_fstring(domaincfg.sid, &domainsid);
    316 
    317                 ret = dbwrap_trans_do(autorid_db,
    318                                       idmap_autorid_get_domainrange,
    319                                       &domaincfg);
    320 
    321                 if (!NT_STATUS_IS_OK(ret)) {
    322                         DEBUG(3, ("Could not determine range for domain, "
    323                                   "check previous messages for reason\n"));
    324                         goto failure;
    325                 }
    326 
    327                 ret = idmap_autorid_sid_to_id(global, &domaincfg, ids[i]);
    328 
     608                ret = idmap_autorid_sid_to_id(commoncfg, dom, ids[i]);
    329609                if ((!NT_STATUS_IS_OK(ret)) &&
    330610                    (!NT_STATUS_EQUAL(ret, NT_STATUS_NONE_MAPPED))) {
     
    332612                        DEBUG(3, ("Unexpected error resolving a SID (%s)\n",
    333613                                  sid_string_dbg(ids[i]->sid)));
    334                         goto failure;
    335                 }
    336         }
     614                        return ret;
     615                }
     616
     617                if (NT_STATUS_IS_OK(ret) && ids[i]->status == ID_MAPPED) {
     618                        num_mapped++;
     619                }
     620        }
     621
     622        if (num_tomap == num_mapped) {
     623                return NT_STATUS_OK;
     624        } else if (num_mapped == 0) {
     625                return NT_STATUS_NONE_MAPPED;
     626        }
     627
     628        return STATUS_SOME_UNMAPPED;
     629}
     630
     631static NTSTATUS idmap_autorid_preallocate_wellknown(struct idmap_domain *dom)
     632{
     633        const char *groups[] = { "S-1-1-0", "S-1-2-0", "S-1-2-1",
     634                "S-1-3-0", "S-1-3-1", "S-1-3-2", "S-1-3-3", "S-1-3-4",
     635                "S-1-5-1", "S-1-5-2", "S-1-5-3", "S-1-5-4", "S-1-5-6",
     636                "S-1-5-7", "S-1-5-8", "S-1-5-9", "S-1-5-10", "S-1-5-11",
     637                "S-1-5-12", "S-1-5-13", "S-1-5-14", "S-1-5-15",
     638                "S-1-5-17", "S-1-5-18", "S-1-5-19", "S-1-5-20"
     639        };
     640
     641        struct id_map **maps;
     642        int i, num;
     643        NTSTATUS status;
     644
     645        if (dom->read_only) {
     646                return NT_STATUS_OK;
     647        }
     648
     649        num = ARRAY_SIZE(groups);
     650
     651        maps = talloc_array(talloc_tos(), struct id_map*, num+1);
     652        if (!maps) {
     653                return NT_STATUS_NO_MEMORY;
     654        }
     655
     656        for (i = 0; i < num; i++) {
     657                maps[i] = talloc(maps, struct id_map);
     658                if (maps[i] == NULL) {
     659                        talloc_free(maps);
     660                        return NT_STATUS_NO_MEMORY;
     661                }
     662                maps[i]->xid.type = ID_TYPE_GID;
     663                maps[i]->sid = dom_sid_parse_talloc(maps, groups[i]);
     664        }
     665
     666        maps[num] = NULL;
     667
     668        status = idmap_autorid_sids_to_unixids(dom, maps);
     669
     670        DEBUG(10,("Preallocation run finished with status %s\n",
     671                  nt_errstr(status)));
     672
     673        talloc_free(maps);
     674
     675        return NT_STATUS_IS_OK(status)?NT_STATUS_OK:NT_STATUS_UNSUCCESSFUL;
     676}
     677
     678static NTSTATUS idmap_autorid_initialize_action(struct db_context *db,
     679                                                void *private_data)
     680{
     681        struct idmap_domain *dom;
     682        struct idmap_tdb_common_context *common;
     683        struct autorid_global_config *config;
     684        NTSTATUS status;
     685
     686        dom = (struct idmap_domain *)private_data;
     687        common = (struct idmap_tdb_common_context *)dom->private_data;
     688        config = (struct autorid_global_config *)common->private_data;
     689
     690        status = idmap_autorid_init_hwms(db);
     691        if (!NT_STATUS_IS_OK(status)) {
     692                return status;
     693        }
     694
     695        status = idmap_autorid_saveconfig(db, config);
     696        if (!NT_STATUS_IS_OK(status)) {
     697                DEBUG(1, ("Failed to store configuration data!\n"));
     698                return status;
     699        }
     700
     701        status = idmap_autorid_preallocate_wellknown(dom);
     702        if (!NT_STATUS_IS_OK(status)) {
     703                DEBUG(1, ("Failed to preallocate wellknown sids: %s\n",
     704                          nt_errstr(status)));
     705                return status;
     706        }
     707
    337708        return NT_STATUS_OK;
    338 
    339       failure:
    340         return ret;
    341 
    342 }
    343 
    344 /* initialize the given HWM to 0 if it does not exist yet */
    345 static NTSTATUS idmap_autorid_init_hwm(const char *hwm) {
    346 
     709}
     710
     711static NTSTATUS idmap_autorid_initialize(struct idmap_domain *dom)
     712{
     713        struct idmap_tdb_common_context *commonconfig;
     714        struct autorid_global_config *config;
    347715        NTSTATUS status;
    348         int32_t hwmval;
    349 
    350         hwmval = dbwrap_fetch_int32(autorid_db, hwm);
    351         if ((hwmval < 0))  {
    352                 status = dbwrap_trans_store_int32(autorid_db, hwm, 0);
    353                 if (!NT_STATUS_IS_OK(status)) {
    354                         DEBUG(0,
    355                               ("Unable to initialise HWM (%s) in autorid "
    356                                "database: %s\n", hwm, nt_errstr(status)));
    357                         return NT_STATUS_INTERNAL_DB_ERROR;
    358                 }
    359         }
    360 
    361         return NT_STATUS_OK;
    362 }
    363 
    364 /*
    365  * open and initialize the database which stores the ranges for the domains
    366  */
    367 static NTSTATUS idmap_autorid_db_init(void)
    368 {
    369         NTSTATUS status;
    370 
    371         if (autorid_db) {
    372                 /* its already open */
    373                 return NT_STATUS_OK;
    374         }
    375 
    376         /* Open idmap repository */
    377         autorid_db = db_open(NULL, state_path("autorid.tdb"), 0,
    378                              TDB_DEFAULT, O_RDWR | O_CREAT, 0644);
    379 
    380         if (!autorid_db) {
    381                 DEBUG(0, ("Unable to open idmap_autorid database '%s'\n",
    382                           state_path("autorid.tdb")));
    383                 return NT_STATUS_UNSUCCESSFUL;
    384         }
    385 
    386         /* Initialize high water mark for the currently used range to 0 */
    387 
    388         status = idmap_autorid_init_hwm(HWM);
    389         NT_STATUS_NOT_OK_RETURN(status);
    390 
    391         status = idmap_autorid_init_hwm(ALLOC_HWM_UID);
    392         NT_STATUS_NOT_OK_RETURN(status);
    393 
    394         status = idmap_autorid_init_hwm(ALLOC_HWM_GID);
    395 
    396         return status;
    397 }
    398 
    399 static struct autorid_global_config *idmap_autorid_loadconfig(TALLOC_CTX * ctx)
    400 {
    401 
    402         TDB_DATA data;
    403         struct autorid_global_config *cfg;
    404         unsigned long minvalue, rangesize, maxranges;
    405 
    406         data = dbwrap_fetch_bystring(autorid_db, ctx, CONFIGKEY);
    407 
    408         if (!data.dptr) {
    409                 DEBUG(10, ("No saved config found\n"));
    410                 return NULL;
    411         }
    412 
    413         cfg = TALLOC_ZERO_P(ctx, struct autorid_global_config);
    414         if (!cfg) {
    415                 return NULL;
    416         }
    417 
    418         if (sscanf((char *)data.dptr,
    419                    "minvalue:%lu rangesize:%lu maxranges:%lu",
    420                    &minvalue, &rangesize, &maxranges) != 3) {
    421                 DEBUG(1,
    422                       ("Found invalid configuration data"
    423                        "creating new config\n"));
    424                 return NULL;
    425         }
    426 
    427         cfg->minvalue = minvalue;
    428         cfg->rangesize = rangesize;
    429         cfg->maxranges = maxranges;
    430 
    431         DEBUG(10, ("Loaded previously stored configuration "
    432                    "minvalue:%d rangesize:%d\n",
    433                    cfg->minvalue, cfg->rangesize));
    434 
    435         return cfg;
    436 
    437 }
    438 
    439 static NTSTATUS idmap_autorid_saveconfig(struct autorid_global_config *cfg)
    440 {
    441 
    442         NTSTATUS status;
    443         TDB_DATA data;
    444         char *cfgstr;
    445 
    446         cfgstr =
    447             talloc_asprintf(talloc_tos(),
    448                             "minvalue:%u rangesize:%u maxranges:%u",
    449                             cfg->minvalue, cfg->rangesize, cfg->maxranges);
    450 
    451         if (!cfgstr) {
    452                 return NT_STATUS_NO_MEMORY;
    453         }
    454 
    455         data = string_tdb_data(cfgstr);
    456 
    457         status = dbwrap_trans_store_bystring(autorid_db, CONFIGKEY,
    458                                              data, TDB_REPLACE);
    459 
    460         talloc_free(cfgstr);
    461 
    462         return status;
    463 }
    464 
    465 static NTSTATUS idmap_autorid_initialize(struct idmap_domain *dom)
    466 {
    467         struct autorid_global_config *config;
    468         struct autorid_global_config *storedconfig = NULL;
    469         NTSTATUS status;
    470         uint32_t hwm;
     716        char *db_path;
    471717
    472718        if (!strequal(dom->name, "*")) {
     
    477723        }
    478724
    479         config = TALLOC_ZERO_P(dom, struct autorid_global_config);
     725        commonconfig = talloc_zero(dom, struct idmap_tdb_common_context);
     726        if (!commonconfig) {
     727                DEBUG(0, ("Out of memory!\n"));
     728                return NT_STATUS_NO_MEMORY;
     729        }
     730        dom->private_data = commonconfig;
     731
     732        commonconfig->rw_ops = talloc_zero(commonconfig, struct idmap_rw_ops);
     733        if (commonconfig->rw_ops == NULL) {
     734                DEBUG(0, ("Out of memory!\n"));
     735                return NT_STATUS_NO_MEMORY;
     736        }
     737
     738        config = talloc_zero(commonconfig, struct autorid_global_config);
    480739        if (!config) {
    481740                DEBUG(0, ("Out of memory!\n"));
    482741                return NT_STATUS_NO_MEMORY;
    483742        }
    484 
    485         status = idmap_autorid_db_init();
    486         if (!NT_STATUS_IS_OK(status)) {
    487                 goto error;
    488         }
     743        commonconfig->private_data = config;
    489744
    490745        config->minvalue = dom->low_id;
    491         config->rangesize = lp_parm_int(-1, "idmap config *", "rangesize", 100000);
    492 
    493         if (config->rangesize < 2000) {
    494                 DEBUG(1, ("autorid rangesize must be at least 2000\n"));
    495                 status = NT_STATUS_INVALID_PARAMETER;
    496                 goto error;
    497         }
     746        config->rangesize = lp_parm_int(-1, "idmap config *",
     747                                        "rangesize", 100000);
    498748
    499749        config->maxranges = (dom->high_id - dom->low_id + 1) /
     
    501751
    502752        if (config->maxranges == 0) {
    503                 DEBUG(1, ("allowed uid range is smaller then rangesize, "
    504                           "increase uid range or decrease rangesize\n"));
     753                DEBUG(1, ("Allowed uid range is smaller than rangesize. "
     754                          "Increase uid range or decrease rangesize.\n"));
    505755                status = NT_STATUS_INVALID_PARAMETER;
    506756                goto error;
     
    516766        }
    517767
    518         DEBUG(10, ("Current configuration in config is "
    519                    "minvalue:%d rangesize:%d maxranges:%d\n",
    520                    config->minvalue, config->rangesize, config->maxranges));
    521 
    522         /* read previously stored config and current HWM */
    523         storedconfig = idmap_autorid_loadconfig(talloc_tos());
    524 
    525         if (!dbwrap_fetch_uint32(autorid_db, HWM, &hwm)) {
    526                 DEBUG(1, ("Fatal error while fetching current "
    527                           "HWM value!\n"));
    528                 status = NT_STATUS_INTERNAL_ERROR;
    529                 goto error;
    530         }
    531 
    532         /* did the minimum value or rangesize change? */
    533         if (storedconfig &&
    534             ((storedconfig->minvalue != config->minvalue) ||
    535              (storedconfig->rangesize != config->rangesize))) {
    536                 DEBUG(1, ("New configuration values for rangesize or "
    537                           "minimum uid value conflict with previously "
    538                           "used values! Aborting initialization\n"));
    539                 status = NT_STATUS_INVALID_PARAMETER;
    540                 goto error;
    541         }
    542 
    543         /*
    544          * has the highest uid value been reduced to setting that is not
    545          * sufficient any more for already existing ranges?
    546          */
    547         if (hwm > config->maxranges) {
    548                 DEBUG(1, ("New upper uid limit is too low to cover "
    549                           "existing mappings! Aborting initialization\n"));
    550                 status = NT_STATUS_INVALID_PARAMETER;
    551                 goto error;
    552         }
    553 
    554         status = idmap_autorid_saveconfig(config);
    555 
    556         if (!NT_STATUS_IS_OK(status)) {
    557                 DEBUG(1, ("Failed to store configuration data!\n"));
    558                 goto error;
    559         }
    560 
    561768        DEBUG(5, ("%d domain ranges with a size of %d are available\n",
    562769                  config->maxranges, config->rangesize));
    563770
    564         dom->private_data = config;
     771        ignore_builtin = lp_parm_bool(-1, "idmap config *",
     772                                      "ignore builtin", false);
     773
     774        /* fill the TDB common configuration */
     775
     776        commonconfig->max_id = config->rangesize - 1
     777                             - IDMAP_AUTORID_ALLOC_RESERVED;
     778        commonconfig->hwmkey_uid = ALLOC_HWM_UID;
     779        commonconfig->hwmkey_gid = ALLOC_HWM_GID;
     780        commonconfig->rw_ops->get_new_id = idmap_autorid_allocate_id;
     781        commonconfig->rw_ops->set_mapping = idmap_tdb_common_set_mapping;
     782
     783        db_path = state_path("autorid.tdb");
     784        if (db_path == NULL) {
     785                status = NT_STATUS_NO_MEMORY;
     786                goto error;
     787        }
     788
     789        status = idmap_autorid_db_open(db_path,
     790                                       NULL, /* TALLOC_CTX */
     791                                       &autorid_db);
     792        TALLOC_FREE(db_path);
     793        if (!NT_STATUS_IS_OK(status)) {
     794                goto error;
     795        }
     796
     797        commonconfig->db = autorid_db;
     798
     799        status = dbwrap_trans_do(autorid_db,
     800                                 idmap_autorid_initialize_action,
     801                                 dom);
     802        if (!NT_STATUS_IS_OK(status)) {
     803                DEBUG(1, ("Failed to init the idmap database: %s\n",
     804                          nt_errstr(status)));
     805                goto error;
     806        }
    565807
    566808        goto done;
     
    570812
    571813done:
    572         talloc_free(storedconfig);
    573 
    574814        return status;
    575 }
    576 
    577 static NTSTATUS idmap_autorid_allocate_id(struct idmap_domain *dom,
    578                                           struct unixid *xid) {
    579 
    580         NTSTATUS ret;
    581         struct autorid_global_config *globalcfg;
    582         struct autorid_domain_config domaincfg;
    583         uint32_t hwm;
    584         const char *hwmkey;
    585 
    586         if (!strequal(dom->name, "*")) {
    587                 DEBUG(3, ("idmap_autorid_allocate_id: "
    588                           "Refusing creation of mapping for domain'%s'. "
    589                           "Currently only supported for the default "
    590                           "domain \"*\".\n",
    591                            dom->name));
    592                 return NT_STATUS_NOT_IMPLEMENTED;
    593         }
    594 
    595         if ((xid->type != ID_TYPE_UID) && (xid->type != ID_TYPE_GID)) {
    596                 return NT_STATUS_INVALID_PARAMETER;
    597         }
    598 
    599 
    600         globalcfg = talloc_get_type(dom->private_data,
    601                                     struct autorid_global_config);
    602 
    603         /* fetch the range for the allocation pool */
    604 
    605         ZERO_STRUCT(domaincfg);
    606 
    607         domaincfg.globalcfg = globalcfg;
    608         fstrcpy(domaincfg.sid, ALLOC_RANGE);
    609 
    610         ret = dbwrap_trans_do(autorid_db,
    611                               idmap_autorid_get_domainrange,
    612                               &domaincfg);
    613         if (!NT_STATUS_IS_OK(ret)) {
    614                 DEBUG(3, ("Could not determine range for allocation pool, "
    615                           "check previous messages for reason\n"));
    616                 return ret;
    617         }
    618 
    619         /* fetch the current HWM */
    620         hwmkey = (xid->type==ID_TYPE_UID)?ALLOC_HWM_UID:ALLOC_HWM_GID;
    621 
    622         if (!dbwrap_fetch_uint32(autorid_db, hwmkey, &hwm)) {
    623                 DEBUG(1, ("Failed to fetch current allocation HWM value: %s\n",
    624                           nt_errstr(ret)));
    625                 return NT_STATUS_INTERNAL_ERROR;
    626         }
    627 
    628         if (hwm >= globalcfg->rangesize) {
    629                 DEBUG(1, ("allocation range is depleted!\n"));
    630                 return NT_STATUS_NO_MEMORY;
    631         }
    632 
    633         ret = dbwrap_change_uint32_atomic(autorid_db, hwmkey, &(xid->id), 1);
    634         if (!NT_STATUS_IS_OK(ret)) {
    635                 DEBUG(1, ("Fatal error while allocating new ID!\n"));
    636                 return ret;
    637         }
    638 
    639         xid->id = globalcfg->minvalue +
    640                   globalcfg->rangesize * domaincfg.domainnum +
    641                   xid->id;
    642 
    643         DEBUG(10, ("Returned new %s %d from allocation range\n",
    644                    (xid->type==ID_TYPE_UID)?"uid":"gid", xid->id));
    645 
    646         return ret;
    647815}
    648816
     
    657825};
    658826
     827static_decl_idmap;
    659828NTSTATUS idmap_autorid_init(void)
    660829{
  • vendor/current/source3/winbindd/idmap_hash/idmap_hash.c

    r746 r988  
    105105 ********************************************************************/
    106106
    107 static NTSTATUS be_init(struct idmap_domain *dom)
     107static NTSTATUS idmap_hash_initialize(struct idmap_domain *dom)
    108108{
    109109        struct sid_hash_table *hashed_domains;
     
    113113        int i;
    114114
     115        if (!strequal(dom->name, "*")) {
     116                DBG_ERR("Error: idmap_hash configured for domain '%s'. "
     117                        "But the hash module can only be used for the default "
     118                        "idmap configuration.\n", dom->name);
     119                return NT_STATUS_INVALID_PARAMETER;
     120        }
     121
    115122        /* If the domain SID hash table has been initialized, assume
    116123           that we completed this function previously */
     
    128135        /* Create the hash table of domain SIDs */
    129136
    130         hashed_domains = TALLOC_ZERO_ARRAY(dom, struct sid_hash_table, 4096);
     137        hashed_domains = talloc_zero_array(dom, struct sid_hash_table, 4096);
    131138        BAIL_ON_PTR_NT_ERROR(hashed_domains, nt_status);
    132139
     
    138145                if (is_null_sid(&dom_list[i].sid))
    139146                        continue;
     147
     148                /*
     149                 * Check if the domain from the list is not already configured
     150                 * to use another idmap backend. Not checking this makes the
     151                 * idmap_hash module map IDs for *all* domains implicitly.  This
     152                 * is quite dangerous in setups that use multiple idmap
     153                 * configurations.
     154                 */
     155
     156                if (domain_has_idmap_config(dom_list[i].domain_name)) {
     157                        continue;
     158                }
     159
    140160                if ((hash = hash_domain_sid(&dom_list[i].sid)) == 0)
    141161                        continue;
    142162
    143                 DEBUG(5,("hash:be_init() Adding %s (%s) -> %d\n",
     163                DBG_INFO("Adding %s (%s) -> %d\n",
    144164                         dom_list[i].domain_name,
    145165                         sid_string_dbg(&dom_list[i].sid),
    146                          hash));
     166                         hash);
    147167
    148168                hashed_domains[hash].sid = talloc(hashed_domains, struct dom_sid);
     
    167187        int i;
    168188
     189        if (!ids) {
     190                nt_status = NT_STATUS_INVALID_PARAMETER;
     191                BAIL_ON_NTSTATUS_ERROR(nt_status);
     192        }
     193
    169194        /* initialize the status to avoid suprise */
    170195        for (i = 0; ids[i]; i++) {
     
    172197        }
    173198
    174         nt_status = be_init(dom);
     199        nt_status = idmap_hash_initialize(dom);
    175200        BAIL_ON_NTSTATUS_ERROR(nt_status);
    176 
    177         if (!ids) {
    178                 nt_status = NT_STATUS_INVALID_PARAMETER;
    179                 BAIL_ON_NTSTATUS_ERROR(nt_status);
    180         }
    181201
    182202        for (i=0; ids[i]; i++) {
     
    217237        int i;
    218238
     239        if (!ids) {
     240                nt_status = NT_STATUS_INVALID_PARAMETER;
     241                BAIL_ON_NTSTATUS_ERROR(nt_status);
     242        }
     243
    219244        /* initialize the status to avoid suprise */
    220245        for (i = 0; ids[i]; i++) {
     
    222247        }
    223248
    224         nt_status = be_init(dom);
     249        nt_status = idmap_hash_initialize(dom);
    225250        BAIL_ON_NTSTATUS_ERROR(nt_status);
    226 
    227         if (!ids) {
    228                 nt_status = NT_STATUS_INVALID_PARAMETER;
    229                 BAIL_ON_NTSTATUS_ERROR(nt_status);
    230         }
    231251
    232252        for (i=0; ids[i]; i++) {
     
    348368
    349369static struct idmap_methods hash_idmap_methods = {
    350         .init            = be_init,
     370        .init            = idmap_hash_initialize,
    351371        .unixids_to_sids = unixids_to_sids,
    352372        .sids_to_unixids = sids_to_unixids,
     
    367387 **********************************************************************/
    368388
     389static_decl_idmap;
    369390NTSTATUS idmap_hash_init(void)
    370391{
  • vendor/current/source3/winbindd/idmap_hash/mapfile.c

    r740 r988  
    6868                return false;
    6969
    70         if ((p = x_fgets(buffer, sizeof(buffer)-1, lw_map_file)) == NULL) {
     70        p = x_fgets(buffer, sizeof(buffer)-1, lw_map_file);
     71        if (p == NULL) {
    7172                return false;
    7273        }
     
    7475        /* Strip newlines and carriage returns */
    7576
    76         len = strlen_m(buffer) - 1;
     77        len = strlen_m(buffer);
     78        if (len == 0) {
     79                return false;
     80        }
     81        len -= 1;
     82
    7783        while ((buffer[len] == '\n') || (buffer[len] == '\r')) {
    7884                buffer[len--] = '\0';
     
    8894        p++;
    8995
    90         fstrcpy(key, buffer);
    91         fstrcpy(value, p);
     96        strlcpy(key, buffer, sizeof(fstring));
     97        strlcpy(value, p, sizeof(fstring));
    9298
    9399        /* Eat whitespace */
  • vendor/current/source3/winbindd/idmap_ldap.c

    r740 r988  
    3838
    3939#include "smbldap.h"
    40 
    41 static char *idmap_fetch_secret(const char *backend,
    42                                 const char *domain, const char *identity)
    43 {
    44         char *tmp, *ret;
    45         int r;
    46 
    47         r = asprintf(&tmp, "IDMAP_%s_%s", backend, domain);
    48 
    49         if (r < 0)
    50                 return NULL;
    51 
    52         strupper_m(tmp); /* make sure the key is case insensitive */
    53         ret = secrets_fetch_generic(tmp, identity);
    54 
    55         SAFE_FREE(tmp);
    56 
    57         return ret;
    58 }
     40#include "passdb/pdb_ldap_schema.h"
    5941
    6042struct idmap_ldap_context {
     
    300282        }
    301283
    302         talloc_autofree_ldapmsg(mem_ctx, result);
     284        smbldap_talloc_autofree_ldapmsg(mem_ctx, result);
    303285
    304286        count = ldap_count_entries(ctx->smbldap_state->ldap_struct, result);
     
    444426        }
    445427
    446         ctx = TALLOC_ZERO_P(dom, struct idmap_ldap_context);
     428        ctx = talloc_zero(dom, struct idmap_ldap_context);
    447429        if ( ! ctx) {
    448430                DEBUG(0, ("Out of memory!\n"));
     
    471453        tmp = lp_parm_const_string(-1, config_option, "ldap_base_dn", NULL);
    472454        if ( ! tmp || ! *tmp) {
    473                 tmp = lp_ldap_idmap_suffix();
     455                tmp = lp_ldap_idmap_suffix(talloc_tos());
    474456                if ( ! tmp) {
    475457                        DEBUG(1, ("ERROR: missing idmap ldap suffix\n"));
     
    488470        ctx->rw_ops->set_mapping = idmap_ldap_set_mapping;
    489471
     472        /* get_credentials deals with setting up creds */
     473
    490474        ret = smbldap_init(ctx, winbind_event_context(), ctx->url,
    491                            &ctx->smbldap_state);
     475                           false, NULL, NULL, &ctx->smbldap_state);
    492476        if (!NT_STATUS_IS_OK(ret)) {
    493477                DEBUG(1, ("ERROR: smbldap_init (%s) failed!\n", ctx->url));
     
    656640}
    657641
    658 
    659 /* max number of ids requested per batch query */
    660 #define IDMAP_LDAP_MAX_IDS 30
    661 
    662642/**********************************
    663643 lookup a set of unix ids.
    664644**********************************/
    665 
    666 /* this function searches up to IDMAP_LDAP_MAX_IDS entries
    667  * in maps for a match */
    668 static struct id_map *find_map_by_id(struct id_map **maps,
    669                                      enum id_type type,
    670                                      uint32_t id)
    671 {
    672         int i;
    673 
    674         for (i = 0; i < IDMAP_LDAP_MAX_IDS; i++) {
    675                 if (maps[i] == NULL) { /* end of the run */
    676                         return NULL;
    677                 }
    678                 if ((maps[i]->xid.type == type) && (maps[i]->xid.id == id)) {
    679                         return maps[i];
    680                 }
    681         }
    682 
    683         return NULL;
    684 }
    685645
    686646static NTSTATUS idmap_ldap_unixids_to_sids(struct idmap_domain *dom,
     
    839799                TALLOC_FREE(tmp);
    840800
    841                 map = find_map_by_id(&ids[bidx], type, id);
     801                map = idmap_find_map_by_id(&ids[bidx], type, id);
    842802                if (!map) {
    843803                        DEBUG(2, ("WARNING: couldn't match sid (%s) "
     
    895855 lookup a set of sids.
    896856**********************************/
    897 
    898 /* this function searches up to IDMAP_LDAP_MAX_IDS entries
    899  * in maps for a match */
    900 static struct id_map *find_map_by_sid(struct id_map **maps, struct dom_sid *sid)
    901 {
    902         int i;
    903 
    904         for (i = 0; i < IDMAP_LDAP_MAX_IDS; i++) {
    905                 if (maps[i] == NULL) { /* end of the run */
    906                         return NULL;
    907                 }
    908                 if (dom_sid_equal(maps[i]->sid, sid)) {
    909                         return maps[i];
    910                 }
    911         }
    912 
    913         return NULL;
    914 }
    915857
    916858static NTSTATUS idmap_ldap_sids_to_unixids(struct idmap_domain *dom,
     
    1046988                }
    1047989
    1048                 map = find_map_by_sid(&ids[bidx], &sid);
     990                map = idmap_find_map_by_sid(&ids[bidx], &sid);
    1049991                if (!map) {
    1050992                        DEBUG(2, ("WARNING: couldn't find entry sid (%s) "
  • vendor/current/source3/winbindd/idmap_nss.c

    r740 r988  
    3131
    3232/*****************************
    33  Initialise idmap database. 
     33 Initialise idmap database.
    3434*****************************/
    3535
    3636static NTSTATUS idmap_nss_int_init(struct idmap_domain *dom)
    37 {       
     37{
    3838        return NT_STATUS_OK;
    3939}
    4040
    4141/**********************************
    42  lookup a set of unix ids. 
     42 lookup a set of unix ids.
    4343**********************************/
    4444
     
    121121
    122122/**********************************
    123  lookup a set of sids. 
     123 lookup a set of sids.
    124124**********************************/
    125125
     
    136136                struct group *gr;
    137137                enum lsa_SidType type;
     138                const char *p = NULL;
    138139                char *name = NULL;
    139140                bool ret;
     
    143144                (void)winbind_on();
    144145                ret = winbind_lookup_sid(talloc_tos(), ids[i]->sid, NULL,
    145                                          (const char **)&name, &type);
     146                                         &p, &type);
    146147                (void)winbind_off();
     148                name = discard_const_p(char, p);
    147149
    148150                if (!ret) {
  • vendor/current/source3/winbindd/idmap_passdb.c

    r740 r988  
    4545
    4646        for (i = 0; ids[i]; i++) {
    47 
    4847                /* unmapped by default */
    4948                ids[i]->status = ID_UNMAPPED;
    5049
    51                 switch (ids[i]->xid.type) {
    52                 case ID_TYPE_UID:
    53                         if (pdb_uid_to_sid((uid_t)ids[i]->xid.id, ids[i]->sid)) {
    54                                 ids[i]->status = ID_MAPPED;
    55                         }
    56                         break;
    57                 case ID_TYPE_GID:
    58                         if (pdb_gid_to_sid((gid_t)ids[i]->xid.id, ids[i]->sid)) {
    59                                 ids[i]->status = ID_MAPPED;
    60                         }
    61                         break;
    62                 default: /* ?? */
    63                         ids[i]->status = ID_UNKNOWN;
     50                if (pdb_id_to_sid(&ids[i]->xid, ids[i]->sid)) {
     51                        ids[i]->status = ID_MAPPED;
    6452                }
    6553        }
     
    7765
    7866        for (i = 0; ids[i]; i++) {
    79                 enum lsa_SidType type;
    80                 union unid_t id;
    81 
    82                 if (pdb_sid_to_id(ids[i]->sid, &id, &type)) {
    83                         switch (type) {
    84                         case SID_NAME_USER:
    85                                 ids[i]->xid.id = id.uid;
    86                                 ids[i]->xid.type = ID_TYPE_UID;
    87                                 ids[i]->status = ID_MAPPED;
    88                                 break;
    89 
    90                         case SID_NAME_DOM_GRP:
    91                         case SID_NAME_ALIAS:
    92                         case SID_NAME_WKN_GRP:
    93                                 ids[i]->xid.id = id.gid;
    94                                 ids[i]->xid.type = ID_TYPE_GID;
    95                                 ids[i]->status = ID_MAPPED;
    96                                 break;
    97 
    98                         default: /* ?? */
    99                                 /* make sure it is marked as unmapped */
    100                                 ids[i]->status = ID_UNKNOWN;
    101                                 break;
    102                         }
     67                if (pdb_sid_to_id(ids[i]->sid, &ids[i]->xid)) {
     68                        ids[i]->status = ID_MAPPED;
    10369                } else {
    10470                        /* Query Failed */
  • vendor/current/source3/winbindd/idmap_proto.h

    r740 r988  
    3535NTSTATUS idmap_allocate_uid(struct unixid *id);
    3636NTSTATUS idmap_allocate_gid(struct unixid *id);
    37 NTSTATUS idmap_backends_unixid_to_sid(const char *domname,
    38                                       struct id_map *id);
    39 NTSTATUS idmap_backends_sid_to_unixid(const char *domname,
    40                                       struct id_map *id);
     37NTSTATUS idmap_backends_unixid_to_sid(struct id_map *id);
    4138
    4239/* The following definitions come from winbindd/idmap_nss.c  */
     
    5451/* The following definitions come from winbindd/idmap_util.c  */
    5552
    56 NTSTATUS idmap_uid_to_sid(const char *domname, struct dom_sid *sid, uid_t uid);
    57 NTSTATUS idmap_gid_to_sid(const char *domname, struct dom_sid *sid, gid_t gid);
    58 NTSTATUS idmap_sid_to_uid(const char *dom_name, struct dom_sid *sid, uid_t *uid);
    59 NTSTATUS idmap_sid_to_gid(const char *domname, struct dom_sid *sid, gid_t *gid);
     53NTSTATUS idmap_uid_to_sid(struct dom_sid *sid, uid_t uid);
     54NTSTATUS idmap_gid_to_sid(struct dom_sid *sid, gid_t gid);
    6055bool idmap_unix_id_is_in_range(uint32_t id, struct idmap_domain *dom);
     56struct id_map *idmap_find_map_by_id(struct id_map **maps, enum id_type type,
     57                                    uint32_t id);
     58struct id_map *idmap_find_map_by_sid(struct id_map **maps, struct dom_sid *sid);
     59char *idmap_fetch_secret(const char *backend, const char *domain,
     60                         const char *identity);
     61
     62/* max number of ids requested per LDAP batch query */
     63#define IDMAP_LDAP_MAX_IDS 30
    6164
    6265#endif /* _WINBINDD_IDMAP_PROTO_H_ */
  • vendor/current/source3/winbindd/idmap_rid.c

    r740 r988  
    4242        char *config_option = NULL;
    4343
    44         ctx = TALLOC_ZERO_P(dom, struct idmap_rid_context);
     44        ctx = talloc_zero(dom, struct idmap_rid_context);
    4545        if (ctx == NULL) {
    4646                DEBUG(0, ("Out of memory!\n"));
     
    8888        sid_compose(map->sid, &domain->sid, map->xid.id - dom->low_id + ctx->base_rid);
    8989
    90         /* We **really** should have some way of validating
    91            the SID exists and is the correct type here.  But
    92            that is a deficiency in the idmap_rid design. */
    93 
    9490        map->status = ID_MAPPED;
     91        map->xid.type = ID_TYPE_BOTH;
    9592
    9693        return NT_STATUS_OK;
     
    9895
    9996/**********************************
    100  Single sid to id lookup function. 
     97 Single sid to id lookup function.
    10198**********************************/
    10299
     
    110107        sid_peek_rid(map->sid, &rid);
    111108        map->xid.id = rid - ctx->base_rid + dom->low_id;
     109        map->xid.type = ID_TYPE_BOTH;
    112110
    113111        /* apply filters before returning result */
     
    126124
    127125/**********************************
    128  lookup a set of unix ids. 
     126 lookup a set of unix ids.
    129127**********************************/
    130128
     
    154152
    155153/**********************************
    156  lookup a set of sids. 
     154 lookup a set of sids.
    157155**********************************/
    158156
     
    188186};
    189187
     188static_decl_idmap;
    190189NTSTATUS idmap_rid_init(void)
    191190{
  • vendor/current/source3/winbindd/idmap_tdb.c

    r740 r988  
    2929#include "idmap.h"
    3030#include "idmap_rw.h"
    31 #include "dbwrap.h"
     31#include "idmap_tdb_common.h"
     32#include "dbwrap/dbwrap.h"
     33#include "dbwrap/dbwrap_open.h"
    3234#include "../libcli/security/security.h"
    3335#include "util_tdb.h"
     
    4042
    4143#define IDMAP_VERSION 2
    42 
    43 struct idmap_tdb_context {
    44         struct db_context *db;
    45         struct idmap_rw_ops *rw_ops;
    46 };
    4744
    4845/* High water mark keys */
     
    6663        NTSTATUS status;
    6764        struct dom_sid sid;
    68         uint32 rid;
     65        uint32_t rid;
    6966        fstring keystr;
    7067        fstring dom_name;
     68        TDB_DATA key;
    7169        TDB_DATA key2;
     70        TDB_DATA value;
    7271        struct convert_fn_state *s = (struct convert_fn_state *)private_data;
    7372
    74         DEBUG(10,("Converting %s\n", (const char *)rec->key.dptr));
    75 
    76         p = strchr((const char *)rec->key.dptr, '/');
     73        key = dbwrap_record_get_key(rec);
     74
     75        DEBUG(10,("Converting %s\n", (const char *)key.dptr));
     76
     77        p = strchr((const char *)key.dptr, '/');
    7778        if (!p)
    7879                return 0;
    7980
    8081        *p = 0;
    81         fstrcpy(dom_name, (const char *)rec->key.dptr);
     82        fstrcpy(dom_name, (const char *)key.dptr);
    8283        *p++ = '/';
    8384
     
    8687                /* We must delete the old record. */
    8788                DEBUG(0,("Unable to find domain %s\n", dom_name ));
    88                 DEBUG(0,("deleting record %s\n", (const char *)rec->key.dptr ));
    89 
    90                 status = rec->delete_rec(rec);
     89                DEBUG(0,("deleting record %s\n", (const char *)key.dptr ));
     90
     91                status = dbwrap_record_delete(rec);
    9192                if (!NT_STATUS_IS_OK(status)) {
    9293                        DEBUG(0, ("Unable to delete record %s:%s\n",
    93                                 (const char *)rec->key.dptr,
     94                                (const char *)key.dptr,
    9495                                nt_errstr(status)));
    9596                        s->failed = true;
     
    107108        key2 = string_term_tdb_data(keystr);
    108109
    109         status = dbwrap_store(s->db, key2, rec->value, TDB_INSERT);
     110        value = dbwrap_record_get_value(rec);
     111
     112        status = dbwrap_store(s->db, key2, value, TDB_INSERT);
    110113        if (!NT_STATUS_IS_OK(status)) {
    111114                DEBUG(0,("Unable to add record %s:%s\n",
     
    116119        }
    117120
    118         status = dbwrap_store(s->db, rec->value, key2, TDB_REPLACE);
     121        status = dbwrap_store(s->db, value, key2, TDB_REPLACE);
    119122        if (!NT_STATUS_IS_OK(status)) {
    120123                DEBUG(0,("Unable to update record %s:%s\n",
    121                         (const char *)rec->value.dptr,
     124                        (const char *)value.dptr,
    122125                        nt_errstr(status)));
    123126                s->failed = true;
     
    125128        }
    126129
    127         status = rec->delete_rec(rec);
     130        status = dbwrap_record_delete(rec);
    128131        if (!NT_STATUS_IS_OK(status)) {
    129132                DEBUG(0,("Unable to delete record %s:%s\n",
    130                         (const char *)rec->key.dptr,
     133                        (const char *)key.dptr,
    131134                        nt_errstr(status)));
    132135                s->failed = true;
     
    143146static bool idmap_tdb_upgrade(struct idmap_domain *dom, struct db_context *db)
    144147{
    145         int32 vers;
    146         bool bigendianheader;
     148        int32_t vers;
    147149        struct convert_fn_state s;
    148 
    149         DEBUG(0, ("Upgrading winbindd_idmap.tdb from an old version\n"));
    150 
    151         bigendianheader = (db->get_flags(db) & TDB_BIGENDIAN) ? True : False;
    152 
    153         vers = dbwrap_fetch_int32(db, "IDMAP_VERSION");
    154 
    155         if (((vers == -1) && bigendianheader) || (IREV(vers) == IDMAP_VERSION)) {
    156                 /* Arrggghh ! Bytereversed or old big-endian - make order independent ! */
     150        NTSTATUS status;
     151
     152        status = dbwrap_fetch_int32_bystring(db, "IDMAP_VERSION", &vers);
     153        if (!NT_STATUS_IS_OK(status)) {
     154                vers = -1;
     155        }
     156
     157        if (IREV(vers) == IDMAP_VERSION) {
     158                /* Arrggghh ! Bytereversed - make order independent ! */
    157159                /*
    158160                 * high and low records were created on a
     
    160162                 */
    161163
    162                 int32 wm;
    163 
    164                 wm = dbwrap_fetch_int32(db, HWM_USER);
     164                int32_t wm;
     165
     166                status = dbwrap_fetch_int32_bystring(db, HWM_USER, &wm);
     167                if (!NT_STATUS_IS_OK(status)) {
     168                        wm = -1;
     169                }
    165170
    166171                if (wm != -1) {
     
    170175                }
    171176
    172                 if (dbwrap_store_int32(db, HWM_USER, wm) == -1) {
    173                         DEBUG(0, ("Unable to byteswap user hwm in idmap database\n"));
     177                status = dbwrap_store_int32_bystring(db, HWM_USER, wm);
     178                if (!NT_STATUS_IS_OK(status)) {
     179                        DEBUG(0, ("Unable to byteswap user hwm in idmap "
     180                                  "database: %s\n", nt_errstr(status)));
    174181                        return False;
    175182                }
    176183
    177                 wm = dbwrap_fetch_int32(db, HWM_GROUP);
     184                status = dbwrap_fetch_int32_bystring(db, HWM_GROUP, &wm);
     185                if (!NT_STATUS_IS_OK(status)) {
     186                        wm = -1;
     187                }
     188
    178189                if (wm != -1) {
    179190                        wm = IREV(wm);
     
    182193                }
    183194
    184                 if (dbwrap_store_int32(db, HWM_GROUP, wm) == -1) {
    185                         DEBUG(0, ("Unable to byteswap group hwm in idmap database\n"));
     195                status = dbwrap_store_int32_bystring(db, HWM_GROUP, wm);
     196                if (!NT_STATUS_IS_OK(status)) {
     197                        DEBUG(0, ("Unable to byteswap group hwm in idmap "
     198                                  "database: %s\n", nt_errstr(status)));
    186199                        return False;
    187200                }
     
    192205
    193206        /* the old format stored as DOMAIN/rid - now we store the SID direct */
    194         db->traverse(db, convert_fn, &s);
     207        status = dbwrap_traverse(db, convert_fn, &s, NULL);
     208
     209        if (!NT_STATUS_IS_OK(status)) {
     210                DEBUG(0, ("Database traverse failed during conversion\n"));
     211                return false;
     212        }
    195213
    196214        if (s.failed) {
     
    199217        }
    200218
    201         if (dbwrap_store_int32(db, "IDMAP_VERSION", IDMAP_VERSION) == -1) {
    202                 DEBUG(0, ("Unable to store idmap version in database\n"));
     219        status = dbwrap_store_int32_bystring(db, "IDMAP_VERSION",
     220                                             IDMAP_VERSION);
     221        if (!NT_STATUS_IS_OK(status)) {
     222                DEBUG(0, ("Unable to store idmap version in database: %s\n",
     223                          nt_errstr(status)));
    203224                return False;
    204225        }
     
    209230static NTSTATUS idmap_tdb_init_hwm(struct idmap_domain *dom)
    210231{
    211         int ret;
    212232        uint32_t low_uid;
    213233        uint32_t low_gid;
    214234        bool update_uid = false;
    215235        bool update_gid = false;
    216         struct idmap_tdb_context *ctx;
    217 
    218         ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context);
    219 
    220         low_uid = dbwrap_fetch_int32(ctx->db, HWM_USER);
    221         if (low_uid == -1 || low_uid < dom->low_id) {
     236        struct idmap_tdb_common_context *ctx;
     237        NTSTATUS status;
     238
     239        ctx = talloc_get_type(dom->private_data,
     240                              struct idmap_tdb_common_context);
     241
     242        status = dbwrap_fetch_uint32_bystring(ctx->db, HWM_USER, &low_uid);
     243        if (!NT_STATUS_IS_OK(status) || low_uid < dom->low_id) {
    222244                update_uid = true;
    223245        }
    224246
    225         low_gid = dbwrap_fetch_int32(ctx->db, HWM_GROUP);
    226         if (low_gid == -1 || low_gid < dom->low_id) {
     247        status = dbwrap_fetch_uint32_bystring(ctx->db, HWM_GROUP, &low_gid);
     248        if (!NT_STATUS_IS_OK(status) || low_gid < dom->low_id) {
    227249                update_gid = true;
    228250        }
     
    232254        }
    233255
    234         if (ctx->db->transaction_start(ctx->db) != 0) {
     256        if (dbwrap_transaction_start(ctx->db) != 0) {
    235257                DEBUG(0, ("Unable to start upgrade transaction!\n"));
    236258                return NT_STATUS_INTERNAL_DB_ERROR;
     
    238260
    239261        if (update_uid) {
    240                 ret = dbwrap_store_int32(ctx->db, HWM_USER, dom->low_id);
    241                 if (ret == -1) {
    242                         ctx->db->transaction_cancel(ctx->db);
     262                status = dbwrap_store_uint32_bystring(ctx->db, HWM_USER,
     263                                                      dom->low_id);
     264                if (!NT_STATUS_IS_OK(status)) {
     265                        dbwrap_transaction_cancel(ctx->db);
    243266                        DEBUG(0, ("Unable to initialise user hwm in idmap "
    244                                   "database\n"));
     267                                  "database: %s\n", nt_errstr(status)));
    245268                        return NT_STATUS_INTERNAL_DB_ERROR;
    246269                }
     
    248271
    249272        if (update_gid) {
    250                 ret = dbwrap_store_int32(ctx->db, HWM_GROUP, dom->low_id);
    251                 if (ret == -1) {
    252                         ctx->db->transaction_cancel(ctx->db);
     273                status = dbwrap_store_uint32_bystring(ctx->db, HWM_GROUP,
     274                                                      dom->low_id);
     275                if (!NT_STATUS_IS_OK(status)) {
     276                        dbwrap_transaction_cancel(ctx->db);
    253277                        DEBUG(0, ("Unable to initialise group hwm in idmap "
    254                                   "database\n"));
     278                                  "database: %s\n", nt_errstr(status)));
    255279                        return NT_STATUS_INTERNAL_DB_ERROR;
    256280                }
    257281        }
    258282
    259         if (ctx->db->transaction_commit(ctx->db) != 0) {
     283        if (dbwrap_transaction_commit(ctx->db) != 0) {
    260284                DEBUG(0, ("Unable to commit upgrade transaction!\n"));
    261285                return NT_STATUS_INTERNAL_DB_ERROR;
     
    273297        int32_t version;
    274298        bool config_error = false;
    275         struct idmap_tdb_context *ctx;
    276 
    277         ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context);
     299        struct idmap_tdb_common_context *ctx;
     300
     301        ctx = talloc_get_type(dom->private_data,
     302                              struct idmap_tdb_common_context);
    278303
    279304        if (ctx->db) {
     
    296321
    297322        /* Open idmap repository */
    298         db = db_open(mem_ctx, tdbfile, 0, TDB_DEFAULT, O_RDWR | O_CREAT, 0644);
     323        db = db_open(mem_ctx, tdbfile, 0, TDB_DEFAULT, O_RDWR | O_CREAT, 0644,
     324                     DBWRAP_LOCK_ORDER_1, DBWRAP_FLAG_NONE);
    299325        if (!db) {
    300326                DEBUG(0, ("Unable to open idmap database\n"));
     
    304330
    305331        /* check against earlier versions */
    306         version = dbwrap_fetch_int32(db, "IDMAP_VERSION");
     332        ret = dbwrap_fetch_int32_bystring(db, "IDMAP_VERSION", &version);
     333        if (!NT_STATUS_IS_OK(ret)) {
     334                version = -1;
     335        }
     336
    307337        if (version != IDMAP_VERSION) {
    308338                if (config_error) {
     
    313343                        goto done;
    314344                }
    315                 if (db->transaction_start(db) != 0) {
     345                if (dbwrap_transaction_start(db) != 0) {
    316346                        DEBUG(0, ("Unable to start upgrade transaction!\n"));
    317347                        ret = NT_STATUS_INTERNAL_DB_ERROR;
     
    320350
    321351                if (!idmap_tdb_upgrade(dom, db)) {
    322                         db->transaction_cancel(db);
     352                        dbwrap_transaction_cancel(db);
    323353                        DEBUG(0, ("Unable to open idmap database, it's in an old format, and upgrade failed!\n"));
    324354                        ret = NT_STATUS_INTERNAL_DB_ERROR;
     
    326356                }
    327357
    328                 if (db->transaction_commit(db) != 0) {
     358                if (dbwrap_transaction_commit(db) != 0) {
    329359                        DEBUG(0, ("Unable to commit upgrade transaction!\n"));
    330360                        ret = NT_STATUS_INTERNAL_DB_ERROR;
     
    343373
    344374/**********************************************************************
    345  IDMAP ALLOC TDB BACKEND
    346 **********************************************************************/
    347 
    348 /**********************************
    349  Allocate a new id.
    350 **********************************/
    351 
    352 struct idmap_tdb_allocate_id_context {
    353         const char *hwmkey;
    354         const char *hwmtype;
    355         uint32_t high_hwm;
    356         uint32_t hwm;
    357 };
    358 
    359 static NTSTATUS idmap_tdb_allocate_id_action(struct db_context *db,
    360                                              void *private_data)
    361 {
    362         NTSTATUS ret;
    363         struct idmap_tdb_allocate_id_context *state;
    364         uint32_t hwm;
    365 
    366         state = (struct idmap_tdb_allocate_id_context *)private_data;
    367 
    368         hwm = dbwrap_fetch_int32(db, state->hwmkey);
    369         if (hwm == -1) {
    370                 ret = NT_STATUS_INTERNAL_DB_ERROR;
    371                 goto done;
    372         }
    373 
    374         /* check it is in the range */
    375         if (hwm > state->high_hwm) {
    376                 DEBUG(1, ("Fatal Error: %s range full!! (max: %lu)\n",
    377                           state->hwmtype, (unsigned long)state->high_hwm));
    378                 ret = NT_STATUS_UNSUCCESSFUL;
    379                 goto done;
    380         }
    381 
    382         /* fetch a new id and increment it */
    383         ret = dbwrap_trans_change_uint32_atomic(db, state->hwmkey, &hwm, 1);
    384         if (!NT_STATUS_IS_OK(ret)) {
    385                 DEBUG(0, ("Fatal error while fetching a new %s value: %s\n!",
    386                           state->hwmtype, nt_errstr(ret)));
    387                 goto done;
    388         }
    389 
    390         /* recheck it is in the range */
    391         if (hwm > state->high_hwm) {
    392                 DEBUG(1, ("Fatal Error: %s range full!! (max: %lu)\n",
    393                           state->hwmtype, (unsigned long)state->high_hwm));
    394                 ret = NT_STATUS_UNSUCCESSFUL;
    395                 goto done;
    396         }
    397 
    398         ret = NT_STATUS_OK;
    399         state->hwm = hwm;
    400 
    401 done:
    402         return ret;
    403 }
    404 
    405 static NTSTATUS idmap_tdb_allocate_id(struct idmap_domain *dom,
    406                                       struct unixid *xid)
    407 {
    408         const char *hwmkey;
    409         const char *hwmtype;
    410         uint32_t high_hwm;
    411         uint32_t hwm = 0;
    412         NTSTATUS status;
    413         struct idmap_tdb_allocate_id_context state;
    414         struct idmap_tdb_context *ctx;
    415 
    416         ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context);
    417 
    418         /* Get current high water mark */
    419         switch (xid->type) {
    420 
    421         case ID_TYPE_UID:
    422                 hwmkey = HWM_USER;
    423                 hwmtype = "UID";
    424                 break;
    425 
    426         case ID_TYPE_GID:
    427                 hwmkey = HWM_GROUP;
    428                 hwmtype = "GID";
    429                 break;
    430 
    431         default:
    432                 DEBUG(2, ("Invalid ID type (0x%x)\n", xid->type));
    433                 return NT_STATUS_INVALID_PARAMETER;
    434         }
    435 
    436         high_hwm = dom->high_id;
    437 
    438         state.hwm = hwm;
    439         state.high_hwm = high_hwm;
    440         state.hwmtype = hwmtype;
    441         state.hwmkey = hwmkey;
    442 
    443         status = dbwrap_trans_do(ctx->db, idmap_tdb_allocate_id_action,
    444                                  &state);
    445 
    446         if (NT_STATUS_IS_OK(status)) {
    447                 xid->id = state.hwm;
    448                 DEBUG(10,("New %s = %d\n", hwmtype, state.hwm));
    449         } else {
    450                 DEBUG(1, ("Error allocating a new %s\n", hwmtype));
    451         }
    452 
    453         return status;
    454 }
    455 
    456 /**
    457  * Allocate a new unix-ID.
    458  * For now this is for the default idmap domain only.
    459  * Should be extended later on.
    460  */
    461 static NTSTATUS idmap_tdb_get_new_id(struct idmap_domain *dom,
    462                                      struct unixid *id)
    463 {
    464         NTSTATUS ret;
    465 
    466         if (!strequal(dom->name, "*")) {
    467                 DEBUG(3, ("idmap_tdb_get_new_id: "
    468                           "Refusing allocation of a new unixid for domain'%s'. "
    469                           "Currently only supported for the default "
    470                           "domain \"*\".\n",
    471                            dom->name));
    472                 return NT_STATUS_NOT_IMPLEMENTED;
    473         }
    474 
    475         ret = idmap_tdb_allocate_id(dom, id);
    476 
    477         return ret;
    478 }
    479 
    480 /**********************************************************************
    481375 IDMAP MAPPING TDB BACKEND
    482376**********************************************************************/
     
    486380*****************************/
    487381
    488 static NTSTATUS idmap_tdb_set_mapping(struct idmap_domain *dom,
    489                                       const struct id_map *map);
    490 
    491382static NTSTATUS idmap_tdb_db_init(struct idmap_domain *dom)
    492383{
    493384        NTSTATUS ret;
    494         struct idmap_tdb_context *ctx;
     385        struct idmap_tdb_common_context *ctx;
    495386
    496387        DEBUG(10, ("idmap_tdb_db_init called for domain '%s'\n", dom->name));
    497388
    498         ctx = talloc_zero(dom, struct idmap_tdb_context);
     389        ctx = talloc_zero(dom, struct idmap_tdb_common_context);
    499390        if ( ! ctx) {
    500391                DEBUG(0, ("Out of memory!\n"));
     
    516407        }
    517408
    518         ctx->rw_ops->get_new_id = idmap_tdb_get_new_id;
    519         ctx->rw_ops->set_mapping = idmap_tdb_set_mapping;
     409        ctx->max_id = dom->high_id;
     410        ctx->hwmkey_uid = HWM_USER;
     411        ctx->hwmkey_gid = HWM_GROUP;
     412
     413        ctx->rw_ops->get_new_id = idmap_tdb_common_get_new_id;
     414        ctx->rw_ops->set_mapping = idmap_tdb_common_set_mapping;
    520415
    521416        dom->private_data = ctx;
     
    533428}
    534429
    535 
    536 /**
    537  * store a mapping in the database
    538  */
    539 
    540 struct idmap_tdb_set_mapping_context {
    541         const char *ksidstr;
    542         const char *kidstr;
    543 };
    544 
    545 static NTSTATUS idmap_tdb_set_mapping_action(struct db_context *db,
    546                                              void *private_data)
    547 {
    548         NTSTATUS ret;
    549         struct idmap_tdb_set_mapping_context *state;
    550 
    551         state = (struct idmap_tdb_set_mapping_context *)private_data;
    552 
    553         DEBUG(10, ("Storing %s <-> %s map\n", state->ksidstr, state->kidstr));
    554 
    555         ret = dbwrap_store_bystring(db, state->ksidstr,
    556                                     string_term_tdb_data(state->kidstr),
    557                                     TDB_REPLACE);
    558         if (!NT_STATUS_IS_OK(ret)) {
    559                 DEBUG(0, ("Error storing SID -> ID (%s -> %s): %s\n",
    560                           state->ksidstr, state->kidstr, nt_errstr(ret)));
    561                 goto done;
    562         }
    563 
    564         ret = dbwrap_store_bystring(db, state->kidstr,
    565                                     string_term_tdb_data(state->ksidstr),
    566                                     TDB_REPLACE);
    567         if (!NT_STATUS_IS_OK(ret)) {
    568                 DEBUG(0, ("Error storing ID -> SID (%s -> %s): %s\n",
    569                           state->kidstr, state->ksidstr, nt_errstr(ret)));
    570                 goto done;
    571         }
    572 
    573         DEBUG(10,("Stored %s <-> %s\n", state->ksidstr, state->kidstr));
    574         ret = NT_STATUS_OK;
    575 
    576 done:
    577         return ret;
    578 }
    579 
    580 static NTSTATUS idmap_tdb_set_mapping(struct idmap_domain *dom,
    581                                       const struct id_map *map)
    582 {
    583         struct idmap_tdb_context *ctx;
    584         NTSTATUS ret;
    585         char *ksidstr, *kidstr;
    586         struct idmap_tdb_set_mapping_context state;
    587 
    588         if (!map || !map->sid) {
    589                 return NT_STATUS_INVALID_PARAMETER;
    590         }
    591 
    592         ksidstr = kidstr = NULL;
    593 
    594         /* TODO: should we filter a set_mapping using low/high filters ? */
    595 
    596         ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context);
    597 
    598         switch (map->xid.type) {
    599 
    600         case ID_TYPE_UID:
    601                 kidstr = talloc_asprintf(ctx, "UID %lu",
    602                                          (unsigned long)map->xid.id);
    603                 break;
    604 
    605         case ID_TYPE_GID:
    606                 kidstr = talloc_asprintf(ctx, "GID %lu",
    607                                          (unsigned long)map->xid.id);
    608                 break;
    609 
    610         default:
    611                 DEBUG(2, ("INVALID unix ID type: 0x02%x\n", map->xid.type));
    612                 return NT_STATUS_INVALID_PARAMETER;
    613         }
    614 
    615         if (kidstr == NULL) {
    616                 DEBUG(0, ("ERROR: Out of memory!\n"));
    617                 ret = NT_STATUS_NO_MEMORY;
    618                 goto done;
    619         }
    620 
    621         ksidstr = sid_string_talloc(ctx, map->sid);
    622         if (ksidstr == NULL) {
    623                 DEBUG(0, ("Out of memory!\n"));
    624                 ret = NT_STATUS_NO_MEMORY;
    625                 goto done;
    626         }
    627 
    628         state.ksidstr = ksidstr;
    629         state.kidstr = kidstr;
    630 
    631         ret = dbwrap_trans_do(ctx->db, idmap_tdb_set_mapping_action, &state);
    632 
    633 done:
    634         talloc_free(ksidstr);
    635         talloc_free(kidstr);
    636         return ret;
    637 }
    638 
    639 /**
    640  * Create a new mapping for an unmapped SID, also allocating a new ID.
    641  * This should be run inside a transaction.
    642  *
    643  * TODO:
    644  * Properly integrate this with multi domain idmap config:
    645  * Currently, the allocator is default-config only.
    646  */
    647 static NTSTATUS idmap_tdb_new_mapping(struct idmap_domain *dom, struct id_map *map)
    648 {
    649         NTSTATUS ret;
    650         struct idmap_tdb_context *ctx;
    651 
    652         ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context);
    653 
    654         ret = idmap_rw_new_mapping(dom, ctx->rw_ops, map);
    655 
    656         return ret;
    657 }
    658 
    659 
    660 /**********************************
    661  Single id to sid lookup function.
    662 **********************************/
    663 
    664 static NTSTATUS idmap_tdb_id_to_sid(struct idmap_domain *dom, struct id_map *map)
    665 {
    666         NTSTATUS ret;
    667         TDB_DATA data;
    668         char *keystr;
    669         struct idmap_tdb_context *ctx;
    670 
    671         if (!dom || !map) {
    672                 return NT_STATUS_INVALID_PARAMETER;
    673         }
    674 
    675         ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context);
    676 
    677         /* apply filters before checking */
    678         if (!idmap_unix_id_is_in_range(map->xid.id, dom)) {
    679                 DEBUG(5, ("Requested id (%u) out of range (%u - %u). Filtered!\n",
    680                                 map->xid.id, dom->low_id, dom->high_id));
    681                 return NT_STATUS_NONE_MAPPED;
    682         }
    683 
    684         switch (map->xid.type) {
    685 
    686         case ID_TYPE_UID:
    687                 keystr = talloc_asprintf(ctx, "UID %lu", (unsigned long)map->xid.id);
    688                 break;
    689 
    690         case ID_TYPE_GID:
    691                 keystr = talloc_asprintf(ctx, "GID %lu", (unsigned long)map->xid.id);
    692                 break;
    693 
    694         default:
    695                 DEBUG(2, ("INVALID unix ID type: 0x02%x\n", map->xid.type));
    696                 return NT_STATUS_INVALID_PARAMETER;
    697         }
    698 
    699         /* final SAFE_FREE safe */
    700         data.dptr = NULL;
    701 
    702         if (keystr == NULL) {
    703                 DEBUG(0, ("Out of memory!\n"));
    704                 ret = NT_STATUS_NO_MEMORY;
    705                 goto done;
    706         }
    707 
    708         DEBUG(10,("Fetching record %s\n", keystr));
    709 
    710         /* Check if the mapping exists */
    711         data = dbwrap_fetch_bystring(ctx->db, NULL, keystr);
    712 
    713         if (!data.dptr) {
    714                 DEBUG(10,("Record %s not found\n", keystr));
    715                 ret = NT_STATUS_NONE_MAPPED;
    716                 goto done;
    717         }
    718 
    719         if (!string_to_sid(map->sid, (const char *)data.dptr)) {
    720                 DEBUG(10,("INVALID SID (%s) in record %s\n",
    721                         (const char *)data.dptr, keystr));
    722                 ret = NT_STATUS_INTERNAL_DB_ERROR;
    723                 goto done;
    724         }
    725 
    726         DEBUG(10,("Found record %s -> %s\n", keystr, (const char *)data.dptr));
    727         ret = NT_STATUS_OK;
    728 
    729 done:
    730         talloc_free(data.dptr);
    731         talloc_free(keystr);
    732         return ret;
    733 }
    734 
    735 /**********************************
    736  Single sid to id lookup function.
    737 **********************************/
    738 
    739 static NTSTATUS idmap_tdb_sid_to_id(struct idmap_domain *dom, struct id_map *map)
    740 {
    741         NTSTATUS ret;
    742         TDB_DATA data;
    743         char *keystr;
    744         unsigned long rec_id = 0;
    745         struct idmap_tdb_context *ctx;
    746         TALLOC_CTX *tmp_ctx = talloc_stackframe();
    747 
    748         ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context);
    749 
    750         keystr = sid_string_talloc(tmp_ctx, map->sid);
    751         if (keystr == NULL) {
    752                 DEBUG(0, ("Out of memory!\n"));
    753                 ret = NT_STATUS_NO_MEMORY;
    754                 goto done;
    755         }
    756 
    757         DEBUG(10,("Fetching record %s\n", keystr));
    758 
    759         /* Check if sid is present in database */
    760         data = dbwrap_fetch_bystring(ctx->db, tmp_ctx, keystr);
    761         if (!data.dptr) {
    762                 DEBUG(10,("Record %s not found\n", keystr));
    763                 ret = NT_STATUS_NONE_MAPPED;
    764                 goto done;
    765         }
    766 
    767         /* What type of record is this ? */
    768         if (sscanf((const char *)data.dptr, "UID %lu", &rec_id) == 1) { /* Try a UID record. */
    769                 map->xid.id = rec_id;
    770                 map->xid.type = ID_TYPE_UID;
    771                 DEBUG(10,("Found uid record %s -> %s \n", keystr, (const char *)data.dptr ));
    772                 ret = NT_STATUS_OK;
    773 
    774         } else if (sscanf((const char *)data.dptr, "GID %lu", &rec_id) == 1) { /* Try a GID record. */
    775                 map->xid.id = rec_id;
    776                 map->xid.type = ID_TYPE_GID;
    777                 DEBUG(10,("Found gid record %s -> %s \n", keystr, (const char *)data.dptr ));
    778                 ret = NT_STATUS_OK;
    779 
    780         } else { /* Unknown record type ! */
    781                 DEBUG(2, ("Found INVALID record %s -> %s\n", keystr, (const char *)data.dptr));
    782                 ret = NT_STATUS_INTERNAL_DB_ERROR;
    783                 goto done;
    784         }
    785 
    786         /* apply filters before returning result */
    787         if (!idmap_unix_id_is_in_range(map->xid.id, dom)) {
    788                 DEBUG(5, ("Requested id (%u) out of range (%u - %u). Filtered!\n",
    789                                 map->xid.id, dom->low_id, dom->high_id));
    790                 ret = NT_STATUS_NONE_MAPPED;
    791         }
    792 
    793 done:
    794         talloc_free(tmp_ctx);
    795         return ret;
    796 }
    797 
    798 /**********************************
    799  lookup a set of unix ids.
    800 **********************************/
    801 
    802 static NTSTATUS idmap_tdb_unixids_to_sids(struct idmap_domain *dom, struct id_map **ids)
    803 {
    804         NTSTATUS ret;
    805         int i;
    806 
    807         /* initialize the status to avoid suprise */
    808         for (i = 0; ids[i]; i++) {
    809                 ids[i]->status = ID_UNKNOWN;
    810         }
    811 
    812         for (i = 0; ids[i]; i++) {
    813                 ret = idmap_tdb_id_to_sid(dom, ids[i]);
    814                 if ( ! NT_STATUS_IS_OK(ret)) {
    815 
    816                         /* if it is just a failed mapping continue */
    817                         if (NT_STATUS_EQUAL(ret, NT_STATUS_NONE_MAPPED)) {
    818 
    819                                 /* make sure it is marked as unmapped */
    820                                 ids[i]->status = ID_UNMAPPED;
    821                                 continue;
    822                         }
    823 
    824                         /* some fatal error occurred, return immediately */
    825                         goto done;
    826                 }
    827 
    828                 /* all ok, id is mapped */
    829                 ids[i]->status = ID_MAPPED;
    830         }
    831 
    832         ret = NT_STATUS_OK;
    833 
    834 done:
    835         return ret;
    836 }
    837 
    838 /**********************************
    839  lookup a set of sids.
    840 **********************************/
    841 
    842 struct idmap_tdb_sids_to_unixids_context {
    843         struct idmap_domain *dom;
    844         struct id_map **ids;
    845         bool allocate_unmapped;
    846 };
    847 
    848 static NTSTATUS idmap_tdb_sids_to_unixids_action(struct db_context *db,
    849                                                  void *private_data)
    850 {
    851         struct idmap_tdb_sids_to_unixids_context *state;
    852         int i;
    853         NTSTATUS ret = NT_STATUS_OK;
    854 
    855         state = (struct idmap_tdb_sids_to_unixids_context *)private_data;
    856 
    857         DEBUG(10, ("idmap_tdb_sids_to_unixids_action: "
    858                    " domain: [%s], allocate: %s\n",
    859                    state->dom->name,
    860                    state->allocate_unmapped ? "yes" : "no"));
    861 
    862         for (i = 0; state->ids[i]; i++) {
    863                 if ((state->ids[i]->status == ID_UNKNOWN) ||
    864                     /* retry if we could not map in previous run: */
    865                     (state->ids[i]->status == ID_UNMAPPED))
    866                 {
    867                         NTSTATUS ret2;
    868 
    869                         ret2 = idmap_tdb_sid_to_id(state->dom, state->ids[i]);
    870                         if (!NT_STATUS_IS_OK(ret2)) {
    871 
    872                                 /* if it is just a failed mapping, continue */
    873                                 if (NT_STATUS_EQUAL(ret2, NT_STATUS_NONE_MAPPED)) {
    874 
    875                                         /* make sure it is marked as unmapped */
    876                                         state->ids[i]->status = ID_UNMAPPED;
    877                                         ret = STATUS_SOME_UNMAPPED;
    878                                 } else {
    879                                         /* some fatal error occurred, return immediately */
    880                                         ret = ret2;
    881                                         goto done;
    882                                 }
    883                         } else {
    884                                 /* all ok, id is mapped */
    885                                 state->ids[i]->status = ID_MAPPED;
    886                         }
    887                 }
    888 
    889                 if ((state->ids[i]->status == ID_UNMAPPED) &&
    890                     state->allocate_unmapped)
    891                 {
    892                         ret = idmap_tdb_new_mapping(state->dom, state->ids[i]);
    893                         if (!NT_STATUS_IS_OK(ret)) {
    894                                 goto done;
    895                         }
    896                 }
    897         }
    898 
    899 done:
    900         return ret;
    901 }
    902 
    903 static NTSTATUS idmap_tdb_sids_to_unixids(struct idmap_domain *dom, struct id_map **ids)
    904 {
    905         struct idmap_tdb_context *ctx;
    906         NTSTATUS ret;
    907         int i;
    908         struct idmap_tdb_sids_to_unixids_context state;
    909 
    910         /* initialize the status to avoid suprise */
    911         for (i = 0; ids[i]; i++) {
    912                 ids[i]->status = ID_UNKNOWN;
    913         }
    914 
    915         ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context);
    916 
    917         state.dom = dom;
    918         state.ids = ids;
    919         state.allocate_unmapped = false;
    920 
    921         ret = idmap_tdb_sids_to_unixids_action(ctx->db, &state);
    922 
    923         if (NT_STATUS_EQUAL(ret, STATUS_SOME_UNMAPPED) && !dom->read_only) {
    924                 state.allocate_unmapped = true;
    925                 ret = dbwrap_trans_do(ctx->db,
    926                                       idmap_tdb_sids_to_unixids_action,
    927                                       &state);
    928         }
    929 
    930         return ret;
    931 }
    932 
    933 
    934 /**********************************
    935  Close the idmap tdb instance
    936 **********************************/
    937 
    938430static struct idmap_methods db_methods = {
    939431        .init = idmap_tdb_db_init,
    940         .unixids_to_sids = idmap_tdb_unixids_to_sids,
    941         .sids_to_unixids = idmap_tdb_sids_to_unixids,
    942         .allocate_id = idmap_tdb_get_new_id,
     432        .unixids_to_sids = idmap_tdb_common_unixids_to_sids,
     433        .sids_to_unixids = idmap_tdb_common_sids_to_unixids,
     434        .allocate_id = idmap_tdb_common_get_new_id,
    943435};
    944436
  • vendor/current/source3/winbindd/idmap_tdb2.c

    r746 r988  
    3737#include "idmap.h"
    3838#include "idmap_rw.h"
    39 #include "dbwrap.h"
     39#include "dbwrap/dbwrap.h"
     40#include "dbwrap/dbwrap_open.h"
    4041#include "../libcli/security/dom_sid.h"
    4142#include "util_tdb.h"
     43#include "idmap_tdb_common.h"
    4244
    4345#undef DBGC_CLASS
     
    4547
    4648struct idmap_tdb2_context {
    47         struct db_context *db;
    4849        const char *script; /* script to provide idmaps */
    49         struct idmap_rw_ops *rw_ops;
    5050};
    5151
     
    5353#define HWM_GROUP  "GROUP HWM"
    5454#define HWM_USER   "USER HWM"
    55 
    5655
    5756/*
     
    6160{
    6261        NTSTATUS status;
    63         uint32 low_id;
    64         struct idmap_tdb2_context *ctx;
    65 
    66         ctx = talloc_get_type(dom->private_data, struct idmap_tdb2_context);
     62        uint32_t low_id;
     63        struct idmap_tdb_common_context *ctx;
     64
     65        ctx = talloc_get_type(dom->private_data,
     66                              struct idmap_tdb_common_context);
    6767
    6868        /* Create high water marks for group and user id */
    6969
    70         low_id = dbwrap_fetch_int32(ctx->db, HWM_USER);
    71         if ((low_id == -1) || (low_id < dom->low_id)) {
    72                 status = dbwrap_trans_store_int32(ctx->db, HWM_USER,
    73                                                   dom->low_id);
     70        status = dbwrap_fetch_uint32_bystring(ctx->db, HWM_USER, &low_id);
     71        if (!NT_STATUS_IS_OK(status) || (low_id < dom->low_id)) {
     72                status = dbwrap_trans_store_uint32_bystring(ctx->db, HWM_USER,
     73                                                            dom->low_id);
    7474                if (!NT_STATUS_IS_OK(status)) {
    7575                        DEBUG(0, ("Unable to initialise user hwm in idmap "
     
    7979        }
    8080
    81         low_id = dbwrap_fetch_int32(ctx->db, HWM_GROUP);
    82         if ((low_id == -1) || (low_id < dom->low_id)) {
    83                 status = dbwrap_trans_store_int32(ctx->db, HWM_GROUP,
    84                                                   dom->low_id);
     81        status = dbwrap_fetch_uint32_bystring(ctx->db, HWM_GROUP, &low_id);
     82        if (!NT_STATUS_IS_OK(status) || (low_id < dom->low_id)) {
     83                status = dbwrap_trans_store_uint32_bystring(ctx->db, HWM_GROUP,
     84                                                            dom->low_id);
    8585                if (!NT_STATUS_IS_OK(status)) {
    8686                        DEBUG(0, ("Unable to initialise group hwm in idmap "
     
    100100{
    101101        char *db_path;
    102         struct idmap_tdb2_context *ctx;
    103 
    104         ctx = talloc_get_type(dom->private_data, struct idmap_tdb2_context);
     102        struct idmap_tdb_common_context *ctx;
     103
     104        ctx = talloc_get_type(dom->private_data,
     105                              struct idmap_tdb_common_context);
    105106
    106107        if (ctx->db) {
     
    113114
    114115        /* Open idmap repository */
    115         ctx->db = db_open(ctx, db_path, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0644);
     116        ctx->db = db_open(ctx, db_path, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0644,
     117                          DBWRAP_LOCK_ORDER_1, DBWRAP_FLAG_NONE);
    116118        TALLOC_FREE(db_path);
    117119
     
    125127}
    126128
    127 
    128 /*
    129   Allocate a new id.
    130 */
    131 
    132 struct idmap_tdb2_allocate_id_context {
    133         const char *hwmkey;
    134         const char *hwmtype;
    135         uint32_t high_hwm;
    136         uint32_t hwm;
    137 };
    138 
    139 static NTSTATUS idmap_tdb2_allocate_id_action(struct db_context *db,
    140                                               void *private_data)
    141 {
    142         NTSTATUS ret;
    143         struct idmap_tdb2_allocate_id_context *state;
    144         uint32_t hwm;
    145 
    146         state = (struct idmap_tdb2_allocate_id_context *)private_data;
    147 
    148         hwm = dbwrap_fetch_int32(db, state->hwmkey);
    149         if (hwm == -1) {
    150                 ret = NT_STATUS_INTERNAL_DB_ERROR;
    151                 goto done;
    152         }
    153 
    154         /* check it is in the range */
    155         if (hwm > state->high_hwm) {
    156                 DEBUG(1, ("Fatal Error: %s range full!! (max: %lu)\n",
    157                           state->hwmtype, (unsigned long)state->high_hwm));
    158                 ret = NT_STATUS_UNSUCCESSFUL;
    159                 goto done;
    160         }
    161 
    162         /* fetch a new id and increment it */
    163         ret = dbwrap_trans_change_uint32_atomic(db, state->hwmkey, &hwm, 1);
    164         if (!NT_STATUS_IS_OK(ret)) {
    165                 DEBUG(1, ("Fatal error while fetching a new %s value\n!",
    166                           state->hwmtype));
    167                 goto done;
    168         }
    169 
    170         /* recheck it is in the range */
    171         if (hwm > state->high_hwm) {
    172                 DEBUG(1, ("Fatal Error: %s range full!! (max: %lu)\n",
    173                           state->hwmtype, (unsigned long)state->high_hwm));
    174                 ret = NT_STATUS_UNSUCCESSFUL;
    175                 goto done;
    176         }
    177 
    178         ret = NT_STATUS_OK;
    179         state->hwm = hwm;
    180 
    181 done:
    182         return ret;
    183 }
    184 
    185 static NTSTATUS idmap_tdb2_allocate_id(struct idmap_domain *dom,
    186                                        struct unixid *xid)
    187 {
    188         const char *hwmkey;
    189         const char *hwmtype;
    190         uint32_t high_hwm;
    191         uint32_t hwm = 0;
    192         NTSTATUS status;
    193         struct idmap_tdb2_allocate_id_context state;
    194         struct idmap_tdb2_context *ctx;
    195 
    196         status = idmap_tdb2_open_db(dom);
    197         NT_STATUS_NOT_OK_RETURN(status);
    198 
    199         ctx = talloc_get_type(dom->private_data, struct idmap_tdb2_context);
    200 
    201         /* Get current high water mark */
    202         switch (xid->type) {
    203 
    204         case ID_TYPE_UID:
    205                 hwmkey = HWM_USER;
    206                 hwmtype = "UID";
    207                 break;
    208 
    209         case ID_TYPE_GID:
    210                 hwmkey = HWM_GROUP;
    211                 hwmtype = "GID";
    212                 break;
    213 
    214         default:
    215                 DEBUG(2, ("Invalid ID type (0x%x)\n", xid->type));
    216                 return NT_STATUS_INVALID_PARAMETER;
    217         }
    218 
    219         high_hwm = dom->high_id;
    220 
    221         state.hwm = hwm;
    222         state.high_hwm = high_hwm;
    223         state.hwmtype = hwmtype;
    224         state.hwmkey = hwmkey;
    225 
    226         status = dbwrap_trans_do(ctx->db, idmap_tdb2_allocate_id_action,
    227                                  &state);
    228 
    229         if (NT_STATUS_IS_OK(status)) {
    230                 xid->id = state.hwm;
    231                 DEBUG(10,("New %s = %d\n", hwmtype, state.hwm));
    232         } else {
    233                 DEBUG(1, ("Error allocating a new %s\n", hwmtype));
    234         }
    235 
    236         return status;
    237 }
    238 
    239 /**
    240  * Allocate a new unix-ID.
    241  * For now this is for the default idmap domain only.
    242  * Should be extended later on.
    243  */
    244 static NTSTATUS idmap_tdb2_get_new_id(struct idmap_domain *dom,
    245                                       struct unixid *id)
    246 {
    247         NTSTATUS ret;
    248 
    249         if (!strequal(dom->name, "*")) {
    250                 DEBUG(3, ("idmap_tdb2_get_new_id: "
    251                           "Refusing creation of mapping for domain'%s'. "
    252                           "Currently only supported for the default "
    253                           "domain \"*\".\n",
    254                            dom->name));
    255                 return NT_STATUS_NOT_IMPLEMENTED;
    256         }
    257 
    258         ret = idmap_tdb2_allocate_id(dom, id);
    259 
    260         return ret;
    261 }
    262 
    263 /*
    264   IDMAP MAPPING TDB BACKEND
    265 */
    266 
    267 static NTSTATUS idmap_tdb2_set_mapping(struct idmap_domain *dom,
    268                                        const struct id_map *map);
    269 
    270 /*
    271   Initialise idmap database.
    272 */
    273 static NTSTATUS idmap_tdb2_db_init(struct idmap_domain *dom)
    274 {
    275         NTSTATUS ret;
    276         struct idmap_tdb2_context *ctx;
    277         char *config_option = NULL;
    278         const char * idmap_script = NULL;
    279 
    280         ctx = talloc_zero(dom, struct idmap_tdb2_context);
    281         if ( ! ctx) {
    282                 DEBUG(0, ("Out of memory!\n"));
    283                 return NT_STATUS_NO_MEMORY;
    284         }
    285 
    286         config_option = talloc_asprintf(ctx, "idmap config %s", dom->name);
    287         if (config_option == NULL) {
    288                 DEBUG(0, ("Out of memory!\n"));
    289                 ret = NT_STATUS_NO_MEMORY;
    290                 goto failed;
    291         }
    292         ctx->script = lp_parm_const_string(-1, config_option, "script", NULL);
    293         talloc_free(config_option);
    294 
    295         idmap_script = lp_parm_const_string(-1, "idmap", "script", NULL);
    296         if (idmap_script != NULL) {
    297                 DEBUG(0, ("Warning: 'idmap:script' is deprecated. "
    298                           " Please use 'idmap config * : script' instead!\n"));
    299         }
    300 
    301         if (strequal(dom->name, "*") && ctx->script == NULL) {
    302                 /* fall back to idmap:script for backwards compatibility */
    303                 ctx->script = idmap_script;
    304         }
    305 
    306         if (ctx->script) {
    307                 DEBUG(1, ("using idmap script '%s'\n", ctx->script));
    308         }
    309 
    310         ctx->rw_ops = talloc_zero(ctx, struct idmap_rw_ops);
    311         if (ctx->rw_ops == NULL) {
    312                 DEBUG(0, ("Out of memory!\n"));
    313                 ret = NT_STATUS_NO_MEMORY;
    314                 goto failed;
    315         }
    316 
    317         ctx->rw_ops->get_new_id = idmap_tdb2_get_new_id;
    318         ctx->rw_ops->set_mapping = idmap_tdb2_set_mapping;
    319 
    320         dom->private_data = ctx;
    321 
    322         ret = idmap_tdb2_open_db(dom);
    323         if (!NT_STATUS_IS_OK(ret)) {
    324                 goto failed;
    325         }
    326 
    327         return NT_STATUS_OK;
    328 
    329 failed:
    330         talloc_free(ctx);
    331         return ret;
    332 }
    333 
    334 
    335129/**
    336130 * store a mapping in the database.
     
    355149
    356150        /* check wheter sid mapping is already present in db */
    357         data = dbwrap_fetch_bystring(db, tmp_ctx, state->ksidstr);
    358         if (data.dptr) {
     151        ret = dbwrap_fetch_bystring(db, tmp_ctx, state->ksidstr, &data);
     152        if (NT_STATUS_IS_OK(ret)) {
    359153                ret = NT_STATUS_OBJECT_NAME_COLLISION;
    360154                goto done;
     
    391185        NTSTATUS ret;
    392186        char *ksidstr, *kidstr;
     187        struct idmap_tdb_common_context *commonctx;
    393188        struct idmap_tdb2_set_mapping_context state;
    394189
     
    401196        /* TODO: should we filter a set_mapping using low/high filters ? */
    402197
    403         ctx = talloc_get_type(dom->private_data, struct idmap_tdb2_context);
     198        commonctx = talloc_get_type(dom->private_data,
     199                                    struct idmap_tdb_common_context);
     200
     201        ctx = talloc_get_type(commonctx->private_data,
     202                              struct idmap_tdb2_context);
    404203
    405204        switch (map->xid.type) {
     
    434233        state.kidstr = kidstr;
    435234
    436         ret = dbwrap_trans_do(ctx->db, idmap_tdb2_set_mapping_action,
     235        ret = dbwrap_trans_do(commonctx->db, idmap_tdb2_set_mapping_action,
    437236                              &state);
    438237
     
    442241        return ret;
    443242}
    444 
    445 /**
    446  * Create a new mapping for an unmapped SID, also allocating a new ID.
    447  * This should be run inside a transaction.
    448  *
    449  * TODO:
    450 *  Properly integrate this with multi domain idmap config:
    451  * Currently, the allocator is default-config only.
    452  */
    453 static NTSTATUS idmap_tdb2_new_mapping(struct idmap_domain *dom, struct id_map *map)
    454 {
    455         NTSTATUS ret;
    456         struct idmap_tdb2_context *ctx;
    457 
    458         ctx = talloc_get_type(dom->private_data, struct idmap_tdb2_context);
    459 
    460         ret = idmap_rw_new_mapping(dom, ctx->rw_ops, map);
    461 
    462         return ret;
    463 }
    464 
    465243
    466244/*
     
    542320        char *keystr;
    543321        NTSTATUS status;
     322        struct idmap_tdb_common_context *commonctx;
    544323        struct idmap_tdb2_context *ctx;
    545324
     
    552331        NT_STATUS_NOT_OK_RETURN(status);
    553332
    554         ctx = talloc_get_type(dom->private_data, struct idmap_tdb2_context);
     333        commonctx = talloc_get_type(dom->private_data,
     334                                    struct idmap_tdb_common_context);
     335
     336        ctx = talloc_get_type(commonctx->private_data,
     337                              struct idmap_tdb2_context);
    555338
    556339        /* apply filters before checking */
     
    585368
    586369        /* Check if the mapping exists */
    587         data = dbwrap_fetch_bystring(ctx->db, keystr, keystr);
    588 
    589         if (!data.dptr) {
     370        status = dbwrap_fetch_bystring(commonctx->db, keystr, keystr, &data);
     371
     372        if (!NT_STATUS_IS_OK(status)) {
    590373                char *sidstr;
    591374                struct idmap_tdb2_set_mapping_context store_state;
     
    611394                store_state.kidstr = keystr;
    612395
    613                 ret = dbwrap_trans_do(ctx->db, idmap_tdb2_set_mapping_action,
     396                ret = dbwrap_trans_do(commonctx->db,
     397                                      idmap_tdb2_set_mapping_action,
    614398                                      &store_state);
    615399                goto done;
     
    641425        char *keystr;
    642426        unsigned long rec_id = 0;
     427        struct idmap_tdb_common_context *commonctx;
    643428        struct idmap_tdb2_context *ctx;
    644429        TALLOC_CTX *tmp_ctx = talloc_stackframe();
     
    647432        NT_STATUS_NOT_OK_RETURN(ret);
    648433
    649         ctx = talloc_get_type(dom->private_data, struct idmap_tdb2_context);
     434        commonctx = talloc_get_type(dom->private_data,
     435                                    struct idmap_tdb_common_context);
     436
     437        ctx = talloc_get_type(commonctx->private_data,
     438                              struct idmap_tdb2_context);
    650439
    651440        keystr = sid_string_talloc(tmp_ctx, map->sid);
     
    659448
    660449        /* Check if sid is present in database */
    661         data = dbwrap_fetch_bystring(ctx->db, tmp_ctx, keystr);
    662         if (!data.dptr) {
     450        ret = dbwrap_fetch_bystring(commonctx->db, tmp_ctx, keystr, &data);
     451        if (!NT_STATUS_IS_OK(ret)) {
    663452                char *idstr;
    664453                struct idmap_tdb2_set_mapping_context store_state;
     
    696485                store_state.kidstr = idstr;
    697486
    698                 ret = dbwrap_trans_do(ctx->db, idmap_tdb2_set_mapping_action,
     487                ret = dbwrap_trans_do(commonctx->db,
     488                                      idmap_tdb2_set_mapping_action,
    699489                                      &store_state);
    700490                goto done;
     
    733523
    734524/*
    735   lookup a set of unix ids.
     525  Initialise idmap database.
    736526*/
    737 static NTSTATUS idmap_tdb2_unixids_to_sids(struct idmap_domain *dom, struct id_map **ids)
     527static NTSTATUS idmap_tdb2_db_init(struct idmap_domain *dom)
    738528{
    739529        NTSTATUS ret;
    740         int i;
    741 
    742         /* initialize the status to avoid suprise */
    743         for (i = 0; ids[i]; i++) {
    744                 ids[i]->status = ID_UNKNOWN;
    745         }
    746 
    747         for (i = 0; ids[i]; i++) {
    748                 ret = idmap_tdb2_id_to_sid(dom, ids[i]);
    749                 if ( ! NT_STATUS_IS_OK(ret)) {
    750 
    751                         /* if it is just a failed mapping continue */
    752                         if (NT_STATUS_EQUAL(ret, NT_STATUS_NONE_MAPPED)) {
    753 
    754                                 /* make sure it is marked as unmapped */
    755                                 ids[i]->status = ID_UNMAPPED;
    756                                 continue;
    757                         }
    758 
    759                         /* some fatal error occurred, return immediately */
    760                         goto done;
    761                 }
    762 
    763                 /* all ok, id is mapped */
    764                 ids[i]->status = ID_MAPPED;
    765         }
    766 
    767         ret = NT_STATUS_OK;
    768 
    769 done:
    770         return ret;
    771 }
    772 
    773 /*
    774   lookup a set of sids.
    775 */
    776 
    777 struct idmap_tdb2_sids_to_unixids_context {
    778         struct idmap_domain *dom;
    779         struct id_map **ids;
    780         bool allocate_unmapped;
    781 };
    782 
    783 static NTSTATUS idmap_tdb2_sids_to_unixids_action(struct db_context *db,
    784                                                   void *private_data)
    785 {
    786         struct idmap_tdb2_sids_to_unixids_context *state;
    787         int i;
    788         NTSTATUS ret = NT_STATUS_OK;
    789 
    790         state = (struct idmap_tdb2_sids_to_unixids_context *)private_data;
    791 
    792         DEBUG(10, ("idmap_tdb2_sids_to_unixids_action: "
    793                    " domain: [%s], allocate: %s\n",
    794                    state->dom->name,
    795                    state->allocate_unmapped ? "yes" : "no"));
    796 
    797         for (i = 0; state->ids[i]; i++) {
    798                 if ((state->ids[i]->status == ID_UNKNOWN) ||
    799                     /* retry if we could not map in previous run: */
    800                     (state->ids[i]->status == ID_UNMAPPED))
    801                 {
    802                         NTSTATUS ret2;
    803 
    804                         ret2 = idmap_tdb2_sid_to_id(state->dom, state->ids[i]);
    805                         if (!NT_STATUS_IS_OK(ret2)) {
    806 
    807                                 /* if it is just a failed mapping, continue */
    808                                 if (NT_STATUS_EQUAL(ret2, NT_STATUS_NONE_MAPPED)) {
    809 
    810                                         /* make sure it is marked as unmapped */
    811                                         state->ids[i]->status = ID_UNMAPPED;
    812                                         ret = STATUS_SOME_UNMAPPED;
    813                                 } else {
    814                                         /* some fatal error occurred, return immediately */
    815                                         ret = ret2;
    816                                         goto done;
    817                                 }
    818                         } else {
    819                                 /* all ok, id is mapped */
    820                                 state->ids[i]->status = ID_MAPPED;
    821                         }
    822                 }
    823 
    824                 if ((state->ids[i]->status == ID_UNMAPPED) &&
    825                     state->allocate_unmapped)
    826                 {
    827                         ret = idmap_tdb2_new_mapping(state->dom, state->ids[i]);
    828                         if (!NT_STATUS_IS_OK(ret)) {
    829                                 goto done;
    830                         }
    831                 }
    832         }
    833 
    834 done:
    835         return ret;
    836 }
    837 
    838 static NTSTATUS idmap_tdb2_sids_to_unixids(struct idmap_domain *dom, struct id_map **ids)
    839 {
    840         NTSTATUS ret;
    841         int i;
    842         struct idmap_tdb2_sids_to_unixids_context state;
     530        struct idmap_tdb_common_context *commonctx;
    843531        struct idmap_tdb2_context *ctx;
    844 
    845         ctx = talloc_get_type(dom->private_data, struct idmap_tdb2_context);
    846 
    847         /* initialize the status to avoid suprise */
    848         for (i = 0; ids[i]; i++) {
    849                 ids[i]->status = ID_UNKNOWN;
    850         }
    851 
    852         state.dom = dom;
    853         state.ids = ids;
    854         state.allocate_unmapped = false;
    855 
    856         ret = idmap_tdb2_sids_to_unixids_action(ctx->db, &state);
    857 
    858         if (NT_STATUS_EQUAL(ret, STATUS_SOME_UNMAPPED) && !dom->read_only) {
    859                 state.allocate_unmapped = true;
    860                 ret = dbwrap_trans_do(ctx->db,
    861                                       idmap_tdb2_sids_to_unixids_action,
    862                                       &state);
    863         }
    864 
     532        char *config_option = NULL;
     533        const char * idmap_script = NULL;
     534
     535        commonctx = talloc_zero(dom, struct idmap_tdb_common_context);
     536        if(!commonctx) {
     537                DEBUG(0, ("Out of memory!\n"));
     538                return NT_STATUS_NO_MEMORY;
     539        }
     540
     541        commonctx->rw_ops = talloc_zero(commonctx, struct idmap_rw_ops);
     542        if (commonctx->rw_ops == NULL) {
     543                DEBUG(0, ("Out of memory!\n"));
     544                ret = NT_STATUS_NO_MEMORY;
     545                goto failed;
     546        }
     547
     548        ctx = talloc_zero(commonctx, struct idmap_tdb2_context);
     549        if (!ctx) {
     550                DEBUG(0, ("Out of memory!\n"));
     551                ret = NT_STATUS_NO_MEMORY;
     552                goto failed;
     553        }
     554
     555        config_option = talloc_asprintf(ctx, "idmap config %s", dom->name);
     556        if (config_option == NULL) {
     557                DEBUG(0, ("Out of memory!\n"));
     558                ret = NT_STATUS_NO_MEMORY;
     559                goto failed;
     560        }
     561        ctx->script = lp_parm_const_string(-1, config_option, "script", NULL);
     562        talloc_free(config_option);
     563
     564        idmap_script = lp_parm_const_string(-1, "idmap", "script", NULL);
     565        if (idmap_script != NULL) {
     566                DEBUG(0, ("Warning: 'idmap:script' is deprecated. "
     567                          " Please use 'idmap config * : script' instead!\n"));
     568        }
     569
     570        if (strequal(dom->name, "*") && ctx->script == NULL) {
     571                /* fall back to idmap:script for backwards compatibility */
     572                ctx->script = idmap_script;
     573        }
     574
     575        if (ctx->script) {
     576                DEBUG(1, ("using idmap script '%s'\n", ctx->script));
     577        }
     578
     579        commonctx->max_id = dom->high_id;
     580        commonctx->hwmkey_uid = HWM_USER;
     581        commonctx->hwmkey_gid = HWM_GROUP;
     582
     583        commonctx->sid_to_unixid_fn = idmap_tdb2_sid_to_id;
     584        commonctx->unixid_to_sid_fn = idmap_tdb2_id_to_sid;
     585
     586        commonctx->rw_ops->get_new_id = idmap_tdb_common_get_new_id;
     587        commonctx->rw_ops->set_mapping = idmap_tdb2_set_mapping;
     588
     589        commonctx->private_data = ctx;
     590        dom->private_data = commonctx;
     591
     592        ret = idmap_tdb2_open_db(dom);
     593        if (!NT_STATUS_IS_OK(ret)) {
     594                goto failed;
     595        }
     596
     597        return NT_STATUS_OK;
     598
     599failed:
     600        talloc_free(commonctx);
    865601        return ret;
    866602}
     
    869605static struct idmap_methods db_methods = {
    870606        .init            = idmap_tdb2_db_init,
    871         .unixids_to_sids = idmap_tdb2_unixids_to_sids,
    872         .sids_to_unixids = idmap_tdb2_sids_to_unixids,
    873         .allocate_id     = idmap_tdb2_get_new_id
     607        .unixids_to_sids = idmap_tdb_common_unixids_to_sids,
     608        .sids_to_unixids = idmap_tdb_common_sids_to_unixids,
     609        .allocate_id     = idmap_tdb_common_get_new_id
    874610};
    875611
     612static_decl_idmap;
    876613NTSTATUS idmap_tdb2_init(void)
    877614{
  • vendor/current/source3/winbindd/idmap_util.c

    r740 r988  
    2525#include "idmap_cache.h"
    2626#include "../libcli/security/security.h"
     27#include "secrets.h"
    2728
    2829#undef DBGC_CLASS
     
    3233 Returns the SID mapped to the given UID.
    3334 If mapping is not possible returns an error.
    34 *****************************************************************/ 
    35 
    36 NTSTATUS idmap_uid_to_sid(const char *domname, struct dom_sid *sid, uid_t uid)
     35*****************************************************************/
     36
     37NTSTATUS idmap_uid_to_sid(struct dom_sid *sid, uid_t uid)
    3738{
    3839        NTSTATUS ret;
     
    4041        bool expired;
    4142
    42         DEBUG(10,("idmap_uid_to_sid: uid = [%lu], domain = '%s'\n",
    43                   (unsigned long)uid, domname?domname:"NULL"));
     43        DEBUG(10, ("idmap_uid_to_sid: uid = [%lu]\n", (unsigned long)uid));
    4444
    4545        if (winbindd_use_idmap_cache()
     
    6161
    6262backend:
     63        ZERO_STRUCT(map);
    6364        map.sid = sid;
    6465        map.xid.type = ID_TYPE_UID;
    6566        map.xid.id = uid;
    6667
    67         ret = idmap_backends_unixid_to_sid(domname, &map);
     68        ret = idmap_backends_unixid_to_sid(&map);
    6869        if ( ! NT_STATUS_IS_OK(ret)) {
    69                 DEBUG(10, ("error mapping uid [%lu]\n", (unsigned long)uid));
    70                 return ret;
     70                DEBUG(10, ("error mapping uid [%lu]: %s\n", (unsigned long)uid,
     71                           nt_errstr(ret)));
     72                map.status = ID_UNMAPPED;
    7173        }
    7274
     
    7476                if (winbindd_use_idmap_cache()) {
    7577                        struct dom_sid null_sid;
     78                        struct unixid id;
     79                        id.type = ID_TYPE_UID;
     80                        id.id = uid;
    7681                        ZERO_STRUCT(null_sid);
    77                         idmap_cache_set_sid2uid(&null_sid, uid);
     82                        idmap_cache_set_sid2unixid(&null_sid, &id);
    7883                }
    7984                DEBUG(10, ("uid [%lu] not mapped\n", (unsigned long)uid));
     
    8287
    8388        if (winbindd_use_idmap_cache()) {
    84                 idmap_cache_set_sid2uid(sid, uid);
     89                idmap_cache_set_sid2unixid(sid, &map.xid);
    8590        }
    8691
     
    9196 Returns SID mapped to the given GID.
    9297 If mapping is not possible returns an error.
    93 *****************************************************************/ 
    94 
    95 NTSTATUS idmap_gid_to_sid(const char *domname, struct dom_sid *sid, gid_t gid)
     98*****************************************************************/
     99
     100NTSTATUS idmap_gid_to_sid(struct dom_sid *sid, gid_t gid)
    96101{
    97102        NTSTATUS ret;
     
    99104        bool expired;
    100105
    101         DEBUG(10,("idmap_gid_to_sid: gid = [%lu], domain = '%s'\n",
    102                   (unsigned long)gid, domname?domname:"NULL"));
     106        DEBUG(10, ("idmap_gid_to_sid: gid = [%lu]\n", (unsigned long)gid));
    103107
    104108        if (winbindd_use_idmap_cache()
     
    120124
    121125backend:
     126        ZERO_STRUCT(map);
    122127        map.sid = sid;
    123128        map.xid.type = ID_TYPE_GID;
    124129        map.xid.id = gid;
    125130
    126         ret = idmap_backends_unixid_to_sid(domname, &map);
     131        ret = idmap_backends_unixid_to_sid(&map);
    127132        if ( ! NT_STATUS_IS_OK(ret)) {
    128                 DEBUG(10, ("error mapping gid [%lu]\n", (unsigned long)gid));
    129                 return ret;
     133                DEBUG(10, ("error mapping gid [%lu]: %s\n", (unsigned long)gid,
     134                           nt_errstr(ret)));
     135                map.status = ID_UNMAPPED;
    130136        }
    131137
     
    133139                if (winbindd_use_idmap_cache()) {
    134140                        struct dom_sid null_sid;
     141                        struct unixid id;
     142                        id.type = ID_TYPE_GID;
     143                        id.id = gid;
    135144                        ZERO_STRUCT(null_sid);
    136                         idmap_cache_set_sid2gid(&null_sid, gid);
     145                        idmap_cache_set_sid2unixid(&null_sid, &id);
    137146                }
    138147                DEBUG(10, ("gid [%lu] not mapped\n", (unsigned long)gid));
     
    141150
    142151        if (winbindd_use_idmap_cache()) {
    143                 idmap_cache_set_sid2gid(sid, gid);
    144         }
    145 
    146         return NT_STATUS_OK;
    147 }
    148 
    149 /*****************************************************************
    150  Returns the UID mapped to the given SID.
    151  If mapping is not possible or SID maps to a GID returns an error.
    152 *****************************************************************/ 
    153 
    154 NTSTATUS idmap_sid_to_uid(const char *dom_name, struct dom_sid *sid, uid_t *uid)
    155 {
    156         NTSTATUS ret;
    157         struct id_map map;
    158         bool expired;
    159 
    160         DEBUG(10,("idmap_sid_to_uid: sid = [%s], domain = '%s'\n",
    161                   sid_string_dbg(sid), dom_name));
    162 
    163         if (winbindd_use_idmap_cache()
    164             && idmap_cache_find_sid2uid(sid, uid, &expired)) {
    165                 DEBUG(10, ("idmap_cache_find_sid2uid found %d%s\n",
    166                            (int)(*uid), expired ? " (expired)": ""));
    167                 if (expired && idmap_is_online()) {
    168                         DEBUG(10, ("revalidating expired entry\n"));
    169                         goto backend;
    170                 }
    171                 if ((*uid) == -1) {
    172                         DEBUG(10, ("Returning negative cache entry\n"));
    173                         return NT_STATUS_NONE_MAPPED;
    174                 }
    175                 DEBUG(10, ("Returning positive cache entry\n"));
    176                 return NT_STATUS_OK;
    177         }
    178 
    179 backend:
    180         map.sid = sid;
    181         map.xid.type = ID_TYPE_UID;     
    182 
    183         ret = idmap_backends_sid_to_unixid(dom_name, &map);
    184 
    185         if (!NT_STATUS_IS_OK(ret)) {
    186                 DEBUG(10, ("idmap_backends_sid_to_unixid failed: %s\n",
    187                            nt_errstr(ret)));
    188                 if (winbindd_use_idmap_cache()) {
    189                         idmap_cache_set_sid2uid(sid, -1);
    190                 }
    191                 return ret;
    192         }
    193 
    194         if (map.status != ID_MAPPED) {
    195                 DEBUG(10, ("sid [%s] is not mapped\n", sid_string_dbg(sid)));
    196                 if (winbindd_use_idmap_cache()) {
    197                         idmap_cache_set_sid2uid(sid, -1);
    198                 }
    199                 return NT_STATUS_NONE_MAPPED;
    200         }
    201 
    202         if (map.xid.type != ID_TYPE_UID) {
    203                 DEBUG(10, ("sid [%s] not mapped to a uid "
    204                            "[%u,%u,%u]\n",
    205                            sid_string_dbg(sid),
    206                            map.status,
    207                            map.xid.type,
    208                            map.xid.id));
    209                 if (winbindd_use_idmap_cache()) {
    210                         idmap_cache_set_sid2uid(sid, -1);
    211                 }
    212                 return NT_STATUS_NONE_MAPPED;
    213         }
    214 
    215         *uid = (uid_t)map.xid.id;
    216         if (winbindd_use_idmap_cache()) {
    217                 idmap_cache_set_sid2uid(sid, *uid);
    218         }
    219         return NT_STATUS_OK;
    220 }
    221 
    222 /*****************************************************************
    223  Returns the GID mapped to the given SID.
    224  If mapping is not possible or SID maps to a UID returns an error.
    225 *****************************************************************/ 
    226 
    227 NTSTATUS idmap_sid_to_gid(const char *domname, struct dom_sid *sid, gid_t *gid)
    228 {
    229         NTSTATUS ret;
    230         struct id_map map;
    231         bool expired;
    232 
    233         DEBUG(10,("idmap_sid_to_gid: sid = [%s], domain = '%s'\n",
    234                   sid_string_dbg(sid), domname));
    235 
    236         if (winbindd_use_idmap_cache()
    237             && idmap_cache_find_sid2gid(sid, gid, &expired)) {
    238                 DEBUG(10, ("idmap_cache_find_sid2gid found %d%s\n",
    239                            (int)(*gid), expired ? " (expired)": ""));
    240                 if (expired && idmap_is_online()) {
    241                         DEBUG(10, ("revalidating expired entry\n"));
    242                         goto backend;
    243                 }
    244                 if ((*gid) == -1) {
    245                         DEBUG(10, ("Returning negative cache entry\n"));
    246                         return NT_STATUS_NONE_MAPPED;
    247                 }
    248                 DEBUG(10, ("Returning positive cache entry\n"));
    249                 return NT_STATUS_OK;
    250         }
    251 
    252 backend:
    253         map.sid = sid;
    254         map.xid.type = ID_TYPE_GID;
    255 
    256         ret = idmap_backends_sid_to_unixid(domname, &map);
    257 
    258         if (!NT_STATUS_IS_OK(ret)) {
    259                 DEBUG(10, ("idmap_backends_sid_to_unixid failed: %s\n",
    260                            nt_errstr(ret)));
    261                 if (winbindd_use_idmap_cache()) {
    262                         idmap_cache_set_sid2gid(sid, -1);
    263                 }
    264                 return ret;
    265         }
    266 
    267         if (map.status != ID_MAPPED) {
    268                 DEBUG(10, ("sid [%s] is not mapped\n", sid_string_dbg(sid)));
    269                 if (winbindd_use_idmap_cache()) {
    270                         idmap_cache_set_sid2gid(sid, -1);
    271                 }
    272                 return NT_STATUS_NONE_MAPPED;
    273         }
    274 
    275         if (map.xid.type != ID_TYPE_GID) {
    276                 DEBUG(10, ("sid [%s] not mapped to a gid "
    277                            "[%u,%u,%u]\n",
    278                            sid_string_dbg(sid),
    279                            map.status,
    280                            map.xid.type,
    281                            map.xid.id));
    282                 if (winbindd_use_idmap_cache()) {
    283                         idmap_cache_set_sid2gid(sid, -1);
    284                 }
    285                 return NT_STATUS_NONE_MAPPED;
    286         }
    287 
    288         *gid = map.xid.id;
    289         if (winbindd_use_idmap_cache()) {
    290                 idmap_cache_set_sid2gid(sid, *gid);
    291         }
     152                idmap_cache_set_sid2unixid(sid, &map.xid);
     153        }
     154
    292155        return NT_STATUS_OK;
    293156}
     
    311174        return true;
    312175}
     176
     177/**
     178 * Helper for unixids_to_sids: find entry by id in mapping array,
     179 * search up to IDMAP_AD_MAX_IDS entries
     180 */
     181struct id_map *idmap_find_map_by_id(struct id_map **maps, enum id_type type,
     182                                    uint32_t id)
     183{
     184        int i;
     185
     186        for (i = 0; i < IDMAP_LDAP_MAX_IDS; i++) {
     187                if (maps[i] == NULL) { /* end of the run */
     188                        return NULL;
     189                }
     190                if ((maps[i]->xid.type == type) && (maps[i]->xid.id == id)) {
     191                        return maps[i];
     192                }
     193        }
     194
     195        return NULL;
     196}
     197
     198/**
     199 * Helper for sids_to_unix_ids: find entry by SID in mapping array,
     200 * search up to IDMAP_AD_MAX_IDS entries
     201 */
     202struct id_map *idmap_find_map_by_sid(struct id_map **maps, struct dom_sid *sid)
     203{
     204        int i;
     205
     206        for (i = 0; i < IDMAP_LDAP_MAX_IDS; i++) {
     207                if (maps[i] == NULL) { /* end of the run */
     208                        return NULL;
     209                }
     210                if (dom_sid_equal(maps[i]->sid, sid)) {
     211                        return maps[i];
     212                }
     213        }
     214
     215        return NULL;
     216}
     217
     218char *idmap_fetch_secret(const char *backend, const char *domain,
     219                         const char *identity)
     220{
     221        char *tmp, *ret;
     222        int r;
     223
     224        r = asprintf(&tmp, "IDMAP_%s_%s", backend, domain);
     225
     226        if (r < 0)
     227                return NULL;
     228
     229        /* make sure the key is case insensitive */
     230        if (!strupper_m(tmp)) {
     231                SAFE_FREE(tmp);
     232                return NULL;
     233        }
     234
     235        ret = secrets_fetch_generic(tmp, identity);
     236
     237        SAFE_FREE(tmp);
     238
     239        return ret;
     240}
  • vendor/current/source3/winbindd/nss_info.c

    r740 r988  
    6767
    6868        if ( nss_get_backend(name) ) {
    69                 DEBUG(0,("smb_register_idmap_nss: idmap module %s "
     69                DEBUG(5,("smb_register_idmap_nss: idmap module %s "
    7070                         "already registered!\n", name));
    7171                return NT_STATUS_OBJECT_NAME_COLLISION;
     
    119119        struct nss_domain_entry *nss_domain;
    120120
    121         nss_domain = TALLOC_ZERO_P(nss_domain_list, struct nss_domain_entry);
     121        nss_domain = talloc_zero(nss_domain_list, struct nss_domain_entry);
    122122        if (!nss_domain) {
    123123                DEBUG(0, ("nss_domain_list_add_domain: talloc() failure!\n"));
  • vendor/current/source3/winbindd/nss_info_template.c

    r740 r988  
    4949        *homedir = talloc_strdup( ctx, lp_template_homedir() );
    5050        *shell   = talloc_strdup( ctx, lp_template_shell() );
    51         *gecos   = NULL;
    5251
    5352        if ( !*homedir || !*shell ) {
  • vendor/current/source3/winbindd/wb_dsgetdcname.c

    r740 r988  
    2020#include "includes.h"
    2121#include "winbindd.h"
    22 #include "librpc/gen_ndr/ndr_wbint_c.h"
     22#include "librpc/gen_ndr/ndr_winbind_c.h"
    2323
    2424struct wb_dsgetdcname_state {
     
    4646        }
    4747
    48         if (strequal(domain_name, "BUILTIN")
    49             || strequal(domain_name, get_global_sam_name())) {
     48        if (strequal(domain_name, "BUILTIN")) {
    5049                /*
    51                  * Two options here: Give back our own address, or say there's
    52                  * nobody around. Right now opting for the latter, one measure
    53                  * to prevent the loopback connects. This might change if
    54                  * needed.
     50                 * This makes no sense
    5551                 */
    5652                tevent_req_nterror(req, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND);
    5753                return tevent_req_post(req, ev);
     54        }
     55
     56        if (strequal(domain_name, get_global_sam_name())) {
     57                int role = lp_server_role();
     58                if ( role != ROLE_ACTIVE_DIRECTORY_DC ) {
     59                        /*
     60                         * Two options here: Give back our own address, or say there's
     61                         * nobody around. Right now opting for the latter, one measure
     62                         * to prevent the loopback connects. This might change if
     63                         * needed.
     64                         */
     65                        tevent_req_nterror(req, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND);
     66                        return tevent_req_post(req, ev);
     67                }
    5868        }
    5969
  • vendor/current/source3/winbindd/wb_fill_pwent.c

    r740 r988  
    2020#include "includes.h"
    2121#include "winbindd.h"
    22 #include "librpc/gen_ndr/ndr_wbint_c.h"
     22#include "librpc/gen_ndr/ndr_winbind_c.h"
    2323
    2424struct wb_fill_pwent_state {
     
    3030static bool fillup_pw_field(const char *lp_template,
    3131                            const char *username,
     32                            const char *grpname,
    3233                            const char *domname,
    3334                            uid_t uid,
     
    3738
    3839static void wb_fill_pwent_sid2uid_done(struct tevent_req *subreq);
    39 static void wb_fill_pwent_sid2gid_done(struct tevent_req *subreq);
     40static void wb_fill_pwent_getgrsid_done(struct tevent_req *subreq);
    4041
    4142struct tevent_req *wb_fill_pwent_send(TALLOC_CTX *mem_ctx,
     
    5556        state->pw = pw;
    5657
    57         subreq = wb_sid2uid_send(state, state->ev, &state->info->user_sid);
     58        subreq = wb_sids2xids_send(state, state->ev, &state->info->user_sid, 1);
    5859        if (tevent_req_nomem(subreq, req)) {
    5960                return tevent_req_post(req, ev);
     
    7071                req, struct wb_fill_pwent_state);
    7172        NTSTATUS status;
    72 
    73         status = wb_sid2uid_recv(subreq, &state->pw->pw_uid);
     73        struct unixid xids[1];
     74
     75        status = wb_sids2xids_recv(subreq, xids, ARRAY_SIZE(xids));
    7476        TALLOC_FREE(subreq);
    7577        if (tevent_req_nterror(req, status)) {
     
    7779        }
    7880
    79         subreq = wb_sid2gid_send(state, state->ev, &state->info->group_sid);
     81        /*
     82         * We are filtering further down in sids2xids, but that filtering
     83         * depends on the actual type of the sid handed in (as determined
     84         * by lookupsids). Here we need to filter for the type of object
     85         * actually requested, in this case uid.
     86         */
     87        if (!(xids[0].type == ID_TYPE_UID || xids[0].type == ID_TYPE_BOTH)) {
     88                tevent_req_nterror(req, NT_STATUS_NONE_MAPPED);
     89                return;
     90        }
     91
     92        state->pw->pw_uid = (uid_t)xids[0].id;
     93
     94        subreq = wb_getgrsid_send(state, state->ev, &state->info->group_sid, 0);
    8095        if (tevent_req_nomem(subreq, req)) {
    8196                return;
    8297        }
    83         tevent_req_set_callback(subreq, wb_fill_pwent_sid2gid_done, req);
    84 }
    85 
    86 static void wb_fill_pwent_sid2gid_done(struct tevent_req *subreq)
     98        tevent_req_set_callback(subreq, wb_fill_pwent_getgrsid_done, req);
     99}
     100
     101static void wb_fill_pwent_getgrsid_done(struct tevent_req *subreq)
    87102{
    88103        struct tevent_req *req = tevent_req_callback_data(
     
    91106                req, struct wb_fill_pwent_state);
    92107        struct winbindd_domain *domain;
    93         char *dom_name;
     108        const char *dom_name;
     109        const char *grp_name;
    94110        fstring user_name, output_username;
    95111        char *mapped_name = NULL;
     112        struct talloc_dict *members;
     113        TALLOC_CTX *tmp_ctx = talloc_stackframe();
    96114        NTSTATUS status;
    97 
    98         status = wb_sid2gid_recv(subreq, &state->pw->pw_gid);
     115        bool ok;
     116
     117        /* xid handling is done in getgrsid() */
     118        status = wb_getgrsid_recv(subreq,
     119                                  tmp_ctx,
     120                                  &dom_name,
     121                                  &grp_name,
     122                                  &state->pw->pw_gid,
     123                                  &members);
    99124        TALLOC_FREE(subreq);
    100125        if (tevent_req_nterror(req, status)) {
     126                talloc_free(tmp_ctx);
    101127                return;
    102128        }
     
    104130        domain = find_domain_from_sid_noinit(&state->info->user_sid);
    105131        if (domain == NULL) {
     132                talloc_free(tmp_ctx);
    106133                tevent_req_nterror(req, NT_STATUS_NO_SUCH_USER);
    107134                return;
     
    112139
    113140        fstrcpy(user_name, state->info->acct_name);
    114         strlower_m(user_name);
     141        if (!strlower_m(user_name)) {
     142                tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
     143                return;
     144        }
    115145        status = normalize_name_map(state, domain, user_name, &mapped_name);
    116146
     
    130160        }
    131161
    132         fstrcpy(state->pw->pw_name, output_username);
    133         fstrcpy(state->pw->pw_gecos, state->info->full_name);
     162        strlcpy(state->pw->pw_name,
     163                output_username,
     164                sizeof(state->pw->pw_name));
     165        /* FIXME The full_name can be longer than 255 chars */
     166        strlcpy(state->pw->pw_gecos,
     167                state->info->full_name != NULL ? state->info->full_name : "",
     168                sizeof(state->pw->pw_gecos));
    134169
    135170        /* Home directory and shell */
    136 
    137         if (!fillup_pw_field(lp_template_homedir(), user_name, dom_name,
    138                              state->pw->pw_uid, state->pw->pw_gid,
    139                              state->info->homedir, state->pw->pw_dir)) {
     171        ok = fillup_pw_field(lp_template_homedir(),
     172                             user_name,
     173                             grp_name,
     174                             dom_name,
     175                             state->pw->pw_uid,
     176                             state->pw->pw_gid,
     177                             state->info->homedir,
     178                             state->pw->pw_dir);
     179        if (!ok) {
     180                talloc_free(tmp_ctx);
    140181                tevent_req_nterror(req, NT_STATUS_NO_SUCH_USER);
    141182                return;
    142183        }
    143184
    144         if (!fillup_pw_field(lp_template_shell(), user_name, dom_name,
    145                              state->pw->pw_uid, state->pw->pw_gid,
    146                              state->info->shell, state->pw->pw_shell)) {
     185        ok = fillup_pw_field(lp_template_shell(),
     186                             user_name,
     187                             grp_name,
     188                             dom_name,
     189                             state->pw->pw_uid,
     190                             state->pw->pw_gid,
     191                             state->info->shell,
     192                             state->pw->pw_shell);
     193        talloc_free(tmp_ctx);
     194        if (!ok) {
    147195                tevent_req_nterror(req, NT_STATUS_NO_SUCH_USER);
    148196                return;
     
    163211static bool fillup_pw_field(const char *lp_template,
    164212                            const char *username,
     213                            const char *grpname,
    165214                            const char *domname,
    166215                            uid_t uid,
     
    169218                            fstring out)
    170219{
    171         char *templ;
     220        const char *templ;
     221        char *result;
    172222
    173223        if (out == NULL)
    174224                return False;
    175225
    176         /* The substitution of %U and %D in the 'template
    177            homedir' is done by talloc_sub_specified() below.
    178            If we have an in string (which means the value has already
    179            been set in the nss_info backend), then use that.
    180            Otherwise use the template value passed in. */
     226        templ = lp_template;
    181227
    182228        if ((in != NULL) && (in[0] != '\0') && (lp_security() == SEC_ADS)) {
    183                 templ = talloc_sub_specified(talloc_tos(), in,
    184                                              username, domname,
    185                                              uid, gid);
    186         } else {
    187                 templ = talloc_sub_specified(talloc_tos(), lp_template,
    188                                              username, domname,
    189                                              uid, gid);
    190         }
    191 
    192         if (!templ)
     229                /*
     230                 * The backend has already filled in the required value. Use
     231                 * that instead of the template.
     232                 */
     233                templ = in;
     234        }
     235
     236        result = talloc_sub_specified(talloc_tos(), templ,
     237                                      username, grpname, domname,
     238                                      uid, gid);
     239        if (result == NULL) {
    193240                return False;
    194 
    195         safe_strcpy(out, templ, sizeof(fstring) - 1);
    196         TALLOC_FREE(templ);
     241        }
     242
     243        fstrcpy(out, result);
     244        TALLOC_FREE(result);
    197245
    198246        return True;
  • vendor/current/source3/winbindd/wb_getgrsid.c

    r740 r988  
    2020#include "includes.h"
    2121#include "winbindd.h"
    22 #include "librpc/gen_ndr/ndr_wbint_c.h"
     22#include "librpc/gen_ndr/ndr_winbind_c.h"
    2323#include "../libcli/security/security.h"
    2424
     
    9292        case SID_NAME_ALIAS:
    9393        case SID_NAME_WKN_GRP:
     94        /*
     95         * also treat user-type SIDS (they might map to ID_TYPE_BOTH)
     96         */
     97        case SID_NAME_USER:
     98        case SID_NAME_COMPUTER:
    9499                break;
    95100        default:
     
    98103        }
    99104
    100         subreq = wb_sid2gid_send(state, state->ev, &state->sid);
     105        subreq = wb_sids2xids_send(state, state->ev, &state->sid, 1);
    101106        if (tevent_req_nomem(subreq, req)) {
    102107                return;
     
    112117                req, struct wb_getgrsid_state);
    113118        NTSTATUS status;
    114 
    115         status = wb_sid2gid_recv(subreq, &state->gid);
     119        struct unixid xids[1];
     120
     121        status = wb_sids2xids_recv(subreq, xids, ARRAY_SIZE(xids));
    116122        TALLOC_FREE(subreq);
    117123        if (tevent_req_nterror(req, status)) {
    118124                return;
    119125        }
     126
     127        /*
     128         * We are filtering further down in sids2xids, but that filtering
     129         * depends on the actual type of the sid handed in (as determined
     130         * by lookupsids). Here we need to filter for the type of object
     131         * actually requested, in this case uid.
     132         */
     133        if (!(xids[0].type == ID_TYPE_GID || xids[0].type == ID_TYPE_BOTH)) {
     134                tevent_req_nterror(req, NT_STATUS_NONE_MAPPED);
     135                return;
     136        }
     137
     138        state->gid = (gid_t)xids[0].id;
     139
     140        if (state->type == SID_NAME_USER || state->type == SID_NAME_COMPUTER) {
     141                /*
     142                 * special treatment for a user sid that is
     143                 * mapped to ID_TYPE_BOTH:
     144                 * create a group with the sid/xid as only member
     145                 */
     146                const char *name;
     147
     148                if (xids[0].type != ID_TYPE_BOTH) {
     149                        tevent_req_nterror(req, NT_STATUS_NO_SUCH_GROUP);
     150                        return;
     151                }
     152
     153                state->members = talloc_dict_init(state);
     154                if (tevent_req_nomem(state->members, req)) {
     155                        return;
     156                }
     157
     158                name = fill_domain_username_talloc(talloc_tos(),
     159                                                   state->domname,
     160                                                   state->name,
     161                                                   true /* can_assume */);
     162                if (tevent_req_nomem(name, req)) {
     163                        return;
     164                }
     165
     166                status = add_wbint_Principal_to_dict(talloc_tos(),
     167                                                     &state->sid,
     168                                                     &name,
     169                                                     state->type,
     170                                                     state->members);
     171                if (!NT_STATUS_IS_OK(status)) {
     172                        tevent_req_nterror(req, status);
     173                        return;
     174                }
     175
     176                tevent_req_done(req);
     177                return;
     178        }
     179
     180        /*
     181         * the "regular" case of a group type sid.
     182         */
     183
    120184        subreq = wb_group_members_send(state, state->ev, &state->sid,
    121185                                       state->type, state->max_nesting);
  • vendor/current/source3/winbindd/wb_getpwsid.c

    r740 r988  
    2020#include "includes.h"
    2121#include "winbindd.h"
    22 #include "librpc/gen_ndr/ndr_wbint_c.h"
     22#include "librpc/gen_ndr/ndr_winbind_c.h"
    2323#include "../libcli/security/security.h"
    2424
    2525struct wb_getpwsid_state {
    26         struct winbindd_domain *user_domain;
    2726        struct tevent_context *ev;
    2827        struct dom_sid sid;
     
    5150        state->pw = pw;
    5251
    53         state->user_domain = find_domain_from_sid_noinit(user_sid);
    54         if (state->user_domain == NULL) {
    55                 tevent_req_nterror(req, NT_STATUS_NO_SUCH_USER);
    56                 return tevent_req_post(req, ev);
    57         }
    58 
    5952        subreq = wb_queryuser_send(state, ev, &state->sid);
    6053        if (tevent_req_nomem(subreq, req)) {
     
    7568        status = wb_queryuser_recv(subreq, state, &state->userinfo);
    7669        TALLOC_FREE(subreq);
    77         if (tevent_req_nterror(req, status)) {
    78                 return;
    79         }
    80 
    81         if ((state->userinfo->acct_name != NULL)
    82             && (state->userinfo->acct_name[0] != '\0')) {
     70        if (NT_STATUS_IS_OK(status)
     71            && (state->userinfo->acct_name != NULL)
     72            && (state->userinfo->acct_name[0] != '\0'))
     73        {
    8374                /*
    84                  * QueryUser got us a name, let's got directly to the
     75                 * QueryUser got us a name, let's go directly to the
    8576                 * fill_pwent step
    8677                 */
     
    9586
    9687        /*
    97          * QueryUser didn't get us a name, do it via LSA.
     88         * Either query_user did not succeed, or it
     89         * succeeded but did not return an acct_name.
     90         * (TODO: Can this happen at all???)
     91         * ==> Try lsa_lookupsids.
    9892         */
    99         subreq = wb_lookupsid_send(state, state->ev,
    100                                    &state->userinfo->user_sid);
     93        if (state->userinfo == NULL) {
     94                state->userinfo = talloc_zero(state, struct wbint_userinfo);
     95                if (tevent_req_nomem(state->userinfo, req)) {
     96                        return;
     97                }
     98
     99                /* a successful query_user call would have filled these */
     100                sid_copy(&state->userinfo->user_sid, &state->sid);
     101                state->userinfo->homedir = NULL;
     102                state->userinfo->shell = NULL;
     103                state->userinfo->primary_gid = (gid_t)-1;
     104        }
     105
     106        subreq = wb_lookupsid_send(state, state->ev, &state->sid);
    101107        if (tevent_req_nomem(subreq, req)) {
    102108                return;
     
    121127                return;
    122128        }
     129
     130        switch (type) {
     131        case SID_NAME_USER:
     132        case SID_NAME_COMPUTER:
     133                /*
     134                 * user case: we only need the account name from lookup_sids
     135                 */
     136                break;
     137        case SID_NAME_DOM_GRP:
     138        case SID_NAME_ALIAS:
     139        case SID_NAME_WKN_GRP:
     140                /*
     141                 * also treat group-type SIDs (they might map to ID_TYPE_BOTH)
     142                 */
     143                sid_copy(&state->userinfo->group_sid, &state->sid);
     144                break;
     145        default:
     146                tevent_req_nterror(req, NT_STATUS_NO_SUCH_USER);
     147                return;
     148        }
     149
    123150        subreq = wb_fill_pwent_send(state, state->ev, state->userinfo,
    124151                                    state->pw);
     
    144171NTSTATUS wb_getpwsid_recv(struct tevent_req *req)
    145172{
    146         NTSTATUS status;
    147 
    148         if (tevent_req_is_nterror(req, &status)) {
    149                 return status;
    150         }
    151         return NT_STATUS_OK;
     173        return tevent_req_simple_recv_ntstatus(req);
    152174}
  • vendor/current/source3/winbindd/wb_gettoken.c

    r740 r988  
    2020#include "includes.h"
    2121#include "winbindd.h"
    22 #include "librpc/gen_ndr/ndr_wbint_c.h"
     22#include "librpc/gen_ndr/ndr_winbind_c.h"
    2323#include "../libcli/security/security.h"
    2424#include "passdb/machine_sid.h"
  • vendor/current/source3/winbindd/wb_gid2sid.c

    r740 r988  
    2020#include "includes.h"
    2121#include "winbindd.h"
    22 #include "librpc/gen_ndr/ndr_wbint_c.h"
     22#include "librpc/gen_ndr/ndr_winbind_c.h"
    2323#include "idmap_cache.h"
    2424#include "idmap.h"
     
    2727struct wb_gid2sid_state {
    2828        struct tevent_context *ev;
    29         char *dom_name;
    3029        struct dom_sid sid;
    3130};
     
    3938        struct tevent_req *req, *subreq;
    4039        struct wb_gid2sid_state *state;
    41         struct winbindd_domain *domain;
    4240        struct winbindd_child *child;
    4341        bool expired;
     
    6563        }
    6664
    67         state->dom_name = NULL;
    68 
    69         for (domain = domain_list(); domain != NULL; domain = domain->next) {
    70                 if (domain->have_idmap_config
    71                     && (gid >= domain->id_range_low)
    72                     && (gid <= domain->id_range_high)) {
    73                         state->dom_name = domain->name;
    74                         break;
    75                 }
    76         }
    77 
    7865        child = idmap_child();
    7966
    8067        subreq = dcerpc_wbint_Gid2Sid_send(
    81                 state, ev, child->binding_handle, state->dom_name,
     68                state, ev, child->binding_handle,
    8269                gid, &state->sid);
    8370        if (tevent_req_nomem(subreq, req)) {
  • vendor/current/source3/winbindd/wb_group_members.c

    r746 r988  
    2020#include "includes.h"
    2121#include "winbindd.h"
    22 #include "librpc/gen_ndr/ndr_wbint_c.h"
     22#include "librpc/gen_ndr/ndr_winbind_c.h"
    2323#include "../librpc/gen_ndr/ndr_security.h"
    2424#include "../libcli/security/security.h"
     
    140140                                                 struct wbint_Principal *groups)
    141141{
    142         struct tevent_req *req, *subreq;
     142        struct tevent_req *req, *subreq = NULL;
    143143        struct wb_groups_members_state *state;
    144144        NTSTATUS status;
     
    291291                                         int max_depth)
    292292{
    293         struct tevent_req *req, *subreq;
     293        struct tevent_req *req, *subreq = NULL;
    294294        struct wb_group_members_state *state;
    295295        NTSTATUS status;
     
    350350}
    351351
     352
     353/**
     354 * compose a wbint_Principal and add it to  talloc_dict
     355 *
     356 * NOTE: this has a side effect: *name needs to be talloc'd
     357 * and it is talloc_move'd to mem_ctx.
     358 */
     359NTSTATUS add_wbint_Principal_to_dict(TALLOC_CTX *mem_ctx,
     360                                     struct dom_sid *sid,
     361                                     const char **name,
     362                                     enum lsa_SidType type,
     363                                     struct talloc_dict *dict)
     364{
     365        struct wbint_Principal *m;
     366        DATA_BLOB key;
     367        bool ok;
     368
     369        m = talloc(mem_ctx, struct wbint_Principal);
     370        if (m == NULL) {
     371                return NT_STATUS_NO_MEMORY;
     372        }
     373
     374        sid_copy(&m->sid, sid);
     375        m->name = talloc_move(m, name);
     376        m->type = type;
     377
     378        key = data_blob_const(&m->sid, sizeof(m->sid));
     379
     380        ok = talloc_dict_set(dict, key, &m);
     381        if (!ok) {
     382                return NT_STATUS_NO_MEMORY;
     383        }
     384
     385        return NT_STATUS_OK;
     386}
     387
    352388static void wb_group_members_done(struct tevent_req *subreq)
    353389{
     
    356392        struct wb_group_members_state *state = tevent_req_data(
    357393                req, struct wb_group_members_state);
    358         int i, num_groups, new_users, new_groups;
     394        int i, num_groups, new_groups;
    359395        int num_members = 0;
    360396        struct wbint_Principal *members = NULL;
     
    367403        }
    368404
    369         new_users = new_groups = 0;
     405        new_groups = 0;
    370406        for (i=0; i<num_members; i++) {
    371407                switch (members[i].type) {
     
    398434                         * Add a copy of members[i] to state->users
    399435                         */
    400                         struct wbint_Principal *m;
    401                         struct dom_sid *sid;
    402                         DATA_BLOB key;
    403 
    404                         m = talloc(talloc_tos(), struct wbint_Principal);
    405                         if (tevent_req_nomem(m, req)) {
     436                        status = add_wbint_Principal_to_dict(talloc_tos(),
     437                                                             &members[i].sid,
     438                                                             &members[i].name,
     439                                                             members[i].type,
     440                                                             state->users);
     441                        if (tevent_req_nterror(req, status)) {
    406442                                return;
    407443                        }
    408                         sid_copy(&m->sid, &members[i].sid);
    409                         m->name = talloc_move(m, &members[i].name);
    410                         m->type = members[i].type;
    411 
    412                         sid = &members[i].sid;
    413                         key = data_blob_const(
    414                                 sid, ndr_size_dom_sid(sid, 0));
    415 
    416                         if (!talloc_dict_set(state->users, key, &m)) {
    417                                 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
    418                                 return;
    419                         }
     444
    420445                        break;
    421446                }
  • vendor/current/source3/winbindd/wb_lookupname.c

    r740 r988  
    2020#include "includes.h"
    2121#include "winbindd.h"
    22 #include "librpc/gen_ndr/ndr_wbint_c.h"
     22#include "librpc/gen_ndr/ndr_winbind_c.h"
    2323#include "../libcli/security/security.h"
    2424
  • vendor/current/source3/winbindd/wb_lookupsid.c

    r740 r988  
    2020#include "includes.h"
    2121#include "winbindd.h"
    22 #include "librpc/gen_ndr/ndr_wbint_c.h"
     22#include "librpc/gen_ndr/ndr_winbind_c.h"
    2323#include "../libcli/security/security.h"
    2424
  • vendor/current/source3/winbindd/wb_lookupsids.c

    r860 r988  
    2020#include "includes.h"
    2121#include "winbindd.h"
    22 #include "librpc/gen_ndr/ndr_wbint_c.h"
     22#include "librpc/gen_ndr/ndr_winbind_c.h"
    2323#include "../libcli/security/security.h"
    2424#include "passdb/machine_sid.h"
     
    124124        state->num_sids = num_sids;
    125125
    126         state->single_sids = TALLOC_ARRAY(state, uint32_t, num_sids);
     126        state->single_sids = talloc_array(state, uint32_t, num_sids);
    127127        if (tevent_req_nomem(state->single_sids, req)) {
    128128                return tevent_req_post(req, ev);
    129129        }
    130130
    131         state->res_domains = TALLOC_ZERO_P(state, struct lsa_RefDomainList);
     131        state->res_domains = talloc_zero(state, struct lsa_RefDomainList);
    132132        if (tevent_req_nomem(state->res_domains, req)) {
    133133                return tevent_req_post(req, ev);
    134134        }
    135         state->res_domains->domains = TALLOC_ARRAY(
     135        state->res_domains->domains = talloc_array(
    136136                state->res_domains, struct lsa_DomainInfo, num_sids);
    137137        if (tevent_req_nomem(state->res_domains->domains, req)) {
     
    139139        }
    140140
    141         state->res_names = TALLOC_ZERO_P(state, struct lsa_TransNameArray);
     141        state->res_names = talloc_zero(state, struct lsa_TransNameArray);
    142142        if (tevent_req_nomem(state->res_names, req)) {
    143143                return tevent_req_post(req, ev);
    144144        }
    145         state->res_names->names = TALLOC_ARRAY(
     145        state->res_names->names = talloc_array(
    146146                state->res_names, struct lsa_TranslatedName, num_sids);
    147147        if (tevent_req_nomem(state->res_names->names, req)) {
     
    186186                d = &state->domains[state->domains_done];
    187187
    188                 if (sid_check_is_domain(&d->sid)) {
     188                if (sid_check_is_our_sam(&d->sid)) {
    189189                        state->rids.num_rids = d->sids.num_sids;
    190                         state->rids.rids = TALLOC_ARRAY(state, uint32_t,
     190                        state->rids.rids = talloc_array(state, uint32_t,
    191191                                                        state->rids.num_rids);
    192192                        if (tevent_req_nomem(state->rids.rids, req)) {
     
    256256        }
    257257
    258         if (sid_check_is_in_our_domain(sid)) {
     258        if (sid_check_is_in_our_sam(sid)) {
    259259                /*
    260260                 * Passdb lookup via lookuprids
     
    321321        }
    322322
    323         wb_domain = find_domain_from_sid_noinit(sid);
     323        wb_domain = find_lookup_domain_from_sid(sid);
    324324        if (wb_domain == NULL) {
    325325                return NULL;
    326326        }
    327327
    328         domains = TALLOC_REALLOC_ARRAY(
     328        domains = talloc_realloc(
    329329                mem_ctx, domains, struct wb_lookupsids_domain, num_domains+1);
    330330        if (domains == NULL) {
     
    338338        domain->domain = wb_domain;
    339339
    340         domain->sids.sids = TALLOC_ARRAY(domains, struct lsa_SidPtr, num_sids);
     340        domain->sids.sids = talloc_array(domains, struct lsa_SidPtr, num_sids);
    341341        if (domains->sids.sids == NULL) {
    342342                goto fail;
     
    344344        domain->sids.num_sids = 0;
    345345
    346         domain->sid_indexes = TALLOC_ARRAY(domains, uint32_t, num_sids);
     346        domain->sid_indexes = talloc_array(domains, uint32_t, num_sids);
    347347        if (domain->sid_indexes == NULL) {
    348348                TALLOC_FREE(domain->sids.sids);
     
    355355         * Realloc to the state it was in before
    356356         */
    357         *pdomains = TALLOC_REALLOC_ARRAY(
     357        *pdomains = talloc_realloc(
    358358                mem_ctx, domains, struct wb_lookupsids_domain, num_domains);
    359359        return NULL;
     
    368368
    369369        for (i=0; i<list->count; i++) {
    370                 if (sid_equal(domain->sid, list->domains[i].sid)) {
     370                if (dom_sid_equal(domain->sid, list->domains[i].sid)) {
    371371                        *idx = i;
    372372                        return true;
     
    485485                            state->res_domains, state->res_names,
    486486                            res_sid_index)) {
    487                         tevent_req_nomem(NULL, req);
     487                        tevent_req_oom(req);
    488488                        return;
    489489                }
     
    548548                    state->res_domains, state->res_names,
    549549                    res_sid_index)) {
    550                 tevent_req_nomem(NULL, req);
     550                tevent_req_oom(req);
    551551                return;
    552552        }
     
    623623                            state->res_domains, state->res_names,
    624624                            res_sid_index)) {
    625                         tevent_req_nomem(NULL, req);
     625                        tevent_req_oom(req);
    626626                        return;
    627627                }
     
    649649         *
    650650         */
    651         SMB_ASSERT(state->res_names->count == state->num_sids);
     651        if (state->res_names->count != state->num_sids) {
     652                DEBUG(0, ("res_names->count = %d, expected %d\n",
     653                          state->res_names->count, state->num_sids));
     654                return NT_STATUS_INTERNAL_ERROR;
     655        }
    652656
    653657        /*
  • vendor/current/source3/winbindd/wb_lookupuseraliases.c

    r740 r988  
    2020#include "includes.h"
    2121#include "winbindd.h"
    22 #include "librpc/gen_ndr/ndr_wbint_c.h"
     22#include "librpc/gen_ndr/ndr_winbind_c.h"
    2323
    2424struct wb_lookupuseraliases_state {
     
    4545        }
    4646        state->sids.num_sids = num_sids;
    47         state->sids.sids = CONST_DISCARD(struct dom_sid *, sids);
     47        state->sids.sids = discard_const_p(struct dom_sid, sids);
    4848
    4949        subreq = dcerpc_wbint_LookupUserAliases_send(
  • vendor/current/source3/winbindd/wb_lookupusergroups.c

    r740 r988  
    2020#include "includes.h"
    2121#include "winbindd.h"
    22 #include "librpc/gen_ndr/ndr_wbint_c.h"
     22#include "librpc/gen_ndr/ndr_winbind_c.h"
    2323#include "../libcli/security/security.h"
    2424
     
    3838        struct tevent_req *req, *subreq;
    3939        struct wb_lookupusergroups_state *state;
     40        NTSTATUS status;
    4041
    4142        req = tevent_req_create(mem_ctx, &state,
     
    4546        }
    4647        sid_copy(&state->sid, sid);
     48
     49        status = lookup_usergroups_cached(NULL,
     50                                          state,
     51                                          &state->sid,
     52                                          &state->sids.num_sids,
     53                                          &state->sids.sids);
     54        if (NT_STATUS_IS_OK(status)) {
     55                tevent_req_done(req);
     56                return tevent_req_post(req, ev);
     57        }
    4758
    4859        subreq = dcerpc_wbint_LookupUserGroups_send(
  • vendor/current/source3/winbindd/wb_next_grent.c

    r740 r988  
    2020#include "includes.h"
    2121#include "winbindd.h"
    22 #include "librpc/gen_ndr/ndr_wbint_c.h"
     22#include "librpc/gen_ndr/ndr_winbind_c.h"
    2323#include "passdb/machine_sid.h"
    2424
     
    2727        int max_nesting;
    2828        struct getgrent_state *gstate;
    29         struct wbint_Principals next_groups;
    3029        struct winbindd_gr *gr;
    3130        struct talloc_dict *members;
     
    3534static void wb_next_grent_getgrsid_done(struct tevent_req *subreq);
    3635
     36static void wb_next_grent_send_do(struct tevent_req *req,
     37                                  struct wb_next_grent_state *state)
     38{
     39        struct tevent_req *subreq;
     40
     41        if (state->gstate->next_group >= state->gstate->num_groups) {
     42                TALLOC_FREE(state->gstate->groups);
     43
     44                state->gstate->domain = wb_next_domain(state->gstate->domain);
     45                if (state->gstate->domain == NULL) {
     46                        tevent_req_nterror(req, NT_STATUS_NO_MORE_ENTRIES);
     47                        return;
     48                }
     49
     50                subreq = wb_query_group_list_send(state, state->ev,
     51                                                  state->gstate->domain);
     52                if (tevent_req_nomem(subreq, req)) {
     53                        return;
     54                }
     55                tevent_req_set_callback(subreq, wb_next_grent_fetch_done, req);
     56                return;
     57        }
     58
     59        subreq = wb_getgrsid_send(
     60                state, state->ev,
     61                &state->gstate->groups[state->gstate->next_group].sid,
     62                state->max_nesting);
     63        if (tevent_req_nomem(subreq, req)) {
     64                return;
     65        }
     66        tevent_req_set_callback(subreq, wb_next_grent_getgrsid_done, req);
     67}
     68
    3769struct tevent_req *wb_next_grent_send(TALLOC_CTX *mem_ctx,
    3870                                      struct tevent_context *ev,
     
    4173                                      struct winbindd_gr *gr)
    4274{
    43         struct tevent_req *req, *subreq;
     75        struct tevent_req *req;
    4476        struct wb_next_grent_state *state;
    4577
     
    5385        state->max_nesting = max_nesting;
    5486
    55         if (state->gstate->next_group >= state->gstate->num_groups) {
    56                 TALLOC_FREE(state->gstate->groups);
    57 
    58                 if (state->gstate->domain == NULL) {
    59                         state->gstate->domain = domain_list();
    60                 } else {
    61                         state->gstate->domain = state->gstate->domain->next;
    62                 }
    63 
    64                 if ((state->gstate->domain != NULL)
    65                     && sid_check_is_domain(&state->gstate->domain->sid)) {
    66                         state->gstate->domain = state->gstate->domain->next;
    67                 }
    68 
    69                 if (state->gstate->domain == NULL) {
    70                         tevent_req_nterror(req, NT_STATUS_NO_MORE_ENTRIES);
    71                         return tevent_req_post(req, ev);
    72                 }
    73                 subreq = dcerpc_wbint_QueryGroupList_send(
    74                         state, state->ev, dom_child_handle(state->gstate->domain),
    75                         &state->next_groups);
    76                 if (tevent_req_nomem(subreq, req)) {
    77                         return tevent_req_post(req, ev);
    78                 }
    79                 tevent_req_set_callback(subreq, wb_next_grent_fetch_done, req);
    80                 return req;
     87        wb_next_grent_send_do(req, state);
     88        if (!tevent_req_is_in_progress(req)) {
     89                return tevent_req_post(req, ev);
    8190        }
    8291
    83         subreq = wb_getgrsid_send(
    84                 state, state->ev,
    85                 &state->gstate->groups[state->gstate->next_group].sid,
    86                 state->max_nesting);
    87         if (tevent_req_nomem(subreq, req)) {
    88                 return tevent_req_post(req, ev);
    89         }
    90         tevent_req_set_callback(subreq, wb_next_grent_getgrsid_done, req);
    9192        return req;
    9293}
     
    9899        struct wb_next_grent_state *state = tevent_req_data(
    99100                req, struct wb_next_grent_state);
    100         NTSTATUS status, result;
     101        NTSTATUS status;
    101102
    102         status = dcerpc_wbint_QueryGroupList_recv(subreq, state, &result);
     103        status = wb_query_group_list_recv(subreq, state->gstate,
     104                                          &state->gstate->num_groups,
     105                                          &state->gstate->groups);
    103106        TALLOC_FREE(subreq);
    104         if (tevent_req_nterror(req, status)) {
     107        if (!NT_STATUS_IS_OK(status)) {
    105108                /* Ignore errors here, just log it */
    106                 DEBUG(10, ("query_user_list for domain %s returned %s\n",
    107                            state->gstate->domain->name,
    108                            nt_errstr(status)));
    109                 return;
    110         }
    111         if (!NT_STATUS_IS_OK(result)) {
    112                 /* Ignore errors here, just log it */
    113                 DEBUG(10, ("query_user_list for domain %s returned %s/%s\n",
    114                            state->gstate->domain->name,
    115                            nt_errstr(status), nt_errstr(result)));
    116                 tevent_req_nterror(req, result);
    117                 return;
    118         }
    119 
    120         state->gstate->num_groups = state->next_groups.num_principals;
    121         state->gstate->groups = talloc_move(
    122                 state->gstate, &state->next_groups.principals);
    123 
    124         if (state->gstate->num_groups == 0) {
    125                 state->gstate->domain = state->gstate->domain->next;
    126 
    127                 if ((state->gstate->domain != NULL)
    128                     && sid_check_is_domain(&state->gstate->domain->sid)) {
    129                         state->gstate->domain = state->gstate->domain->next;
    130                 }
    131 
    132                 if (state->gstate->domain == NULL) {
    133                         tevent_req_nterror(req, NT_STATUS_NO_MORE_ENTRIES);
    134                         return;
    135                 }
    136                 subreq = dcerpc_wbint_QueryGroupList_send(
    137                         state, state->ev, dom_child_handle(state->gstate->domain),
    138                         &state->next_groups);
    139                 if (tevent_req_nomem(subreq, req)) {
    140                         return;
    141                 }
    142                 tevent_req_set_callback(subreq, wb_next_grent_fetch_done, req);
    143                 return;
     109                DEBUG(10, ("query_group_list for domain %s returned %s\n",
     110                           state->gstate->domain->name, nt_errstr(status)));
     111                state->gstate->num_groups = 0;
    144112        }
    145113
    146114        state->gstate->next_group = 0;
    147115
    148         subreq = wb_getgrsid_send(
    149                 state, state->ev,
    150                 &state->gstate->groups[state->gstate->next_group].sid,
    151                 state->max_nesting);
    152         if (tevent_req_nomem(subreq, req)) {
    153                 return;
    154         }
    155         tevent_req_set_callback(subreq, wb_next_grent_getgrsid_done, req);
    156         return;
     116        wb_next_grent_send_do(req, state);
    157117}
    158118
     
    169129                                  &state->gr->gr_gid, &state->members);
    170130        TALLOC_FREE(subreq);
    171         if (tevent_req_nterror(req, status)) {
     131
     132        if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
     133                state->gstate->next_group += 1;
     134
     135                wb_next_grent_send_do(req, state);
     136
     137                return;
     138        } else if (tevent_req_nterror(req, status)) {
    172139                return;
    173140        }
     141
    174142        if (!fill_grent(talloc_tos(), state->gr, domname, name,
    175143                        state->gr->gr_gid)) {
  • vendor/current/source3/winbindd/wb_next_pwent.c

    r746 r988  
    2020#include "includes.h"
    2121#include "winbindd.h"
    22 #include "librpc/gen_ndr/ndr_wbint_c.h"
     22#include "librpc/gen_ndr/ndr_winbind_c.h"
    2323#include "passdb/machine_sid.h"
    2424
     
    3232static void wb_next_pwent_fill_done(struct tevent_req *subreq);
    3333
    34 static struct winbindd_domain *wb_next_find_domain(struct winbindd_domain *domain)
     34static void wb_next_pwent_send_do(struct tevent_req *req,
     35                                  struct wb_next_pwent_state *state)
    3536{
    36         if (domain == NULL) {
    37                 domain = domain_list();
    38         } else {
    39                 domain = domain->next;
     37        struct tevent_req *subreq;
     38
     39        if (state->gstate->next_user >= state->gstate->num_users) {
     40                TALLOC_FREE(state->gstate->users);
     41
     42                state->gstate->domain = wb_next_domain(state->gstate->domain);
     43                if (state->gstate->domain == NULL) {
     44                        tevent_req_nterror(req, NT_STATUS_NO_MORE_ENTRIES);
     45                        return;
     46                }
     47
     48                subreq = wb_query_user_list_send(state, state->ev,
     49                                                 state->gstate->domain);
     50                if (tevent_req_nomem(subreq, req)) {
     51                        return;
     52                }
     53
     54                tevent_req_set_callback(subreq, wb_next_pwent_fetch_done, req);
     55                return;
    4056        }
    4157
    42         if ((domain != NULL)
    43             && sid_check_is_domain(&domain->sid)) {
    44                 domain = domain->next;
     58        subreq = wb_fill_pwent_send(state, state->ev,
     59                                &state->gstate->users[state->gstate->next_user],
     60                                state->pw);
     61        if (tevent_req_nomem(subreq, req)) {
     62                return;
    4563        }
    4664
    47         if (domain == NULL) {
    48                 return NULL;
    49         }
    50 
    51         return domain;
     65        tevent_req_set_callback(subreq, wb_next_pwent_fill_done, req);
    5266}
    5367
     
    5771                                      struct winbindd_pw *pw)
    5872{
    59         struct tevent_req *req, *subreq;
     73        struct tevent_req *req;
    6074        struct wb_next_pwent_state *state;
    6175
     
    6882        state->pw = pw;
    6983
    70         if (state->gstate->next_user >= state->gstate->num_users) {
    71                 TALLOC_FREE(state->gstate->users);
    72 
    73                 state->gstate->domain = wb_next_find_domain(state->gstate->domain);
    74                 if (state->gstate->domain == NULL) {
    75                         tevent_req_nterror(req, NT_STATUS_NO_MORE_ENTRIES);
    76                         return tevent_req_post(req, ev);
    77                 }
    78                 subreq = wb_query_user_list_send(state, state->ev,
    79                                                  state->gstate->domain);
    80                 if (tevent_req_nomem(subreq, req)) {
    81                         return tevent_req_post(req, ev);
    82                 }
    83                 tevent_req_set_callback(subreq, wb_next_pwent_fetch_done, req);
    84                 return req;
     84        wb_next_pwent_send_do(req, state);
     85        if (!tevent_req_is_in_progress(req)) {
     86                return tevent_req_post(req, ev);
    8587        }
    8688
    87         subreq = wb_fill_pwent_send(
    88                 state, state->ev,
    89                 &state->gstate->users[state->gstate->next_user],
    90                 state->pw);
    91         if (tevent_req_nomem(subreq, req)) {
    92                 return tevent_req_post(req, ev);
    93         }
    94         tevent_req_set_callback(subreq, wb_next_pwent_fill_done, req);
    9589        return req;
    9690}
     
    116110        }
    117111
    118         if (state->gstate->num_users == 0) {
    119                 state->gstate->domain = state->gstate->domain->next;
    120 
    121                 if ((state->gstate->domain != NULL)
    122                     && sid_check_is_domain(&state->gstate->domain->sid)) {
    123                         state->gstate->domain = state->gstate->domain->next;
    124                 }
    125 
    126                 if (state->gstate->domain == NULL) {
    127                         tevent_req_nterror(req, NT_STATUS_NO_MORE_ENTRIES);
    128                         return;
    129                 }
    130                 subreq = wb_query_user_list_send(state, state->ev,
    131                                                  state->gstate->domain);
    132                 if (tevent_req_nomem(subreq, req)) {
    133                         return;
    134                 }
    135                 tevent_req_set_callback(subreq, wb_next_pwent_fetch_done, req);
    136                 return;
    137         }
    138 
    139112        state->gstate->next_user = 0;
    140113
    141         subreq = wb_fill_pwent_send(
    142                 state, state->ev,
    143                 &state->gstate->users[state->gstate->next_user],
    144                 state->pw);
    145         if (tevent_req_nomem(subreq, req)) {
    146                 return;
    147         }
    148         tevent_req_set_callback(subreq, wb_next_pwent_fill_done, req);
     114        wb_next_pwent_send_do(req, state);
    149115}
    150116
     
    166132                state->gstate->next_user += 1;
    167133
    168                 if (state->gstate->next_user >= state->gstate->num_users) {
    169                         TALLOC_FREE(state->gstate->users);
    170 
    171                         state->gstate->domain = wb_next_find_domain(state->gstate->domain);
    172                         if (state->gstate->domain == NULL) {
    173                                 tevent_req_nterror(req, NT_STATUS_NO_MORE_ENTRIES);
    174                                 return;
    175                         }
    176 
    177                         subreq = wb_query_user_list_send(state, state->ev,
    178                                         state->gstate->domain);
    179                         if (tevent_req_nomem(subreq, req)) {
    180                                 return;
    181                         }
    182                         tevent_req_set_callback(subreq, wb_next_pwent_fetch_done, req);
    183                         return;
    184                 }
    185 
    186                 subreq = wb_fill_pwent_send(state,
    187                                             state->ev,
    188                                             &state->gstate->users[state->gstate->next_user],
    189                                             state->pw);
    190                 if (tevent_req_nomem(subreq, req)) {
    191                         return;
    192                 }
    193                 tevent_req_set_callback(subreq, wb_next_pwent_fill_done, req);
     134                wb_next_pwent_send_do(req, state);
    194135
    195136                return;
  • vendor/current/source3/winbindd/wb_query_user_list.c

    r740 r988  
    2020#include "includes.h"
    2121#include "winbindd.h"
    22 #include "librpc/gen_ndr/ndr_wbint_c.h"
     22#include "librpc/gen_ndr/ndr_winbind_c.h"
    2323
    2424struct wb_query_user_list_state {
  • vendor/current/source3/winbindd/wb_queryuser.c

    r740 r988  
    2020#include "includes.h"
    2121#include "winbindd.h"
    22 #include "librpc/gen_ndr/ndr_wbint_c.h"
     22#include "librpc/gen_ndr/ndr_winbind_c.h"
    2323#include "../libcli/security/security.h"
    2424
  • vendor/current/source3/winbindd/wb_seqnum.c

    r740 r988  
    2020#include "includes.h"
    2121#include "winbindd.h"
    22 #include "librpc/gen_ndr/ndr_wbint_c.h"
     22#include "librpc/gen_ndr/ndr_winbind_c.h"
    2323
    2424struct wb_seqnum_state {
  • vendor/current/source3/winbindd/wb_seqnums.c

    r740 r988  
    2222#include "includes.h"
    2323#include "winbindd.h"
    24 #include "librpc/gen_ndr/ndr_wbint_c.h"
     24#include "librpc/gen_ndr/ndr_winbind_c.h"
    2525
    2626struct wb_seqnums_state {
  • vendor/current/source3/winbindd/wb_uid2sid.c

    r740 r988  
    2020#include "includes.h"
    2121#include "winbindd.h"
    22 #include "librpc/gen_ndr/ndr_wbint_c.h"
     22#include "librpc/gen_ndr/ndr_winbind_c.h"
    2323#include "idmap_cache.h"
    2424#include "idmap.h"
     
    2727struct wb_uid2sid_state {
    2828        struct tevent_context *ev;
    29         char *dom_name;
    3029        struct dom_sid sid;
    3130};
     
    3938        struct tevent_req *req, *subreq;
    4039        struct wb_uid2sid_state *state;
    41         struct winbindd_domain *domain;
    4240        struct winbindd_child *child;
    4341        bool expired;
     
    6563        }
    6664
    67         state->dom_name = NULL;
    68 
    69         for (domain = domain_list(); domain != NULL; domain = domain->next) {
    70                 if (domain->have_idmap_config
    71                     && (uid >= domain->id_range_low)
    72                     && (uid <= domain->id_range_high)) {
    73                         state->dom_name = domain->name;
    74                         break;
    75                 }
    76         }
    77 
    7865        child = idmap_child();
    7966
    8067        subreq = dcerpc_wbint_Uid2Sid_send(
    81                 state, ev, child->binding_handle, state->dom_name,
     68                state, ev, child->binding_handle,
    8269                uid, &state->sid);
    8370        if (tevent_req_nomem(subreq, req)) {
  • vendor/current/source3/winbindd/winbindd.c

    r860 r988  
    1 /* 
     1/*
    22   Unix SMB/CIFS implementation.
    33
     
    3232#include "../librpc/gen_ndr/srv_samr.h"
    3333#include "secrets.h"
     34#include "rpc_client/cli_netlogon.h"
    3435#include "idmap.h"
    3536#include "lib/addrchange.h"
     
    3738#include "auth.h"
    3839#include "messages.h"
     40#include "../lib/util/pidfile.h"
     41#include "util_cluster.h"
     42#include "source4/lib/messaging/irpc.h"
     43#include "source4/lib/messaging/messaging.h"
     44#include "lib/param/param.h"
     45#include "lib/async_req/async_sock.h"
    3946
    4047#undef DBGC_CLASS
    4148#define DBGC_CLASS DBGC_WINBIND
    4249
     50#define SCRUB_CLIENTS_INTERVAL 5
     51
    4352static bool client_is_idle(struct winbindd_cli_state *state);
    4453static void remove_client(struct winbindd_cli_state *state);
     54static void winbindd_setup_max_fds(void);
    4555
    4656static bool opt_nocache = False;
     
    4959extern bool override_logfile;
    5060
     61struct tevent_context *winbind_event_context(void)
     62{
     63        static struct tevent_context *ev = NULL;
     64
     65        if (ev != NULL) {
     66                return ev;
     67        }
     68
     69        /*
     70         * Note we MUST use the NULL context here, not the autofree context,
     71         * to avoid side effects in forked children exiting.
     72         */
     73        ev = samba_tevent_context_init(NULL);
     74        if (ev == NULL) {
     75                smb_panic("Could not init winbindd's messaging context.\n");
     76        }
     77        return ev;
     78}
     79
    5180struct messaging_context *winbind_messaging_context(void)
    5281{
    53         struct messaging_context *msg_ctx = server_messaging_context();
    54         if (likely(msg_ctx != NULL)) {
    55                 return msg_ctx;
    56         }
    57         smb_panic("Could not init winbindd's messaging context.\n");
    58         return NULL;
     82        static struct messaging_context *msg = NULL;
     83
     84        if (msg != NULL) {
     85                return msg;
     86        }
     87
     88        /*
     89         * Note we MUST use the NULL context here, not the autofree context,
     90         * to avoid side effects in forked children exiting.
     91         */
     92        msg = messaging_init(NULL, winbind_event_context());
     93        if (msg == NULL) {
     94                smb_panic("Could not init winbindd's messaging context.\n");
     95        }
     96        return msg;
     97}
     98
     99struct imessaging_context *winbind_imessaging_context(void)
     100{
     101        static struct imessaging_context *msg = NULL;
     102        struct messaging_context *msg_ctx;
     103        struct server_id myself;
     104        struct loadparm_context *lp_ctx;
     105
     106        if (msg != NULL) {
     107                return msg;
     108        }
     109
     110        msg_ctx = server_messaging_context();
     111        if (msg_ctx == NULL) {
     112                smb_panic("server_messaging_context failed\n");
     113        }
     114        myself = messaging_server_id(msg_ctx);
     115
     116        lp_ctx = loadparm_init_s3(NULL, loadparm_s3_helpers());
     117        if (lp_ctx == NULL) {
     118                smb_panic("Could not load smb.conf to init winbindd's imessaging context.\n");
     119        }
     120
     121        /*
     122         * Note we MUST use the NULL context here, not the autofree context,
     123         * to avoid side effects in forked children exiting.
     124         */
     125        msg = imessaging_init(NULL, lp_ctx, myself, winbind_event_context(),
     126                              false);
     127        talloc_unlink(NULL, lp_ctx);
     128
     129        if (msg == NULL) {
     130                smb_panic("Could not init winbindd's messaging context.\n");
     131        }
     132        return msg;
    59133}
    60134
     
    66140
    67141        if (lp_loaded()) {
    68                 char *fname = lp_configfile();
     142                char *fname = lp_next_configfile(talloc_tos());
    69143
    70144                if (file_exist(fname) && !strcsequal(fname,get_dyn_CONFIGFILE())) {
     
    81155
    82156        reopen_logs();
    83         ret = lp_load(get_dyn_CONFIGFILE(),False,False,True,True);
     157        ret = lp_load_global(get_dyn_CONFIGFILE());
    84158
    85159        reopen_logs();
    86160        load_interfaces();
     161        winbindd_setup_max_fds();
    87162
    88163        return(ret);
    89164}
    90165
    91 
    92 /**************************************************************************** **
    93  Handle a fault..
    94  **************************************************************************** */
    95 
    96 static void fault_quit(void)
    97 {
    98         dump_core();
    99 }
    100166
    101167static void winbindd_status(void)
     
    170236
    171237                if (asprintf(&path, "%s/%s",
    172                         get_winbind_pipe_dir(), WINBINDD_SOCKET_NAME) > 0) {
     238                        lp_winbindd_socket_directory(), WINBINDD_SOCKET_NAME) > 0) {
    173239                        unlink(path);
    174240                        SAFE_FREE(path);
     
    193259
    194260        if (is_parent) {
    195                 serverid_deregister(procid_self());
    196                 pidfile_unlink();
     261                struct messaging_context *msg = winbind_messaging_context();
     262                struct server_id self = messaging_server_id(msg);
     263                serverid_deregister(self);
     264                pidfile_unlink(lp_pid_directory(), "winbindd");
    197265        }
    198266
     
    212280                 signum, (int)*is_parent));
    213281        terminate(*is_parent);
     282}
     283
     284/*
     285  handle stdin becoming readable when we are in --foreground mode
     286 */
     287static void winbindd_stdin_handler(struct tevent_context *ev,
     288                               struct tevent_fd *fde,
     289                               uint16_t flags,
     290                               void *private_data)
     291{
     292        char c;
     293        if (read(0, &c, 1) != 1) {
     294                bool *is_parent = talloc_get_type_abort(private_data, bool);
     295
     296                /* we have reached EOF on stdin, which means the
     297                   parent has exited. Shutdown the server */
     298                DEBUG(0,("EOF on stdin (is_parent=%d)\n",
     299                         (int)*is_parent));
     300                terminate(*is_parent);
     301        }
    214302}
    215303
     
    262350}
    263351
     352bool winbindd_setup_stdin_handler(bool parent, bool foreground)
     353{
     354        bool *is_parent;
     355
     356        if (foreground) {
     357                struct stat st;
     358
     359                is_parent = talloc(winbind_event_context(), bool);
     360                if (!is_parent) {
     361                        return false;
     362                }
     363
     364                *is_parent = parent;
     365
     366                /* if we are running in the foreground then look for
     367                   EOF on stdin, and exit if it happens. This allows
     368                   us to die if the parent process dies
     369                   Only do this on a pipe or socket, no other device.
     370                */
     371                if (fstat(0, &st) != 0) {
     372                        return false;
     373                }
     374                if (S_ISFIFO(st.st_mode) || S_ISSOCK(st.st_mode)) {
     375                        tevent_add_fd(winbind_event_context(),
     376                                        is_parent,
     377                                        0,
     378                                        TEVENT_FD_READ,
     379                                        winbindd_stdin_handler,
     380                                        is_parent);
     381                }
     382        }
     383
     384        return true;
     385}
     386
    264387static void winbindd_sig_hup_handler(struct tevent_context *ev,
    265388                                     struct tevent_signal *se,
     
    388511                                       DATA_BLOB *data)
    389512{
    390         uint8 ret;
     513        uint8_t ret;
    391514        pid_t child_pid;
    392515        NTSTATUS status;
     
    400523         * code can safely use fork/waitpid...
    401524         */
    402         child_pid = sys_fork();
     525        child_pid = fork();
    403526
    404527        if (child_pid == -1) {
     
    427550        CatchSignal(SIGCHLD, SIG_DFL);
    428551
    429         ret = (uint8)winbindd_validate_cache_nobackup();
     552        ret = (uint8_t)winbindd_validate_cache_nobackup();
    430553        DEBUG(10, ("winbindd_msg_validata_cache: got return value %d\n", ret));
    431554        messaging_send_buf(msg_ctx, server_id, MSG_WINBIND_VALIDATE_CACHE, &ret,
     
    460583        { WINBINDD_CCACHE_NTLMAUTH, winbindd_ccache_ntlm_auth, "NTLMAUTH" },
    461584        { WINBINDD_CCACHE_SAVE, winbindd_ccache_save, "CCACHE_SAVE" },
    462 
    463         /* WINS functions */
    464 
    465         { WINBINDD_WINS_BYNAME, winbindd_wins_byname, "WINS_BYNAME" },
    466         { WINBINDD_WINS_BYIP, winbindd_wins_byip, "WINS_BYIP" },
    467585
    468586        /* End of list */
     
    556674          winbindd_pam_chng_pswd_auth_crap_send,
    557675          winbindd_pam_chng_pswd_auth_crap_recv },
     676        { WINBINDD_WINS_BYIP, "WINS_BYIP",
     677          winbindd_wins_byip_send, winbindd_wins_byip_recv },
     678        { WINBINDD_WINS_BYNAME, "WINS_BYNAME",
     679          winbindd_wins_byname_send, winbindd_wins_byname_recv },
    558680
    559681        { 0, NULL, NULL, NULL }
     
    589711        state->cmd_name = "unknown request";
    590712        state->recv_fn = NULL;
    591         state->last_access = time(NULL);
     713        /* client is newest */
     714        winbindd_promote_client(state);
    592715
    593716        /* Process command */
     
    700823static void winbind_client_request_read(struct tevent_req *req);
    701824static void winbind_client_response_written(struct tevent_req *req);
     825static void winbind_client_activity(struct tevent_req *req);
    702826
    703827static void request_finished(struct winbindd_cli_state *state)
    704828{
    705829        struct tevent_req *req;
     830
     831        /* free client socket monitoring request */
     832        TALLOC_FREE(state->io_req);
    706833
    707834        TALLOC_FREE(state->request);
     
    717844        }
    718845        tevent_req_set_callback(req, winbind_client_response_written, state);
     846        state->io_req = req;
    719847}
    720848
     
    725853        ssize_t ret;
    726854        int err;
     855
     856        state->io_req = NULL;
    727857
    728858        ret = wb_resp_write_recv(req, &err);
     
    752882        }
    753883        tevent_req_set_callback(req, winbind_client_request_read, state);
     884        state->io_req = req;
    754885}
    755886
     
    786917        if (sock == -1) {
    787918                if (errno != EINTR) {
    788                         DEBUG(0, ("Faild to accept socket - %s\n",
     919                        DEBUG(0, ("Failed to accept socket - %s\n",
    789920                                  strerror(errno)));
    790921                }
     
    796927        /* Create new connection structure */
    797928
    798         if ((state = TALLOC_ZERO_P(NULL, struct winbindd_cli_state)) == NULL) {
     929        if ((state = talloc_zero(NULL, struct winbindd_cli_state)) == NULL) {
    799930                close(sock);
    800931                return;
     
    809940                return;
    810941        }
    811 
    812         state->last_access = time(NULL);       
    813942
    814943        state->privileged = privileged;
     
    822951        }
    823952        tevent_req_set_callback(req, winbind_client_request_read, state);
     953        state->io_req = req;
    824954
    825955        /* Add to connection list */
     
    834964        ssize_t ret;
    835965        int err;
     966
     967        state->io_req = NULL;
    836968
    837969        ret = wb_req_read_recv(req, state, &state->request, &err);
     
    850982                return;
    851983        }
     984
     985        req = wait_for_read_send(state, winbind_event_context(), state->sock,
     986                                 true);
     987        if (req == NULL) {
     988                DEBUG(0, ("winbind_client_request_read[%d:%s]:"
     989                          " wait_for_read_send failed - removing client\n",
     990                          (int)state->pid, state->cmd_name));
     991                remove_client(state);
     992                return;
     993        }
     994        tevent_req_set_callback(req, winbind_client_activity, state);
     995        state->io_req = req;
     996
    852997        process_request(state);
     998}
     999
     1000static void winbind_client_activity(struct tevent_req *req)
     1001{
     1002        struct winbindd_cli_state *state =
     1003            tevent_req_callback_data(req, struct winbindd_cli_state);
     1004        int err;
     1005        bool has_data;
     1006
     1007        has_data = wait_for_read_recv(req, &err);
     1008
     1009        if (has_data) {
     1010                DEBUG(0, ("winbind_client_activity[%d:%s]:"
     1011                          "unexpected data from client - removing client\n",
     1012                          (int)state->pid, state->cmd_name));
     1013        } else {
     1014                if (err == EPIPE) {
     1015                        DEBUG(6, ("winbind_client_activity[%d:%s]: "
     1016                                  "client has closed connection - removing "
     1017                                  "client\n",
     1018                                  (int)state->pid, state->cmd_name));
     1019                } else {
     1020                        DEBUG(2, ("winbind_client_activity[%d:%s]: "
     1021                                  "client socket error (%s) - removing "
     1022                                  "client\n",
     1023                                  (int)state->pid, state->cmd_name,
     1024                                  strerror(err)));
     1025                }
     1026        }
     1027
     1028        remove_client(state);
    8531029}
    8541030
     
    8651041                return;
    8661042        }
     1043
     1044        /*
     1045         * We need to remove a pending wb_req_read_*
     1046         * or wb_resp_write_* request before closing the
     1047         * socket.
     1048         *
     1049         * This is important as they might have used tevent_add_fd() and we
     1050         * use the epoll * backend on linux. So we must remove the tevent_fd
     1051         * before closing the fd.
     1052         *
     1053         * Otherwise we might hit a race with close_conns_after_fork() (via
     1054         * winbindd_reinit_after_fork()) where a file description
     1055         * is still open in a child, which means it's still active in
     1056         * the parents epoll queue, but the related tevent_fd is already
     1057         * already gone in the parent.
     1058         *
     1059         * See bug #11141.
     1060         */
     1061        TALLOC_FREE(state->io_req);
    8671062
    8681063        if (state->sock != -1) {
     
    9011096{
    9021097        struct winbindd_cli_state *state, *remove_state = NULL;
    903         time_t last_access = 0;
    9041098        int nidle = 0;
    9051099
     
    9071101                if (client_is_idle(state)) {
    9081102                        nidle++;
    909                         if (!last_access || state->last_access < last_access) {
    910                                 last_access = state->last_access;
    911                                 remove_state = state;
    912                         }
     1103                        /* list is sorted by access time */
     1104                        remove_state = state;
    9131105                }
    9141106        }
     
    9221114
    9231115        return False;
     1116}
     1117
     1118/*
     1119 * Terminate all clients whose requests have taken longer than
     1120 * "winbind request timeout" seconds to process, or have been
     1121 * idle for more than "winbind request timeout" seconds.
     1122 */
     1123
     1124static void remove_timed_out_clients(void)
     1125{
     1126        struct winbindd_cli_state *state, *prev = NULL;
     1127        time_t curr_time = time(NULL);
     1128        int timeout_val = lp_winbind_request_timeout();
     1129
     1130        for (state = winbindd_client_list_tail(); state; state = prev) {
     1131                time_t expiry_time;
     1132
     1133                prev = winbindd_client_list_prev(state);
     1134                expiry_time = state->last_access + timeout_val;
     1135
     1136                if (curr_time > expiry_time) {
     1137                        if (client_is_idle(state)) {
     1138                                DEBUG(5,("Idle client timed out, "
     1139                                        "shutting down sock %d, pid %u\n",
     1140                                        state->sock,
     1141                                        (unsigned int)state->pid));
     1142                        } else {
     1143                                DEBUG(5,("Client request timed out, "
     1144                                        "shutting down sock %d, pid %u\n",
     1145                                        state->sock,
     1146                                        (unsigned int)state->pid));
     1147                        }
     1148                        remove_client(state);
     1149                } else {
     1150                        /* list is sorted, previous clients in
     1151                           list are newer */
     1152                        break;
     1153                }
     1154        }
     1155}
     1156
     1157static void winbindd_scrub_clients_handler(struct tevent_context *ev,
     1158                                           struct tevent_timer *te,
     1159                                           struct timeval current_time,
     1160                                           void *private_data)
     1161{
     1162        remove_timed_out_clients();
     1163        if (tevent_add_timer(ev, ev,
     1164                             timeval_current_ofs(SCRUB_CLIENTS_INTERVAL, 0),
     1165                             winbindd_scrub_clients_handler, NULL) == NULL) {
     1166                DEBUG(0, ("winbindd: failed to reschedule client scrubber\n"));
     1167                exit(1);
     1168        }
    9241169}
    9251170
     
    9491194                }
    9501195        }
     1196        remove_timed_out_clients();
    9511197        new_connection(s->fd, s->privileged);
    9521198}
     
    9561202 */
    9571203
    958 const char *get_winbind_pipe_dir(void)
    959 {
    960         return lp_parm_const_string(-1, "winbindd", "socket dir", WINBINDD_SOCKET_DIR);
    961 }
    962 
    9631204char *get_winbind_priv_pipe_dir(void)
    9641205{
    965         return lock_path(WINBINDD_PRIV_SOCKET_SUBDIR);
     1206        return state_path(WINBINDD_PRIV_SOCKET_SUBDIR);
     1207}
     1208
     1209static void winbindd_setup_max_fds(void)
     1210{
     1211        int num_fds = MAX_OPEN_FUDGEFACTOR;
     1212        int actual_fds;
     1213
     1214        num_fds += lp_winbind_max_clients();
     1215        /* Add some more to account for 2 sockets open
     1216           when the client transitions from unprivileged
     1217           to privileged socket
     1218        */
     1219        num_fds += lp_winbind_max_clients() / 10;
     1220
     1221        /* Add one socket per child process
     1222           (yeah there are child processes other than the
     1223           domain children but only domain children can vary
     1224           with configuration
     1225        */
     1226        num_fds += lp_winbind_max_domain_connections() *
     1227                   (lp_allow_trusted_domains() ? WINBIND_MAX_DOMAINS_HINT : 1);
     1228
     1229        actual_fds = set_maxfiles(num_fds);
     1230
     1231        if (actual_fds < num_fds) {
     1232                DEBUG(1, ("winbindd_setup_max_fds: Information only: "
     1233                          "requested %d open files, %d are available.\n",
     1234                          num_fds, actual_fds));
     1235        }
    9661236}
    9671237
     
    9711241        struct winbindd_listen_state *priv_state = NULL;
    9721242        struct tevent_fd *fde;
     1243        int rc;
     1244        char *socket_path;
    9731245
    9741246        pub_state = talloc(winbind_event_context(),
     
    9801252        pub_state->privileged = false;
    9811253        pub_state->fd = create_pipe_sock(
    982                 get_winbind_pipe_dir(), WINBINDD_SOCKET_NAME, 0755);
     1254                lp_winbindd_socket_directory(), WINBINDD_SOCKET_NAME, 0755);
    9831255        if (pub_state->fd == -1) {
     1256                goto failed;
     1257        }
     1258        rc = listen(pub_state->fd, 5);
     1259        if (rc < 0) {
    9841260                goto failed;
    9851261        }
     
    10001276        }
    10011277
     1278        socket_path = get_winbind_priv_pipe_dir();
     1279        if (socket_path == NULL) {
     1280                goto failed;
     1281        }
     1282
    10021283        priv_state->privileged = true;
    10031284        priv_state->fd = create_pipe_sock(
    1004                 get_winbind_priv_pipe_dir(), WINBINDD_SOCKET_NAME, 0750);
     1285                socket_path, WINBINDD_SOCKET_NAME, 0750);
     1286        TALLOC_FREE(socket_path);
    10051287        if (priv_state->fd == -1) {
     1288                goto failed;
     1289        }
     1290        rc = listen(priv_state->fd, 5);
     1291        if (rc < 0) {
    10061292                goto failed;
    10071293        }
     
    10161302        tevent_fd_set_auto_close(fde);
    10171303
     1304        winbindd_scrub_clients_handler(winbind_event_context(), NULL,
     1305                                       timeval_current(), NULL);
    10181306        return true;
    10191307failed:
     
    10331321}
    10341322
    1035 void winbindd_register_handlers(void)
    1036 {
     1323static void winbindd_register_handlers(struct messaging_context *msg_ctx,
     1324                                       bool foreground)
     1325{
     1326        NTSTATUS status;
    10371327        /* Setup signal handlers */
    10381328
    10391329        if (!winbindd_setup_sig_term_handler(true))
     1330                exit(1);
     1331        if (!winbindd_setup_stdin_handler(true, foreground))
    10401332                exit(1);
    10411333        if (!winbindd_setup_sig_hup_handler(NULL))
     
    10581350        /* get broadcast messages */
    10591351
    1060         if (!serverid_register(procid_self(),
    1061                                FLAG_MSG_GENERAL|FLAG_MSG_DBWRAP)) {
     1352        if (!serverid_register(messaging_server_id(msg_ctx),
     1353                               FLAG_MSG_GENERAL |
     1354                               FLAG_MSG_WINBIND |
     1355                               FLAG_MSG_DBWRAP)) {
    10621356                DEBUG(1, ("Could not register myself in serverid.tdb\n"));
    10631357                exit(1);
     
    10661360        /* React on 'smbcontrol winbindd reload-config' in the same way
    10671361           as to SIGHUP signal */
    1068         messaging_register(winbind_messaging_context(), NULL,
     1362        messaging_register(msg_ctx, NULL,
    10691363                           MSG_SMB_CONF_UPDATED, msg_reload_services);
    1070         messaging_register(winbind_messaging_context(), NULL,
     1364        messaging_register(msg_ctx, NULL,
    10711365                           MSG_SHUTDOWN, msg_shutdown);
    10721366
    10731367        /* Handle online/offline messages. */
    1074         messaging_register(winbind_messaging_context(), NULL,
     1368        messaging_register(msg_ctx, NULL,
    10751369                           MSG_WINBIND_OFFLINE, winbind_msg_offline);
    1076         messaging_register(winbind_messaging_context(), NULL,
     1370        messaging_register(msg_ctx, NULL,
    10771371                           MSG_WINBIND_ONLINE, winbind_msg_online);
    1078         messaging_register(winbind_messaging_context(), NULL,
     1372        messaging_register(msg_ctx, NULL,
    10791373                           MSG_WINBIND_ONLINESTATUS, winbind_msg_onlinestatus);
    10801374
     
    10851379                           MSG_WINBIND_DOMAIN_ONLINE, winbind_msg_domain_online);
    10861380
    1087         messaging_register(winbind_messaging_context(), NULL,
     1381        messaging_register(msg_ctx, NULL,
    10881382                           MSG_DUMP_EVENT_LIST, winbind_msg_dump_event_list);
    10891383
    1090         messaging_register(winbind_messaging_context(), NULL,
     1384        messaging_register(msg_ctx, NULL,
    10911385                           MSG_WINBIND_VALIDATE_CACHE,
    10921386                           winbind_msg_validate_cache);
    10931387
    1094         messaging_register(winbind_messaging_context(), NULL,
     1388        messaging_register(msg_ctx, NULL,
    10951389                           MSG_WINBIND_DUMP_DOMAIN_LIST,
    10961390                           winbind_msg_dump_domain_list);
    10971391
    1098         messaging_register(winbind_messaging_context(), NULL,
     1392        messaging_register(msg_ctx, NULL,
    10991393                           MSG_WINBIND_IP_DROPPED,
    11001394                           winbind_msg_ip_dropped_parent);
    11011395
    11021396        /* Register handler for MSG_DEBUG. */
    1103         messaging_register(winbind_messaging_context(), NULL,
     1397        messaging_register(msg_ctx, NULL,
    11041398                           MSG_DEBUG,
    11051399                           winbind_msg_debug);
     
    11301424        }
    11311425
     1426        status = wb_irpc_register();
     1427
     1428        if (!NT_STATUS_IS_OK(status)) {
     1429                DEBUG(0, ("Could not register IRPC handlers\n"));
     1430                exit(1);
     1431        }
    11321432}
    11331433
     
    12181518/* Main function */
    12191519
    1220 int main(int argc, char **argv, char **envp)
     1520int main(int argc, const char **argv)
    12211521{
    12221522        static bool is_daemon = False;
     
    12451545        TALLOC_CTX *frame;
    12461546        NTSTATUS status;
     1547        bool ok;
    12471548
    12481549        /*
     
    12521553        frame = talloc_stackframe();
    12531554
     1555        /*
     1556         * We want total control over the permissions on created files,
     1557         * so set our umask to 0.
     1558         */
     1559        umask(0);
     1560
     1561        setup_logging("winbindd", DEBUG_DEFAULT_STDOUT);
     1562
    12541563        /* glibc (?) likes to print "User defined signal 1" and exit if a
    12551564           SIGUSR[12] is received before a handler is installed */
     
    12581567        CatchSignal(SIGUSR2, SIG_IGN);
    12591568
    1260         fault_setup((void (*)(void *))fault_quit );
    1261         dump_core_setup("winbindd");
    1262 
    1263         load_case_tables();
     1569        fault_setup();
     1570        dump_core_setup("winbindd", lp_logfile(talloc_tos()));
     1571
     1572        smb_init_locale();
    12641573
    12651574        /* Initialise for running in non-root mode */
     
    12791588        /* Initialise samba/rpc client stuff */
    12801589
    1281         pc = poptGetContext("winbindd", argc, (const char **)argv, long_options, 0);
     1590        pc = poptGetContext("winbindd", argc, argv, long_options, 0);
    12821591
    12831592        while ((opt = poptGetNextOpt(pc)) != -1) {
     
    13191628         * in production.
    13201629         */
    1321         dump_core_setup("winbindd");
    1322 
     1630        dump_core_setup("winbindd", lp_logfile(talloc_tos()));
    13231631        if (is_daemon && interactive) {
    13241632                d_fprintf(stderr,"\nERROR: "
     
    13451653                }
    13461654        }
     1655
    13471656        if (log_stdout) {
    13481657                setup_logging("winbindd", DEBUG_STDOUT);
     
    13561665
    13571666        if (!lp_load_initial_only(get_dyn_CONFIGFILE())) {
    1358                 DEBUG(0, ("error opening config file\n"));
     1667                DEBUG(0, ("error opening config file '%s'\n", get_dyn_CONFIGFILE()));
    13591668                exit(1);
    13601669        }
     
    13631672         * path is by default basename(lp_logfile()).
    13641673         */
    1365         dump_core_setup("winbindd");
     1674        dump_core_setup("winbindd", lp_logfile(talloc_tos()));
     1675
     1676        if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC
     1677            && !lp_parm_bool(-1, "server role check", "inhibit", false)) {
     1678                DEBUG(0, ("server role = 'active directory domain controller' not compatible with running the winbindd binary. \n"));
     1679                DEBUGADD(0, ("You should start 'samba' instead, and it will control starting the internal AD DC winbindd implementation, which is not the same as this one\n"));
     1680                exit(1);
     1681        }
     1682
     1683        if (!cluster_probe_ok()) {
     1684                exit(1);
     1685        }
    13661686
    13671687        /* Initialise messaging system */
     
    13761696        }
    13771697
    1378         if (!directory_exist(lp_lockdir())) {
    1379                 mkdir(lp_lockdir(), 0755);
     1698        ok = directory_create_or_exist(lp_lock_directory(), 0755);
     1699        if (!ok) {
     1700                DEBUG(0, ("Failed to create directory %s for lock files - %s\n",
     1701                          lp_lock_directory(), strerror(errno)));
     1702                exit(1);
     1703        }
     1704
     1705        ok = directory_create_or_exist(lp_pid_directory(), 0755);
     1706        if (!ok) {
     1707                DEBUG(0, ("Failed to create directory %s for pid files - %s\n",
     1708                          lp_pid_directory(), strerror(errno)));
     1709                exit(1);
    13801710        }
    13811711
     
    13911721                DEBUG(0,("Could not initialize domain trust account secrets. Giving up\n"));
    13921722                return False;
     1723        }
     1724
     1725        status = rpccli_pre_open_netlogon_creds();
     1726        if (!NT_STATUS_IS_OK(status)) {
     1727                DEBUG(0, ("rpccli_pre_open_netlogon_creds() - %s\n",
     1728                          nt_errstr(status)));
     1729                exit(1);
    13931730        }
    13941731
     
    14071744                become_daemon(Fork, no_process_group, log_stdout);
    14081745
    1409         pidfile_create("winbindd");
     1746        pidfile_create(lp_pid_directory(), "winbindd");
    14101747
    14111748#if HAVE_SETPGID
     
    14271764        status = reinit_after_fork(winbind_messaging_context(),
    14281765                                   winbind_event_context(),
    1429                                    procid_self(), false);
     1766                                   false, NULL);
    14301767        if (!NT_STATUS_IS_OK(status)) {
    1431                 DEBUG(0,("reinit_after_fork() failed\n"));
    1432                 exit(1);
    1433         }
    1434 
    1435         winbindd_register_handlers();
    1436 
    1437         status = init_system_info();
     1768                exit_daemon("Winbindd reinit_after_fork() failed", map_errno_from_nt_status(status));
     1769        }
     1770
     1771        /*
     1772         * Do not initialize the parent-child-pipe before becoming
     1773         * a daemon: this is used to detect a died parent in the child
     1774         * process.
     1775         */
     1776        status = init_before_fork();
    14381777        if (!NT_STATUS_IS_OK(status)) {
    1439                 DEBUG(1, ("ERROR: failed to setup system user info: %s.\n",
    1440                           nt_errstr(status)));
    1441                 exit(1);
     1778                exit_daemon(nt_errstr(status), map_errno_from_nt_status(status));
     1779        }
     1780
     1781        winbindd_register_handlers(winbind_messaging_context(), !Fork);
     1782
     1783        if (!messaging_parent_dgm_cleanup_init(winbind_messaging_context())) {
     1784                exit(1);
     1785        }
     1786
     1787        status = init_system_session_info();
     1788        if (!NT_STATUS_IS_OK(status)) {
     1789                exit_daemon("Winbindd failed to setup system user info", map_errno_from_nt_status(status));
    14421790        }
    14431791
     
    14511799
    14521800        if (!winbindd_setup_listeners()) {
    1453                 DEBUG(0,("winbindd_setup_listeners() failed\n"));
    1454                 exit(1);
    1455         }
     1801                exit_daemon("Winbindd failed to setup listeners", EPIPE);
     1802        }
     1803
     1804        irpc_add_name(winbind_imessaging_context(), "winbind_server");
    14561805
    14571806        TALLOC_FREE(frame);
     1807
     1808        if (!interactive) {
     1809                daemon_ready("winbindd");
     1810        }
     1811
    14581812        /* Loop waiting for requests */
    14591813        while (1) {
  • vendor/current/source3/winbindd/winbindd.h

    r740 r988  
    2626#include "nsswitch/winbind_struct_protocol.h"
    2727#include "nsswitch/libwbclient/wbclient.h"
    28 #include "librpc/gen_ndr/wbint.h"
     28#include "librpc/gen_ndr/dcerpc.h"
     29#include "librpc/gen_ndr/winbind.h"
    2930
    3031#include "talloc_dict.h"
    31 #include "smb_ldap.h"
    3232
    3333#include "../lib/util/tevent_ntstatus.h"
     
    6868        struct tevent_queue *out_queue;
    6969        struct winbindd_response *response;        /* Respose to client */
    70         bool getpwent_initialized;                /* Has getpwent_state been
    71                                                    * initialized? */
    72         bool getgrent_initialized;                /* Has getgrent_state been
    73                                                    * initialized? */
     70        struct tevent_req *io_req; /* wb_req_read_* or wb_resp_write_* */
    7471
    7572        struct getpwent_state *pwent_state; /* State for getpwent() */
     
    107104        struct cli_state *cli;
    108105
     106        enum dcerpc_AuthLevel auth_level;
     107
    109108        struct rpc_pipe_client *samr_pipe;
    110109        struct policy_handle sam_connect_handle, sam_domain_handle;
     
    115114
    116115        struct rpc_pipe_client *netlogon_pipe;
     116        struct netlogon_creds_cli_context *netlogon_creds;
     117        uint32_t netlogon_flags;
     118        bool netlogon_force_reauth;
    117119};
    118120
     
    139141        struct dcerpc_binding_handle *binding_handle;
    140142
    141         struct timed_event *lockout_policy_event;
    142         struct timed_event *machine_password_change_event;
     143        struct tevent_timer *lockout_policy_event;
     144        struct tevent_timer *machine_password_change_event;
    143145
    144146        const struct winbindd_child_dispatch_table *table;
     
    148150
    149151struct winbindd_domain {
    150         fstring name;                          /* Domain name (NetBIOS) */
    151         fstring alt_name;                      /* alt Domain name, if any (FQDN for ADS) */
    152         fstring forest_name;                   /* Name of the AD forest we're in */
     152        char *name;                            /* Domain name (NetBIOS) */
     153        char *alt_name;                        /* alt Domain name, if any (FQDN for ADS) */
     154        char *forest_name;                     /* Name of the AD forest we're in */
    153155        struct dom_sid sid;                           /* SID for this domain */
    154         uint32 domain_flags;                   /* Domain flags from netlogon.h */
    155         uint32 domain_type;                    /* Domain type from netlogon.h */
    156         uint32 domain_trust_attribs;           /* Trust attribs from netlogon.h */
     156        uint32_t domain_flags;                   /* Domain flags from netlogon.h */
     157        uint32_t domain_type;                    /* Domain type from netlogon.h */
     158        uint32_t domain_trust_attribs;           /* Trust attribs from netlogon.h */
    157159        bool initialized;                      /* Did we already ask for the domain mode? */
    158160        bool native_mode;                      /* is this a win2k domain in native mode ? */
     
    160162        bool primary;                          /* is this our primary domain ? */
    161163        bool internal;                         /* BUILTIN and member SAM */
     164        bool rodc;                             /* Are we an RODC for this AD domain? (do some operations locally) */
    162165        bool online;                           /* is this domain available ? */
    163166        time_t startup_time;                   /* When we set "startup" true. monotonic clock */
    164167        bool startup;                          /* are we in the first 30 seconds after startup_time ? */
    165168
    166         bool can_do_samlogon_ex; /* Due to the lack of finer control what type
    167                                   * of DC we have, let us try to do a
    168                                   * credential-chain less samlogon_ex call
    169                                   * with AD and schannel. If this fails with
    170                                   * DCERPC_FAULT_OP_RNG_ERROR, then set this
    171                                   * to False. This variable is around so that
    172                                   * we don't have to try _ex every time. */
    173 
    174169        bool can_do_ncacn_ip_tcp;
    175         bool can_do_validation6;
    176170
    177171        /* Lookup methods for this domain (LDAP or RPC) */
     
    186180        void *private_data;
    187181
    188         /*
    189          * idmap config settings, used to tell the idmap child which
    190          * special domain config to use for a mapping
    191          */
    192         bool have_idmap_config;
    193         uint32_t id_range_low, id_range_high;
    194 
    195182        /* A working DC */
    196183        pid_t dc_probe_pid; /* Child we're using to detect the DC. */
    197         fstring dcname;
     184        char *dcname;
    198185        struct sockaddr_storage dcaddr;
    199186
     
    201188
    202189        time_t last_seq_check;
    203         uint32 sequence_number;
     190        uint32_t sequence_number;
    204191        NTSTATUS last_status;
    205192
     
    214201        /* Callback we use to try put us back online. */
    215202
    216         uint32 check_online_timeout;
    217         struct timed_event *check_online_event;
     203        uint32_t check_online_timeout;
     204        struct tevent_timer *check_online_event;
    218205
    219206        /* Linked list info */
     
    238225        NTSTATUS (*query_user_list)(struct winbindd_domain *domain,
    239226                                   TALLOC_CTX *mem_ctx,
    240                                    uint32 *num_entries,
     227                                   uint32_t *num_entries,
    241228                                   struct wbint_userinfo **info);
    242229
     
    244231        NTSTATUS (*enum_dom_groups)(struct winbindd_domain *domain,
    245232                                    TALLOC_CTX *mem_ctx,
    246                                     uint32 *num_entries,
     233                                    uint32_t *num_entries,
    247234                                    struct wb_acct_info **info);
    248235
     
    250237        NTSTATUS (*enum_local_groups)(struct winbindd_domain *domain,
    251238                                    TALLOC_CTX *mem_ctx,
    252                                     uint32 *num_entries,
     239                                    uint32_t *num_entries,
    253240                                    struct wb_acct_info **info);
    254241
     
    273260                                  TALLOC_CTX *mem_ctx,
    274261                                  const struct dom_sid *domain_sid,
    275                                   uint32 *rids,
     262                                  uint32_t *rids,
    276263                                  size_t num_rids,
    277264                                  char **domain_name,
     
    291278                                      TALLOC_CTX *mem_ctx,
    292279                                      const struct dom_sid *user_sid,
    293                                       uint32 *num_groups, struct dom_sid **user_gids);
     280                                      uint32_t *num_groups, struct dom_sid **user_gids);
    294281
    295282        /* Lookup all aliases that the sids delivered are member of. This is
     
    297284        NTSTATUS (*lookup_useraliases)(struct winbindd_domain *domain,
    298285                                       TALLOC_CTX *mem_ctx,
    299                                        uint32 num_sids,
     286                                       uint32_t num_sids,
    300287                                       const struct dom_sid *sids,
    301                                        uint32 *num_aliases,
    302                                        uint32 **alias_rids);
     288                                       uint32_t *num_aliases,
     289                                       uint32_t **alias_rids);
    303290
    304291        /* find all members of the group with the specified group_rid */
     
    307294                                    const struct dom_sid *group_sid,
    308295                                    enum lsa_SidType type,
    309                                     uint32 *num_names,
     296                                    uint32_t *num_names,
    310297                                    struct dom_sid **sid_mem, char ***names,
    311                                     uint32 **name_types);
     298                                    uint32_t **name_types);
    312299
    313300        /* return the current global sequence number */
    314         NTSTATUS (*sequence_number)(struct winbindd_domain *domain, uint32 *seq);
     301        NTSTATUS (*sequence_number)(struct winbindd_domain *domain, uint32_t *seq);
    315302
    316303        /* return the lockout policy */
     
    353340        const char *dns_name;
    354341        struct dom_sid sid;
    355         uint32 trust_flags;
    356         uint32 trust_attribs;
    357         uint32 trust_type;
     342        uint32_t trust_flags;
     343        uint32_t trust_attribs;
     344        uint32_t trust_type;
    358345};
    359346
     
    388375        time_t renew_until;
    389376        time_t refresh_time;
    390         struct timed_event *event;
     377        struct tevent_timer *event;
    391378};
    392379
     
    396383#define WINBINDD_RESCAN_FREQ lp_winbind_cache_time()
    397384#define WINBINDD_PAM_AUTH_KRB5_RENEW_TIME 2592000 /* one month */
    398 #define DOM_SEQUENCE_NONE ((uint32)-1)
    399 
    400 #define winbind_event_context server_event_context
     385#define DOM_SEQUENCE_NONE ((uint32_t)-1)
    401386
    402387#endif /* _WINBINDD_H */
  • vendor/current/source3/winbindd/winbindd_ads.c

    r746 r988  
    2828#include "../libds/common/flags.h"
    2929#include "ads.h"
    30 #include "secrets.h"
    3130#include "../libcli/ldap/ldap_ndr.h"
    3231#include "../libcli/security/security.h"
     
    4039
    4140extern struct winbindd_methods reconnect_methods;
     41extern struct winbindd_methods msrpc_methods;
     42
     43#define WINBIND_CCACHE_NAME "MEMORY:winbind_ccache"
     44
     45/**
     46 * Check if cached connection can be reused. If the connection cannot
     47 * be reused the ADS_STRUCT is freed and the pointer is set to NULL.
     48 */
     49static void ads_cached_connection_reuse(ADS_STRUCT **adsp)
     50{
     51
     52        ADS_STRUCT *ads = *adsp;
     53
     54        if (ads != NULL) {
     55                time_t expire;
     56                time_t now = time(NULL);
     57
     58                expire = MIN(ads->auth.tgt_expire, ads->auth.tgs_expire);
     59
     60                DEBUG(7, ("Current tickets expire in %d seconds (at %d, time "
     61                          "is now %d)\n", (uint32_t)expire - (uint32_t)now,
     62                          (uint32_t) expire, (uint32_t) now));
     63
     64                if ( ads->config.realm && (expire > now)) {
     65                        return;
     66                } else {
     67                        /* we own this ADS_STRUCT so make sure it goes away */
     68                        DEBUG(7,("Deleting expired krb5 credential cache\n"));
     69                        ads->is_mine = True;
     70                        ads_destroy( &ads );
     71                        ads_kdestroy(WINBIND_CCACHE_NAME);
     72                        *adsp = NULL;
     73                }
     74        }
     75}
     76
     77/**
     78 * @brief Establish a connection to a DC
     79 *
     80 * @param[out]   adsp             ADS_STRUCT that will be created
     81 * @param[in]    target_realm     Realm of domain to connect to
     82 * @param[in]    target_dom_name  'workgroup' name of domain to connect to
     83 * @param[in]    ldap_server      DNS name of server to connect to
     84 * @param[in]    password         Our machine acount secret
     85 * @param[in]    auth_realm       Realm of local domain for creating krb token
     86 * @param[in]    renewable        Renewable ticket time
     87 *
     88 * @return ADS_STATUS
     89 */
     90static ADS_STATUS ads_cached_connection_connect(ADS_STRUCT **adsp,
     91                                                const char *target_realm,
     92                                                const char *target_dom_name,
     93                                                const char *ldap_server,
     94                                                char *password,
     95                                                char *auth_realm,
     96                                                time_t renewable)
     97{
     98        ADS_STRUCT *ads;
     99        ADS_STATUS status;
     100        struct sockaddr_storage dc_ss;
     101        fstring dc_name;
     102
     103        if (auth_realm == NULL) {
     104                return ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL);
     105        }
     106
     107        /* we don't want this to affect the users ccache */
     108        setenv("KRB5CCNAME", WINBIND_CCACHE_NAME, 1);
     109
     110        ads = ads_init(target_realm, target_dom_name, ldap_server);
     111        if (!ads) {
     112                DEBUG(1,("ads_init for domain %s failed\n", target_dom_name));
     113                return ADS_ERROR(LDAP_NO_MEMORY);
     114        }
     115
     116        SAFE_FREE(ads->auth.password);
     117        SAFE_FREE(ads->auth.realm);
     118
     119        ads->auth.renewable = renewable;
     120        ads->auth.password = password;
     121
     122        ads->auth.realm = SMB_STRDUP(auth_realm);
     123        if (!strupper_m(ads->auth.realm)) {
     124                ads_destroy(&ads);
     125                return ADS_ERROR_NT(NT_STATUS_INTERNAL_ERROR);
     126        }
     127
     128        /* Setup the server affinity cache.  We don't reaally care
     129           about the name.  Just setup affinity and the KRB5_CONFIG
     130           file. */
     131        get_dc_name(ads->server.workgroup, ads->server.realm, dc_name, &dc_ss);
     132
     133        status = ads_connect(ads);
     134        if (!ADS_ERR_OK(status)) {
     135                DEBUG(1,("ads_connect for domain %s failed: %s\n",
     136                         target_dom_name, ads_errstr(status)));
     137                ads_destroy(&ads);
     138                return status;
     139        }
     140
     141        /* set the flag that says we don't own the memory even
     142           though we do so that ads_destroy() won't destroy the
     143           structure we pass back by reference */
     144
     145        ads->is_mine = False;
     146
     147        *adsp = ads;
     148
     149        return status;
     150}
     151
     152ADS_STATUS ads_idmap_cached_connection(ADS_STRUCT **adsp, const char *dom_name)
     153{
     154        char *ldap_server, *realm, *password;
     155        struct winbindd_domain *wb_dom;
     156        ADS_STATUS status;
     157
     158        ads_cached_connection_reuse(adsp);
     159        if (*adsp != NULL) {
     160                return ADS_SUCCESS;
     161        }
     162
     163        /*
     164         * At this point we only have the NetBIOS domain name.
     165         * Check if we can get server nam and realm from SAF cache
     166         * and the domain list.
     167         */
     168        ldap_server = saf_fetch(talloc_tos(), dom_name);
     169        DEBUG(10, ("ldap_server from saf cache: '%s'\n",
     170                   ldap_server ? ldap_server : ""));
     171
     172        wb_dom = find_domain_from_name(dom_name);
     173        if (wb_dom == NULL) {
     174                DEBUG(10, ("could not find domain '%s'\n", dom_name));
     175                return ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL);
     176        }
     177
     178        DEBUG(10, ("find_domain_from_name found realm '%s' for "
     179                          " domain '%s'\n", wb_dom->alt_name, dom_name));
     180
     181        if (!get_trust_pw_clear(dom_name, &password, NULL, NULL)) {
     182                TALLOC_FREE(ldap_server);
     183                return ADS_ERROR_NT(NT_STATUS_CANT_ACCESS_DOMAIN_INFO);
     184        }
     185
     186        if (IS_DC) {
     187                SMB_ASSERT(wb_dom->alt_name != NULL);
     188                realm = SMB_STRDUP(wb_dom->alt_name);
     189        } else {
     190                struct winbindd_domain *our_domain = wb_dom;
     191
     192                /* always give preference to the alt_name in our
     193                   primary domain if possible */
     194
     195                if (!wb_dom->primary) {
     196                        our_domain = find_our_domain();
     197                }
     198
     199                if (our_domain->alt_name != NULL) {
     200                        realm = SMB_STRDUP(our_domain->alt_name);
     201                } else {
     202                        realm = SMB_STRDUP(lp_realm());
     203                }
     204        }
     205
     206        status = ads_cached_connection_connect(
     207                adsp,                   /* Returns ads struct. */
     208                wb_dom->alt_name,       /* realm to connect to. */
     209                dom_name,               /* 'workgroup' name for ads_init */
     210                ldap_server,            /* DNS name to connect to. */
     211                password,               /* password for auth realm. */
     212                realm,                  /* realm used for krb5 ticket. */
     213                0);                     /* renewable ticket time. */
     214
     215        SAFE_FREE(realm);
     216        TALLOC_FREE(ldap_server);
     217
     218        return status;
     219}
    42220
    43221/*
     
    47225static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain)
    48226{
    49         ADS_STRUCT *ads;
    50227        ADS_STATUS status;
    51         fstring dc_name;
    52         struct sockaddr_storage dc_ss;
     228        char *password, *realm;
    53229
    54230        DEBUG(10,("ads_cached_connection\n"));
     231        ads_cached_connection_reuse((ADS_STRUCT **)&domain->private_data);
    55232
    56233        if (domain->private_data) {
    57 
    58                 time_t expire;
    59                 time_t now = time(NULL);
    60 
    61                 /* check for a valid structure */
    62                 ads = (ADS_STRUCT *)domain->private_data;
    63 
    64                 expire = MIN(ads->auth.tgt_expire, ads->auth.tgs_expire);
    65 
    66                 DEBUG(7, ("Current tickets expire in %d seconds (at %d, time is now %d)\n",
    67                           (uint32)expire-(uint32)now, (uint32) expire, (uint32) now));
    68 
    69                 if ( ads->config.realm && (expire > now)) {
    70                         return ads;
    71                 } else {
    72                         /* we own this ADS_STRUCT so make sure it goes away */
    73                         DEBUG(7,("Deleting expired krb5 credential cache\n"));
    74                         ads->is_mine = True;
    75                         ads_destroy( &ads );
    76                         ads_kdestroy("MEMORY:winbind_ccache");
    77                         domain->private_data = NULL;
    78                 }
    79         }
    80 
    81         /* we don't want this to affect the users ccache */
    82         setenv("KRB5CCNAME", "MEMORY:winbind_ccache", 1);
    83 
    84         ads = ads_init(domain->alt_name, domain->name, NULL);
    85         if (!ads) {
    86                 DEBUG(1,("ads_init for domain %s failed\n", domain->name));
     234                return (ADS_STRUCT *)domain->private_data;
     235        }
     236
     237        /* the machine acct password might have change - fetch it every time */
     238
     239        if (!get_trust_pw_clear(domain->name, &password, NULL, NULL)) {
    87240                return NULL;
    88241        }
    89242
    90         /* the machine acct password might have change - fetch it every time */
    91 
    92         SAFE_FREE(ads->auth.password);
    93         SAFE_FREE(ads->auth.realm);
    94 
    95243        if ( IS_DC ) {
    96 
    97                 if ( !pdb_get_trusteddom_pw( domain->name, &ads->auth.password, NULL, NULL ) ) {
    98                         ads_destroy( &ads );
    99                         return NULL;
    100                 }
    101                 ads->auth.realm = SMB_STRDUP( ads->server.realm );
    102                 strupper_m( ads->auth.realm );
     244                SMB_ASSERT(domain->alt_name != NULL);
     245                realm = SMB_STRDUP(domain->alt_name);
    103246        }
    104247        else {
    105248                struct winbindd_domain *our_domain = domain;
    106249
    107                 ads->auth.password = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL);
    108250
    109251                /* always give preference to the alt_name in our
     
    113255                        our_domain = find_our_domain();
    114256
    115                 if ( our_domain->alt_name[0] != '\0' ) {
    116                         ads->auth.realm = SMB_STRDUP( our_domain->alt_name );
    117                         strupper_m( ads->auth.realm );
     257                if (our_domain->alt_name != NULL) {
     258                        realm = SMB_STRDUP( our_domain->alt_name );
    118259                }
    119260                else
    120                         ads->auth.realm = SMB_STRDUP( lp_realm() );
    121         }
    122 
    123         ads->auth.renewable = WINBINDD_PAM_AUTH_KRB5_RENEW_TIME;
    124 
    125         /* Setup the server affinity cache.  We don't reaally care
    126            about the name.  Just setup affinity and the KRB5_CONFIG
    127            file. */
    128 
    129         get_dc_name( ads->server.workgroup, ads->server.realm, dc_name, &dc_ss );
    130 
    131         status = ads_connect(ads);
    132         if (!ADS_ERR_OK(status) || !ads->config.realm) {
    133                 DEBUG(1,("ads_connect for domain %s failed: %s\n",
    134                          domain->name, ads_errstr(status)));
    135                 ads_destroy(&ads);
    136 
     261                        realm = SMB_STRDUP( lp_realm() );
     262        }
     263
     264        status = ads_cached_connection_connect(
     265                                        (ADS_STRUCT **)&domain->private_data,
     266                                        domain->alt_name,
     267                                        domain->name, NULL,
     268                                        password, realm,
     269                                        WINBINDD_PAM_AUTH_KRB5_RENEW_TIME);
     270        SAFE_FREE(realm);
     271
     272        if (!ADS_ERR_OK(status)) {
    137273                /* if we get ECONNREFUSED then it might be a NT4
    138274                   server, fall back to MSRPC */
     
    146282        }
    147283
    148         /* set the flag that says we don't own the memory even
    149            though we do so that ads_destroy() won't destroy the
    150            structure we pass back by reference */
    151 
    152         ads->is_mine = False;
    153 
    154         domain->private_data = (void *)ads;
    155         return ads;
    156 }
    157 
     284        return (ADS_STRUCT *)domain->private_data;
     285}
    158286
    159287/* Query display info for a realm. This is the basic user list fn */
    160288static NTSTATUS query_user_list(struct winbindd_domain *domain,
    161289                               TALLOC_CTX *mem_ctx,
    162                                uint32 *num_entries,
     290                               uint32_t *num_entries,
    163291                               struct wbint_userinfo **pinfo)
    164292{
     
    192320                DEBUG(1,("query_user_list ads_search: %s\n", ads_errstr(rc)));
    193321                status = ads_ntstatus(rc);
     322                goto done;
    194323        } else if (!res) {
    195324                DEBUG(1,("query_user_list ads_search returned NULL res\n"));
    196 
    197325                goto done;
    198326        }
     
    204332        }
    205333
    206         (*pinfo) = TALLOC_ZERO_ARRAY(mem_ctx, struct wbint_userinfo, count);
     334        (*pinfo) = talloc_zero_array(mem_ctx, struct wbint_userinfo, count);
    207335        if (!*pinfo) {
    208336                status = NT_STATUS_NO_MEMORY;
     
    214342        for (msg = ads_first_entry(ads, res); msg; msg = ads_next_entry(ads, msg)) {
    215343                struct wbint_userinfo *info = &((*pinfo)[count]);
    216                 uint32 group;
    217                 uint32 atype;
     344                uint32_t group;
     345                uint32_t atype;
    218346
    219347                if (!ads_pull_uint32(ads, msg, "sAMAccountType", &atype) ||
     
    224352
    225353                info->acct_name = ads_pull_username(ads, mem_ctx, msg);
    226                 info->full_name = ads_pull_string(ads, mem_ctx, msg, "name");
     354                info->full_name = ads_pull_string(ads, mem_ctx, msg, "displayName");
     355                if (info->full_name == NULL) {
     356                        info->full_name = ads_pull_string(ads, mem_ctx, msg, "name");
     357                }
    227358                info->homedir = NULL;
    228359                info->shell = NULL;
     
    281412static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
    282413                                TALLOC_CTX *mem_ctx,
    283                                 uint32 *num_entries,
     414                                uint32_t *num_entries,
    284415                                struct wb_acct_info **info)
    285416{
     
    360491        }
    361492
    362         (*info) = TALLOC_ZERO_ARRAY(mem_ctx, struct wb_acct_info, count);
     493        (*info) = talloc_zero_array(mem_ctx, struct wb_acct_info, count);
    363494        if (!*info) {
    364495                status = NT_STATUS_NO_MEMORY;
     
    371502                char *name, *gecos;
    372503                struct dom_sid sid;
    373                 uint32 rid;
     504                uint32_t rid;
    374505
    375506                name = ads_pull_username(ads, mem_ctx, msg);
     
    407538static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
    408539                                TALLOC_CTX *mem_ctx,
    409                                 uint32 *num_entries,
     540                                uint32_t *num_entries,
    410541                                struct wb_acct_info **info)
    411542{
     
    434565                            enum lsa_SidType *type)
    435566{
    436         return reconnect_methods.name_to_sid(domain, mem_ctx,
    437                                              domain_name, name, flags,
    438                                              sid, type);
     567        return msrpc_methods.name_to_sid(domain, mem_ctx, domain_name, name,
     568                                         flags, sid, type);
    439569}
    440570
     
    447577                            enum lsa_SidType *type)
    448578{
    449         return reconnect_methods.sid_to_name(domain, mem_ctx, sid,
    450                                              domain_name, name, type);
     579        return msrpc_methods.sid_to_name(domain, mem_ctx, sid,
     580                                         domain_name, name, type);
    451581}
    452582
     
    455585                              TALLOC_CTX *mem_ctx,
    456586                              const struct dom_sid *sid,
    457                               uint32 *rids,
     587                              uint32_t *rids,
    458588                              size_t num_rids,
    459589                              char **domain_name,
     
    461591                              enum lsa_SidType **types)
    462592{
    463         return reconnect_methods.rids_to_names(domain, mem_ctx, sid,
    464                                                rids, num_rids,
    465                                                domain_name, names, types);
     593        return msrpc_methods.rids_to_names(domain, mem_ctx, sid,
     594                                           rids, num_rids,
     595                                           domain_name, names, types);
    466596}
    467597
     
    484614        char *ldap_exp;
    485615        char *sidstr;
    486         uint32 group_rid;
     616        uint32_t group_rid;
    487617        NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
    488618        struct netr_SamInfo3 *user = NULL;
    489619        gid_t gid = -1;
    490620        int ret;
    491         char *ads_name;
     621        char *full_name;
    492622
    493623        DEBUG(3,("ads: query_user\n"));
     
    498628        /* try netsamlogon cache first */
    499629
    500         if ( (user = netsamlogon_cache_get( mem_ctx, sid )) != NULL ) 
     630        if ( (user = netsamlogon_cache_get( mem_ctx, sid )) != NULL )
    501631        {
    502632                DEBUG(5,("query_user: Cache lookup succeeded for %s\n",
     
    515645
    516646                TALLOC_FREE(user);
     647
     648                if (info->full_name == NULL) {
     649                        /* this might fail so we don't check the return code */
     650                        wcache_query_user_fullname(domain,
     651                                                   mem_ctx,
     652                                                   sid,
     653                                                   &info->full_name);
     654                }
    517655
    518656                return NT_STATUS_OK;
     
    593731         * the ads struct, potentially invalidating the ldap message.
    594732         */
    595         ads_name = ads_pull_string(ads, mem_ctx, msg, "name");
     733        full_name = ads_pull_string(ads, mem_ctx, msg, "displayName");
     734        if (full_name == NULL) {
     735                full_name = ads_pull_string(ads, mem_ctx, msg, "name");
     736        }
    596737
    597738        ads_msgfree(ads, msg);
     
    609750
    610751        if (info->full_name == NULL) {
    611                 info->full_name = ads_name;
     752                info->full_name = full_name;
    612753        } else {
    613                 TALLOC_FREE(ads_name);
     754                TALLOC_FREE(full_name);
    614755        }
    615756
     
    786927        }
    787928
    788         group_sids = TALLOC_ZERO_ARRAY(mem_ctx, struct dom_sid, num_strings + 1);
     929        group_sids = talloc_zero_array(mem_ctx, struct dom_sid, num_strings + 1);
    789930        if (!group_sids) {
    790931                status = NT_STATUS_NO_MEMORY;
     
    849990                                  TALLOC_CTX *mem_ctx,
    850991                                  const struct dom_sid *sid,
    851                                   uint32 *p_num_groups, struct dom_sid **user_sids)
     992                                  uint32_t *p_num_groups, struct dom_sid **user_sids)
    852993{
    853994        ADS_STRUCT *ads = NULL;
     
    8601001        int i;
    8611002        struct dom_sid primary_group;
    862         uint32 primary_group_rid;
     1003        uint32_t primary_group_rid;
    8631004        NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
    8641005        uint32_t num_groups = 0;
     
    9851126        }
    9861127
    987         *p_num_groups = (uint32)num_groups;
     1128        *p_num_groups = (uint32_t)num_groups;
    9881129        status = (*user_sids != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
    9891130
     
    9991140static NTSTATUS lookup_useraliases(struct winbindd_domain *domain,
    10001141                                   TALLOC_CTX *mem_ctx,
    1001                                    uint32 num_sids, const struct dom_sid *sids,
    1002                                    uint32 *num_aliases, uint32 **alias_rids)
    1003 {
    1004         return reconnect_methods.lookup_useraliases(domain, mem_ctx,
    1005                                                     num_sids, sids,
    1006                                                     num_aliases,
    1007                                                     alias_rids);
     1142                                   uint32_t num_sids, const struct dom_sid *sids,
     1143                                   uint32_t *num_aliases, uint32_t **alias_rids)
     1144{
     1145        return msrpc_methods.lookup_useraliases(domain, mem_ctx, num_sids, sids,
     1146                                                num_aliases, alias_rids);
     1147}
     1148
     1149static NTSTATUS add_primary_group_members(
     1150        ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, uint32_t rid,
     1151        char ***all_members, size_t *num_all_members)
     1152{
     1153        char *filter;
     1154        NTSTATUS status = NT_STATUS_NO_MEMORY;
     1155        ADS_STATUS rc;
     1156        const char *attrs[] = { "dn", NULL };
     1157        LDAPMessage *res = NULL;
     1158        LDAPMessage *msg;
     1159        char **members;
     1160        size_t num_members;
     1161        ads_control args;
     1162
     1163        filter = talloc_asprintf(
     1164                mem_ctx, "(&(objectCategory=user)(primaryGroupID=%u))",
     1165                (unsigned)rid);
     1166        if (filter == NULL) {
     1167                goto done;
     1168        }
     1169
     1170        args.control = ADS_EXTENDED_DN_OID;
     1171        args.val = ADS_EXTENDED_DN_HEX_STRING;
     1172        args.critical = True;
     1173
     1174        rc = ads_do_search_all_args(ads, ads->config.bind_path,
     1175                                    LDAP_SCOPE_SUBTREE, filter, attrs, &args,
     1176                                    &res);
     1177
     1178        if (!ADS_ERR_OK(rc)) {
     1179                status = ads_ntstatus(rc);
     1180                DEBUG(1,("%s: ads_search: %s\n", __func__, ads_errstr(rc)));
     1181                goto done;
     1182        }
     1183        if (res == NULL) {
     1184                DEBUG(1,("%s: ads_search returned NULL res\n", __func__));
     1185                goto done;
     1186        }
     1187
     1188        num_members = ads_count_replies(ads, res);
     1189
     1190        DEBUG(10, ("%s: Got %ju primary group members\n", __func__,
     1191                   (uintmax_t)num_members));
     1192
     1193        if (num_members == 0) {
     1194                status = NT_STATUS_OK;
     1195                goto done;
     1196        }
     1197
     1198        members = talloc_realloc(mem_ctx, *all_members, char *,
     1199                                 *num_all_members + num_members);
     1200        if (members == NULL) {
     1201                DEBUG(1, ("%s: talloc_realloc failed\n", __func__));
     1202                goto done;
     1203        }
     1204        *all_members = members;
     1205
     1206        for (msg = ads_first_entry(ads, res); msg != NULL;
     1207             msg = ads_next_entry(ads, msg)) {
     1208                char *dn;
     1209
     1210                dn = ads_get_dn(ads, members, msg);
     1211                if (dn == NULL) {
     1212                        DEBUG(1, ("%s: ads_get_dn failed\n", __func__));
     1213                        continue;
     1214                }
     1215
     1216                members[*num_all_members] = dn;
     1217                *num_all_members += 1;
     1218        }
     1219
     1220        status = NT_STATUS_OK;
     1221done:
     1222        if (res != NULL) {
     1223                ads_msgfree(ads, res);
     1224        }
     1225        TALLOC_FREE(filter);
     1226        return status;
    10081227}
    10091228
     
    10151234                                const struct dom_sid *group_sid,
    10161235                                enum lsa_SidType type,
    1017                                 uint32 *num_names,
     1236                                uint32_t *num_names,
    10181237                                struct dom_sid **sid_mem, char ***names,
    1019                                 uint32 **name_types)
     1238                                uint32_t **name_types)
    10201239{
    10211240        ADS_STATUS rc;
     
    10321251        enum lsa_SidType *name_types_nocache = NULL;
    10331252        char **domains_nocache = NULL;     /* only needed for rpccli_lsa_lookup_sids */
    1034         uint32 num_nocache = 0;
     1253        uint32_t num_nocache = 0;
    10351254        TALLOC_CTX *tmp_ctx = NULL;
     1255        uint32_t rid;
    10361256
    10371257        DEBUG(10,("ads: lookup_groupmem %s sid=%s\n", domain->name,
     
    10441264                DEBUG(1, ("ads: lookup_groupmem: talloc failed\n"));
    10451265                status = NT_STATUS_NO_MEMORY;
     1266                goto done;
     1267        }
     1268
     1269        if (!sid_peek_rid(group_sid, &rid)) {
     1270                DEBUG(1, ("%s: sid_peek_rid failed\n", __func__));
     1271                status = NT_STATUS_INVALID_PARAMETER;
    10461272                goto done;
    10471273        }
     
    10881314
    10891315        DEBUG(10, ("ads lookup_groupmem: got %d sids via extended dn call\n", (int)num_members));
     1316
     1317        status = add_primary_group_members(ads, mem_ctx, rid,
     1318                                           &members, &num_members);
     1319        if (!NT_STATUS_IS_OK(status)) {
     1320                DEBUG(10, ("%s: add_primary_group_members failed: %s\n",
     1321                           __func__, nt_errstr(status)));
     1322                goto done;
     1323        }
     1324
     1325        DEBUG(10, ("%s: Got %d sids after adding primary group members\n",
     1326                   __func__, (int)num_members));
    10901327
    10911328        /* Now that we have a list of sids, we need to get the
     
    11021339
    11031340        if (num_members) {
    1104                 (*sid_mem) = TALLOC_ZERO_ARRAY(mem_ctx, struct dom_sid, num_members);
    1105                 (*names) = TALLOC_ZERO_ARRAY(mem_ctx, char *, num_members);
    1106                 (*name_types) = TALLOC_ZERO_ARRAY(mem_ctx, uint32, num_members);
    1107                 (sid_mem_nocache) = TALLOC_ZERO_ARRAY(tmp_ctx, struct dom_sid, num_members);
     1341                (*sid_mem) = talloc_zero_array(mem_ctx, struct dom_sid, num_members);
     1342                (*names) = talloc_zero_array(mem_ctx, char *, num_members);
     1343                (*name_types) = talloc_zero_array(mem_ctx, uint32_t, num_members);
     1344                (sid_mem_nocache) = talloc_zero_array(tmp_ctx, struct dom_sid, num_members);
    11081345
    11091346                if ((members == NULL) || (*sid_mem == NULL) ||
     
    12441481
    12451482/* find the sequence number for a domain */
    1246 static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
     1483static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32_t *seq)
    12471484{
    12481485        ADS_STRUCT *ads = NULL;
     
    12771514                        ads->is_mine = True;
    12781515                        ads_destroy(&ads);
    1279                         ads_kdestroy("MEMORY:winbind_ccache");
     1516                        ads_kdestroy(WINBIND_CCACHE_NAME);
    12801517                        domain->private_data = NULL;
    12811518                }
     
    12891526                               struct samr_DomInfo12 *policy)
    12901527{
    1291         return reconnect_methods.lockout_policy(domain, mem_ctx, policy);
     1528        return msrpc_methods.lockout_policy(domain, mem_ctx, policy);
    12921529}
    12931530
     
    12971534                                struct samr_DomInfo1 *policy)
    12981535{
    1299         return reconnect_methods.password_policy(domain, mem_ctx, policy);
     1536        return msrpc_methods.password_policy(domain, mem_ctx, policy);
    13001537}
    13011538
     
    13081545        WERROR werr;
    13091546        int                     i;
    1310         uint32                  flags; 
     1547        uint32_t                flags;
    13111548        struct rpc_pipe_client *cli;
    13121549        int ret_count;
     
    13731610
    13741611                if ((trust->trust_attributes
    1375                      == NETR_TRUST_ATTRIBUTE_QUARANTINED_DOMAIN) &&
     1612                     == LSA_TRUST_ATTRIBUTE_QUARANTINED_DOMAIN) &&
    13761613                    !domain->primary )
    13771614                {
     
    13851622                /* add to the trusted domain cache */
    13861623
    1387                 fstrcpy(d.name, trust->netbios_name);
    1388                 fstrcpy(d.alt_name, trust->dns_name);
     1624                d.name = discard_const_p(char, trust->netbios_name);
     1625                d.alt_name = discard_const_p(char, trust->dns_name);
     1626
    13891627                if (trust->sid) {
    13901628                        sid_copy(&d.sid, trust->sid);
  • vendor/current/source3/winbindd/winbindd_allocate_gid.c

    r740 r988  
    2020#include "includes.h"
    2121#include "winbindd.h"
    22 #include "librpc/gen_ndr/ndr_wbint_c.h"
     22#include "librpc/gen_ndr/ndr_winbind_c.h"
    2323
    2424struct winbindd_allocate_gid_state {
  • vendor/current/source3/winbindd/winbindd_allocate_uid.c

    r740 r988  
    2020#include "includes.h"
    2121#include "winbindd.h"
    22 #include "librpc/gen_ndr/ndr_wbint_c.h"
     22#include "librpc/gen_ndr/ndr_winbind_c.h"
    2323
    2424struct winbindd_allocate_uid_state {
  • vendor/current/source3/winbindd/winbindd_cache.c

    r860 r988  
    2929#include "tdb_validate.h"
    3030#include "../libcli/auth/libcli_auth.h"
    31 #include "../librpc/gen_ndr/ndr_wbint.h"
     31#include "../librpc/gen_ndr/ndr_winbind.h"
    3232#include "ads.h"
    3333#include "nss_info.h"
     
    4747extern struct winbindd_methods reconnect_methods;
    4848#ifdef HAVE_ADS
    49 extern struct winbindd_methods ads_methods;
     49extern struct winbindd_methods reconnect_ads_methods;
    5050#endif
    5151extern struct winbindd_methods builtin_passdb_methods;
     
    6060static const char *non_centry_keys[] = {
    6161        "SEQNUM/",
    62         "DR/",
    63         "DE/",
    6462        "WINBINDD_OFFLINE",
    6563        WINBINDD_CACHE_VERSION_KEYSTR,
     
    102100struct cache_entry {
    103101        NTSTATUS status;
    104         uint32 sequence_number;
     102        uint32_t sequence_number;
    105103        uint64_t timeout;
    106         uint8 *data;
    107         uint32 len, ofs;
     104        uint8_t *data;
     105        uint32_t len, ofs;
    108106};
    109107
     
    123121        if (domain->internal) {
    124122                domain->backend = &builtin_passdb_methods;
    125                 domain->initialized = True;
     123        }
     124
     125        if (dom_sid_equal(&domain->sid, &global_sid_Builtin)) {
     126                domain->initialized = true;
    126127        }
    127128
    128129        if (strequal(domain->name, get_global_sam_name()) &&
    129             sid_check_is_domain(&domain->sid)) {
     130            sid_check_is_our_sam(&domain->sid)) {
    130131                domain->backend = &sam_passdb_methods;
    131                 domain->initialized = True;
    132132        }
    133133
    134134        if ( !domain->initialized ) {
    135                 init_dc_connection( domain );
     135                /* We do not need a connection to an RW DC for cache operation */
     136                init_dc_connection(domain, false);
    136137        }
    137138
     
    168169                    && !lp_winbind_rpc_only()) {
    169170                        DEBUG(5,("get_cache: Setting ADS methods for domain %s\n", domain->name));
    170                         domain->backend = &ads_methods;
     171                        domain->backend = &reconnect_ads_methods;
    171172                } else {
    172173#endif  /* HAVE_ADS */
     
    228229
    229230/*
    230   pull a uint32 from a cache entry
     231  pull a uint32_t from a cache entry
    231232*/
    232 static uint32 centry_uint32(struct cache_entry *centry)
    233 {
    234         uint32 ret;
     233static uint32_t centry_uint32(struct cache_entry *centry)
     234{
     235        uint32_t ret;
    235236
    236237        if (!centry_check_bytes(centry, 4)) {
     
    243244
    244245/*
    245   pull a uint16 from a cache entry
     246  pull a uint16_t from a cache entry
    246247*/
    247 static uint16 centry_uint16(struct cache_entry *centry)
    248 {
    249         uint16 ret;
     248static uint16_t centry_uint16(struct cache_entry *centry)
     249{
     250        uint16_t ret;
    250251        if (!centry_check_bytes(centry, 2)) {
    251252                smb_panic_fn("centry_uint16");
     
    257258
    258259/*
    259   pull a uint8 from a cache entry
     260  pull a uint8_t from a cache entry
    260261*/
    261 static uint8 centry_uint8(struct cache_entry *centry)
    262 {
    263         uint8 ret;
     262static uint8_t centry_uint8(struct cache_entry *centry)
     263{
     264        uint8_t ret;
    264265        if (!centry_check_bytes(centry, 1)) {
    265266                smb_panic_fn("centry_uint8");
     
    281282        ret = IVAL(centry->data, centry->ofs);
    282283        centry->ofs += 4;
    283         ret += (uint64)IVAL(centry->data, centry->ofs) << 32;
     284        ret += (uint64_t)IVAL(centry->data, centry->ofs) << 32;
    284285        centry->ofs += 4;
    285286        return ret;
     
    299300static char *centry_string(struct cache_entry *centry, TALLOC_CTX *mem_ctx)
    300301{
    301         uint32 len;
     302        uint32_t len;
    302303        char *ret;
    303304
     
    313314        }
    314315
    315         ret = TALLOC_ARRAY(mem_ctx, char, len+1);
     316        ret = talloc_array(mem_ctx, char, len+1);
    316317        if (!ret) {
    317318                smb_panic_fn("centry_string out of memory\n");
     
    328329static char *centry_hash16(struct cache_entry *centry, TALLOC_CTX *mem_ctx)
    329330{
    330         uint32 len;
     331        uint32_t len;
    331332        char *ret;
    332333
     
    343344        }
    344345
    345         ret = TALLOC_ARRAY(mem_ctx, char, 16);
     346        ret = talloc_array(mem_ctx, char, 16);
    346347        if (!ret) {
    347348                smb_panic_fn("centry_hash out of memory\n");
     
    398399}
    399400
     401struct wcache_seqnum_state {
     402        uint32_t *seqnum;
     403        uint32_t *last_seq_check;
     404};
     405
     406static int wcache_seqnum_parser(TDB_DATA key, TDB_DATA data,
     407                                void *private_data)
     408{
     409        struct wcache_seqnum_state *state = private_data;
     410
     411        if (data.dsize != 8) {
     412                DEBUG(10, ("wcache_fetch_seqnum: invalid data size %d\n",
     413                           (int)data.dsize));
     414                return -1;
     415        }
     416
     417        *state->seqnum = IVAL(data.dptr, 0);
     418        *state->last_seq_check = IVAL(data.dptr, 4);
     419        return 0;
     420}
     421
    400422static bool wcache_fetch_seqnum(const char *domain_name, uint32_t *seqnum,
    401423                                uint32_t *last_seq_check)
    402424{
    403         char *key;
    404         TDB_DATA data;
     425        struct wcache_seqnum_state state = {
     426                .seqnum = seqnum, .last_seq_check = last_seq_check
     427        };
     428        size_t len = strlen(domain_name);
     429        char keystr[len+8];
     430        TDB_DATA key = { .dptr = (uint8_t *)keystr, .dsize = sizeof(keystr) };
     431        int ret;
    405432
    406433        if (wcache->tdb == NULL) {
     
    409436        }
    410437
    411         key = talloc_asprintf(talloc_tos(), "SEQNUM/%s", domain_name);
    412         if (key == NULL) {
    413                 DEBUG(10, ("talloc failed\n"));
    414                 return false;
    415         }
    416 
    417         data = tdb_fetch_bystring(wcache->tdb, key);
    418         TALLOC_FREE(key);
    419 
    420         if (data.dptr == NULL) {
    421                 DEBUG(10, ("wcache_fetch_seqnum: %s not found\n",
    422                            domain_name));
    423                 return false;
    424         }
    425         if (data.dsize != 8) {
    426                 DEBUG(10, ("wcache_fetch_seqnum: invalid data size %d\n",
    427                            (int)data.dsize));
    428                 SAFE_FREE(data.dptr);
    429                 return false;
    430         }
    431 
    432         *seqnum = IVAL(data.dptr, 0);
    433         *last_seq_check = IVAL(data.dptr, 4);
    434         SAFE_FREE(data.dptr);
    435 
    436         return true;
     438        snprintf(keystr, sizeof(keystr),  "SEQNUM/%s", domain_name);
     439
     440        ret = tdb_parse_record(wcache->tdb, key, wcache_seqnum_parser,
     441                               &state);
     442        return (ret == 0);
    437443}
    438444
    439445static NTSTATUS fetch_cache_seqnum( struct winbindd_domain *domain, time_t now )
    440446{
    441         uint32 last_check, time_diff;
     447        uint32_t last_check, time_diff;
    442448
    443449        if (!wcache_fetch_seqnum(domain->name, &domain->sequence_number,
     
    453459                DEBUG(10,("fetch_cache_seqnum: timeout [%s][%u @ %u]\n",
    454460                        domain->name, domain->sequence_number,
    455                         (uint32)domain->last_seq_check));
     461                        (uint32_t)domain->last_seq_check));
    456462                return NT_STATUS_UNSUCCESSFUL;
    457463        }
     
    459465        DEBUG(10,("fetch_cache_seqnum: success [%s][%u @ %u]\n",
    460466                domain->name, domain->sequence_number,
    461                 (uint32)domain->last_seq_check));
     467                (uint32_t)domain->last_seq_check));
    462468
    463469        return NT_STATUS_OK;
     
    467473                         time_t last_seq_check)
    468474{
    469         char *key_str;
     475        size_t len = strlen(domain_name);
     476        char keystr[len+8];
     477        TDB_DATA key = { .dptr = (uint8_t *)keystr, .dsize = sizeof(keystr) };
    470478        uint8_t buf[8];
    471479        int ret;
     
    476484        }
    477485
    478         key_str = talloc_asprintf(talloc_tos(), "SEQNUM/%s", domain_name);
    479         if (key_str == NULL) {
    480                 DEBUG(10, ("talloc_asprintf failed\n"));
    481                 return false;
    482         }
     486        snprintf(keystr, sizeof(keystr),  "SEQNUM/%s", domain_name);
    483487
    484488        SIVAL(buf, 0, seqnum);
    485489        SIVAL(buf, 4, last_seq_check);
    486490
    487         ret = tdb_store_bystring(wcache->tdb, key_str,
    488                                  make_tdb_data(buf, sizeof(buf)), TDB_REPLACE);
    489         TALLOC_FREE(key_str);
    490         if (ret == -1) {
     491        ret = tdb_store(wcache->tdb, key, make_tdb_data(buf, sizeof(buf)),
     492                        TDB_REPLACE);
     493        if (ret != 0) {
    491494                DEBUG(10, ("tdb_store_bystring failed: %s\n",
    492495                           tdb_errorstr(wcache->tdb)));
    493                 TALLOC_FREE(key_str);
    494496                return false;
    495497        }
     
    671673{
    672674        if (strequal(domain->name, get_global_sam_name()) &&
    673             sid_check_is_domain(&domain->sid)) {
     675            sid_check_is_our_sam(&domain->sid)) {
    674676                return true;
    675677        }
     
    758760  make sure we have at least len bytes available in a centry
    759761*/
    760 static void centry_expand(struct cache_entry *centry, uint32 len)
     762static void centry_expand(struct cache_entry *centry, uint32_t len)
    761763{
    762764        if (centry->len - centry->ofs >= len)
     
    782784
    783785/*
    784   push a uint32 into a centry
     786  push a uint32_t into a centry
    785787*/
    786 static void centry_put_uint32(struct cache_entry *centry, uint32 v)
     788static void centry_put_uint32(struct cache_entry *centry, uint32_t v)
    787789{
    788790        centry_expand(centry, 4);
     
    792794
    793795/*
    794   push a uint16 into a centry
     796  push a uint16_t into a centry
    795797*/
    796 static void centry_put_uint16(struct cache_entry *centry, uint16 v)
     798static void centry_put_uint16(struct cache_entry *centry, uint16_t v)
    797799{
    798800        centry_expand(centry, 2);
     
    802804
    803805/*
    804   push a uint8 into a centry
     806  push a uint8_t into a centry
    805807*/
    806 static void centry_put_uint8(struct cache_entry *centry, uint8 v)
     808static void centry_put_uint8(struct cache_entry *centry, uint8_t v)
    807809{
    808810        centry_expand(centry, 1);
     
    839841   push a 16 byte hash into a centry - treat as 16 byte string.
    840842 */
    841 static void centry_put_hash16(struct cache_entry *centry, const uint8 val[16])
     843static void centry_put_hash16(struct cache_entry *centry, const uint8_t val[16])
    842844{
    843845        centry_put_uint8(centry, 16);
     
    859861static void centry_put_ntstatus(struct cache_entry *centry, NTSTATUS status)
    860862{
    861         uint32 status_value = NT_STATUS_V(status);
     863        uint32_t status_value = NT_STATUS_V(status);
    862864        centry_put_uint32(centry, status_value);
    863865}
     
    889891  start a centry for output. When finished, call centry_end()
    890892*/
    891 struct cache_entry *centry_start(struct winbindd_domain *domain, NTSTATUS status)
     893static struct cache_entry *centry_start(struct winbindd_domain *domain,
     894                                        NTSTATUS status)
    892895{
    893896        struct cache_entry *centry;
     
    899902
    900903        centry->len = 8192; /* reasonable default */
    901         centry->data = SMB_XMALLOC_ARRAY(uint8, centry->len);
     904        centry->data = SMB_XMALLOC_ARRAY(uint8_t, centry->len);
    902905        centry->ofs = 0;
    903906        centry->sequence_number = domain->sequence_number;
     
    958961        centry_put_sid(centry, sid);
    959962        fstrcpy(uname, name);
    960         strupper_m(uname);
     963        (void)strupper_m(uname);
    961964        centry_end(centry, "NS/%s/%s", domain_name, uname);
    962965        DEBUG(10,("wcache_save_name_to_sid: %s\\%s -> %s (%s)\n", domain_name,
     
    990993
    991994        centry_end(centry, "SN/%s", sid_to_fstring(sid_string, sid));
    992         DEBUG(10,("wcache_save_sid_to_name: %s -> %s (%s)\n", sid_string,
    993                   name, nt_errstr(status)));
     995        DEBUG(10,("wcache_save_sid_to_name: %s -> %s\\%s (%s)\n", sid_string,
     996                  domain_name, name, nt_errstr(status)));
    994997        centry_free(centry);
    995998}
     
    10841087
    10851088        fstrcpy(uname, name);
    1086         strupper_m(uname);
     1089        (void)strupper_m(uname);
    10871090        centry_end(centry, "NSS/NA/%s", uname);
    10881091
     
    11051108
    11061109        fstrcpy(uname, alias);
    1107         strupper_m(uname);
     1110        (void)strupper_m(uname);
    11081111        centry_end(centry, "NSS/AN/%s", uname);
    11091112
     
    11311134                goto do_query;
    11321135
    1133         if ( (upper_name = SMB_STRDUP(name)) == NULL )
     1136        upper_name = talloc_strdup(mem_ctx, name);
     1137        if (upper_name == NULL) {
    11341138                return NT_STATUS_NO_MEMORY;
    1135         strupper_m(upper_name);
     1139        }
     1140        if (!strupper_m(upper_name)) {
     1141                talloc_free(upper_name);
     1142                return NT_STATUS_INVALID_PARAMETER;
     1143        }
    11361144
    11371145        centry = wcache_fetch(cache, domain, "NSS/NA/%s", upper_name);
    11381146
    1139         SAFE_FREE( upper_name );
     1147        talloc_free(upper_name);
    11401148
    11411149        if (!centry)
     
    12061214                goto do_query;
    12071215
    1208         if ( (upper_name = SMB_STRDUP(alias)) == NULL )
     1216        upper_name = talloc_strdup(mem_ctx, alias);
     1217        if (upper_name == NULL) {
    12091218                return NT_STATUS_NO_MEMORY;
    1210         strupper_m(upper_name);
     1219        }
     1220        if (!strupper_m(upper_name)) {
     1221                talloc_free(upper_name);
     1222                return NT_STATUS_INVALID_PARAMETER;
     1223        }
    12111224
    12121225        centry = wcache_fetch(cache, domain, "NSS/AN/%s", upper_name);
    12131226
    1214         SAFE_FREE( upper_name );
     1227        talloc_free(upper_name);
    12151228
    12161229        if (!centry)
     
    12761289        TDB_DATA data;
    12771290        fstring key_str, tmp;
    1278         uint32 rid;
     1291        uint32_t rid;
    12791292
    12801293        if (!cache->tdb) {
     
    13071320                          TALLOC_CTX *mem_ctx,
    13081321                          const struct dom_sid *sid,
    1309                           const uint8 **cached_nt_pass,
    1310                           const uint8 **cached_salt)
     1322                          const uint8_t **cached_nt_pass,
     1323                          const uint8_t **cached_salt)
    13111324{
    13121325        struct winbind_cache *cache = get_cache(domain);
    13131326        struct cache_entry *centry = NULL;
    13141327        NTSTATUS status;
    1315         time_t t;
    1316         uint32 rid;
     1328        uint32_t rid;
    13171329        fstring tmp;
    13181330
     
    13401352        }
    13411353
    1342         t = centry_time(centry);
     1354        /*
     1355         * We don't use the time element at this moment,
     1356         * but we have to consume it, so that we don't
     1357         * neet to change the disk format of the cache.
     1358         */
     1359        (void)centry_time(centry);
    13431360
    13441361        /* In the salted case this isn't actually the nt_hash itself,
     
    13471364           if we are returning a salted cred. */
    13481365
    1349         *cached_nt_pass = (const uint8 *)centry_hash16(centry, mem_ctx);
     1366        *cached_nt_pass = (const uint8_t *)centry_hash16(centry, mem_ctx);
    13501367        if (*cached_nt_pass == NULL) {
    13511368                fstring sidstr;
     
    13641381        /* We only have 17 bytes more data in the salted cred case. */
    13651382        if (centry->len - centry->ofs == 17) {
    1366                 *cached_salt = (const uint8 *)centry_hash16(centry, mem_ctx);
     1383                *cached_salt = (const uint8_t *)centry_hash16(centry, mem_ctx);
    13671384        } else {
    13681385                *cached_salt = NULL;
     
    13871404NTSTATUS wcache_save_creds(struct winbindd_domain *domain,
    13881405                           const struct dom_sid *sid,
    1389                            const uint8 nt_pass[NT_HASH_LEN])
     1406                           const uint8_t nt_pass[NT_HASH_LEN])
    13901407{
    13911408        struct cache_entry *centry;
    13921409        fstring sid_string;
    1393         uint32 rid;
    1394         uint8 cred_salt[NT_HASH_LEN];
    1395         uint8 salted_hash[NT_HASH_LEN];
     1410        uint32_t rid;
     1411        uint8_t cred_salt[NT_HASH_LEN];
     1412        uint8_t salted_hash[NT_HASH_LEN];
    13961413
    13971414        if (is_null_sid(sid)) {
     
    14311448static NTSTATUS query_user_list(struct winbindd_domain *domain,
    14321449                                TALLOC_CTX *mem_ctx,
    1433                                 uint32 *num_entries,
     1450                                uint32_t *num_entries,
    14341451                                struct wbint_userinfo **info)
    14351452{
     
    14531470                goto do_cached;
    14541471
    1455         (*info) = TALLOC_ARRAY(mem_ctx, struct wbint_userinfo, *num_entries);
     1472        (*info) = talloc_array(mem_ctx, struct wbint_userinfo, *num_entries);
    14561473        if (! (*info)) {
    14571474                smb_panic_fn("query_user_list out of memory");
     
    15061523                        DEBUG(3, ("query_user_list: flushing "
    15071524                                  "connection cache\n"));
    1508                         invalidate_cm_connection(&domain->conn);
     1525                        invalidate_cm_connection(domain);
    15091526                }
    15101527                if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT) ||
     
    15821599static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
    15831600                                TALLOC_CTX *mem_ctx,
    1584                                 uint32 *num_entries,
     1601                                uint32_t *num_entries,
    15851602                                struct wb_acct_info **info)
    15861603{
     
    16051622                goto do_cached;
    16061623
    1607         (*info) = TALLOC_ARRAY(mem_ctx, struct wb_acct_info, *num_entries);
     1624        (*info) = talloc_array(mem_ctx, struct wb_acct_info, *num_entries);
    16081625        if (! (*info)) {
    16091626                smb_panic_fn("enum_dom_groups out of memory");
     
    16771694static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
    16781695                                TALLOC_CTX *mem_ctx,
    1679                                 uint32 *num_entries,
     1696                                uint32_t *num_entries,
    16801697                                struct wb_acct_info **info)
    16811698{
     
    17001717                goto do_cached;
    17011718
    1702         (*info) = TALLOC_ARRAY(mem_ctx, struct wb_acct_info, *num_entries);
     1719        (*info) = talloc_array(mem_ctx, struct wb_acct_info, *num_entries);
    17031720        if (! (*info)) {
    17041721                smb_panic_fn("enum_dom_groups out of memory");
     
    18821899                /* Only save the reverse mapping if this was not a UPN */
    18831900                if (!strchr(name, '@')) {
    1884                         strupper_m(CONST_DISCARD(char *,domain_name));
    1885                         strlower_m(CONST_DISCARD(char *,name));
     1901                        if (!strupper_m(discard_const_p(char, domain_name))) {
     1902                                return NT_STATUS_INVALID_PARAMETER;
     1903                        }
     1904                        (void)strlower_m(discard_const_p(char, name));
    18861905                        wcache_save_sid_to_name(domain, status, sid, domain_name, name, *type);
    18871906                }
     
    18911910}
    18921911
    1893 NTSTATUS wcache_sid_to_name(struct winbindd_domain *domain,
    1894                             const struct dom_sid *sid,
    1895                             TALLOC_CTX *mem_ctx,
    1896                             char **domain_name,
    1897                             char **name,
    1898                             enum lsa_SidType *type)
     1912static NTSTATUS wcache_sid_to_name(struct winbindd_domain *domain,
     1913                                   const struct dom_sid *sid,
     1914                                   TALLOC_CTX *mem_ctx,
     1915                                   char **domain_name,
     1916                                   char **name,
     1917                                   enum lsa_SidType *type)
    18991918{
    19001919        struct winbind_cache *cache = get_cache(domain);
     
    20012020                              TALLOC_CTX *mem_ctx,
    20022021                              const struct dom_sid *domain_sid,
    2003                               uint32 *rids,
     2022                              uint32_t *rids,
    20042023                              size_t num_rids,
    20052024                              char **domain_name,
     
    20272046        }
    20282047
    2029         *names = TALLOC_ARRAY(mem_ctx, char *, num_rids);
    2030         *types = TALLOC_ARRAY(mem_ctx, enum lsa_SidType, num_rids);
     2048        *names = talloc_array(mem_ctx, char *, num_rids);
     2049        *types = talloc_array(mem_ctx, enum lsa_SidType, num_rids);
    20312050
    20322051        if ((*names == NULL) || (*types == NULL)) {
     
    20772096                        /* something's definitely wrong */
    20782097                        result = centry->status;
     2098                        centry_free(centry);
    20792099                        goto error;
    20802100                }
     
    21102130                        old_status) {
    21112131                        have_mapped = have_unmapped = false;
     2132
     2133                        *names = talloc_array(mem_ctx, char *, num_rids);
     2134                        if (*names == NULL) {
     2135                                result = NT_STATUS_NO_MEMORY;
     2136                                goto error;
     2137                        }
     2138
     2139                        *types = talloc_array(mem_ctx, enum lsa_SidType,
     2140                                              num_rids);
     2141                        if (*types == NULL) {
     2142                                result = NT_STATUS_NO_MEMORY;
     2143                                goto error;
     2144                        }
    21122145
    21132146                        for (i=0; i<num_rids; i++) {
     
    22832316}
    22842317
     2318
     2319/**
     2320* @brief Query a fullname from the username cache (for further gecos processing)
     2321*
     2322* @param domain         A pointer to the winbindd_domain struct.
     2323* @param mem_ctx        The talloc context.
     2324* @param user_sid       The user sid.
     2325* @param full_name      A pointer to the full_name string.
     2326*
     2327* @return NTSTATUS code
     2328*/
     2329NTSTATUS wcache_query_user_fullname(struct winbindd_domain *domain,
     2330                                    TALLOC_CTX *mem_ctx,
     2331                                    const struct dom_sid *user_sid,
     2332                                    const char **full_name)
     2333{
     2334        NTSTATUS status;
     2335        struct wbint_userinfo info;
     2336
     2337        status = wcache_query_user(domain, mem_ctx, user_sid, &info);
     2338        if (!NT_STATUS_IS_OK(status)) {
     2339                return status;
     2340        }
     2341
     2342        if (info.full_name != NULL) {
     2343                *full_name = talloc_strdup(mem_ctx, info.full_name);
     2344                if (*full_name == NULL) {
     2345                        return NT_STATUS_NO_MEMORY;
     2346                }
     2347        }
     2348
     2349        return NT_STATUS_OK;
     2350}
     2351
    22852352/* Lookup user information from a rid */
    22862353static NTSTATUS query_user(struct winbindd_domain *domain,
     
    23962463                                  TALLOC_CTX *mem_ctx,
    23972464                                  const struct dom_sid *user_sid,
    2398                                   uint32 *num_groups, struct dom_sid **user_gids)
     2465                                  uint32_t *num_groups, struct dom_sid **user_gids)
    23992466{
    24002467        struct cache_entry *centry = NULL;
     
    25462613static NTSTATUS lookup_useraliases(struct winbindd_domain *domain,
    25472614                                   TALLOC_CTX *mem_ctx,
    2548                                    uint32 num_sids, const struct dom_sid *sids,
    2549                                    uint32 *num_aliases, uint32 **alias_rids)
     2615                                   uint32_t num_sids, const struct dom_sid *sids,
     2616                                   uint32_t *num_aliases, uint32_t **alias_rids)
    25502617{
    25512618        struct cache_entry *centry = NULL;
     
    26522719        *sid_mem = talloc_array(mem_ctx, struct dom_sid, *num_names);
    26532720        *names = talloc_array(mem_ctx, char *, *num_names);
    2654         *name_types = talloc_array(mem_ctx, uint32, *num_names);
     2721        *name_types = talloc_array(mem_ctx, uint32_t, *num_names);
    26552722
    26562723        if ((*sid_mem == NULL) || (*names == NULL) || (*name_types == NULL)) {
     
    26812748                                const struct dom_sid *group_sid,
    26822749                                enum lsa_SidType type,
    2683                                 uint32 *num_names,
     2750                                uint32_t *num_names,
    26842751                                struct dom_sid **sid_mem, char ***names,
    2685                                 uint32 **name_types)
     2752                                uint32_t **name_types)
    26862753{
    26872754        struct cache_entry *centry = NULL;
     
    27522819
    27532820/* find the sequence number for a domain */
    2754 static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
     2821static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32_t *seq)
    27552822{
    27562823        refresh_sequence_number(domain, false);
     
    27962863
    27972864do_fetch_cache:
    2798         trusts->array = TALLOC_ZERO_ARRAY(mem_ctx, struct netr_DomainTrust, num_domains);
     2865        trusts->array = talloc_zero_array(mem_ctx, struct netr_DomainTrust, num_domains);
    27992866        if (!trusts->array) {
    28002867                TALLOC_FREE(dom_list);
     
    30343101        struct winbind_cache *cache;
    30353102
    3036         /* dont clear cached U/SID and UG/SID entries when we want to logon
     3103        /* don't clear cached U/SID and UG/SID entries when we want to logon
    30373104         * offline - gd */
    30383105
     
    31193186bool init_wcache(void)
    31203187{
     3188        char *db_path;
     3189
    31213190        if (wcache == NULL) {
    31223191                wcache = SMB_XMALLOC_P(struct winbind_cache);
     
    31273196                return true;
    31283197
     3198        db_path = state_path("winbindd_cache.tdb");
     3199        if (db_path == NULL) {
     3200                return false;
     3201        }
     3202
    31293203        /* when working offline we must not clear the cache on restart */
    3130         wcache->tdb = tdb_open_log(cache_path("winbindd_cache.tdb"),
     3204        wcache->tdb = tdb_open_log(db_path,
    31313205                                WINBINDD_CACHE_TDB_DEFAULT_HASH_SIZE,
    31323206                                TDB_INCOMPATIBLE_HASH |
    31333207                                        (lp_winbind_offline_logon() ? TDB_DEFAULT : (TDB_DEFAULT | TDB_CLEAR_IF_FIRST)),
    31343208                                O_RDWR|O_CREAT, 0600);
    3135 
     3209        TALLOC_FREE(db_path);
    31363210        if (wcache->tdb == NULL) {
    31373211                DEBUG(0,("Failed to open winbindd_cache.tdb!\n"));
     
    31513225{
    31523226        bool cache_bad = true;
    3153         uint32 vers;
     3227        uint32_t vers;
    31543228
    31553229        if (!init_wcache()) {
     
    31653239
    31663240        if (cache_bad) {
     3241                char *db_path;
     3242
    31673243                DEBUG(0,("initialize_winbindd_cache: clearing cache "
    31683244                        "and re-creating with version number %d\n",
     
    31723248                wcache->tdb = NULL;
    31733249
    3174                 if (unlink(cache_path("winbindd_cache.tdb")) == -1) {
     3250                db_path = state_path("winbindd_cache.tdb");
     3251                if (db_path == NULL) {
     3252                        return false;
     3253                }
     3254
     3255                if (unlink(db_path) == -1) {
    31753256                        DEBUG(0,("initialize_winbindd_cache: unlink %s failed %s ",
    3176                                 cache_path("winbindd_cache.tdb"),
     3257                                db_path,
    31773258                                strerror(errno) ));
     3259                        TALLOC_FREE(db_path);
    31783260                        return false;
    31793261                }
     3262                TALLOC_FREE(db_path);
    31803263                if (!init_wcache()) {
    31813264                        DEBUG(0,("initialize_winbindd_cache: re-initialization "
     
    32903373void wcache_flush_cache(void)
    32913374{
     3375        char *db_path;
     3376
    32923377        if (!wcache)
    32933378                return;
     
    33003385        }
    33013386
     3387        db_path = state_path("winbindd_cache.tdb");
     3388        if (db_path == NULL) {
     3389                return;
     3390        }
     3391
    33023392        /* when working offline we must not clear the cache on restart */
    3303         wcache->tdb = tdb_open_log(cache_path("winbindd_cache.tdb"),
    3304                                 WINBINDD_CACHE_TDB_DEFAULT_HASH_SIZE, 
     3393        wcache->tdb = tdb_open_log(db_path,
     3394                                WINBINDD_CACHE_TDB_DEFAULT_HASH_SIZE,
    33053395                                TDB_INCOMPATIBLE_HASH |
    33063396                                (lp_winbind_offline_logon() ? TDB_DEFAULT : (TDB_DEFAULT | TDB_CLEAR_IF_FIRST)),
    33073397                                O_RDWR|O_CREAT, 0600);
    3308 
     3398        TALLOC_FREE(db_path);
    33093399        if (!wcache->tdb) {
    33103400                DEBUG(0,("Failed to open winbindd_cache.tdb!\n"));
     
    34053495        if (ret == 0) {
    34063496                return NT_STATUS_OK;
    3407         } else if ((ret == -1) || (wcache_cred_list == NULL)) {
     3497        } else if ((ret < 0) || (wcache_cred_list == NULL)) {
    34083498                return NT_STATUS_OBJECT_NAME_NOT_FOUND;
    34093499        }
     
    35343624
    35353625        centry = SMB_XMALLOC_P(struct cache_entry);
    3536         centry->data = (unsigned char *)memdup(data.dptr, data.dsize);
     3626        centry->data = (unsigned char *)smb_memdup(data.dptr, data.dsize);
    35373627        if (!centry->data) {
    35383628                SAFE_FREE(centry);
     
    37193809{
    37203810        struct cache_entry *centry = create_centry_validate(keystr, dbuf, state);
    3721         int32 num_entries, i;
     3811        int32_t num_entries, i;
    37223812
    37233813        if (!centry) {
     
    37253815        }
    37263816
    3727         num_entries = (int32)centry_uint32(centry);
     3817        num_entries = (int32_t)centry_uint32(centry);
    37283818
    37293819        for (i=0; i< num_entries; i++) {
     
    37503840{
    37513841        struct cache_entry *centry = create_centry_validate(keystr, dbuf, state);
    3752         int32 num_entries, i;
     3842        int32_t num_entries, i;
    37533843
    37543844        if (!centry) {
     
    37773867{
    37783868        struct cache_entry *centry = create_centry_validate(keystr, dbuf, state);
    3779         int32 num_groups, i;
     3869        int32_t num_groups, i;
    37803870
    37813871        if (!centry) {
     
    38033893{
    38043894        struct cache_entry *centry = create_centry_validate(keystr, dbuf, state);
    3805         int32 num_aliases, i;
     3895        int32_t num_aliases, i;
    38063896
    38073897        if (!centry) {
     
    38283918{
    38293919        struct cache_entry *centry = create_centry_validate(keystr, dbuf, state);
    3830         int32 num_names, i;
     3920        int32_t num_names, i;
    38313921
    38323922        if (!centry) {
     
    40514141
    40524142        /* Paranoia check. */
    4053         if (strncmp("UA/", (const char *)kbuf.dptr, 3) == 0) {
     4143        if (strncmp("UA/", (const char *)kbuf.dptr, 3) == 0 ||
     4144            strncmp("NDR/", (const char *)kbuf.dptr, 4) == 0) {
    40544145                max_key_len = 1024 * 1024;
    40554146        }
     
    40924183
    40934184        DEBUG(0,("cache_traverse_validate_fn: unknown cache entry\nkey :\n"));
    4094         dump_data(0, (uint8 *)kbuf.dptr, kbuf.dsize);
     4185        dump_data(0, (uint8_t *)kbuf.dptr, kbuf.dsize);
    40954186        DEBUG(0,("data :\n"));
    4096         dump_data(0, (uint8 *)dbuf.dptr, dbuf.dsize);
     4187        dump_data(0, (uint8_t *)dbuf.dptr, dbuf.dsize);
    40974188        v_state->unknown_key = true;
    40984189        v_state->success = false;
     
    41794270{
    41804271        int ret = -1;
    4181         const char *tdb_path = cache_path("winbindd_cache.tdb");
     4272        char *tdb_path = NULL;
    41824273        TDB_CONTEXT *tdb = NULL;
    41834274        uint32_t vers_id;
     
    41874278        smb_panic_fn = validate_panic;
    41884279
    4189         tdb = tdb_open_log(tdb_path,
     4280        tdb_path = state_path("winbindd_cache.tdb");
     4281        if (tdb_path == NULL) {
     4282                goto done;
     4283        }
     4284
     4285        tdb = tdb_open_log(tdb_path,
    41904286                           WINBINDD_CACHE_TDB_DEFAULT_HASH_SIZE,
    41914287                           TDB_INCOMPATIBLE_HASH |
    4192                            ( lp_winbind_offline_logon() 
    4193                              ? TDB_DEFAULT 
     4288                           ( lp_winbind_offline_logon()
     4289                             ? TDB_DEFAULT
    41944290                             : TDB_DEFAULT | TDB_CLEAR_IF_FIRST ),
    4195                            O_RDWR|O_CREAT, 
     4291                           O_RDWR|O_CREAT,
    41964292                           0600);
    41974293        if (!tdb) {
     
    42354331
    42364332done:
     4333        TALLOC_FREE(tdb_path);
    42374334        DEBUG(10, ("winbindd_validate_cache: restoring panic function\n"));
    42384335        smb_panic_fn = smb_panic;
     
    42474344{
    42484345        int ret = -1;
    4249         const char *tdb_path = cache_path("winbindd_cache.tdb");
     4346        char *tdb_path;
    42504347
    42514348        DEBUG(10, ("winbindd_validate_cache: replacing panic function\n"));
    42524349        smb_panic_fn = validate_panic;
    42534350
     4351        tdb_path = state_path("winbindd_cache.tdb");
     4352        if (tdb_path == NULL) {
     4353                goto err_panic_restore;
     4354        }
    42544355
    42554356        if (wcache == NULL || wcache->tdb == NULL) {
     
    42644365        }
    42654366
     4367        TALLOC_FREE(tdb_path);
     4368err_panic_restore:
    42664369        DEBUG(10, ("winbindd_validate_cache_nobackup: restoring panic "
    42674370                   "function\n"));
     
    43144417        if ( !set_only ) {
    43154418                if ( !*domains ) {
    4316                         list = TALLOC_ARRAY( NULL, struct winbindd_tdc_domain, 1 );
     4419                        list = talloc_array( NULL, struct winbindd_tdc_domain, 1 );
    43174420                        idx = 0;
    43184421                } else {
    4319                         list = TALLOC_REALLOC_ARRAY( *domains, *domains,
     4422                        list = talloc_realloc( *domains, *domains,
    43204423                                                     struct winbindd_tdc_domain, 
    43214424                                                     (*num_domains)+1);
     
    43294432                return false;
    43304433
    4331         list[idx].domain_name = talloc_strdup( list, new_dom->name );
    4332         list[idx].dns_name = talloc_strdup( list, new_dom->alt_name );
     4434        list[idx].domain_name = talloc_strdup(list, new_dom->name);
     4435        if (list[idx].domain_name == NULL) {
     4436                return false;
     4437        }
     4438        if (new_dom->alt_name != NULL) {
     4439                list[idx].dns_name = talloc_strdup(list, new_dom->alt_name);
     4440                if (list[idx].dns_name == NULL) {
     4441                        return false;
     4442                }
     4443        }
    43334444
    43344445        if ( !is_null_sid( &new_dom->sid ) ) {
     
    44134524                len += tdb_pack( buffer+len, buflen-len, "fffddd",
    44144525                                 domains[i].domain_name,
    4415                                  domains[i].dns_name,
     4526                                 domains[i].dns_name ? domains[i].dns_name : "",
    44164527                                 sid_to_fstring(tmp, &domains[i].sid),
    44174528                                 domains[i].trust_flags,
     
    44444555{
    44454556        fstring domain_name, dns_name, sid_string;     
    4446         uint32 type, attribs, flags;
     4557        uint32_t type, attribs, flags;
    44474558        int num_domains;
    44484559        int len = 0;
     
    44574568        }
    44584569
    4459         list = TALLOC_ARRAY( NULL, struct winbindd_tdc_domain, num_domains );
     4570        list = talloc_array( NULL, struct winbindd_tdc_domain, num_domains );
    44604571        if ( !list ) {
    44614572                DEBUG(0,("unpack_tdc_domains: Failed to talloc() domain list!\n"));
     
    44644575
    44654576        for ( i=0; i<num_domains; i++ ) {
    4466                 len += tdb_unpack( buf+len, buflen-len, "fffddd",
     4577                int this_len;
     4578
     4579                this_len = tdb_unpack( buf+len, buflen-len, "fffddd",
    44674580                                   domain_name,
    44684581                                   dns_name,
     
    44724585                                   &type );
    44734586
    4474                 if ( len == -1 ) {
     4587                if ( this_len == -1 ) {
    44754588                        DEBUG(5,("unpack_tdc_domains: Failed to unpack domain array\n"));
    44764589                        TALLOC_FREE( list );                   
    44774590                        return 0;
    44784591                }
     4592                len += this_len;
    44794593
    44804594                DEBUG(11,("unpack_tdc_domains: Unpacking domain %s (%s) "
     
    44844598
    44854599                list[i].domain_name = talloc_strdup( list, domain_name );
    4486                 list[i].dns_name = talloc_strdup( list, dns_name );
     4600                list[i].dns_name = NULL;
     4601                if (dns_name[0] != '\0') {
     4602                        list[i].dns_name = talloc_strdup(list, dns_name);
     4603                }
    44874604                if ( !string_to_sid( &(list[i].sid), sid_string ) ) {                   
    44884605                        DEBUG(10,("unpack_tdc_domains: no SID for domain %s\n",
     
    45314648        SAFE_FREE( key.dptr );
    45324649
    4533         return ( ret != -1 );   
     4650        return ( ret == 0 );
    45344651}
    45354652
     
    46114728}
    46124729
     4730static struct winbindd_tdc_domain *wcache_tdc_dup_domain(
     4731        TALLOC_CTX *mem_ctx, const struct winbindd_tdc_domain *src)
     4732{
     4733        struct winbindd_tdc_domain *dst;
     4734
     4735        dst = talloc(mem_ctx, struct winbindd_tdc_domain);
     4736        if (dst == NULL) {
     4737                goto fail;
     4738        }
     4739        dst->domain_name = talloc_strdup(dst, src->domain_name);
     4740        if (dst->domain_name == NULL) {
     4741                goto fail;
     4742        }
     4743
     4744        dst->dns_name = NULL;
     4745        if (src->dns_name != NULL) {
     4746                dst->dns_name = talloc_strdup(dst, src->dns_name);
     4747                if (dst->dns_name == NULL) {
     4748                        goto fail;
     4749                }
     4750        }
     4751
     4752        sid_copy(&dst->sid, &src->sid);
     4753        dst->trust_flags = src->trust_flags;
     4754        dst->trust_type = src->trust_type;
     4755        dst->trust_attribs = src->trust_attribs;
     4756        return dst;
     4757fail:
     4758        TALLOC_FREE(dst);
     4759        return NULL;
     4760}
     4761
    46134762/*********************************************************************
    46144763 ********************************************************************/
     
    46244773
    46254774        if ( !init_wcache() ) {
    4626                 return false;
     4775                return NULL;
    46274776        }
    46284777
     
    46384787                                  name));
    46394788
    4640                         d = TALLOC_P( ctx, struct winbindd_tdc_domain );
    4641                         if ( !d )
    4642                                 break;                 
    4643 
    4644                         d->domain_name = talloc_strdup( d, dom_list[i].domain_name );
    4645                         d->dns_name = talloc_strdup( d, dom_list[i].dns_name );
    4646                         sid_copy( &d->sid, &dom_list[i].sid );
    4647                         d->trust_flags   = dom_list[i].trust_flags;
    4648                         d->trust_type    = dom_list[i].trust_type;
    4649                         d->trust_attribs = dom_list[i].trust_attribs;
    4650 
     4789                        d = wcache_tdc_dup_domain(ctx, &dom_list[i]);
    46514790                        break;
    46524791                }
     
    46744813
    46754814        if (!init_wcache()) {
    4676                 return false;
     4815                return NULL;
    46774816        }
    46784817
     
    46824821
    46834822        for (i = 0; i<num_domains; i++) {
    4684                 if (sid_equal(sid, &(dom_list[i].sid))) {
     4823                if (dom_sid_equal(sid, &(dom_list[i].sid))) {
    46854824                        DEBUG(10, ("wcache_tdc_fetch_domainbysid: "
    46864825                                   "Found domain %s for SID %s\n",
     
    46884827                                   sid_string_dbg(sid)));
    46894828
    4690                         d = TALLOC_P(ctx, struct winbindd_tdc_domain);
    4691                         if (!d)
    4692                                 break;
    4693 
    4694                         d->domain_name = talloc_strdup(d,
    4695                                                        dom_list[i].domain_name);
    4696 
    4697                         d->dns_name = talloc_strdup(d, dom_list[i].dns_name);
    4698                         sid_copy(&d->sid, &dom_list[i].sid);
    4699                         d->trust_flags = dom_list[i].trust_flags;
    4700                         d->trust_type = dom_list[i].trust_type;
    4701                         d->trust_attribs = dom_list[i].trust_attribs;
    4702 
     4829                        d = wcache_tdc_dup_domain(ctx, &dom_list[i]);
    47034830                        break;
    47044831                }
     
    47344861                                    const char *shell,
    47354862                                    const char *gecos,
    4736                                     uint32 gid)
     4863                                    uint32_t gid)
    47374864{
    47384865        struct cache_entry *centry;
     
    48354962};
    48364963
    4837 static bool wcache_ndr_key(TALLOC_CTX *mem_ctx, char *domain_name,
     4964static bool wcache_ndr_key(TALLOC_CTX *mem_ctx, const char *domain_name,
    48384965                           uint32_t opnum, const DATA_BLOB *req,
    48394966                           TDB_DATA *pkey)
  • vendor/current/source3/winbindd/winbindd_ccache_access.c

    r740 r988  
    77   Copyright (C) Jeremy Allison 2006 (minor fixes to fit into Samba and
    88                                      protect against integer wrap).
     9   Copyright (C) Andrew Bartlett 2011
    910
    1011   This program is free software; you can redistribute it and/or modify
     
    2425#include "includes.h"
    2526#include "winbindd.h"
    26 #include "../libcli/auth/ntlmssp.h"
     27#include "auth/gensec/gensec.h"
     28#include "auth_generic.h"
    2729
    2830#undef DBGC_CLASS
     
    4244}
    4345
    44 static NTSTATUS do_ntlm_auth_with_hashes(const char *username,
    45                                         const char *domain,
    46                                         const unsigned char lm_hash[LM_HASH_LEN],
    47                                         const unsigned char nt_hash[NT_HASH_LEN],
    48                                         const DATA_BLOB initial_msg,
    49                                         const DATA_BLOB challenge_msg,
    50                                         DATA_BLOB *auth_msg,
    51                                         uint8_t session_key[16])
     46static NTSTATUS do_ntlm_auth_with_stored_pw(const char *username,
     47                                            const char *domain,
     48                                            const char *password,
     49                                            const DATA_BLOB initial_msg,
     50                                            const DATA_BLOB challenge_msg,
     51                                            TALLOC_CTX *mem_ctx,
     52                                            DATA_BLOB *auth_msg,
     53                                            uint8_t session_key[16],
     54                                            uint8_t *new_spnego)
    5255{
    5356        NTSTATUS status;
    54         struct ntlmssp_state *ntlmssp_state = NULL;
    55         DATA_BLOB dummy_msg, reply;
    56 
    57         status = ntlmssp_client_start(NULL,
    58                                       global_myname(),
    59                                       lp_workgroup(),
    60                                       lp_client_ntlmv2_auth(),
    61                                       &ntlmssp_state);
     57        struct auth_generic_state *auth_generic_state = NULL;
     58        DATA_BLOB reply, session_key_blob;
     59
     60        status = auth_generic_client_prepare(mem_ctx, &auth_generic_state);
    6261
    6362        if (!NT_STATUS_IS_OK(status)) {
     
    6766        }
    6867
    69         status = ntlmssp_set_username(ntlmssp_state, username);
     68        status = auth_generic_set_username(auth_generic_state, username);
    7069
    7170        if (!NT_STATUS_IS_OK(status)) {
     
    7574        }
    7675
    77         status = ntlmssp_set_domain(ntlmssp_state, domain);
     76        status = auth_generic_set_domain(auth_generic_state, domain);
    7877
    7978        if (!NT_STATUS_IS_OK(status)) {
     
    8382        }
    8483
    85         status = ntlmssp_set_hashes(ntlmssp_state, lm_hash, nt_hash);
    86 
    87         if (!NT_STATUS_IS_OK(status)) {
    88                 DEBUG(1, ("Could not set hashes: %s\n",
    89                         nt_errstr(status)));
    90                 goto done;
    91         }
    92 
    93         ntlmssp_want_feature(ntlmssp_state, NTLMSSP_FEATURE_SESSION_KEY);
    94 
    95         /* We need to get our protocol handler into the right state. So first
    96            we ask it to generate the initial message. Actually the client has already
    97            sent its own initial message, so we're going to drop this one on the floor.
    98            The client might have sent a different message, for example with different
    99            negotiation options, but as far as I can tell this won't hurt us. (Unless
    100            the client sent a different username or domain, in which case that's their
    101            problem for telling us the wrong username or domain.)
    102            Since we have a copy of the initial message that the client sent, we could
    103            resolve any discrepancies if we had to.
    104         */
    105         dummy_msg = data_blob_null;
     84        status = auth_generic_set_password(auth_generic_state, password);
     85
     86        if (!NT_STATUS_IS_OK(status)) {
     87                DEBUG(1, ("Could not set password: %s\n",
     88                        nt_errstr(status)));
     89                goto done;
     90        }
     91
     92        if (initial_msg.length == 0) {
     93                gensec_want_feature(auth_generic_state->gensec_security,
     94                                    GENSEC_FEATURE_SESSION_KEY);
     95        }
     96
     97        status = auth_generic_client_start_by_name(auth_generic_state,
     98                                                   "ntlmssp_resume_ccache");
     99        if (!NT_STATUS_IS_OK(status)) {
     100                DEBUG(1, ("Could not start NTLMSSP resume mech: %s\n",
     101                        nt_errstr(status)));
     102                goto done;
     103        }
     104
     105        /*
     106         * We inject the inital NEGOTIATE message our caller used
     107         * in order to get the state machine into the correct possition.
     108         */
    106109        reply = data_blob_null;
    107         status = ntlmssp_update(ntlmssp_state, dummy_msg, &reply);
    108         data_blob_free(&dummy_msg);
     110        status = gensec_update(auth_generic_state->gensec_security,
     111                               talloc_tos(), initial_msg, &reply);
    109112        data_blob_free(&reply);
    110113
     
    116119
    117120        /* Now we are ready to handle the server's actual response. */
    118         status = ntlmssp_update(ntlmssp_state, challenge_msg, &reply);
    119 
     121        status = gensec_update(auth_generic_state->gensec_security,
     122                               mem_ctx, challenge_msg, &reply);
    120123        if (!NT_STATUS_EQUAL(status, NT_STATUS_OK)) {
    121124                DEBUG(1, ("We didn't get a response to the challenge! [%s]\n",
     
    125128        }
    126129
    127         if (ntlmssp_state->session_key.length != 16) {
     130        status = gensec_session_key(auth_generic_state->gensec_security,
     131                                    talloc_tos(), &session_key_blob);
     132        if (!NT_STATUS_EQUAL(status, NT_STATUS_OK)) {
     133                DEBUG(1, ("We didn't get the session key we requested! [%s]\n",
     134                        nt_errstr(status)));
     135                data_blob_free(&reply);
     136                goto done;
     137        }
     138
     139        if (session_key_blob.length != 16) {
    128140                DEBUG(1, ("invalid session key length %d\n",
    129                           (int)ntlmssp_state->session_key.length));
     141                          (int)session_key_blob.length));
    130142                data_blob_free(&reply);
    131143                goto done;
    132144        }
    133 
    134         *auth_msg = data_blob(reply.data, reply.length);
    135         memcpy(session_key, ntlmssp_state->session_key.data, 16);
     145        memcpy(session_key, session_key_blob.data, 16);
     146        data_blob_free(&session_key_blob);
     147        *auth_msg = reply;
     148        *new_spnego = gensec_have_feature(auth_generic_state->gensec_security,
     149                                          GENSEC_FEATURE_NEW_SPNEGO);
    136150        status = NT_STATUS_OK;
    137151
    138152done:
    139         TALLOC_FREE(ntlmssp_state);
     153        TALLOC_FREE(auth_generic_state);
    140154        return status;
    141155}
     
    145159        int ret;
    146160        uid_t ret_uid;
     161        gid_t ret_gid;
    147162
    148163        ret_uid = (uid_t)-1;
    149164
    150         ret = sys_getpeereid(state->sock, &ret_uid);
     165        ret = getpeereid(state->sock, &ret_uid, &ret_gid);
    151166        if (ret != 0) {
    152167                DEBUG(1, ("check_client_uid: Could not get socket peer uid: %s; "
     
    155170        }
    156171
    157         if (uid != ret_uid) {
     172        if (uid != ret_uid && ret_uid != sec_initial_uid()) {
    158173                DEBUG(1, ("check_client_uid: Client lied about its uid: said %u, "
    159174                        "actually was %u; denying access\n",
     
    172187        struct WINBINDD_MEMORY_CREDS *entry;
    173188        DATA_BLOB initial, challenge, auth;
    174         uint32 initial_blob_len, challenge_blob_len, extra_len;
     189        uint32_t initial_blob_len, challenge_blob_len, extra_len;
    175190
    176191        /* Ensure null termination */
     
    258273                state->request->data.ccache_ntlm_auth.challenge_blob_len);
    259274
    260         result = do_ntlm_auth_with_hashes(
    261                 name_user, name_domain, entry->lm_hash, entry->nt_hash,
    262                 initial, challenge, &auth,
    263                 state->response->data.ccache_ntlm_auth.session_key);
     275        result = do_ntlm_auth_with_stored_pw(
     276                name_user, name_domain, entry->pass,
     277                initial, challenge, talloc_tos(), &auth,
     278                state->response->data.ccache_ntlm_auth.session_key,
     279                &state->response->data.ccache_ntlm_auth.new_spnego);
    264280
    265281        if (!NT_STATUS_IS_OK(result)) {
  • vendor/current/source3/winbindd/winbindd_change_machine_acct.c

    r740 r988  
    2121#include "includes.h"
    2222#include "winbindd.h"
    23 #include "librpc/gen_ndr/ndr_wbint_c.h"
     23#include "librpc/gen_ndr/ndr_winbind_c.h"
    2424
    2525struct winbindd_change_machine_acct_state {
     
    5353                 * Internal domains are passdb based, we can always
    5454                 * contact them.
     55                 *
     56                 * This also protects us from changing the password on
     57                 * the AD DC without updating all the right databases.
     58                 * Do not remove this until that code is fixed.
    5559                 */
    5660                tevent_req_done(req);
  • vendor/current/source3/winbindd/winbindd_check_machine_acct.c

    r740 r988  
    2020#include "includes.h"
    2121#include "winbindd.h"
    22 #include "librpc/gen_ndr/ndr_wbint_c.h"
     22#include "librpc/gen_ndr/ndr_winbind_c.h"
    2323
    2424struct winbindd_check_machine_acct_state {
  • vendor/current/source3/winbindd/winbindd_cm.c

    r919 r988  
    7777#include "passdb.h"
    7878#include "messages.h"
     79#include "auth/gensec/gensec.h"
     80#include "../libcli/smb/smbXcli_base.h"
     81#include "libcli/auth/netlogon_creds_cli.h"
     82#include "auth.h"
     83#include "rpc_server/rpc_ncacn_np.h"
     84#include "auth/credentials/credentials.h"
     85#include "lib/param/param.h"
    7986
    8087#undef DBGC_CLASS
     
    8996extern bool override_logfile;
    9097
    91 static NTSTATUS init_dc_connection_network(struct winbindd_domain *domain);
     98static NTSTATUS init_dc_connection_network(struct winbindd_domain *domain, bool need_rw_dc);
    9299static void set_dc_type_and_flags( struct winbindd_domain *domain );
     100static bool set_dc_type_and_flags_trustinfo( struct winbindd_domain *domain );
    93101static bool get_dcs(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain,
    94102                    struct dc_name_ip **dcs, int *num_dcs);
     
    171179                           check so always does network calls. */
    172180
    173                         init_dc_connection_network(domain);
     181                        init_dc_connection_network(domain, true);
    174182                        break;
    175183                }
     
    188196        int num_dcs = 0;
    189197        TALLOC_CTX *mem_ctx = NULL;
    190         pid_t parent_pid = sys_getpid();
     198        pid_t parent_pid = getpid();
    191199        char *lfile = NULL;
    192200        NTSTATUS status;
     
    206214        }
    207215
    208         domain->dc_probe_pid = sys_fork();
     216        domain->dc_probe_pid = fork();
    209217
    210218        if (domain->dc_probe_pid == (pid_t)-1) {
     
    242250                                   pid_to_procid(parent_pid),
    243251                                   MSG_WINBIND_FAILED_TO_GO_ONLINE,
    244                                    (uint8 *)domain->name,
     252                                   (const uint8_t *)domain->name,
    245253                                   strlen(domain->name)+1);
    246254                _exit(1);
     
    254262                                   pid_to_procid(parent_pid),
    255263                                   MSG_WINBIND_FAILED_TO_GO_ONLINE,
    256                                    (uint8 *)domain->name,
     264                                   (const uint8_t *)domain->name,
    257265                                   strlen(domain->name)+1);
    258266                _exit(1);
     
    264272                                   pid_to_procid(parent_pid),
    265273                                   MSG_WINBIND_FAILED_TO_GO_ONLINE,
    266                                    (uint8 *)domain->name,
     274                                   (const uint8_t *)domain->name,
    267275                                   strlen(domain->name)+1);
    268276                _exit(0);
     
    275283                           pid_to_procid(parent_pid),
    276284                           MSG_WINBIND_TRY_TO_GO_ONLINE,
    277                            (uint8 *)domain->name,
     285                           (const uint8_t *)domain->name,
    278286                           strlen(domain->name)+1);
    279287        _exit(0);
     
    284292****************************************************************/
    285293
    286 static void check_domain_online_handler(struct event_context *ctx,
    287                                         struct timed_event *te,
     294static void check_domain_online_handler(struct tevent_context *ctx,
     295                                        struct tevent_timer *te,
    288296                                        struct timeval now,
    289297                                        void *private_data)
     
    420428        calc_new_online_timeout_check(domain);
    421429
    422         domain->check_online_event = event_add_timed(winbind_event_context(),
     430        domain->check_online_event = tevent_add_timer(winbind_event_context(),
    423431                                                NULL,
    424432                                                timeval_current_ofs(domain->check_online_timeout,0),
     
    439447                                   pid_to_procid(parent_pid),
    440448                                   MSG_WINBIND_DOMAIN_OFFLINE,
    441                                    (uint8 *)domain->name,
     449                                   (uint8_t *)domain->name,
    442450                                   strlen(domain->name) + 1);
    443451        }
     
    453461                                           pid_to_procid(idmap->pid),
    454462                                           MSG_WINBIND_OFFLINE,
    455                                            (uint8 *)domain->name,
     463                                           (const uint8_t *)domain->name,
    456464                                           strlen(domain->name)+1);
    457465                }                       
     
    525533                                   pid_to_procid(parent_pid),
    526534                                   MSG_WINBIND_DOMAIN_ONLINE,
    527                                    (uint8 *)domain->name,
     535                                   (uint8_t *)domain->name,
    528536                                   strlen(domain->name) + 1);
    529537        }
     
    539547                                           pid_to_procid(idmap->pid),
    540548                                           MSG_WINBIND_ONLINE,
    541                                            (uint8 *)domain->name,
     549                                           (const uint8_t *)domain->name,
    542550                                           strlen(domain->name)+1);
    543551                }                       
     
    596604        TALLOC_FREE(domain->check_online_event);
    597605
    598         domain->check_online_event = event_add_timed(winbind_event_context(),
     606        domain->check_online_event = tevent_add_timer(winbind_event_context(),
    599607                                                     NULL,
    600608                                                     tev,
     
    621629           remove it. */
    622630        saf_delete(domain->name);
    623         if (*domain->alt_name) {
     631        if (domain->alt_name != NULL) {
    624632                add_failed_connection_entry(domain->alt_name, server, result);
    625633                saf_delete(domain->alt_name);
     
    659667                *password = smb_xstrdup("");
    660668        }
     669}
     670
     671static NTSTATUS cm_get_ipc_credentials(TALLOC_CTX *mem_ctx,
     672                                       struct cli_credentials **_creds)
     673{
     674
     675        TALLOC_CTX *frame = talloc_stackframe();
     676        NTSTATUS status = NT_STATUS_INTERNAL_ERROR;
     677        struct loadparm_context *lp_ctx;
     678        char *username = NULL;
     679        char *netbios_domain = NULL;
     680        char *password = NULL;
     681        struct cli_credentials *creds = NULL;
     682        bool ok;
     683
     684        cm_get_ipc_userpass(&username, &netbios_domain, &password);
     685
     686        lp_ctx = loadparm_init_s3(frame, loadparm_s3_helpers());
     687        if (lp_ctx == NULL) {
     688                DEBUG(1, ("loadparm_init_s3 failed\n"));
     689                status = NT_STATUS_INTERNAL_ERROR;
     690                goto fail;
     691        }
     692
     693        creds = cli_credentials_init(mem_ctx);
     694        if (creds == NULL) {
     695                status = NT_STATUS_NO_MEMORY;
     696                goto fail;
     697        }
     698
     699        cli_credentials_set_conf(creds, lp_ctx);
     700        cli_credentials_set_kerberos_state(creds, CRED_DONT_USE_KERBEROS);
     701
     702        ok = cli_credentials_set_domain(creds, netbios_domain, CRED_SPECIFIED);
     703        if (!ok) {
     704                status = NT_STATUS_NO_MEMORY;
     705                goto fail;
     706        }
     707
     708        ok = cli_credentials_set_username(creds, username, CRED_SPECIFIED);
     709        if (!ok) {
     710                status = NT_STATUS_NO_MEMORY;
     711                goto fail;
     712        }
     713
     714        ok = cli_credentials_set_password(creds, password, CRED_SPECIFIED);
     715        if (!ok) {
     716                status = NT_STATUS_NO_MEMORY;
     717                goto fail;
     718        }
     719
     720        *_creds = creds;
     721        creds = NULL;
     722        status = NT_STATUS_OK;
     723 fail:
     724        TALLOC_FREE(creds);
     725        SAFE_FREE(username);
     726        SAFE_FREE(netbios_domain);
     727        SAFE_FREE(password);
     728        TALLOC_FREE(frame);
     729        return status;
     730}
     731
     732static bool cm_is_ipc_credentials(struct cli_credentials *creds)
     733{
     734        TALLOC_CTX *frame = talloc_stackframe();
     735        char *ipc_account = NULL;
     736        char *ipc_domain = NULL;
     737        char *ipc_password = NULL;
     738        const char *creds_account = NULL;
     739        const char *creds_domain = NULL;
     740        const char *creds_password = NULL;
     741        bool ret = false;
     742
     743        cm_get_ipc_userpass(&ipc_account, &ipc_domain, &ipc_password);
     744
     745        creds_account = cli_credentials_get_username(creds);
     746        creds_domain = cli_credentials_get_domain(creds);
     747        creds_password = cli_credentials_get_password(creds);
     748
     749        if (!strequal(ipc_domain, creds_domain)) {
     750                goto done;
     751        }
     752
     753        if (!strequal(ipc_account, creds_account)) {
     754                goto done;
     755        }
     756
     757        if (!strcsequal(ipc_password, creds_password)) {
     758                goto done;
     759        }
     760
     761        ret = true;
     762 done:
     763        SAFE_FREE(ipc_account);
     764        SAFE_FREE(ipc_domain);
     765        SAFE_FREE(ipc_password);
     766        TALLOC_FREE(frame);
     767        return ret;
    661768}
    662769
     
    725832                                return false;
    726833                        }
    727                         if (strlen(domain->alt_name) == 0) {
    728                                 fstrcpy(domain->alt_name,
    729                                         domain_info->domain_name);
     834                        if (domain->alt_name == NULL) {
     835                                domain->alt_name = talloc_strdup(domain,
     836                                                                 domain_info->domain_name);
     837                                if (domain->alt_name == NULL) {
     838                                        DEBUG(0, ("talloc_strdup failed\n"));
     839                                        talloc_destroy(mem_ctx);
     840                                        return false;
     841                                }
    730842                        }
    731                         if (strlen(domain->forest_name) == 0) {
    732                                 fstrcpy(domain->forest_name,
    733                                         domain_info->forest_name);
     843                        if (domain->forest_name == NULL) {
     844                                domain->forest_name = talloc_strdup(domain,
     845                                                                    domain_info->forest_name);
     846                                if (domain->forest_name == NULL) {
     847                                        DEBUG(0, ("talloc_strdup failed\n"));
     848                                        talloc_destroy(mem_ctx);
     849                                        return false;
     850                                }
    734851                        }
    735852                }
     
    778895 * Helper function to assemble trust password and account name
    779896 */
    780 static NTSTATUS get_trust_creds(const struct winbindd_domain *domain,
    781                                 char **machine_password,
    782                                 char **machine_account,
    783                                 char **machine_krb5_principal)
    784 {
    785         const char *account_name;
    786         const char *name = NULL;
     897static NTSTATUS get_trust_credentials(struct winbindd_domain *domain,
     898                                      TALLOC_CTX *mem_ctx,
     899                                      bool netlogon,
     900                                      struct cli_credentials **_creds)
     901{
     902        const struct winbindd_domain *creds_domain = NULL;
     903        struct cli_credentials *creds;
     904        NTSTATUS status;
     905        bool force_machine_account = false;
    787906
    788907        /* If we are a DC and this is not our own domain */
    789908
    790         if (IS_DC) {
    791                 name = domain->name;
     909        if (!domain->active_directory) {
     910                if (!netlogon) {
     911                        /*
     912                         * For non active directory domains
     913                         * we can only use NTLMSSP for SMB.
     914                         *
     915                         * But the trust account is not allowed
     916                         * to use SMB with NTLMSSP.
     917                         */
     918                        force_machine_account = true;
     919                }
     920        }
     921
     922        if (IS_DC && !force_machine_account) {
     923                creds_domain = domain;
    792924        } else {
    793                 struct winbindd_domain *our_domain = find_our_domain();
    794 
    795                 if (!our_domain)
    796                         return NT_STATUS_INVALID_SERVER_STATE;         
    797 
    798                 name = our_domain->name;               
    799         }       
    800 
    801         if (!get_trust_pw_clear(name, machine_password,
    802                                 &account_name, NULL))
    803         {
     925                creds_domain = find_our_domain();
     926                if (creds_domain == NULL) {
     927                        return NT_STATUS_INVALID_SERVER_STATE;
     928                }
     929        }
     930
     931        status = pdb_get_trust_credentials(creds_domain->name,
     932                                           creds_domain->alt_name,
     933                                           mem_ctx,
     934                                           &creds);
     935        if (!NT_STATUS_IS_OK(status)) {
     936                goto ipc_fallback;
     937        }
     938
     939        if (domain->primary && lp_security() == SEC_ADS) {
     940                cli_credentials_set_kerberos_state(creds,
     941                                                   CRED_AUTO_USE_KERBEROS);
     942        } else if (domain->active_directory) {
     943                cli_credentials_set_kerberos_state(creds,
     944                                                   CRED_MUST_USE_KERBEROS);
     945        } else {
     946                cli_credentials_set_kerberos_state(creds,
     947                                                   CRED_DONT_USE_KERBEROS);
     948        }
     949
     950        if (creds_domain != domain) {
     951                /*
     952                 * We can only use schannel against a direct trust
     953                 */
     954                cli_credentials_set_secure_channel_type(creds,
     955                                                        SEC_CHAN_NULL);
     956        }
     957
     958        *_creds = creds;
     959        return NT_STATUS_OK;
     960
     961 ipc_fallback:
     962        if (netlogon) {
    804963                return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
    805964        }
    806965
    807         if ((machine_account != NULL) &&
    808             (asprintf(machine_account, "%s$", account_name) == -1))
    809         {
    810                 return NT_STATUS_NO_MEMORY;
    811         }
    812 
    813         /* For now assume our machine account only exists in our domain */
    814 
    815         if (machine_krb5_principal != NULL)
    816         {
    817                 struct winbindd_domain *our_domain = find_our_domain();
    818 
    819                 if (!our_domain) {
    820                         return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;                       
    821                 }
    822 
    823                 if (asprintf(machine_krb5_principal, "%s$@%s",
    824                              account_name, our_domain->alt_name) == -1)
    825                 {
    826                         return NT_STATUS_NO_MEMORY;
    827                 }
    828 
    829                 strupper_m(*machine_krb5_principal);
    830         }
    831 
     966        status = cm_get_ipc_credentials(mem_ctx, &creds);
     967        if (!NT_STATUS_IS_OK(status)) {
     968                return status;
     969        }
     970
     971        *_creds = creds;
    832972        return NT_STATUS_OK;
    833973}
     
    838978************************************************************************/
    839979
    840 static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain,
     980static NTSTATUS cm_prepare_connection(struct winbindd_domain *domain,
    841981                                      const int sockfd,
    842982                                      const char *controller,
     
    844984                                      bool *retry)
    845985{
    846         char *machine_password = NULL;
    847         char *machine_krb5_principal = NULL;
    848         char *machine_account = NULL;
    849         char *ipc_username = NULL;
    850         char *ipc_domain = NULL;
    851         char *ipc_password = NULL;
     986        bool try_ipc_auth = false;
     987        const char *machine_password = NULL;
     988        const char *machine_krb5_principal = NULL;
     989        const char *machine_account = NULL;
     990        const char *machine_domain = NULL;
     991        int flags = 0;
     992        struct cli_credentials *creds = NULL;
     993        enum credentials_use_kerberos krb5_state;
    852994
    853995        struct named_mutex *mutex;
     
    855997        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
    856998
    857         struct sockaddr peeraddr;
    858         socklen_t peeraddr_len;
    859 
    860         struct sockaddr_in *peeraddr_in =
    861                 (struct sockaddr_in *)(void *)&peeraddr;
     999        enum smb_signing_setting smb_sign_client_connections = lp_client_ipc_signing();
     1000
     1001        if (smb_sign_client_connections == SMB_SIGNING_DEFAULT) {
     1002                /*
     1003                 * If we are connecting to our own AD domain, require
     1004                 * smb signing to disrupt MITM attacks
     1005                 */
     1006                if (domain->primary && lp_security() == SEC_ADS) {
     1007                        smb_sign_client_connections = SMB_SIGNING_REQUIRED;
     1008                /*
     1009                 * If we are in or are an AD domain and connecting to another
     1010                 * AD domain in our forest
     1011                 * then require smb signing to disrupt MITM attacks
     1012                 */
     1013                } else if ((lp_security() == SEC_ADS ||
     1014                            lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC)
     1015                           && domain->active_directory
     1016                           && (domain->domain_trust_attribs
     1017                               & LSA_TRUST_ATTRIBUTE_WITHIN_FOREST)) {
     1018                        smb_sign_client_connections = SMB_SIGNING_REQUIRED;
     1019                }
     1020        }
    8621021
    8631022        DEBUG(10,("cm_prepare_connection: connecting to DC %s for domain %s\n",
     
    8691028                                 WINBIND_SERVER_MUTEX_WAIT_TIME);
    8701029        if (mutex == NULL) {
     1030                close(sockfd);
    8711031                DEBUG(0,("cm_prepare_connection: mutex grab failed for %s\n",
    8721032                         controller));
     
    8751035        }
    8761036
    877         if ((*cli = cli_initialise()) == NULL) {
     1037        flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
     1038
     1039        *cli = cli_state_create(NULL, sockfd,
     1040                                controller, domain->alt_name,
     1041                                smb_sign_client_connections, flags);
     1042        if (*cli == NULL) {
     1043                close(sockfd);
    8781044                DEBUG(1, ("Could not cli_initialize\n"));
    8791045                result = NT_STATUS_NO_MEMORY;
     
    8811047        }
    8821048
    883         (*cli)->timeout = 10000;        /* 10 seconds */
    884         (*cli)->fd = sockfd;
    885         (*cli)->desthost = talloc_strdup((*cli), controller);
    886         if ((*cli)->desthost == NULL) {
    887                 result = NT_STATUS_NO_MEMORY;
    888                 goto done;
    889         }
    890 
    891         (*cli)->use_kerberos = True;
    892 
    893         peeraddr_len = sizeof(peeraddr);
    894 
    895         if ((getpeername((*cli)->fd, &peeraddr, &peeraddr_len) != 0)) {
    896                 DEBUG(0,("cm_prepare_connection: getpeername failed with: %s\n",
    897                         strerror(errno)));
    898                 result = NT_STATUS_UNSUCCESSFUL;
    899                 goto done;
    900         }
    901 
    902         if ((peeraddr_len != sizeof(struct sockaddr_in))
    903 #ifdef HAVE_IPV6
    904             && (peeraddr_len != sizeof(struct sockaddr_in6))
    905 #endif
    906             ) {
    907                 DEBUG(0,("cm_prepare_connection: got unexpected peeraddr len %d\n",
    908                         peeraddr_len));
    909                 result = NT_STATUS_UNSUCCESSFUL;
    910                 goto done;
    911         }
    912 
    913         if ((peeraddr_in->sin_family != PF_INET)
    914 #ifdef HAVE_IPV6
    915             && (peeraddr_in->sin_family != PF_INET6)
    916 #endif
    917             ) {
    918                 DEBUG(0,("cm_prepare_connection: got unexpected family %d\n",
    919                         peeraddr_in->sin_family));
    920                 result = NT_STATUS_UNSUCCESSFUL;
    921                 goto done;
    922         }
    923 
    924         result = cli_negprot(*cli);
     1049        cli_set_timeout(*cli, 10000); /* 10 seconds */
     1050
     1051        result = smbXcli_negprot((*cli)->conn, (*cli)->timeout,
     1052                                 lp_client_ipc_min_protocol(),
     1053                                 lp_client_ipc_max_protocol());
    9251054
    9261055        if (!NT_STATUS_IS_OK(result)) {
     
    9291058        }
    9301059
    931         if (!is_dc_trusted_domain_situation(domain->name) &&
    932             (*cli)->protocol >= PROTOCOL_NT1 &&
    933             (*cli)->capabilities & CAP_EXTENDED_SECURITY)
    934         {
    935                 ADS_STATUS ads_status;
    936 
    937                 result = get_trust_creds(domain, &machine_password,
    938                                          &machine_account,
    939                                          &machine_krb5_principal);
     1060        if (smbXcli_conn_protocol((*cli)->conn) >= PROTOCOL_NT1 &&
     1061            smb1cli_conn_capabilities((*cli)->conn) & CAP_EXTENDED_SECURITY) {
     1062                try_ipc_auth = true;
     1063        } else if (smbXcli_conn_protocol((*cli)->conn) >= PROTOCOL_SMB2_02) {
     1064                try_ipc_auth = true;
     1065        } else if (smb_sign_client_connections == SMB_SIGNING_REQUIRED) {
     1066                /*
     1067                 * If we are forcing on SMB signing, then we must
     1068                 * require authentication unless this is a one-way
     1069                 * trust, and we have no stored user/password
     1070                 */
     1071                try_ipc_auth = true;
     1072        }
     1073
     1074        if (try_ipc_auth) {
     1075                result = get_trust_credentials(domain, talloc_tos(), false, &creds);
    9401076                if (!NT_STATUS_IS_OK(result)) {
    941                         goto anon_fallback;
    942                 }
    943 
    944                 if (lp_security() == SEC_ADS) {
    945 
    946                         /* Try a krb5 session */
    947 
    948                         (*cli)->use_kerberos = True;
    949                         DEBUG(5, ("connecting to %s from %s with kerberos principal "
    950                                   "[%s] and realm [%s]\n", controller, global_myname(),
    951                                   machine_krb5_principal, domain->alt_name));
    952 
    953                         winbindd_set_locator_kdc_envs(domain);
    954 
    955                         ads_status = cli_session_setup_spnego(*cli,
    956                                                               machine_krb5_principal,
    957                                                               machine_password,
    958                                                               lp_workgroup(),
    959                                                               domain->alt_name);
    960 
    961                         if (!ADS_ERR_OK(ads_status)) {
    962                                 DEBUG(4,("failed kerberos session setup with %s\n",
    963                                          ads_errstr(ads_status)));
    964                         }
    965 
    966                         result = ads_ntstatus(ads_status);
    967                         if (NT_STATUS_IS_OK(result)) {
    968                                 /* Ensure creds are stored for NTLMSSP authenticated pipe access. */
    969                                 result = cli_init_creds(*cli, machine_account, lp_workgroup(), machine_password);
    970                                 if (!NT_STATUS_IS_OK(result)) {
    971                                         goto done;
    972                                 }
    973                                 goto session_setup_done;
    974                         }
    975                 }
    976 
     1077                        DEBUG(1, ("get_trust_credentials(%s) failed: %s\n",
     1078                                  domain->name, nt_errstr(result)));
     1079                        goto done;
     1080                }
     1081        } else {
     1082                /*
     1083                 * Without SPNEGO or NTLMSSP (perhaps via SMB2) we
     1084                 * would try and authentication with our machine
     1085                 * account password and fail.  This is very rare in
     1086                 * the modern world however
     1087                 */
     1088                creds = cli_credentials_init_anon(talloc_tos());
     1089                if (creds == NULL) {
     1090                        result = NT_STATUS_NO_MEMORY;
     1091                        DEBUG(1, ("cli_credentials_init_anon(%s) failed: %s\n",
     1092                                  domain->name, nt_errstr(result)));
     1093                        goto done;
     1094                }
     1095        }
     1096
     1097        krb5_state = cli_credentials_get_kerberos_state(creds);
     1098
     1099        machine_krb5_principal = cli_credentials_get_principal(creds,
     1100                                                        talloc_tos());
     1101        if (machine_krb5_principal == NULL) {
     1102                krb5_state = CRED_DONT_USE_KERBEROS;
     1103        }
     1104
     1105        machine_account = cli_credentials_get_username(creds);
     1106        machine_password = cli_credentials_get_password(creds);
     1107        machine_domain = cli_credentials_get_domain(creds);
     1108
     1109        if (krb5_state != CRED_DONT_USE_KERBEROS) {
     1110
     1111                /* Try a krb5 session */
     1112
     1113                (*cli)->use_kerberos = True;
     1114                DEBUG(5, ("connecting to %s from %s with kerberos principal "
     1115                          "[%s] and realm [%s]\n", controller, lp_netbios_name(),
     1116                          machine_krb5_principal, domain->alt_name));
     1117
     1118                winbindd_set_locator_kdc_envs(domain);
     1119
     1120                result = cli_session_setup(*cli,
     1121                                           machine_krb5_principal,
     1122                                           machine_password,
     1123                                           strlen(machine_password)+1,
     1124                                           machine_password,
     1125                                           strlen(machine_password)+1,
     1126                                           machine_domain);
     1127
     1128                if (NT_STATUS_IS_OK(result)) {
     1129                        goto session_setup_done;
     1130                }
     1131
     1132                DEBUG(4,("failed kerberos session setup with %s\n",
     1133                         nt_errstr(result)));
     1134        }
     1135
     1136        if (krb5_state != CRED_MUST_USE_KERBEROS) {
    9771137                /* Fall back to non-kerberos session setup using NTLMSSP SPNEGO with the machine account. */
    9781138                (*cli)->use_kerberos = False;
    9791139
    980                 DEBUG(5, ("connecting to %s from %s with username "
    981                           "[%s]\\[%s]\n",  controller, global_myname(),
    982                           lp_workgroup(), machine_account));
    983 
    984                 ads_status = cli_session_setup_spnego(*cli,
    985                                                       machine_account,
    986                                                       machine_password,
    987                                                       lp_workgroup(),
    988                                                       NULL);
    989                 if (!ADS_ERR_OK(ads_status)) {
    990                         DEBUG(4, ("authenticated session setup failed with %s\n",
    991                                 ads_errstr(ads_status)));
    992                 }
    993 
    994                 result = ads_ntstatus(ads_status);
    995                 if (NT_STATUS_IS_OK(result)) {
    996                         /* Ensure creds are stored for NTLMSSP authenticated pipe access. */
    997                         result = cli_init_creds(*cli, machine_account, lp_workgroup(), machine_password);
    998                         if (!NT_STATUS_IS_OK(result)) {
    999                                 goto done;
    1000                         }
    1001                         goto session_setup_done;
    1002                 }
    1003         }
    1004 
    1005         /* Fall back to non-kerberos session setup with auth_user */
    1006 
     1140                DEBUG(5, ("connecting to %s from %s using NTLMSSP with username "
     1141                          "[%s]\\[%s]\n",  controller, lp_netbios_name(),
     1142                          machine_domain, machine_account));
     1143
     1144                result = cli_session_setup(*cli,
     1145                                           machine_account,
     1146                                           machine_password,
     1147                                           strlen(machine_password)+1,
     1148                                           machine_password,
     1149                                           strlen(machine_password)+1,
     1150                                           machine_domain);
     1151        }
     1152
     1153        if (NT_STATUS_IS_OK(result)) {
     1154                goto session_setup_done;
     1155        }
     1156
     1157        /*
     1158         * If we are not going to validiate the conneciton
     1159         * with SMB signing, then allow us to fall back to
     1160         * anonymous
     1161         */
     1162        if (NT_STATUS_EQUAL(result, NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT)
     1163            || NT_STATUS_EQUAL(result, NT_STATUS_TRUSTED_DOMAIN_FAILURE)
     1164            || NT_STATUS_EQUAL(result, NT_STATUS_INVALID_ACCOUNT_NAME)
     1165            || NT_STATUS_EQUAL(result, NT_STATUS_NO_LOGON_SERVERS)
     1166            || NT_STATUS_EQUAL(result, NT_STATUS_LOGON_FAILURE))
     1167        {
     1168                if (cli_credentials_is_anonymous(creds)) {
     1169                        goto done;
     1170                }
     1171
     1172                if (!cm_is_ipc_credentials(creds)) {
     1173                        goto ipc_fallback;
     1174                }
     1175
     1176                if (smb_sign_client_connections == SMB_SIGNING_REQUIRED) {
     1177                        goto done;
     1178                }
     1179
     1180                goto anon_fallback;
     1181        }
     1182
     1183        DEBUG(4, ("authenticated session setup failed with %s\n",
     1184                nt_errstr(result)));
     1185
     1186        goto done;
     1187
     1188 ipc_fallback:
     1189        result = cm_get_ipc_credentials(talloc_tos(), &creds);
     1190        if (!NT_STATUS_IS_OK(result)) {
     1191                goto done;
     1192        }
     1193
     1194        if (cli_credentials_is_anonymous(creds)) {
     1195                TALLOC_FREE(creds);
     1196                goto anon_fallback;
     1197        }
     1198
     1199        machine_account = cli_credentials_get_username(creds);
     1200        machine_password = cli_credentials_get_password(creds);
     1201        machine_domain = cli_credentials_get_domain(creds);
     1202
     1203        /* Fall back to non-kerberos session setup using NTLMSSP SPNEGO with the ipc creds. */
    10071204        (*cli)->use_kerberos = False;
    10081205
    1009         cm_get_ipc_userpass(&ipc_username, &ipc_domain, &ipc_password);
    1010 
    1011         if ((((*cli)->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) != 0) &&
    1012             (strlen(ipc_username) > 0)) {
    1013 
    1014                 /* Only try authenticated if we have a username */
    1015 
    1016                 DEBUG(5, ("connecting to %s from %s with username "
    1017                           "[%s]\\[%s]\n",  controller, global_myname(),
    1018                           ipc_domain, ipc_username));
    1019 
    1020                 if (NT_STATUS_IS_OK(cli_session_setup(
    1021                                             *cli, ipc_username,
    1022                                             ipc_password, strlen(ipc_password)+1,
    1023                                             ipc_password, strlen(ipc_password)+1,
    1024                                             ipc_domain))) {
    1025                         /* Successful logon with given username. */
    1026                         result = cli_init_creds(*cli, ipc_username, ipc_domain, ipc_password);
    1027                         if (!NT_STATUS_IS_OK(result)) {
    1028                                 goto done;
    1029                         }
    1030                         goto session_setup_done;
    1031                 } else {
    1032                         DEBUG(4, ("authenticated session setup with user %s\\%s failed.\n",
    1033                                 ipc_domain, ipc_username ));
    1034                 }
    1035         }
     1206        DEBUG(5, ("connecting to %s from %s using NTLMSSP with username "
     1207                  "[%s]\\[%s]\n",  controller, lp_netbios_name(),
     1208                  machine_domain, machine_account));
     1209
     1210        result = cli_session_setup(*cli,
     1211                                   machine_account,
     1212                                   machine_password,
     1213                                   strlen(machine_password)+1,
     1214                                   machine_password,
     1215                                   strlen(machine_password)+1,
     1216                                   machine_domain);
     1217
     1218        if (NT_STATUS_IS_OK(result)) {
     1219                goto session_setup_done;
     1220        }
     1221
     1222        /*
     1223         * If we are not going to validiate the conneciton
     1224         * with SMB signing, then allow us to fall back to
     1225         * anonymous
     1226         */
     1227        if (NT_STATUS_EQUAL(result, NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT)
     1228            || NT_STATUS_EQUAL(result, NT_STATUS_TRUSTED_DOMAIN_FAILURE)
     1229            || NT_STATUS_EQUAL(result, NT_STATUS_INVALID_ACCOUNT_NAME)
     1230            || NT_STATUS_EQUAL(result, NT_STATUS_NO_LOGON_SERVERS)
     1231            || NT_STATUS_EQUAL(result, NT_STATUS_LOGON_FAILURE))
     1232        {
     1233                goto anon_fallback;
     1234        }
     1235
     1236        DEBUG(4, ("authenticated session setup failed with %s\n",
     1237                nt_errstr(result)));
     1238
     1239        goto done;
    10361240
    10371241 anon_fallback:
     1242
     1243        if (smb_sign_client_connections == SMB_SIGNING_REQUIRED) {
     1244                goto done;
     1245        }
    10381246
    10391247        /* Fall back to anonymous connection, this might fail later */
     
    10421250                controller ));
    10431251
    1044         if (NT_STATUS_IS_OK(cli_session_setup(*cli, "", NULL, 0,
    1045                                               NULL, 0, ""))) {
     1252        (*cli)->use_kerberos = False;
     1253
     1254        result = cli_session_setup(*cli, "", "", 0, "", 0, "");
     1255        if (NT_STATUS_IS_OK(result)) {
    10461256                DEBUG(5, ("Connected anonymously\n"));
    1047                 result = cli_init_creds(*cli, "", "", "");
    1048                 if (!NT_STATUS_IS_OK(result)) {
    1049                         goto done;
    1050                 }
    10511257                goto session_setup_done;
    10521258        }
    10531259
    1054         result = cli_nt_error(*cli);
    1055 
    1056         if (NT_STATUS_IS_OK(result))
    1057                 result = NT_STATUS_UNSUCCESSFUL;
    1058 
    10591260        /* We can't session setup */
    1060 
    10611261        goto done;
    10621262
    10631263 session_setup_done:
    10641264
    1065         /* cache the server name for later connections */
    1066 
    1067         saf_store( domain->name, (*cli)->desthost );
    1068         if (domain->alt_name && (*cli)->use_kerberos) {
    1069                 saf_store( domain->alt_name, (*cli)->desthost );
    1070         }
    1071 
    1072         winbindd_set_locator_kdc_envs(domain);
    1073 
    1074         result = cli_tcon_andx(*cli, "IPC$", "IPC", "", 0);
     1265        /*
     1266         * This should be a short term hack until
     1267         * dynamic re-authentication is implemented.
     1268         *
     1269         * See Bug 9175 - winbindd doesn't recover from
     1270         * NT_STATUS_NETWORK_SESSION_EXPIRED
     1271         */
     1272        if (smbXcli_conn_protocol((*cli)->conn) >= PROTOCOL_SMB2_02) {
     1273                smbXcli_session_set_disconnect_expired((*cli)->smb2.session);
     1274        }
     1275
     1276        result = cli_tree_connect(*cli, "IPC$", "IPC", "", 0);
    10751277
    10761278        if (!NT_STATUS_IS_OK(result)) {
     
    10791281        }
    10801282
     1283        /* cache the server name for later connections */
     1284
     1285        saf_store(domain->name, controller);
     1286        if (domain->alt_name && (*cli)->use_kerberos) {
     1287                saf_store(domain->alt_name, controller);
     1288        }
     1289
     1290        winbindd_set_locator_kdc_envs(domain);
     1291
    10811292        TALLOC_FREE(mutex);
    10821293        *retry = False;
    10831294
    1084         /* set the domain if empty; needed for schannel connections */
    1085         if ( !(*cli)->domain[0] ) {
    1086                 result = cli_set_domain((*cli), domain->name);
    1087                 if (!NT_STATUS_IS_OK(result)) {
    1088                         SAFE_FREE(ipc_username);
    1089                         SAFE_FREE(ipc_domain);
    1090                         SAFE_FREE(ipc_password);
    1091                         return result;
    1092                 }
    1093         }
    1094 
    10951295        result = NT_STATUS_OK;
    10961296
    10971297 done:
    10981298        TALLOC_FREE(mutex);
    1099         SAFE_FREE(machine_account);
    1100         SAFE_FREE(machine_password);
    1101         SAFE_FREE(machine_krb5_principal);
    1102         SAFE_FREE(ipc_username);
    1103         SAFE_FREE(ipc_domain);
    1104         SAFE_FREE(ipc_password);
    11051299
    11061300        if (!NT_STATUS_IS_OK(result)) {
     
    11481342                        return False;
    11491343
    1150         *dcs = TALLOC_REALLOC_ARRAY(mem_ctx, *dcs, struct dc_name_ip, (*num)+1);
     1344        *dcs = talloc_realloc(mem_ctx, *dcs, struct dc_name_ip, (*num)+1);
    11511345
    11521346        if (*dcs == NULL)
     
    11601354
    11611355static bool add_sockaddr_to_array(TALLOC_CTX *mem_ctx,
    1162                                   struct sockaddr_storage *pss, uint16 port,
     1356                                  struct sockaddr_storage *pss, uint16_t port,
    11631357                                  struct sockaddr_storage **addrs, int *num)
    11641358{
    1165         *addrs = TALLOC_REALLOC_ARRAY(mem_ctx, *addrs, struct sockaddr_storage, (*num)+1);
     1359        *addrs = talloc_realloc(mem_ctx, *addrs, struct sockaddr_storage, (*num)+1);
    11661360
    11671361        if (*addrs == NULL) {
     
    11841378                const struct winbindd_domain *domain,
    11851379                struct sockaddr_storage *pss,
    1186                 fstring name )
     1380                char **name)
    11871381{
    11881382        struct ip_service ip_list;
     
    11901384        NTSTATUS status;
    11911385        const char *dc_name;
    1192 
     1386        fstring nbtname;
     1387#ifdef HAVE_ADS
     1388        bool is_ad_domain = false;
     1389#endif
    11931390        ip_list.ss = *pss;
    11941391        ip_list.port = 0;
     
    11981395           None of these failures should be considered critical for now */
    11991396
    1200         if (lp_security() == SEC_ADS) {
     1397        if ((lp_security() == SEC_ADS) && (domain->alt_name != NULL)) {
     1398                is_ad_domain = true;
     1399        } else if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
     1400                is_ad_domain = domain->active_directory;
     1401        }
     1402
     1403        if (is_ad_domain) {
    12011404                ADS_STRUCT *ads;
    12021405                ADS_STATUS ads_status;
     
    12111414                if (ADS_ERR_OK(ads_status)) {
    12121415                        /* We got a cldap packet. */
    1213                         fstrcpy(name, ads->config.ldap_server_name);
    1214                         namecache_store(name, 0x20, 1, &ip_list);
     1416                        *name = talloc_strdup(mem_ctx,
     1417                                             ads->config.ldap_server_name);
     1418                        if (*name == NULL) {
     1419                                return false;
     1420                        }
     1421                        namecache_store(*name, 0x20, 1, &ip_list);
    12151422
    12161423                        DEBUG(10,("dcip_to_name: flags = 0x%x\n", (unsigned int)ads->config.flags));
     
    12181425                        if (domain->primary && (ads->config.flags & NBT_SERVER_KDC)) {
    12191426                                if (ads_closest_dc(ads)) {
    1220                                         char *sitename = sitename_fetch(ads->config.realm);
     1427                                        char *sitename = sitename_fetch(mem_ctx, ads->config.realm);
    12211428
    12221429                                        /* We're going to use this KDC for this realm/domain.
     
    12271434                                                                        domain->name,
    12281435                                                                        sitename,
    1229                                                                         pss,
    1230                                                                         name);
    1231 
    1232                                         SAFE_FREE(sitename);
     1436                                                                        pss);
     1437
     1438                                        TALLOC_FREE(sitename);
    12331439                                } else {
    12341440                                        /* use an off site KDC */
     
    12361442                                                                        domain->name,
    12371443                                                                        NULL,
    1238                                                                         pss,
    1239                                                                         name);
     1444                                                                        pss);
    12401445                                }
    12411446                                winbindd_set_locator_kdc_envs(domain);
    12421447
    12431448                                /* Ensure we contact this DC also. */
    1244                                 saf_store( domain->name, name);
    1245                                 saf_store( domain->alt_name, name);
     1449                                saf_store(domain->name, *name);
     1450                                saf_store(domain->alt_name, *name);
    12461451                        }
    12471452
     
    12591464                           &dc_name, NULL);
    12601465        if (NT_STATUS_IS_OK(status)) {
    1261                 fstrcpy(name, dc_name);
    1262                 namecache_store(name, 0x20, 1, &ip_list);
     1466                *name = talloc_strdup(mem_ctx, dc_name);
     1467                if (*name == NULL) {
     1468                        return false;
     1469                }
     1470                namecache_store(*name, 0x20, 1, &ip_list);
    12631471                return True;
    12641472        }
     
    12661474        /* try node status request */
    12671475
    1268         if ( name_status_find(domain->name, 0x1c, 0x20, pss, name) ) {
    1269                 namecache_store(name, 0x20, 1, &ip_list);
    1270                 return True;
     1476        if (name_status_find(domain->name, 0x1c, 0x20, pss, nbtname) ) {
     1477                namecache_store(nbtname, 0x20, 1, &ip_list);
     1478
     1479                if (name != NULL) {
     1480                        *name = talloc_strdup(mem_ctx, nbtname);
     1481                        if (*name == NULL) {
     1482                                return false;
     1483                        }
     1484                }
     1485
     1486                return true;
    12711487        }
    12721488        return False;
     
    13111527        }
    13121528
    1313         if (sec == SEC_ADS) {
     1529        if ((sec == SEC_ADS) && (domain->alt_name != NULL)) {
    13141530                char *sitename = NULL;
    13151531
     
    13251541                get_dc_name(domain->name, domain->alt_name, dcname, &ss);
    13261542
    1327                 sitename = sitename_fetch(domain->alt_name);
     1543                sitename = sitename_fetch(mem_ctx, domain->alt_name);
    13281544                if (sitename) {
    13291545
     
    13491565
    13501566                        SAFE_FREE(ip_list);
    1351                         SAFE_FREE(sitename);
     1567                        TALLOC_FREE(sitename);
    13521568                        iplist_size = 0;
    13531569                }
     
    13731589        }
    13741590
    1375         /* Try standard netbios queries if no ADS */
     1591        /* Try standard netbios queries if no ADS and fall back to DNS queries
     1592         * if alt_name is available */
    13761593        if (*num_dcs == 0) {
    13771594                get_sorted_dc_list(domain->name, NULL, &ip_list, &iplist_size,
    1378                        False);
     1595                       false);
     1596                if (iplist_size == 0) {
     1597                        if (domain->alt_name != NULL) {
     1598                                get_sorted_dc_list(domain->alt_name, NULL, &ip_list,
     1599                                       &iplist_size, true);
     1600                        }
     1601                }
    13791602
    13801603                for ( i=0; i<iplist_size; i++ ) {
     
    14101633static bool find_new_dc(TALLOC_CTX *mem_ctx,
    14111634                        struct winbindd_domain *domain,
    1412                         fstring dcname, struct sockaddr_storage *pss, int *fd)
     1635                        char **dcname, struct sockaddr_storage *pss, int *fd)
    14131636{
    14141637        struct dc_name_ip *dcs = NULL;
     
    14161639
    14171640        const char **dcnames = NULL;
    1418         int num_dcnames = 0;
     1641        size_t num_dcnames = 0;
    14191642
    14201643        struct sockaddr_storage *addrs = NULL;
     
    14381661                        return False;
    14391662                }
    1440                 if (!add_sockaddr_to_array(mem_ctx, &dcs[i].ss, 445,
     1663                if (!add_sockaddr_to_array(mem_ctx, &dcs[i].ss, TCP_SMB_PORT,
    14411664                                      &addrs, &num_addrs)) {
    14421665                        return False;
     
    14691692        if (*dcnames[fd_index] != '\0' && !is_ipaddress(dcnames[fd_index])) {
    14701693                /* Ok, we've got a name for the DC */
    1471                 fstrcpy(dcname, dcnames[fd_index]);
    1472                 return True;
     1694                *dcname = talloc_strdup(mem_ctx, dcnames[fd_index]);
     1695                if (*dcname == NULL) {
     1696                        return false;
     1697                }
     1698                return true;
    14731699        }
    14741700
     
    15121738        char *value = NULL;
    15131739
    1514         if (cli == NULL) {
     1740        if (!cli_state_is_connected(cli)) {
    15151741                return;
    15161742        }
    1517         if (cli->fd == -1) {
    1518                 return;
    1519         }
    1520         get_peer_addr(cli->fd, addr, sizeof(addr));
     1743
     1744        print_sockaddr(addr, sizeof(addr),
     1745                       smbXcli_conn_remote_sockaddr(cli->conn));
    15211746
    15221747        key = current_dc_key(talloc_tos(), domain_name);
     
    15401765                                    char **p_dc_name, char **p_dc_ip)
    15411766{
    1542         char *key, *value, *p;
     1767        char *key, *p;
     1768        char *value = NULL;
    15431769        bool ret = false;
    15441770        char *dc_name = NULL;
     
    15491775                goto done;
    15501776        }
    1551         if (!gencache_get(key, &value, NULL)) {
     1777        if (!gencache_get(key, mem_ctx, &value, NULL)) {
    15521778                goto done;
    15531779        }
     
    15781804        TALLOC_FREE(dc_ip);
    15791805        TALLOC_FREE(key);
     1806        TALLOC_FREE(value);
    15801807        return ret;
     1808}
     1809
     1810NTSTATUS wb_open_internal_pipe(TALLOC_CTX *mem_ctx,
     1811                               const struct ndr_interface_table *table,
     1812                               struct rpc_pipe_client **ret_pipe)
     1813{
     1814        struct rpc_pipe_client *cli = NULL;
     1815        const struct auth_session_info *session_info;
     1816        NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
     1817
     1818
     1819        session_info = get_session_info_system();
     1820        SMB_ASSERT(session_info != NULL);
     1821
     1822        /* create a connection to the specified pipe */
     1823        if (lp_parm_bool(-1, "winbindd", "use external pipes", false)) {
     1824                status = rpc_pipe_open_interface(mem_ctx,
     1825                                                 table,
     1826                                                 session_info,
     1827                                                 NULL,
     1828                                                 winbind_messaging_context(),
     1829                                                 &cli);
     1830        } else {
     1831                status = rpc_pipe_open_internal(mem_ctx,
     1832                                                &table->syntax_id,
     1833                                                session_info,
     1834                                                NULL,
     1835                                                winbind_messaging_context(),
     1836                                                &cli);
     1837        }
     1838        if (!NT_STATUS_IS_OK(status)) {
     1839                DEBUG(0, ("open_internal_pipe: Could not connect to %s pipe: %s\n",
     1840                          table->name, nt_errstr(status)));
     1841                return status;
     1842        }
     1843
     1844        if (ret_pipe) {
     1845                *ret_pipe = cli;
     1846        }
     1847
     1848        return NT_STATUS_OK;
    15811849}
    15821850
     
    15861854        TALLOC_CTX *mem_ctx;
    15871855        NTSTATUS result;
    1588         char *saf_servername = saf_fetch( domain->name );
     1856        char *saf_servername;
    15891857        int retries;
    15901858
    15911859        if ((mem_ctx = talloc_init("cm_open_connection")) == NULL) {
    1592                 SAFE_FREE(saf_servername);
    15931860                set_domain_offline(domain);
    15941861                return NT_STATUS_NO_MEMORY;
    15951862        }
     1863
     1864        saf_servername = saf_fetch(mem_ctx, domain->name );
    15961865
    15971866        /* we have to check the server affinity cache here since
     
    16091878                /* convert an ip address to a name */
    16101879                if (is_ipaddress( saf_servername ) ) {
    1611                         fstring saf_name;
     1880                        char *dcname = NULL;
    16121881                        struct sockaddr_storage ss;
    16131882
    16141883                        if (!interpret_string_addr(&ss, saf_servername,
    16151884                                                AI_NUMERICHOST)) {
     1885                                TALLOC_FREE(mem_ctx);
    16161886                                return NT_STATUS_UNSUCCESSFUL;
    16171887                        }
    1618                         if (dcip_to_name(mem_ctx, domain, &ss, saf_name )) {
    1619                                 fstrcpy( domain->dcname, saf_name );
     1888                        if (dcip_to_name(mem_ctx, domain, &ss, &dcname)) {
     1889                                domain->dcname = talloc_strdup(domain,
     1890                                                               dcname);
     1891                                if (domain->dcname == NULL) {
     1892                                        TALLOC_FREE(mem_ctx);
     1893                                        return NT_STATUS_NO_MEMORY;
     1894                                }
    16201895                        } else {
    16211896                                winbind_add_failed_connection_entry(
     
    16241899                        }
    16251900                } else {
    1626                         fstrcpy( domain->dcname, saf_servername );
    1627                 }
    1628 
    1629                 SAFE_FREE( saf_servername );
     1901                        domain->dcname = talloc_strdup(domain, saf_servername);
     1902                        if (domain->dcname == NULL) {
     1903                                TALLOC_FREE(mem_ctx);
     1904                                return NT_STATUS_NO_MEMORY;
     1905                        }
     1906                }
    16301907        }
    16311908
     
    16331910                int fd = -1;
    16341911                bool retry = False;
     1912                char *dcname = NULL;
    16351913
    16361914                result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
    16371915
    16381916                DEBUG(10,("cm_open_connection: dcname is '%s' for domain %s\n",
    1639                         domain->dcname, domain->name ));
    1640 
    1641                 if (*domain->dcname
     1917                        domain->dcname ? domain->dcname : "", domain->name ));
     1918
     1919                if (domain->dcname != NULL
    16421920                        && NT_STATUS_IS_OK(check_negative_conn_cache( domain->name, domain->dcname))
    16431921                        && (resolve_name(domain->dcname, &domain->dcaddr, 0x20, true)))
     
    16531931                }
    16541932
    1655                 if ((fd == -1)
    1656                         && !find_new_dc(mem_ctx, domain, domain->dcname, &domain->dcaddr, &fd))
     1933                if ((fd == -1) &&
     1934                    !find_new_dc(mem_ctx, domain, &dcname, &domain->dcaddr, &fd))
    16571935                {
    16581936                        /* This is the one place where we will
     
    16631941                        break;
    16641942                }
     1943                if (dcname != NULL) {
     1944                        talloc_free(domain->dcname);
     1945
     1946                        domain->dcname = talloc_move(domain, &dcname);
     1947                        if (domain->dcname == NULL) {
     1948                                result = NT_STATUS_NO_MEMORY;
     1949                                break;
     1950                        }
     1951                }
    16651952
    16661953                new_conn->cli = NULL;
     
    16781965
    16791966        if (NT_STATUS_IS_OK(result)) {
     1967                bool seal_pipes = true;
    16801968
    16811969                winbindd_set_locator_kdc_envs(domain);
     
    16971985                store_current_dc_in_gencache(domain->name, domain->dcname,
    16981986                                             new_conn->cli);
     1987
     1988                seal_pipes = lp_winbind_sealed_pipes();
     1989                seal_pipes = lp_parm_bool(-1, "winbind sealed pipes",
     1990                                          domain->name,
     1991                                          seal_pipes);
     1992
     1993                if (seal_pipes) {
     1994                        new_conn->auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
     1995                } else {
     1996                        new_conn->auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
     1997                }
    16991998        } else {
    17001999                /* Ensure we setup the retry handler. */
     
    17082007/* Close down all open pipes on a connection. */
    17092008
    1710 void invalidate_cm_connection(struct winbindd_cm_conn *conn)
     2009void invalidate_cm_connection(struct winbindd_domain *domain)
    17112010{
    17122011        NTSTATUS result;
     2012        struct winbindd_cm_conn *conn = &domain->conn;
    17132013
    17142014        /* We're closing down a possibly dead
     
    17692069        }
    17702070
     2071        conn->auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
     2072        conn->netlogon_force_reauth = false;
     2073        conn->netlogon_flags = 0;
     2074        TALLOC_FREE(conn->netlogon_creds);
     2075
    17712076        if (conn->cli) {
    17722077                cli_shutdown(conn->cli);
     
    17822087
    17832088        for (domain = domain_list(); domain; domain = domain->next) {
    1784                 struct cli_state *cli = domain->conn.cli;
    1785 
    17862089                /*
    17872090                 * first close the low level SMB TCP connection
     
    17892092                 * requests in invalidate_cm_connection()
    17902093                 */
    1791                 if (cli && cli->fd != -1) {
    1792                         close(domain->conn.cli->fd);
    1793                         domain->conn.cli->fd = -1;
    1794                 }
    1795 
    1796                 invalidate_cm_connection(&domain->conn);
     2094                if (cli_state_is_connected(domain->conn.cli)) {
     2095                        smbXcli_conn_disconnect(domain->conn.cli->conn, NT_STATUS_OK);
     2096                }
     2097
     2098                invalidate_cm_connection(domain);
    17972099        }
    17982100
     
    18292131   Bypass online status check so always does network calls. */
    18302132
    1831 static NTSTATUS init_dc_connection_network(struct winbindd_domain *domain)
     2133static NTSTATUS init_dc_connection_network(struct winbindd_domain *domain, bool need_rw_dc)
    18322134{
    18332135        NTSTATUS result;
     2136        bool skip_connection = domain->internal;
     2137        if (need_rw_dc && domain->rodc) {
     2138                skip_connection = false;
     2139        }
    18342140
    18352141        /* Internal connections never use the network. */
    1836         if (domain->internal) {
    1837                 domain->initialized = True;
    1838                 return NT_STATUS_OK;
    1839         }
    1840 
    1841         if (connection_ok(domain)) {
     2142        if (dom_sid_equal(&domain->sid, &global_sid_Builtin)) {
     2143                return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
     2144        }
     2145
     2146        /* Still ask the internal LSA and SAMR server about the local domain */
     2147        if (skip_connection || connection_ok(domain)) {
    18422148                if (!domain->initialized) {
    18432149                        set_dc_type_and_flags(domain);
     
    18462152        }
    18472153
    1848         invalidate_cm_connection(&domain->conn);
     2154        invalidate_cm_connection(domain);
     2155
     2156        if (!domain->primary && !domain->initialized) {
     2157                /*
     2158                 * Before we connect to a trust, work out if it is an
     2159                 * AD domain by asking our own domain.
     2160                 */
     2161                set_dc_type_and_flags_trustinfo(domain);
     2162        }
    18492163
    18502164        result = cm_open_connection(domain, &domain->conn);
     
    18572171}
    18582172
    1859 NTSTATUS init_dc_connection(struct winbindd_domain *domain)
    1860 {
    1861         if (domain->internal) {
     2173NTSTATUS init_dc_connection(struct winbindd_domain *domain, bool need_rw_dc)
     2174{
     2175        if (dom_sid_equal(&domain->sid, &global_sid_Builtin)) {
    18622176                return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
    18632177        }
     
    18682182        }
    18692183
    1870         return init_dc_connection_network(domain);
    1871 }
    1872 
    1873 static NTSTATUS init_dc_connection_rpc(struct winbindd_domain *domain)
     2184        return init_dc_connection_network(domain, need_rw_dc);
     2185}
     2186
     2187static NTSTATUS init_dc_connection_rpc(struct winbindd_domain *domain, bool need_rw_dc)
    18742188{
    18752189        NTSTATUS status;
    18762190
    1877         status = init_dc_connection(domain);
     2191        status = init_dc_connection(domain, need_rw_dc);
    18782192        if (!NT_STATUS_IS_OK(status)) {
    18792193                return status;
     
    18992213        struct netr_DomainTrustList trusts;
    19002214        int i;
    1901         uint32 flags = (NETR_TRUST_FLAG_IN_FOREST |
     2215        uint32_t flags = (NETR_TRUST_FLAG_IN_FOREST |
    19022216                        NETR_TRUST_FLAG_OUTBOUND |
    19032217                        NETR_TRUST_FLAG_INBOUND);
     
    19142228        }
    19152229
     2230        mem_ctx = talloc_stackframe();
    19162231        our_domain = find_our_domain();
    1917 
    1918         if ( !connection_ok(our_domain) ) {
    1919                 DEBUG(3,("set_dc_type_and_flags_trustinfo: No connection to our domain!\n"));           
     2232        if (our_domain->internal) {
     2233                result = init_dc_connection(our_domain, false);
     2234                if (!NT_STATUS_IS_OK(result)) {
     2235                        DEBUG(3,("set_dc_type_and_flags_trustinfo: "
     2236                                 "Not able to make a connection to our domain: %s\n",
     2237                                  nt_errstr(result)));
     2238                        TALLOC_FREE(mem_ctx);
     2239                        return false;
     2240                }
     2241        }
     2242
     2243        /* This won't work unless our domain is AD */
     2244        if ( !our_domain->active_directory ) {
     2245                TALLOC_FREE(mem_ctx);
    19202246                return False;
    19212247        }
    19222248
    1923         /* This won't work unless our domain is AD */
    1924 
    1925         if ( !our_domain->active_directory ) {
     2249        if (our_domain->internal) {
     2250                result = wb_open_internal_pipe(mem_ctx, &ndr_table_netlogon, &cli);
     2251        } else if (!connection_ok(our_domain)) {
     2252                DEBUG(3,("set_dc_type_and_flags_trustinfo: "
     2253                         "No connection to our domain!\n"));
     2254                TALLOC_FREE(mem_ctx);
    19262255                return False;
    1927         }
    1928 
    1929         /* Use DsEnumerateDomainTrusts to get us the trust direction
    1930            and type */
    1931 
    1932         result = cm_connect_netlogon(our_domain, &cli);
     2256        } else {
     2257                result = cm_connect_netlogon(our_domain, &cli);
     2258        }
    19332259
    19342260        if (!NT_STATUS_IS_OK(result)) {
     
    19362262                          "a connection to %s for PIPE_NETLOGON (%s)\n",
    19372263                          domain->name, nt_errstr(result)));
     2264                TALLOC_FREE(mem_ctx);
    19382265                return False;
    19392266        }
    1940 
    19412267        b = cli->binding_handle;
    19422268
    1943         if ( (mem_ctx = talloc_init("set_dc_type_and_flags_trustinfo")) == NULL ) {
    1944                 DEBUG(0,("set_dc_type_and_flags_trustinfo: talloc_init() failed!\n"));
    1945                 return False;
    1946         }       
    1947 
     2269        /* Use DsEnumerateDomainTrusts to get us the trust direction and type. */
    19482270        result = dcerpc_netr_DsrEnumerateDomainTrusts(b, mem_ctx,
    19492271                                                      cli->desthost,
     
    19552277                        "failed to query trusted domain list: %s\n",
    19562278                        nt_errstr(result)));
    1957                 talloc_destroy(mem_ctx);
     2279                TALLOC_FREE(mem_ctx);
    19582280                return false;
    19592281        }
     
    19622284                        "failed to query trusted domain list: %s\n",
    19632285                        win_errstr(werr)));
    1964                 talloc_destroy(mem_ctx);
     2286                TALLOC_FREE(mem_ctx);
    19652287                return false;
    19662288        }
     
    19742296                        domain->domain_trust_attribs  = trusts.array[i].trust_attributes;
    19752297
    1976                         if ( domain->domain_type == NETR_TRUST_TYPE_UPLEVEL )
     2298                        if ( domain->domain_type == LSA_TRUST_TYPE_UPLEVEL )
    19772299                                domain->active_directory = True;
    19782300
     
    19922314
    19932315                        domain->can_do_ncacn_ip_tcp = domain->active_directory;
    1994                         domain->can_do_validation6 = domain->active_directory;
    19952316
    19962317                        domain->initialized = True;
     
    20002321        }
    20012322
    2002         talloc_destroy( mem_ctx );
     2323        TALLOC_FREE(mem_ctx);
    20032324
    20042325        return domain->initialized;     
     
    20232344        union lsa_PolicyInformation *lsa_info = NULL;
    20242345
    2025         if (!connection_ok(domain)) {
     2346        if (!domain->internal && !connection_ok(domain)) {
    20262347                return;
    20272348        }
     
    20362357        DEBUG(5, ("set_dc_type_and_flags_connect: domain %s\n", domain->name ));
    20372358
    2038         status = cli_rpc_pipe_open_noauth(domain->conn.cli,
    2039                                           &ndr_table_dssetup.syntax_id,
    2040                                           &cli);
     2359        if (domain->internal) {
     2360                status = wb_open_internal_pipe(mem_ctx,
     2361                                               &ndr_table_dssetup,
     2362                                               &cli);
     2363        } else {
     2364                status = cli_rpc_pipe_open_noauth(domain->conn.cli,
     2365                                                  &ndr_table_dssetup,
     2366                                                  &cli);
     2367        }
    20412368
    20422369        if (!NT_STATUS_IS_OK(status)) {
     
    20872414
    20882415no_dssetup:
    2089         status = cli_rpc_pipe_open_noauth(domain->conn.cli,
    2090                                           &ndr_table_lsarpc.syntax_id, &cli);
    2091 
     2416        if (domain->internal) {
     2417                status = wb_open_internal_pipe(mem_ctx,
     2418                                               &ndr_table_lsarpc,
     2419                                               &cli);
     2420        } else {
     2421                status = cli_rpc_pipe_open_noauth(domain->conn.cli,
     2422                                                  &ndr_table_lsarpc, &cli);
     2423        }
    20922424        if (!NT_STATUS_IS_OK(status)) {
    20932425                DEBUG(5, ("set_dc_type_and_flags_connect: Could not bind to "
     
    21162448
    21172449                if (lsa_info->dns.name.string) {
    2118                         fstrcpy(domain->name, lsa_info->dns.name.string);
     2450                        if (!strequal(domain->name, lsa_info->dns.name.string))
     2451                        {
     2452                                DEBUG(1, ("set_dc_type_and_flags_connect: DC "
     2453                                          "for domain %s claimed it was a DC "
     2454                                          "for domain %s, refusing to "
     2455                                          "initialize\n",
     2456                                          domain->name,
     2457                                          lsa_info->dns.name.string));
     2458                                TALLOC_FREE(cli);
     2459                                TALLOC_FREE(mem_ctx);
     2460                                return;
     2461                        }
     2462                        talloc_free(domain->name);
     2463                        domain->name = talloc_strdup(domain,
     2464                                                     lsa_info->dns.name.string);
     2465                        if (domain->name == NULL) {
     2466                                goto done;
     2467                        }
    21192468                }
    21202469
    21212470                if (lsa_info->dns.dns_domain.string) {
    2122                         fstrcpy(domain->alt_name,
    2123                                 lsa_info->dns.dns_domain.string);
     2471                        if (domain->alt_name != NULL &&
     2472                            !strequal(domain->alt_name,
     2473                                      lsa_info->dns.dns_domain.string))
     2474                        {
     2475                                DEBUG(1, ("set_dc_type_and_flags_connect: DC "
     2476                                          "for domain %s (%s) claimed it was "
     2477                                          "a DC for domain %s, refusing to "
     2478                                          "initialize\n",
     2479                                          domain->alt_name, domain->name,
     2480                                          lsa_info->dns.dns_domain.string));
     2481                                TALLOC_FREE(cli);
     2482                                TALLOC_FREE(mem_ctx);
     2483                                return;
     2484                        }
     2485                        talloc_free(domain->alt_name);
     2486                        domain->alt_name =
     2487                                talloc_strdup(domain,
     2488                                              lsa_info->dns.dns_domain.string);
     2489                        if (domain->alt_name == NULL) {
     2490                                goto done;
     2491                        }
    21242492                }
    21252493
     
    21282496
    21292497                if (lsa_info->dns.dns_forest.string) {
    2130                         fstrcpy(domain->forest_name,
    2131                                 lsa_info->dns.dns_forest.string);
     2498                        talloc_free(domain->forest_name);
     2499                        domain->forest_name =
     2500                                talloc_strdup(domain,
     2501                                              lsa_info->dns.dns_forest.string);
     2502                        if (domain->forest_name == NULL) {
     2503                                goto done;
     2504                        }
    21322505
    21332506                        if (strequal(domain->forest_name, domain->alt_name)) {
     
    21372510
    21382511                if (lsa_info->dns.sid) {
     2512                        if (!is_null_sid(&domain->sid) &&
     2513                            !dom_sid_equal(&domain->sid,
     2514                                           lsa_info->dns.sid))
     2515                        {
     2516                                DEBUG(1, ("set_dc_type_and_flags_connect: DC "
     2517                                          "for domain %s (%s) claimed it was "
     2518                                          "a DC for domain %s, refusing to "
     2519                                          "initialize\n",
     2520                                          dom_sid_string(talloc_tos(),
     2521                                                         &domain->sid),
     2522                                          domain->name,
     2523                                          dom_sid_string(talloc_tos(),
     2524                                                         lsa_info->dns.sid)));
     2525                                TALLOC_FREE(cli);
     2526                                TALLOC_FREE(mem_ctx);
     2527                                return;
     2528                        }
    21392529                        sid_copy(&domain->sid, lsa_info->dns.sid);
    21402530                }
     
    21582548
    21592549                        if (lsa_info->account_domain.name.string) {
    2160                                 fstrcpy(domain->name,
    2161                                         lsa_info->account_domain.name.string);
     2550                                if (!strequal(domain->name,
     2551                                        lsa_info->account_domain.name.string))
     2552                                {
     2553                                        DEBUG(1,
     2554                                              ("set_dc_type_and_flags_connect: "
     2555                                               "DC for domain %s claimed it was"
     2556                                               " a DC for domain %s, refusing "
     2557                                               "to initialize\n", domain->name,
     2558                                               lsa_info->
     2559                                                account_domain.name.string));
     2560                                        TALLOC_FREE(cli);
     2561                                        TALLOC_FREE(mem_ctx);
     2562                                        return;
     2563                                }
     2564                                talloc_free(domain->name);
     2565                                domain->name =
     2566                                        talloc_strdup(domain,
     2567                                                      lsa_info->account_domain.name.string);
    21622568                        }
    21632569
    21642570                        if (lsa_info->account_domain.sid) {
     2571                                if (!is_null_sid(&domain->sid) &&
     2572                                    !dom_sid_equal(&domain->sid,
     2573                                                lsa_info->account_domain.sid))
     2574                                {
     2575                                        DEBUG(1,
     2576                                              ("set_dc_type_and_flags_connect: "
     2577                                               "DC for domain %s (%s) claimed "
     2578                                               "it was a DC for domain %s, "
     2579                                               "refusing to initialize\n",
     2580                                               dom_sid_string(talloc_tos(),
     2581                                                              &domain->sid),
     2582                                               domain->name,
     2583                                               dom_sid_string(talloc_tos(),
     2584                                                lsa_info->account_domain.sid)));
     2585                                        TALLOC_FREE(cli);
     2586                                        TALLOC_FREE(mem_ctx);
     2587                                        return;
     2588                                }
    21652589                                sid_copy(&domain->sid, lsa_info->account_domain.sid);
    21662590                        }
     
    21762600
    21772601        domain->can_do_ncacn_ip_tcp = domain->active_directory;
    2178         domain->can_do_validation6 = domain->active_directory;
    21792602
    21802603        TALLOC_FREE(cli);
     
    21932616        /* we always have to contact our primary domain */
    21942617
    2195         if ( domain->primary ) {
     2618        if ( domain->primary || domain->internal) {
    21962619                DEBUG(10,("set_dc_type_and_flags: setting up flags for "
    2197                           "primary domain\n"));
     2620                          "primary or internal domain\n"));
    21982621                set_dc_type_and_flags_connect( domain );
    21992622                return;         
     
    22172640
    22182641static NTSTATUS cm_get_schannel_creds(struct winbindd_domain *domain,
    2219                                    struct netlogon_creds_CredentialState **ppdc)
     2642                                   struct netlogon_creds_cli_context **ppdc)
    22202643{
    22212644        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
    22222645        struct rpc_pipe_client *netlogon_pipe;
    22232646
    2224         if (lp_client_schannel() == False) {
    2225                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
     2647        *ppdc = NULL;
     2648
     2649        if ((!IS_DC) && (!domain->primary)) {
     2650                return NT_STATUS_TRUSTED_DOMAIN_FAILURE;
     2651        }
     2652
     2653        if (domain->conn.netlogon_creds != NULL) {
     2654                if (!(domain->conn.netlogon_flags & NETLOGON_NEG_AUTHENTICATED_RPC)) {
     2655                        return NT_STATUS_TRUSTED_DOMAIN_FAILURE;
     2656                }
     2657                *ppdc = domain->conn.netlogon_creds;
     2658                return NT_STATUS_OK;
    22262659        }
    22272660
     
    22312664        }
    22322665
    2233         /* Return a pointer to the struct netlogon_creds_CredentialState from the
    2234            netlogon pipe. */
    2235 
    2236         if (!domain->conn.netlogon_pipe->dc) {
    2237                 return NT_STATUS_INTERNAL_ERROR; /* This shouldn't happen. */
    2238         }
    2239 
    2240         *ppdc = domain->conn.netlogon_pipe->dc;
     2666        if (domain->conn.netlogon_creds == NULL) {
     2667                return NT_STATUS_TRUSTED_DOMAIN_FAILURE;
     2668        }
     2669
     2670        if (!(domain->conn.netlogon_flags & NETLOGON_NEG_AUTHENTICATED_RPC)) {
     2671                return NT_STATUS_TRUSTED_DOMAIN_FAILURE;
     2672        }
     2673
     2674        *ppdc = domain->conn.netlogon_creds;
    22412675        return NT_STATUS_OK;
    22422676}
    22432677
    22442678NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
     2679                        bool need_rw_dc,
    22452680                        struct rpc_pipe_client **cli, struct policy_handle *sam_handle)
    22462681{
    22472682        struct winbindd_cm_conn *conn;
    22482683        NTSTATUS status, result;
    2249         struct netlogon_creds_CredentialState *p_creds;
    2250         char *machine_password = NULL;
    2251         char *machine_account = NULL;
    2252         char *domain_name = NULL;
    2253 
    2254         if (sid_check_is_domain(&domain->sid)) {
    2255                 return open_internal_samr_conn(mem_ctx, domain, cli, sam_handle);
    2256         }
    2257 
    2258         status = init_dc_connection_rpc(domain);
     2684        struct netlogon_creds_cli_context *p_creds;
     2685        struct cli_credentials *creds = NULL;
     2686        bool retry = false; /* allow one retry attempt for expired session */
     2687
     2688        if (sid_check_is_our_sam(&domain->sid)) {
     2689                if (domain->rodc == false || need_rw_dc == false) {
     2690                        return open_internal_samr_conn(mem_ctx, domain, cli, sam_handle);
     2691                }
     2692        }
     2693
     2694retry:
     2695        status = init_dc_connection_rpc(domain, need_rw_dc);
    22592696        if (!NT_STATUS_IS_OK(status)) {
    22602697                return status;
     
    22762713         */
    22772714
    2278         if ((conn->cli->user_name[0] == '\0') ||
    2279             (conn->cli->domain[0] == '\0') ||
    2280             (conn->cli->password == NULL || conn->cli->password[0] == '\0'))
    2281         {
    2282                 status = get_trust_creds(domain, &machine_password,
    2283                                          &machine_account, NULL);
    2284                 if (!NT_STATUS_IS_OK(status)) {
    2285                         DEBUG(10, ("cm_connect_sam: No no user available for "
    2286                                    "domain %s, trying schannel\n", conn->cli->domain));
    2287                         goto schannel;
    2288                 }
    2289                 domain_name = domain->name;
    2290         } else {
    2291                 machine_password = SMB_STRDUP(conn->cli->password);
    2292                 machine_account = SMB_STRDUP(conn->cli->user_name);
    2293                 domain_name = conn->cli->domain;
    2294         }
    2295 
    2296         if (!machine_password || !machine_account) {
    2297                 status = NT_STATUS_NO_MEMORY;
    2298                 goto done;
    2299         }
    2300 
    2301         /* We have an authenticated connection. Use a NTLMSSP SPNEGO
    2302            authenticated SAMR pipe with sign & seal. */
    2303         status = cli_rpc_pipe_open_spnego_ntlmssp(conn->cli,
    2304                                                   &ndr_table_samr.syntax_id,
    2305                                                   NCACN_NP,
    2306                                                   DCERPC_AUTH_LEVEL_PRIVACY,
    2307                                                   domain_name,
    2308                                                   machine_account,
    2309                                                   machine_password,
    2310                                                   &conn->samr_pipe);
     2715        result = get_trust_credentials(domain, talloc_tos(), false, &creds);
     2716        if (!NT_STATUS_IS_OK(result)) {
     2717                DEBUG(10, ("cm_connect_sam: No user available for "
     2718                           "domain %s, trying schannel\n", domain->name));
     2719                goto schannel;
     2720        }
     2721
     2722        if (cli_credentials_is_anonymous(creds)) {
     2723                goto anonymous;
     2724        }
     2725
     2726        /*
     2727         * We have an authenticated connection. Use a SPNEGO
     2728         * authenticated SAMR pipe with sign & seal.
     2729         */
     2730        status = cli_rpc_pipe_open_with_creds(conn->cli,
     2731                                              &ndr_table_samr,
     2732                                              NCACN_NP,
     2733                                              DCERPC_AUTH_TYPE_SPNEGO,
     2734                                              conn->auth_level,
     2735                                              smbXcli_conn_remote_name(conn->cli->conn),
     2736                                              creds,
     2737                                              &conn->samr_pipe);
     2738
     2739        if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)
     2740            && !retry) {
     2741                invalidate_cm_connection(domain);
     2742                retry = true;
     2743                goto retry;
     2744        }
    23112745
    23122746        if (!NT_STATUS_IS_OK(status)) {
    23132747                DEBUG(10,("cm_connect_sam: failed to connect to SAMR "
    23142748                          "pipe for domain %s using NTLMSSP "
    2315                           "authenticated pipe: user %s\\%s. Error was "
    2316                           "%s\n", domain->name, domain_name,
    2317                           machine_account, nt_errstr(status)));
     2749                          "authenticated pipe: user %s. Error was "
     2750                          "%s\n", domain->name,
     2751                          cli_credentials_get_unparsed_name(creds, talloc_tos()),
     2752                          nt_errstr(status)));
    23182753                goto schannel;
    23192754        }
     
    23212756        DEBUG(10,("cm_connect_sam: connected to SAMR pipe for "
    23222757                  "domain %s using NTLMSSP authenticated "
    2323                   "pipe: user %s\\%s\n", domain->name,
    2324                   domain_name, machine_account));
     2758                  "pipe: user %s\n", domain->name,
     2759                  cli_credentials_get_unparsed_name(creds, talloc_tos())));
    23252760
    23262761        status = dcerpc_samr_Connect2(conn->samr_pipe->binding_handle, mem_ctx,
     
    23292764                                      &conn->sam_connect_handle,
    23302765                                      &result);
     2766
     2767        if (NT_STATUS_EQUAL(status, NT_STATUS_IO_DEVICE_ERROR) && !retry) {
     2768                invalidate_cm_connection(domain);
     2769                TALLOC_FREE(conn->samr_pipe);
     2770                retry = true;
     2771                goto retry;
     2772        }
     2773
    23312774        if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) {
    23322775                goto open_domain;
     
    23542797                goto anonymous;
    23552798        }
    2356         status = cli_rpc_pipe_open_schannel_with_key
    2357                 (conn->cli, &ndr_table_samr.syntax_id, NCACN_NP,
    2358                  DCERPC_AUTH_LEVEL_PRIVACY,
    2359                  domain->name, &p_creds, &conn->samr_pipe);
     2799        TALLOC_FREE(creds);
     2800        result = get_trust_credentials(domain, talloc_tos(), true, &creds);
     2801        if (!NT_STATUS_IS_OK(result)) {
     2802                DEBUG(10, ("cm_connect_sam: No user available for "
     2803                           "domain %s (error %s), trying anon\n", domain->name,
     2804                           nt_errstr(result)));
     2805                goto anonymous;
     2806        }
     2807        status = cli_rpc_pipe_open_schannel_with_creds
     2808                (conn->cli, &ndr_table_samr, NCACN_NP,
     2809                 creds, p_creds, &conn->samr_pipe);
     2810
     2811        if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)
     2812            && !retry) {
     2813                invalidate_cm_connection(domain);
     2814                retry = true;
     2815                goto retry;
     2816        }
    23602817
    23612818        if (!NT_STATUS_IS_OK(status)) {
     
    23732830                                      &conn->sam_connect_handle,
    23742831                                      &result);
     2832
     2833        if (NT_STATUS_EQUAL(status, NT_STATUS_IO_DEVICE_ERROR) && !retry) {
     2834                invalidate_cm_connection(domain);
     2835                TALLOC_FREE(conn->samr_pipe);
     2836                retry = true;
     2837                goto retry;
     2838        }
     2839
    23752840        if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) {
    23762841                goto open_domain;
     
    23852850
    23862851 anonymous:
    2387         if (lp_winbind_sealed_pipes() && (IS_DC || domain->primary)) {
     2852
     2853        /* Finally fall back to anonymous. */
     2854        if (lp_winbind_sealed_pipes() || lp_require_strong_key()) {
    23882855                status = NT_STATUS_DOWNGRADE_DETECTED;
    2389                 DEBUG(1, ("Unwilling to make SAMR connection to domain %s "
     2856                DEBUG(1, ("Unwilling to make SAMR connection to domain %s"
    23902857                          "without connection level security, "
    2391                           "must set 'winbind sealed pipes = false' "
    2392                           "to proceed: %s\n",
     2858                          "must set 'winbind sealed pipes = false' and "
     2859                          "'require strong key = false' to proceed: %s\n",
    23932860                          domain->name, nt_errstr(status)));
    23942861                goto done;
    23952862        }
    2396 
    2397         /* Finally fall back to anonymous. */
    2398         status = cli_rpc_pipe_open_noauth(conn->cli, &ndr_table_samr.syntax_id,
     2863        status = cli_rpc_pipe_open_noauth(conn->cli, &ndr_table_samr,
    23992864                                          &conn->samr_pipe);
     2865
     2866        if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)
     2867            && !retry) {
     2868                invalidate_cm_connection(domain);
     2869                retry = true;
     2870                goto retry;
     2871        }
    24002872
    24012873        if (!NT_STATUS_IS_OK(status)) {
     
    24082880                                      &conn->sam_connect_handle,
    24092881                                      &result);
     2882
     2883        if (NT_STATUS_EQUAL(status, NT_STATUS_IO_DEVICE_ERROR) && !retry) {
     2884                invalidate_cm_connection(domain);
     2885                TALLOC_FREE(conn->samr_pipe);
     2886                retry = true;
     2887                goto retry;
     2888        }
     2889
    24102890        if (!NT_STATUS_IS_OK(status)) {
    24112891                DEBUG(10,("cm_connect_sam: rpccli_samr_Connect2 failed "
     
    24492929                return status;
    24502930        } else if (!NT_STATUS_IS_OK(status)) {
    2451                 invalidate_cm_connection(conn);
     2931                invalidate_cm_connection(domain);
    24522932                return status;
    24532933        }
     
    24552935        *cli = conn->samr_pipe;
    24562936        *sam_handle = conn->sam_domain_handle;
    2457         SAFE_FREE(machine_password);
    2458         SAFE_FREE(machine_account);
    24592937        return status;
    24602938}
     
    24642942***********************************************************************/
    24652943
    2466 NTSTATUS cm_connect_lsa_tcp(struct winbindd_domain *domain,
    2467                             TALLOC_CTX *mem_ctx,
    2468                             struct rpc_pipe_client **cli)
     2944static NTSTATUS cm_connect_lsa_tcp(struct winbindd_domain *domain,
     2945                                   TALLOC_CTX *mem_ctx,
     2946                                   struct rpc_pipe_client **cli)
    24692947{
    24702948        struct winbindd_cm_conn *conn;
    2471         struct netlogon_creds_CredentialState *creds;
     2949        struct netlogon_creds_cli_context *p_creds = NULL;
     2950        struct cli_credentials *creds = NULL;
    24722951        NTSTATUS status;
    24732952
    24742953        DEBUG(10,("cm_connect_lsa_tcp\n"));
    24752954
    2476         status = init_dc_connection_rpc(domain);
     2955        status = init_dc_connection_rpc(domain, false);
    24772956        if (!NT_STATUS_IS_OK(status)) {
    24782957                return status;
     
    24832962        if (conn->lsa_pipe_tcp &&
    24842963            conn->lsa_pipe_tcp->transport->transport == NCACN_IP_TCP &&
    2485             conn->lsa_pipe_tcp->auth->auth_level == DCERPC_AUTH_LEVEL_PRIVACY &&
     2964            conn->lsa_pipe_tcp->auth->auth_level >= DCERPC_AUTH_LEVEL_INTEGRITY &&
    24862965            rpccli_is_connected(conn->lsa_pipe_tcp)) {
    24872966                goto done;
     
    24902969        TALLOC_FREE(conn->lsa_pipe_tcp);
    24912970
    2492         status = cm_get_schannel_creds(domain, &creds);
     2971        status = cm_get_schannel_creds(domain, &p_creds);
    24932972        if (!NT_STATUS_IS_OK(status)) {
    24942973                goto done;
    24952974        }
    24962975
    2497         status = cli_rpc_pipe_open_schannel_with_key(conn->cli,
    2498                                                      &ndr_table_lsarpc.syntax_id,
    2499                                                      NCACN_IP_TCP,
    2500                                                      DCERPC_AUTH_LEVEL_PRIVACY,
    2501                                                      domain->name,
    2502                                                      &creds,
    2503                                                      &conn->lsa_pipe_tcp);
     2976        status = get_trust_credentials(domain, talloc_tos(), true, &creds);
     2977        if (!NT_STATUS_IS_OK(status)) {
     2978                goto done;
     2979        }
     2980
     2981        status = cli_rpc_pipe_open_schannel_with_creds(conn->cli,
     2982                                                       &ndr_table_lsarpc,
     2983                                                       NCACN_IP_TCP,
     2984                                                       creds,
     2985                                                       p_creds,
     2986                                                       &conn->lsa_pipe_tcp);
    25042987        if (!NT_STATUS_IS_OK(status)) {
    25052988                DEBUG(10,("cli_rpc_pipe_open_schannel_with_key failed: %s\n",
     
    25243007        struct winbindd_cm_conn *conn;
    25253008        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
    2526         struct netlogon_creds_CredentialState *p_creds;
    2527 
    2528         result = init_dc_connection_rpc(domain);
     3009        struct netlogon_creds_cli_context *p_creds;
     3010        struct cli_credentials *creds = NULL;
     3011        bool retry = false; /* allow one retry attempt for expired session */
     3012
     3013retry:
     3014        result = init_dc_connection_rpc(domain, false);
    25293015        if (!NT_STATUS_IS_OK(result))
    25303016                return result;
     
    25383024        TALLOC_FREE(conn->lsa_pipe);
    25393025
    2540         if ((conn->cli->user_name[0] == '\0') ||
    2541             (conn->cli->domain[0] == '\0') ||
    2542             (conn->cli->password == NULL || conn->cli->password[0] == '\0')) {
    2543                 DEBUG(10, ("cm_connect_lsa: No no user available for "
    2544                            "domain %s, trying schannel\n", conn->cli->domain));
     3026        result = get_trust_credentials(domain, talloc_tos(), false, &creds);
     3027        if (!NT_STATUS_IS_OK(result)) {
     3028                DEBUG(10, ("cm_connect_lsa: No user available for "
     3029                           "domain %s, trying schannel\n", domain->name));
    25453030                goto schannel;
    25463031        }
    25473032
    2548         /* We have an authenticated connection. Use a NTLMSSP SPNEGO
    2549          * authenticated LSA pipe with sign & seal. */
    2550         result = cli_rpc_pipe_open_spnego_ntlmssp
    2551                 (conn->cli, &ndr_table_lsarpc.syntax_id, NCACN_NP,
    2552                  DCERPC_AUTH_LEVEL_PRIVACY,
    2553                  conn->cli->domain, conn->cli->user_name, conn->cli->password,
     3033        if (cli_credentials_is_anonymous(creds)) {
     3034                goto anonymous;
     3035        }
     3036
     3037        /*
     3038         * We have an authenticated connection. Use a SPNEGO
     3039         * authenticated LSA pipe with sign & seal.
     3040         */
     3041        result = cli_rpc_pipe_open_with_creds
     3042                (conn->cli, &ndr_table_lsarpc, NCACN_NP,
     3043                 DCERPC_AUTH_TYPE_SPNEGO,
     3044                 conn->auth_level,
     3045                 smbXcli_conn_remote_name(conn->cli->conn),
     3046                 creds,
    25543047                 &conn->lsa_pipe);
     3048
     3049        if (NT_STATUS_EQUAL(result, NT_STATUS_NETWORK_SESSION_EXPIRED)
     3050            && !retry) {
     3051                invalidate_cm_connection(domain);
     3052                retry = true;
     3053                goto retry;
     3054        }
    25553055
    25563056        if (!NT_STATUS_IS_OK(result)) {
    25573057                DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
    25583058                          "domain %s using NTLMSSP authenticated pipe: user "
    2559                           "%s\\%s. Error was %s. Trying schannel.\n",
    2560                           domain->name, conn->cli->domain,
    2561                           conn->cli->user_name, nt_errstr(result)));
     3059                          "%s. Error was %s. Trying schannel.\n",
     3060                          domain->name,
     3061                          cli_credentials_get_unparsed_name(creds, talloc_tos()),
     3062                          nt_errstr(result)));
    25623063                goto schannel;
    25633064        }
    25643065
    25653066        DEBUG(10,("cm_connect_lsa: connected to LSA pipe for domain %s using "
    2566                   "NTLMSSP authenticated pipe: user %s\\%s\n",
    2567                   domain->name, conn->cli->domain, conn->cli->user_name ));
     3067                  "NTLMSSP authenticated pipe: user %s\n",
     3068                  domain->name, cli_credentials_get_unparsed_name(creds, talloc_tos())));
    25683069
    25693070        result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
    25703071                                        SEC_FLAG_MAXIMUM_ALLOWED,
    25713072                                        &conn->lsa_policy);
     3073        if (NT_STATUS_EQUAL(result, NT_STATUS_IO_DEVICE_ERROR) && !retry) {
     3074                invalidate_cm_connection(domain);
     3075                TALLOC_FREE(conn->lsa_pipe);
     3076                retry = true;
     3077                goto retry;
     3078        }
     3079
    25723080        if (NT_STATUS_IS_OK(result)) {
    25733081                goto done;
     
    25923100                goto anonymous;
    25933101        }
    2594         result = cli_rpc_pipe_open_schannel_with_key
    2595                 (conn->cli, &ndr_table_lsarpc.syntax_id, NCACN_NP,
    2596                  DCERPC_AUTH_LEVEL_PRIVACY,
    2597                  domain->name, &p_creds, &conn->lsa_pipe);
     3102
     3103        TALLOC_FREE(creds);
     3104        result = get_trust_credentials(domain, talloc_tos(), true, &creds);
     3105        if (!NT_STATUS_IS_OK(result)) {
     3106                DEBUG(10, ("cm_connect_lsa: No user available for "
     3107                           "domain %s (error %s), trying anon\n", domain->name,
     3108                           nt_errstr(result)));
     3109                goto anonymous;
     3110        }
     3111        result = cli_rpc_pipe_open_schannel_with_creds
     3112                (conn->cli, &ndr_table_lsarpc, NCACN_NP,
     3113                 creds, p_creds, &conn->lsa_pipe);
     3114
     3115        if (NT_STATUS_EQUAL(result, NT_STATUS_NETWORK_SESSION_EXPIRED)
     3116            && !retry) {
     3117                invalidate_cm_connection(domain);
     3118                retry = true;
     3119                goto retry;
     3120        }
    25983121
    25993122        if (!NT_STATUS_IS_OK(result)) {
     
    26093132                                        SEC_FLAG_MAXIMUM_ALLOWED,
    26103133                                        &conn->lsa_policy);
     3134
     3135        if (NT_STATUS_EQUAL(result, NT_STATUS_IO_DEVICE_ERROR) && !retry) {
     3136                invalidate_cm_connection(domain);
     3137                TALLOC_FREE(conn->lsa_pipe);
     3138                retry = true;
     3139                goto retry;
     3140        }
     3141
    26113142        if (NT_STATUS_IS_OK(result)) {
    26123143                goto done;
     
    26203151 anonymous:
    26213152
    2622         if (lp_winbind_sealed_pipes() && (IS_DC || domain->primary)) {
     3153        if (lp_winbind_sealed_pipes() || lp_require_strong_key()) {
    26233154                result = NT_STATUS_DOWNGRADE_DETECTED;
    26243155                DEBUG(1, ("Unwilling to make LSA connection to domain %s "
    26253156                          "without connection level security, "
    2626                           "must set 'winbind sealed pipes = false' "
    2627                           "to proceed: %s\n",
     3157                          "must set 'winbind sealed pipes = false' and "
     3158                          "'require strong key = false' to proceed: %s\n",
    26283159                          domain->name, nt_errstr(result)));
    26293160                goto done;
     
    26313162
    26323163        result = cli_rpc_pipe_open_noauth(conn->cli,
    2633                                           &ndr_table_lsarpc.syntax_id,
     3164                                          &ndr_table_lsarpc,
    26343165                                          &conn->lsa_pipe);
     3166
     3167        if (NT_STATUS_EQUAL(result, NT_STATUS_NETWORK_SESSION_EXPIRED)
     3168            && !retry) {
     3169                invalidate_cm_connection(domain);
     3170                retry = true;
     3171                goto retry;
     3172        }
     3173
    26353174        if (!NT_STATUS_IS_OK(result)) {
    2636                 result = NT_STATUS_PIPE_NOT_AVAILABLE;
    26373175                goto done;
    26383176        }
     
    26413179                                        SEC_FLAG_MAXIMUM_ALLOWED,
    26423180                                        &conn->lsa_policy);
     3181
     3182        if (NT_STATUS_EQUAL(result, NT_STATUS_IO_DEVICE_ERROR) && !retry) {
     3183                invalidate_cm_connection(domain);
     3184                TALLOC_FREE(conn->lsa_pipe);
     3185                retry = true;
     3186                goto retry;
     3187        }
     3188
    26433189 done:
    26443190        if (!NT_STATUS_IS_OK(result)) {
    2645                 invalidate_cm_connection(conn);
     3191                invalidate_cm_connection(domain);
    26463192                return result;
    26473193        }
     
    26683214                    NT_STATUS_EQUAL(status, NT_STATUS_RPC_SEC_PKG_ERROR) ||
    26693215                    NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_ACCESS_DENIED)) {
    2670                         invalidate_cm_connection(&domain->conn);
     3216                        invalidate_cm_connection(domain);
    26713217                        status = cm_connect_lsa_tcp(domain, mem_ctx, cli);
    26723218                }
     
    26793225                 * failed - maybe it is a trusted domain we can't connect to ?
    26803226                 * do not try tcp next time - gd
     3227                 *
     3228                 * This also prevents NETLOGON over TCP
    26813229                 */
    26823230                domain->can_do_ncacn_ip_tcp = false;
     
    26933241****************************************************************************/
    26943242
    2695 NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain,
    2696                              struct rpc_pipe_client **cli)
    2697 {
     3243static NTSTATUS cm_connect_netlogon_transport(struct winbindd_domain *domain,
     3244                                              enum dcerpc_transport_t transport,
     3245                                              struct rpc_pipe_client **cli)
     3246{
     3247        struct messaging_context *msg_ctx = winbind_messaging_context();
    26983248        struct winbindd_cm_conn *conn;
    26993249        NTSTATUS result;
    2700 
    2701         uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
    2702         uint8  mach_pwd[16];
    27033250        enum netr_SchannelType sec_chan_type;
    2704         const char *account_name;
    2705         struct rpc_pipe_client *netlogon_pipe = NULL;
     3251        struct netlogon_creds_CredentialState *netlogon_creds = NULL;
     3252        struct cli_credentials *creds = NULL;
    27063253
    27073254        *cli = NULL;
    27083255
    2709         result = init_dc_connection_rpc(domain);
     3256        result = init_dc_connection_rpc(domain, domain->rodc);
    27103257        if (!NT_STATUS_IS_OK(result)) {
    27113258                return result;
     
    27203267
    27213268        TALLOC_FREE(conn->netlogon_pipe);
    2722 
    2723         result = cli_rpc_pipe_open_noauth(conn->cli,
    2724                                           &ndr_table_netlogon.syntax_id,
    2725                                           &netlogon_pipe);
     3269        conn->netlogon_flags = 0;
     3270        TALLOC_FREE(conn->netlogon_creds);
     3271
     3272        result = get_trust_credentials(domain, talloc_tos(), true, &creds);
    27263273        if (!NT_STATUS_IS_OK(result)) {
     3274                DEBUG(10, ("cm_connect_sam: No user available for "
     3275                           "domain %s when trying schannel\n", domain->name));
     3276                return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
     3277        }
     3278
     3279        if (cli_credentials_is_anonymous(creds)) {
     3280                DEBUG(1, ("get_trust_credential only gave anonymous for %s, unable to make get NETLOGON credentials\n",
     3281                          domain->name));
     3282                return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
     3283        }
     3284
     3285        sec_chan_type = cli_credentials_get_secure_channel_type(creds);
     3286        if (sec_chan_type == SEC_CHAN_NULL) {
     3287                return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
     3288        }
     3289
     3290        result = rpccli_create_netlogon_creds_with_creds(creds,
     3291                                                         domain->dcname,
     3292                                                         msg_ctx,
     3293                                                         domain,
     3294                                                         &conn->netlogon_creds);
     3295        if (!NT_STATUS_IS_OK(result)) {
     3296                DEBUG(1, ("rpccli_create_netlogon_creds failed for %s, "
     3297                          "unable to create NETLOGON credentials: %s\n",
     3298                          domain->name, nt_errstr(result)));
    27273299                return result;
    27283300        }
    27293301
    2730         if ((!IS_DC) && (!domain->primary)) {
    2731                 /* Clear the schannel request bit and drop down */
    2732                 neg_flags &= ~NETLOGON_NEG_SCHANNEL;           
    2733                 goto no_schannel;
    2734         }
    2735 
    2736         if (lp_client_schannel() != False) {
    2737                 neg_flags |= NETLOGON_NEG_SCHANNEL;
    2738         }
    2739 
    2740         if (!get_trust_pw_hash(domain->name, mach_pwd, &account_name,
    2741                                &sec_chan_type))
    2742         {
    2743                 TALLOC_FREE(netlogon_pipe);
    2744                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
    2745         }
    2746 
    2747         result = rpccli_netlogon_setup_creds(
    2748                  netlogon_pipe,
    2749                  domain->dcname, /* server name. */
    2750                  domain->name,   /* domain name */
    2751                  global_myname(), /* client name */
    2752                  account_name,   /* machine account */
    2753                  mach_pwd,       /* machine password */
    2754                  sec_chan_type,  /* from get_trust_pw */
    2755                  &neg_flags);
    2756 
     3302        result = rpccli_setup_netlogon_creds_with_creds(conn->cli, transport,
     3303                                                conn->netlogon_creds,
     3304                                                conn->netlogon_force_reauth,
     3305                                                creds);
     3306        conn->netlogon_force_reauth = false;
    27573307        if (!NT_STATUS_IS_OK(result)) {
    2758                 TALLOC_FREE(netlogon_pipe);
     3308                DEBUG(1, ("rpccli_setup_netlogon_creds failed for %s, "
     3309                          "unable to setup NETLOGON credentials: %s\n",
     3310                          domain->name, nt_errstr(result)));
    27593311                return result;
    27603312        }
    27613313
    2762         if ((lp_client_schannel() == True) &&
    2763                         ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
    2764                 DEBUG(3, ("Server did not offer schannel\n"));
    2765                 TALLOC_FREE(netlogon_pipe);
    2766                 return NT_STATUS_ACCESS_DENIED;
    2767         }
    2768 
    2769  no_schannel:
    2770         if ((lp_client_schannel() == False) ||
    2771                 ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
    2772                 if (lp_winbind_sealed_pipes() && (IS_DC || domain->primary)) {
     3314        result = netlogon_creds_cli_get(conn->netlogon_creds,
     3315                                        talloc_tos(),
     3316                                        &netlogon_creds);
     3317        if (!NT_STATUS_IS_OK(result)) {
     3318                DEBUG(1, ("netlogon_creds_cli_get failed for %s, "
     3319                          "unable to get NETLOGON credentials: %s\n",
     3320                          domain->name, nt_errstr(result)));
     3321                return result;
     3322        }
     3323        conn->netlogon_flags = netlogon_creds->negotiate_flags;
     3324        TALLOC_FREE(netlogon_creds);
     3325
     3326        if (!(conn->netlogon_flags & NETLOGON_NEG_AUTHENTICATED_RPC)) {
     3327                if (lp_winbind_sealed_pipes() || lp_require_strong_key()) {
    27733328                        result = NT_STATUS_DOWNGRADE_DETECTED;
    2774                         DEBUG(1, ("Unwilling to make connection to domain %s "
     3329                        DEBUG(1, ("Unwilling to make connection to domain %s"
    27753330                                  "without connection level security, "
    2776                                   "must set 'winbind sealed pipes = false' "
    2777                                   "to proceed: %s\n",
     3331                                  "must set 'winbind sealed pipes = false' and "
     3332                                  "'require strong key = false' to proceed: %s\n",
    27783333                                  domain->name, nt_errstr(result)));
    2779                         TALLOC_FREE(netlogon_pipe);
    2780                         invalidate_cm_connection(conn);
     3334                        invalidate_cm_connection(domain);
    27813335                        return result;
    27823336                }
    2783                 /*
    2784                  * NetSamLogonEx only works for schannel
    2785                  */
    2786                 domain->can_do_samlogon_ex = False;
    2787 
    2788                 /* We're done - just keep the existing connection to NETLOGON
    2789                  * open */
    2790                 conn->netlogon_pipe = netlogon_pipe;
     3337                result = cli_rpc_pipe_open_noauth_transport(conn->cli,
     3338                                                            transport,
     3339                                                            &ndr_table_netlogon,
     3340                                                            &conn->netlogon_pipe);
     3341                if (!NT_STATUS_IS_OK(result)) {
     3342                        invalidate_cm_connection(domain);
     3343                        return result;
     3344                }
     3345
    27913346                *cli = conn->netlogon_pipe;
    27923347                return NT_STATUS_OK;
     
    27983353        */
    27993354
    2800         result = cli_rpc_pipe_open_schannel_with_key(
    2801                 conn->cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
    2802                 DCERPC_AUTH_LEVEL_PRIVACY, domain->name, &netlogon_pipe->dc,
     3355        result = cli_rpc_pipe_open_schannel_with_creds(
     3356                conn->cli, &ndr_table_netlogon, transport,
     3357                creds,
     3358                conn->netlogon_creds,
    28033359                &conn->netlogon_pipe);
    2804 
    2805         /* We can now close the initial netlogon pipe. */
    2806         TALLOC_FREE(netlogon_pipe);
    2807 
    28083360        if (!NT_STATUS_IS_OK(result)) {
    28093361                DEBUG(3, ("Could not open schannel'ed NETLOGON pipe. Error "
    28103362                          "was %s\n", nt_errstr(result)));
    28113363
    2812                 invalidate_cm_connection(conn);
     3364                invalidate_cm_connection(domain);
    28133365                return result;
    28143366        }
    2815 
    2816         /*
    2817          * Always try netr_LogonSamLogonEx. We will fall back for NT4
    2818          * which gives DCERPC_FAULT_OP_RNG_ERROR (function not
    2819          * supported). We used to only try SamLogonEx for AD, but
    2820          * Samba DCs can also do it. And because we don't distinguish
    2821          * between Samba and NT4, always try it once.
    2822          */
    2823         domain->can_do_samlogon_ex = true;
    28243367
    28253368        *cli = conn->netlogon_pipe;
    28263369        return NT_STATUS_OK;
     3370}
     3371
     3372/****************************************************************************
     3373Open a LSA connection to a DC, suiteable for LSA lookup calls.
     3374****************************************************************************/
     3375
     3376NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain,
     3377                             struct rpc_pipe_client **cli)
     3378{
     3379        NTSTATUS status;
     3380
     3381        status = init_dc_connection_rpc(domain, domain->rodc);
     3382        if (!NT_STATUS_IS_OK(status)) {
     3383                return status;
     3384        }
     3385
     3386        if (domain->active_directory && domain->can_do_ncacn_ip_tcp) {
     3387                status = cm_connect_netlogon_transport(domain, NCACN_IP_TCP, cli);
     3388                if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) ||
     3389                    NT_STATUS_EQUAL(status, NT_STATUS_RPC_SEC_PKG_ERROR) ||
     3390                    NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_ACCESS_DENIED)) {
     3391                        invalidate_cm_connection(domain);
     3392                        status = cm_connect_netlogon_transport(domain, NCACN_IP_TCP, cli);
     3393                }
     3394                if (NT_STATUS_IS_OK(status)) {
     3395                        return status;
     3396                }
     3397
     3398                /*
     3399                 * we tried twice to connect via ncan_ip_tcp and schannel and
     3400                 * failed - maybe it is a trusted domain we can't connect to ?
     3401                 * do not try tcp next time - gd
     3402                 *
     3403                 * This also prevents LSA over TCP
     3404                 */
     3405                domain->can_do_ncacn_ip_tcp = false;
     3406        }
     3407
     3408        status = cm_connect_netlogon_transport(domain, NCACN_NP, cli);
     3409        if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
     3410                /*
     3411                 * SMB2 session expired, needs reauthentication. Drop
     3412                 * connection and retry.
     3413                 */
     3414                invalidate_cm_connection(domain);
     3415                status = cm_connect_netlogon_transport(domain, NCACN_NP, cli);
     3416        }
     3417
     3418        return status;
    28273419}
    28283420
     
    28723464        for (domain = domain_list(); domain != NULL; domain = domain->next) {
    28733465                char sockaddr[INET6_ADDRSTRLEN];
    2874                 if (domain->conn.cli == NULL) {
     3466
     3467                if (!cli_state_is_connected(domain->conn.cli)) {
    28753468                        continue;
    28763469                }
    2877                 if (domain->conn.cli->fd == -1) {
    2878                         continue;
    2879                 }
    2880                 client_socket_addr(domain->conn.cli->fd, sockaddr,
    2881                                    sizeof(sockaddr));
     3470
     3471                print_sockaddr(sockaddr, sizeof(sockaddr),
     3472                               smbXcli_conn_local_sockaddr(domain->conn.cli->conn));
     3473
    28823474                if (strequal(sockaddr, addr)) {
    2883                         close(domain->conn.cli->fd);
    2884                         domain->conn.cli->fd = -1;
     3475                        smbXcli_conn_disconnect(domain->conn.cli->conn, NT_STATUS_OK);
    28853476                }
    28863477        }
  • vendor/current/source3/winbindd/winbindd_cred_cache.c

    r746 r988  
    3939
    4040static struct WINBINDD_CCACHE_ENTRY *ccache_list;
    41 static void krb5_ticket_gain_handler(struct event_context *,
    42                                      struct timed_event *,
     41static void krb5_ticket_gain_handler(struct tevent_context *,
     42                                     struct tevent_timer *,
    4343                                     struct timeval,
    4444                                     void *);
     
    105105****************************************************************/
    106106
    107 static void krb5_ticket_refresh_handler(struct event_context *event_ctx,
    108                                         struct timed_event *te,
     107static void krb5_ticket_refresh_handler(struct tevent_context *event_ctx,
     108                                        struct tevent_timer *te,
    109109                                        struct timeval now,
    110110                                        void *private_data)
     
    286286                entry->refresh_time = new_start;
    287287        }
    288         entry->event = event_add_timed(winbind_event_context(), entry,
     288        entry->event = tevent_add_timer(winbind_event_context(), entry,
    289289                                       timeval_set(new_start, 0),
    290290                                       krb5_ticket_refresh_handler,
     
    298298****************************************************************/
    299299
    300 static void krb5_ticket_gain_handler(struct event_context *event_ctx,
    301                                      struct timed_event *te,
     300static void krb5_ticket_gain_handler(struct tevent_context *event_ctx,
     301                                     struct tevent_timer *te,
    302302                                     struct timeval now,
    303303                                     void *private_data)
     
    386386                entry->refresh_time = t.tv_sec;
    387387        }
    388         entry->event = event_add_timed(winbind_event_context(),
     388        entry->event = tevent_add_timer(winbind_event_context(),
    389389                                       entry,
    390390                                       t,
     
    405405{
    406406        entry->refresh_time = 0;
    407         entry->event = event_add_timed(winbind_event_context(),
     407        entry->event = tevent_add_timer(winbind_event_context(),
    408408                                       entry,
    409409                                       t,
     
    418418
    419419        for (cur = ccache_list; cur; cur = cur->next) {
    420                 struct timed_event *new_event;
     420                struct tevent_timer *new_event;
    421421
    422422                /*
     
    425425                 */
    426426                if (cur->refresh_time == 0) {
    427                         new_event = event_add_timed(winbind_event_context(),
     427                        new_event = tevent_add_timer(winbind_event_context(),
    428428                                                    cur,
    429429                                                    t,
     
    431431                                                    cur);
    432432                } else {
    433                         new_event = event_add_timed(winbind_event_context(),
     433                        new_event = tevent_add_timer(winbind_event_context(),
    434434                                                    cur,
    435435                                                    t,
     
    502502        struct timeval t;
    503503        NTSTATUS ntret;
    504 #ifdef HAVE_KRB5
    505         int ret;
    506 #endif
    507504
    508505        if ((username == NULL && princ_name == NULL) ||
     
    516513                return NT_STATUS_NO_MORE_ENTRIES;
    517514        }
    518 
    519         /* If it is cached login, destroy krb5 ticket
    520          * to avoid surprise. */
    521 #ifdef HAVE_KRB5
    522         if (postponed_request) {
    523                 /* ignore KRB5_FCC_NOFILE error here */
    524                 ret = ads_kdestroy(ccname);
    525                 if (ret == KRB5_FCC_NOFILE) {
    526                         ret = 0;
    527                 }
    528                 if (ret) {
    529                         DEBUG(0, ("add_ccache_to_list: failed to destroy "
    530                                    "user krb5 ccache %s with %s\n", ccname,
    531                                    error_message(ret)));
    532                         return krb5_to_nt_status(ret);
    533                 }
    534                 DEBUG(10, ("add_ccache_to_list: successfully destroyed "
    535                            "krb5 ccache %s for user %s\n", ccname,
    536                            username));
    537         }
    538 #endif
    539515
    540516        /* Reference count old entries */
     
    572548                                        entry->refresh_time = t.tv_sec;
    573549                                }
    574                                 entry->event = event_add_timed(winbind_event_context(),
     550                                entry->event = tevent_add_timer(winbind_event_context(),
    575551                                                               entry,
    576552                                                               t,
     
    612588        }
    613589
    614         entry = TALLOC_P(NULL, struct WINBINDD_CCACHE_ENTRY);
     590        entry = talloc(NULL, struct WINBINDD_CCACHE_ENTRY);
    615591        if (!entry) {
    616592                return NT_STATUS_NO_MEMORY;
     
    670646                        entry->refresh_time = t.tv_sec;
    671647                }
    672                 entry->event = event_add_timed(winbind_event_context(),
     648                entry->event = tevent_add_timer(winbind_event_context(),
    673649                                               entry,
    674650                                               t,
     
    847823#endif
    848824
    849         /* Create and store the password hashes. */
    850         E_md4hash(pass, memcredp->nt_hash);
    851         E_deshash(pass, memcredp->lm_hash);
    852 
    853825        if (pass) {
     826                /* Create and store the password hashes. */
     827                E_md4hash(pass, memcredp->nt_hash);
     828                E_deshash(pass, memcredp->lm_hash);
     829
    854830                memcredp->pass = (char *)memcredp->lm_hash + LM_HASH_LEN;
    855831                memcpy(memcredp->pass, pass,
     
    938914        }
    939915
    940         memcredp = TALLOC_ZERO_P(NULL, struct WINBINDD_MEMORY_CREDS);
     916        memcredp = talloc_zero(NULL, struct WINBINDD_MEMORY_CREDS);
    941917        if (!memcredp) {
    942918                return NT_STATUS_NO_MEMORY;
  • vendor/current/source3/winbindd/winbindd_creds.c

    r740 r988  
    3333                            const struct dom_sid *sid,
    3434                            struct netr_SamInfo3 **info3,
    35                             const uint8 *cached_nt_pass[NT_HASH_LEN],
    36                             const uint8 *cred_salt[NT_HASH_LEN])
     35                            const uint8_t *cached_nt_pass[NT_HASH_LEN],
     36                            const uint8_t *cred_salt[NT_HASH_LEN])
    3737{
    3838        struct netr_SamInfo3 *info;
  • vendor/current/source3/winbindd/winbindd_dsgetdcname.c

    r740 r988  
    2020#include "includes.h"
    2121#include "winbindd.h"
    22 #include "librpc/gen_ndr/ndr_wbint_c.h"
     22#include "librpc/gen_ndr/ndr_winbind_c.h"
    2323
    2424struct winbindd_dsgetdcname_state {
     
    5858                  request->data.dsgetdcname.domain_name));
    5959
    60         ds_flags = get_dsgetdc_flags(request->flags);
     60        ds_flags = get_dsgetdc_flags(request->data.dsgetdcname.flags);
    6161
    6262        status = GUID_from_string(request->data.dsgetdcname.domain_guid,
     
    102102        struct winbindd_dsgetdcname_state *state = tevent_req_data(
    103103                req, struct winbindd_dsgetdcname_state);
     104        struct GUID_txt_buf guid_str_buf;
    104105        char *guid_str;
    105106        NTSTATUS status;
     
    110111        }
    111112
    112         guid_str = GUID_string(talloc_tos(), &state->dc_info->domain_guid);
    113         if (guid_str == NULL) {
    114                 return NT_STATUS_NO_MEMORY;
    115         }
    116113
    117114        fstrcpy(response->data.dsgetdcname.dc_unc,
     
    121118        response->data.dsgetdcname.dc_address_type =
    122119                state->dc_info->dc_address_type;
     120
     121        guid_str = GUID_buf_string(&state->dc_info->domain_guid,
     122                                   &guid_str_buf);
    123123        fstrcpy(response->data.dsgetdcname.domain_guid, guid_str);
    124         TALLOC_FREE(guid_str);
     124
    125125        fstrcpy(response->data.dsgetdcname.domain_name,
    126126                state->dc_info->domain_name);
  • vendor/current/source3/winbindd/winbindd_dual.c

    r860 r988  
    3030#include "includes.h"
    3131#include "winbindd.h"
     32#include "rpc_client/rpc_client.h"
    3233#include "nsswitch/wb_reqtrans.h"
    3334#include "secrets.h"
     
    3738#include "messages.h"
    3839#include "../lib/util/tevent_unix.h"
     40#include "lib/param/loadparm.h"
     41#include "lib/util/sys_rw.h"
     42#include "lib/util/sys_rw_data.h"
    3943
    4044#undef DBGC_CLASS
     
    4246
    4347extern bool override_logfile;
    44 extern struct winbindd_methods cache_methods;
    4548
    4649static struct winbindd_child *winbindd_children = NULL;
     
    4851/* Read some data from a client connection */
    4952
    50 static NTSTATUS child_read_request(struct winbindd_cli_state *state)
     53static NTSTATUS child_read_request(int sock, struct winbindd_request *wreq)
    5154{
    5255        NTSTATUS status;
    5356
    54         /* Read data */
    55 
    56         status = read_data(state->sock, (char *)state->request,
    57                            sizeof(*state->request));
    58 
     57        status = read_data_ntstatus(sock, (char *)wreq, sizeof(*wreq));
    5958        if (!NT_STATUS_IS_OK(status)) {
    6059                DEBUG(3, ("child_read_request: read_data failed: %s\n",
     
    6362        }
    6463
    65         if (state->request->extra_len == 0) {
    66                 state->request->extra_data.data = NULL;
     64        if (wreq->extra_len == 0) {
     65                wreq->extra_data.data = NULL;
    6766                return NT_STATUS_OK;
    6867        }
    6968
    70         DEBUG(10, ("Need to read %d extra bytes\n", (int)state->request->extra_len));
    71 
    72         state->request->extra_data.data =
    73                 SMB_MALLOC_ARRAY(char, state->request->extra_len + 1);
    74 
    75         if (state->request->extra_data.data == NULL) {
     69        DEBUG(10, ("Need to read %d extra bytes\n", (int)wreq->extra_len));
     70
     71        wreq->extra_data.data = SMB_MALLOC_ARRAY(char, wreq->extra_len + 1);
     72        if (wreq->extra_data.data == NULL) {
    7673                DEBUG(0, ("malloc failed\n"));
    7774                return NT_STATUS_NO_MEMORY;
     
    7976
    8077        /* Ensure null termination */
    81         state->request->extra_data.data[state->request->extra_len] = '\0';
    82 
    83         status= read_data(state->sock, state->request->extra_data.data,
    84                           state->request->extra_len);
    85 
     78        wreq->extra_data.data[wreq->extra_len] = '\0';
     79
     80        status = read_data_ntstatus(sock, wreq->extra_data.data,
     81                                    wreq->extra_len);
    8682        if (!NT_STATUS_IS_OK(status)) {
    8783                DEBUG(0, ("Could not read extra data: %s\n",
     
    8985        }
    9086        return status;
     87}
     88
     89static NTSTATUS child_write_response(int sock, struct winbindd_response *wrsp)
     90{
     91        struct iovec iov[2];
     92        int iov_count;
     93
     94        iov[0].iov_base = (void *)wrsp;
     95        iov[0].iov_len = sizeof(struct winbindd_response);
     96        iov_count = 1;
     97
     98        if (wrsp->length > sizeof(struct winbindd_response)) {
     99                iov[1].iov_base = (void *)wrsp->extra_data.data;
     100                iov[1].iov_len = wrsp->length-iov[0].iov_len;
     101                iov_count = 2;
     102        }
     103
     104        DEBUG(10, ("Writing %d bytes to parent\n", (int)wrsp->length));
     105
     106        if (write_data_iov(sock, iov, iov_count) != wrsp->length) {
     107                DEBUG(0, ("Could not write result\n"));
     108                return NT_STATUS_INVALID_HANDLE;
     109        }
     110
     111        return NT_STATUS_OK;
    91112}
    92113
     
    99120struct wb_child_request_state {
    100121        struct tevent_context *ev;
     122        struct tevent_req *subreq;
    101123        struct winbindd_child *child;
    102124        struct winbindd_request *request;
     
    110132static void wb_child_request_done(struct tevent_req *subreq);
    111133
     134static void wb_child_request_cleanup(struct tevent_req *req,
     135                                     enum tevent_req_state req_state);
     136
    112137struct tevent_req *wb_child_request_send(TALLOC_CTX *mem_ctx,
    113138                                         struct tevent_context *ev,
     
    130155        if (!tevent_queue_add(child->queue, ev, req,
    131156                              wb_child_request_trigger, NULL)) {
    132                 tevent_req_nomem(NULL, req);
     157                tevent_req_oom(req);
    133158                return tevent_req_post(req, ev);
    134159        }
     160
     161        tevent_req_set_cleanup_fn(req, wb_child_request_cleanup);
     162
    135163        return req;
    136164}
     
    153181                return;
    154182        }
     183
     184        state->subreq = subreq;
    155185        tevent_req_set_callback(subreq, wb_child_request_done, req);
    156186        tevent_req_set_endtime(req, state->ev, timeval_current_ofs(300, 0));
     
    166196
    167197        ret = wb_simple_trans_recv(subreq, state, &state->response, &err);
    168         TALLOC_FREE(subreq);
     198        /* Freeing the subrequest is deferred until the cleanup function,
     199         * which has to know whether a subrequest exists, and consequently
     200         * decide whether to shut down the pipe to the child process.
     201         */
    169202        if (ret == -1) {
    170                 /*
    171                  * The basic parent/child communication broke, close
    172                  * our socket
    173                  */
    174                 close(state->child->sock);
    175                 state->child->sock = -1;
    176                 DLIST_REMOVE(winbindd_children, state->child);
    177203                tevent_req_error(req, err);
    178204                return;
     
    192218        *presponse = talloc_move(mem_ctx, &state->response);
    193219        return 0;
     220}
     221
     222static void wb_child_request_cleanup(struct tevent_req *req,
     223                                     enum tevent_req_state req_state)
     224{
     225        struct wb_child_request_state *state =
     226            tevent_req_data(req, struct wb_child_request_state);
     227
     228        if (state->subreq == NULL) {
     229                /* nothing to cleanup */
     230                return;
     231        }
     232
     233        TALLOC_FREE(state->subreq);
     234
     235        if (req_state == TEVENT_REQ_DONE) {
     236                /* transmitted request and got response */
     237                return;
     238        }
     239
     240        /*
     241         * Failed to transmit and receive response, or request
     242         * cancelled while being serviced.
     243         * The basic parent/child communication broke, close
     244         * our socket
     245         */
     246        close(state->child->sock);
     247        state->child->sock = -1;
     248        DLIST_REMOVE(winbindd_children, state->child);
    194249}
    195250
     
    369424                return;
    370425        }
    371         fstrcpy(state->domain->name, response->data.domain_info.name);
    372         fstrcpy(state->domain->alt_name, response->data.domain_info.alt_name);
     426
     427        talloc_free(state->domain->name);
     428        state->domain->name = talloc_strdup(state->domain,
     429                                            response->data.domain_info.name);
     430        if (state->domain->name == NULL) {
     431                tevent_req_error(req, ENOMEM);
     432                return;
     433        }
     434
     435        if (response->data.domain_info.alt_name[0] != '\0') {
     436                talloc_free(state->domain->alt_name);
     437
     438                state->domain->alt_name = talloc_strdup(state->domain,
     439                                response->data.domain_info.alt_name);
     440                if (state->domain->alt_name == NULL) {
     441                        tevent_req_error(req, ENOMEM);
     442                        return;
     443                }
     444        }
     445
    373446        state->domain->native_mode = response->data.domain_info.native_mode;
    374447        state->domain->active_directory =
     
    456529                char *logbase = NULL;
    457530
    458                 if (*lp_logfile()) {
     531                if (*lp_logfile(talloc_tos())) {
    459532                        char *end = NULL;
    460533
    461                         if (asprintf(&logbase, "%s", lp_logfile()) < 0) {
     534                        if (asprintf(&logbase, "%s", lp_logfile(talloc_tos())) < 0) {
    462535                                smb_panic("Internal error: asprintf failed");
    463536                        }
     
    524597{
    525598        flush_negative_conn_cache_for_domain(domain->name);
    526         if (*domain->alt_name) {
     599        if (domain->alt_name != NULL) {
    527600                flush_negative_conn_cache_for_domain(domain->alt_name);
    528601        }
     
    608681
    609682                DEBUG(10,("winbind_msg_offline: sending message to pid %u for domain %s.\n",
    610                         (unsigned int)child->pid, domain->name ));
     683                        (unsigned int)child->pid, child->domain->name ));
    611684
    612685                messaging_send_buf(msg_ctx, pid_to_procid(child->pid),
    613686                                   MSG_WINBIND_OFFLINE,
    614                                    (uint8 *)child->domain->name,
     687                                   (const uint8_t *)child->domain->name,
    615688                                   strlen(child->domain->name)+1);
    616689        }
     
    661734                                                   pid_to_procid(idmap->pid),
    662735                                                   MSG_WINBIND_ONLINE,
    663                                                    (uint8 *)domain->name,
     736                                                   (const uint8_t *)domain->name,
    664737                                                   strlen(domain->name)+1);
    665738                        }
     
    686759                messaging_send_buf(msg_ctx, pid_to_procid(child->pid),
    687760                                   MSG_WINBIND_ONLINE,
    688                                    (uint8 *)child->domain->name,
     761                                   (const uint8_t *)child->domain->name,
    689762                                   strlen(child->domain->name)+1);
    690763        }
     
    748821
    749822        messaging_send_buf(msg_ctx, *sender, MSG_WINBIND_ONLINESTATUS,
    750                            (uint8 *)message, strlen(message) + 1);
     823                           (const uint8_t *)message, strlen(message) + 1);
    751824
    752825        talloc_destroy(mem_ctx);
     
    825898                messaging_send_buf(msg_ctx, *sender,
    826899                                   MSG_WINBIND_DUMP_DOMAIN_LIST,
    827                                    (uint8_t *)message, strlen(message) + 1);
     900                                   (const uint8_t *)message, strlen(message) + 1);
    828901
    829902                talloc_destroy(mem_ctx);
     
    859932}
    860933
    861 static void account_lockout_policy_handler(struct event_context *ctx,
    862                                            struct timed_event *te,
     934static void account_lockout_policy_handler(struct tevent_context *ctx,
     935                                           struct tevent_timer *te,
    863936                                           struct timeval now,
    864937                                           void *private_data)
     
    898971        }
    899972
    900         child->lockout_policy_event = event_add_timed(winbind_event_context(), NULL,
     973        child->lockout_policy_event = tevent_add_timer(winbind_event_context(), NULL,
    901974                                                      timeval_current_ofs(3600, 0),
    902975                                                      account_lockout_policy_handler,
     
    9761049}
    9771050
    978 static void machine_password_change_handler(struct event_context *ctx,
    979                                             struct timed_event *te,
     1051static void machine_password_change_handler(struct tevent_context *ctx,
     1052                                            struct tevent_timer *te,
    9801053                                            struct timeval now,
    9811054                                            void *private_data)
    9821055{
     1056        struct messaging_context *msg_ctx = winbind_messaging_context();
    9831057        struct winbindd_child *child =
    9841058                (struct winbindd_child *)private_data;
    9851059        struct rpc_pipe_client *netlogon_pipe = NULL;
    986         TALLOC_CTX *frame;
    9871060        NTSTATUS result;
    9881061        struct timeval next_change;
     
    10211094        }
    10221095
    1023         frame = talloc_stackframe();
    1024 
    1025         result = trust_pw_find_change_and_store_it(netlogon_pipe,
    1026                                                    frame,
    1027                                                    child->domain->name);
    1028         TALLOC_FREE(frame);
     1096        result = trust_pw_change(child->domain->conn.netlogon_creds,
     1097                                 msg_ctx,
     1098                                 netlogon_pipe->binding_handle,
     1099                                 child->domain->name,
     1100                                 false); /* force */
    10291101
    10301102        DEBUG(10, ("machine_password_change_handler: "
    1031                    "trust_pw_find_change_and_store_it returned %s\n",
     1103                   "trust_pw_change returned %s\n",
    10321104                   nt_errstr(result)));
    10331105
     
    10381110                         "Killing connections to domain %s\n",
    10391111                         child->domain->name));
    1040                 TALLOC_FREE(child->domain->conn.netlogon_pipe);
     1112                invalidate_cm_connection(child->domain);
    10411113        }
    10421114
     
    10601132
    10611133done:
    1062         child->machine_password_change_event = event_add_timed(winbind_event_context(), NULL,
     1134        child->machine_password_change_event = tevent_add_timer(winbind_event_context(), NULL,
    10631135                                                              next_change,
    10641136                                                              machine_password_change_handler,
     
    11831255                winbind_messaging_context(),
    11841256                winbind_event_context(),
    1185                 procid_self(),
    1186                 true);
     1257                true, NULL);
    11871258        if (!NT_STATUS_IS_OK(status)) {
    11881259                DEBUG(0,("reinit_after_fork() failed\n"));
     
    12951366}
    12961367
     1368struct child_handler_state {
     1369        struct winbindd_child *child;
     1370        struct winbindd_cli_state cli;
     1371};
     1372
     1373static void child_handler(struct tevent_context *ev, struct tevent_fd *fde,
     1374                          uint16_t flags, void *private_data)
     1375{
     1376        struct child_handler_state *state =
     1377                (struct child_handler_state *)private_data;
     1378        NTSTATUS status;
     1379
     1380        /* fetch a request from the main daemon */
     1381        status = child_read_request(state->cli.sock, state->cli.request);
     1382
     1383        if (!NT_STATUS_IS_OK(status)) {
     1384                /* we lost contact with our parent */
     1385                _exit(0);
     1386        }
     1387
     1388        DEBUG(4,("child daemon request %d\n",
     1389                 (int)state->cli.request->cmd));
     1390
     1391        ZERO_STRUCTP(state->cli.response);
     1392        state->cli.request->null_term = '\0';
     1393        state->cli.mem_ctx = talloc_tos();
     1394        child_process_request(state->child, &state->cli);
     1395
     1396        DEBUG(4, ("Finished processing child request %d\n",
     1397                  (int)state->cli.request->cmd));
     1398
     1399        SAFE_FREE(state->cli.request->extra_data.data);
     1400
     1401        status = child_write_response(state->cli.sock, state->cli.response);
     1402        if (!NT_STATUS_IS_OK(status)) {
     1403                exit(1);
     1404        }
     1405}
     1406
    12971407static bool fork_domain_child(struct winbindd_child *child)
    12981408{
    12991409        int fdpair[2];
    1300         struct winbindd_cli_state state;
     1410        struct child_handler_state state;
    13011411        struct winbindd_request request;
    13021412        struct winbindd_response response;
     
    13041414        NTSTATUS status;
    13051415        ssize_t nwritten;
     1416        struct tevent_fd *fde;
    13061417
    13071418        if (child->domain) {
     
    13191430
    13201431        ZERO_STRUCT(state);
    1321         state.pid = sys_getpid();
    1322         state.request = &request;
    1323         state.response = &response;
    1324 
    1325         child->pid = sys_fork();
     1432        state.child = child;
     1433        state.cli.pid = getpid();
     1434        state.cli.request = &request;
     1435        state.cli.response = &response;
     1436
     1437        child->pid = fork();
    13261438
    13271439        if (child->pid == -1) {
    13281440                DEBUG(0, ("Could not fork: %s\n", strerror(errno)));
     1441                close(fdpair[0]);
     1442                close(fdpair[1]);
    13291443                return False;
    13301444        }
     
    13601474        child_domain = child->domain;
    13611475
    1362         DEBUG(10, ("Child process %d\n", (int)sys_getpid()));
    1363 
    1364         state.sock = fdpair[0];
     1476        DEBUG(10, ("Child process %d\n", (int)getpid()));
     1477
     1478        state.cli.sock = fdpair[0];
    13651479        close(fdpair[1]);
    13661480
    13671481        status = winbindd_reinit_after_fork(child, child->logfilename);
    13681482
    1369         nwritten = sys_write(state.sock, &status, sizeof(status));
     1483        nwritten = sys_write(state.cli.sock, &status, sizeof(status));
    13701484        if (nwritten != sizeof(status)) {
    13711485                DEBUG(1, ("fork_domain_child: Could not write status: "
     
    14441558                }
    14451559
    1446                 child->lockout_policy_event = event_add_timed(
     1560                child->lockout_policy_event = tevent_add_timer(
    14471561                        winbind_event_context(), NULL, timeval_zero(),
    14481562                        account_lockout_policy_handler,
     
    14581572                if (calculate_next_machine_pwd_change(child->domain->name,
    14591573                                                       &next_change)) {
    1460                         child->machine_password_change_event = event_add_timed(
     1574                        child->machine_password_change_event = tevent_add_timer(
    14611575                                winbind_event_context(), NULL, next_change,
    14621576                                machine_password_change_handler,
     
    14651579        }
    14661580
     1581        fde = tevent_add_fd(winbind_event_context(), NULL, state.cli.sock,
     1582                            TEVENT_FD_READ, child_handler, &state);
     1583        if (fde == NULL) {
     1584                DEBUG(1, ("tevent_add_fd failed\n"));
     1585                _exit(1);
     1586        }
     1587
    14671588        while (1) {
    14681589
    14691590                int ret;
    1470                 struct pollfd *pfds;
    1471                 int num_pfds;
    1472                 int timeout;
    1473                 struct timeval t;
    1474                 struct timeval *tp;
    14751591                TALLOC_CTX *frame = talloc_stackframe();
    1476                 struct iovec iov[2];
    1477                 int iov_count;
    1478 
    1479                 if (run_events_poll(winbind_event_context(), 0, NULL, 0)) {
    1480                         TALLOC_FREE(frame);
    1481                         continue;
     1592
     1593                ret = tevent_loop_once(winbind_event_context());
     1594                if (ret != 0) {
     1595                        DEBUG(1, ("tevent_loop_once failed: %s\n",
     1596                                  strerror(errno)));
     1597                        _exit(1);
    14821598                }
    14831599
     
    14901606                }
    14911607
    1492                 pfds = TALLOC_ZERO_P(talloc_tos(), struct pollfd);
    1493                 if (pfds == NULL) {
    1494                         DEBUG(1, ("talloc failed\n"));
    1495                         _exit(1);
    1496                 }
    1497 
    1498                 pfds->fd = state.sock;
    1499                 pfds->events = POLLIN|POLLHUP;
    1500                 num_pfds = 1;
    1501 
    1502                 timeout = INT_MAX;
    1503 
    1504                 if (!event_add_to_poll_args(
    1505                             winbind_event_context(), talloc_tos(),
    1506                             &pfds, &num_pfds, &timeout)) {
    1507                         DEBUG(1, ("event_add_to_poll_args failed\n"));
    1508                         _exit(1);
    1509                 }
    1510                 tp = get_timed_events_timeout(winbind_event_context(), &t);
    1511                 if (tp) {
    1512                         DEBUG(11,("select will use timeout of %u.%u seconds\n",
    1513                                 (unsigned int)tp->tv_sec, (unsigned int)tp->tv_usec ));
    1514                 }
    1515 
    1516                 ret = sys_poll(pfds, num_pfds, timeout);
    1517 
    1518                 if (run_events_poll(winbind_event_context(), ret,
    1519                                     pfds, num_pfds)) {
    1520                         /* We got a signal - continue. */
    1521                         TALLOC_FREE(frame);
    1522                         continue;
    1523                 }
    1524 
    1525                 TALLOC_FREE(pfds);
    1526 
    1527                 if (ret == 0) {
    1528                         DEBUG(11,("nothing is ready yet, continue\n"));
    1529                         TALLOC_FREE(frame);
    1530                         continue;
    1531                 }
    1532 
    1533                 if (ret == -1 && errno == EINTR) {
    1534                         /* We got a signal - continue. */
    1535                         TALLOC_FREE(frame);
    1536                         continue;
    1537                 }
    1538 
    1539                 if (ret == -1 && errno != EINTR) {
    1540                         DEBUG(0,("poll error occured\n"));
    1541                         TALLOC_FREE(frame);
    1542                         perror("poll");
    1543                         _exit(1);
    1544                 }
    1545 
    1546                 /* fetch a request from the main daemon */
    1547                 status = child_read_request(&state);
    1548 
    1549                 if (!NT_STATUS_IS_OK(status)) {
    1550                         /* we lost contact with our parent */
    1551                         _exit(0);
    1552                 }
    1553 
    1554                 DEBUG(4,("child daemon request %d\n", (int)state.request->cmd));
    1555 
    1556                 ZERO_STRUCTP(state.response);
    1557                 state.request->null_term = '\0';
    1558                 state.mem_ctx = frame;
    1559                 child_process_request(child, &state);
    1560 
    1561                 DEBUG(4, ("Finished processing child request %d\n",
    1562                           (int)state.request->cmd));
    1563 
    1564                 SAFE_FREE(state.request->extra_data.data);
    1565 
    1566                 iov[0].iov_base = (void *)state.response;
    1567                 iov[0].iov_len = sizeof(struct winbindd_response);
    1568                 iov_count = 1;
    1569 
    1570                 if (state.response->length > sizeof(struct winbindd_response)) {
    1571                         iov[1].iov_base =
    1572                                 (void *)state.response->extra_data.data;
    1573                         iov[1].iov_len = state.response->length-iov[0].iov_len;
    1574                         iov_count = 2;
    1575                 }
    1576 
    1577                 DEBUG(10, ("Writing %d bytes to parent\n",
    1578                            (int)state.response->length));
    1579 
    1580                 if (write_data_iov(state.sock, iov, iov_count) !=
    1581                     state.response->length) {
    1582                         DEBUG(0, ("Could not write result\n"));
    1583                         exit(1);
    1584                 }
    15851608                TALLOC_FREE(frame);
    15861609        }
  • vendor/current/source3/winbindd/winbindd_dual_ndr.c

    r740 r988  
    3131#include "winbindd/winbindd_proto.h"
    3232#include "ntdomain.h"
    33 #include "librpc/gen_ndr/srv_wbint.h"
     33#include "librpc/gen_ndr/srv_winbind.h"
    3434
    3535struct wbint_bh_state {
     
    9797        ok = wbint_bh_is_connected(h);
    9898        if (!ok) {
    99                 tevent_req_nterror(req, NT_STATUS_INVALID_CONNECTION);
     99                tevent_req_nterror(req, NT_STATUS_CONNECTION_DISCONNECTED);
    100100                return tevent_req_post(req, ev);
    101101        }
     
    145145                state->response->length - sizeof(struct winbindd_response));
    146146        if (state->response->extra_data.data && !state->out_data.data) {
    147                 tevent_req_nomem(NULL, req);
     147                tevent_req_oom(req);
    148148                return;
    149149        }
     
    202202        ok = wbint_bh_is_connected(h);
    203203        if (!ok) {
    204                 tevent_req_nterror(req, NT_STATUS_INVALID_CONNECTION);
     204                tevent_req_nterror(req, NT_STATUS_CONNECTION_DISCONNECTED);
    205205                return tevent_req_post(req, ev);
    206206        }
     
    284284                                         &wbint_bh_ops,
    285285                                         NULL,
    286                                          &ndr_table_wbint,
     286                                         &ndr_table_winbind,
    287287                                         &hs,
    288288                                         struct wbint_bh_state,
     
    305305        bool ret;
    306306
    307         wbint_get_pipe_fns(&fns, &num_fns);
     307        winbind_get_pipe_fns(&fns, &num_fns);
    308308
    309309        if (state->request->data.ndrcmd >= num_fns) {
  • vendor/current/source3/winbindd/winbindd_dual_srv.c

    r740 r988  
    2626#include "rpc_client/cli_pipe.h"
    2727#include "ntdomain.h"
    28 #include "librpc/gen_ndr/srv_wbint.h"
     28#include "librpc/gen_ndr/srv_winbind.h"
    2929#include "../librpc/gen_ndr/ndr_netlogon_c.h"
     30#include "../librpc/gen_ndr/ndr_lsa_c.h"
    3031#include "idmap.h"
    3132#include "../libcli/security/security.h"
     33#include "../libcli/auth/netlogon_creds_cli.h"
     34#include "passdb.h"
     35#include "../source4/dsdb/samdb/samdb.h"
    3236
    3337void _wbint_Ping(struct pipes_struct *p, struct wbint_Ping *r)
     
    4044{
    4145        if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
    42                 invalidate_cm_connection(&domain->conn);
     46                invalidate_cm_connection(domain);
    4347                /* We invalidated the connection. */
    4448                return true;
     
    7579{
    7680        struct winbindd_domain *domain = wb_child_domain();
     81        struct lsa_RefDomainList *domains = r->out.domains;
    7782        NTSTATUS status;
    7883
     
    8893         */
    8994        status = rpc_lookup_sids(p->mem_ctx, domain, r->in.sids,
    90                                  &r->out.domains, &r->out.names);
     95                                 &domains, &r->out.names);
     96
     97        if (domains != NULL) {
     98                r->out.domains = domains;
     99        }
     100
    91101        reset_cm_connection_on_error(domain, status);
    92102        return status;
     
    107117        reset_cm_connection_on_error(domain, status);
    108118        return status;
    109 }
    110 
    111 NTSTATUS _wbint_Sid2Uid(struct pipes_struct *p, struct wbint_Sid2Uid *r)
    112 {
    113         uid_t uid;
    114         NTSTATUS status;
    115 
    116         status = idmap_sid_to_uid(r->in.dom_name ? r->in.dom_name : "",
    117                                   r->in.sid, &uid);
    118         if (!NT_STATUS_IS_OK(status)) {
    119                 return status;
    120         }
    121         *r->out.uid = uid;
    122         return NT_STATUS_OK;
    123 }
    124 
    125 NTSTATUS _wbint_Sid2Gid(struct pipes_struct *p, struct wbint_Sid2Gid *r)
    126 {
    127         gid_t gid;
    128         NTSTATUS status;
    129 
    130         status = idmap_sid_to_gid(r->in.dom_name ? r->in.dom_name : "",
    131                                   r->in.sid, &gid);
    132         if (!NT_STATUS_IS_OK(status)) {
    133                 return status;
    134         }
    135         *r->out.gid = gid;
    136         return NT_STATUS_OK;
    137119}
    138120
     
    152134                uint32_t num_ids;
    153135
    154                 dom = idmap_find_domain(d->name.string);
     136                dom = idmap_find_domain_with_sid(d->name.string, d->sid);
    155137                if (dom == NULL) {
    156                         DEBUG(10, ("idmap domain %s not found\n",
    157                                    d->name.string));
     138                        DEBUG(10, ("idmap domain %s:%s not found\n",
     139                                   d->name.string, sid_string_dbg(d->sid)));
    158140                        continue;
    159141                }
     
    167149                }
    168150
    169                 ids = TALLOC_REALLOC_ARRAY(talloc_tos(), ids,
     151                ids = talloc_realloc(talloc_tos(), ids,
    170152                                           struct id_map, num_ids);
    171153                if (ids == NULL) {
    172154                        goto nomem;
    173155                }
    174                 id_ptrs = TALLOC_REALLOC_ARRAY(talloc_tos(), id_ptrs,
     156                id_ptrs = talloc_realloc(talloc_tos(), id_ptrs,
    175157                                               struct id_map *, num_ids+1);
    176158                if (id_ptrs == NULL) {
    177159                        goto nomem;
    178160                }
    179                 id_idx = TALLOC_REALLOC_ARRAY(talloc_tos(), id_idx,
     161                id_idx = talloc_realloc(talloc_tos(), id_idx,
    180162                                              uint32_t, num_ids);
    181163                if (id_idx == NULL) {
    182164                        goto nomem;
    183165                }
    184                 sids = TALLOC_REALLOC_ARRAY(talloc_tos(), sids,
     166                sids = talloc_realloc(talloc_tos(), sids,
    185167                                            struct dom_sid, num_ids);
    186168                if (sids == NULL) {
     
    190172                num_ids = 0;
    191173
     174                /*
     175                 * Convert the input data into a list of
     176                 * id_map structs suitable for handing in
     177                 * to the idmap sids_to_unixids method.
     178                 */
    192179                for (j=0; j<r->in.ids->num_ids; j++) {
    193180                        struct wbint_TransID *id = &r->in.ids->ids[j];
     
    211198                           nt_errstr(status)));
    212199
     200                /*
     201                 * Extract the results for handing them back to the caller.
     202                 */
    213203                for (j=0; j<num_ids; j++) {
    214204                        struct wbint_TransID *id = &r->in.ids->ids[id_idx[j]];
    215205
    216206                        if (ids[j].status != ID_MAPPED) {
     207                                id->xid.id = UINT32_MAX;
     208                                id->xid.type = ID_TYPE_NOT_SPECIFIED;
    217209                                continue;
    218210                        }
    219                         id->unix_id = ids[j].xid.id;
     211
     212                        id->xid = ids[j].xid;
    220213                }
    221214        }
     
    231224NTSTATUS _wbint_Uid2Sid(struct pipes_struct *p, struct wbint_Uid2Sid *r)
    232225{
    233         return idmap_uid_to_sid(r->in.dom_name ? r->in.dom_name : "",
    234                                 r->out.sid, r->in.uid);
     226        return idmap_uid_to_sid(r->out.sid, r->in.uid);
    235227}
    236228
    237229NTSTATUS _wbint_Gid2Sid(struct pipes_struct *p, struct wbint_Gid2Sid *r)
    238230{
    239         return idmap_gid_to_sid(r->in.dom_name ? r->in.dom_name : "",
    240                                 r->out.sid, r->in.gid);
     231        return idmap_gid_to_sid(r->out.sid, r->in.gid);
    241232}
    242233
     
    391382{
    392383        struct winbindd_domain *domain = wb_child_domain();
    393         uint32_t i, num_groups;
    394         struct wb_acct_info *groups;
     384        uint32_t i;
     385        uint32_t num_local_groups = 0;
     386        struct wb_acct_info *local_groups = NULL;
     387        uint32_t num_dom_groups = 0;
     388        struct wb_acct_info *dom_groups = NULL;
     389        uint32_t ti = 0;
     390        uint64_t num_total = 0;
    395391        struct wbint_Principal *result;
    396392        NTSTATUS status;
     393        bool include_local_groups = false;
    397394
    398395        if (domain == NULL) {
     
    400397        }
    401398
     399        switch (lp_server_role()) {
     400        case ROLE_ACTIVE_DIRECTORY_DC:
     401                if (domain->internal) {
     402                        /*
     403                         * we want to include local groups
     404                         * for BUILTIN and WORKGROUP
     405                         */
     406                        include_local_groups = true;
     407                }
     408                break;
     409        default:
     410                /*
     411                 * We might include local groups in more
     412                 * setups later, but that requires more work
     413                 * elsewhere.
     414                 */
     415                break;
     416        }
     417
     418        if (include_local_groups) {
     419                status = domain->methods->enum_local_groups(domain, talloc_tos(),
     420                                                            &num_local_groups,
     421                                                            &local_groups);
     422                reset_cm_connection_on_error(domain, status);
     423                if (!NT_STATUS_IS_OK(status)) {
     424                        return status;
     425                }
     426        }
     427
    402428        status = domain->methods->enum_dom_groups(domain, talloc_tos(),
    403                                                   &num_groups, &groups);
     429                                                  &num_dom_groups,
     430                                                  &dom_groups);
    404431        reset_cm_connection_on_error(domain, status);
    405432        if (!NT_STATUS_IS_OK(status)) {
     
    407434        }
    408435
     436        num_total = num_local_groups + num_dom_groups;
     437        if (num_total > UINT32_MAX) {
     438                return NT_STATUS_INTERNAL_ERROR;
     439        }
     440
    409441        result = talloc_array(r->out.groups, struct wbint_Principal,
    410                               num_groups);
     442                              num_total);
    411443        if (result == NULL) {
    412444                return NT_STATUS_NO_MEMORY;
    413445        }
    414446
    415         for (i=0; i<num_groups; i++) {
    416                 sid_compose(&result[i].sid, &domain->sid, groups[i].rid);
    417                 result[i].type = SID_NAME_DOM_GRP;
    418                 result[i].name = talloc_strdup(result, groups[i].acct_name);
    419                 if (result[i].name == NULL) {
     447        for (i = 0; i < num_local_groups; i++) {
     448                struct wb_acct_info *lg = &local_groups[i];
     449                struct wbint_Principal *rg = &result[ti++];
     450
     451                sid_compose(&rg->sid, &domain->sid, lg->rid);
     452                rg->type = SID_NAME_ALIAS;
     453                rg->name = talloc_strdup(result, lg->acct_name);
     454                if (rg->name == NULL) {
    420455                        TALLOC_FREE(result);
    421                         TALLOC_FREE(groups);
     456                        TALLOC_FREE(dom_groups);
     457                        TALLOC_FREE(local_groups);
    422458                        return NT_STATUS_NO_MEMORY;
    423459                }
    424460        }
    425 
    426         r->out.groups->num_principals = num_groups;
     461        num_local_groups = 0;
     462        TALLOC_FREE(local_groups);
     463
     464        for (i = 0; i < num_dom_groups; i++) {
     465                struct wb_acct_info *dg = &dom_groups[i];
     466                struct wbint_Principal *rg = &result[ti++];
     467
     468                sid_compose(&rg->sid, &domain->sid, dg->rid);
     469                rg->type = SID_NAME_DOM_GRP;
     470                rg->name = talloc_strdup(result, dg->acct_name);
     471                if (rg->name == NULL) {
     472                        TALLOC_FREE(result);
     473                        TALLOC_FREE(dom_groups);
     474                        TALLOC_FREE(local_groups);
     475                        return NT_STATUS_NO_MEMORY;
     476                }
     477        }
     478        num_dom_groups = 0;
     479        TALLOC_FREE(dom_groups);
     480
     481        r->out.groups->num_principals = ti;
    427482        r->out.groups->principals = result;
    428483
    429         TALLOC_FREE(groups);
    430484        return NT_STATUS_OK;
    431485}
     
    591645
    592646again:
    593         invalidate_cm_connection(&domain->conn);
     647        invalidate_cm_connection(domain);
     648        domain->conn.netlogon_force_reauth = true;
    594649
    595650        {
     
    633688                                     struct wbint_ChangeMachineAccount *r)
    634689{
     690        struct messaging_context *msg_ctx = winbind_messaging_context();
    635691        struct winbindd_domain *domain;
    636         int num_retries = 0;
    637692        NTSTATUS status;
    638693        struct rpc_pipe_client *netlogon_pipe;
    639         TALLOC_CTX *tmp_ctx;
    640 
    641 again:
     694
    642695        domain = wb_child_domain();
    643696        if (domain == NULL) {
     
    645698        }
    646699
    647         invalidate_cm_connection(&domain->conn);
    648 
    649         {
    650                 status = cm_connect_netlogon(domain, &netlogon_pipe);
    651         }
    652 
    653         /* There is a race condition between fetching the trust account
    654            password and the periodic machine password change.  So it's
    655            possible that the trust account password has been changed on us.
    656            We are returned NT_STATUS_ACCESS_DENIED if this happens. */
    657 
    658 #define MAX_RETRIES 3
    659 
    660         if ((num_retries < MAX_RETRIES)
    661              && NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
    662                 num_retries++;
    663                 goto again;
    664         }
    665 
     700        status = cm_connect_netlogon(domain, &netlogon_pipe);
    666701        if (!NT_STATUS_IS_OK(status)) {
    667702                DEBUG(3, ("could not open handle to NETLOGON pipe\n"));
     
    669704        }
    670705
    671         tmp_ctx = talloc_new(p->mem_ctx);
    672 
    673         status = trust_pw_find_change_and_store_it(netlogon_pipe,
    674                                                    tmp_ctx,
    675                                                    domain->name);
    676         talloc_destroy(tmp_ctx);
     706        status = trust_pw_change(domain->conn.netlogon_creds,
     707                                 msg_ctx,
     708                                 netlogon_pipe->binding_handle,
     709                                 domain->name,
     710                                 true); /* force */
    677711
    678712        /* Pass back result code - zero for success, other values for
     
    699733        fstring logon_server;
    700734        struct dcerpc_binding_handle *b;
     735        bool retry = false;
    701736
    702737        domain = wb_child_domain();
     
    705740        }
    706741
     742reconnect:
    707743        status = cm_connect_netlogon(domain, &netlogon_pipe);
    708744        reset_cm_connection_on_error(domain, status);
    709745        if (!NT_STATUS_IS_OK(status)) {
    710                 DEBUG(3, ("could not open handle to NETLOGON pipe\n"));
     746                DEBUG(3, ("could not open handle to NETLOGON pipe: %s\n",
     747                          nt_errstr(status)));
    711748                return status;
    712749        }
     
    715752
    716753        fstr_sprintf(logon_server, "\\\\%s", domain->dcname);
     754        *r->out.dcname = talloc_strdup(p->mem_ctx, domain->dcname);
     755        if (*r->out.dcname == NULL) {
     756                DEBUG(2, ("Could not allocate memory\n"));
     757                return NT_STATUS_NO_MEMORY;
     758        }
    717759
    718760        /*
     
    726768                                          2, &info, &werr);
    727769
     770        if (!dcerpc_binding_handle_is_connected(b) && !retry) {
     771                DEBUG(10, ("Session might have expired. "
     772                           "Reconnect and retry once.\n"));
     773                invalidate_cm_connection(domain);
     774                retry = true;
     775                goto reconnect;
     776        }
     777
    728778        reset_cm_connection_on_error(domain, status);
    729779        if (!NT_STATUS_IS_OK(status)) {
     
    743793        return NT_STATUS_OK;
    744794}
     795
     796NTSTATUS _winbind_DsrUpdateReadOnlyServerDnsRecords(struct pipes_struct *p,
     797                                                    struct winbind_DsrUpdateReadOnlyServerDnsRecords *r)
     798{
     799        struct winbindd_domain *domain;
     800        NTSTATUS status;
     801        struct rpc_pipe_client *netlogon_pipe;
     802
     803        domain = wb_child_domain();
     804        if (domain == NULL) {
     805                return NT_STATUS_REQUEST_NOT_ACCEPTED;
     806        }
     807
     808        status = cm_connect_netlogon(domain, &netlogon_pipe);
     809        if (!NT_STATUS_IS_OK(status)) {
     810                DEBUG(3, ("could not open handle to NETLOGON pipe\n"));
     811                goto done;
     812        }
     813
     814        status = netlogon_creds_cli_DsrUpdateReadOnlyServerDnsRecords(domain->conn.netlogon_creds,
     815                                                                      netlogon_pipe->binding_handle,
     816                                                                      r->in.site_name,
     817                                                                      r->in.dns_ttl,
     818                                                                      r->in.dns_names);
     819
     820        /* Pass back result code - zero for success, other values for
     821           specific failures. */
     822
     823        DEBUG(3,("DNS records for domain %s %s\n", domain->name,
     824                NT_STATUS_IS_OK(status) ? "changed" : "unchanged"));
     825
     826 done:
     827        DEBUG(NT_STATUS_IS_OK(status) ? 5 : 2,
     828              ("Update of DNS records via RW DC %s returned %s\n",
     829               domain->name, nt_errstr(status)));
     830
     831        return status;
     832}
     833
     834NTSTATUS _winbind_SamLogon(struct pipes_struct *p,
     835                        struct winbind_SamLogon *r)
     836{
     837        struct winbindd_domain *domain;
     838        NTSTATUS status;
     839        DATA_BLOB lm_response, nt_response;
     840        domain = wb_child_domain();
     841        if (domain == NULL) {
     842                return NT_STATUS_REQUEST_NOT_ACCEPTED;
     843        }
     844
     845        /* TODO: Handle interactive logons here */
     846        if (r->in.validation_level != 3 ||
     847            r->in.logon.network == NULL ||
     848            (r->in.logon_level != NetlogonNetworkInformation
     849             && r->in.logon_level != NetlogonNetworkTransitiveInformation)) {
     850                return NT_STATUS_REQUEST_NOT_ACCEPTED;
     851        }
     852
     853
     854        lm_response = data_blob_talloc(p->mem_ctx, r->in.logon.network->lm.data, r->in.logon.network->lm.length);
     855        nt_response = data_blob_talloc(p->mem_ctx, r->in.logon.network->nt.data, r->in.logon.network->nt.length);
     856
     857        status = winbind_dual_SamLogon(domain, p->mem_ctx,
     858                                       r->in.logon.network->identity_info.parameter_control,
     859                                       r->in.logon.network->identity_info.account_name.string,
     860                                       r->in.logon.network->identity_info.domain_name.string,
     861                                       r->in.logon.network->identity_info.workstation.string,
     862                                       r->in.logon.network->challenge,
     863                                       lm_response, nt_response, &r->out.validation.sam3);
     864        return status;
     865}
     866
     867static WERROR _winbind_LogonControl_REDISCOVER(struct pipes_struct *p,
     868                             struct winbindd_domain *domain,
     869                             struct winbind_LogonControl *r)
     870{
     871        NTSTATUS status;
     872        struct rpc_pipe_client *netlogon_pipe = NULL;
     873        struct netr_NETLOGON_INFO_2 *info2 = NULL;
     874        WERROR check_result = WERR_INTERNAL_ERROR;
     875
     876        info2 = talloc_zero(p->mem_ctx, struct netr_NETLOGON_INFO_2);
     877        if (info2 == NULL) {
     878                return WERR_NOMEM;
     879        }
     880
     881        if (domain->internal) {
     882                check_result = WERR_OK;
     883                goto check_return;
     884        }
     885
     886        /*
     887         * For now we just force a reconnect
     888         *
     889         * TODO: take care of the optional '\dcname'
     890         */
     891        invalidate_cm_connection(domain);
     892        domain->conn.netlogon_force_reauth = true;
     893        status = cm_connect_netlogon(domain, &netlogon_pipe);
     894        reset_cm_connection_on_error(domain, status);
     895        if (NT_STATUS_EQUAL(status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) {
     896                status = NT_STATUS_NO_LOGON_SERVERS;
     897        }
     898        if (!NT_STATUS_IS_OK(status)) {
     899                DEBUG(2, ("%s: domain[%s/%s] cm_connect_netlogon() returned %s\n",
     900                          __func__, domain->name, domain->alt_name,
     901                          nt_errstr(status)));
     902                /*
     903                 * Here we return a top level error!
     904                 * This is different than TC_QUERY or TC_VERIFY.
     905                 */
     906                return ntstatus_to_werror(status);
     907        }
     908        check_result = WERR_OK;
     909
     910check_return:
     911        info2->pdc_connection_status = WERR_OK;
     912        if (domain->dcname != NULL) {
     913                info2->flags |= NETLOGON_HAS_IP;
     914                info2->flags |= NETLOGON_HAS_TIMESERV;
     915                info2->trusted_dc_name = talloc_asprintf(info2, "\\\\%s",
     916                                                         domain->dcname);
     917                if (info2->trusted_dc_name == NULL) {
     918                        return WERR_NOMEM;
     919                }
     920        } else {
     921                info2->trusted_dc_name = talloc_strdup(info2, "");
     922                if (info2->trusted_dc_name == NULL) {
     923                        return WERR_NOMEM;
     924                }
     925        }
     926        info2->tc_connection_status = check_result;
     927
     928        if (!W_ERROR_IS_OK(info2->pdc_connection_status)) {
     929                DEBUG(2, ("%s: domain[%s/%s] dcname[%s] "
     930                          "pdc_connection[%s] tc_connection[%s]\n",
     931                          __func__, domain->name, domain->alt_name,
     932                          domain->dcname,
     933                          win_errstr(info2->pdc_connection_status),
     934                          win_errstr(info2->tc_connection_status)));
     935        }
     936
     937        r->out.query->info2 = info2;
     938
     939        DEBUG(5, ("%s: succeeded.\n", __func__));
     940        return WERR_OK;
     941}
     942
     943static WERROR _winbind_LogonControl_TC_QUERY(struct pipes_struct *p,
     944                             struct winbindd_domain *domain,
     945                             struct winbind_LogonControl *r)
     946{
     947        NTSTATUS status;
     948        struct rpc_pipe_client *netlogon_pipe = NULL;
     949        struct netr_NETLOGON_INFO_2 *info2 = NULL;
     950        WERROR check_result = WERR_INTERNAL_ERROR;
     951
     952        info2 = talloc_zero(p->mem_ctx, struct netr_NETLOGON_INFO_2);
     953        if (info2 == NULL) {
     954                return WERR_NOMEM;
     955        }
     956
     957        if (domain->internal) {
     958                check_result = WERR_OK;
     959                goto check_return;
     960        }
     961
     962        status = cm_connect_netlogon(domain, &netlogon_pipe);
     963        reset_cm_connection_on_error(domain, status);
     964        if (NT_STATUS_EQUAL(status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) {
     965                status = NT_STATUS_NO_LOGON_SERVERS;
     966        }
     967        if (!NT_STATUS_IS_OK(status)) {
     968                DEBUG(3, ("could not open handle to NETLOGON pipe: %s\n",
     969                          nt_errstr(status)));
     970                check_result = ntstatus_to_werror(status);
     971                goto check_return;
     972        }
     973        check_result = WERR_OK;
     974
     975check_return:
     976        info2->pdc_connection_status = WERR_OK;
     977        if (domain->dcname != NULL) {
     978                info2->flags |= NETLOGON_HAS_IP;
     979                info2->flags |= NETLOGON_HAS_TIMESERV;
     980                info2->trusted_dc_name = talloc_asprintf(info2, "\\\\%s",
     981                                                         domain->dcname);
     982                if (info2->trusted_dc_name == NULL) {
     983                        return WERR_NOMEM;
     984                }
     985        } else {
     986                info2->trusted_dc_name = talloc_strdup(info2, "");
     987                if (info2->trusted_dc_name == NULL) {
     988                        return WERR_NOMEM;
     989                }
     990        }
     991        info2->tc_connection_status = check_result;
     992
     993        if (!W_ERROR_IS_OK(info2->pdc_connection_status)) {
     994                DEBUG(2, ("%s: domain[%s/%s] dcname[%s] "
     995                          "pdc_connection[%s] tc_connection[%s]\n",
     996                          __func__, domain->name, domain->alt_name,
     997                          domain->dcname,
     998                          win_errstr(info2->pdc_connection_status),
     999                          win_errstr(info2->tc_connection_status)));
     1000        }
     1001
     1002        r->out.query->info2 = info2;
     1003
     1004        DEBUG(5, ("%s: succeeded.\n", __func__));
     1005        return WERR_OK;
     1006}
     1007
     1008static WERROR _winbind_LogonControl_TC_VERIFY(struct pipes_struct *p,
     1009                             struct winbindd_domain *domain,
     1010                             struct winbind_LogonControl *r)
     1011{
     1012        TALLOC_CTX *frame = talloc_stackframe();
     1013        NTSTATUS status;
     1014        NTSTATUS result;
     1015        struct lsa_String trusted_domain_name = {};
     1016        struct lsa_StringLarge trusted_domain_name_l = {};
     1017        struct rpc_pipe_client *local_lsa_pipe = NULL;
     1018        struct policy_handle local_lsa_policy = {};
     1019        struct dcerpc_binding_handle *local_lsa = NULL;
     1020        struct rpc_pipe_client *netlogon_pipe = NULL;
     1021        struct cli_credentials *creds = NULL;
     1022        struct samr_Password *cur_nt_hash = NULL;
     1023        uint32_t trust_attributes = 0;
     1024        struct samr_Password new_owf_password = {};
     1025        int cmp_new = -1;
     1026        struct samr_Password old_owf_password = {};
     1027        int cmp_old = -1;
     1028        const struct lsa_TrustDomainInfoInfoEx *local_tdo = NULL;
     1029        bool fetch_fti = false;
     1030        struct lsa_ForestTrustInformation *new_fti = NULL;
     1031        struct netr_TrustInfo *trust_info = NULL;
     1032        struct netr_NETLOGON_INFO_2 *info2 = NULL;
     1033        struct dcerpc_binding_handle *b = NULL;
     1034        WERROR check_result = WERR_INTERNAL_ERROR;
     1035        WERROR verify_result = WERR_INTERNAL_ERROR;
     1036        bool retry = false;
     1037
     1038        trusted_domain_name.string = domain->name;
     1039        trusted_domain_name_l.string = domain->name;
     1040
     1041        info2 = talloc_zero(p->mem_ctx, struct netr_NETLOGON_INFO_2);
     1042        if (info2 == NULL) {
     1043                TALLOC_FREE(frame);
     1044                return WERR_NOMEM;
     1045        }
     1046
     1047        if (domain->internal) {
     1048                check_result = WERR_OK;
     1049                goto check_return;
     1050        }
     1051
     1052        status = pdb_get_trust_credentials(domain->name,
     1053                                           domain->alt_name,
     1054                                           frame,
     1055                                           &creds);
     1056        if (NT_STATUS_IS_OK(status)) {
     1057                cur_nt_hash = cli_credentials_get_nt_hash(creds, frame);
     1058                TALLOC_FREE(creds);
     1059        }
     1060
     1061        if (!domain->primary) {
     1062                union lsa_TrustedDomainInfo *tdi = NULL;
     1063
     1064                status = open_internal_lsa_conn(frame, &local_lsa_pipe,
     1065                                                &local_lsa_policy);
     1066                if (!NT_STATUS_IS_OK(status)) {
     1067                        DEBUG(0,("%s:%s: open_internal_lsa_conn() failed - %s\n",
     1068                                 __location__, __func__, nt_errstr(status)));
     1069                        TALLOC_FREE(frame);
     1070                        return WERR_INTERNAL_ERROR;
     1071                }
     1072                local_lsa = local_lsa_pipe->binding_handle;
     1073
     1074                status = dcerpc_lsa_QueryTrustedDomainInfoByName(local_lsa, frame,
     1075                                                        &local_lsa_policy,
     1076                                                        &trusted_domain_name,
     1077                                                        LSA_TRUSTED_DOMAIN_INFO_INFO_EX,
     1078                                                        &tdi, &result);
     1079                if (!NT_STATUS_IS_OK(status)) {
     1080                        DEBUG(0,("%s:%s: local_lsa.QueryTrustedDomainInfoByName(%s) failed - %s\n",
     1081                                 __location__, __func__, domain->name, nt_errstr(status)));
     1082                        TALLOC_FREE(frame);
     1083                        return WERR_INTERNAL_ERROR;
     1084                }
     1085                if (NT_STATUS_EQUAL(result, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
     1086                        DEBUG(1,("%s:%s: domain[%s] not found via LSA, might be removed already.\n",
     1087                                 __location__, __func__, domain->name));
     1088                        TALLOC_FREE(frame);
     1089                        return WERR_NO_SUCH_DOMAIN;
     1090                }
     1091                if (!NT_STATUS_IS_OK(result)) {
     1092                        DEBUG(0,("%s:%s: local_lsa.QueryTrustedDomainInfoByName(%s) returned %s\n",
     1093                                 __location__, __func__, domain->name, nt_errstr(result)));
     1094                        TALLOC_FREE(frame);
     1095                        return WERR_INTERNAL_ERROR;
     1096                }
     1097                if (tdi == NULL) {
     1098                        DEBUG(0,("%s:%s: local_lsa.QueryTrustedDomainInfoByName() "
     1099                                 "returned no trusted domain information\n",
     1100                                 __location__, __func__));
     1101                        TALLOC_FREE(frame);
     1102                        return WERR_INTERNAL_ERROR;
     1103                }
     1104
     1105                local_tdo = &tdi->info_ex;
     1106                trust_attributes = local_tdo->trust_attributes;
     1107        }
     1108
     1109        if (trust_attributes & LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
     1110                struct lsa_ForestTrustInformation *old_fti = NULL;
     1111
     1112                status = dcerpc_lsa_lsaRQueryForestTrustInformation(local_lsa, frame,
     1113                                                        &local_lsa_policy,
     1114                                                        &trusted_domain_name,
     1115                                                        LSA_FOREST_TRUST_DOMAIN_INFO,
     1116                                                        &old_fti, &result);
     1117                if (!NT_STATUS_IS_OK(status)) {
     1118                        DEBUG(0,("%s:%s: local_lsa.lsaRQueryForestTrustInformation(%s) failed %s\n",
     1119                                 __location__, __func__, domain->name, nt_errstr(status)));
     1120                        TALLOC_FREE(frame);
     1121                        return WERR_INTERNAL_ERROR;
     1122                }
     1123                if (NT_STATUS_EQUAL(result, NT_STATUS_NOT_FOUND)) {
     1124                        DEBUG(2,("%s: no forest trust information available for domain[%s] yet.\n",
     1125                                  __func__, domain->name));
     1126                        old_fti = NULL;
     1127                        fetch_fti = true;
     1128                        result = NT_STATUS_OK;
     1129                }
     1130                if (!NT_STATUS_IS_OK(result)) {
     1131                        DEBUG(0,("%s:%s: local_lsa.lsaRQueryForestTrustInformation(%s) returned %s\n",
     1132                                 __location__, __func__, domain->name, nt_errstr(result)));
     1133                        TALLOC_FREE(frame);
     1134                        return WERR_INTERNAL_ERROR;
     1135                }
     1136
     1137                TALLOC_FREE(old_fti);
     1138        }
     1139
     1140reconnect:
     1141        status = cm_connect_netlogon(domain, &netlogon_pipe);
     1142        reset_cm_connection_on_error(domain, status);
     1143        if (NT_STATUS_EQUAL(status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) {
     1144                status = NT_STATUS_NO_LOGON_SERVERS;
     1145        }
     1146        if (!NT_STATUS_IS_OK(status)) {
     1147                DEBUG(3, ("could not open handle to NETLOGON pipe: %s\n",
     1148                          nt_errstr(status)));
     1149                check_result = ntstatus_to_werror(status);
     1150                goto check_return;
     1151        }
     1152        check_result = WERR_OK;
     1153        b = netlogon_pipe->binding_handle;
     1154
     1155        if (cur_nt_hash == NULL) {
     1156                verify_result = WERR_NO_TRUST_LSA_SECRET;
     1157                goto verify_return;
     1158        }
     1159
     1160        if (fetch_fti) {
     1161                status = netlogon_creds_cli_GetForestTrustInformation(domain->conn.netlogon_creds,
     1162                                                                      b, frame,
     1163                                                                      &new_fti);
     1164                if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) {
     1165                        status = NT_STATUS_NOT_SUPPORTED;
     1166                }
     1167                if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
     1168                        new_fti = NULL;
     1169                        status = NT_STATUS_OK;
     1170                }
     1171                if (!NT_STATUS_IS_OK(status)) {
     1172                        if (!retry && dcerpc_binding_handle_is_connected(b)) {
     1173                                invalidate_cm_connection(domain);
     1174                                retry = true;
     1175                                goto reconnect;
     1176                        }
     1177                        DEBUG(2, ("netlogon_creds_cli_GetForestTrustInformation(%s)"
     1178                                  "failed: %s\n",
     1179                                  domain->name, nt_errstr(status)));
     1180                        check_result = ntstatus_to_werror(status);
     1181                        goto check_return;
     1182                }
     1183        }
     1184
     1185        if (new_fti != NULL) {
     1186                struct lsa_ForestTrustInformation old_fti = {};
     1187                struct lsa_ForestTrustInformation *merged_fti = NULL;
     1188                struct lsa_ForestTrustCollisionInfo *collision_info = NULL;
     1189
     1190                status = dsdb_trust_merge_forest_info(frame, local_tdo,
     1191                                                      &old_fti, new_fti,
     1192                                                      &merged_fti);
     1193                if (!NT_STATUS_IS_OK(status)) {
     1194                        DEBUG(0,("%s:%s: dsdb_trust_merge_forest_info(%s) failed %s\n",
     1195                                 __location__, __func__,
     1196                                 domain->name, nt_errstr(status)));
     1197                        TALLOC_FREE(frame);
     1198                        return ntstatus_to_werror(status);
     1199                }
     1200
     1201                status = dcerpc_lsa_lsaRSetForestTrustInformation(local_lsa, frame,
     1202                                                &local_lsa_policy,
     1203                                                &trusted_domain_name_l,
     1204                                                LSA_FOREST_TRUST_DOMAIN_INFO,
     1205                                                merged_fti,
     1206                                                0, /* check_only=0 => store it! */
     1207                                                &collision_info,
     1208                                                &result);
     1209                if (!NT_STATUS_IS_OK(status)) {
     1210                        DEBUG(0,("%s:%s: local_lsa.lsaRSetForestTrustInformation(%s) failed %s\n",
     1211                                 __location__, __func__, domain->name, nt_errstr(status)));
     1212                        TALLOC_FREE(frame);
     1213                        return WERR_INTERNAL_ERROR;
     1214                }
     1215                if (!NT_STATUS_IS_OK(result)) {
     1216                        DEBUG(0,("%s:%s: local_lsa.lsaRSetForestTrustInformation(%s) returned %s\n",
     1217                                 __location__, __func__, domain->name, nt_errstr(result)));
     1218                        TALLOC_FREE(frame);
     1219                        return ntstatus_to_werror(result);
     1220                }
     1221        }
     1222
     1223        status = netlogon_creds_cli_ServerGetTrustInfo(domain->conn.netlogon_creds,
     1224                                                       b, frame,
     1225                                                       &new_owf_password,
     1226                                                       &old_owf_password,
     1227                                                       &trust_info);
     1228        if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) {
     1229                status = NT_STATUS_NOT_SUPPORTED;
     1230        }
     1231        if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
     1232                DEBUG(5, ("netlogon_creds_cli_ServerGetTrustInfo failed: %s\n",
     1233                        nt_errstr(status)));
     1234                verify_result = WERR_OK;
     1235                goto verify_return;
     1236        }
     1237        if (!NT_STATUS_IS_OK(status)) {
     1238                if (!retry && dcerpc_binding_handle_is_connected(b)) {
     1239                        invalidate_cm_connection(domain);
     1240                        retry = true;
     1241                        goto reconnect;
     1242                }
     1243                DEBUG(2, ("netlogon_creds_cli_ServerGetTrustInfo failed: %s\n",
     1244                        nt_errstr(status)));
     1245
     1246                if (!dcerpc_binding_handle_is_connected(b)) {
     1247                        check_result = ntstatus_to_werror(status);
     1248                        goto check_return;
     1249                } else {
     1250                        verify_result = ntstatus_to_werror(status);
     1251                        goto verify_return;
     1252                }
     1253        }
     1254
     1255        if (trust_info != NULL && trust_info->count >= 1) {
     1256                uint32_t diff = trust_info->data[0] ^ trust_attributes;
     1257
     1258                if (diff & LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
     1259                        verify_result = WERR_DOMAIN_TRUST_INCONSISTENT;
     1260                        goto verify_return;
     1261                }
     1262        }
     1263
     1264        cmp_new = memcmp(new_owf_password.hash,
     1265                         cur_nt_hash->hash,
     1266                         sizeof(cur_nt_hash->hash));
     1267        cmp_old = memcmp(old_owf_password.hash,
     1268                         cur_nt_hash->hash,
     1269                         sizeof(cur_nt_hash->hash));
     1270        if (cmp_new != 0 && cmp_old != 0) {
     1271                DEBUG(1,("%s:Error: credentials for domain[%s/%s] doesn't match "
     1272                         "any password known to dcname[%s]\n",
     1273                         __func__, domain->name, domain->alt_name,
     1274                         domain->dcname));
     1275                verify_result = WERR_WRONG_PASSWORD;
     1276                goto verify_return;
     1277        }
     1278
     1279        if (cmp_new != 0) {
     1280                DEBUG(2,("%s:Warning: credentials for domain[%s/%s] only match "
     1281                         "against the old password known to dcname[%s]\n",
     1282                         __func__, domain->name, domain->alt_name,
     1283                         domain->dcname));
     1284        }
     1285
     1286        verify_result = WERR_OK;
     1287        goto verify_return;
     1288
     1289check_return:
     1290        verify_result = check_result;
     1291verify_return:
     1292        info2->flags |= NETLOGON_VERIFY_STATUS_RETURNED;
     1293        info2->pdc_connection_status = verify_result;
     1294        if (domain->dcname != NULL) {
     1295                info2->flags |= NETLOGON_HAS_IP;
     1296                info2->flags |= NETLOGON_HAS_TIMESERV;
     1297                info2->trusted_dc_name = talloc_asprintf(info2, "\\\\%s",
     1298                                                         domain->dcname);
     1299                if (info2->trusted_dc_name == NULL) {
     1300                        TALLOC_FREE(frame);
     1301                        return WERR_NOMEM;
     1302                }
     1303        } else {
     1304                info2->trusted_dc_name = talloc_strdup(info2, "");
     1305                if (info2->trusted_dc_name == NULL) {
     1306                        TALLOC_FREE(frame);
     1307                        return WERR_NOMEM;
     1308                }
     1309        }
     1310        info2->tc_connection_status = check_result;
     1311
     1312        if (!W_ERROR_IS_OK(info2->pdc_connection_status)) {
     1313                DEBUG(2, ("%s: domain[%s/%s] dcname[%s] "
     1314                          "pdc_connection[%s] tc_connection[%s]\n",
     1315                          __func__, domain->name, domain->alt_name,
     1316                          domain->dcname,
     1317                          win_errstr(info2->pdc_connection_status),
     1318                          win_errstr(info2->tc_connection_status)));
     1319        }
     1320
     1321        r->out.query->info2 = info2;
     1322
     1323        DEBUG(5, ("%s: succeeded.\n", __func__));
     1324        TALLOC_FREE(frame);
     1325        return WERR_OK;
     1326}
     1327
     1328static WERROR _winbind_LogonControl_CHANGE_PASSWORD(struct pipes_struct *p,
     1329                             struct winbindd_domain *domain,
     1330                             struct winbind_LogonControl *r)
     1331{
     1332        struct messaging_context *msg_ctx = winbind_messaging_context();
     1333        NTSTATUS status;
     1334        struct rpc_pipe_client *netlogon_pipe;
     1335        struct cli_credentials *creds = NULL;
     1336        struct samr_Password *cur_nt_hash = NULL;
     1337        struct netr_NETLOGON_INFO_1 *info1 = NULL;
     1338        struct dcerpc_binding_handle *b;
     1339        WERROR change_result = WERR_OK;
     1340        bool retry = false;
     1341
     1342        info1 = talloc_zero(p->mem_ctx, struct netr_NETLOGON_INFO_1);
     1343        if (info1 == NULL) {
     1344                return WERR_NOMEM;
     1345        }
     1346
     1347        if (domain->internal) {
     1348                return WERR_NOT_SUPPORTED;
     1349        }
     1350
     1351        status = pdb_get_trust_credentials(domain->name,
     1352                                           domain->alt_name,
     1353                                           p->mem_ctx,
     1354                                           &creds);
     1355        if (NT_STATUS_IS_OK(status)) {
     1356                cur_nt_hash = cli_credentials_get_nt_hash(creds, p->mem_ctx);
     1357                TALLOC_FREE(creds);
     1358        }
     1359
     1360reconnect:
     1361        status = cm_connect_netlogon(domain, &netlogon_pipe);
     1362        reset_cm_connection_on_error(domain, status);
     1363        if (NT_STATUS_EQUAL(status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) {
     1364                status = NT_STATUS_NO_LOGON_SERVERS;
     1365        }
     1366        if (!NT_STATUS_IS_OK(status)) {
     1367                DEBUG(2, ("%s: domain[%s/%s] cm_connect_netlogon() returned %s\n",
     1368                          __func__, domain->name, domain->alt_name,
     1369                          nt_errstr(status)));
     1370                /*
     1371                 * Here we return a top level error!
     1372                 * This is different than TC_QUERY or TC_VERIFY.
     1373                 */
     1374                return ntstatus_to_werror(status);
     1375        }
     1376        b = netlogon_pipe->binding_handle;
     1377
     1378        if (cur_nt_hash == NULL) {
     1379                change_result = WERR_NO_TRUST_LSA_SECRET;
     1380                goto change_return;
     1381        }
     1382        TALLOC_FREE(cur_nt_hash);
     1383
     1384        status = trust_pw_change(domain->conn.netlogon_creds,
     1385                                 msg_ctx, b, domain->name,
     1386                                 true); /* force */
     1387        if (!NT_STATUS_IS_OK(status)) {
     1388                if (!retry && dcerpc_binding_handle_is_connected(b)) {
     1389                        invalidate_cm_connection(domain);
     1390                        retry = true;
     1391                        goto reconnect;
     1392                }
     1393
     1394                DEBUG(1, ("trust_pw_change(%s): %s\n",
     1395                          domain->name, nt_errstr(status)));
     1396
     1397                change_result = ntstatus_to_werror(status);
     1398                goto change_return;
     1399        }
     1400
     1401        change_result = WERR_OK;
     1402
     1403change_return:
     1404        info1->pdc_connection_status = change_result;
     1405
     1406        if (!W_ERROR_IS_OK(info1->pdc_connection_status)) {
     1407                DEBUG(2, ("%s: domain[%s/%s] dcname[%s] "
     1408                          "pdc_connection[%s]\n",
     1409                          __func__, domain->name, domain->alt_name,
     1410                          domain->dcname,
     1411                          win_errstr(info1->pdc_connection_status)));
     1412        }
     1413
     1414        r->out.query->info1 = info1;
     1415
     1416        DEBUG(5, ("%s: succeeded.\n", __func__));
     1417        return WERR_OK;
     1418}
     1419
     1420WERROR _winbind_LogonControl(struct pipes_struct *p,
     1421                             struct winbind_LogonControl *r)
     1422{
     1423        struct winbindd_domain *domain;
     1424
     1425        domain = wb_child_domain();
     1426        if (domain == NULL) {
     1427                return WERR_NO_SUCH_DOMAIN;
     1428        }
     1429
     1430        switch (r->in.function_code) {
     1431        case NETLOGON_CONTROL_REDISCOVER:
     1432                if (r->in.level != 2) {
     1433                        return WERR_INVALID_PARAMETER;
     1434                }
     1435                return _winbind_LogonControl_REDISCOVER(p, domain, r);
     1436        case NETLOGON_CONTROL_TC_QUERY:
     1437                if (r->in.level != 2) {
     1438                        return WERR_INVALID_PARAMETER;
     1439                }
     1440                return _winbind_LogonControl_TC_QUERY(p, domain, r);
     1441        case NETLOGON_CONTROL_TC_VERIFY:
     1442                if (r->in.level != 2) {
     1443                        return WERR_INVALID_PARAMETER;
     1444                }
     1445                return _winbind_LogonControl_TC_VERIFY(p, domain, r);
     1446        case NETLOGON_CONTROL_CHANGE_PASSWORD:
     1447                if (r->in.level != 1) {
     1448                        return WERR_INVALID_PARAMETER;
     1449                }
     1450                return _winbind_LogonControl_CHANGE_PASSWORD(p, domain, r);
     1451        default:
     1452                break;
     1453        }
     1454
     1455        DEBUG(4, ("%s: function_code[0x%x] not supported\n",
     1456                  __func__, r->in.function_code));
     1457        return WERR_NOT_SUPPORTED;
     1458}
     1459
     1460WERROR _winbind_GetForestTrustInformation(struct pipes_struct *p,
     1461                             struct winbind_GetForestTrustInformation *r)
     1462{
     1463        TALLOC_CTX *frame = talloc_stackframe();
     1464        NTSTATUS status, result;
     1465        struct winbindd_domain *domain;
     1466        struct rpc_pipe_client *netlogon_pipe;
     1467        struct dcerpc_binding_handle *b;
     1468        bool retry = false;
     1469        struct lsa_String trusted_domain_name = {};
     1470        struct lsa_StringLarge trusted_domain_name_l = {};
     1471        union lsa_TrustedDomainInfo *tdi = NULL;
     1472        const struct lsa_TrustDomainInfoInfoEx *tdo = NULL;
     1473        struct lsa_ForestTrustInformation _old_fti = {};
     1474        struct lsa_ForestTrustInformation *old_fti = NULL;
     1475        struct lsa_ForestTrustInformation *new_fti = NULL;
     1476        struct lsa_ForestTrustInformation *merged_fti = NULL;
     1477        struct lsa_ForestTrustCollisionInfo *collision_info = NULL;
     1478        bool update_fti = false;
     1479        struct rpc_pipe_client *local_lsa_pipe;
     1480        struct policy_handle local_lsa_policy;
     1481        struct dcerpc_binding_handle *local_lsa = NULL;
     1482
     1483        domain = wb_child_domain();
     1484        if (domain == NULL) {
     1485                TALLOC_FREE(frame);
     1486                return WERR_NO_SUCH_DOMAIN;
     1487        }
     1488
     1489        /*
     1490         * checking for domain->internal and domain->primary
     1491         * makes sure we only do some work when running as DC.
     1492         */
     1493
     1494        if (domain->internal) {
     1495                TALLOC_FREE(frame);
     1496                return WERR_NO_SUCH_DOMAIN;
     1497        }
     1498
     1499        if (domain->primary) {
     1500                TALLOC_FREE(frame);
     1501                return WERR_NO_SUCH_DOMAIN;
     1502        }
     1503
     1504        trusted_domain_name.string = domain->name;
     1505        trusted_domain_name_l.string = domain->name;
     1506
     1507        status = open_internal_lsa_conn(frame, &local_lsa_pipe,
     1508                                        &local_lsa_policy);
     1509        if (!NT_STATUS_IS_OK(status)) {
     1510                DEBUG(0,("%s:%s: open_internal_lsa_conn() failed - %s\n",
     1511                         __location__, __func__, nt_errstr(status)));
     1512                TALLOC_FREE(frame);
     1513                return WERR_INTERNAL_ERROR;
     1514        }
     1515        local_lsa = local_lsa_pipe->binding_handle;
     1516
     1517        status = dcerpc_lsa_QueryTrustedDomainInfoByName(local_lsa, frame,
     1518                                                &local_lsa_policy,
     1519                                                &trusted_domain_name,
     1520                                                LSA_TRUSTED_DOMAIN_INFO_INFO_EX,
     1521                                                &tdi, &result);
     1522        if (!NT_STATUS_IS_OK(status)) {
     1523                DEBUG(0,("%s:%s: local_lsa.QueryTrustedDomainInfoByName(%s) failed - %s\n",
     1524                         __location__, __func__, domain->name, nt_errstr(status)));
     1525                TALLOC_FREE(frame);
     1526                return WERR_INTERNAL_ERROR;
     1527        }
     1528        if (NT_STATUS_EQUAL(result, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
     1529                DEBUG(1,("%s:%s: domain[%s] not found via LSA, might be removed already.\n",
     1530                         __location__, __func__, domain->name));
     1531                TALLOC_FREE(frame);
     1532                return WERR_NO_SUCH_DOMAIN;
     1533        }
     1534        if (!NT_STATUS_IS_OK(result)) {
     1535                DEBUG(0,("%s:%s: local_lsa.QueryTrustedDomainInfoByName(%s) returned %s\n",
     1536                         __location__, __func__, domain->name, nt_errstr(result)));
     1537                TALLOC_FREE(frame);
     1538                return WERR_INTERNAL_ERROR;
     1539        }
     1540        if (tdi == NULL) {
     1541                DEBUG(0,("%s:%s: local_lsa.QueryTrustedDomainInfoByName() "
     1542                         "returned no trusted domain information\n",
     1543                         __location__, __func__));
     1544                TALLOC_FREE(frame);
     1545                return WERR_INTERNAL_ERROR;
     1546        }
     1547
     1548        tdo = &tdi->info_ex;
     1549
     1550        if (!(tdo->trust_attributes & LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)) {
     1551                DEBUG(2,("%s: tdo[%s/%s] is no forest trust attributes[0x%08X]\n",
     1552                         __func__, tdo->netbios_name.string,
     1553                         tdo->domain_name.string,
     1554                         (unsigned)tdo->trust_attributes));
     1555                TALLOC_FREE(frame);
     1556                return WERR_NO_SUCH_DOMAIN;
     1557        }
     1558
     1559        if (r->in.flags & ~DS_GFTI_UPDATE_TDO) {
     1560                TALLOC_FREE(frame);
     1561                return WERR_INVALID_FLAGS;
     1562        }
     1563
     1564reconnect:
     1565        status = cm_connect_netlogon(domain, &netlogon_pipe);
     1566        reset_cm_connection_on_error(domain, status);
     1567        if (NT_STATUS_EQUAL(status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) {
     1568                status = NT_STATUS_NO_LOGON_SERVERS;
     1569        }
     1570        if (!NT_STATUS_IS_OK(status)) {
     1571                DEBUG(3, ("could not open handle to NETLOGON pipe: %s\n",
     1572                          nt_errstr(status)));
     1573                TALLOC_FREE(frame);
     1574                return ntstatus_to_werror(status);
     1575        }
     1576        b = netlogon_pipe->binding_handle;
     1577
     1578        status = netlogon_creds_cli_GetForestTrustInformation(domain->conn.netlogon_creds,
     1579                                                              b, p->mem_ctx,
     1580                                                              &new_fti);
     1581        if (!NT_STATUS_IS_OK(status)) {
     1582                if (!retry && dcerpc_binding_handle_is_connected(b)) {
     1583                        invalidate_cm_connection(domain);
     1584                        retry = true;
     1585                        goto reconnect;
     1586                }
     1587                DEBUG(2, ("netlogon_creds_cli_GetForestTrustInformation(%s) failed: %s\n",
     1588                          domain->name, nt_errstr(status)));
     1589                TALLOC_FREE(frame);
     1590                return ntstatus_to_werror(status);
     1591        }
     1592
     1593        *r->out.forest_trust_info = new_fti;
     1594
     1595        if (r->in.flags & DS_GFTI_UPDATE_TDO) {
     1596                update_fti = true;
     1597        }
     1598
     1599        status = dcerpc_lsa_lsaRQueryForestTrustInformation(local_lsa, frame,
     1600                                                &local_lsa_policy,
     1601                                                &trusted_domain_name,
     1602                                                LSA_FOREST_TRUST_DOMAIN_INFO,
     1603                                                &old_fti, &result);
     1604        if (!NT_STATUS_IS_OK(status)) {
     1605                DEBUG(0,("%s:%s: local_lsa.lsaRQueryForestTrustInformation(%s) failed %s\n",
     1606                         __location__, __func__, domain->name, nt_errstr(status)));
     1607                TALLOC_FREE(frame);
     1608                return WERR_INTERNAL_ERROR;
     1609        }
     1610        if (NT_STATUS_EQUAL(result, NT_STATUS_NOT_FOUND)) {
     1611                DEBUG(2,("%s: no forest trust information available for domain[%s] yet.\n",
     1612                          __func__, domain->name));
     1613                update_fti = true;
     1614                old_fti = &_old_fti;
     1615                result = NT_STATUS_OK;
     1616        }
     1617        if (!NT_STATUS_IS_OK(result)) {
     1618                DEBUG(0,("%s:%s: local_lsa.lsaRQueryForestTrustInformation(%s) returned %s\n",
     1619                         __location__, __func__, domain->name, nt_errstr(result)));
     1620                TALLOC_FREE(frame);
     1621                return WERR_INTERNAL_ERROR;
     1622        }
     1623
     1624        if (old_fti == NULL) {
     1625                DEBUG(0,("%s:%s: local_lsa.lsaRQueryForestTrustInformation() "
     1626                         "returned success without returning forest trust information\n",
     1627                         __location__, __func__));
     1628                TALLOC_FREE(frame);
     1629                return WERR_INTERNAL_ERROR;
     1630        }
     1631
     1632        if (!update_fti) {
     1633                goto done;
     1634        }
     1635
     1636        status = dsdb_trust_merge_forest_info(frame, tdo, old_fti, new_fti,
     1637                                              &merged_fti);
     1638        if (!NT_STATUS_IS_OK(status)) {
     1639                DEBUG(0,("%s:%s: dsdb_trust_merge_forest_info(%s) failed %s\n",
     1640                         __location__, __func__, domain->name, nt_errstr(status)));
     1641                TALLOC_FREE(frame);
     1642                return ntstatus_to_werror(status);
     1643        }
     1644
     1645        status = dcerpc_lsa_lsaRSetForestTrustInformation(local_lsa, frame,
     1646                                                &local_lsa_policy,
     1647                                                &trusted_domain_name_l,
     1648                                                LSA_FOREST_TRUST_DOMAIN_INFO,
     1649                                                merged_fti,
     1650                                                0, /* check_only=0 => store it! */
     1651                                                &collision_info,
     1652                                                &result);
     1653        if (!NT_STATUS_IS_OK(status)) {
     1654                DEBUG(0,("%s:%s: local_lsa.lsaRSetForestTrustInformation(%s) failed %s\n",
     1655                         __location__, __func__, domain->name, nt_errstr(status)));
     1656                TALLOC_FREE(frame);
     1657                return WERR_INTERNAL_ERROR;
     1658        }
     1659        if (!NT_STATUS_IS_OK(result)) {
     1660                DEBUG(0,("%s:%s: local_lsa.lsaRSetForestTrustInformation(%s) returned %s\n",
     1661                         __location__, __func__, domain->name, nt_errstr(result)));
     1662                TALLOC_FREE(frame);
     1663                return ntstatus_to_werror(result);
     1664        }
     1665
     1666done:
     1667        DEBUG(5, ("_winbind_GetForestTrustInformation succeeded\n"));
     1668        TALLOC_FREE(frame);
     1669        return WERR_OK;
     1670}
  • vendor/current/source3/winbindd/winbindd_getdcname.c

    r740 r988  
    2020#include "includes.h"
    2121#include "winbindd.h"
    22 #include "librpc/gen_ndr/ndr_wbint_c.h"
     22#include "librpc/gen_ndr/ndr_winbind_c.h"
    2323
    2424struct winbindd_getdcname_state {
  • vendor/current/source3/winbindd/winbindd_getgrgid.c

    r740 r988  
    125125        }
    126126
    127         response->data.gr.num_gr_mem = (uint32)num_members;
     127        response->data.gr.num_gr_mem = (uint32_t)num_members;
    128128
    129129        /* Group membership lives at start of extra data */
  • vendor/current/source3/winbindd/winbindd_getgrnam.c

    r740 r988  
    3131};
    3232
    33 static void winbindd_getgrnam_lookupsid_done(struct tevent_req *subreq);
     33static void winbindd_getgrnam_lookupname_done(struct tevent_req *subreq);
    3434static void winbindd_getgrnam_done(struct tevent_req *subreq);
    3535
     
    8282                return tevent_req_post(req, ev);
    8383        }
    84         tevent_req_set_callback(subreq, winbindd_getgrnam_lookupsid_done,
     84        tevent_req_set_callback(subreq, winbindd_getgrnam_lookupname_done,
    8585                                req);
    8686        return req;
    8787}
    8888
    89 static void winbindd_getgrnam_lookupsid_done(struct tevent_req *subreq)
     89static void winbindd_getgrnam_lookupname_done(struct tevent_req *subreq)
    9090{
    9191        struct tevent_req *req = tevent_req_callback_data(
     
    102102        }
    103103
    104         if ( (type != SID_NAME_DOM_GRP) && (type != SID_NAME_ALIAS) ) {
    105                 DEBUG(5,("getgrnam_recv: not a group!\n"));
     104        switch (type) {
     105        case SID_NAME_DOM_GRP:
     106        case SID_NAME_ALIAS:
     107        case SID_NAME_WKN_GRP:
     108        /*
     109         * Also give user types a chance:
     110         * These might be user sids mapped to the ID_TYPE_BOTH,
     111         * and in that case we should construct a group struct.
     112         */
     113        case SID_NAME_USER:
     114        case SID_NAME_COMPUTER:
     115                break;
     116        default:
    106117                tevent_req_nterror(req, NT_STATUS_NO_SUCH_GROUP);
    107118                return;
     
    160171        }
    161172
    162         response->data.gr.num_gr_mem = (uint32)num_members;
     173        response->data.gr.num_gr_mem = (uint32_t)num_members;
    163174
    164175        /* Group membership lives at start of extra data */
  • vendor/current/source3/winbindd/winbindd_getgroups.c

    r740 r988  
    3030        int num_sids;
    3131        struct dom_sid *sids;
    32         int next_sid;
    3332        int num_gids;
    3433        gid_t *gids;
     
    125124        /*
    126125         * Convert the group SIDs to gids. state->sids[0] contains the user
    127          * sid, so start at index 1.
     126         * sid. If the idmap backend uses ID_TYPE_BOTH, we might need the
     127         * the id of the user sid in the list of group sids, so map the
     128         * complete token.
    128129         */
    129130
    130         state->gids = talloc_array(state, gid_t, state->num_sids-1);
    131         if (tevent_req_nomem(state->gids, req)) {
    132                 return;
    133         }
    134         state->num_gids = 0;
    135         state->next_sid = 1;
    136 
    137         subreq = wb_sid2gid_send(state, state->ev,
    138                                  &state->sids[state->next_sid]);
     131        subreq = wb_sids2xids_send(state, state->ev,
     132                                   state->sids, state->num_sids);
    139133        if (tevent_req_nomem(subreq, req)) {
    140134                return;
     
    150144                req, struct winbindd_getgroups_state);
    151145        NTSTATUS status;
    152 
    153         status = wb_sid2gid_recv(subreq, &state->gids[state->num_gids]);
     146        struct unixid *xids;
     147        int i;
     148
     149        xids = talloc_array(state, struct unixid, state->num_sids);
     150        if (tevent_req_nomem(xids, req)) {
     151                return;
     152        }
     153        for (i=0; i < state->num_sids; i++) {
     154                xids[i].type = ID_TYPE_NOT_SPECIFIED;
     155                xids[i].id = UINT32_MAX;
     156        }
     157
     158        status = wb_sids2xids_recv(subreq, xids, state->num_sids);
    154159        TALLOC_FREE(subreq);
     160        if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED) ||
     161            NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED))
     162        {
     163                status = NT_STATUS_OK;
     164        }
     165        if (tevent_req_nterror(req, status)) {
     166                return;
     167        }
     168
     169        state->gids = talloc_array(state, gid_t, state->num_sids);
     170        if (tevent_req_nomem(state->gids, req)) {
     171                return;
     172        }
     173        state->num_gids = 0;
     174
     175        for (i=0; i < state->num_sids; i++) {
     176                bool include_gid = false;
     177                const char *debug_missing = NULL;
     178
     179                switch (xids[i].type) {
     180                case ID_TYPE_NOT_SPECIFIED:
     181                        debug_missing = "not specified";
     182                        break;
     183                case ID_TYPE_UID:
     184                        if (i != 0) {
     185                                debug_missing = "uid";
     186                        }
     187                        break;
     188                case ID_TYPE_GID:
     189                case ID_TYPE_BOTH:
     190                        include_gid = true;
     191                        break;
     192                }
     193
     194                if (!include_gid) {
     195                        if (debug_missing == NULL) {
     196                                continue;
     197                        }
     198
     199                        DEBUG(10, ("WARNING: skipping unix id (%u) for sid %s "
     200                                   "from group list because the idmap type "
     201                                   "is %s. "
     202                                   "This might be a security problem when ACLs "
     203                                   "contain DENY ACEs!\n",
     204                                   (unsigned)xids[i].id,
     205                                   sid_string_tos(&state->sids[i]),
     206                                   debug_missing));
     207                        continue;
     208                }
     209
     210                state->gids[state->num_gids] = (gid_t)xids[i].id;
     211                state->num_gids += 1;
     212        }
    155213
    156214        /*
    157          * In case of failure, just continue with the next gid
     215         * This should not fail, as it does not do any reallocation,
     216         * just updating the talloc size.
    158217         */
    159         if (NT_STATUS_IS_OK(status)) {
    160                 state->num_gids += 1;
    161         }
    162         state->next_sid += 1;
    163 
    164         if (state->next_sid >= state->num_sids) {
    165                 tevent_req_done(req);
    166                 return;
    167         }
    168 
    169         subreq = wb_sid2gid_send(state, state->ev,
    170                                  &state->sids[state->next_sid]);
    171         if (tevent_req_nomem(subreq, req)) {
    172                 return;
    173         }
    174         tevent_req_set_callback(subreq, winbindd_getgroups_sid2gid_done, req);
     218        state->gids = talloc_realloc(state, state->gids, gid_t, state->num_gids);
     219        if (tevent_req_nomem(state->gids, req)) {
     220                return;
     221        }
     222
     223        tevent_req_done(req);
    175224}
    176225
  • vendor/current/source3/winbindd/winbindd_group.c

    r746 r988  
    6969        /* Group name and password */
    7070
    71         safe_strcpy(gr->gr_name, full_group_name, sizeof(gr->gr_name) - 1);
    72         safe_strcpy(gr->gr_passwd, "x", sizeof(gr->gr_passwd) - 1);
     71        strlcpy(gr->gr_name, full_group_name, sizeof(gr->gr_name));
     72        strlcpy(gr->gr_passwd, "x", sizeof(gr->gr_passwd));
    7373
    7474        return True;
  • vendor/current/source3/winbindd/winbindd_list_groups.c

    r740 r988  
    2020#include "includes.h"
    2121#include "winbindd.h"
    22 #include "librpc/gen_ndr/ndr_wbint_c.h"
     22#include "librpc/gen_ndr/ndr_winbind_c.h"
    2323
    2424struct winbindd_list_groups_domstate {
  • vendor/current/source3/winbindd/winbindd_list_users.c

    r740 r988  
    2020#include "includes.h"
    2121#include "winbindd.h"
    22 #include "librpc/gen_ndr/ndr_wbint_c.h"
     22#include "librpc/gen_ndr/ndr_winbind_c.h"
    2323
    2424struct winbindd_list_users_domstate {
  • vendor/current/source3/winbindd/winbindd_lookuprids.c

    r740 r988  
    2020#include "includes.h"
    2121#include "winbindd.h"
    22 #include "librpc/gen_ndr/ndr_wbint_c.h"
     22#include "librpc/gen_ndr/ndr_winbind_c.h"
    2323#include "../libcli/security/security.h"
    2424
  • vendor/current/source3/winbindd/winbindd_misc.c

    r740 r988  
    2323#include "includes.h"
    2424#include "winbindd.h"
     25#include "libcli/security/dom_sid.h"
    2526
    2627#undef DBGC_CLASS
     
    4344static enum trust_type get_trust_type(struct winbindd_tdc_domain *domain)
    4445{
    45         if (domain->trust_attribs == NETR_TRUST_ATTRIBUTE_QUARANTINED_DOMAIN)   
     46        if (domain->trust_attribs == LSA_TRUST_ATTRIBUTE_QUARANTINED_DOMAIN)
    4647                return EXTERNAL;
    47         else if (domain->trust_attribs == NETR_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)
     48        else if (domain->trust_attribs == LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)
    4849                return FOREST;
    4950        else if (((domain->trust_flags & NETR_TRUST_FLAG_IN_FOREST) == NETR_TRUST_FLAG_IN_FOREST) &&
     
    7879static bool trust_is_transitive(struct winbindd_tdc_domain *domain)
    7980{
    80         if ((domain->trust_attribs == NETR_TRUST_ATTRIBUTE_NON_TRANSITIVE) ||         
    81             (domain->trust_attribs == NETR_TRUST_ATTRIBUTE_QUARANTINED_DOMAIN) ||
    82             (domain->trust_attribs == NETR_TRUST_ATTRIBUTE_TREAT_AS_EXTERNAL))
     81        if ((domain->trust_attribs == LSA_TRUST_ATTRIBUTE_NON_TRANSITIVE) ||
     82            (domain->trust_attribs == LSA_TRUST_ATTRIBUTE_QUARANTINED_DOMAIN) ||
     83            (domain->trust_attribs == LSA_TRUST_ATTRIBUTE_TREAT_AS_EXTERNAL))
    8384                return False;
    8485        return True;
     
    121122                        "%s\\%s\\%s\\%s\\%s\\%s\\%s\\%s\n",
    122123                        d->domain_name,
    123                         d->dns_name ? d->dns_name : d->domain_name,
     124                        d->dns_name ? d->dns_name : "",
    124125                        sid_string_talloc(state->mem_ctx, &d->sid),
    125126                        get_trust_type_string(d),
     
    172173
    173174        for (i=0; i<trusts.count; i++) {
     175
     176                if (trusts.array[i].sid == NULL) {
     177                        continue;
     178                }
     179                if (dom_sid_equal(trusts.array[i].sid, &global_sid_NULL)) {
     180                        continue;
     181                }
     182
    174183                extra_data = talloc_asprintf_append_buffer(
    175                         extra_data, "%s\\%s\\%s\n",
    176                         trusts.array[i].netbios_name,
    177                         trusts.array[i].dns_name,
    178                         sid_string_talloc(state->mem_ctx,
    179                                           trusts.array[i].sid));
     184                    extra_data, "%s\\%s\\%s\\%u\\%u\\%u\n",
     185                    trusts.array[i].netbios_name, trusts.array[i].dns_name,
     186                    sid_string_talloc(state->mem_ctx, trusts.array[i].sid),
     187                    trusts.array[i].trust_flags,
     188                    (uint32_t)trusts.array[i].trust_type,
     189                    trusts.array[i].trust_attributes);
    180190        }
    181191
     
    192202                extra_data = talloc_asprintf_append_buffer(
    193203                        extra_data, "%s\\%s\\%s\n", domain->name,
    194                         domain->alt_name ? domain->alt_name : domain->name,
     204                        domain->alt_name != NULL ?
     205                                domain->alt_name :
     206                                domain->name,
    195207                        sid_string_talloc(state->mem_ctx, &domain->sid));
    196208        }
     
    203215
    204216                state->response->extra_data.data = extra_data;
    205                 state->response->length += extra_data_len+1;
     217                state->response->length += extra_data_len;
    206218        }
    207219
     
    381393void winbindd_interface_version(struct winbindd_cli_state *state)
    382394{
    383         DEBUG(3, ("[%5lu]: request interface version\n",
    384                   (unsigned long)state->pid));
     395        DEBUG(3, ("[%5lu]: request interface version (version = %d)\n",
     396                  (unsigned long)state->pid, WINBIND_INTERFACE_VERSION));
    385397
    386398        state->response->data.interface_version = WINBIND_INTERFACE_VERSION;
     
    405417                  (unsigned long)state->pid));
    406418
    407         fstrcpy(state->response->data.netbios_name, global_myname());
     419        fstrcpy(state->response->data.netbios_name, lp_netbios_name());
    408420        request_ok(state);
    409421}
  • vendor/current/source3/winbindd/winbindd_msrpc.c

    r860 r988  
    7777        }
    7878
    79         status = cm_connect_sam(domain, tmp_ctx, &samr_pipe, &dom_pol);
     79        status = cm_connect_sam(domain, tmp_ctx, false, &samr_pipe, &dom_pol);
    8080        if (!NT_STATUS_IS_OK(status)) {
    8181                goto done;
     
    136136        }
    137137
    138         status = cm_connect_sam(domain, tmp_ctx, &samr_pipe, &dom_pol);
     138        status = cm_connect_sam(domain, tmp_ctx, false, &samr_pipe, &dom_pol);
    139139        if (!NT_STATUS_IS_OK(status)) {
    140140                goto done;
     
    195195        }
    196196
    197         status = cm_connect_sam(domain, tmp_ctx, &samr_pipe, &dom_pol);
     197        status = cm_connect_sam(domain, tmp_ctx, false, &samr_pipe, &dom_pol);
    198198        if (!NT_STATUS_IS_OK(status)) {
    199199                goto done;
     
    235235        enum lsa_SidType *types = NULL;
    236236        char *full_name = NULL;
     237        const char *names[1];
    237238        NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
    238239        char *mapped_name = NULL;
     
    255256                                               &mapped_name);
    256257
    257         /* Reset the full_name pointer if we mapped anytthing */
     258        /* Reset the full_name pointer if we mapped anything */
    258259
    259260        if (NT_STATUS_IS_OK(name_map_status) ||
     
    266267                 full_name?full_name:"", domain_name ));
    267268
     269        names[0] = full_name;
     270
    268271        result = winbindd_lookup_names(mem_ctx, domain, 1,
    269                                        (const char **)&full_name, NULL,
     272                                       names, NULL,
    270273                                       &sids, &types);
    271274        if (!NT_STATUS_IS_OK(result))
     
    335338                                    TALLOC_CTX *mem_ctx,
    336339                                    const struct dom_sid *sid,
    337                                     uint32 *rids,
     340                                    uint32_t *rids,
    338341                                    size_t num_rids,
    339342                                    char **domain_name,
     
    350353
    351354        if (num_rids) {
    352                 sids = TALLOC_ARRAY(mem_ctx, struct dom_sid, num_rids);
     355                sids = talloc_array(mem_ctx, struct dom_sid, num_rids);
    353356                if (sids == NULL) {
    354357                        return NT_STATUS_NO_MEMORY;
     
    440443                                                     user->base.full_name.string);
    441444
     445                if (user_info->full_name == NULL) {
     446                        /* this might fail so we don't check the return code */
     447                        wcache_query_user_fullname(domain,
     448                                                   mem_ctx,
     449                                                   user_sid,
     450                                                   &user_info->full_name);
     451                }
     452
    442453                status = NT_STATUS_OK;
    443454                goto done;
     
    453464
    454465        /* no cache; hit the wire */
    455         status = cm_connect_sam(domain, tmp_ctx, &samr_pipe, &dom_pol);
     466        status = cm_connect_sam(domain, tmp_ctx, false, &samr_pipe, &dom_pol);
    456467        if (!NT_STATUS_IS_OK(status)) {
    457468                goto done;
     
    513524
    514525        /* no cache; hit the wire */
    515         status = cm_connect_sam(domain, tmp_ctx, &samr_pipe, &dom_pol);
     526        status = cm_connect_sam(domain, tmp_ctx, false, &samr_pipe, &dom_pol);
    516527        if (!NT_STATUS_IS_OK(status)) {
    517528                goto done;
     
    546557static NTSTATUS msrpc_lookup_useraliases(struct winbindd_domain *domain,
    547558                                         TALLOC_CTX *mem_ctx,
    548                                          uint32 num_sids, const struct dom_sid *sids,
    549                                          uint32 *pnum_aliases,
    550                                          uint32 **palias_rids)
     559                                         uint32_t num_sids, const struct dom_sid *sids,
     560                                         uint32_t *pnum_aliases,
     561                                         uint32_t **palias_rids)
    551562{
    552563        struct rpc_pipe_client *samr_pipe;
     
    576587        }
    577588
    578         status = cm_connect_sam(domain, tmp_ctx, &samr_pipe, &dom_pol);
     589        status = cm_connect_sam(domain, tmp_ctx, false, &samr_pipe, &dom_pol);
    579590        if (!NT_STATUS_IS_OK(status)) {
    580591                goto done;
     
    617628{
    618629        NTSTATUS status, result;
    619         uint32 i, total_names = 0;
     630        uint32_t i, total_names = 0;
    620631        struct policy_handle dom_pol, group_pol;
    621         uint32 des_access = SEC_FLAG_MAXIMUM_ALLOWED;
    622         uint32 *rid_mem = NULL;
    623         uint32 group_rid;
     632        uint32_t des_access = SEC_FLAG_MAXIMUM_ALLOWED;
     633        uint32_t *rid_mem = NULL;
     634        uint32_t group_rid;
    624635        unsigned int j, r;
    625636        struct rpc_pipe_client *cli;
     
    642653        *num_names = 0;
    643654
    644         result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
     655        result = cm_connect_sam(domain, mem_ctx, false, &cli, &dom_pol);
    645656        if (!NT_STATUS_IS_OK(result))
    646657                return result;
     
    707718#define MAX_LOOKUP_RIDS 900
    708719
    709         *names = TALLOC_ZERO_ARRAY(mem_ctx, char *, *num_names);
    710         *name_types = TALLOC_ZERO_ARRAY(mem_ctx, uint32, *num_names);
    711         *sid_mem = TALLOC_ZERO_ARRAY(mem_ctx, struct dom_sid, *num_names);
     720        *names = talloc_zero_array(mem_ctx, char *, *num_names);
     721        *name_types = talloc_zero_array(mem_ctx, uint32_t, *num_names);
     722        *sid_mem = talloc_zero_array(mem_ctx, struct dom_sid, *num_names);
    712723
    713724        for (j=0;j<(*num_names);j++)
     
    774785#ifdef HAVE_LDAP
    775786
    776 #include <ldap.h>
    777 
    778 static int get_ldap_seq(const char *server, int port, uint32 *seq)
     787#include "ads.h"
     788
     789static int get_ldap_seq(const char *server, struct sockaddr_storage *ss, int port, uint32_t *seq)
    779790{
    780791        int ret = -1;
     
    792803         */
    793804
    794         ldp = ldap_open_with_timeout(server, port, lp_ldap_timeout());
     805        ldp = ldap_open_with_timeout(server, ss, port, lp_ldap_timeout());
    795806        if (ldp == NULL)
    796807                return -1;
     
    801812
    802813        if (ldap_search_st(ldp, "", LDAP_SCOPE_BASE, "(objectclass=*)",
    803                            CONST_DISCARD(char **, attrs), 0, &to, &res))
     814                           discard_const_p(char *, attrs), 0, &to, &res))
    804815                goto done;
    805816
     
    830841**********************************************************************/
    831842
    832 static int get_ldap_sequence_number(struct winbindd_domain *domain, uint32 *seq)
     843static int get_ldap_sequence_number(struct winbindd_domain *domain, uint32_t *seq)
    833844{
    834845        int ret = -1;
     
    836847
    837848        print_sockaddr(addr, sizeof(addr), &domain->dcaddr);
    838         if ((ret = get_ldap_seq(addr, LDAP_PORT, seq)) == 0) {
     849        if ((ret = get_ldap_seq(addr, &domain->dcaddr, LDAP_PORT, seq)) == 0) {
    839850                DEBUG(3, ("get_ldap_sequence_number: Retrieved sequence "
    840851                          "number for Domain (%s) from DC (%s)\n",
     
    852863        struct rpc_pipe_client *samr_pipe;
    853864        struct policy_handle dom_pol;
    854         uint32_t seq;
     865        uint32_t seq = DOM_SEQUENCE_NONE;
    855866        TALLOC_CTX *tmp_ctx;
    856867        NTSTATUS status;
     
    904915#endif /* HAVE_LDAP */
    905916
    906         status = cm_connect_sam(domain, tmp_ctx, &samr_pipe, &dom_pol);
     917        status = cm_connect_sam(domain, tmp_ctx, false, &samr_pipe, &dom_pol);
    907918        if (!NT_STATUS_IS_OK(status)) {
    908919                goto done;
     
    9931004        }
    9941005
    995         status = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
     1006        status = cm_connect_sam(domain, mem_ctx, false, &cli, &dom_pol);
    9961007        if (!NT_STATUS_IS_OK(status)) {
    9971008                goto done;
     
    10431054        }
    10441055
    1045         status = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
     1056        status = cm_connect_sam(domain, mem_ctx, false, &cli, &dom_pol);
    10461057        if (!NT_STATUS_IS_OK(status)) {
    10471058                goto done;
     
    11311142                 * a netlogon connection first.
    11321143                 */
    1133                 invalidate_cm_connection(&domain->conn);
     1144                invalidate_cm_connection(domain);
    11341145                domain->can_do_ncacn_ip_tcp = domain->active_directory;
    11351146                if (!retried) {
     
    12111222                 * a netlogon connection first.
    12121223                 */
    1213                 invalidate_cm_connection(&domain->conn);
     1224                invalidate_cm_connection(domain);
    12141225                if (!retried) {
    12151226                        retried = true;
  • vendor/current/source3/winbindd/winbindd_ndr.c

    r740 r988  
    2222#include "../librpc/gen_ndr/ndr_netlogon.h"
    2323#include "../librpc/gen_ndr/ndr_security.h"
    24 #include "librpc/ndr/util.h"
     24#include "../librpc/gen_ndr/ndr_lsa.h"
     25#include "../librpc/ndr/libndr.h"
    2526
    2627#undef DBGC_CLASS
     
    7576#ifdef HAVE_ADS
    7677extern struct winbindd_methods ads_methods;
     78extern struct winbindd_methods reconnect_ads_methods;
    7779#endif
    7880extern struct winbindd_methods msrpc_methods;
     
    100102        } else if (r == &ads_methods) {
    101103                ndr_print_string(ndr, name, "ads_methods");
     104        } else if (r == &reconnect_ads_methods) {
     105                ndr_print_string(ndr, name, "reconnect_ads_methods");
    102106#endif
    103107        } else if (r == &builtin_passdb_methods) {
     
    134138        ndr_print_dom_sid(ndr, "sid", &r->sid);
    135139        ndr_print_netr_TrustFlags(ndr, "domain_flags", r->domain_flags);
    136         ndr_print_netr_TrustType(ndr, "domain_type", r->domain_type);
    137         ndr_print_netr_TrustAttributes(ndr, "domain_trust_attribs", r->domain_trust_attribs);
     140        ndr_print_lsa_TrustType(ndr, "domain_type", r->domain_type);
     141        ndr_print_lsa_TrustAttributes(ndr, "domain_trust_attribs", r->domain_trust_attribs);
    138142        ndr_print_bool(ndr, "initialized", r->initialized);
    139143        ndr_print_bool(ndr, "native_mode", r->native_mode);
  • vendor/current/source3/winbindd/winbindd_pam.c

    r860 r988  
    3838#include "passdb/machine_sid.h"
    3939#include "auth.h"
     40#include "../lib/tsocket/tsocket.h"
     41#include "auth/kerberos/pac_utils.h"
     42#include "auth/gensec/gensec.h"
     43#include "librpc/crypto/gse_krb5.h"
     44#include "lib/afs/afs_funcs.h"
    4045
    4146#undef DBGC_CLASS
     
    5257
    5358        resp->data.auth.info3.logon_time =
    54                 nt_time_to_unix(info3->base.last_logon);
     59                nt_time_to_unix(info3->base.logon_time);
    5560        resp->data.auth.info3.logoff_time =
    56                 nt_time_to_unix(info3->base.last_logoff);
     61                nt_time_to_unix(info3->base.logoff_time);
    5762        resp->data.auth.info3.kickoff_time =
    58                 nt_time_to_unix(info3->base.acct_expiry);
     63                nt_time_to_unix(info3->base.kickoff_time);
    5964        resp->data.auth.info3.pass_last_set_time =
    6065                nt_time_to_unix(info3->base.last_password_change);
     
    9398                info3->base.logon_server.string);
    9499        fstrcpy(resp->data.auth.info3.logon_dom,
    95                 info3->base.domain.string);
     100                info3->base.logon_domain.string);
    96101
    97102        ex = talloc_strdup(mem_ctx, "");
     
    156161        const char *nt_username, *nt_domain;
    157162
    158         nt_domain = talloc_strdup(mem_ctx, info3->base.domain.string);
     163        nt_domain = talloc_strdup(mem_ctx, info3->base.logon_domain.string);
    159164        if (!nt_domain) {
    160165                /* If the server didn't give us one, just use the one
     
    217222        }
    218223
    219         strlower_m(afsname);
     224        if (!strlower_m(afsname)) {
     225                return NT_STATUS_INVALID_PARAMETER;
     226        }
    220227
    221228        DEBUG(10, ("Generating token for user %s\n", afsname));
     
    271278        if (!group_sid || !group_sid[0]) {
    272279                /* NO sid supplied, all users may access */
     280                TALLOC_FREE(frame);
    273281                return NT_STATUS_OK;
    274282        }
     
    386394                p->password_properties;
    387395        r->data.auth.policy.expire      =
    388                 nt_time_to_unix_abs((NTTIME *)&(p->max_password_age));
     396                nt_time_to_unix_abs((const NTTIME *)&(p->max_password_age));
    389397        r->data.auth.policy.min_passwordage =
    390                 nt_time_to_unix_abs((NTTIME *)&(p->min_password_age));
     398                nt_time_to_unix_abs((const NTTIME *)&(p->min_password_age));
    391399}
    392400
     
    422430static NTSTATUS get_max_bad_attempts_from_lockout_policy(struct winbindd_domain *domain,
    423431                                                         TALLOC_CTX *mem_ctx,
    424                                                          uint16 *lockout_threshold)
     432                                                         uint16_t *lockout_threshold)
    425433{
    426434        struct winbindd_methods *methods;
     
    444452static NTSTATUS get_pwd_properties(struct winbindd_domain *domain,
    445453                                   TALLOC_CTX *mem_ctx,
    446                                    uint32 *password_properties)
     454                                   uint32_t *password_properties)
    447455{
    448456        struct winbindd_methods *methods;
     
    485493                        gen_cc = talloc_asprintf(
    486494                                mem_ctx, "WRFILE:/tmp/krb5cc_%d", uid);
     495                }
     496                if (strequal(type, "KEYRING")) {
     497                        gen_cc = talloc_asprintf(
     498                                mem_ctx, "KEYRING:persistent:%d", uid);
     499                }
     500
     501                if (strnequal(type, "FILE:/", 6) ||
     502                    strnequal(type, "WRFILE:/", 8) ||
     503                    strnequal(type, "DIR:/", 5)) {
     504
     505                        /* we allow only one "%u" substitution */
     506
     507                        char *p;
     508
     509                        p = strchr(type, '%');
     510                        if (p != NULL) {
     511
     512                                p++;
     513
     514                                if (p != NULL && *p == 'u' && strchr(p, '%') == NULL) {
     515                                        char uid_str[sizeof("18446744073709551615")];
     516
     517                                        snprintf(uid_str, sizeof(uid_str), "%u", uid);
     518
     519                                        gen_cc = talloc_string_sub2(mem_ctx,
     520                                                        type,
     521                                                        "%u",
     522                                                        uid_str,
     523                                                        /* remove_unsafe_characters */
     524                                                        false,
     525                                                        /* replace_once */
     526                                                        true,
     527                                                        /* allow_trailing_dollar */
     528                                                        false);
     529                                }
     530                        }
    487531                }
    488532        }
     
    547591        const char *user_ccache_file;
    548592        struct PAC_LOGON_INFO *logon_info = NULL;
     593        struct PAC_DATA *pac_data = NULL;
     594        struct PAC_DATA_CTR *pac_data_ctr = NULL;
     595        const char *local_service;
     596        int i;
     597        struct netr_SamInfo3 *info3_copy = NULL;
    549598
    550599        *info3 = NULL;
     600
     601        if (domain->alt_name == NULL) {
     602                return NT_STATUS_INVALID_PARAMETER;
     603        }
    551604
    552605        /* 1st step:
     
    580633        parse_domain_user(user, name_domain, name_user);
    581634
    582         realm = domain->alt_name;
    583         strupper_m(realm);
     635        realm = talloc_strdup(mem_ctx, domain->alt_name);
     636        if (realm == NULL) {
     637                return NT_STATUS_NO_MEMORY;
     638        }
     639
     640        if (!strupper_m(realm)) {
     641                return NT_STATUS_INVALID_PARAMETER;
     642        }
    584643
    585644        principal_s = talloc_asprintf(mem_ctx, "%s@%s", name_user, realm);
     
    592651                return NT_STATUS_NO_MEMORY;
    593652        }
     653
     654        local_service = talloc_asprintf(mem_ctx, "%s$@%s",
     655                                        lp_netbios_name(), lp_realm());
     656        if (local_service == NULL) {
     657                return NT_STATUS_NO_MEMORY;
     658        }
     659
    594660
    595661        /* if this is a user ccache, we need to act as the user to let the krb5
     
    614680                                     WINBINDD_PAM_AUTH_KRB5_RENEW_TIME,
    615681                                     NULL,
    616                                      &logon_info);
     682                                     local_service,
     683                                     &pac_data_ctr);
    617684        if (user_ccache_file != NULL) {
    618685                gain_root_privilege();
     
    625692        }
    626693
    627         *info3 = &logon_info->info3;
     694        if (pac_data_ctr == NULL) {
     695                goto failed;
     696        }
     697
     698        pac_data = pac_data_ctr->pac_data;
     699        if (pac_data == NULL) {
     700                goto failed;
     701        }
     702
     703        for (i=0; i < pac_data->num_buffers; i++) {
     704
     705                if (pac_data->buffers[i].type != PAC_TYPE_LOGON_INFO) {
     706                        continue;
     707                }
     708
     709                logon_info = pac_data->buffers[i].info->logon_info.info;
     710                if (!logon_info) {
     711                        return NT_STATUS_INVALID_PARAMETER;
     712                }
     713
     714                break;
     715        }
     716
     717        if (logon_info == NULL) {
     718                DEBUG(10,("Missing logon_info in ticket of %s\n",
     719                        principal_s));
     720                return NT_STATUS_INVALID_PARAMETER;
     721        }
    628722
    629723        DEBUG(10,("winbindd_raw_kerberos_login: winbindd validated ticket of %s\n",
    630724                principal_s));
     725
     726        result = create_info3_from_pac_logon_info(mem_ctx, logon_info, &info3_copy);
     727        if (!NT_STATUS_IS_OK(result)) {
     728                goto failed;
     729        }
    631730
    632731        /* if we had a user's ccache then return that string for the pam
     
    665764
    666765        }
    667 
     766        *info3 = info3_copy;
    668767        return NT_STATUS_OK;
    669768
     
    727826****************************************************************/
    728827
    729 static NTSTATUS append_auth_data(TALLOC_CTX *mem_ctx,
    730                                 struct winbindd_response *resp,
    731                                 uint32_t request_flags,
    732                                 struct netr_SamInfo3 *info3,
    733                                 const char *name_domain,
    734                                 const char *name_user)
     828NTSTATUS append_auth_data(TALLOC_CTX *mem_ctx,
     829                          struct winbindd_response *resp,
     830                          uint32_t request_flags,
     831                          struct netr_SamInfo3 *info3,
     832                          const char *name_domain,
     833                          const char *name_user)
    735834{
    736835        NTSTATUS result;
     
    798897{
    799898        NTSTATUS result = NT_STATUS_LOGON_FAILURE;
    800         uint16 max_allowed_bad_attempts;
     899        uint16_t max_allowed_bad_attempts;
    801900        fstring name_domain, name_user;
    802901        struct dom_sid sid;
    803902        enum lsa_SidType type;
    804903        uchar new_nt_pass[NT_HASH_LEN];
    805         const uint8 *cached_nt_pass;
    806         const uint8 *cached_salt;
     904        const uint8_t *cached_nt_pass;
     905        const uint8_t *cached_salt;
    807906        struct netr_SamInfo3 *my_info3;
    808907        time_t kickoff_time, must_change_time;
     
    9041003                }
    9051004
    906                 kickoff_time = nt_time_to_unix(my_info3->base.acct_expiry);
     1005                kickoff_time = nt_time_to_unix(my_info3->base.kickoff_time);
    9071006                if (kickoff_time != 0 && time(NULL) > kickoff_time) {
    9081007                        return NT_STATUS_ACCOUNT_EXPIRED;
     
    9201019                if ((state->request->flags & WBFLAG_PAM_KRB5) &&
    9211020                    ((tdc_domain = wcache_tdc_fetch_domain(state->mem_ctx, name_domain)) != NULL) &&
    922                     ((tdc_domain->trust_type & NETR_TRUST_TYPE_UPLEVEL) ||
     1021                    ((tdc_domain->trust_type & LSA_TRUST_TYPE_UPLEVEL) ||
    9231022                    /* used to cope with the case winbindd starting without network. */
    9241023                    !strequal(tdc_domain->domain_name, tdc_domain->dns_name))) {
     
    9301029                        const char *service = NULL;
    9311030                        const char *user_ccache_file;
     1031
     1032                        if (domain->alt_name == NULL) {
     1033                                return NT_STATUS_INVALID_PARAMETER;
     1034                        }
    9321035
    9331036                        uid = get_uid_from_request(state->request);
     
    9451048                        }
    9461049
    947                         realm = domain->alt_name;
    948                         strupper_m(realm);
     1050                        realm = talloc_strdup(state->mem_ctx, domain->alt_name);
     1051                        if (realm == NULL) {
     1052                                return NT_STATUS_NO_MEMORY;
     1053                        }
     1054
     1055                        if (!strupper_m(realm)) {
     1056                                return NT_STATUS_INVALID_PARAMETER;
     1057                        }
    9491058
    9501059                        principal_s = talloc_asprintf(state->mem_ctx, "%s@%s", name_user, realm);
     
    9681077                                                            state->request->data.auth.user,
    9691078                                                            state->request->data.auth.pass,
    970                                                             domain->alt_name,
     1079                                                            realm,
    9711080                                                            uid,
    9721081                                                            time(NULL),
     
    9871096                 * offline?) see auth/auth_sam.c:sam_account_ok for details */
    9881097
    989                 unix_to_nt_time(&my_info3->base.last_logon, time(NULL));
     1098                unix_to_nt_time(&my_info3->base.logon_time, time(NULL));
    9901099                my_info3->base.bad_password_count = 0;
    9911100
     
    10261135        if (my_info3->base.bad_password_count >= max_allowed_bad_attempts) {
    10271136
    1028                 uint32 password_properties;
     1137                uint32_t password_properties;
    10291138
    10301139                result = get_pwd_properties(domain, state->mem_ctx, &password_properties);
     
    11001209
    11011210        if (!contact_domain->initialized) {
    1102                 init_dc_connection(contact_domain);
     1211                init_dc_connection(contact_domain, false);
    11031212        }
    11041213
     
    11201229
    11211230static NTSTATUS winbindd_dual_auth_passdb(TALLOC_CTX *mem_ctx,
     1231                                          uint32_t logon_parameters,
    11221232                                          const char *domain, const char *user,
    11231233                                          const DATA_BLOB *challenge,
     
    11261236                                          struct netr_SamInfo3 **pinfo3)
    11271237{
     1238        struct auth_context *auth_context;
     1239        struct auth_serversupplied_info *server_info;
    11281240        struct auth_usersupplied_info *user_info = NULL;
     1241        struct tsocket_address *local;
     1242        struct netr_SamInfo3 *info3;
    11291243        NTSTATUS status;
    1130 
    1131         status = make_user_info(&user_info, user, user, domain, domain,
    1132                                 global_myname(), lm_resp, nt_resp, NULL, NULL,
     1244        int rc;
     1245        TALLOC_CTX *frame = talloc_stackframe();
     1246
     1247        rc = tsocket_address_inet_from_strings(frame,
     1248                                               "ip",
     1249                                               "127.0.0.1",
     1250                                               0,
     1251                                               &local);
     1252        if (rc < 0) {
     1253                TALLOC_FREE(frame);
     1254                return NT_STATUS_NO_MEMORY;
     1255        }
     1256        status = make_user_info(frame, &user_info, user, user, domain, domain,
     1257                                lp_netbios_name(), local, lm_resp, nt_resp, NULL, NULL,
    11331258                                NULL, AUTH_PASSWORD_RESPONSE);
    11341259        if (!NT_STATUS_IS_OK(status)) {
    11351260                DEBUG(10, ("make_user_info failed: %s\n", nt_errstr(status)));
     1261                TALLOC_FREE(frame);
    11361262                return status;
    11371263        }
     1264
     1265        user_info->logon_parameters = logon_parameters;
    11381266
    11391267        /* We don't want any more mapping of the username */
    11401268        user_info->mapped_state = True;
    11411269
    1142         status = check_sam_security_info3(challenge, talloc_tos(), user_info,
    1143                                           pinfo3);
    1144         free_user_info(&user_info);
     1270        /* We don't want to come back to winbindd or to do PAM account checks */
     1271        user_info->flags |= USER_INFO_LOCAL_SAM_ONLY | USER_INFO_INFO3_AND_NO_AUTHZ;
     1272
     1273        status = make_auth_context_fixed(frame, &auth_context, challenge->data);
     1274
     1275        if (!NT_STATUS_IS_OK(status)) {
     1276                DEBUG(0, ("Failed to test authentication with check_sam_security_info3: %s\n", nt_errstr(status)));
     1277                TALLOC_FREE(frame);
     1278                return status;
     1279        }
     1280
     1281        status = auth_check_ntlm_password(mem_ctx,
     1282                                          auth_context,
     1283                                          user_info,
     1284                                          &server_info);
     1285
     1286        if (!NT_STATUS_IS_OK(status)) {
     1287                TALLOC_FREE(frame);
     1288                return status;
     1289        }
     1290
     1291        info3 = talloc_zero(mem_ctx, struct netr_SamInfo3);
     1292        if (info3 == NULL) {
     1293                TALLOC_FREE(frame);
     1294                return NT_STATUS_NO_MEMORY;
     1295        }
     1296
     1297        status = serverinfo_to_SamInfo3(server_info, info3);
     1298        if (!NT_STATUS_IS_OK(status)) {
     1299                TALLOC_FREE(frame);
     1300                TALLOC_FREE(info3);
     1301                DEBUG(0, ("serverinfo_to_SamInfo3 failed: %s\n",
     1302                          nt_errstr(status)));
     1303                return status;
     1304        }
     1305
     1306        *pinfo3 = info3;
    11451307        DEBUG(10, ("Authenticaticating user %s\\%s returned %s\n", domain,
    11461308                   user, nt_errstr(status)));
     1309        TALLOC_FREE(frame);
    11471310        return status;
    11481311}
     
    11511314                                            TALLOC_CTX *mem_ctx,
    11521315                                            uint32_t logon_parameters,
    1153                                             const char *server,
    11541316                                            const char *username,
     1317                                            const char *password,
    11551318                                            const char *domainname,
    11561319                                            const char *workstation,
     
    11581321                                            DATA_BLOB lm_response,
    11591322                                            DATA_BLOB nt_response,
     1323                                            bool interactive,
    11601324                                            struct netr_SamInfo3 **info3)
    11611325{
     
    11671331        do {
    11681332                struct rpc_pipe_client *netlogon_pipe;
    1169                 const struct pipe_auth_data *auth;
    1170                 uint32_t neg_flags = 0;
     1333                uint8_t authoritative = 0;
     1334                uint32_t flags = 0;
    11711335
    11721336                ZERO_STRUCTP(info3);
     
    11851349                                          "particular call, forcing the close "
    11861350                                          "of this connection\n"));
    1187                                 invalidate_cm_connection(&domain->conn);
     1351                                invalidate_cm_connection(domain);
    11881352                        }
    11891353
     
    12161380                }
    12171381                netr_attempts = 0;
    1218 
    1219                 auth = netlogon_pipe->auth;
    1220                 if (netlogon_pipe->dc) {
    1221                         neg_flags = netlogon_pipe->dc->negotiate_flags;
    1222                 }
    1223 
    1224                 /* It is really important to try SamLogonEx here,
    1225                  * because in a clustered environment, we want to use
    1226                  * one machine account from multiple physical
    1227                  * computers.
    1228                  *
    1229                  * With a normal SamLogon call, we must keep the
    1230                  * credentials chain updated and intact between all
    1231                  * users of the machine account (which would imply
    1232                  * cross-node communication for every NTLM logon).
    1233                  *
    1234                  * (The credentials chain is not per NETLOGON pipe
    1235                  * connection, but globally on the server/client pair
    1236                  * by machine name).
    1237                  *
    1238                  * When using SamLogonEx, the credentials are not
    1239                  * supplied, but the session key is implied by the
    1240                  * wrapping SamLogon context.
    1241                  *
    1242                  *  -- abartlet 21 April 2008
    1243                  *
    1244                  * It's also important to use NetlogonValidationSamInfo4 (6),
    1245                  * because it relies on the rpc transport encryption
    1246                  * and avoids using the global netlogon schannel
    1247                  * session key to en/decrypt secret information
    1248                  * like the user_session_key for network logons.
    1249                  *
    1250                  * [MS-APDS] 3.1.5.2 NTLM Network Logon
    1251                  * says NETLOGON_NEG_CROSS_FOREST_TRUSTS and
    1252                  * NETLOGON_NEG_AUTHENTICATED_RPC set together
    1253                  * are the indication that the server supports
    1254                  * NetlogonValidationSamInfo4 (6). And it must only
    1255                  * be used if "SealSecureChannel" is used.
    1256                  *
    1257                  * -- metze 4 February 2011
    1258                  */
    1259 
    1260                 if (auth == NULL) {
    1261                         domain->can_do_validation6 = false;
    1262                 } else if (auth->auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
    1263                         domain->can_do_validation6 = false;
    1264                 } else if (auth->auth_level != DCERPC_AUTH_LEVEL_PRIVACY) {
    1265                         domain->can_do_validation6 = false;
    1266                 } else if (!(neg_flags & NETLOGON_NEG_CROSS_FOREST_TRUSTS)) {
    1267                         domain->can_do_validation6 = false;
    1268                 } else if (!(neg_flags & NETLOGON_NEG_AUTHENTICATED_RPC)) {
    1269                         domain->can_do_validation6 = false;
    1270                 }
    1271 
    1272                 if (domain->can_do_samlogon_ex && domain->can_do_validation6) {
    1273                         result = rpccli_netlogon_sam_network_logon_ex(
    1274                                         netlogon_pipe,
    1275                                         mem_ctx,
    1276                                         logon_parameters,
    1277                                         server,         /* server name */
    1278                                         username,       /* user name */
    1279                                         domainname,     /* target domain */
    1280                                         workstation,    /* workstation */
    1281                                         chal,
    1282                                         6,
    1283                                         lm_response,
    1284                                         nt_response,
    1285                                         info3);
     1382                if (domain->conn.netlogon_creds == NULL) {
     1383                        DBG_NOTICE("No security credentials available for "
     1384                                  "domain [%s]\n", domainname);
     1385                        result = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
     1386                } else if (interactive && username != NULL && password != NULL) {
     1387                        result = rpccli_netlogon_password_logon(domain->conn.netlogon_creds,
     1388                                                                netlogon_pipe->binding_handle,
     1389                                                                mem_ctx,
     1390                                                                logon_parameters,
     1391                                                                domainname,
     1392                                                                username,
     1393                                                                password,
     1394                                                                workstation,
     1395                                                                NetlogonInteractiveInformation,
     1396                                                                info3);
    12861397                } else {
    1287                         result = rpccli_netlogon_sam_network_logon(
    1288                                         netlogon_pipe,
    1289                                         mem_ctx,
    1290                                         logon_parameters,
    1291                                         server,         /* server name */
    1292                                         username,       /* user name */
    1293                                         domainname,     /* target domain */
    1294                                         workstation,    /* workstation */
    1295                                         chal,
    1296                                         domain->can_do_validation6 ? 6 : 3,
    1297                                         lm_response,
    1298                                         nt_response,
    1299                                         info3);
    1300                 }
    1301 
    1302                 if (NT_STATUS_EQUAL(result, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) {
    1303 
    1304                         /*
    1305                          * It's likely that the server also does not support
    1306                          * validation level 6
    1307                          */
    1308                         domain->can_do_validation6 = false;
    1309 
    1310                         if (domain->can_do_samlogon_ex) {
    1311                                 DEBUG(3, ("Got a DC that can not do NetSamLogonEx, "
    1312                                           "retrying with NetSamLogon\n"));
    1313                                 domain->can_do_samlogon_ex = false;
    1314                                 retry = true;
    1315                                 continue;
    1316                         }
    1317 
    1318 
    1319                         /* Got DCERPC_FAULT_OP_RNG_ERROR for SamLogon
    1320                          * (no Ex). This happens against old Samba
    1321                          * DCs. Drop the connection.
    1322                          */
    1323                         invalidate_cm_connection(&domain->conn);
    1324                         result = NT_STATUS_LOGON_FAILURE;
    1325                         break;
    1326                 }
    1327 
    1328                 if (domain->can_do_validation6 &&
    1329                     (NT_STATUS_EQUAL(result, NT_STATUS_INVALID_INFO_CLASS) ||
    1330                      NT_STATUS_EQUAL(result, NT_STATUS_INVALID_PARAMETER) ||
    1331                      NT_STATUS_EQUAL(result, NT_STATUS_BUFFER_TOO_SMALL))) {
    1332                         DEBUG(3,("Got a DC that can not do validation level 6, "
    1333                                   "retrying with level 3\n"));
    1334                         domain->can_do_validation6 = false;
    1335                         retry = true;
    1336                         continue;
     1398                        result = rpccli_netlogon_network_logon(domain->conn.netlogon_creds,
     1399                                                        netlogon_pipe->binding_handle,
     1400                                                        mem_ctx,
     1401                                                        logon_parameters,
     1402                                                        username,
     1403                                                        domainname,
     1404                                                        workstation,
     1405                                                        chal,
     1406                                                        lm_response,
     1407                                                        nt_response,
     1408                                                        &authoritative,
     1409                                                        &flags,
     1410                                                        info3);
    13371411                }
    13381412
     
    13581432
    13591433                if ( NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED) ) {
    1360                         DEBUG(3,("winbind_samlogon_retry_loop: sam_logon returned "
    1361                                  "ACCESS_DENIED.  Maybe the trust account "
     1434                        DEBUG(1,("winbind_samlogon_retry_loop: sam_logon returned "
     1435                                 "ACCESS_DENIED.  Maybe the DC has Restrict "
     1436                                 "NTLM set or the trust account "
    13621437                                "password was changed and we didn't know it. "
    13631438                                 "Killing connections to domain %s\n",
    13641439                                domainname));
    1365                         invalidate_cm_connection(&domain->conn);
     1440                        invalidate_cm_connection(domain);
    13661441                        retry = true;
     1442                }
     1443
     1444                if (NT_STATUS_EQUAL(result, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) {
     1445                        /*
     1446                         * Got DCERPC_FAULT_OP_RNG_ERROR for SamLogon
     1447                         * (no Ex). This happens against old Samba
     1448                         * DCs, if LogonSamLogonEx() fails with an error
     1449                         * e.g. NT_STATUS_NO_SUCH_USER or NT_STATUS_WRONG_PASSWORD.
     1450                         *
     1451                         * The server will log something like this:
     1452                         * api_net_sam_logon_ex: Failed to marshall NET_R_SAM_LOGON_EX.
     1453                         *
     1454                         * This sets the whole connection into a fault_state mode
     1455                         * and all following request get NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE.
     1456                         *
     1457                         * This also happens to our retry with LogonSamLogonWithFlags()
     1458                         * and LogonSamLogon().
     1459                         *
     1460                         * In order to recover from this situation, we need to
     1461                         * drop the connection.
     1462                         */
     1463                        invalidate_cm_connection(domain);
     1464                        result = NT_STATUS_LOGON_FAILURE;
     1465                        break;
    13671466                }
    13681467
     
    13741473                                "Killing connections to domain %s\n",
    13751474                        domainname));
    1376                 invalidate_cm_connection(&domain->conn);
     1475                invalidate_cm_connection(domain);
    13771476        }
    13781477        return result;
     
    14171516                */
    14181517                names_blob = NTLMv2_generate_names_blob(
    1419                         mem_ctx, global_myname(), lp_workgroup());
     1518                        mem_ctx, lp_netbios_name(), lp_workgroup());
    14201519
    14211520                if (!SMBNTLMv2encrypt(mem_ctx, name_user, name_domain,
     
    14421541
    14431542                result = winbindd_dual_auth_passdb(
    1444                         mem_ctx, name_domain, name_user,
     1543                        mem_ctx, 0, name_domain, name_user,
    14451544                        &chal_blob, &lm_resp, &nt_resp, info3);
    1446                 goto done;
     1545
     1546                /*
     1547                 * We need to try the remote NETLOGON server if this is NOT_IMPLEMENTED
     1548                 */
     1549                if (!NT_STATUS_EQUAL(result, NT_STATUS_NOT_IMPLEMENTED)) {
     1550                        goto done;
     1551                }
    14471552        }
    14481553
     
    14521557                                             mem_ctx,
    14531558                                             0,
    1454                                              domain->dcname,
    14551559                                             name_user,
     1560                                             pass,
    14561561                                             name_domain,
    1457                                              global_myname(),
     1562                                             lp_netbios_name(),
    14581563                                             chal,
    14591564                                             lm_resp,
    14601565                                             nt_resp,
     1566                                             true, /* interactive */
    14611567                                             &my_info3);
    14621568        if (!NT_STATUS_IS_OK(result)) {
     
    14751581                union samr_UserInfo *info = NULL;
    14761582                NTSTATUS status_tmp, result_tmp;
    1477                 uint32 acct_flags;
     1583                uint32_t acct_flags;
    14781584                struct dcerpc_binding_handle *b;
    14791585
    1480                 status_tmp = cm_connect_sam(domain, mem_ctx,
     1586                status_tmp = cm_connect_sam(domain, mem_ctx, false,
    14811587                                            &samr_pipe, &samr_domain_handle);
    14821588
     
    15861692                        *lp_winbind_separator(),
    15871693                        name_user );
    1588                 safe_strcpy( state->request->data.auth.user, domain_user,
    1589                              sizeof(state->request->data.auth.user)-1 );
     1694                strlcpy( state->request->data.auth.user, domain_user,
     1695                             sizeof(state->request->data.auth.user));
    15901696        }
    15911697
     
    16011707
    16021708                        winbindd_flush_negative_conn_cache(domain);
    1603                         result = init_dc_connection(domain);
     1709                        result = init_dc_connection(domain, false);
    16041710                }
    16051711        }
     
    17241830                            info3->base.rid);
    17251831
     1832                if (info3->base.full_name.string == NULL) {
     1833                        struct netr_SamInfo3 *cached_info3;
     1834
     1835                        cached_info3 = netsamlogon_cache_get(state->mem_ctx,
     1836                                                             &user_sid);
     1837                        if (cached_info3 != NULL &&
     1838                            cached_info3->base.full_name.string != NULL) {
     1839                                info3->base.full_name.string =
     1840                                        talloc_strdup(info3,
     1841                                                      cached_info3->base.full_name.string);
     1842                        } else {
     1843
     1844                                /* this might fail so we don't check the return code */
     1845                                wcache_query_user_fullname(domain,
     1846                                                info3,
     1847                                                &user_sid,
     1848                                                &info3->base.full_name.string);
     1849                        }
     1850                }
     1851
    17261852                wcache_invalidate_samlogon(find_domain_from_name(name_domain),
    17271853                                           &user_sid);
     
    18071933
    18081934        return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
     1935}
     1936
     1937NTSTATUS winbind_dual_SamLogon(struct winbindd_domain *domain,
     1938                               TALLOC_CTX *mem_ctx,
     1939                               uint32_t logon_parameters,
     1940                               const char *name_user,
     1941                               const char *name_domain,
     1942                               const char *workstation,
     1943                               const uint8_t chal[8],
     1944                               DATA_BLOB lm_response,
     1945                               DATA_BLOB nt_response,
     1946                               struct netr_SamInfo3 **info3)
     1947{
     1948        NTSTATUS result;
     1949
     1950        if (strequal(name_domain, get_global_sam_name())) {
     1951                DATA_BLOB chal_blob = data_blob_const(
     1952                        chal, 8);
     1953
     1954                result = winbindd_dual_auth_passdb(
     1955                        mem_ctx,
     1956                        logon_parameters,
     1957                        name_domain, name_user,
     1958                        &chal_blob, &lm_response, &nt_response, info3);
     1959
     1960                /*
     1961                 * We need to try the remote NETLOGON server if this is NOT_IMPLEMENTED
     1962                 */
     1963                if (!NT_STATUS_EQUAL(result, NT_STATUS_NOT_IMPLEMENTED)) {
     1964                        goto process_result;
     1965                }
     1966        }
     1967
     1968        result = winbind_samlogon_retry_loop(domain,
     1969                                             mem_ctx,
     1970                                             logon_parameters,
     1971                                             name_user,
     1972                                             NULL, /* password */
     1973                                             name_domain,
     1974                                             /* Bug #3248 - found by Stefan Burkei. */
     1975                                             workstation, /* We carefully set this above so use it... */
     1976                                             chal,
     1977                                             lm_response,
     1978                                             nt_response,
     1979                                             false, /* interactive */
     1980                                             info3);
     1981        if (!NT_STATUS_IS_OK(result)) {
     1982                goto done;
     1983        }
     1984
     1985process_result:
     1986
     1987        if (NT_STATUS_IS_OK(result)) {
     1988                struct dom_sid user_sid;
     1989
     1990                sid_compose(&user_sid, (*info3)->base.domain_sid,
     1991                            (*info3)->base.rid);
     1992
     1993                if ((*info3)->base.full_name.string == NULL) {
     1994                        struct netr_SamInfo3 *cached_info3;
     1995
     1996                        cached_info3 = netsamlogon_cache_get(mem_ctx,
     1997                                                             &user_sid);
     1998                        if (cached_info3 != NULL &&
     1999                            cached_info3->base.full_name.string != NULL) {
     2000                                (*info3)->base.full_name.string =
     2001                                        talloc_strdup(*info3,
     2002                                                      cached_info3->base.full_name.string);
     2003                        } else {
     2004
     2005                                /* this might fail so we don't check the return code */
     2006                                wcache_query_user_fullname(domain,
     2007                                                *info3,
     2008                                                &user_sid,
     2009                                                &(*info3)->base.full_name.string);
     2010                        }
     2011                }
     2012
     2013                wcache_invalidate_samlogon(find_domain_from_name(name_domain),
     2014                                           &user_sid);
     2015                netsamlogon_cache_store(name_user, *info3);
     2016        }
     2017
     2018done:
     2019
     2020        /* give us a more useful (more correct?) error code */
     2021        if ((NT_STATUS_EQUAL(result, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND) ||
     2022            (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)))) {
     2023                result = NT_STATUS_NO_LOGON_SERVERS;
     2024        }
     2025
     2026        DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2,
     2027              ("NTLM CRAP authentication for user [%s]\\[%s] returned %s\n",
     2028               name_domain,
     2029               name_user,
     2030               nt_errstr(result)));
     2031
     2032        return result;
    18092033}
    18102034
     
    18592083        }
    18602084
    1861         if (strequal(name_domain, get_global_sam_name())) {
    1862                 DATA_BLOB chal_blob = data_blob_const(
    1863                         state->request->data.auth_crap.chal,
    1864                         sizeof(state->request->data.auth_crap.chal));
    1865 
    1866                 result = winbindd_dual_auth_passdb(
    1867                         state->mem_ctx, name_domain, name_user,
    1868                         &chal_blob, &lm_resp, &nt_resp, &info3);
    1869                 goto process_result;
    1870         }
    1871 
    1872         result = winbind_samlogon_retry_loop(domain,
    1873                                              state->mem_ctx,
    1874                                              state->request->data.auth_crap.logon_parameters,
    1875                                              domain->dcname,
    1876                                              name_user,
    1877                                              name_domain,
    1878                                              /* Bug #3248 - found by Stefan Burkei. */
    1879                                              workstation, /* We carefully set this above so use it... */
    1880                                              state->request->data.auth_crap.chal,
    1881                                              lm_resp,
    1882                                              nt_resp,
    1883                                              &info3);
     2085        result = winbind_dual_SamLogon(domain,
     2086                                       state->mem_ctx,
     2087                                       state->request->data.auth_crap.logon_parameters,
     2088                                       name_user,
     2089                                       name_domain,
     2090                                       /* Bug #3248 - found by Stefan Burkei. */
     2091                                       workstation, /* We carefully set this above so use it... */
     2092                                       state->request->data.auth_crap.chal,
     2093                                       lm_resp,
     2094                                       nt_resp,
     2095                                       &info3);
    18842096        if (!NT_STATUS_IS_OK(result)) {
    18852097                goto done;
    18862098        }
    18872099
    1888 process_result:
    1889 
    18902100        if (NT_STATUS_IS_OK(result)) {
    1891                 struct dom_sid user_sid;
    1892 
    1893                 sid_compose(&user_sid, info3->base.domain_sid,
    1894                             info3->base.rid);
    1895                 wcache_invalidate_samlogon(find_domain_from_name(name_domain),
    1896                                            &user_sid);
    1897                 netsamlogon_cache_store(name_user, info3);
    1898 
    18992101                /* Check if the user is in the right group */
    19002102
     
    19202122done:
    19212123
    1922         /* give us a more useful (more correct?) error code */
    1923         if ((NT_STATUS_EQUAL(result, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND) ||
    1924             (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)))) {
    1925                 result = NT_STATUS_NO_LOGON_SERVERS;
    1926         }
    1927 
    19282124        if (state->request->flags & WBFLAG_PAM_NT_STATUS_SQUASH) {
    19292125                result = nt_status_squash(result);
     
    19312127
    19322128        set_auth_errors(state->response, result);
    1933 
    1934         DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2,
    1935               ("NTLM CRAP authentication for user [%s]\\[%s] returned %s (PAM: %d)\n",
    1936                name_domain,
    1937                name_user,
    1938                state->response->data.auth.nt_status_string,
    1939                state->response->data.auth.pam_error));
    19402129
    19412130        return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
     
    19752164        /* Get sam handle */
    19762165
    1977         result = cm_connect_sam(contact_domain, state->mem_ctx, &cli,
     2166        result = cm_connect_sam(contact_domain, state->mem_ctx, true, &cli,
    19782167                                &dom_pol);
    19792168        if (!NT_STATUS_IS_OK(result)) {
     
    22142403
    22152404        if (!*domain && lp_winbind_use_default_domain()) {
    2216                 fstrcpy(domain,(char *)lp_workgroup());
     2405                fstrcpy(domain,lp_workgroup());
    22172406        }
    22182407
     
    22422431                        state->request->data.chng_pswd_auth_crap.old_lm_hash_enc_len);
    22432432        } else {
    2244                 new_lm_password.length = 0;
    2245                 old_lm_hash_enc.length = 0;
     2433                new_lm_password = data_blob_null;
     2434                old_lm_hash_enc = data_blob_null;
    22462435        }
    22472436
    22482437        /* Get sam handle */
    22492438
    2250         result = cm_connect_sam(contact_domain, state->mem_ctx, &cli, &dom_pol);
     2439        result = cm_connect_sam(contact_domain, state->mem_ctx, true, &cli, &dom_pol);
    22512440        if (!NT_STATUS_IS_OK(result)) {
    22522441                DEBUG(1, ("could not get SAM handle on DC for %s\n", domain));
     
    22832472        return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
    22842473}
     2474
     2475#ifdef HAVE_KRB5
     2476static NTSTATUS extract_pac_vrfy_sigs(TALLOC_CTX *mem_ctx, DATA_BLOB pac_blob,
     2477                                      struct PAC_LOGON_INFO **logon_info)
     2478{
     2479        krb5_context krbctx = NULL;
     2480        krb5_error_code k5ret;
     2481        krb5_keytab keytab;
     2482        krb5_kt_cursor cursor;
     2483        krb5_keytab_entry entry;
     2484        NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
     2485
     2486        ZERO_STRUCT(entry);
     2487        ZERO_STRUCT(cursor);
     2488
     2489        k5ret = krb5_init_context(&krbctx);
     2490        if (k5ret) {
     2491                DEBUG(1, ("Failed to initialize kerberos context: %s\n",
     2492                          error_message(k5ret)));
     2493                status = krb5_to_nt_status(k5ret);
     2494                goto out;
     2495        }
     2496
     2497        k5ret =  gse_krb5_get_server_keytab(krbctx, &keytab);
     2498        if (k5ret) {
     2499                DEBUG(1, ("Failed to get keytab: %s\n",
     2500                          error_message(k5ret)));
     2501                status = krb5_to_nt_status(k5ret);
     2502                goto out_free;
     2503        }
     2504
     2505        k5ret = krb5_kt_start_seq_get(krbctx, keytab, &cursor);
     2506        if (k5ret) {
     2507                DEBUG(1, ("Failed to start seq: %s\n",
     2508                          error_message(k5ret)));
     2509                status = krb5_to_nt_status(k5ret);
     2510                goto out_keytab;
     2511        }
     2512
     2513        k5ret = krb5_kt_next_entry(krbctx, keytab, &entry, &cursor);
     2514        while (k5ret == 0) {
     2515                status = kerberos_pac_logon_info(mem_ctx, pac_blob,
     2516                                                 krbctx, NULL,
     2517                                                 KRB5_KT_KEY(&entry), NULL, 0,
     2518                                                 logon_info);
     2519                if (NT_STATUS_IS_OK(status)) {
     2520                        break;
     2521                }
     2522                k5ret = smb_krb5_kt_free_entry(krbctx, &entry);
     2523                k5ret = krb5_kt_next_entry(krbctx, keytab, &entry, &cursor);
     2524        }
     2525
     2526        k5ret = krb5_kt_end_seq_get(krbctx, keytab, &cursor);
     2527        if (k5ret) {
     2528                DEBUG(1, ("Failed to end seq: %s\n",
     2529                          error_message(k5ret)));
     2530        }
     2531out_keytab:
     2532        k5ret = krb5_kt_close(krbctx, keytab);
     2533        if (k5ret) {
     2534                DEBUG(1, ("Failed to close keytab: %s\n",
     2535                          error_message(k5ret)));
     2536        }
     2537out_free:
     2538        krb5_free_context(krbctx);
     2539out:
     2540        return status;
     2541}
     2542
     2543NTSTATUS winbindd_pam_auth_pac_send(struct winbindd_cli_state *state,
     2544                                    struct netr_SamInfo3 **info3)
     2545{
     2546        struct winbindd_request *req = state->request;
     2547        DATA_BLOB pac_blob;
     2548        struct PAC_LOGON_INFO *logon_info = NULL;
     2549        struct netr_SamInfo3 *info3_copy = NULL;
     2550        NTSTATUS result;
     2551
     2552        pac_blob = data_blob_const(req->extra_data.data, req->extra_len);
     2553        result = extract_pac_vrfy_sigs(state->mem_ctx, pac_blob, &logon_info);
     2554        if (!NT_STATUS_IS_OK(result) &&
     2555            !NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED)) {
     2556                DEBUG(1, ("Error during PAC signature verification: %s\n",
     2557                          nt_errstr(result)));
     2558                return result;
     2559        }
     2560
     2561        if (logon_info) {
     2562                /* Signature verification succeeded, trust the PAC */
     2563                result = create_info3_from_pac_logon_info(state->mem_ctx,
     2564                                                        logon_info,
     2565                                                        &info3_copy);
     2566                if (!NT_STATUS_IS_OK(result)) {
     2567                        return result;
     2568                }
     2569                netsamlogon_cache_store(NULL, info3_copy);
     2570
     2571        } else {
     2572                /* Try without signature verification */
     2573                result = kerberos_pac_logon_info(state->mem_ctx, pac_blob, NULL,
     2574                                                 NULL, NULL, NULL, 0,
     2575                                                 &logon_info);
     2576                if (!NT_STATUS_IS_OK(result)) {
     2577                        DEBUG(10, ("Could not extract PAC: %s\n",
     2578                                   nt_errstr(result)));
     2579                        return result;
     2580                }
     2581                if (logon_info) {
     2582                        /*
     2583                         * Don't strictly need to copy here,
     2584                         * but it makes it explicit we're
     2585                         * returning a copy talloc'ed off
     2586                         * the state->mem_ctx.
     2587                         */
     2588                        info3_copy = copy_netr_SamInfo3(state->mem_ctx,
     2589                                        &logon_info->info3);
     2590                        if (info3_copy == NULL) {
     2591                                return NT_STATUS_NO_MEMORY;
     2592                        }
     2593                }
     2594        }
     2595
     2596        *info3 = info3_copy;
     2597
     2598        return NT_STATUS_OK;
     2599}
     2600#else /* HAVE_KRB5 */
     2601NTSTATUS winbindd_pam_auth_pac_send(struct winbindd_cli_state *state,
     2602                                    struct netr_SamInfo3 **info3)
     2603{
     2604        return NT_STATUS_NO_SUCH_USER;
     2605}
     2606#endif /* HAVE_KRB5 */
  • vendor/current/source3/winbindd/winbindd_pam_auth_crap.c

    r740 r988  
    2323struct winbindd_pam_auth_crap_state {
    2424        struct winbindd_response *response;
     25        struct netr_SamInfo3 *info3;
     26        uint32_t flags;
    2527};
    2628
     
    4143        if (req == NULL) {
    4244                return NULL;
     45        }
     46
     47        if (request->flags & WBFLAG_PAM_AUTH_PAC) {
     48                NTSTATUS status;
     49
     50                state->flags = request->flags;
     51                status = winbindd_pam_auth_pac_send(cli, &state->info3);
     52                if (NT_STATUS_IS_OK(status)) {
     53                        /* Defer filling out response to recv */
     54                        tevent_req_done(req);
     55                } else {
     56                        tevent_req_nterror(req, status);
     57                }
     58
     59                return tevent_req_post(req, ev);
    4360        }
    4461
     
    7592
    7693        if (request->data.auth_crap.workstation[0] == '\0') {
    77                 fstrcpy(request->data.auth_crap.workstation, global_myname());
     94                fstrcpy(request->data.auth_crap.workstation, lp_netbios_name());
    7895        }
    7996
     
    115132                return status;
    116133        }
     134
     135        if (state->flags & WBFLAG_PAM_AUTH_PAC) {
     136                return append_auth_data(response, response, state->flags,
     137                                        state->info3, NULL, NULL);
     138        }
     139
    117140        *response = *state->response;
    118141        response->result = WINBINDD_PENDING;
  • vendor/current/source3/winbindd/winbindd_pam_logoff.c

    r740 r988  
    3838        fstring name_domain, user;
    3939        uid_t caller_uid;
     40        gid_t caller_gid;
    4041        int res;
    4142
     
    7273        caller_uid = (uid_t)-1;
    7374
    74         res = sys_getpeereid(cli->sock, &caller_uid);
     75        res = getpeereid(cli->sock, &caller_uid, &caller_gid);
    7576        if (res != 0) {
    7677                DEBUG(1,("winbindd_pam_logoff: failed to check peerid: %s\n",
  • vendor/current/source3/winbindd/winbindd_ping_dc.c

    r740 r988  
    2020#include "includes.h"
    2121#include "winbindd.h"
    22 #include "librpc/gen_ndr/ndr_wbint_c.h"
     22#include "librpc/gen_ndr/ndr_winbind_c.h"
    2323
    2424struct winbindd_ping_dc_state {
    25         uint8_t dummy;
     25        const char *dcname;
     26        NTSTATUS result;
    2627};
    2728
     
    4748                domain = find_our_domain();
    4849        } else {
    49                 domain = find_domain_from_name(request->domain_name);
     50                domain = find_domain_from_name_noinit(request->domain_name);
    5051        }
    5152        if (domain == NULL) {
     
    5455        }
    5556        if (domain->internal) {
     57                const char *d = lp_dnsdomain();
     58                const char *n = lp_netbios_name();
     59
    5660                /*
    5761                 * Internal domains are passdb based, we can always
    5862                 * contact them.
    5963                 */
     64
     65                if (d != NULL) {
     66                        char *h;
     67                        h = strlower_talloc(mem_ctx, n);
     68                        if (tevent_req_nomem(h, req)) {
     69                                return tevent_req_post(req, ev);
     70                        }
     71
     72                        state->dcname = talloc_asprintf(state, "%s.%s", h, d);
     73                        if (tevent_req_nomem(state->dcname, req)) {
     74                                return tevent_req_post(req, ev);
     75                        }
     76                } else {
     77                        state->dcname = talloc_strdup(state, n);
     78                        if (tevent_req_nomem(state->dcname, req)) {
     79                                return tevent_req_post(req, ev);
     80                        }
     81                }
     82
    6083                tevent_req_done(req);
    6184                return tevent_req_post(req, ev);
    6285        }
    6386
    64         subreq = dcerpc_wbint_PingDc_send(state, ev, dom_child_handle(domain));
     87        subreq = dcerpc_wbint_PingDc_send(state, ev, dom_child_handle(domain),
     88                                          &state->dcname);
    6589        if (tevent_req_nomem(subreq, req)) {
    6690                return tevent_req_post(req, ev);
     
    79103
    80104        status = dcerpc_wbint_PingDc_recv(subreq, state, &result);
     105        state->result = result;
    81106        if (any_nt_status_not_ok(status, result, &status)) {
    82107                tevent_req_nterror(req, status);
     
    89114                               struct winbindd_response *presp)
    90115{
     116        struct winbindd_ping_dc_state *state = tevent_req_data(
     117                req, struct winbindd_ping_dc_state);
     118
     119        if (!NT_STATUS_IS_OK(state->result)) {
     120                set_auth_errors(presp, state->result);
     121        }
     122
     123        if (state->dcname) {
     124                presp->extra_data.data = talloc_strdup(presp, state->dcname);
     125                presp->length += strlen((char *)presp->extra_data.data) + 1;
     126        }
     127
    91128        return tevent_req_simple_recv_ntstatus(req);
    92129}
  • vendor/current/source3/winbindd/winbindd_proto.h

    r860 r988  
    2424#define _WINBINDD_PROTO_H_
    2525
     26#include "ads.h"
     27
    2628/* The following definitions come from winbindd/winbindd.c  */
    2729struct messaging_context *winbind_messaging_context(void);
     30struct imessaging_context *winbind_imessaging_context(void);
    2831void request_error(struct winbindd_cli_state *state);
    2932void request_ok(struct winbindd_cli_state *state);
    3033bool winbindd_setup_sig_term_handler(bool parent);
     34bool winbindd_setup_stdin_handler(bool parent, bool foreground);
    3135bool winbindd_setup_sig_hup_handler(const char *lfile);
    3236bool winbindd_use_idmap_cache(void);
    3337bool winbindd_use_cache(void);
    34 void winbindd_register_handlers(void);
    35 const char *get_winbind_pipe_dir(void);
    3638char *get_winbind_priv_pipe_dir(void);
    37 int main(int argc, char **argv, char **envp);
     39struct tevent_context *winbind_event_context(void);
    3840
    3941/* The following definitions come from winbindd/winbindd_ads.c  */
     
    5658/* The following definitions come from winbindd/winbindd_cache.c  */
    5759
    58 struct cache_entry *centry_start(struct winbindd_domain *domain, NTSTATUS status);
    5960NTSTATUS wcache_cached_creds_exist(struct winbindd_domain *domain, const struct dom_sid *sid);
    6061NTSTATUS wcache_get_creds(struct winbindd_domain *domain,
    6162                          TALLOC_CTX *mem_ctx,
    6263                          const struct dom_sid *sid,
    63                           const uint8 **cached_nt_pass,
    64                           const uint8 **cached_salt);
     64                          const uint8_t **cached_nt_pass,
     65                          const uint8_t **cached_salt);
    6566NTSTATUS wcache_save_creds(struct winbindd_domain *domain,
    6667                           const struct dom_sid *sid,
    67                            const uint8 nt_pass[NT_HASH_LEN]);
     68                           const uint8_t nt_pass[NT_HASH_LEN]);
    6869void wcache_invalidate_samlogon(struct winbindd_domain *domain,
    6970                                const struct dom_sid *user_sid);
     
    7374bool initialize_winbindd_cache(void);
    7475void close_winbindd_cache(void);
    75 NTSTATUS wcache_sid_to_name(struct winbindd_domain *domain,
    76                             const struct dom_sid *sid,
    77                             TALLOC_CTX *mem_ctx,
    78                             char **domain_name,
    79                             char **name,
    80                             enum lsa_SidType *type);
    8176NTSTATUS wcache_lookup_groupmem(struct winbindd_domain *domain,
    8277                                TALLOC_CTX *mem_ctx,
     
    10499                           const struct dom_sid *user_sid,
    105100                           struct wbint_userinfo *info);
     101NTSTATUS wcache_query_user_fullname(struct winbindd_domain *domain,
     102                                    TALLOC_CTX *mem_ctx,
     103                                    const struct dom_sid *user_sid,
     104                                    const char **full_name);
    106105NTSTATUS wcache_lookup_useraliases(struct winbindd_domain *domain,
    107106                                   TALLOC_CTX *mem_ctx,
    108                                    uint32 num_sids, const struct dom_sid *sids,
    109                                    uint32 *pnum_aliases, uint32 **paliases);
     107                                   uint32_t num_sids, const struct dom_sid *sids,
     108                                   uint32_t *pnum_aliases, uint32_t **paliases);
    110109NTSTATUS wcache_lookup_usergroups(struct winbindd_domain *domain,
    111110                                  TALLOC_CTX *mem_ctx,
     
    164163void set_domain_offline(struct winbindd_domain *domain);
    165164void set_domain_online_request(struct winbindd_domain *domain);
    166 void invalidate_cm_connection(struct winbindd_cm_conn *conn);
     165
     166struct ndr_interface_table;
     167NTSTATUS wb_open_internal_pipe(TALLOC_CTX *mem_ctx,
     168                               const struct ndr_interface_table *table,
     169                               struct rpc_pipe_client **ret_pipe);
     170void invalidate_cm_connection(struct winbindd_domain *domain);
    167171void close_conns_after_fork(void);
    168 NTSTATUS init_dc_connection(struct winbindd_domain *domain);
     172NTSTATUS init_dc_connection(struct winbindd_domain *domain, bool need_rw_dc);
    169173NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
     174                        bool need_rw_dc,
    170175                        struct rpc_pipe_client **cli, struct policy_handle *sam_handle);
    171176NTSTATUS cm_connect_lsa(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
    172177                        struct rpc_pipe_client **cli, struct policy_handle *lsa_policy);
    173 NTSTATUS cm_connect_lsa_tcp(struct winbindd_domain *domain,
    174                             TALLOC_CTX *mem_ctx,
    175                             struct rpc_pipe_client **cli);
    176178NTSTATUS cm_connect_lsat(struct winbindd_domain *domain,
    177179                         TALLOC_CTX *mem_ctx,
     
    218220                            const struct dom_sid *sid,
    219221                            struct netr_SamInfo3 **info3,
    220                             const uint8 *cached_nt_pass[NT_HASH_LEN],
    221                             const uint8 *cred_salt[NT_HASH_LEN]);
     222                            const uint8_t *cached_nt_pass[NT_HASH_LEN],
     223                            const uint8_t *cred_salt[NT_HASH_LEN]);
    222224NTSTATUS winbindd_store_creds(struct winbindd_domain *domain,
    223225                              const char *user,
     
    327329void init_idmap_child(void);
    328330struct winbindd_child *idmap_child(void);
    329 struct idmap_domain *idmap_find_domain(const char *domname);
     331struct idmap_domain *idmap_find_domain_with_sid(const char *domname,
     332                                                const struct dom_sid *sid);
     333bool domain_has_idmap_config(const char *domname);
    330334
    331335/* The following definitions come from winbindd/winbindd_locator.c  */
     
    367371
    368372bool check_request_flags(uint32_t flags);
     373NTSTATUS append_auth_data(TALLOC_CTX *mem_ctx,
     374                          struct winbindd_response *resp,
     375                          uint32_t request_flags,
     376                          struct netr_SamInfo3 *info3,
     377                          const char *name_domain,
     378                          const char *name_user);
    369379uid_t get_uid_from_request(struct winbindd_request *request);
    370380struct winbindd_domain *find_auth_domain(uint8_t flags,
     
    379389                                              struct winbindd_cli_state *state) ;
    380390enum winbindd_result winbindd_dual_pam_chng_pswd_auth_crap(struct winbindd_domain *domainSt, struct winbindd_cli_state *state);
     391NTSTATUS winbindd_pam_auth_pac_send(struct winbindd_cli_state *state,
     392                                    struct netr_SamInfo3 **info3);
     393
     394NTSTATUS winbind_dual_SamLogon(struct winbindd_domain *domain,
     395                               TALLOC_CTX *mem_ctx,
     396                               uint32_t logon_parameters,
     397                               const char *name_user,
     398                               const char *name_domain,
     399                               const char *workstation,
     400                               const uint8_t chal[8],
     401                               DATA_BLOB lm_response,
     402                               DATA_BLOB nt_response,
     403                               struct netr_SamInfo3 **info3);
    381404
    382405/* The following definitions come from winbindd/winbindd_util.c  */
    383406
    384407struct winbindd_domain *domain_list(void);
     408struct winbindd_domain *wb_next_domain(struct winbindd_domain *domain);
    385409bool domain_is_forest_root(const struct winbindd_domain *domain);
    386410void rescan_trusted_domains(struct tevent_context *ev, struct tevent_timer *te,
     
    408432                                  bool can_assume);
    409433struct winbindd_cli_state *winbindd_client_list(void);
     434struct winbindd_cli_state *winbindd_client_list_tail(void);
     435struct winbindd_cli_state *
     436winbindd_client_list_prev(struct winbindd_cli_state *cli);
    410437void winbindd_add_client(struct winbindd_cli_state *cli);
    411438void winbindd_remove_client(struct winbindd_cli_state *cli);
     439void winbindd_promote_client(struct winbindd_cli_state *cli);
    412440int winbindd_num_clients(void);
    413441NTSTATUS lookup_usergroups_cached(struct winbindd_domain *domain,
    414442                                  TALLOC_CTX *mem_ctx,
    415443                                  const struct dom_sid *user_sid,
    416                                   uint32 *p_num_groups, struct dom_sid **user_sids);
     444                                  uint32_t *p_num_groups, struct dom_sid **user_sids);
    417445
    418446NTSTATUS normalize_name_map(TALLOC_CTX *mem_ctx,
     
    445473/* The following definitions come from winbindd/winbindd_wins.c  */
    446474
    447 void winbindd_wins_byip(struct winbindd_cli_state *state);
    448475void winbindd_wins_byname(struct winbindd_cli_state *state);
    449476
     
    498525                                  struct winbindd_response *response);
    499526
    500 struct tevent_req *wb_sid2uid_send(TALLOC_CTX *mem_ctx,
    501                                    struct tevent_context *ev,
    502                                    const struct dom_sid *sid);
    503 NTSTATUS wb_sid2uid_recv(struct tevent_req *req, uid_t *uid);
    504 
    505527struct tevent_req *winbindd_sid_to_uid_send(TALLOC_CTX *mem_ctx,
    506528                                            struct tevent_context *ev,
     
    509531NTSTATUS winbindd_sid_to_uid_recv(struct tevent_req *req,
    510532                                  struct winbindd_response *response);
    511 
    512 struct tevent_req *wb_sid2gid_send(TALLOC_CTX *mem_ctx,
    513                                    struct tevent_context *ev,
    514                                    const struct dom_sid *sid);
    515 NTSTATUS wb_sid2gid_recv(struct tevent_req *req, gid_t *gid);
    516533
    517534struct tevent_req *winbindd_sid_to_gid_send(TALLOC_CTX *mem_ctx,
     
    655672NTSTATUS wb_group_members_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
    656673                               struct talloc_dict **members);
     674NTSTATUS add_wbint_Principal_to_dict(TALLOC_CTX *mem_ctx,
     675                                     struct dom_sid *sid,
     676                                     const char **name,
     677                                     enum lsa_SidType type,
     678                                     struct talloc_dict *dict);
    657679
    658680struct tevent_req *wb_getgrsid_send(TALLOC_CTX *mem_ctx,
     
    698720                                 int *num_users,
    699721                                 struct wbint_userinfo **users);
     722
     723struct tevent_req *wb_query_group_list_send(TALLOC_CTX *mem_ctx,
     724                                            struct tevent_context *ev,
     725                                            struct winbindd_domain *domain);
     726NTSTATUS wb_query_group_list_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
     727                                  int *num_users,
     728                                  struct wbint_Principal **groups);
     729
    700730
    701731struct tevent_req *wb_fill_pwent_send(TALLOC_CTX *mem_ctx,
     
    864894                            struct lsa_TransNameArray **names);
    865895
     896struct tevent_req *wb_sids2xids_send(TALLOC_CTX *mem_ctx,
     897                                     struct tevent_context *ev,
     898                                     const struct dom_sid *sids,
     899                                     const uint32_t num_sids);
     900NTSTATUS wb_sids2xids_recv(struct tevent_req *req,
     901                           struct unixid xids[], uint32_t num_xids);
    866902struct tevent_req *winbindd_sids_to_xids_send(TALLOC_CTX *mem_ctx,
    867903                                              struct tevent_context *ev,
     
    870906NTSTATUS winbindd_sids_to_xids_recv(struct tevent_req *req,
    871907                                    struct winbindd_response *response);
     908struct tevent_req *winbindd_wins_byip_send(TALLOC_CTX *mem_ctx,
     909                                           struct tevent_context *ev,
     910                                           struct winbindd_cli_state *cli,
     911                                           struct winbindd_request *request);
     912NTSTATUS winbindd_wins_byip_recv(struct tevent_req *req,
     913                                 struct winbindd_response *presp);
     914struct tevent_req *winbindd_wins_byname_send(TALLOC_CTX *mem_ctx,
     915                                             struct tevent_context *ev,
     916                                             struct winbindd_cli_state *cli,
     917                                             struct winbindd_request *request);
     918NTSTATUS winbindd_wins_byname_recv(struct tevent_req *req,
     919                                   struct winbindd_response *presp);
    872920
    873921
     
    878926                                 struct rpc_pipe_client **samr_pipe,
    879927                                 struct policy_handle *samr_domain_hnd);
     928NTSTATUS open_internal_lsa_conn(TALLOC_CTX *mem_ctx,
     929                                struct rpc_pipe_client **lsa_pipe,
     930                                struct policy_handle *lsa_hnd);
     931
     932/* The following definitions come from winbindd/winbindd_ads.c  */
     933ADS_STATUS ads_idmap_cached_connection(ADS_STRUCT **adsp, const char *dom_name);
     934
     935/* The following definitions come from winbindd/winbindd_irpc.c  */
     936NTSTATUS wb_irpc_register(void);
     937
     938/* The following definitions come from winbindd/winbindd_reconnect.c  */
     939bool reconnect_need_retry(NTSTATUS status, struct winbindd_domain *domain);
    880940
    881941#endif /*  _WINBINDD_PROTO_H_  */
  • vendor/current/source3/winbindd/winbindd_reconnect.c

    r740 r988  
    2828extern struct winbindd_methods msrpc_methods;
    2929
    30 static bool reconnect_need_retry(NTSTATUS status)
     30bool reconnect_need_retry(NTSTATUS status, struct winbindd_domain *domain)
    3131{
    3232        if (NT_STATUS_IS_OK(status)) {
     
    6868        if (NT_STATUS_EQUAL(status, NT_STATUS_NO_MEMORY)) {
    6969                return false;
     70        }
     71
     72        if (NT_STATUS_EQUAL(status, NT_STATUS_IO_DEVICE_ERROR)) {
     73                /*
     74                 * RPC call sent on expired session, needs
     75                 * reauthentication.
     76                 */
     77                invalidate_cm_connection(domain);
    7078        }
    7179
     
    7684static NTSTATUS query_user_list(struct winbindd_domain *domain,
    7785                                TALLOC_CTX *mem_ctx,
    78                                 uint32 *num_entries,
     86                                uint32_t *num_entries,
    7987                                struct wbint_userinfo **info)
    8088{
     
    8492                                               num_entries, info);
    8593
    86         if (reconnect_need_retry(result))
     94        if (reconnect_need_retry(result, domain))
    8795                result = msrpc_methods.query_user_list(domain, mem_ctx,
    8896                                                       num_entries, info);
     
    93101static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
    94102                                TALLOC_CTX *mem_ctx,
    95                                 uint32 *num_entries,
     103                                uint32_t *num_entries,
    96104                                struct wb_acct_info **info)
    97105{
     
    101109                                               num_entries, info);
    102110
    103         if (reconnect_need_retry(result))
     111        if (reconnect_need_retry(result, domain))
    104112                result = msrpc_methods.enum_dom_groups(domain, mem_ctx,
    105113                                                       num_entries, info);
     
    111119static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
    112120                                  TALLOC_CTX *mem_ctx,
    113                                   uint32 *num_entries,
     121                                  uint32_t *num_entries,
    114122                                  struct wb_acct_info **info)
    115123{
     
    119127                                                 num_entries, info);
    120128
    121         if (reconnect_need_retry(result))
     129        if (reconnect_need_retry(result, domain))
    122130                result = msrpc_methods.enum_local_groups(domain, mem_ctx,
    123131                                                         num_entries, info);
     
    140148                                           flags, sid, type);
    141149
    142         if (reconnect_need_retry(result))
     150        if (reconnect_need_retry(result, domain))
    143151                result = msrpc_methods.name_to_sid(domain, mem_ctx,
    144152                                                   domain_name, name, flags,
     
    163171                                           domain_name, name, type);
    164172
    165         if (reconnect_need_retry(result))
     173        if (reconnect_need_retry(result, domain))
    166174                result = msrpc_methods.sid_to_name(domain, mem_ctx, sid,
    167175                                                   domain_name, name, type);
     
    173181                              TALLOC_CTX *mem_ctx,
    174182                              const struct dom_sid *sid,
    175                               uint32 *rids,
     183                              uint32_t *rids,
    176184                              size_t num_rids,
    177185                              char **domain_name,
     
    184192                                             rids, num_rids,
    185193                                             domain_name, names, types);
    186         if (reconnect_need_retry(result)) {
     194        if (reconnect_need_retry(result, domain)) {
    187195                result = msrpc_methods.rids_to_names(domain, mem_ctx, sid,
    188196                                                     rids, num_rids,
     
    205213                                          user_info);
    206214
    207         if (reconnect_need_retry(result))
     215        if (reconnect_need_retry(result, domain))
    208216                result = msrpc_methods.query_user(domain, mem_ctx, user_sid,
    209217                                                  user_info);
     
    216224                                  TALLOC_CTX *mem_ctx,
    217225                                  const struct dom_sid *user_sid,
    218                                   uint32 *num_groups, struct dom_sid **user_gids)
     226                                  uint32_t *num_groups, struct dom_sid **user_gids)
    219227{
    220228        NTSTATUS result;
     
    224232                                                 user_gids);
    225233
    226         if (reconnect_need_retry(result))
     234        if (reconnect_need_retry(result, domain))
    227235                result = msrpc_methods.lookup_usergroups(domain, mem_ctx,
    228236                                                         user_sid, num_groups,
     
    234242static NTSTATUS lookup_useraliases(struct winbindd_domain *domain,
    235243                                   TALLOC_CTX *mem_ctx,
    236                                    uint32 num_sids, const struct dom_sid *sids,
    237                                    uint32 *num_aliases, uint32 **alias_rids)
     244                                   uint32_t num_sids, const struct dom_sid *sids,
     245                                   uint32_t *num_aliases, uint32_t **alias_rids)
    238246{
    239247        NTSTATUS result;
     
    244252                                                  alias_rids);
    245253
    246         if (reconnect_need_retry(result))
     254        if (reconnect_need_retry(result, domain))
    247255                result = msrpc_methods.lookup_useraliases(domain, mem_ctx,
    248256                                                          num_sids, sids,
     
    258266                                const struct dom_sid *group_sid,
    259267                                enum lsa_SidType type,
    260                                 uint32 *num_names,
     268                                uint32_t *num_names,
    261269                                struct dom_sid **sid_mem, char ***names,
    262                                 uint32 **name_types)
     270                                uint32_t **name_types)
    263271{
    264272        NTSTATUS result;
     
    269277                                               name_types);
    270278
    271         if (reconnect_need_retry(result))
     279        if (reconnect_need_retry(result, domain))
    272280                result = msrpc_methods.lookup_groupmem(domain, mem_ctx,
    273281                                                       group_sid, type,
     
    280288
    281289/* find the sequence number for a domain */
    282 static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
     290static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32_t *seq)
    283291{
    284292        NTSTATUS result;
     
    286294        result = msrpc_methods.sequence_number(domain, seq);
    287295
    288         if (reconnect_need_retry(result))
     296        if (reconnect_need_retry(result, domain))
    289297                result = msrpc_methods.sequence_number(domain, seq);
    290298
     
    301309        result = msrpc_methods.lockout_policy(domain, mem_ctx, policy);
    302310
    303         if (reconnect_need_retry(result))
     311        if (reconnect_need_retry(result, domain))
    304312                result = msrpc_methods.lockout_policy(domain, mem_ctx, policy);
    305313
     
    316324        result = msrpc_methods.password_policy(domain, mem_ctx, policy);
    317325
    318         if (reconnect_need_retry(result))
     326        if (reconnect_need_retry(result, domain))
    319327                result = msrpc_methods.password_policy(domain, mem_ctx, policy);
    320328       
     
    331339        result = msrpc_methods.trusted_domains(domain, mem_ctx, trusts);
    332340
    333         if (reconnect_need_retry(result))
     341        if (reconnect_need_retry(result, domain))
    334342                result = msrpc_methods.trusted_domains(domain, mem_ctx,
    335343                                                       trusts);
  • vendor/current/source3/winbindd/winbindd_rpc.c

    r860 r988  
    9090                num_info += num_dom_users;
    9191
    92                 info = TALLOC_REALLOC_ARRAY(mem_ctx,
     92                info = talloc_realloc(mem_ctx,
    9393                                            info,
    9494                                            struct wbint_userinfo,
     
    121121                        dst->homedir = NULL;
    122122                        dst->shell = NULL;
    123 
     123                        dst->primary_gid = (gid_t)-1;
    124124                        sid_compose(&dst->user_sid, domain_sid, rid);
    125125
     
    182182                }
    183183
    184                 info = TALLOC_REALLOC_ARRAY(mem_ctx,
     184                info = talloc_realloc(mem_ctx,
    185185                                            info,
    186186                                            struct wb_acct_info,
     
    191191
    192192                for (g = 0; g < count; g++) {
    193                         fstrcpy(info[num_info + g].acct_name,
     193                        struct wb_acct_info *i = &info[num_info + g];
     194
     195                        fstrcpy(i->acct_name,
    194196                                sam_array->entries[g].name.string);
    195 
    196                         info[num_info + g].rid = sam_array->entries[g].idx;
     197                        fstrcpy(i->acct_desc, "");
     198                        i->rid = sam_array->entries[g].idx;
    197199                }
    198200
     
    242244                }
    243245
    244                 info = TALLOC_REALLOC_ARRAY(mem_ctx,
     246                info = talloc_realloc(mem_ctx,
    245247                                            info,
    246248                                            struct wb_acct_info,
     
    251253
    252254                for (g = 0; g < count; g++) {
    253                         fstrcpy(info[num_info + g].acct_name,
     255                        struct wb_acct_info *i = &info[num_info + g];
     256
     257                        fstrcpy(i->acct_name,
    254258                                sam_array->entries[g].name.string);
    255                         info[num_info + g].rid = sam_array->entries[g].idx;
     259                        fstrcpy(i->acct_desc, "");
     260                        i->rid = sam_array->entries[g].idx;
    256261                }
    257262
     
    278283        struct dom_sid *sids = NULL;
    279284        char *full_name = NULL;
     285        const char *names[1];
    280286        char *mapped_name = NULL;
    281287        NTSTATUS status;
     
    302308        DEBUG(3,("name_to_sid: %s for domain %s\n",
    303309                 full_name ? full_name : "", domain_name ));
     310
     311        names[0] = full_name;
    304312
    305313        /*
     
    311319                                         lsa_policy,
    312320                                         1, /* num_names */
    313                                          (const char **) &full_name,
     321                                         names,
    314322                                         NULL, /* domains */
    315323                                         1, /* level */
     
    363371        map_status = normalize_name_map(mem_ctx,
    364372                                        domain,
    365                                         *pname,
     373                                        names[0],
    366374                                        &mapped_name);
    367375        if (NT_STATUS_IS_OK(map_status) ||
     
    372380                *pname = talloc_strdup(mem_ctx, names[0]);
    373381        }
    374         if (*pname == NULL) {
     382        if ((names[0] != NULL) && (*pname == NULL)) {
    375383                return NT_STATUS_NO_MEMORY;
    376384        }
     
    405413
    406414        if (num_rids > 0) {
    407                 sids = TALLOC_ARRAY(mem_ctx, struct dom_sid, num_rids);
     415                sids = talloc_array(mem_ctx, struct dom_sid, num_rids);
    408416                if (sids == NULL) {
    409417                        return NT_STATUS_NO_MEMORY;
     
    527535                                        info->info21.full_name.string);
    528536        if ((info->info21.full_name.string != NULL) &&
    529             (user_info->acct_name == NULL))
     537            (user_info->full_name == NULL))
    530538        {
    531539                return NT_STATUS_NO_MEMORY;
     
    581589                                              &rid_array,
    582590                                              &result);
    583         num_groups = rid_array->count;
    584 
    585591        {
    586592                NTSTATUS _result;
     
    591597                return status;
    592598        }
    593         if (!NT_STATUS_IS_OK(result) || num_groups == 0) {
     599        if (!NT_STATUS_IS_OK(result)) {
    594600                return result;
    595601        }
    596602
    597         user_grpsids = TALLOC_ARRAY(mem_ctx, struct dom_sid, num_groups);
     603        num_groups = rid_array->count;
     604
     605        user_grpsids = talloc_array(mem_ctx, struct dom_sid, num_groups);
    598606        if (user_grpsids == NULL) {
    599607                status = NT_STATUS_NO_MEMORY;
     
    645653
    646654                if (num_query_sids) {
    647                         sid_array.sids = TALLOC_ZERO_ARRAY(mem_ctx, struct lsa_SidPtr, num_query_sids);
     655                        sid_array.sids = talloc_zero_array(mem_ctx, struct lsa_SidPtr, num_query_sids);
    648656                        if (sid_array.sids == NULL) {
    649657                                return NT_STATUS_NO_MEMORY;
     
    840848         */
    841849        if (num_names > 0) {
    842                 names = TALLOC_ZERO_ARRAY(mem_ctx, char *, num_names);
    843                 name_types = TALLOC_ZERO_ARRAY(mem_ctx, uint32_t, num_names);
    844                 sid_mem = TALLOC_ZERO_ARRAY(mem_ctx, struct dom_sid, num_names);
     850                names = talloc_zero_array(mem_ctx, char *, num_names);
     851                name_types = talloc_zero_array(mem_ctx, uint32_t, num_names);
     852                sid_mem = talloc_zero_array(mem_ctx, struct dom_sid, num_names);
    845853                if (names == NULL || name_types == NULL || sid_mem == NULL) {
    846854                        return NT_STATUS_NO_MEMORY;
     
    979987        do {
    980988                struct lsa_DomainList dom_list;
    981                 uint32_t start_idx;
     989                struct lsa_DomainListEx dom_list_ex;
     990                bool has_ex = false;
    982991                uint32_t i;
    983992
     
    986995                 * called in the main function.
    987996                 */
    988                 status = dcerpc_lsa_EnumTrustDom(b,
    989                                                  mem_ctx,
    990                                                  lsa_policy,
    991                                                  &enum_ctx,
    992                                                  &dom_list,
    993                                                  (uint32_t) -1,
    994                                                  &result);
    995                 if (!NT_STATUS_IS_OK(status)) {
    996                         return status;
    997                 }
    998                 if (!NT_STATUS_IS_OK(result)) {
    999                         if (!NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
    1000                                 return result;
     997                status = dcerpc_lsa_EnumTrustedDomainsEx(b,
     998                                                         mem_ctx,
     999                                                         lsa_policy,
     1000                                                         &enum_ctx,
     1001                                                         &dom_list_ex,
     1002                                                         (uint32_t) -1,
     1003                                                         &result);
     1004                if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_ERR(result) &&
     1005                    dom_list_ex.count > 0) {
     1006                        count += dom_list_ex.count;
     1007                        has_ex = true;
     1008                } else {
     1009                        status = dcerpc_lsa_EnumTrustDom(b,
     1010                                                         mem_ctx,
     1011                                                         lsa_policy,
     1012                                                         &enum_ctx,
     1013                                                         &dom_list,
     1014                                                         (uint32_t) -1,
     1015                                                         &result);
     1016                        if (!NT_STATUS_IS_OK(status)) {
     1017                                return status;
    10011018                        }
    1002                 }
    1003 
    1004                 start_idx = count;
    1005                 count += dom_list.count;
     1019                        if (!NT_STATUS_IS_OK(result)) {
     1020                                if (!NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
     1021                                        return result;
     1022                                }
     1023                        }
     1024
     1025                        count += dom_list.count;
     1026                }
    10061027
    10071028                array = talloc_realloc(mem_ctx,
     
    10131034                }
    10141035
    1015                 for (i = 0; i < dom_list.count; i++) {
     1036                for (i = 0; i < count; i++) {
    10161037                        struct netr_DomainTrust *trust = &array[i];
    10171038                        struct dom_sid *sid;
    10181039
    10191040                        ZERO_STRUCTP(trust);
    1020 
    1021                         trust->netbios_name = talloc_move(array,
    1022                                                           &dom_list.domains[i].name.string);
    1023                         trust->dns_name = NULL;
    10241041
    10251042                        sid = talloc(array, struct dom_sid);
     
    10271044                                return NT_STATUS_NO_MEMORY;
    10281045                        }
    1029                         sid_copy(sid, dom_list.domains[i].sid);
     1046
     1047                        if (has_ex) {
     1048                                trust->netbios_name = talloc_move(array,
     1049                                                                  &dom_list_ex.domains[i].netbios_name.string);
     1050                                trust->dns_name = talloc_move(array,
     1051                                                              &dom_list_ex.domains[i].domain_name.string);
     1052                                if (dom_list_ex.domains[i].sid == NULL) {
     1053                                        DEBUG(0, ("Trusted Domain %s has no SID, aborting!\n", trust->dns_name));
     1054                                        return NT_STATUS_INVALID_NETWORK_RESPONSE;
     1055                                }
     1056                                sid_copy(sid, dom_list_ex.domains[i].sid);
     1057                        } else {
     1058                                trust->netbios_name = talloc_move(array,
     1059                                                                  &dom_list.domains[i].name.string);
     1060                                trust->dns_name = NULL;
     1061
     1062                                if (dom_list.domains[i].sid == NULL) {
     1063                                        DEBUG(0, ("Trusted Domain %s has no SID, aborting!\n", trust->netbios_name));
     1064                                        return NT_STATUS_INVALID_NETWORK_RESPONSE;
     1065                                }
     1066
     1067                                sid_copy(sid, dom_list.domains[i].sid);
     1068                        }
     1069
    10301070                        trust->sid = sid;
    10311071                }
     
    10471087        struct lsa_TransNameArray2 lsa_names2;
    10481088        struct lsa_TransNameArray *names = *pnames;
    1049         uint32_t i, count;
     1089        uint32_t i, count = 0;
    10501090        NTSTATUS status, result;
    10511091
  • vendor/current/source3/winbindd/winbindd_samr.c

    r740 r988  
    4040#define DBGC_CLASS DBGC_WINBIND
    4141
    42 static NTSTATUS open_internal_samr_pipe(TALLOC_CTX *mem_ctx,
    43                                         struct rpc_pipe_client **samr_pipe)
    44 {
    45         struct rpc_pipe_client *cli = NULL;
    46         struct auth_serversupplied_info *session_info = NULL;
    47         NTSTATUS status;
    48 
    49         if (session_info == NULL) {
    50                 status = make_session_info_system(mem_ctx, &session_info);
    51                 if (!NT_STATUS_IS_OK(status)) {
    52                         DEBUG(0, ("open_samr_pipe: Could not create auth_serversupplied_info: %s\n",
    53                                   nt_errstr(status)));
    54                         return status;
    55                 }
    56         }
    57 
    58         /* create a samr connection */
    59         status = rpc_pipe_open_interface(mem_ctx,
    60                                         &ndr_table_samr.syntax_id,
    61                                         session_info,
    62                                         NULL,
    63                                         winbind_messaging_context(),
    64                                         &cli);
    65         if (!NT_STATUS_IS_OK(status)) {
    66                 DEBUG(0, ("open_samr_pipe: Could not connect to samr_pipe: %s\n",
    67                           nt_errstr(status)));
    68                 return status;
    69         }
    70 
    71         if (samr_pipe) {
    72                 *samr_pipe = cli;
    73         }
    74 
    75         return NT_STATUS_OK;
    76 }
    77 
    7842NTSTATUS open_internal_samr_conn(TALLOC_CTX *mem_ctx,
    7943                                 struct winbindd_domain *domain,
     
    8549        struct dcerpc_binding_handle *b;
    8650
    87         status = open_internal_samr_pipe(mem_ctx, samr_pipe);
     51        status = wb_open_internal_pipe(mem_ctx, &ndr_table_samr, samr_pipe);
    8852        if (!NT_STATUS_IS_OK(status)) {
    8953                return status;
     
    11781}
    11882
    119 static NTSTATUS open_internal_lsa_pipe(TALLOC_CTX *mem_ctx,
    120                                        struct rpc_pipe_client **lsa_pipe)
    121 {
    122         struct rpc_pipe_client *cli = NULL;
    123         struct auth_serversupplied_info *session_info = NULL;
     83NTSTATUS open_internal_lsa_conn(TALLOC_CTX *mem_ctx,
     84                                struct rpc_pipe_client **lsa_pipe,
     85                                struct policy_handle *lsa_hnd)
     86{
    12487        NTSTATUS status;
    12588
    126         if (session_info == NULL) {
    127                 status = make_session_info_system(mem_ctx, &session_info);
    128                 if (!NT_STATUS_IS_OK(status)) {
    129                         DEBUG(0, ("open_lsa_pipe: Could not create auth_serversupplied_info: %s\n",
    130                                   nt_errstr(status)));
    131                         return status;
    132                 }
    133         }
    134 
    135         /* create a lsa connection */
    136         status = rpc_pipe_open_interface(mem_ctx,
    137                                         &ndr_table_lsarpc.syntax_id,
    138                                         session_info,
    139                                         NULL,
    140                                         winbind_messaging_context(),
    141                                         &cli);
    142         if (!NT_STATUS_IS_OK(status)) {
    143                 DEBUG(0, ("open_lsa_pipe: Could not connect to lsa_pipe: %s\n",
    144                           nt_errstr(status)));
    145                 return status;
    146         }
    147 
    148         if (lsa_pipe) {
    149                 *lsa_pipe = cli;
    150         }
    151 
    152         return NT_STATUS_OK;
    153 }
    154 
    155 static NTSTATUS open_internal_lsa_conn(TALLOC_CTX *mem_ctx,
    156                                        struct rpc_pipe_client **lsa_pipe,
    157                                        struct policy_handle *lsa_hnd)
    158 {
    159         NTSTATUS status;
    160 
    161         status = open_internal_lsa_pipe(mem_ctx, lsa_pipe);
     89        status = wb_open_internal_pipe(mem_ctx, &ndr_table_lsarpc, lsa_pipe);
    16290        if (!NT_STATUS_IS_OK(status)) {
    16391                return status;
     
    314242
    315243        /* Paranoia check */
    316         if (!sid_check_is_in_our_domain(user_sid)) {
     244        if (!sid_check_is_in_our_sam(user_sid)) {
    317245                return NT_STATUS_NO_SUCH_USER;
    318246        }
    319247
    320         if (user_info) {
    321                 user_info->homedir = NULL;
    322                 user_info->shell = NULL;
    323                 user_info->primary_gid = (gid_t) -1;
    324         }
     248        user_info->homedir = NULL;
     249        user_info->shell = NULL;
     250        user_info->primary_gid = (gid_t) -1;
    325251
    326252        tmp_ctx = talloc_stackframe();
     
    441367
    442368        if (pnum_names) {
    443                 pnum_names = 0;
     369                *pnum_names = 0;
    444370        }
    445371
     
    500426static NTSTATUS builtin_enum_dom_groups(struct winbindd_domain *domain,
    501427                                TALLOC_CTX *mem_ctx,
    502                                 uint32 *num_entries,
     428                                uint32_t *num_entries,
    503429                                struct wb_acct_info **info)
    504430{
     
    512438static NTSTATUS builtin_query_user_list(struct winbindd_domain *domain,
    513439                                TALLOC_CTX *mem_ctx,
    514                                 uint32 *num_entries,
     440                                uint32_t *num_entries,
    515441                                struct wbint_userinfo **info)
    516442{
     
    687613        /* Paranoia check */
    688614        if (!sid_check_is_in_builtin(sid) &&
    689             !sid_check_is_in_our_domain(sid) &&
     615            !sid_check_is_builtin(sid) &&
     616            !sid_check_is_in_our_sam(sid) &&
     617            !sid_check_is_our_sam(sid) &&
    690618            !sid_check_is_in_unix_users(sid) &&
    691619            !sid_check_is_unix_users(sid) &&
     
    743671                                  TALLOC_CTX *mem_ctx,
    744672                                  const struct dom_sid *domain_sid,
    745                                   uint32 *rids,
     673                                  uint32_t *rids,
    746674                                  size_t num_rids,
    747675                                  char **pdomain_name,
     
    764692        /* Paranoia check */
    765693        if (!sid_check_is_builtin(domain_sid) &&
    766             !sid_check_is_domain(domain_sid) &&
     694            !sid_check_is_our_sam(domain_sid) &&
    767695            !sid_check_is_unix_users(domain_sid) &&
    768696            !sid_check_is_unix_groups(domain_sid) &&
     
    850778                                             mem_ctx,
    851779                                             &dom_pol,
    852                                              12,
     780                                             DomainLockoutInformation,
    853781                                             &info,
    854782                                             &result);
     
    902830                                             mem_ctx,
    903831                                             &dom_pol,
    904                                              1,
     832                                             DomainPasswordInformation,
    905833                                             &info,
    906834                                             &result);
     
    1056984        struct rpc_pipe_client *samr_pipe;
    1057985        struct policy_handle dom_pol;
    1058         uint32_t seq;
     986        uint32_t seq = DOM_SEQUENCE_NONE;
    1059987        TALLOC_CTX *tmp_ctx;
    1060988        NTSTATUS status, result;
  • vendor/current/source3/winbindd/winbindd_sid_to_gid.c

    r740 r988  
    5555        }
    5656
    57         subreq = wb_sid2gid_send(state, ev, &state->sid);
     57        subreq = wb_sids2xids_send(state, ev, &state->sid, 1);
    5858        if (tevent_req_nomem(subreq, req)) {
    5959                return tevent_req_post(req, ev);
     
    7070                req, struct winbindd_sid_to_gid_state);
    7171        NTSTATUS status;
     72        struct unixid xids[1];
    7273
    73         status = wb_sid2gid_recv(subreq, &state->gid);
     74        status = wb_sids2xids_recv(subreq, xids, ARRAY_SIZE(xids));
    7475        TALLOC_FREE(subreq);
    7576        if (tevent_req_nterror(req, status)) {
    7677                return;
    7778        }
     79
     80        /*
     81         * We are filtering further down in sids2xids, but that filtering
     82         * depends on the actual type of the sid handed in (as determined
     83         * by lookupsids). Here we need to filter for the type of object
     84         * actually requested, in this case gid.
     85         */
     86        if (!(xids[0].type == ID_TYPE_GID || xids[0].type == ID_TYPE_BOTH)) {
     87                tevent_req_nterror(req, NT_STATUS_NONE_MAPPED);
     88                return;
     89        }
     90
     91        state->gid = (gid_t)xids[0].id;
    7892        tevent_req_done(req);
    7993}
  • vendor/current/source3/winbindd/winbindd_sid_to_uid.c

    r740 r988  
    5555        }
    5656
    57         subreq = wb_sid2uid_send(state, ev, &state->sid);
     57        subreq = wb_sids2xids_send(state, ev, &state->sid, 1);
    5858        if (tevent_req_nomem(subreq, req)) {
    5959                return tevent_req_post(req, ev);
     
    7070                req, struct winbindd_sid_to_uid_state);
    7171        NTSTATUS status;
     72        struct unixid xids[1];
    7273
    73         status = wb_sid2uid_recv(subreq, &state->uid);
     74        status = wb_sids2xids_recv(subreq, xids, ARRAY_SIZE(xids));
    7475        TALLOC_FREE(subreq);
    7576        if (tevent_req_nterror(req, status)) {
    7677                return;
    7778        }
     79
     80        /*
     81         * We are filtering further down in sids2xids, but that filtering
     82         * depends on the actual type of the sid handed in (as determined
     83         * by lookupsids). Here we need to filter for the type of object
     84         * actually requested, in this case uid.
     85         */
     86        if (!(xids[0].type == ID_TYPE_UID || xids[0].type == ID_TYPE_BOTH)) {
     87                tevent_req_nterror(req, NT_STATUS_NONE_MAPPED);
     88                return;
     89        }
     90
     91        state->uid = (uid_t)xids[0].id;
    7892        tevent_req_done(req);
    7993}
  • vendor/current/source3/winbindd/winbindd_sids_to_xids.c

    r746 r988  
    33   async implementation of WINBINDD_SIDS_TO_XIDS
    44   Copyright (C) Volker Lendecke 2011
     5   Copyright (C) Michael Adam 2012
    56
    67   This program is free software; you can redistribute it and/or modify
     
    2122#include "winbindd.h"
    2223#include "../libcli/security/security.h"
    23 #include "librpc/gen_ndr/ndr_wbint_c.h"
    24 #include "idmap_cache.h"
     24
    2525
    2626struct winbindd_sids_to_xids_state {
     
    2828        struct dom_sid *sids;
    2929        uint32_t num_sids;
    30 
    31         struct id_map *cached;
    32 
    33         struct dom_sid *non_cached;
    34         uint32_t num_non_cached;
    35 
    36         struct lsa_RefDomainList *domains;
    37         struct lsa_TransNameArray *names;
    38 
    39         struct wbint_TransIDArray ids;
     30        struct unixid *xids;
    4031};
    4132
    42 static bool winbindd_sids_to_xids_in_cache(struct dom_sid *sid,
    43                                            struct id_map *map);
    44 static void winbindd_sids_to_xids_lookupsids_done(struct tevent_req *subreq);
    4533static void winbindd_sids_to_xids_done(struct tevent_req *subreq);
    4634
     
    5240        struct tevent_req *req, *subreq;
    5341        struct winbindd_sids_to_xids_state *state;
    54         uint32_t i;
    5542
    5643        req = tevent_req_create(mem_ctx, &state,
     
    8168        DEBUG(10, ("num_sids: %d\n", (int)state->num_sids));
    8269
    83         state->cached = TALLOC_ZERO_ARRAY(state, struct id_map,
    84                                           state->num_sids);
    85         if (tevent_req_nomem(state->cached, req)) {
    86                 return tevent_req_post(req, ev);
    87         }
    88         state->non_cached = TALLOC_ARRAY(state, struct dom_sid,
    89                                          state->num_sids);
    90         if (tevent_req_nomem(state->non_cached, req)) {
     70        subreq = wb_sids2xids_send(state, ev, state->sids, state->num_sids);
     71        if (tevent_req_nomem(subreq, req)) {
    9172                return tevent_req_post(req, ev);
    9273        }
    9374
    94         for (i=0; i<state->num_sids; i++) {
    95 
    96                 DEBUG(10, ("SID %d: %s\n", (int)i,
    97                            sid_string_dbg(&state->sids[i])));
    98 
    99                 if (winbindd_sids_to_xids_in_cache(&state->sids[i],
    100                                                    &state->cached[i])) {
    101                         continue;
    102                 }
    103                 sid_copy(&state->non_cached[state->num_non_cached],
    104                          &state->sids[i]);
    105                 state->num_non_cached += 1;
    106         }
    107 
    108         if (state->num_non_cached == 0) {
    109                 tevent_req_done(req);
    110                 return tevent_req_post(req, ev);
    111         }
    112 
    113         subreq = wb_lookupsids_send(state, ev, state->non_cached,
    114                                     state->num_non_cached);
    115         if (tevent_req_nomem(subreq, req)) {
    116                 return tevent_req_post(req, ev);
    117         }
    118         tevent_req_set_callback(subreq, winbindd_sids_to_xids_lookupsids_done,
    119                                 req);
     75        tevent_req_set_callback(subreq, winbindd_sids_to_xids_done, req);
    12076        return req;
    121 }
    122 
    123 static bool winbindd_sids_to_xids_in_cache(struct dom_sid *sid,
    124                                            struct id_map *map)
    125 {
    126         bool is_online = is_domain_online(find_our_domain());
    127         gid_t gid = (gid_t)-1;
    128         bool gid_expired = false;
    129         bool gid_cached = false;
    130         bool gid_negative = false;
    131         uid_t uid = (uid_t)-1;
    132         bool uid_expired = false;
    133         bool uid_cached = false;
    134         bool uid_negative = false;
    135 
    136         if (!winbindd_use_idmap_cache()) {
    137                 return false;
    138         }
    139 
    140         /*
    141          * SIDS_TO_XIDS is primarily used to resolve the user's group
    142          * sids. So we check groups before users.
    143          */
    144         gid_cached = idmap_cache_find_sid2gid(sid, &gid, &gid_expired);
    145         if (!is_online) {
    146                 gid_expired = false;
    147         }
    148         if (gid_cached && !gid_expired) {
    149                 if (gid != (gid_t)-1) {
    150                         map->sid = sid;
    151                         map->xid.id = gid;
    152                         map->xid.type = ID_TYPE_GID;
    153                         map->status = ID_MAPPED;
    154                         return true;
    155                 }
    156                 gid_negative = true;
    157         }
    158         uid_cached = idmap_cache_find_sid2uid(sid, &uid, &uid_expired);
    159         if (!is_online) {
    160                 uid_expired = false;
    161         }
    162         if (uid_cached && !uid_expired) {
    163                 if (uid != (uid_t)-1) {
    164                         map->sid = sid;
    165                         map->xid.id = uid;
    166                         map->xid.type = ID_TYPE_UID;
    167                         map->status = ID_MAPPED;
    168                         return true;
    169                 }
    170                 uid_negative = true;
    171         }
    172 
    173         /*
    174          * Here we know that we only have negative
    175          * or no entries.
    176          *
    177          * All valid cases already returned to the caller.
    178          */
    179 
    180         if (gid_negative && uid_negative) {
    181                 map->sid = sid;
    182                 map->xid.id = UINT32_MAX;
    183                 map->xid.type = ID_TYPE_NOT_SPECIFIED;
    184                 map->status = ID_MAPPED;
    185                 return true;
    186         }
    187 
    188         if (gid_negative) {
    189                 map->sid = sid;
    190                 map->xid.id = gid; /* this is (gid_t)-1 */
    191                 map->xid.type = ID_TYPE_GID;
    192                 map->status = ID_MAPPED;
    193                 return true;
    194         }
    195 
    196         if (uid_negative) {
    197                 map->sid = sid;
    198                 map->xid.id = uid; /* this is (uid_t)-1 */
    199                 map->xid.type = ID_TYPE_UID;
    200                 map->status = ID_MAPPED;
    201                 return true;
    202         }
    203 
    204         return false;
    205 }
    206 
    207 static void winbindd_sids_to_xids_lookupsids_done(struct tevent_req *subreq)
    208 {
    209         struct tevent_req *req = tevent_req_callback_data(
    210                 subreq, struct tevent_req);
    211         struct winbindd_sids_to_xids_state *state = tevent_req_data(
    212                 req, struct winbindd_sids_to_xids_state);
    213         struct winbindd_child *child;
    214         NTSTATUS status;
    215         int i;
    216 
    217         status = wb_lookupsids_recv(subreq, state, &state->domains,
    218                                     &state->names);
    219         TALLOC_FREE(subreq);
    220         if (tevent_req_nterror(req, status)) {
    221                 return;
    222         }
    223 
    224         state->ids.num_ids = state->num_non_cached;
    225         state->ids.ids = TALLOC_ARRAY(state, struct wbint_TransID,
    226                                       state->num_non_cached);
    227         if (tevent_req_nomem(state->ids.ids, req)) {
    228                 return;
    229         }
    230 
    231         for (i=0; i<state->num_non_cached; i++) {
    232                 struct lsa_TranslatedName *n = &state->names->names[i];
    233                 struct wbint_TransID *t = &state->ids.ids[i];
    234 
    235                 switch (n->sid_type) {
    236                 case SID_NAME_USER:
    237                 case SID_NAME_COMPUTER:
    238                         t->type = WBC_ID_TYPE_UID;
    239                         break;
    240                 case SID_NAME_DOM_GRP:
    241                 case SID_NAME_ALIAS:
    242                 case SID_NAME_WKN_GRP:
    243                         t->type = WBC_ID_TYPE_GID;
    244                         break;
    245                 default:
    246                         t->type = WBC_ID_TYPE_NOT_SPECIFIED;
    247                         break;
    248                 };
    249                 t->domain_index = n->sid_index;
    250                 sid_peek_rid(&state->non_cached[i], &t->rid);
    251                 t->unix_id = (uint64_t)-1;
    252         }
    253 
    254         child = idmap_child();
    255 
    256         subreq = dcerpc_wbint_Sids2UnixIDs_send(
    257                 state, state->ev, child->binding_handle, state->domains,
    258                 &state->ids);
    259         if (tevent_req_nomem(subreq, req)) {
    260                 return;
    261         }
    262         tevent_req_set_callback(subreq, winbindd_sids_to_xids_done, req);
    26377}
    26478
     
    26983        struct winbindd_sids_to_xids_state *state = tevent_req_data(
    27084                req, struct winbindd_sids_to_xids_state);
    271         NTSTATUS status, result;
     85        NTSTATUS status;
    27286
    273         status = dcerpc_wbint_Sids2UnixIDs_recv(subreq, state, &result);
     87        state->xids = talloc_zero_array(state, struct unixid, state->num_sids);
     88        if (tevent_req_nomem(state->xids, req)) {
     89                return;
     90        }
     91
     92        status = wb_sids2xids_recv(subreq, state->xids, state->num_sids);
    27493        TALLOC_FREE(subreq);
    275         if (any_nt_status_not_ok(status, result, &status)) {
    276                 tevent_req_nterror(req, status);
     94        if (tevent_req_nterror(req, status)) {
    27795                return;
    27896        }
     
    286104                req, struct winbindd_sids_to_xids_state);
    287105        NTSTATUS status;
    288         char *result;
    289         uint32_t i, num_non_cached;
     106        char *result = NULL;
     107        uint32_t i;
    290108
    291109        if (tevent_req_is_nterror(req, &status)) {
    292                 DEBUG(5, ("wb_sids_to_xids failed: %s\n", nt_errstr(status)));
     110                DEBUG(5, ("Could not convert sids: %s\n", nt_errstr(status)));
    293111                return status;
    294112        }
     
    299117        }
    300118
    301         num_non_cached = 0;
     119        for (i=0; i<state->num_sids; i++) {
     120                char type = '\0';
     121                bool found = true;
     122                struct unixid xid;
    302123
    303         for (i=0; i<state->num_sids; i++) {
    304                 char type;
    305                 uint32_t unix_id = UINT32_MAX;
    306                 bool found = true;
     124                xid = state->xids[i];
    307125
    308                 if (state->cached[i].sid != NULL) {
    309                         unix_id = state->cached[i].xid.id;
    310 
    311                         switch (state->cached[i].xid.type) {
    312                         case ID_TYPE_UID:
    313                                 type = 'U';
    314                                 break;
    315                         case ID_TYPE_GID:
    316                                 type = 'G';
    317                                 break;
    318                         default:
    319                                 found = false;
    320                                 break;
    321                         }
    322                 } else {
    323                         unix_id = state->ids.ids[num_non_cached].unix_id;
    324 
    325                         switch(state->ids.ids[num_non_cached].type) {
    326                         case WBC_ID_TYPE_UID:
    327                                 type = 'U';
    328                                 idmap_cache_set_sid2uid(
    329                                         &state->non_cached[num_non_cached],
    330                                         unix_id);
    331                                 break;
    332                         case WBC_ID_TYPE_GID:
    333                                 type = 'G';
    334                                 idmap_cache_set_sid2gid(
    335                                         &state->non_cached[num_non_cached],
    336                                         unix_id);
    337                                 break;
    338                         default:
    339                                 found = false;
    340                                 break;
    341                         }
    342                         num_non_cached += 1;
     126                switch (xid.type) {
     127                case ID_TYPE_UID:
     128                        type = 'U';
     129                        break;
     130                case ID_TYPE_GID:
     131                        type = 'G';
     132                        break;
     133                case ID_TYPE_BOTH:
     134                        type = 'B';
     135                        break;
     136                default:
     137                        found = false;
     138                        break;
    343139                }
    344140
    345                 if (unix_id == UINT32_MAX) {
     141                if (xid.id == UINT32_MAX) {
    346142                        found = false;
    347143                }
     
    350146                        result = talloc_asprintf_append_buffer(
    351147                                result, "%c%lu\n", type,
    352                                 (unsigned long)unix_id);
     148                                (unsigned long)xid.id);
    353149                } else {
    354150                        result = talloc_asprintf_append_buffer(result, "\n");
     
    361157        response->extra_data.data = result;
    362158        response->length += talloc_get_size(result);
     159
    363160        return NT_STATUS_OK;
    364161}
  • vendor/current/source3/winbindd/winbindd_util.c

    r746 r988  
    2727#include "../libcli/auth/pam_errors.h"
    2828#include "passdb/machine_sid.h"
     29#include "passdb.h"
     30#include "source4/lib/messaging/messaging.h"
     31#include "librpc/gen_ndr/ndr_lsa.h"
     32#include "auth/credentials/credentials.h"
    2933
    3034#undef DBGC_CLASS
    3135#define DBGC_CLASS DBGC_WINBIND
    3236
     37static struct winbindd_domain *
     38add_trusted_domain_from_tdc(const struct winbindd_tdc_domain *tdc,
     39                            struct winbindd_methods *methods);
     40
    3341extern struct winbindd_methods cache_methods;
    3442
    3543/**
    36  * @file winbindd_util.cq
     44 * @file winbindd_util.c
    3745 *
    3846 * Winbind daemon for NT domain authentication nss module.
     
    6876
    6977                DLIST_REMOVE(_domain_list, domain);
    70                 SAFE_FREE(domain);
     78                TALLOC_FREE(domain);
    7179                domain = next;
    7280        }
     81}
     82
     83/**
     84 * Iterator for winbindd's domain list.
     85 * To be used (e.g.) in tevent based loops.
     86 */
     87struct winbindd_domain *wb_next_domain(struct winbindd_domain *domain)
     88{
     89        if (domain == NULL) {
     90                domain = domain_list();
     91        } else {
     92                domain = domain->next;
     93        }
     94
     95        if ((domain != NULL) &&
     96            (lp_server_role() != ROLE_ACTIVE_DIRECTORY_DC) &&
     97            sid_check_is_our_sam(&domain->sid))
     98        {
     99                domain = domain->next;
     100        }
     101
     102        return domain;
    73103}
    74104
     
    78108                return False;
    79109
    80         return (sid_check_is_domain(sid) || sid_check_is_builtin(sid));
     110        return (sid_check_is_our_sam(sid) || sid_check_is_builtin(sid));
    81111}
    82112
     
    86116                return False;
    87117
    88         return (sid_check_is_in_our_domain(sid) || sid_check_is_in_builtin(sid));
    89 }
    90 
    91 
    92 /* Add a trusted domain to our list of domains */
    93 static struct winbindd_domain *add_trusted_domain(const char *domain_name, const char *alt_name,
    94                                                   struct winbindd_methods *methods,
    95                                                   const struct dom_sid *sid)
     118        return (sid_check_is_in_our_sam(sid) || sid_check_is_in_builtin(sid));
     119}
     120
     121
     122/* Add a trusted domain to our list of domains.
     123   If the domain already exists in the list,
     124   return it and don't re-initialize.  */
     125
     126static struct winbindd_domain *
     127add_trusted_domain(const char *domain_name, const char *alt_name,
     128                   struct winbindd_methods *methods, const struct dom_sid *sid)
     129{
     130        struct winbindd_tdc_domain tdc;
     131
     132        ZERO_STRUCT(tdc);
     133
     134        tdc.domain_name = domain_name;
     135        tdc.dns_name = alt_name;
     136        if (sid) {
     137                sid_copy(&tdc.sid, sid);
     138        }
     139
     140        return add_trusted_domain_from_tdc(&tdc, methods);
     141}
     142
     143/* Add a trusted domain out of a trusted domain cache
     144   entry
     145*/
     146static struct winbindd_domain *
     147add_trusted_domain_from_tdc(const struct winbindd_tdc_domain *tdc,
     148                            struct winbindd_methods *methods)
    96149{
    97150        struct winbindd_domain *domain;
    98151        const char *alternative_name = NULL;
    99         char *idmap_config_option;
    100         const char *param;
    101152        const char **ignored_domains, **dom;
     153        int role = lp_server_role();
     154        const char *domain_name = tdc->domain_name;
     155        const struct dom_sid *sid = &tdc->sid;
     156
     157        if (is_null_sid(sid)) {
     158                sid = NULL;
     159        }
    102160
    103161        ignored_domains = lp_parm_string_list(-1, "winbind", "ignore domains", NULL);
     
    109167        }
    110168
    111         /* ignore alt_name if we are not in an AD domain */
    112 
    113         if ( (lp_security() == SEC_ADS) && alt_name && *alt_name) {
    114                 alternative_name = alt_name;
     169        /* use alt_name if available to allow DNS lookups */
     170
     171        if (tdc->dns_name && *tdc->dns_name) {
     172                alternative_name = tdc->dns_name;
    115173        }
    116174
     
    124182                }
    125183
    126                 if (alternative_name && *alternative_name)
    127                 {
     184                if (alternative_name) {
    128185                        if (strequal(alternative_name, domain->name) ||
    129186                            strequal(alternative_name, domain->alt_name))
     
    133190                }
    134191
    135                 if (sid)
    136                 {
    137                         if (is_null_sid(sid)) {
    138                                 continue;
    139                         }
    140 
     192                if (sid != NULL) {
    141193                        if (dom_sid_equal(sid, &domain->sid)) {
    142194                                break;
     
    147199        if (domain != NULL) {
    148200                /*
    149                  * We found a match. Possibly update the SID
     201                 * We found a match on domain->name or
     202                 * domain->alt_name. Possibly update the SID
     203                 * if the stored SID was the NULL SID
     204                 * and return the matching entry.
    150205                 */
    151206                if ((sid != NULL)
     
    157212
    158213        /* Create new domain entry */
    159 
    160         if ((domain = SMB_MALLOC_P(struct winbindd_domain)) == NULL)
     214        domain = talloc_zero(NULL, struct winbindd_domain);
     215        if (domain == NULL) {
    161216                return NULL;
    162 
    163         /* Fill in fields */
    164 
    165         ZERO_STRUCTP(domain);
    166 
    167         domain->children = SMB_MALLOC_ARRAY(
    168                 struct winbindd_child, lp_winbind_max_domain_connections());
     217        }
     218
     219        domain->children = talloc_zero_array(domain,
     220                                             struct winbindd_child,
     221                                             lp_winbind_max_domain_connections());
    169222        if (domain->children == NULL) {
    170                 SAFE_FREE(domain);
     223                TALLOC_FREE(domain);
    171224                return NULL;
    172225        }
    173         memset(domain->children, 0,
    174                sizeof(struct winbindd_child)
    175                * lp_winbind_max_domain_connections());
    176 
    177         fstrcpy(domain->name, domain_name);
     226
     227        domain->name = talloc_strdup(domain, domain_name);
     228        if (domain->name == NULL) {
     229                TALLOC_FREE(domain);
     230                return NULL;
     231        }
     232
    178233        if (alternative_name) {
    179                 fstrcpy(domain->alt_name, alternative_name);
     234                domain->alt_name = talloc_strdup(domain, alternative_name);
     235                if (domain->alt_name == NULL) {
     236                        TALLOC_FREE(domain);
     237                        return NULL;
     238                }
    180239        }
    181240
     
    185244        domain->sequence_number = DOM_SEQUENCE_NONE;
    186245        domain->last_seq_check = 0;
    187         domain->initialized = False;
     246        domain->initialized = false;
    188247        domain->online = is_internal_domain(sid);
    189248        domain->check_online_timeout = 0;
    190249        domain->dc_probe_pid = (pid_t)-1;
    191         if (sid) {
     250        if (sid != NULL) {
    192251                sid_copy(&domain->sid, sid);
    193252        }
     253        domain->domain_flags = tdc->trust_flags;
     254        domain->domain_type = tdc->trust_type;
     255        domain->domain_trust_attribs = tdc->trust_attribs;
     256
     257        /* Is this our primary domain ? */
     258        if (strequal(domain_name, get_global_sam_name()) &&
     259                        (role != ROLE_DOMAIN_MEMBER)) {
     260                domain->primary = true;
     261        } else if (strequal(domain_name, lp_workgroup()) &&
     262                        (role == ROLE_DOMAIN_MEMBER)) {
     263                domain->primary = true;
     264        }
     265
     266        if (domain->primary) {
     267                if (role == ROLE_ACTIVE_DIRECTORY_DC) {
     268                        domain->active_directory = true;
     269                }
     270                if (lp_security() == SEC_ADS) {
     271                        domain->active_directory = true;
     272                }
     273        } else if (!domain->internal) {
     274                if (domain->domain_type == LSA_TRUST_TYPE_UPLEVEL) {
     275                        domain->active_directory = true;
     276                }
     277        }
    194278
    195279        /* Link to domain list */
    196         DLIST_ADD_END(_domain_list, domain, struct winbindd_domain *);
     280        DLIST_ADD_END(_domain_list, domain);
    197281
    198282        wcache_tdc_add_domain( domain );
    199283
    200         idmap_config_option = talloc_asprintf(talloc_tos(), "idmap config %s",
    201                                               domain->name);
    202         if (idmap_config_option == NULL) {
    203                 DEBUG(0, ("talloc failed, not looking for idmap config\n"));
    204                 goto done;
    205         }
    206 
    207         param = lp_parm_const_string(-1, idmap_config_option, "range", NULL);
    208 
    209         DEBUG(10, ("%s : range = %s\n", idmap_config_option,
    210                    param ? param : "not defined"));
    211 
    212         if (param != NULL) {
    213                 unsigned low_id, high_id;
    214                 if (sscanf(param, "%u - %u", &low_id, &high_id) != 2) {
    215                         DEBUG(1, ("invalid range syntax in %s: %s\n",
    216                                   idmap_config_option, param));
    217                         goto done;
    218                 }
    219                 if (low_id > high_id) {
    220                         DEBUG(1, ("invalid range in %s: %s\n",
    221                                   idmap_config_option, param));
    222                         goto done;
    223                 }
    224                 domain->have_idmap_config = true;
    225                 domain->id_range_low = low_id;
    226                 domain->id_range_high = high_id;
    227         }
    228 
    229 done:
    230 
    231         DEBUG(2,("Added domain %s %s %s\n",
    232                  domain->name, domain->alt_name,
    233                  &domain->sid?sid_string_dbg(&domain->sid):""));
     284        setup_domain_child(domain);
     285
     286        DEBUG(2,
     287              ("Added domain %s %s %s\n", domain->name, domain->alt_name,
     288               !is_null_sid(&domain->sid) ? sid_string_dbg(&domain->sid) : ""));
    234289
    235290        return domain;
     
    262317        struct tevent_req *req;
    263318
    264         state = TALLOC_ZERO_P(NULL, struct trustdom_state);
     319        state = talloc_zero(NULL, struct trustdom_state);
    265320        if (state == NULL) {
    266321                DEBUG(0, ("talloc failed\n"));
     
    289344        int res, err;
    290345        char *p;
     346        struct winbindd_tdc_domain trust_params = {0};
     347        ptrdiff_t extra_len;
    291348
    292349        res = wb_domain_request_recv(req, state, &response, &err);
    293350        if ((res == -1) || (response->result != WINBINDD_OK)) {
    294                 DEBUG(1, ("Could not receive trustdoms\n"));
     351                DBG_WARNING("Could not receive trustdoms\n");
    295352                TALLOC_FREE(state);
    296353                return;
    297354        }
    298355
     356        if (response->length < sizeof(struct winbindd_response)) {
     357                DBG_ERR("ill-formed trustdom response - short length\n");
     358                TALLOC_FREE(state);
     359                return;
     360        }
     361
     362        extra_len = response->length - sizeof(struct winbindd_response);
     363
    299364        p = (char *)response->extra_data.data;
    300365
    301         while ((p != NULL) && (*p != '\0')) {
     366        while ((p - (char *)response->extra_data.data) < extra_len) {
    302367                char *q, *sidstr, *alt_name;
    303                 struct dom_sid sid;
    304                 struct winbindd_domain *domain;
    305                 char *alternate_name = NULL;
     368
     369                DBG_DEBUG("parsing response line '%s'\n", p);
     370
     371                ZERO_STRUCT(trust_params);
     372                trust_params.domain_name = p;
    306373
    307374                alt_name = strchr(p, '\\');
    308375                if (alt_name == NULL) {
     376                        DBG_ERR("Got invalid trustdom response\n");
     377                        break;
     378                }
     379
     380                *alt_name = '\0';
     381                alt_name += 1;
     382
     383                sidstr = strchr(alt_name, '\\');
     384                if (sidstr == NULL) {
     385                        DBG_ERR("Got invalid trustdom response\n");
     386                        break;
     387                }
     388
     389                *sidstr = '\0';
     390                sidstr += 1;
     391
     392                /* use the real alt_name if we have one, else pass in NULL */
     393                if (!strequal(alt_name, "(null)")) {
     394                        trust_params.dns_name = alt_name;
     395                }
     396
     397                q = strtok(sidstr, "\\");
     398                if (q == NULL) {
     399                        DBG_ERR("Got invalid trustdom response\n");
     400                        break;
     401                }
     402
     403                if (!string_to_sid(&trust_params.sid, sidstr)) {
    309404                        DEBUG(0, ("Got invalid trustdom response\n"));
    310405                        break;
    311406                }
    312407
    313                 *alt_name = '\0';
    314                 alt_name += 1;
    315 
    316                 sidstr = strchr(alt_name, '\\');
    317                 if (sidstr == NULL) {
    318                         DEBUG(0, ("Got invalid trustdom response\n"));
     408                q = strtok(NULL, "\\");
     409                if (q == NULL) {
     410                        DBG_ERR("Got invalid trustdom response\n");
    319411                        break;
    320412                }
    321413
    322                 *sidstr = '\0';
    323                 sidstr += 1;
    324 
    325                 q = strchr(sidstr, '\n');
    326                 if (q != NULL)
    327                         *q = '\0';
    328 
    329                 if (!string_to_sid(&sid, sidstr)) {
    330                         DEBUG(0, ("Got invalid trustdom response\n"));
     414                trust_params.trust_flags = (uint32_t)strtoul(q, NULL, 10);
     415
     416                q = strtok(NULL, "\\");
     417                if (q == NULL) {
     418                        DBG_ERR("Got invalid trustdom response\n");
    331419                        break;
    332420                }
    333421
    334                 /* use the real alt_name if we have one, else pass in NULL */
    335 
    336                 if ( !strequal( alt_name, "(null)" ) )
    337                         alternate_name = alt_name;
    338 
    339                 /* If we have an existing domain structure, calling
    340                    add_trusted_domain() will update the SID if
    341                    necessary.  This is important because we need the
    342                    SID for sibling domains */
    343 
    344                 if ( find_domain_from_name_noinit(p) != NULL ) {
    345                         domain = add_trusted_domain(p, alternate_name,
    346                                                     &cache_methods,
    347                                                     &sid);
    348                 } else {
    349                         domain = add_trusted_domain(p, alternate_name,
    350                                                     &cache_methods,
    351                                                     &sid);
    352                         if (domain) {
    353                                 setup_domain_child(domain);
    354                         }
    355                 }
    356                 p=q;
    357                 if (p != NULL)
    358                         p += 1;
     422                trust_params.trust_type = (uint32_t)strtoul(q, NULL, 10);
     423
     424                q = strtok(NULL, "\n");
     425                if (q == NULL) {
     426                        DBG_ERR("Got invalid trustdom response\n");
     427                        break;
     428                }
     429
     430                trust_params.trust_attribs = (uint32_t)strtoul(q, NULL, 10);
     431
     432                /*
     433                 * We always call add_trusted_domain() cause on an existing
     434                 * domain structure, it will update the SID if necessary.
     435                 * This is important because we need the SID for sibling
     436                 * domains.
     437                 */
     438                (void)add_trusted_domain_from_tdc(&trust_params,
     439                                                  &cache_methods);
     440
     441                p = q + strlen(q) + 1;
    359442        }
    360443
     
    423506
    424507                if ( !d ) {
    425                         d = add_trusted_domain( dom_list[i].domain_name,
    426                                                 dom_list[i].dns_name,
    427                                                 &cache_methods,
    428                                                 &dom_list[i].sid );
    429                         if (d != NULL) {
    430                                 setup_domain_child(d);
    431                         }
     508                        d = add_trusted_domain_from_tdc(&dom_list[i],
     509                                                        &cache_methods);
    432510                }
    433511
     
    476554
    477555        for ( i=0; i<num_trusts; i++ ) {
    478                 uint32 flags   = dom_list[i].trust_flags;
    479                 uint32 type    = dom_list[i].trust_type;
    480                 uint32 attribs = dom_list[i].trust_attribs;
     556                uint32_t flags   = dom_list[i].trust_flags;
     557                uint32_t type    = dom_list[i].trust_type;
     558                uint32_t attribs = dom_list[i].trust_attribs;
    481559
    482560                d = find_domain_from_name_noinit( dom_list[i].domain_name );
     
    488566
    489567                if ( (flags & NETR_TRUST_FLAG_INBOUND) &&
    490                      (type == NETR_TRUST_TYPE_UPLEVEL) &&
    491                      (attribs == NETR_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) )
     568                     (type == LSA_TRUST_TYPE_UPLEVEL) &&
     569                     (attribs == LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) )
    492570                {
    493571                        /* add the trusted domain if we don't know
     
    495573
    496574                        if ( !d ) {
    497                                 d = add_trusted_domain( dom_list[i].domain_name,
    498                                                         dom_list[i].dns_name,
    499                                                         &cache_methods,
    500                                                         &dom_list[i].sid );
    501                                 if (d != NULL) {
    502                                         setup_domain_child(d);
    503                                 }
     575                                d = add_trusted_domain_from_tdc(&dom_list[i],
     576                                                                &cache_methods);
    504577                        }
    505578
     
    569642        }
    570643
    571         if (domain->internal) {
    572                 domain->initialized = true;
    573         } else {
    574                 init_dc_connection(domain);
    575         }
     644        init_dc_connection(domain, false);
    576645
    577646        if (!domain->initialized) {
     
    599668}
    600669
     670static void wb_imsg_new_trusted_domain(struct imessaging_context *msg,
     671                                       void *private_data,
     672                                       uint32_t msg_type,
     673                                       struct server_id server_id,
     674                                       DATA_BLOB *data)
     675{
     676        TALLOC_CTX *frame = talloc_stackframe();
     677        struct lsa_TrustDomainInfoInfoEx info;
     678        enum ndr_err_code ndr_err;
     679        struct winbindd_domain *d = NULL;
     680
     681        DEBUG(5, ("wb_imsg_new_trusted_domain\n"));
     682
     683        if (data == NULL) {
     684                TALLOC_FREE(frame);
     685                return;
     686        }
     687
     688        ndr_err = ndr_pull_struct_blob_all(data, frame, &info,
     689                        (ndr_pull_flags_fn_t)ndr_pull_lsa_TrustDomainInfoInfoEx);
     690        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     691                TALLOC_FREE(frame);
     692                return;
     693        }
     694
     695        d = find_domain_from_name_noinit(info.netbios_name.string);
     696        if (d != NULL) {
     697                TALLOC_FREE(frame);
     698                return;
     699        }
     700
     701        d = add_trusted_domain(info.netbios_name.string,
     702                               info.domain_name.string,
     703                               &cache_methods,
     704                               info.sid);
     705        if (d == NULL) {
     706                TALLOC_FREE(frame);
     707                return;
     708        }
     709
     710        if (d->internal) {
     711                TALLOC_FREE(frame);
     712                return;
     713        }
     714
     715        if (d->primary) {
     716                TALLOC_FREE(frame);
     717                return;
     718        }
     719
     720        if (info.trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
     721                d->domain_flags |= NETR_TRUST_FLAG_INBOUND;
     722        }
     723        if (info.trust_direction & LSA_TRUST_DIRECTION_OUTBOUND) {
     724                d->domain_flags |= NETR_TRUST_FLAG_OUTBOUND;
     725        }
     726        if (info.trust_attributes & LSA_TRUST_ATTRIBUTE_WITHIN_FOREST) {
     727                d->domain_flags |= NETR_TRUST_FLAG_IN_FOREST;
     728        }
     729        d->domain_type = info.trust_type;
     730        d->domain_trust_attribs = info.trust_attributes;
     731
     732        TALLOC_FREE(frame);
     733}
     734
     735/*
     736 * We did not get the secret when we queried secrets.tdb, so read it
     737 * from secrets.tdb and re-sync the databases
     738 */
     739static bool migrate_secrets_tdb_to_ldb(struct winbindd_domain *domain)
     740{
     741        bool ok;
     742        struct cli_credentials *creds;
     743        NTSTATUS can_migrate = pdb_get_trust_credentials(domain->name,
     744                                                         NULL, domain, &creds);
     745        if (!NT_STATUS_IS_OK(can_migrate)) {
     746                DEBUG(0, ("Failed to fetch our own, local AD domain join "
     747                        "password for winbindd's internal use, both from "
     748                        "secrets.tdb and secrets.ldb: %s\n",
     749                        nt_errstr(can_migrate)));
     750                return false;
     751        }
     752
     753        /*
     754         * NOTE: It is very unlikely we end up here if there is an
     755         * oldpass, because a new password is created at
     756         * classicupgrade, so this is not a concern.
     757         */
     758        ok = secrets_store_machine_pw_sync(cli_credentials_get_password(creds),
     759                   NULL /* oldpass */,
     760                   cli_credentials_get_domain(creds),
     761                   cli_credentials_get_realm(creds),
     762                   cli_credentials_get_salt_principal(creds),
     763                   0, /* Supported enc types, unused */
     764                   &domain->sid,
     765                   cli_credentials_get_password_last_changed_time(creds),
     766                   cli_credentials_get_secure_channel_type(creds),
     767                   false /* do_delete: Do not delete */);
     768        TALLOC_FREE(creds);
     769        if (ok == false) {
     770                DEBUG(0, ("Failed to write our our own, "
     771                          "local AD domain join password for "
     772                          "winbindd's internal use into secrets.tdb\n"));
     773                return false;
     774        }
     775        return true;
     776}
     777
    601778/* Look up global info for the winbind daemon */
    602779bool init_domain_list(void)
    603780{
    604         struct winbindd_domain *domain;
    605781        int role = lp_server_role();
     782        NTSTATUS status;
    606783
    607784        /* Free existing list */
     
    610787        /* BUILTIN domain */
    611788
    612         domain = add_trusted_domain("BUILTIN", NULL, &cache_methods,
     789        (void)add_trusted_domain("BUILTIN", NULL, &cache_methods,
    613790                                    &global_sid_Builtin);
    614         if (domain) {
    615                 setup_domain_child(domain);
    616         }
    617791
    618792        /* Local SAM */
    619793
    620         domain = add_trusted_domain(get_global_sam_name(), NULL,
    621                                     &cache_methods, get_global_sam_sid());
    622         if (domain) {
    623                 if ( role != ROLE_DOMAIN_MEMBER ) {
    624                         domain->primary = True;
    625                 }
    626                 setup_domain_child(domain);
    627         }
    628 
     794        if ( role == ROLE_ACTIVE_DIRECTORY_DC ) {
     795                struct winbindd_domain *domain;
     796                enum netr_SchannelType sec_chan_type;
     797                const char *account_name;
     798                struct samr_Password current_nt_hash;
     799                struct pdb_domain_info *pdb_domain_info;
     800                bool ok;
     801
     802                pdb_domain_info = pdb_get_domain_info(talloc_tos());
     803                if (pdb_domain_info == NULL) {
     804                        DEBUG(0, ("Failed to fetch our own, local AD "
     805                                "domain info from sam.ldb\n"));
     806                        return false;
     807                }
     808                domain = add_trusted_domain(pdb_domain_info->name,
     809                                        pdb_domain_info->dns_domain,
     810                                        &cache_methods,
     811                                        &pdb_domain_info->sid);
     812                TALLOC_FREE(pdb_domain_info);
     813                if (domain == NULL) {
     814                        DEBUG(0, ("Failed to add our own, local AD "
     815                                "domain to winbindd's internal list\n"));
     816                        return false;
     817                }
     818
     819                /*
     820                 * We need to call this to find out if we are an RODC
     821                 */
     822                ok = get_trust_pw_hash(domain->name,
     823                                       current_nt_hash.hash,
     824                                       &account_name,
     825                                       &sec_chan_type);
     826                if (!ok) {
     827                        /*
     828                         * If get_trust_pw_hash() fails, then try and
     829                         * fetch the password from the more recent of
     830                         * secrets.{ldb,tdb} using the
     831                         * pdb_get_trust_credentials()
     832                         */
     833                        ok = migrate_secrets_tdb_to_ldb(domain);
     834
     835                        if (ok == false) {
     836                                DEBUG(0, ("Failed to migrate our own, "
     837                                          "local AD domain join password for "
     838                                          "winbindd's internal use into "
     839                                          "secrets.tdb\n"));
     840                                return false;
     841                        }
     842                        ok = get_trust_pw_hash(domain->name,
     843                                               current_nt_hash.hash,
     844                                               &account_name,
     845                                               &sec_chan_type);
     846                        if (ok == false) {
     847                                DEBUG(0, ("Failed to find our our own, just "
     848                                          "written local AD domain join "
     849                                          "password for winbindd's internal "
     850                                          "use in secrets.tdb\n"));
     851                                return false;
     852                        }
     853                }
     854                if (sec_chan_type == SEC_CHAN_RODC) {
     855                        domain->rodc = true;
     856                }
     857
     858        } else {
     859                (void)add_trusted_domain(get_global_sam_name(), NULL,
     860                                         &cache_methods, get_global_sam_sid());
     861        }
    629862        /* Add ourselves as the first entry. */
    630863
    631864        if ( role == ROLE_DOMAIN_MEMBER ) {
     865                struct winbindd_domain *domain;
    632866                struct dom_sid our_sid;
    633867
     
    640874                                             &cache_methods, &our_sid);
    641875                if (domain) {
    642                         domain->primary = True;
    643                         setup_domain_child(domain);
    644 
    645876                        /* Even in the parent winbindd we'll need to
    646877                           talk to the DC, so try and see if we can
     
    651882                        set_domain_online_request(domain);
    652883                }
     884        }
     885
     886        status = imessaging_register(winbind_imessaging_context(), NULL,
     887                                     MSG_WINBIND_NEW_TRUSTED_DOMAIN,
     888                                     wb_imsg_new_trusted_domain);
     889        if (!NT_STATUS_IS_OK(status)) {
     890                DEBUG(0, ("imessaging_register(MSG_WINBIND_NEW_TRUSTED_DOMAIN) - %s\n",
     891                          nt_errstr(status)));
     892                return false;
    653893        }
    654894
     
    676916        for (domain = domain_list(); domain != NULL; domain = domain->next) {
    677917                if (strequal(domain_name, domain->name) ||
    678                     (domain->alt_name[0] &&
     918                    (domain->alt_name != NULL &&
    679919                     strequal(domain_name, domain->alt_name))) {
    680920                        return domain;
     
    697937
    698938        if (!domain->initialized)
    699                 init_dc_connection(domain);
     939                init_dc_connection(domain, false);
    700940
    701941        return domain;
     
    732972
    733973        if (!domain->initialized)
    734                 init_dc_connection(domain);
     974                init_dc_connection(domain, false);
    735975
    736976        return domain;
     
    756996        struct winbindd_domain *ours = find_our_domain();
    757997
    758         if (ours->forest_name[0] == '\0') {
     998        if (ours->forest_name == NULL) {
    759999                return NULL;
    7601000        }
     
    8781118        }
    8791119
    880         strupper_m(domain);
    881 
    882         return True;
     1120        return strupper_m(domain);
    8831121}
    8841122
     
    9271165    username is then unqualified in unix
    9281166
     1167    On an AD DC we always fill DOMAIN\\USERNAME.
     1168
    9291169    We always canonicalize as UPPERCASE DOMAIN, lowercase username.
    9301170*/
     
    9331173        fstring tmp_user;
    9341174
     1175        if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
     1176                can_assume = false;
     1177        }
     1178
    9351179        fstrcpy(tmp_user, user);
    936         strlower_m(tmp_user);
     1180        (void)strlower_m(tmp_user);
    9371181
    9381182        if (can_assume && assume_domain(domain)) {
     
    9561200        char *tmp_user, *name;
    9571201
     1202        if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
     1203                can_assume = false;
     1204        }
     1205
    9581206        tmp_user = talloc_strdup(mem_ctx, user);
    959         strlower_m(tmp_user);
     1207        if (!strlower_m(tmp_user)) {
     1208                TALLOC_FREE(tmp_user);
     1209                return NULL;
     1210        }
    9601211
    9611212        if (can_assume && assume_domain(domain)) {
     
    9861237}
    9871238
     1239/* Return list-tail of all connected clients */
     1240
     1241struct winbindd_cli_state *winbindd_client_list_tail(void)
     1242{
     1243        return DLIST_TAIL(_client_list);
     1244}
     1245
     1246/* Return previous (read:newer) client in list */
     1247
     1248struct winbindd_cli_state *
     1249winbindd_client_list_prev(struct winbindd_cli_state *cli)
     1250{
     1251        return DLIST_PREV(cli);
     1252}
     1253
    9881254/* Add a connection to the list */
    9891255
    9901256void winbindd_add_client(struct winbindd_cli_state *cli)
    9911257{
     1258        cli->last_access = time(NULL);
    9921259        DLIST_ADD(_client_list, cli);
    9931260        _num_clients++;
     
    10001267        DLIST_REMOVE(_client_list, cli);
    10011268        _num_clients--;
     1269}
     1270
     1271/* Move a client to head or list */
     1272
     1273void winbindd_promote_client(struct winbindd_cli_state *cli)
     1274{
     1275        cli->last_access = time(NULL);
     1276        DLIST_PROMOTE(_client_list, cli);
    10021277}
    10031278
     
    11801455
    11811456        if (domain->primary) {
    1182                 return true;
     1457                ret = true;
     1458                goto done;
    11831459        }
    11841460
     
    11881464                DEBUG(10,("winbindd_can_contact_domain: %s not found in cache\n",
    11891465                          domain->name));
    1190                 return false;
     1466                ret = false;
     1467                goto done;
    11911468        }
    11921469
     
    13581635}
    13591636
     1637/**
     1638 * Parse an char array into a list of sids.
     1639 *
     1640 * The input sidstr should consist of 0-terminated strings
     1641 * representing sids, separated by newline characters '\n'.
     1642 * The list is terminated by an empty string, i.e.
     1643 * character '\0' directly following a character '\n'
     1644 * (or '\0' right at the start of sidstr).
     1645 */
    13601646bool parse_sidlist(TALLOC_CTX *mem_ctx, const char *sidstr,
    13611647                   struct dom_sid **sids, uint32_t *num_sids)
  • vendor/current/source3/winbindd/wscript_build

    r740 r988  
    11#!/usr/bin/env python
    22
    3 IDMAP_AD_SRC = '''idmap_ad.c'''
    4 IDMAP_RID_SRC = '''idmap_rid.c'''
    5 IDMAP_PASSDB_SRC = '''idmap_passdb.c'''
    6 IDMAP_LDAP_SRC = '''idmap_ldap.c'''
    7 IDMAP_NSS_SRC = '''idmap_nss.c'''
    8 IDMAP_TDB_SRC = '''idmap_tdb.c'''
    9 IDMAP_TDB2_SRC = '''idmap_tdb2.c'''
     3bld.SAMBA3_LIBRARY('idmap',
     4                   source='idmap.c idmap_util.c',
     5                   deps='samba-util pdb',
     6                   allow_undefined_symbols=True,
     7                   private_library=True)
    108
    11 IDMAP_HASH_SRC = '''idmap_hash/idmap_hash.c
    12                     idmap_hash/mapfile.c'''
     9bld.SAMBA3_SUBSYSTEM('IDMAP_RW',
     10                     source='idmap_rw.c',
     11                     deps='samba-util')
    1312
    14 IDMAP_ADEX_SRC = '''idmap_adex/idmap_adex.c
    15                     idmap_adex/cell_util.c
    16                     idmap_adex/likewise_cell.c
    17                     idmap_adex/provider_unified.c
    18                     idmap_adex/gc_util.c
    19                     idmap_adex/domain_util.c'''
    20 IDMAP_AUTORID_SRC = '''idmap_autorid.c'''
    21 
    22 IDMAP_RW_SRC = 'idmap_rw.c'
    23 IDMAP_SRC = 'idmap.c idmap_util.c ${IDMAP_RW_SRC}'
    24 
    25 bld.SAMBA3_SUBSYSTEM('idmap',
    26                     source=IDMAP_SRC,
    27                     vars=locals())
    28 
    29 bld.SAMBA3_SUBSYSTEM('IDMAP_ADEX',
    30                     source=IDMAP_ADEX_SRC,
    31                     vars=locals(),
    32                     enabled=bld.env.HAVE_LDAP)
     13bld.SAMBA3_SUBSYSTEM('IDMAP_TDB_COMMON',
     14                     source='idmap_tdb_common.c',
     15                     deps='tdb IDMAP_RW')
    3316
    3417bld.SAMBA3_SUBSYSTEM('IDMAP_HASH',
    35                     source=IDMAP_HASH_SRC,
    36                     vars=locals())
     18                    source='idmap_hash/idmap_hash.c idmap_hash/mapfile.c',
     19                    deps='samba-util krb5samba',
     20                    enabled=bld.SAMBA3_IS_ENABLED_MODULE('idmap_hash'))
    3721
    3822bld.SAMBA3_SUBSYSTEM('IDMAP_AD',
    39                     source=IDMAP_AD_SRC,
    40                     vars=locals(),
    41                     enabled=bld.env.HAVE_LDAP)
     23                    source='idmap_ad.c',
     24                    deps='ads nss_info',
     25                    enabled=bld.SAMBA3_IS_ENABLED_MODULE('idmap_ad'))
    4226
    4327bld.SAMBA3_MODULE('idmap_ad',
    4428                 subsystem='idmap',
     29                 allow_undefined_symbols=True,
    4530                 source='',
    4631                 deps='IDMAP_AD',
    4732                 init_function='',
    4833                 internal_module=bld.SAMBA3_IS_STATIC_MODULE('idmap_ad'),
    49                  enabled=bld.SAMBA3_IS_ENABLED_MODULE('idmap_ad' and bld.env.HAVE_LDAP))
     34                 enabled=bld.SAMBA3_IS_ENABLED_MODULE('idmap_ad'))
     35
     36bld.SAMBA3_MODULE('idmap_rfc2307',
     37                 subsystem='idmap',
     38                 allow_undefined_symbols=True,
     39                 source='idmap_rfc2307.c',
     40                 init_function='',
     41                 deps='ads',
     42                 internal_module=bld.SAMBA3_IS_STATIC_MODULE('idmap_rfc2307'),
     43                 enabled=bld.SAMBA3_IS_ENABLED_MODULE('idmap_rfc2307'))
    5044
    5145bld.SAMBA3_MODULE('idmap_rid',
    5246                 subsystem='idmap',
    53                  source=IDMAP_RID_SRC,
     47                 allow_undefined_symbols=True,
     48                 source='idmap_rid.c',
    5449                 init_function='',
    5550                 internal_module=bld.SAMBA3_IS_STATIC_MODULE('idmap_rid'),
     
    5853bld.SAMBA3_MODULE('idmap_passdb',
    5954                 subsystem='idmap',
    60                  source=IDMAP_PASSDB_SRC,
     55                 source='idmap_passdb.c',
     56                 deps='samba-util samba-passdb',
    6157                 init_function='',
    6258                 internal_module=bld.SAMBA3_IS_STATIC_MODULE('idmap_passdb'),
     
    6561bld.SAMBA3_MODULE('idmap_ldap',
    6662                 subsystem='idmap',
    67                  source=IDMAP_LDAP_SRC,
     63                 source='idmap_ldap.c',
     64                 deps='smbldap smbldaphelper pdb IDMAP_RW',
    6865                 init_function='',
    6966                 internal_module=bld.SAMBA3_IS_STATIC_MODULE('idmap_ldap'),
    70                  enabled=bld.SAMBA3_IS_ENABLED_MODULE('idmap_ldap') and bld.env.HAVE_LDAP)
     67                 enabled=bld.SAMBA3_IS_ENABLED_MODULE('idmap_ldap') and bld.CONFIG_SET("HAVE_LDAP"),
     68                 allow_undefined_symbols=True)
    7169
    7270bld.SAMBA3_MODULE('idmap_nss',
    7371                 subsystem='idmap',
    74                  source=IDMAP_NSS_SRC,
     72                 source='idmap_nss.c',
     73                 deps='samba-util',
    7574                 init_function='',
    7675                 internal_module=bld.SAMBA3_IS_STATIC_MODULE('idmap_nss'),
     
    7978bld.SAMBA3_MODULE('idmap_tdb',
    8079                 subsystem='idmap',
    81                  source=IDMAP_TDB_SRC,
     80                 source='idmap_tdb.c',
     81                 deps='samba-util tdb IDMAP_TDB_COMMON',
    8282                 init_function='',
     83                 allow_undefined_symbols=True,
    8384                 internal_module=bld.SAMBA3_IS_STATIC_MODULE('idmap_tdb'),
    8485                 enabled=bld.SAMBA3_IS_ENABLED_MODULE('idmap_tdb'))
     
    8687bld.SAMBA3_MODULE('idmap_tdb2',
    8788                 subsystem='idmap',
    88                  source=IDMAP_TDB2_SRC,
     89                 source='idmap_tdb2.c',
     90                 deps='samba-util tdb IDMAP_TDB_COMMON',
    8991                 init_function='',
    9092                 internal_module=bld.SAMBA3_IS_STATIC_MODULE('idmap_tdb2'),
     
    9597                 source='',
    9698                 deps='IDMAP_HASH',
     99                 allow_undefined_symbols=True,
    97100                 init_function='',
    98101                 internal_module=bld.SAMBA3_IS_STATIC_MODULE('idmap_hash'),
    99102                 enabled=bld.SAMBA3_IS_ENABLED_MODULE('idmap_hash'))
    100103
    101 bld.SAMBA3_MODULE('idmap_adex',
    102                  subsystem='idmap',
    103                  source='',
    104                  deps='IDMAP_ADEX',
    105                  init_function='',
    106                  internal_module=bld.SAMBA3_IS_STATIC_MODULE('idmap_adex'),
    107                  enabled=bld.SAMBA3_IS_ENABLED_MODULE('idmap_adex') and bld.env.HAVE_LDAP)
     104bld.SAMBA3_SUBSYSTEM('IDMAP_AUTORID_TDB',
     105                     source='idmap_autorid_tdb.c',
     106                     deps='tdb')
    108107
    109108bld.SAMBA3_MODULE('idmap_autorid',
    110109                 subsystem='idmap',
    111                  source=IDMAP_AUTORID_SRC,
     110                 source='idmap_autorid.c',
     111                 deps='samba-util tdb IDMAP_TDB_COMMON IDMAP_AUTORID_TDB',
    112112                 init_function='',
    113113                 internal_module=bld.SAMBA3_IS_STATIC_MODULE('idmap_autorid'),
    114                  enabled=bld.SAMBA3_IS_ENABLED_MODULE('idmap_autorid'))
     114                 enabled=bld.SAMBA3_IS_ENABLED_MODULE('idmap_autorid'),
     115                 allow_undefined_symbols=True)
    115116
    116 
    117 NSS_INFO_TEMPLATE_SRC = 'nss_info_template.c'
    118 NSS_INFO_SRC = 'nss_info.c'
    119 
    120 bld.SAMBA3_SUBSYSTEM('nss_info',
    121                     source=NSS_INFO_SRC,
    122                     vars=locals())
     117bld.SAMBA3_LIBRARY('nss_info',
     118                   source='nss_info.c',
     119                   deps='samba-util param',
     120                   private_library=True)
    123121
    124122bld.SAMBA3_MODULE('nss_info_template',
    125123                 subsystem='nss_info',
    126                  source=NSS_INFO_TEMPLATE_SRC,
     124                 source='nss_info_template.c',
     125                 deps='samba-util krb5samba',
    127126                 init_function='',
    128127                 internal_module=bld.SAMBA3_IS_STATIC_MODULE('nss_info_template'),
    129128                 enabled=bld.SAMBA3_IS_ENABLED_MODULE('nss_info_template'))
    130 
    131 bld.SAMBA3_MODULE('nss_info_adex',
    132                  subsystem='nss_info',
    133                  source='',
    134                  deps='IDMAP_ADEX',
    135                  init_function='',
    136                  internal_module=bld.SAMBA3_IS_STATIC_MODULE('idmap_adex'),
    137                  enabled=bld.SAMBA3_IS_ENABLED_MODULE('idmap_adex') and bld.env.HAVE_LDAP)
    138129
    139130bld.SAMBA3_MODULE('nss_info_hash',
     
    141132                 source='',
    142133                 deps='IDMAP_HASH',
     134                 allow_undefined_symbols=True,
    143135                 init_function='',
    144136                 internal_module=bld.SAMBA3_IS_STATIC_MODULE('idmap_hash'),
     
    149141                 source='',
    150142                 deps='IDMAP_AD',
     143                 allow_undefined_symbols=True,
    151144                 init_function='',
    152145                 internal_module=bld.SAMBA3_IS_STATIC_MODULE('idmap_ad'),
    153                  enabled=bld.SAMBA3_IS_ENABLED_MODULE('idmap_ad') and bld.env.HAVE_LDAP)
     146                 enabled=bld.SAMBA3_IS_ENABLED_MODULE('idmap_ad'))
    154147
    155148bld.SAMBA3_MODULE('nss_info_sfu20',
     
    157150                 source='',
    158151                 deps='IDMAP_AD',
     152                 allow_undefined_symbols=True,
    159153                 init_function='',
    160154                 internal_module=bld.SAMBA3_IS_STATIC_MODULE('idmap_ad'),
    161                  enabled=bld.SAMBA3_IS_ENABLED_MODULE('idmap_ad') and bld.env.HAVE_LDAP)
     155                 enabled=bld.SAMBA3_IS_ENABLED_MODULE('idmap_ad'))
    162156
    163157bld.SAMBA3_MODULE('nss_info_sfu',
     
    165159                 source='',
    166160                 deps='IDMAP_AD',
     161                 allow_undefined_symbols=True,
    167162                 init_function='',
    168163                 internal_module=bld.SAMBA3_IS_STATIC_MODULE('idmap_ad'),
    169                  enabled=bld.SAMBA3_IS_ENABLED_MODULE('idmap_ad') and bld.env.HAVE_LDAP)
     164                 enabled=bld.SAMBA3_IS_ENABLED_MODULE('idmap_ad') and bld.CONFIG_SET("HAVE_LDAP"))
     165
     166bld.SAMBA3_MODULE('idmap_script',
     167                 subsystem='idmap',
     168                 allow_undefined_symbols=True,
     169                 source='idmap_script.c',
     170                 init_function='',
     171                 internal_module=bld.SAMBA3_IS_STATIC_MODULE('idmap_script'),
     172                 enabled=bld.SAMBA3_IS_ENABLED_MODULE('idmap_script'))
Note: See TracChangeset for help on using the changeset viewer.