Ignore:
Timestamp:
Nov 14, 2012, 12:59:34 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: update vendor to 3.6.0

Location:
vendor/current/source3/winbindd
Files:
16 added
4 deleted
88 edited

Legend:

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

    r594 r740  
    66   Copyright (C) Simo Sorce 2003-2007
    77   Copyright (C) Jeremy Allison 2006
     8   Copyright (C) Michael Adam 2010
    89
    910   This program is free software; you can redistribute it and/or modify
     
    2324#include "includes.h"
    2425#include "winbindd.h"
     26#include "idmap.h"
     27#include "passdb/machine_sid.h"
    2528
    2629#undef DBGC_CLASS
     
    2831
    2932static_decl_idmap;
     33
     34static 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}
    3048
    3149/**
     
    4260
    4361/**
    44  * Pointer to the alloc backend methods. Modules register themselves here via
    45  * smb_register_idmap_alloc.
    46  */
    47 struct idmap_alloc_backend {
    48         const char *name;
    49         struct idmap_alloc_methods *methods;
    50         struct idmap_alloc_backend *prev, *next;
    51 };
    52 static struct idmap_alloc_backend *alloc_backends = NULL;
    53 
    54 /**
    55  * The idmap alloc context that is configured via "idmap alloc
    56  * backend". Defaults to "idmap backend" in case the module (tdb, ldap) also
    57  * provides alloc methods.
    58  */
    59 struct idmap_alloc_context {
    60         struct idmap_alloc_methods *methods;
    61 };
    62 static struct idmap_alloc_context *idmap_alloc_ctx = NULL;
    63 
    64 /**
    6562 * Default idmap domain configured via "idmap backend".
    6663 */
     
    8784
    8885        for (b = backends; b; b = b->next) {
    89                 if (strequal(b->name, name)) {
    90                         return b->methods;
    91                 }
    92         }
    93 
    94         return NULL;
    95 }
    96 
    97 static struct idmap_alloc_methods *get_alloc_methods(const char *name)
    98 {
    99         struct idmap_alloc_backend *b;
    100 
    101         for (b = alloc_backends; b; b = b->next) {
    10286                if (strequal(b->name, name)) {
    10387                        return b->methods;
     
    171155}
    172156
    173 /**********************************************************************
    174  Allow a module to register itself as an alloc method.
    175 **********************************************************************/
    176 
    177 NTSTATUS smb_register_idmap_alloc(int version, const char *name,
    178                                   struct idmap_alloc_methods *methods)
    179 {
    180         struct idmap_alloc_methods *test;
    181         struct idmap_alloc_backend *entry;
    182 
    183         if ((version != SMB_IDMAP_INTERFACE_VERSION)) {
    184                 DEBUG(0, ("Failed to register idmap alloc module.\n"
    185                           "The module was compiled against "
    186                           "SMB_IDMAP_INTERFACE_VERSION %d,\n"
    187                           "current SMB_IDMAP_INTERFACE_VERSION is %d.\n"
    188                           "Please recompile against the current version "
    189                           "of samba!\n",
    190                           version, SMB_IDMAP_INTERFACE_VERSION));
    191                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
    192         }
    193 
    194         if (!name || !name[0] || !methods) {
    195                 DEBUG(0,("Called with NULL pointer or empty name!\n"));
    196                 return NT_STATUS_INVALID_PARAMETER;
    197         }
    198 
    199         test = get_alloc_methods(name);
    200         if (test) {
    201                 DEBUG(0,("idmap_alloc module %s already registered!\n", name));
    202                 return NT_STATUS_OBJECT_NAME_COLLISION;
    203         }
    204 
    205         entry = talloc(NULL, struct idmap_alloc_backend);
    206         if ( ! entry) {
    207                 DEBUG(0,("Out of memory!\n"));
    208                 return NT_STATUS_NO_MEMORY;
    209         }
    210         entry->name = talloc_strdup(entry, name);
    211         if ( ! entry->name) {
    212                 DEBUG(0,("Out of memory!\n"));
    213                 return NT_STATUS_NO_MEMORY;
    214         }
    215         entry->methods = methods;
    216 
    217         DLIST_ADD(alloc_backends, entry);
    218         DEBUG(5, ("Successfully added idmap alloc backend '%s'\n", name));
    219         return NT_STATUS_OK;
    220 }
    221 
    222 static int close_domain_destructor(struct idmap_domain *dom)
    223 {
    224         NTSTATUS ret;
    225 
    226         ret = dom->methods->close_fn(dom);
    227         if (!NT_STATUS_IS_OK(ret)) {
    228                 DEBUG(3, ("Failed to close idmap domain [%s]!\n", dom->name));
    229         }
    230 
    231         return 0;
    232 }
    233 
    234 static bool parse_idmap_module(TALLOC_CTX *mem_ctx, const char *param,
    235                                char **pmodulename, char **pargs)
    236 {
    237         char *modulename;
    238         char *args;
    239 
    240         if (strncmp(param, "idmap_", 6) == 0) {
    241                 param += 6;
    242                 DEBUG(1, ("idmap_init: idmap backend uses deprecated "
    243                           "'idmap_' prefix.  Please replace 'idmap_%s' by "
    244                           "'%s'\n", param, param));
    245         }
    246 
    247         modulename = talloc_strdup(mem_ctx, param);
    248         if (modulename == NULL) {
    249                 return false;
    250         }
    251 
    252         args = strchr(modulename, ':');
    253         if (args == NULL) {
    254                 *pmodulename = modulename;
    255                 *pargs = NULL;
    256                 return true;
    257         }
    258 
    259         *args = '\0';
    260 
    261         args = talloc_strdup(mem_ctx, args+1);
    262         if (args == NULL) {
    263                 TALLOC_FREE(modulename);
    264                 return false;
    265         }
    266 
    267         *pmodulename = modulename;
    268         *pargs = args;
    269         return true;
    270 }
    271 
    272157/**
    273158 * Initialize a domain structure
     
    275160 * @param[in] domainname        which domain is this for
    276161 * @param[in] modulename        which backend module
    277  * @param[in] params            parameter to pass to the init function
     162 * @param[in] check_range       whether range checking should be done
    278163 * @result The initialized structure
    279164 */
     
    281166                                              const char *domainname,
    282167                                              const char *modulename,
    283                                               const char *params)
     168                                              bool check_range)
    284169{
    285170        struct idmap_domain *result;
    286171        NTSTATUS status;
     172        char *config_option = NULL;
     173        const char *range;
    287174
    288175        result = talloc_zero(mem_ctx, struct idmap_domain);
     
    296183                DEBUG(0, ("talloc failed\n"));
    297184                goto fail;
     185        }
     186
     187        /*
     188         * load ranges and read only information from the config
     189         */
     190
     191        config_option = talloc_asprintf(result, "idmap config %s",
     192                                        result->name);
     193        if (config_option == NULL) {
     194                DEBUG(0, ("Out of memory!\n"));
     195                goto fail;
     196        }
     197
     198        range = lp_parm_const_string(-1, config_option, "range", NULL);
     199        if (range == NULL) {
     200                DEBUG(1, ("idmap range not specified for domain %s\n",
     201                          result->name));
     202                if (check_range) {
     203                        goto fail;
     204                }
     205        } else if (sscanf(range, "%u - %u", &result->low_id,
     206                          &result->high_id) != 2)
     207        {
     208                DEBUG(1, ("invalid range '%s' specified for domain "
     209                          "'%s'\n", range, result->name));
     210                if (check_range) {
     211                        goto fail;
     212                }
     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));
     223                if (check_range) {
     224                        goto fail;
     225                }
    298226        }
    299227
     
    316244        }
    317245
    318         status = result->methods->init(result, params);
     246        status = result->methods->init(result);
    319247        if (!NT_STATUS_IS_OK(status)) {
    320248                DEBUG(1, ("idmap initialization returned %s\n",
     
    323251        }
    324252
    325         talloc_set_destructor(result, close_domain_destructor);
    326 
    327253        return result;
    328254
    329255fail:
    330         TALLOC_FREE(result);
    331         return NULL;
    332 }
    333 
    334 /**
    335  * Initialize the default domain structure
    336  * @param[in] mem_ctx           memory context for the result
    337  * @result The default domain structure
    338  *
    339  * This routine takes the module name from the "idmap backend" parameter,
    340  * passing a possible parameter like ldap:ldap://ldap-url/ to the module.
    341  */
    342 
    343 static struct idmap_domain *idmap_init_default_domain(TALLOC_CTX *mem_ctx)
    344 {
    345         struct idmap_domain *result;
    346         char *modulename;
    347         char *params;
    348 
    349         DEBUG(10, ("idmap_init_default_domain: calling static_init_idmap\n"));
    350 
    351         static_init_idmap;
    352 
    353         if (!parse_idmap_module(talloc_tos(), lp_idmap_backend(), &modulename,
    354                                 &params)) {
    355                 DEBUG(1, ("parse_idmap_module failed\n"));
    356                 return NULL;
    357         }
    358 
    359         DEBUG(3, ("idmap_init: using '%s' as remote backend\n", modulename));
    360 
    361         result = idmap_init_domain(mem_ctx, "*", modulename, params);
    362         if (result == NULL) {
    363                 goto fail;
    364         }
    365 
    366         TALLOC_FREE(modulename);
    367         TALLOC_FREE(params);
    368         return result;
    369 
    370 fail:
    371         TALLOC_FREE(modulename);
    372         TALLOC_FREE(params);
    373256        TALLOC_FREE(result);
    374257        return NULL;
     
    392275        const char *backend;
    393276
     277        idmap_init();
     278
    394279        config_option = talloc_asprintf(talloc_tos(), "idmap config %s",
    395280                                        domname);
     
    405290        }
    406291
    407         result = idmap_init_domain(mem_ctx, domname, backend, NULL);
     292        result = idmap_init_domain(mem_ctx, domname, backend, true);
    408293        if (result == NULL) {
    409294                goto fail;
     
    417302        TALLOC_FREE(result);
    418303        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
     315static struct idmap_domain *idmap_init_default_domain(TALLOC_CTX *mem_ctx)
     316{
     317        return idmap_init_named_domain(mem_ctx, "*");
    419318}
    420319
     
    429328static struct idmap_domain *idmap_init_passdb_domain(TALLOC_CTX *mem_ctx)
    430329{
     330        idmap_init();
     331
    431332        /*
    432333         * Always init the default domain, we can't go without one
     
    444345
    445346        passdb_idmap_domain = idmap_init_domain(NULL, get_global_sam_name(),
    446                                                 "passdb", NULL);
     347                                                "passdb", false);
    447348        if (passdb_idmap_domain == NULL) {
    448349                DEBUG(1, ("Could not init passdb idmap domain\n"));
     
    467368 */
    468369
    469 static struct idmap_domain *idmap_find_domain(const char *domname)
     370struct idmap_domain *idmap_find_domain(const char *domname)
    470371{
    471372        struct idmap_domain *result;
     
    474375        DEBUG(10, ("idmap_find_domain called for domain '%s'\n",
    475376                   domname?domname:"NULL"));
     377
     378        idmap_init();
    476379
    477380        /*
     
    522425void idmap_close(void)
    523426{
    524         if (idmap_alloc_ctx) {
    525                 idmap_alloc_ctx->methods->close_fn();
    526                 idmap_alloc_ctx->methods = NULL;
    527         }
    528         alloc_backends = NULL;
    529427        TALLOC_FREE(default_idmap_domain);
    530428        TALLOC_FREE(passdb_idmap_domain);
     
    533431}
    534432
    535 /**
    536  * Initialize the idmap alloc backend
    537  * @param[out] ctx              Where to put the alloc_ctx?
    538  * @result Did it work fine?
    539  *
    540  * This routine first looks at "idmap alloc backend" and if that is not
    541  * defined, it uses "idmap backend" for the module name.
    542  */
    543 static NTSTATUS idmap_alloc_init(struct idmap_alloc_context **ctx)
    544 {
    545         const char *backend;
    546         char *modulename, *params;
    547         NTSTATUS ret = NT_STATUS_NO_MEMORY;;
    548 
    549         static_init_idmap;
    550 
    551         if (idmap_alloc_ctx != NULL) {
    552                 *ctx = idmap_alloc_ctx;
    553                 return NT_STATUS_OK;
    554         }
    555 
    556         idmap_alloc_ctx = talloc(NULL, struct idmap_alloc_context);
    557         if (idmap_alloc_ctx == NULL) {
    558                 DEBUG(0, ("talloc failed\n"));
    559                 goto fail;
    560         }
    561 
    562         backend = lp_idmap_alloc_backend();
    563         if ((backend == NULL) || (backend[0] == '\0')) {
    564                 backend = lp_idmap_backend();
    565         }
    566 
    567         if (backend == NULL) {
    568                 DEBUG(3, ("no idmap alloc backend defined\n"));
    569                 ret = NT_STATUS_INVALID_PARAMETER;
    570                 goto fail;
    571         }
    572 
    573         if (!parse_idmap_module(idmap_alloc_ctx, backend, &modulename,
    574                                 &params)) {
    575                 DEBUG(1, ("parse_idmap_module %s failed\n", backend));
    576                 goto fail;
    577         }
    578 
    579         idmap_alloc_ctx->methods = get_alloc_methods(modulename);
    580 
    581         if (idmap_alloc_ctx->methods == NULL) {
    582                 ret = smb_probe_module("idmap", modulename);
    583                 if (NT_STATUS_IS_OK(ret)) {
    584                         idmap_alloc_ctx->methods =
    585                                 get_alloc_methods(modulename);
    586                 }
    587         }
    588 
    589         if (idmap_alloc_ctx->methods == NULL) {
    590                 DEBUG(1, ("could not find idmap alloc module %s\n", backend));
    591                 ret = NT_STATUS_INVALID_PARAMETER;
    592                 goto fail;
    593         }
    594 
    595         ret = idmap_alloc_ctx->methods->init(params);
    596 
    597         if (!NT_STATUS_IS_OK(ret)) {
    598                 DEBUG(0, ("ERROR: Initialization failed for alloc "
    599                           "backend, deferred!\n"));
    600                 goto fail;
    601         }
    602 
    603         TALLOC_FREE(modulename);
    604         TALLOC_FREE(params);
    605 
    606         *ctx = idmap_alloc_ctx;
    607         return NT_STATUS_OK;
    608 
    609 fail:
    610         TALLOC_FREE(idmap_alloc_ctx);
    611         return ret;
    612 }
    613 
    614433/**************************************************************************
    615434 idmap allocator interface functions
    616435**************************************************************************/
    617436
     437static NTSTATUS idmap_allocate_unixid(struct unixid *id)
     438{
     439        struct idmap_domain *dom;
     440        NTSTATUS ret;
     441
     442        dom = idmap_find_domain(NULL);
     443
     444        if (dom == NULL) {
     445                return NT_STATUS_UNSUCCESSFUL;
     446        }
     447
     448        if (dom->methods->allocate_id == NULL) {
     449                return NT_STATUS_NOT_IMPLEMENTED;
     450        }
     451
     452        ret = dom->methods->allocate_id(dom, id);
     453
     454        return ret;
     455}
     456
     457
    618458NTSTATUS idmap_allocate_uid(struct unixid *id)
    619459{
    620         struct idmap_alloc_context *ctx;
    621         NTSTATUS ret;
    622 
    623         if (!NT_STATUS_IS_OK(ret = idmap_alloc_init(&ctx))) {
    624                 return ret;
    625         }
    626 
    627460        id->type = ID_TYPE_UID;
    628         return ctx->methods->allocate_id(id);
     461        return idmap_allocate_unixid(id);
    629462}
    630463
    631464NTSTATUS idmap_allocate_gid(struct unixid *id)
    632465{
    633         struct idmap_alloc_context *ctx;
    634         NTSTATUS ret;
    635 
    636         if (!NT_STATUS_IS_OK(ret = idmap_alloc_init(&ctx))) {
    637                 return ret;
    638         }
    639 
    640466        id->type = ID_TYPE_GID;
    641         return ctx->methods->allocate_id(id);
    642 }
    643 
    644 NTSTATUS idmap_set_uid_hwm(struct unixid *id)
    645 {
    646         struct idmap_alloc_context *ctx;
    647         NTSTATUS ret;
    648 
    649         if (!NT_STATUS_IS_OK(ret = idmap_alloc_init(&ctx))) {
    650                 return ret;
    651         }
    652 
    653         id->type = ID_TYPE_UID;
    654         return ctx->methods->set_id_hwm(id);
    655 }
    656 
    657 NTSTATUS idmap_set_gid_hwm(struct unixid *id)
    658 {
    659         struct idmap_alloc_context *ctx;
    660         NTSTATUS ret;
    661 
    662         if (!NT_STATUS_IS_OK(ret = idmap_alloc_init(&ctx))) {
    663                 return ret;
    664         }
    665 
    666         id->type = ID_TYPE_GID;
    667         return ctx->methods->set_id_hwm(id);
    668 }
    669 
    670 NTSTATUS idmap_new_mapping(const struct dom_sid *psid, enum id_type type,
    671                            struct unixid *pxid)
    672 {
    673         struct dom_sid sid;
    674         struct idmap_domain *dom;
    675         struct id_map map;
    676         NTSTATUS status;
    677 
    678         dom = idmap_find_domain(NULL);
    679         if (dom == NULL) {
    680                 DEBUG(3, ("no default domain, no place to write\n"));
    681                 return NT_STATUS_ACCESS_DENIED;
    682         }
    683         if (dom->methods->set_mapping == NULL) {
    684                 DEBUG(3, ("default domain not writable\n"));
    685                 return NT_STATUS_MEDIA_WRITE_PROTECTED;
    686         }
    687 
    688         sid_copy(&sid, psid);
    689         map.sid = &sid;
    690         map.xid.type = type;
    691 
    692         switch (type) {
    693         case ID_TYPE_UID:
    694                 status = idmap_allocate_uid(&map.xid);
    695                 break;
    696         case ID_TYPE_GID:
    697                 status = idmap_allocate_gid(&map.xid);
    698                 break;
    699         default:
    700                 status = NT_STATUS_INVALID_PARAMETER;
    701                 break;
    702         }
    703 
    704         if (!NT_STATUS_IS_OK(status)) {
    705                 DEBUG(3, ("Could not allocate id: %s\n", nt_errstr(status)));
    706                 return status;
    707         }
    708 
    709         map.status = ID_MAPPED;
    710 
    711         DEBUG(10, ("Setting mapping: %s <-> %s %lu\n",
    712                    sid_string_dbg(map.sid),
    713                    (map.xid.type == ID_TYPE_UID) ? "UID" : "GID",
    714                    (unsigned long)map.xid.id));
    715 
    716         status = dom->methods->set_mapping(dom, &map);
    717 
    718         if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
    719                 struct id_map *ids[2];
    720                 DEBUG(5, ("Mapping for %s exists - retrying to map sid\n",
    721                           sid_string_dbg(map.sid)));
    722                 ids[0] = &map;
    723                 ids[1] = NULL;
    724                 status = dom->methods->sids_to_unixids(dom, ids);
    725         }
    726 
    727         if (!NT_STATUS_IS_OK(status)) {
    728                 DEBUG(3, ("Could not store the new mapping: %s\n",
    729                           nt_errstr(status)));
    730                 return status;
    731         }
    732 
    733         *pxid = map.xid;
    734 
    735         return NT_STATUS_OK;
     467        return idmap_allocate_unixid(id);
    736468}
    737469
     
    772504        struct id_map *maps[2];
    773505
    774          DEBUG(10, ("idmap_backends_sid_to_unixid: domain = '%s', sid = [%s]\n",
    775                     domain?domain:"NULL", sid_string_dbg(id->sid)));
     506        DEBUG(10, ("idmap_backends_sid_to_unixid: domain = '%s', sid = [%s]\n",
     507                   domain?domain:"NULL", sid_string_dbg(id->sid)));
    776508
    777509        maps[0] = id;
     
    779511
    780512        if (sid_check_is_in_builtin(id->sid)
    781             || (sid_check_is_in_our_domain(id->sid))) {
     513            || (sid_check_is_in_our_domain(id->sid)))
     514        {
     515                NTSTATUS status;
     516
     517                DEBUG(10, ("asking passdb...\n"));
    782518
    783519                dom = idmap_init_passdb_domain(NULL);
     
    785521                        return NT_STATUS_NONE_MAPPED;
    786522                }
    787                 return dom->methods->sids_to_unixids(dom, maps);
     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;
    788532        }
    789533
     
    795539        return dom->methods->sids_to_unixids(dom, maps);
    796540}
    797 
    798 NTSTATUS idmap_set_mapping(const struct id_map *map)
    799 {
    800         struct idmap_domain *dom;
    801 
    802         dom = idmap_find_domain(NULL);
    803         if (dom == NULL) {
    804                 DEBUG(3, ("no default domain, no place to write\n"));
    805                 return NT_STATUS_ACCESS_DENIED;
    806         }
    807         if (dom->methods->set_mapping == NULL) {
    808                 DEBUG(3, ("default domain not writable\n"));
    809                 return NT_STATUS_MEDIA_WRITE_PROTECTED;
    810         }
    811 
    812         return dom->methods->set_mapping(dom, map);
    813 }
    814 
    815 NTSTATUS idmap_remove_mapping(const struct id_map *map)
    816 {
    817         struct idmap_domain *dom;
    818 
    819         dom = idmap_find_domain(NULL);
    820         if (dom == NULL) {
    821                 DEBUG(3, ("no default domain, no place to write\n"));
    822                 return NT_STATUS_ACCESS_DENIED;
    823         }
    824         if (dom->methods->remove_mapping == NULL) {
    825                 DEBUG(3, ("default domain not writable\n"));
    826                 return NT_STATUS_MEDIA_WRITE_PROTECTED;
    827         }
    828 
    829         return dom->methods->remove_mapping(dom, map);
    830 }
  • vendor/current/source3/winbindd/idmap_ad.c

    r414 r740  
    1010 * Copyright (C) Gerald (Jerry) Carter 2004-2007
    1111 * Copyright (C) Luke Howard 2001-2004
    12  * Copyright (C) Michael Adam 2008
     12 * Copyright (C) Michael Adam 2008,2010
    1313 *
    1414 * This program is free software; you can redistribute it and/or modify
     
    2828#include "includes.h"
    2929#include "winbindd.h"
     30#include "../libds/common/flags.h"
     31#include "ads.h"
     32#include "libads/ldap_schema.h"
     33#include "nss_info.h"
     34#include "secrets.h"
     35#include "idmap.h"
     36#include "../libcli/ldap/ldap_ndr.h"
     37#include "../libcli/security/security.h"
    3038
    3139#undef DBGC_CLASS
     
    4452
    4553struct idmap_ad_context {
    46         uint32_t filter_low_id;
    47         uint32_t filter_high_id;
    4854        ADS_STRUCT *ads;
    4955        struct posix_schema *ad_schema;
     
    95101                        ads_kdestroy(WINBIND_CCACHE_NAME);
    96102                        ctx->ads = NULL;
    97                         TALLOC_FREE( ctx->ad_schema );
    98103                }
    99104        }
     
    138143
    139144        get_dc_name(dom->name, realm, dc_name, &dc_ip );
    140        
     145
    141146        status = ads_connect(ads);
    142147        if (!ADS_ERR_OK(status)) {
    143                 DEBUG(1, ("ad_idmap_init: failed to connect to AD\n"));
     148                DEBUG(1, ("ad_idmap_cached_connection_internal: failed to "
     149                          "connect to AD\n"));
    144150                ads_destroy(&ads);
    145151                return status;
     
    181187             (ctx->ad_map_type ==  WB_POSIX_MAP_RFC2307) )
    182188        {
    183                 status = ads_check_posix_schema_mapping(NULL, ctx->ads, ctx->ad_map_type, &ctx->ad_schema);
     189                status = ads_check_posix_schema_mapping(
     190                        ctx, ctx->ads, ctx->ad_map_type, &ctx->ad_schema);
    184191                if ( !ADS_ERR_OK(status) ) {
    185192                        DEBUG(2,("ad_idmap_cached_connection: Failed to obtain schema details!\n"));
    186193                }
    187194        }
    188        
     195
    189196        return status;
     197}
     198
     199static int idmap_ad_context_destructor(struct idmap_ad_context *ctx)
     200{
     201        if (ctx->ads != NULL) {
     202                /* we own this ADS_STRUCT so make sure it goes away */
     203                ctx->ads->is_mine = True;
     204                ads_destroy( &ctx->ads );
     205                ctx->ads = NULL;
     206        }
     207        return 0;
    190208}
    191209
     
    193211 ***********************************************************************/
    194212
    195 static NTSTATUS idmap_ad_initialize(struct idmap_domain *dom,
    196                                     const char *params)
     213static NTSTATUS idmap_ad_initialize(struct idmap_domain *dom)
    197214{
    198215        struct idmap_ad_context *ctx;
    199216        char *config_option;
    200         const char *range = NULL;
    201217        const char *schema_mode = NULL;
    202218
    203         if ( (ctx = TALLOC_ZERO_P(dom, struct idmap_ad_context)) == NULL ) {
     219        ctx = TALLOC_ZERO_P(dom, struct idmap_ad_context);
     220        if (ctx == NULL) {
    204221                DEBUG(0, ("Out of memory!\n"));
    205222                return NT_STATUS_NO_MEMORY;
    206223        }
    207 
    208         if ( (config_option = talloc_asprintf(ctx, "idmap config %s", dom->name)) == NULL ) {
     224        talloc_set_destructor(ctx, idmap_ad_context_destructor);
     225
     226        config_option = talloc_asprintf(ctx, "idmap config %s", dom->name);
     227        if (config_option == NULL) {
    209228                DEBUG(0, ("Out of memory!\n"));
    210229                talloc_free(ctx);
    211230                return NT_STATUS_NO_MEMORY;
    212         }
    213 
    214         /* load ranges */
    215         range = lp_parm_const_string(-1, config_option, "range", NULL);
    216         if (range && range[0]) {
    217                 if ((sscanf(range, "%u - %u", &ctx->filter_low_id, &ctx->filter_high_id) != 2) ||
    218                     (ctx->filter_low_id > ctx->filter_high_id)) {
    219                         DEBUG(1, ("ERROR: invalid filter range [%s]", range));
    220                         ctx->filter_low_id = 0;
    221                         ctx->filter_high_id = 0;
    222                 }
    223231        }
    224232
     
    268276 ***********************************************************************/
    269277
    270 static struct id_map *find_map_by_sid(struct id_map **maps, DOM_SID *sid)
     278static struct id_map *find_map_by_sid(struct id_map **maps, struct dom_sid *sid)
    271279{
    272280        int i;
    273281
    274282        for (i = 0; maps[i] && i<IDMAP_AD_MAX_IDS; i++) {
    275                 if (sid_equal(maps[i]->sid, sid)) {
     283                if (dom_sid_equal(maps[i]->sid, sid)) {
    276284                        return maps[i];
    277285                }
     
    309317                ids[i]->status = ID_UNKNOWN;
    310318        }
    311        
     319
    312320        /* Only do query if we are online */
    313321        if (idmap_is_offline()) {
     
    352360                        CHECK_ALLOC_DONE(u_filter);
    353361                        break;
    354                                
     362
    355363                case ID_TYPE_GID:
    356364                        if ( ! g_filter) {
     
    401409        entry = res;
    402410        for (i = 0; (i < count) && entry; i++) {
    403                 DOM_SID sid;
     411                struct dom_sid sid;
    404412                enum id_type type;
    405413                struct id_map *map;
     
    454462                }
    455463
    456                 if ((id == 0) ||
    457                     (ctx->filter_low_id && (id < ctx->filter_low_id)) ||
    458                     (ctx->filter_high_id && (id > ctx->filter_high_id))) {
     464                if (!idmap_unix_id_is_in_range(id, dom)) {
    459465                        DEBUG(5, ("Requested id (%u) out of range (%u - %u). Filtered!\n",
    460                                 id, ctx->filter_low_id, ctx->filter_high_id));
     466                                id, dom->low_id, dom->high_id));
    461467                        continue;
    462468                }
     
    563569                                 ATYPE_NORMAL_ACCOUNT, ATYPE_WORKSTATION_TRUST, ATYPE_INTERDOMAIN_TRUST,
    564570                                 ATYPE_SECURITY_GLOBAL_GROUP, ATYPE_SECURITY_LOCAL_GROUP);
    565                
     571
    566572        CHECK_ALLOC_DONE(filter);
    567573
     
    571577                ids[idx]->status = ID_UNKNOWN;
    572578
    573                 sidstr = sid_binstring(talloc_tos(), ids[idx]->sid);
     579                sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), ids[idx]->sid);
    574580                filter = talloc_asprintf_append_buffer(filter, "(objectSid=%s)", sidstr);
    575                        
     581
    576582                TALLOC_FREE(sidstr);
    577583                CHECK_ALLOC_DONE(filter);
     
    594600        entry = res;   
    595601        for (i = 0; (i < count) && entry; i++) {
    596                 DOM_SID sid;
     602                struct dom_sid sid;
    597603                enum id_type type;
    598604                struct id_map *map;
     
    652658                        continue;
    653659                }
    654                 if ((id == 0) ||
    655                     (ctx->filter_low_id && (id < ctx->filter_low_id)) ||
    656                     (ctx->filter_high_id && (id > ctx->filter_high_id))) {
     660                if (!idmap_unix_id_is_in_range(id, dom)) {
    657661                        DEBUG(5, ("Requested id (%u) out of range (%u - %u). Filtered!\n",
    658                                 id, ctx->filter_low_id, ctx->filter_high_id));
     662                                id, dom->low_id, dom->high_id));
    659663                        continue;
    660664                }
     
    680684        ret = NT_STATUS_OK;
    681685
    682         /* mark all unknwoni/expired ones as unmapped */
     686        /* mark all unknown/expired ones as unmapped */
    683687        for (i = 0; ids[i]; i++) {
    684688                if (ids[i]->status != ID_MAPPED)
     
    689693        talloc_free(memctx);
    690694        return ret;
    691 }
    692 
    693 /************************************************************************
    694  ***********************************************************************/
    695 
    696 static NTSTATUS idmap_ad_close(struct idmap_domain *dom)
    697 {
    698         struct idmap_ad_context * ctx;
    699 
    700         ctx = talloc_get_type(dom->private_data, struct idmap_ad_context);
    701 
    702         if (ctx->ads != NULL) {
    703                 /* we own this ADS_STRUCT so make sure it goes away */
    704                 ctx->ads->is_mine = True;
    705                 ads_destroy( &ctx->ads );
    706                 ctx->ads = NULL;
    707         }
    708 
    709         TALLOC_FREE( ctx->ad_schema );
    710        
    711         return NT_STATUS_OK;
    712695}
    713696
     
    819802
    820803static NTSTATUS nss_ad_get_info( struct nss_domain_entry *e,
    821                                   const DOM_SID *sid,
     804                                  const struct dom_sid *sid,
    822805                                  TALLOC_CTX *mem_ctx,
    823                                   ADS_STRUCT *ads,
    824                                   LDAPMessage *msg,
    825806                                  const char **homedir,
    826807                                  const char **shell,
     
    866847        }
    867848
    868         /* See if we can use the ADS connection struct swe were given */
    869 
    870         if (ads) {
    871                 DEBUG(10, ("nss_ad_get_info: using given ads connection and "
    872                            "LDAP message (%p)\n", msg));
    873 
    874                 *homedir = ads_pull_string( ads, mem_ctx, msg, ctx->ad_schema->posix_homedir_attr );
    875                 *shell   = ads_pull_string( ads, mem_ctx, msg, ctx->ad_schema->posix_shell_attr );
    876                 *gecos   = ads_pull_string( ads, mem_ctx, msg, ctx->ad_schema->posix_gecos_attr );
    877 
    878                 if (gid) {
    879                         if ( !ads_pull_uint32(ads, msg, ctx->ad_schema->posix_gidnumber_attr, gid ) )
    880                                 *gid = (uint32)-1;
    881                 }
    882 
    883                 nt_status = NT_STATUS_OK;
    884                 goto done;
    885         }
    886 
    887849        /* Have to do our own query */
    888850
     
    895857        attrs[3] = ctx->ad_schema->posix_gidnumber_attr;
    896858
    897         sidstr = sid_binstring(mem_ctx, sid);
     859        sidstr = ldap_encode_ndr_dom_sid(mem_ctx, sid);
    898860        filter = talloc_asprintf(mem_ctx, "(objectSid=%s)", sidstr);
    899861        TALLOC_FREE(sidstr);
     
    10951057}
    10961058
    1097 
    1098 /************************************************************************
    1099  ***********************************************************************/
    1100 
    1101 static NTSTATUS nss_ad_close( void )
    1102 {
    1103         /* nothing to do.  All memory is free()'d by the idmap close_fn() */
    1104 
    1105         return NT_STATUS_OK;
    1106 }
    1107 
    11081059/************************************************************************
    11091060 Function dispatch tables for the idmap and nss plugins
     
    11141065        .unixids_to_sids = idmap_ad_unixids_to_sids,
    11151066        .sids_to_unixids = idmap_ad_sids_to_unixids,
    1116         .close_fn        = idmap_ad_close
    11171067};
    11181068
    11191069/* The SFU and RFC2307 NSS plugins share everything but the init
    11201070   function which sets the intended schema model to use */
    1121  
     1071
    11221072static struct nss_info_methods nss_rfc2307_methods = {
    11231073        .init           = nss_rfc2307_init,
     
    11251075        .map_to_alias   = nss_ad_map_to_alias,
    11261076        .map_from_alias = nss_ad_map_from_alias,
    1127         .close_fn       = nss_ad_close
    11281077};
    11291078
     
    11331082        .map_to_alias   = nss_ad_map_to_alias,
    11341083        .map_from_alias = nss_ad_map_from_alias,
    1135         .close_fn       = nss_ad_close
    11361084};
    11371085
     
    11411089        .map_to_alias   = nss_ad_map_to_alias,
    11421090        .map_from_alias = nss_ad_map_from_alias,
    1143         .close_fn       = nss_ad_close
    11441091};
    11451092
     
    11661113                        return status_idmap_ad;         
    11671114        }
    1168        
     1115
    11691116        if ( !NT_STATUS_IS_OK( status_nss_rfc2307 ) ) {
    11701117                status_nss_rfc2307 = smb_register_idmap_nss(SMB_NSS_INFO_INTERFACE_VERSION,
  • vendor/current/source3/winbindd/idmap_adex/cell_util.c

    r414 r740  
    2020
    2121#include "includes.h"
     22#include "ads.h"
     23#include "idmap.h"
    2224#include "idmap_adex.h"
     25#include "../libds/common/flags.h"
    2326
    2427#undef DBGC_CLASS
     
    139142        char *domain_dn = ads_build_dn(lp_realm());
    140143        NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
    141         DOM_SID sid;
     144        struct dom_sid sid;
    142145        struct likewise_cell *cell = NULL;
    143146
  • vendor/current/source3/winbindd/idmap_adex/domain_util.c

    r414 r740  
    2020
    2121#include "includes.h"
     22#include "ads.h"
     23#include "idmap.h"
    2224#include "idmap_adex.h"
    2325
     
    209211                            LDAPMessage **msg,
    210212                            const char *dn,
    211                             const DOM_SID *sid)
     213                            const struct dom_sid *sid)
    212214{
    213215        NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
  • vendor/current/source3/winbindd/idmap_adex/gc_util.c

    r414 r740  
    2020
    2121#include "includes.h"
     22#include "ads.h"
     23#include "idmap.h"
    2224#include "idmap_adex.h"
     25#include "libads/cldap.h"
     26#include "../libcli/ldap/ldap_ndr.h"
    2327
    2428#undef DBGC_CLASS
     
    546550 NTSTATUS gc_name_to_sid(const char *domain,
    547551                         const char *name,
    548                          DOM_SID *sid,
     552                         struct dom_sid *sid,
    549553                         enum lsa_SidType *sid_type)
    550554{
     
    704708 ********************************************************************/
    705709
    706  NTSTATUS gc_sid_to_name(const DOM_SID *sid,
     710 NTSTATUS gc_sid_to_name(const struct dom_sid *sid,
    707711                         char **name,
    708712                         enum lsa_SidType *sid_type)
     
    717721        *name = NULL;
    718722
    719         sid_string = sid_binstring(frame, sid);
     723        sid_string = ldap_encode_ndr_dom_sid(frame, sid);
    720724        BAIL_ON_PTR_ERROR(sid_string, nt_status);
    721725
  • vendor/current/source3/winbindd/idmap_adex/idmap_adex.c

    r414 r740  
    2020
    2121#include "includes.h"
     22#include "ads.h"
     23#include "idmap.h"
    2224#include "idmap_adex.h"
     25#include "nss_info.h"
     26#include "secrets.h"
    2327
    2428#undef DBGC_CLASS
     
    3943 *******************************************************************/
    4044
    41 static NTSTATUS _idmap_adex_init(struct idmap_domain *dom,
    42                                      const char *params)
     45static NTSTATUS _idmap_adex_init(struct idmap_domain *dom)
    4346{
    4447        ADS_STRUCT *ads = NULL;
    4548        ADS_STATUS status;
    4649        static NTSTATUS init_status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
    47         DOM_SID domain_sid;
     50        struct dom_sid domain_sid;
    4851        fstring dcname;
    4952        struct sockaddr_storage ip;
     
    165168        }
    166169       
    167         nt_status = _idmap_adex_init(dom, NULL);
     170        nt_status = _idmap_adex_init(dom);
    168171        if (!NT_STATUS_IS_OK(nt_status))
    169172                return nt_status;
     
    218221        }
    219222       
    220         nt_status = _idmap_adex_init(dom, NULL);
     223        nt_status = _idmap_adex_init(dom);
    221224        if (!NT_STATUS_IS_OK(nt_status))
    222225                return nt_status;
     
    251254}
    252255
    253 /**********************************************************************
    254  *********************************************************************/
    255 
    256 static NTSTATUS _idmap_adex_set_mapping(struct
    257                                             idmap_domain
    258                                             *dom, const struct
    259                                             id_map *map)
    260 {
    261         DEBUG(0, ("_idmap_adex_set_mapping: not implemented\n"));
    262         return NT_STATUS_NOT_IMPLEMENTED;
    263 }
    264 
    265 /**********************************************************************
    266  *********************************************************************/
    267 
    268 static NTSTATUS _idmap_adex_remove_mapping(struct
    269                                                idmap_domain
    270                                                *dom, const
    271                                                struct
    272                                                id_map
    273                                                *map)
    274 {
    275         DEBUG(0, ("_idmap_adex_remove_mapping: not implemented\n"));
    276         return NT_STATUS_NOT_IMPLEMENTED;
    277 }
    278 
    279 /**********************************************************************
    280  *********************************************************************/
    281 
    282 static NTSTATUS _idmap_adex_dump(struct idmap_domain
    283                                      *dom, struct id_map **maps, int *num_map)
    284 {
    285         return NT_STATUS_NOT_IMPLEMENTED;
    286 }
    287 
    288 /**********************************************************************
    289  *********************************************************************/
    290 
    291 static NTSTATUS _idmap_adex_close(struct idmap_domain
    292                                       *dom)
    293 {
    294         /* FIXME!  need to do cleanup here */
    295 
    296         return NT_STATUS_OK;
    297 }
    298 
    299256/*
    300257 * IdMap NSS plugin
     
    307264                                  *e)
    308265{
    309         return _idmap_adex_init(NULL, NULL);
     266        return _idmap_adex_init(NULL);
    310267}
    311268
     
    315272static NTSTATUS _nss_adex_get_info(struct
    316273                                      nss_domain_entry *e,
    317                                       const DOM_SID * sid,
     274                                      const struct dom_sid * sid,
    318275                                      TALLOC_CTX * ctx,
    319                                       ADS_STRUCT * ads,
    320                                       LDAPMessage * msg,
    321276                                      const char **homedir,
    322277                                      const char **shell,
     
    326281        struct likewise_cell *cell;
    327282
    328         nt_status = _idmap_adex_init(NULL, NULL);
     283        nt_status = _idmap_adex_init(NULL);
    329284        if (!NT_STATUS_IS_OK(nt_status))
    330285                return nt_status;
     
    348303        struct likewise_cell *cell = NULL;
    349304
    350         nt_status = _idmap_adex_init(NULL, NULL);
     305        nt_status = _idmap_adex_init(NULL);
    351306        BAIL_ON_NTSTATUS_ERROR(nt_status);
    352307
     
    379334        struct likewise_cell *cell = NULL;
    380335
    381         nt_status = _idmap_adex_init(NULL, NULL);
     336        nt_status = _idmap_adex_init(NULL);
    382337        BAIL_ON_NTSTATUS_ERROR(nt_status);
    383338
     
    417372        .unixids_to_sids  = _idmap_adex_get_sid_from_id,
    418373        .sids_to_unixids  = _idmap_adex_get_id_from_sid,
    419         .set_mapping      = _idmap_adex_set_mapping,
    420         .remove_mapping   = _idmap_adex_remove_mapping,
    421         .dump_data        = _idmap_adex_dump,
    422         .close_fn         = _idmap_adex_close
    423374};
    424375static struct nss_info_methods adex_nss_methods = {
     
    465416        return NT_STATUS_OK;
    466417}
    467 
    468 static NTSTATUS nss_info_adex_init(void)
    469 {
    470         return idmap_adex_init();
    471 }
  • vendor/current/source3/winbindd/idmap_adex/idmap_adex.h

    r414 r740  
    9292
    9393struct cell_provider_api {
    94         NTSTATUS(*get_sid_from_id) (DOM_SID * sid,
     94        NTSTATUS(*get_sid_from_id) (struct dom_sid * sid,
    9595                                    uint32_t id, enum id_type type);
    9696        NTSTATUS(*get_id_from_sid) (uint32_t * id,
    97                                     enum id_type * type, const DOM_SID * sid);
    98         NTSTATUS(*get_nss_info) (const DOM_SID * sid,
     97                                    enum id_type * type, const struct dom_sid * sid);
     98        NTSTATUS(*get_nss_info) (const struct dom_sid * sid,
    9999                                 TALLOC_CTX * ctx,
    100100                                 const char **homedir,
     
    123123        ADS_STRUCT *conn;
    124124        struct likewise_cell *gc_search_cell;
    125         DOM_SID domain_sid;
     125        struct dom_sid domain_sid;
    126126        char *dns_domain;
    127127        char *forest_name;
     
    158158NTSTATUS cell_locate_membership(ADS_STRUCT * ads);
    159159NTSTATUS cell_lookup_settings(struct likewise_cell * cell);
    160 NTSTATUS cell_follow_links(struct likewise_cell *cell);
    161 NTSTATUS cell_set_local_provider(void);
    162160
    163161/* likewise_cell.c */
     
    171169void cell_list_destroy(void);
    172170void cell_destroy(struct likewise_cell *c);
    173 void cell_set_forest_searches(struct likewise_cell *c,
    174                                 bool search);
    175171void cell_set_dns_domain(struct likewise_cell *c,
    176172                           const char *dns_domain);
     
    180176                   const char *dn);
    181177void cell_set_domain_sid(struct likewise_cell *c,
    182                            DOM_SID *sid);
     178                           struct dom_sid *sid);
    183179void cell_set_flags(struct likewise_cell *c, uint32_t flags);
    184180void cell_clear_flags(struct likewise_cell *c, uint32_t flags);
     
    225221NTSTATUS gc_name_to_sid(const char *domain,
    226222                        const char *name,
    227                         DOM_SID *sid,
     223                        struct dom_sid *sid,
    228224                        enum lsa_SidType *sid_type);
    229225
    230 NTSTATUS gc_sid_to_name(const DOM_SID *sid,
     226NTSTATUS gc_sid_to_name(const struct dom_sid *sid,
    231227                        char **name,
    232228                        enum lsa_SidType *sid_type);
     
    253249                           LDAPMessage **msg,
    254250                           const char *dn,
    255                            const DOM_SID *user_sid);
     251                           const struct dom_sid *user_sid);
    256252
    257253
  • vendor/current/source3/winbindd/idmap_adex/likewise_cell.c

    r414 r740  
    2020
    2121#include "includes.h"
     22#include "ads.h"
     23#include "idmap.h"
    2224#include "idmap_adex.h"
     25#include "secrets.h"
     26#include "../libcli/security/dom_sid.h"
    2327
    2428#undef DBGC_CLASS
     
    177181 *********************************************************************/
    178182
    179  void cell_set_domain_sid(struct likewise_cell *c, DOM_SID *sid)
     183 void cell_set_domain_sid(struct likewise_cell *c, struct dom_sid *sid)
    180184{
    181185        sid_copy(&c->domain_sid, sid);
  • vendor/current/source3/winbindd/idmap_adex/provider_unified.c

    r414 r740  
    2222
    2323#include "includes.h"
     24#include "ads.h"
     25#include "idmap.h"
    2426#include "idmap_adex.h"
     27#include "../libcli/ldap/ldap_ndr.h"
     28#include "../libcli/security/dom_sid.h"
    2529
    2630#undef DBGC_CLASS
     
    3640        bool use2307;
    3741        union {
    38                 DOM_SID sid;
     42                struct dom_sid sid;
    3943                struct {
    4044                        uint32_t id;
     
    246250                              LDAPMessage **msg,
    247251                              const char *dn,
    248                               const DOM_SID *sid)
     252                              const struct dom_sid *sid)
    249253{
    250254        NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
     
    342346                                           int num_resp,
    343347                                           char **dn,
    344                                            DOM_SID *user_sid)
     348                                           struct dom_sid *user_sid)
    345349{
    346350        NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
     
    466470        int num_resp = 0;
    467471        LDAPMessage *m;
    468         DOM_SID user_sid;
     472        struct dom_sid user_sid;
    469473        struct likewise_cell *domain_cell = NULL;
    470474
     
    484488                switch (fdata->ftype) {
    485489                case SidFilter:
    486                         sid_binstr = sid_binstring(frame, &fdata->filter.sid);
     490                        sid_binstr = ldap_encode_ndr_dom_sid(frame, &fdata->filter.sid);
    487491                        BAIL_ON_PTR_ERROR(sid_binstr, nt_status);
    488492
     
    612616static NTSTATUS pull_sid(struct likewise_cell *c,
    613617                         LDAPMessage *msg,
    614                          DOM_SID *sid)
     618                         struct dom_sid *sid)
    615619{
    616620        NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
     
    968972 *******************************************************************/
    969973
    970 static NTSTATUS _ccp_get_sid_from_id(DOM_SID * sid,
     974static NTSTATUS _ccp_get_sid_from_id(struct dom_sid * sid,
    971975                                     uint32_t id, enum id_type type)
    972976{
     
    9971001static NTSTATUS _ccp_get_id_from_sid(uint32_t * id,
    9981002                                     enum id_type *type,
    999                                      const DOM_SID * sid)
     1003                                     const struct dom_sid * sid)
    10001004{
    10011005        struct likewise_cell *cell = NULL;
     
    10271031 *******************************************************************/
    10281032
    1029 static NTSTATUS _ccp_nss_get_info(const DOM_SID * sid,
     1033static NTSTATUS _ccp_nss_get_info(const struct dom_sid * sid,
    10301034                                  TALLOC_CTX * ctx,
    10311035                                  const char **homedir,
     
    10721076        TALLOC_CTX *frame = talloc_stackframe();
    10731077        NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
    1074         DOM_SID sid;
     1078        struct dom_sid sid;
    10751079        struct likewise_cell *cell = NULL;
    10761080        LDAPMessage *msg = NULL;
     
    11171121        TALLOC_CTX *frame = talloc_stackframe();
    11181122        NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
    1119         DOM_SID sid;
     1123        struct dom_sid sid;
    11201124        struct likewise_cell *cell_alias = NULL;
    11211125        LDAPMessage *msg_alias = NULL;
  • vendor/current/source3/winbindd/idmap_hash/idmap_hash.c

    r414 r740  
    2121#include "includes.h"
    2222#include "winbindd/winbindd.h"
     23#include "idmap.h"
    2324#include "idmap_hash.h"
     25#include "ads.h"
     26#include "nss_info.h"
     27#include "../libcli/security/dom_sid.h"
    2428
    2529#undef DBGC_CLASS
     
    2731
    2832struct sid_hash_table {
    29         DOM_SID *sid;
     33        struct dom_sid *sid;
    3034};
    3135
    32 struct sid_hash_table *hashed_domains = NULL;
    33 
    3436/*********************************************************************
    3537 Hash a domain SID (S-1-5-12-aaa-bbb-ccc) to a 12bit number
    3638 ********************************************************************/
    3739
    38 static uint32_t hash_domain_sid(const DOM_SID *sid)
     40static uint32_t hash_domain_sid(const struct dom_sid *sid)
    3941{
    4042        uint32_t hash;
     
    103105 ********************************************************************/
    104106
    105 static NTSTATUS be_init(struct idmap_domain *dom,
    106                         const char *params)
    107 {
     107static NTSTATUS be_init(struct idmap_domain *dom)
     108{
     109        struct sid_hash_table *hashed_domains;
    108110        NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
    109111        struct winbindd_tdc_domain *dom_list = NULL;
     
    111113        int i;
    112114
    113         /* If the domain SID hash talbe has been initialized, assume
     115        /* If the domain SID hash table has been initialized, assume
    114116           that we completed this function previously */
    115117
    116         if ( hashed_domains ) {
     118        if (dom->private_data != NULL) {
    117119                nt_status = NT_STATUS_OK;
    118120                goto done;
     
    126128        /* Create the hash table of domain SIDs */
    127129
    128         hashed_domains = TALLOC_ZERO_ARRAY(NULL, struct sid_hash_table, 4096);
     130        hashed_domains = TALLOC_ZERO_ARRAY(dom, struct sid_hash_table, 4096);
    129131        BAIL_ON_PTR_NT_ERROR(hashed_domains, nt_status);
    130132
     
    144146                         hash));
    145147
    146                 hashed_domains[hash].sid = talloc(hashed_domains, DOM_SID);
     148                hashed_domains[hash].sid = talloc(hashed_domains, struct dom_sid);
    147149                sid_copy(hashed_domains[hash].sid, &dom_list[i].sid);
    148150        }
     151
     152        dom->private_data = hashed_domains;
    149153
    150154done:
     
    158162                                struct id_map **ids)
    159163{
     164        struct sid_hash_table *hashed_domains = talloc_get_type_abort(
     165                dom->private_data, struct sid_hash_table);
    160166        NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
    161167        int i;
     
    165171                ids[i]->status = ID_UNKNOWN;
    166172        }
    167        
    168         nt_status = be_init(dom, NULL);
     173
     174        nt_status = be_init(dom);
    169175        BAIL_ON_NTSTATUS_ERROR(nt_status);
    170176
     
    194200                        continue;
    195201
    196                 sid_copy(ids[i]->sid, hashed_domains[h_domain].sid);
    197                 sid_append_rid(ids[i]->sid, h_rid);
     202                sid_compose(ids[i]->sid, hashed_domains[h_domain].sid, h_rid);
    198203                ids[i]->status = ID_MAPPED;
    199204        }
     
    216221                ids[i]->status = ID_UNKNOWN;
    217222        }
    218        
    219         nt_status = be_init(dom, NULL);
     223
     224        nt_status = be_init(dom);
    220225        BAIL_ON_NTSTATUS_ERROR(nt_status);
    221226
     
    226231
    227232        for (i=0; ids[i]; i++) {
    228                 DOM_SID sid;
     233                struct dom_sid sid;
    229234                uint32_t rid;
    230235                uint32_t h_domain, h_rid;
     
    253258 ********************************************************************/
    254259
    255 static NTSTATUS be_close(struct idmap_domain *dom)
    256 {
    257         if (hashed_domains)
    258                 talloc_free(hashed_domains);
    259 
    260         return NT_STATUS_OK;
    261 }
    262 
    263 /*********************************************************************
    264  ********************************************************************/
    265 
    266260static NTSTATUS nss_hash_init(struct nss_domain_entry *e )
    267261{
    268         return be_init(NULL, NULL);
     262        return be_init(NULL);
    269263}
    270264
     
    273267
    274268static NTSTATUS nss_hash_get_info(struct nss_domain_entry *e,
    275                                     const DOM_SID *sid,
     269                                    const struct dom_sid *sid,
    276270                                    TALLOC_CTX *ctx,
    277                                     ADS_STRUCT *ads,
    278                                     LDAPMessage *msg,
    279271                                    const char **homedir,
    280272                                    const char **shell,
     
    359351        .unixids_to_sids = unixids_to_sids,
    360352        .sids_to_unixids = sids_to_unixids,
    361         .close_fn        = be_close
    362353};
    363354
  • vendor/current/source3/winbindd/idmap_hash/mapfile.c

    r414 r740  
    2020
    2121#include "includes.h"
     22#include "system/filesys.h"
    2223#include "winbindd/winbindd.h"
     24#include "idmap.h"
    2325#include "idmap_hash.h"
    2426#include <stdio.h>
  • vendor/current/source3/winbindd/idmap_ldap.c

    r414 r740  
    88   Copyright (C) Gerald Carter          2003
    99   Copyright (C) Simo Sorce             2003-2007
     10   Copyright (C) Michael Adam           2010
    1011
    1112   This program is free software; you can redistribute it and/or modify
     
    2526#include "includes.h"
    2627#include "winbindd.h"
     28#include "secrets.h"
     29#include "idmap.h"
     30#include "idmap_rw.h"
     31#include "../libcli/security/security.h"
    2732
    2833#undef DBGC_CLASS
     
    3439#include "smbldap.h"
    3540
    36 static char *idmap_fetch_secret(const char *backend, bool alloc,
     41static char *idmap_fetch_secret(const char *backend,
    3742                                const char *domain, const char *identity)
    3843{
     
    4045        int r;
    4146
    42         if (alloc) {
    43                 r = asprintf(&tmp, "IDMAP_ALLOC_%s", backend);
    44         } else {
    45                 r = asprintf(&tmp, "IDMAP_%s_%s", backend, domain);
    46         }
     47        r = asprintf(&tmp, "IDMAP_%s_%s", backend, domain);
    4748
    4849        if (r < 0)
     
    6263        char *suffix;
    6364        char *user_dn;
    64         uint32_t filter_low_id, filter_high_id;         /* Filter range */
    6565        bool anon;
    66 };
    67 
    68 struct idmap_ldap_alloc_context {
    69         struct smbldap_state *smbldap_state;
    70         char *url;
    71         char *suffix;
    72         char *user_dn;
    73         uid_t low_uid, high_uid;      /* Range of uids */
    74         gid_t low_gid, high_gid;      /* Range of gids */
    75 
     66        struct idmap_rw_ops *rw_ops;
    7667};
    7768
     
    8778**********************************************************************/
    8879
    89 static struct idmap_ldap_alloc_context *idmap_alloc_ldap;
    90 
    9180/*********************************************************************
    9281 ********************************************************************/
     
    11099        if ( tmp ) {
    111100                if (!dom) {
    112                         /* only the alloc backend can pass in a NULL dom */
    113                         secret = idmap_fetch_secret("ldap", True,
    114                                                     NULL, tmp);
     101                        DEBUG(0, ("get_credentials: Invalid domain 'NULL' "
     102                                  "encountered for user DN %s\n",
     103                                  tmp));
     104                        ret = NT_STATUS_UNSUCCESSFUL;
     105                        goto done;
    115106                } else {
    116                         secret = idmap_fetch_secret("ldap", False,
    117                                                     dom->name, tmp);
     107                        secret = idmap_fetch_secret("ldap", dom->name, tmp);
    118108                }
    119109
     
    154144**********************************************************************/
    155145
    156 static NTSTATUS verify_idpool(void)
     146static NTSTATUS verify_idpool(struct idmap_domain *dom)
    157147{
    158148        NTSTATUS ret;
    159         TALLOC_CTX *ctx;
     149        TALLOC_CTX *mem_ctx;
    160150        LDAPMessage *result = NULL;
    161151        LDAPMod **mods = NULL;
     
    164154        int count;
    165155        int rc;
    166 
    167         if ( ! idmap_alloc_ldap) {
    168                 return NT_STATUS_UNSUCCESSFUL;
    169         }
    170 
    171         ctx = talloc_new(idmap_alloc_ldap);
    172         if ( ! ctx) {
     156        struct idmap_ldap_context *ctx;
     157
     158        ctx = talloc_get_type(dom->private_data, struct idmap_ldap_context);
     159
     160        mem_ctx = talloc_new(ctx);
     161        if (mem_ctx == NULL) {
    173162                DEBUG(0, ("Out of memory!\n"));
    174163                return NT_STATUS_NO_MEMORY;
    175164        }
    176165
    177         filter = talloc_asprintf(ctx, "(objectclass=%s)", LDAP_OBJ_IDPOOL);
     166        filter = talloc_asprintf(mem_ctx, "(objectclass=%s)", LDAP_OBJ_IDPOOL);
    178167        CHECK_ALLOC_DONE(filter);
    179168
    180         attr_list = get_attr_list(ctx, idpool_attr_list);
     169        attr_list = get_attr_list(mem_ctx, idpool_attr_list);
    181170        CHECK_ALLOC_DONE(attr_list);
    182171
    183         rc = smbldap_search(idmap_alloc_ldap->smbldap_state,
    184                                 idmap_alloc_ldap->suffix,
     172        rc = smbldap_search(ctx->smbldap_state,
     173                                ctx->suffix,
    185174                                LDAP_SCOPE_SUBTREE,
    186175                                filter,
     
    195184        }
    196185
    197         count = ldap_count_entries(idmap_alloc_ldap->smbldap_state->ldap_struct,
    198                                    result);
     186        count = ldap_count_entries(ctx->smbldap_state->ldap_struct, result);
    199187
    200188        ldap_msgfree(result);
     
    202190        if ( count > 1 ) {
    203191                DEBUG(0,("Multiple entries returned from %s (base == %s)\n",
    204                         filter, idmap_alloc_ldap->suffix));
     192                        filter, ctx->suffix));
    205193                ret = NT_STATUS_UNSUCCESSFUL;
    206194                goto done;
     
    209197                char *uid_str, *gid_str;
    210198
    211                 uid_str = talloc_asprintf(ctx, "%lu",
    212                                 (unsigned long)idmap_alloc_ldap->low_uid);
    213                 gid_str = talloc_asprintf(ctx, "%lu",
    214                                 (unsigned long)idmap_alloc_ldap->low_gid);
     199                uid_str = talloc_asprintf(mem_ctx, "%lu",
     200                                (unsigned long)dom->low_id);
     201                gid_str = talloc_asprintf(mem_ctx, "%lu",
     202                                (unsigned long)dom->low_id);
    215203
    216204                smbldap_set_mod(&mods, LDAP_MOD_ADD,
     
    225213                                gid_str);
    226214                if (mods) {
    227                         rc = smbldap_modify(idmap_alloc_ldap->smbldap_state,
    228                                                 idmap_alloc_ldap->suffix,
     215                        rc = smbldap_modify(ctx->smbldap_state,
     216                                                ctx->suffix,
    229217                                                mods);
    230218                        ldap_mods_free(mods, True);
     
    237225        ret = (rc == LDAP_SUCCESS)?NT_STATUS_OK:NT_STATUS_UNSUCCESSFUL;
    238226done:
    239         talloc_free(ctx);
    240         return ret;
    241 }
    242 
    243 /*****************************************************************************
    244  Initialise idmap database.
    245 *****************************************************************************/
    246 
    247 static NTSTATUS idmap_ldap_alloc_init(const char *params)
    248 {
    249         NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
    250         const char *tmp;
    251         uid_t low_uid = 0;
    252         uid_t high_uid = 0;
    253         gid_t low_gid = 0;
    254         gid_t high_gid = 0;
    255 
    256         /* Only do init if we are online */
    257         if (idmap_is_offline()) {
    258                 return NT_STATUS_FILE_IS_OFFLINE;
    259         }
    260 
    261         idmap_alloc_ldap = TALLOC_ZERO_P(NULL, struct idmap_ldap_alloc_context);
    262         CHECK_ALLOC_DONE( idmap_alloc_ldap );
    263 
    264         /* load ranges */
    265 
    266         if (!lp_idmap_uid(&low_uid, &high_uid)
    267             || !lp_idmap_gid(&low_gid, &high_gid)) {
    268                 DEBUG(1, ("idmap uid or idmap gid missing\n"));
    269                 ret = NT_STATUS_UNSUCCESSFUL;
    270                 goto done;
    271         }
    272 
    273         idmap_alloc_ldap->low_uid = low_uid;
    274         idmap_alloc_ldap->high_uid = high_uid;
    275         idmap_alloc_ldap->low_gid = low_gid;
    276         idmap_alloc_ldap->high_gid= high_gid;
    277 
    278         if (idmap_alloc_ldap->high_uid <= idmap_alloc_ldap->low_uid) {
    279                 DEBUG(1, ("idmap uid range invalid\n"));
    280                 DEBUGADD(1, ("idmap will be unable to map foreign SIDs\n"));
    281                 ret = NT_STATUS_UNSUCCESSFUL;
    282                 goto done;
    283         }
    284 
    285         if (idmap_alloc_ldap->high_gid <= idmap_alloc_ldap->low_gid) {
    286                 DEBUG(1, ("idmap gid range invalid\n"));
    287                 DEBUGADD(1, ("idmap will be unable to map foreign SIDs\n"));
    288                 ret = NT_STATUS_UNSUCCESSFUL;
    289                 goto done;
    290         }
    291 
    292         if (params && *params) {
    293                 /* assume location is the only parameter */
    294                 idmap_alloc_ldap->url = talloc_strdup(idmap_alloc_ldap, params);
    295         } else {
    296                 tmp = lp_parm_const_string(-1, "idmap alloc config",
    297                                            "ldap_url", NULL);
    298 
    299                 if ( ! tmp) {
    300                         DEBUG(1, ("ERROR: missing idmap ldap url\n"));
    301                         ret = NT_STATUS_UNSUCCESSFUL;
    302                         goto done;
    303                 }
    304 
    305                 idmap_alloc_ldap->url = talloc_strdup(idmap_alloc_ldap, tmp);
    306         }
    307         CHECK_ALLOC_DONE( idmap_alloc_ldap->url );
    308 
    309         trim_char(idmap_alloc_ldap->url, '\"', '\"');
    310 
    311         tmp = lp_parm_const_string(-1, "idmap alloc config",
    312                                    "ldap_base_dn", NULL);
    313         if ( ! tmp || ! *tmp) {
    314                 tmp = lp_ldap_idmap_suffix();
    315                 if ( ! tmp) {
    316                         DEBUG(1, ("ERROR: missing idmap ldap suffix\n"));
    317                         ret = NT_STATUS_UNSUCCESSFUL;
    318                         goto done;
    319                 }
    320         }
    321 
    322         idmap_alloc_ldap->suffix = talloc_strdup(idmap_alloc_ldap, tmp);
    323         CHECK_ALLOC_DONE( idmap_alloc_ldap->suffix );
    324 
    325         ret = smbldap_init(idmap_alloc_ldap, winbind_event_context(),
    326                            idmap_alloc_ldap->url,
    327                            &idmap_alloc_ldap->smbldap_state);
    328         if (!NT_STATUS_IS_OK(ret)) {
    329                 DEBUG(1, ("ERROR: smbldap_init (%s) failed!\n",
    330                           idmap_alloc_ldap->url));
    331                 goto done;
    332         }
    333 
    334         ret = get_credentials( idmap_alloc_ldap,
    335                                idmap_alloc_ldap->smbldap_state,
    336                                "idmap alloc config", NULL,
    337                                &idmap_alloc_ldap->user_dn );
    338         if ( !NT_STATUS_IS_OK(ret) ) {
    339                 DEBUG(1,("idmap_ldap_alloc_init: Failed to get connection "
    340                          "credentials (%s)\n", nt_errstr(ret)));
    341                 goto done;
    342         }
    343 
    344         /* see if the idmap suffix and sub entries exists */
    345 
    346         ret = verify_idpool();
    347 
    348  done:
    349         if ( !NT_STATUS_IS_OK( ret ) )
    350                 TALLOC_FREE( idmap_alloc_ldap );
    351 
     227        talloc_free(mem_ctx);
    352228        return ret;
    353229}
     
    357233********************************/
    358234
    359 static NTSTATUS idmap_ldap_allocate_id(struct unixid *xid)
    360 {
    361         TALLOC_CTX *ctx;
     235static NTSTATUS idmap_ldap_allocate_id_internal(struct idmap_domain *dom,
     236                                                struct unixid *xid)
     237{
     238        TALLOC_CTX *mem_ctx;
    362239        NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
    363240        int rc = LDAP_SERVER_DOWN;
     
    372249        const char **attr_list;
    373250        const char *type;
     251        struct idmap_ldap_context *ctx;
    374252
    375253        /* Only do query if we are online */
     
    378256        }
    379257
    380         if ( ! idmap_alloc_ldap) {
    381                 return NT_STATUS_UNSUCCESSFUL;
    382         }
    383 
    384         ctx = talloc_new(idmap_alloc_ldap);
    385         if ( ! ctx) {
     258        ctx = talloc_get_type(dom->private_data, struct idmap_ldap_context);
     259
     260        mem_ctx = talloc_new(ctx);
     261        if (!mem_ctx) {
    386262                DEBUG(0, ("Out of memory!\n"));
    387263                return NT_STATUS_NO_MEMORY;
     
    406282        }
    407283
    408         filter = talloc_asprintf(ctx, "(objectClass=%s)", LDAP_OBJ_IDPOOL);
     284        filter = talloc_asprintf(mem_ctx, "(objectClass=%s)", LDAP_OBJ_IDPOOL);
    409285        CHECK_ALLOC_DONE(filter);
    410286
    411         attr_list = get_attr_list(ctx, idpool_attr_list);
     287        attr_list = get_attr_list(mem_ctx, idpool_attr_list);
    412288        CHECK_ALLOC_DONE(attr_list);
    413289
    414290        DEBUG(10, ("Search of the id pool (filter: %s)\n", filter));
    415291
    416         rc = smbldap_search(idmap_alloc_ldap->smbldap_state,
    417                                 idmap_alloc_ldap->suffix,
    418                                LDAP_SCOPE_SUBTREE, filter,
    419                                attr_list, 0, &result);
     292        rc = smbldap_search(ctx->smbldap_state,
     293                           ctx->suffix,
     294                           LDAP_SCOPE_SUBTREE, filter,
     295                           attr_list, 0, &result);
    420296
    421297        if (rc != LDAP_SUCCESS) {
     
    424300        }
    425301
    426         talloc_autofree_ldapmsg(ctx, result);
    427 
    428         count = ldap_count_entries(idmap_alloc_ldap->smbldap_state->ldap_struct,
    429                                    result);
     302        talloc_autofree_ldapmsg(mem_ctx, result);
     303
     304        count = ldap_count_entries(ctx->smbldap_state->ldap_struct, result);
    430305        if (count != 1) {
    431306                DEBUG(0,("Single %s object not found\n", LDAP_OBJ_IDPOOL));
     
    433308        }
    434309
    435         entry = ldap_first_entry(idmap_alloc_ldap->smbldap_state->ldap_struct,
    436                                  result);
    437 
    438         dn = smbldap_talloc_dn(ctx,
    439                                idmap_alloc_ldap->smbldap_state->ldap_struct,
     310        entry = ldap_first_entry(ctx->smbldap_state->ldap_struct, result);
     311
     312        dn = smbldap_talloc_dn(mem_ctx,
     313                               ctx->smbldap_state->ldap_struct,
    440314                               entry);
    441315        if ( ! dn) {
     
    443317        }
    444318
    445         if ( ! (id_str = smbldap_talloc_single_attribute(idmap_alloc_ldap->smbldap_state->ldap_struct,
    446                                 entry, type, ctx))) {
     319        id_str = smbldap_talloc_single_attribute(
     320                                ctx->smbldap_state->ldap_struct,
     321                                entry, type, mem_ctx);
     322        if (id_str == NULL) {
    447323                DEBUG(0,("%s attribute not found\n", type));
    448                 goto done;
    449         }
    450         if ( ! id_str) {
    451                 DEBUG(0,("Out of memory\n"));
    452                 ret = NT_STATUS_NO_MEMORY;
     324                ret = NT_STATUS_UNSUCCESSFUL;
    453325                goto done;
    454326        }
     
    460332        switch (xid->type) {
    461333        case ID_TYPE_UID:
    462                 if (xid->id > idmap_alloc_ldap->high_uid) {
     334                if (xid->id > dom->high_id) {
    463335                        DEBUG(0,("Cannot allocate uid above %lu!\n",
    464                                  (unsigned long)idmap_alloc_ldap->high_uid));
     336                                 (unsigned long)dom->high_id));
    465337                        goto done;
    466338                }
     
    468340
    469341        case ID_TYPE_GID:
    470                 if (xid->id > idmap_alloc_ldap->high_gid) {
     342                if (xid->id > dom->high_id) {
    471343                        DEBUG(0,("Cannot allocate gid above %lu!\n",
    472                                  (unsigned long)idmap_alloc_ldap->high_uid));
     344                                 (unsigned long)dom->high_id));
    473345                        goto done;
    474346                }
     
    480352        }
    481353
    482         new_id_str = talloc_asprintf(ctx, "%lu", (unsigned long)xid->id + 1);
     354        new_id_str = talloc_asprintf(mem_ctx, "%lu", (unsigned long)xid->id + 1);
    483355        if ( ! new_id_str) {
    484356                DEBUG(0,("Out of memory\n"));
     
    498370                   id_str, new_id_str));
    499371
    500         rc = smbldap_modify(idmap_alloc_ldap->smbldap_state, dn, mods);
     372        rc = smbldap_modify(ctx->smbldap_state, dn, mods);
    501373
    502374        ldap_mods_free(mods, True);
     
    511383
    512384done:
    513         talloc_free(ctx);
     385        talloc_free(mem_ctx);
    514386        return ret;
    515387}
    516388
    517 /**********************************
    518  Get current highest id.
    519 **********************************/
    520 
    521 static NTSTATUS idmap_ldap_get_hwm(struct unixid *xid)
    522 {
    523         TALLOC_CTX *memctx;
    524         NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
    525         int rc = LDAP_SERVER_DOWN;
    526         int count = 0;
    527         LDAPMessage *result = NULL;
    528         LDAPMessage *entry = NULL;
    529         char *id_str;
    530         char *filter = NULL;
    531         const char **attr_list;
    532         const char *type;
    533 
    534         /* Only do query if we are online */
    535         if (idmap_is_offline()) {
    536                 return NT_STATUS_FILE_IS_OFFLINE;
    537         }
    538 
    539         if ( ! idmap_alloc_ldap) {
    540                 return NT_STATUS_UNSUCCESSFUL;
    541         }
    542 
    543         memctx = talloc_new(idmap_alloc_ldap);
    544         if ( ! memctx) {
    545                 DEBUG(0, ("Out of memory!\n"));
    546                 return NT_STATUS_NO_MEMORY;
    547         }
    548 
    549         /* get type */
    550         switch (xid->type) {
    551 
    552         case ID_TYPE_UID:
    553                 type = get_attr_key2string(idpool_attr_list,
    554                                            LDAP_ATTR_UIDNUMBER);
    555                 break;
    556 
    557         case ID_TYPE_GID:
    558                 type = get_attr_key2string(idpool_attr_list,
    559                                            LDAP_ATTR_GIDNUMBER);
    560                 break;
    561 
    562         default:
    563                 DEBUG(2, ("Invalid ID type (0x%x)\n", xid->type));
    564                 return NT_STATUS_INVALID_PARAMETER;
    565         }
    566 
    567         filter = talloc_asprintf(memctx, "(objectClass=%s)", LDAP_OBJ_IDPOOL);
    568         CHECK_ALLOC_DONE(filter);
    569 
    570         attr_list = get_attr_list(memctx, idpool_attr_list);
    571         CHECK_ALLOC_DONE(attr_list);
    572 
    573         rc = smbldap_search(idmap_alloc_ldap->smbldap_state,
    574                                 idmap_alloc_ldap->suffix,
    575                                LDAP_SCOPE_SUBTREE, filter,
    576                                attr_list, 0, &result);
    577 
    578         if (rc != LDAP_SUCCESS) {
    579                 DEBUG(0,("%s object not found\n", LDAP_OBJ_IDPOOL));
    580                 goto done;
    581         }
    582 
    583         talloc_autofree_ldapmsg(memctx, result);
    584 
    585         count = ldap_count_entries(idmap_alloc_ldap->smbldap_state->ldap_struct,
    586                                    result);
    587         if (count != 1) {
    588                 DEBUG(0,("Single %s object not found\n", LDAP_OBJ_IDPOOL));
    589                 goto done;
    590         }
    591 
    592         entry = ldap_first_entry(idmap_alloc_ldap->smbldap_state->ldap_struct,
    593                                  result);
    594 
    595         id_str = smbldap_talloc_single_attribute(idmap_alloc_ldap->smbldap_state->ldap_struct,
    596                         entry, type, memctx);
    597         if ( ! id_str) {
    598                 DEBUG(0,("%s attribute not found\n", type));
    599                 goto done;
    600         }
    601         if ( ! id_str) {
    602                 DEBUG(0,("Out of memory\n"));
    603                 ret = NT_STATUS_NO_MEMORY;
    604                 goto done;
    605         }
    606 
    607         xid->id = strtoul(id_str, NULL, 10);
    608 
    609         ret = NT_STATUS_OK;
    610 done:
    611         talloc_free(memctx);
     389/**
     390 * Allocate a new unix-ID.
     391 * For now this is for the default idmap domain only.
     392 * Should be extended later on.
     393 */
     394static NTSTATUS idmap_ldap_allocate_id(struct idmap_domain *dom,
     395                                       struct unixid *id)
     396{
     397        NTSTATUS ret;
     398
     399        if (!strequal(dom->name, "*")) {
     400                DEBUG(3, ("idmap_ldap_allocate_id: "
     401                          "Refusing allocation of a new unixid for domain'%s'. "
     402                          "This is only supported for the default "
     403                          "domain \"*\".\n",
     404                           dom->name));
     405                return NT_STATUS_NOT_IMPLEMENTED;
     406        }
     407
     408        ret = idmap_ldap_allocate_id_internal(dom, id);
     409
    612410        return ret;
    613 }
    614 /**********************************
    615  Set highest id.
    616 **********************************/
    617 
    618 static NTSTATUS idmap_ldap_set_hwm(struct unixid *xid)
    619 {
    620         TALLOC_CTX *ctx;
    621         NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
    622         int rc = LDAP_SERVER_DOWN;
    623         int count = 0;
    624         LDAPMessage *result = NULL;
    625         LDAPMessage *entry = NULL;
    626         LDAPMod **mods = NULL;
    627         char *new_id_str;
    628         char *filter = NULL;
    629         const char *dn = NULL;
    630         const char **attr_list;
    631         const char *type;
    632 
    633         /* Only do query if we are online */
    634         if (idmap_is_offline()) {
    635                 return NT_STATUS_FILE_IS_OFFLINE;
    636         }
    637 
    638         if ( ! idmap_alloc_ldap) {
    639                 return NT_STATUS_UNSUCCESSFUL;
    640         }
    641 
    642         ctx = talloc_new(idmap_alloc_ldap);
    643         if ( ! ctx) {
    644                 DEBUG(0, ("Out of memory!\n"));
    645                 return NT_STATUS_NO_MEMORY;
    646         }
    647 
    648         /* get type */
    649         switch (xid->type) {
    650 
    651         case ID_TYPE_UID:
    652                 type = get_attr_key2string(idpool_attr_list,
    653                                            LDAP_ATTR_UIDNUMBER);
    654                 break;
    655 
    656         case ID_TYPE_GID:
    657                 type = get_attr_key2string(idpool_attr_list,
    658                                            LDAP_ATTR_GIDNUMBER);
    659                 break;
    660 
    661         default:
    662                 DEBUG(2, ("Invalid ID type (0x%x)\n", xid->type));
    663                 return NT_STATUS_INVALID_PARAMETER;
    664         }
    665 
    666         filter = talloc_asprintf(ctx, "(objectClass=%s)", LDAP_OBJ_IDPOOL);
    667         CHECK_ALLOC_DONE(filter);
    668 
    669         attr_list = get_attr_list(ctx, idpool_attr_list);
    670         CHECK_ALLOC_DONE(attr_list);
    671 
    672         rc = smbldap_search(idmap_alloc_ldap->smbldap_state,
    673                                 idmap_alloc_ldap->suffix,
    674                                LDAP_SCOPE_SUBTREE, filter,
    675                                attr_list, 0, &result);
    676 
    677         if (rc != LDAP_SUCCESS) {
    678                 DEBUG(0,("%s object not found\n", LDAP_OBJ_IDPOOL));
    679                 goto done;
    680         }
    681 
    682         talloc_autofree_ldapmsg(ctx, result);
    683 
    684         count = ldap_count_entries(idmap_alloc_ldap->smbldap_state->ldap_struct,
    685                                    result);
    686         if (count != 1) {
    687                 DEBUG(0,("Single %s object not found\n", LDAP_OBJ_IDPOOL));
    688                 goto done;
    689         }
    690 
    691         entry = ldap_first_entry(idmap_alloc_ldap->smbldap_state->ldap_struct,
    692                                  result);
    693 
    694         dn = smbldap_talloc_dn(ctx,
    695                                 idmap_alloc_ldap->smbldap_state->ldap_struct,
    696                                 entry);
    697         if ( ! dn) {
    698                 goto done;
    699         }
    700 
    701         new_id_str = talloc_asprintf(ctx, "%lu", (unsigned long)xid->id);
    702         if ( ! new_id_str) {
    703                 DEBUG(0,("Out of memory\n"));
    704                 ret = NT_STATUS_NO_MEMORY;
    705                 goto done;
    706         }
    707 
    708         smbldap_set_mod(&mods, LDAP_MOD_REPLACE, type, new_id_str);
    709 
    710         if (mods == NULL) {
    711                 DEBUG(0,("smbldap_set_mod() failed.\n"));
    712                 goto done;
    713         }
    714 
    715         rc = smbldap_modify(idmap_alloc_ldap->smbldap_state, dn, mods);
    716 
    717         ldap_mods_free(mods, True);
    718 
    719         if (rc != LDAP_SUCCESS) {
    720                 DEBUG(1,("Failed to allocate new %s. "
    721                          "smbldap_modify() failed.\n", type));
    722                 goto done;
    723         }
    724 
    725         ret = NT_STATUS_OK;
    726 
    727 done:
    728         talloc_free(ctx);
    729         return ret;
    730 }
    731 
    732 /**********************************
    733  Close idmap ldap alloc
    734 **********************************/
    735 
    736 static NTSTATUS idmap_ldap_alloc_close(void)
    737 {
    738         if (idmap_alloc_ldap) {
    739                 smbldap_free_struct(&idmap_alloc_ldap->smbldap_state);
    740                 DEBUG(5,("The connection to the LDAP server was closed\n"));
    741                 /* maybe free the results here --metze */
    742                 TALLOC_FREE(idmap_alloc_ldap);
    743         }
    744         return NT_STATUS_OK;
    745411}
    746412
     
    763429********************************/
    764430
    765 static NTSTATUS idmap_ldap_db_init(struct idmap_domain *dom,
    766                                    const char *params)
     431static NTSTATUS idmap_ldap_set_mapping(struct idmap_domain *dom,
     432                                       const struct id_map *map);
     433
     434static NTSTATUS idmap_ldap_db_init(struct idmap_domain *dom)
    767435{
    768436        NTSTATUS ret;
     
    782450        }
    783451
    784         if (strequal(dom->name, "*")) {
    785                 uid_t low_uid = 0;
    786                 uid_t high_uid = 0;
    787                 gid_t low_gid = 0;
    788                 gid_t high_gid = 0;
    789 
    790                 ctx->filter_low_id = 0;
    791                 ctx->filter_high_id = 0;
    792 
    793                 if (lp_idmap_uid(&low_uid, &high_uid)) {
    794                         ctx->filter_low_id = low_uid;
    795                         ctx->filter_high_id = high_uid;
    796                 } else {
    797                         DEBUG(3, ("Warning: 'idmap uid' not set!\n"));
    798                 }
    799 
    800                 if (lp_idmap_gid(&low_gid, &high_gid)) {
    801                         if ((low_gid != low_uid) || (high_gid != high_uid)) {
    802                                 DEBUG(1, ("Warning: 'idmap uid' and 'idmap gid'"
    803                                       " ranges do not agree -- building "
    804                                       "intersection\n"));
    805                                 ctx->filter_low_id = MAX(ctx->filter_low_id,
    806                                                          low_gid);
    807                                 ctx->filter_high_id = MIN(ctx->filter_high_id,
    808                                                           high_gid);
    809                         }
    810                 } else {
    811                         DEBUG(3, ("Warning: 'idmap gid' not set!\n"));
    812                 }
    813         } else {
    814                 const char *range = NULL;
    815 
    816                 config_option = talloc_asprintf(ctx, "idmap config %s", dom->name);
    817                 if ( ! config_option) {
    818                         DEBUG(0, ("Out of memory!\n"));
    819                         ret = NT_STATUS_NO_MEMORY;
    820                         goto done;
    821                 }
    822 
    823                 /* load ranges */
    824                 range = lp_parm_const_string(-1, config_option, "range", NULL);
    825                 if (range && range[0]) {
    826                         if ((sscanf(range, "%u - %u", &ctx->filter_low_id,
    827                                                         &ctx->filter_high_id) != 2))
    828                         {
    829                                 DEBUG(1, ("ERROR: invalid filter range [%s]", range));
    830                                 ctx->filter_low_id = 0;
    831                                 ctx->filter_high_id = 0;
    832                         }
    833                 }
    834         }
    835 
    836         if (ctx->filter_low_id > ctx->filter_high_id) {
    837                 DEBUG(1, ("ERROR: invalid filter range [%u-%u]",
    838                       ctx->filter_low_id, ctx->filter_high_id));
    839                 ctx->filter_low_id = 0;
    840                 ctx->filter_high_id = 0;
    841         }
    842 
    843         if (params != NULL) {
    844                 /* assume location is the only parameter */
    845                 ctx->url = talloc_strdup(ctx, params);
    846         } else {
    847                 tmp = lp_parm_const_string(-1, config_option, "ldap_url", NULL);
    848 
     452        config_option = talloc_asprintf(ctx, "idmap config %s", dom->name);
     453        if (!config_option) {
     454                DEBUG(0, ("Out of memory!\n"));
     455                ret = NT_STATUS_NO_MEMORY;
     456                goto done;
     457        }
     458
     459        tmp = lp_parm_const_string(-1, config_option, "ldap_url", NULL);
     460
     461        if ( ! tmp) {
     462                DEBUG(1, ("ERROR: missing idmap ldap url\n"));
     463                ret = NT_STATUS_UNSUCCESSFUL;
     464                goto done;
     465        }
     466
     467        ctx->url = talloc_strdup(ctx, tmp);
     468
     469        trim_char(ctx->url, '\"', '\"');
     470
     471        tmp = lp_parm_const_string(-1, config_option, "ldap_base_dn", NULL);
     472        if ( ! tmp || ! *tmp) {
     473                tmp = lp_ldap_idmap_suffix();
    849474                if ( ! tmp) {
    850                         DEBUG(1, ("ERROR: missing idmap ldap url\n"));
     475                        DEBUG(1, ("ERROR: missing idmap ldap suffix\n"));
    851476                        ret = NT_STATUS_UNSUCCESSFUL;
    852477                        goto done;
    853478                }
    854 
    855                 ctx->url = talloc_strdup(ctx, tmp);
    856         }
    857         CHECK_ALLOC_DONE(ctx->url);
    858 
    859         trim_char(ctx->url, '\"', '\"');
    860 
    861         tmp = lp_parm_const_string(-1, config_option, "ldap_base_dn", NULL);
    862         if ( ! tmp || ! *tmp) {
    863                 tmp = lp_ldap_idmap_suffix();
    864                 if ( ! tmp) {
    865                         DEBUG(1, ("ERROR: missing idmap ldap suffix\n"));
    866                         ret = NT_STATUS_UNSUCCESSFUL;
    867                         goto done;
    868                 }
    869         }
     479        }
    870480
    871481        ctx->suffix = talloc_strdup(ctx, tmp);
    872482        CHECK_ALLOC_DONE(ctx->suffix);
     483
     484        ctx->rw_ops = talloc_zero(ctx, struct idmap_rw_ops);
     485        CHECK_ALLOC_DONE(ctx->rw_ops);
     486
     487        ctx->rw_ops->get_new_id = idmap_ldap_allocate_id_internal;
     488        ctx->rw_ops->set_mapping = idmap_ldap_set_mapping;
    873489
    874490        ret = smbldap_init(ctx, winbind_event_context(), ctx->url,
     
    879495        }
    880496
    881         ret = get_credentials( ctx, ctx->smbldap_state, config_option,
     497        ret = get_credentials( ctx, ctx->smbldap_state, config_option,
    882498                               dom, &ctx->user_dn );
    883499        if ( !NT_STATUS_IS_OK(ret) ) {
     
    887503        }
    888504
    889         /* set the destructor on the context, so that resource are properly
    890            freed if the contexts is released */
    891 
     505        /*
     506         * Set the destructor on the context, so that resources are
     507         * properly freed when the context is released.
     508         */
    892509        talloc_set_destructor(ctx, idmap_ldap_close_destructor);
    893510
    894511        dom->private_data = ctx;
     512
     513        ret = verify_idpool(dom);
     514        if (!NT_STATUS_IS_OK(ret)) {
     515                DEBUG(1, ("idmap_ldap_db_init: failed to verify ID pool (%s)\n",
     516                         nt_errstr(ret)));
     517                goto done;
     518        }
    895519
    896520        talloc_free(config_option);
     
    902526        return ret;
    903527}
     528
     529/**
     530 * set a mapping.
     531 */
     532
     533/* TODO: change this:  This function cannot be called to modify a mapping,
     534 * only set a new one */
     535
     536static NTSTATUS idmap_ldap_set_mapping(struct idmap_domain *dom,
     537                                       const struct id_map *map)
     538{
     539        NTSTATUS ret;
     540        TALLOC_CTX *memctx;
     541        struct idmap_ldap_context *ctx;
     542        LDAPMessage *entry = NULL;
     543        LDAPMod **mods = NULL;
     544        const char *type;
     545        char *id_str;
     546        char *sid;
     547        char *dn;
     548        int rc = -1;
     549
     550        /* Only do query if we are online */
     551        if (idmap_is_offline()) {
     552                return NT_STATUS_FILE_IS_OFFLINE;
     553        }
     554
     555        ctx = talloc_get_type(dom->private_data, struct idmap_ldap_context);
     556
     557        switch(map->xid.type) {
     558        case ID_TYPE_UID:
     559                type = get_attr_key2string(sidmap_attr_list,
     560                                           LDAP_ATTR_UIDNUMBER);
     561                break;
     562
     563        case ID_TYPE_GID:
     564                type = get_attr_key2string(sidmap_attr_list,
     565                                           LDAP_ATTR_GIDNUMBER);
     566                break;
     567
     568        default:
     569                return NT_STATUS_INVALID_PARAMETER;
     570        }
     571
     572        memctx = talloc_new(ctx);
     573        if ( ! memctx) {
     574                DEBUG(0, ("Out of memory!\n"));
     575                return NT_STATUS_NO_MEMORY;
     576        }
     577
     578        id_str = talloc_asprintf(memctx, "%lu", (unsigned long)map->xid.id);
     579        CHECK_ALLOC_DONE(id_str);
     580
     581        sid = talloc_strdup(memctx, sid_string_talloc(memctx, map->sid));
     582        CHECK_ALLOC_DONE(sid);
     583
     584        dn = talloc_asprintf(memctx, "%s=%s,%s",
     585                        get_attr_key2string(sidmap_attr_list, LDAP_ATTR_SID),
     586                        sid,
     587                        ctx->suffix);
     588        CHECK_ALLOC_DONE(dn);
     589
     590        smbldap_set_mod(&mods, LDAP_MOD_ADD,
     591                        "objectClass", LDAP_OBJ_IDMAP_ENTRY);
     592
     593        smbldap_make_mod(ctx->smbldap_state->ldap_struct,
     594                         entry, &mods, type, id_str);
     595
     596        smbldap_make_mod(ctx->smbldap_state->ldap_struct, entry, &mods,
     597                         get_attr_key2string(sidmap_attr_list, LDAP_ATTR_SID),
     598                         sid);
     599
     600        if ( ! mods) {
     601                DEBUG(2, ("ERROR: No mods?\n"));
     602                ret = NT_STATUS_UNSUCCESSFUL;
     603                goto done;
     604        }
     605
     606        /* TODO: remove conflicting mappings! */
     607
     608        smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_SID_ENTRY);
     609
     610        DEBUG(10, ("Set DN %s (%s -> %s)\n", dn, sid, id_str));
     611
     612        rc = smbldap_add(ctx->smbldap_state, dn, mods);
     613        ldap_mods_free(mods, True);
     614
     615        if (rc != LDAP_SUCCESS) {
     616                char *ld_error = NULL;
     617                ldap_get_option(ctx->smbldap_state->ldap_struct,
     618                                LDAP_OPT_ERROR_STRING, &ld_error);
     619                DEBUG(0,("ldap_set_mapping_internals: Failed to add %s to %lu "
     620                         "mapping [%s]\n", sid,
     621                         (unsigned long)map->xid.id, type));
     622                DEBUG(0, ("ldap_set_mapping_internals: Error was: %s (%s)\n",
     623                        ld_error ? ld_error : "(NULL)", ldap_err2string (rc)));
     624                if (ld_error) {
     625                        ldap_memfree(ld_error);
     626                }
     627                ret = NT_STATUS_UNSUCCESSFUL;
     628                goto done;
     629        }
     630
     631        DEBUG(10,("ldap_set_mapping: Successfully created mapping from %s to "
     632                  "%lu [%s]\n", sid, (unsigned long)map->xid.id, type));
     633
     634        ret = NT_STATUS_OK;
     635
     636done:
     637        talloc_free(memctx);
     638        return ret;
     639}
     640
     641/**
     642 * Create a new mapping for an unmapped SID, also allocating a new ID.
     643 * If possible, this should be run inside a transaction to make the
     644 * action atomic.
     645 */
     646static NTSTATUS idmap_ldap_new_mapping(struct idmap_domain *dom, struct id_map *map)
     647{
     648        NTSTATUS ret;
     649        struct idmap_ldap_context *ctx;
     650
     651        ctx = talloc_get_type(dom->private_data, struct idmap_ldap_context);
     652
     653        ret = idmap_rw_new_mapping(dom, ctx->rw_ops, map);
     654
     655        return ret;
     656}
     657
    904658
    905659/* max number of ids requested per batch query */
     
    1026780        for (i = 0; i < count; i++) {
    1027781                char *sidstr = NULL;
    1028                 char *tmp = NULL;
     782                char *tmp = NULL;
    1029783                enum id_type type;
    1030784                struct id_map *map;
     
    1075829
    1076830                id = strtoul(tmp, NULL, 10);
    1077                 if ((id == 0) ||
    1078                     (ctx->filter_low_id && (id < ctx->filter_low_id)) ||
    1079                     (ctx->filter_high_id && (id > ctx->filter_high_id))) {
     831                if (!idmap_unix_id_is_in_range(id, dom)) {
    1080832                        DEBUG(5, ("Requested id (%u) out of range (%u - %u). "
    1081833                                  "Filtered!\n", id,
    1082                                   ctx->filter_low_id, ctx->filter_high_id));
     834                                  dom->low_id, dom->high_id));
    1083835                        TALLOC_FREE(sidstr);
    1084836                        TALLOC_FREE(tmp);
     
    1146898/* this function searches up to IDMAP_LDAP_MAX_IDS entries
    1147899 * in maps for a match */
    1148 static struct id_map *find_map_by_sid(struct id_map **maps, DOM_SID *sid)
     900static struct id_map *find_map_by_sid(struct id_map **maps, struct dom_sid *sid)
    1149901{
    1150902        int i;
     
    1154906                        return NULL;
    1155907                }
    1156                 if (sid_equal(maps[i]->sid, sid)) {
     908                if (dom_sid_equal(maps[i]->sid, sid)) {
    1157909                        return maps[i];
    1158910                }
     
    1165917                                           struct id_map **ids)
    1166918{
    1167         LDAPMessage *entry = NULL;
     919        LDAPMessage *entry = NULL;
    1168920        NTSTATUS ret;
    1169921        TALLOC_CTX *memctx;
     
    12631015                enum id_type type;
    12641016                struct id_map *map;
    1265                 DOM_SID sid;
     1017                struct dom_sid sid;
    12661018                uint32_t id;
    12671019
     
    13241076
    13251077                id = strtoul(tmp, NULL, 10);
    1326                 if ((id == 0) ||
    1327                     (ctx->filter_low_id && (id < ctx->filter_low_id)) ||
    1328                     (ctx->filter_high_id && (id > ctx->filter_high_id))) {
     1078                if (!idmap_unix_id_is_in_range(id, dom)) {
    13291079                        DEBUG(5, ("Requested id (%u) out of range (%u - %u). "
    13301080                                  "Filtered!\n", id,
    1331                                   ctx->filter_low_id, ctx->filter_high_id));
     1081                                  dom->low_id, dom->high_id));
    13321082                        TALLOC_FREE(sidstr);
    13331083                        TALLOC_FREE(tmp);
     
    13641114        }
    13651115
     1116        /*
     1117         *  try to create new mappings for unmapped sids
     1118         */
     1119        for (i = 0; ids[i]; i++) {
     1120                if (ids[i]->status != ID_MAPPED) {
     1121                        ids[i]->status = ID_UNMAPPED;
     1122                        if (ids[i]->sid != NULL) {
     1123                                ret = idmap_ldap_new_mapping(dom, ids[i]);
     1124                                if (!NT_STATUS_IS_OK(ret)) {
     1125                                        goto done;
     1126                                }
     1127                        }
     1128                }
     1129        }
     1130
    13661131        ret = NT_STATUS_OK;
    1367 
    1368         /* mark all unknwon/expired ones as unmapped */
    1369         for (i = 0; ids[i]; i++) {
    1370                 if (ids[i]->status != ID_MAPPED)
    1371                         ids[i]->status = ID_UNMAPPED;
    1372         }
    13731132
    13741133done:
     
    13781137
    13791138/**********************************
    1380  set a mapping.
    1381 **********************************/
    1382 
    1383 /* TODO: change this:  This function cannot be called to modify a mapping,
    1384  * only set a new one */
    1385 
    1386 static NTSTATUS idmap_ldap_set_mapping(struct idmap_domain *dom,
    1387                                        const struct id_map *map)
    1388 {
    1389         NTSTATUS ret;
    1390         TALLOC_CTX *memctx;
    1391         struct idmap_ldap_context *ctx;
    1392         LDAPMessage *entry = NULL;
    1393         LDAPMod **mods = NULL;
    1394         const char *type;
    1395         char *id_str;
    1396         char *sid;
    1397         char *dn;
    1398         int rc = -1;
    1399 
    1400         /* Only do query if we are online */
    1401         if (idmap_is_offline()) {
    1402                 return NT_STATUS_FILE_IS_OFFLINE;
    1403         }
    1404 
    1405         ctx = talloc_get_type(dom->private_data, struct idmap_ldap_context);
    1406 
    1407         switch(map->xid.type) {
    1408         case ID_TYPE_UID:
    1409                 type = get_attr_key2string(sidmap_attr_list,
    1410                                            LDAP_ATTR_UIDNUMBER);
    1411                 break;
    1412 
    1413         case ID_TYPE_GID:
    1414                 type = get_attr_key2string(sidmap_attr_list,
    1415                                            LDAP_ATTR_GIDNUMBER);
    1416                 break;
    1417 
    1418         default:
    1419                 return NT_STATUS_INVALID_PARAMETER;
    1420         }
    1421 
    1422         memctx = talloc_new(ctx);
    1423         if ( ! memctx) {
    1424                 DEBUG(0, ("Out of memory!\n"));
    1425                 return NT_STATUS_NO_MEMORY;
    1426         }
    1427 
    1428         id_str = talloc_asprintf(memctx, "%lu", (unsigned long)map->xid.id);
    1429         CHECK_ALLOC_DONE(id_str);
    1430 
    1431         sid = talloc_strdup(memctx, sid_string_talloc(memctx, map->sid));
    1432         CHECK_ALLOC_DONE(sid);
    1433 
    1434         dn = talloc_asprintf(memctx, "%s=%s,%s",
    1435                         get_attr_key2string(sidmap_attr_list, LDAP_ATTR_SID),
    1436                         sid,
    1437                         ctx->suffix);
    1438         CHECK_ALLOC_DONE(dn);
    1439 
    1440         smbldap_set_mod(&mods, LDAP_MOD_ADD,
    1441                         "objectClass", LDAP_OBJ_IDMAP_ENTRY);
    1442 
    1443         smbldap_make_mod(ctx->smbldap_state->ldap_struct,
    1444                          entry, &mods, type, id_str);
    1445 
    1446         smbldap_make_mod(ctx->smbldap_state->ldap_struct, entry, &mods,
    1447                          get_attr_key2string(sidmap_attr_list, LDAP_ATTR_SID),
    1448                          sid);
    1449 
    1450         if ( ! mods) {
    1451                 DEBUG(2, ("ERROR: No mods?\n"));
    1452                 ret = NT_STATUS_UNSUCCESSFUL;
    1453                 goto done;
    1454         }
    1455 
    1456         /* TODO: remove conflicting mappings! */
    1457 
    1458         smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_SID_ENTRY);
    1459 
    1460         DEBUG(10, ("Set DN %s (%s -> %s)\n", dn, sid, id_str));
    1461 
    1462         rc = smbldap_add(ctx->smbldap_state, dn, mods);
    1463         ldap_mods_free(mods, True);
    1464 
    1465         if (rc != LDAP_SUCCESS) {
    1466                 char *ld_error = NULL;
    1467                 ldap_get_option(ctx->smbldap_state->ldap_struct,
    1468                                 LDAP_OPT_ERROR_STRING, &ld_error);
    1469                 DEBUG(0,("ldap_set_mapping_internals: Failed to add %s to %lu "
    1470                          "mapping [%s]\n", sid,
    1471                          (unsigned long)map->xid.id, type));
    1472                 DEBUG(0, ("ldap_set_mapping_internals: Error was: %s (%s)\n",
    1473                         ld_error ? ld_error : "(NULL)", ldap_err2string (rc)));
    1474                 if (ld_error) {
    1475                         ldap_memfree(ld_error);
    1476                 }
    1477                 ret = NT_STATUS_UNSUCCESSFUL;
    1478                 goto done;
    1479         }
    1480 
    1481         DEBUG(10,("ldap_set_mapping: Successfully created mapping from %s to "
    1482                   "%lu [%s]\n", sid, (unsigned long)map->xid.id, type));
    1483 
    1484         ret = NT_STATUS_OK;
    1485 
    1486 done:
    1487         talloc_free(memctx);
    1488         return ret;
    1489 }
    1490 
    1491 /**********************************
    14921139 Close the idmap ldap instance
    14931140**********************************/
    1494 
    1495 static NTSTATUS idmap_ldap_close(struct idmap_domain *dom)
    1496 {
    1497         struct idmap_ldap_context *ctx;
    1498 
    1499         if (dom->private_data) {
    1500                 ctx = talloc_get_type(dom->private_data,
    1501                                       struct idmap_ldap_context);
    1502 
    1503                 talloc_free(ctx);
    1504                 dom->private_data = NULL;
    1505         }
    1506 
    1507         return NT_STATUS_OK;
    1508 }
    15091141
    15101142static struct idmap_methods idmap_ldap_methods = {
     
    15131145        .unixids_to_sids = idmap_ldap_unixids_to_sids,
    15141146        .sids_to_unixids = idmap_ldap_sids_to_unixids,
    1515         .set_mapping = idmap_ldap_set_mapping,
    1516         .close_fn = idmap_ldap_close
     1147        .allocate_id = idmap_ldap_allocate_id,
    15171148};
    1518 
    1519 static struct idmap_alloc_methods idmap_ldap_alloc_methods = {
    1520 
    1521         .init = idmap_ldap_alloc_init,
    1522         .allocate_id = idmap_ldap_allocate_id,
    1523         .get_id_hwm = idmap_ldap_get_hwm,
    1524         .set_id_hwm = idmap_ldap_set_hwm,
    1525         .close_fn = idmap_ldap_alloc_close,
    1526         /* .dump_data = TODO */
    1527 };
    1528 
    1529 static NTSTATUS idmap_alloc_ldap_init(void)
    1530 {
    1531         return smb_register_idmap_alloc(SMB_IDMAP_INTERFACE_VERSION, "ldap",
    1532                                         &idmap_ldap_alloc_methods);
    1533 }
    15341149
    15351150NTSTATUS idmap_ldap_init(void);
    15361151NTSTATUS idmap_ldap_init(void)
    15371152{
    1538         NTSTATUS ret;
    1539 
    1540         /* FIXME: bad hack to actually register also the alloc_ldap module
    1541          * without changining configure.in */
    1542         ret = idmap_alloc_ldap_init();
    1543         if (! NT_STATUS_IS_OK(ret)) {
    1544                 return ret;
    1545         }
    15461153        return smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION, "ldap",
    15471154                                  &idmap_ldap_methods);
  • vendor/current/source3/winbindd/idmap_nss.c

    r414 r740  
    22   Unix SMB/CIFS implementation.
    33
    4    idmap PASSDB backend
     4   idmap NSS backend
    55
    66   Copyright (C) Simo Sorce 2006
    7    
     7
    88   This program is free software; you can redistribute it and/or modify
    99   it under the terms of the GNU General Public License as published by
    1010   the Free Software Foundation; either version 3 of the License, or
    1111   (at your option) any later version.
    12    
     12
    1313   This program is distributed in the hope that it will be useful,
    1414   but WITHOUT ANY WARRANTY; without even the implied warranty of
    1515   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1616   GNU General Public License for more details.
    17    
     17
    1818   You should have received a copy of the GNU General Public License
    1919   along with this program.  If not, see <http://www.gnu.org/licenses/>.
     
    2121
    2222#include "includes.h"
     23#include "system/passwd.h"
    2324#include "winbindd.h"
     25#include "nsswitch/winbind_client.h"
     26#include "idmap.h"
     27#include "lib/winbind_util.h"
    2428
    2529#undef DBGC_CLASS
     
    3034*****************************/
    3135
    32 static NTSTATUS idmap_nss_int_init(struct idmap_domain *dom,
    33                                    const char *params)
     36static NTSTATUS idmap_nss_int_init(struct idmap_domain *dom)
    3437{       
    3538        return NT_STATUS_OK;
     
    4245static NTSTATUS idmap_nss_unixids_to_sids(struct idmap_domain *dom, struct id_map **ids)
    4346{
    44         TALLOC_CTX *ctx;
    4547        int i;
    4648
     
    4850        for (i = 0; ids[i]; i++) {
    4951                ids[i]->status = ID_UNKNOWN;
    50         }
    51        
    52         ctx = talloc_new(dom);
    53         if ( ! ctx) {
    54                 DEBUG(0, ("Out of memory!\n"));
    55                 return NT_STATUS_NO_MEMORY;
    5652        }
    5753
     
    6258                enum lsa_SidType type;
    6359                bool ret;
    64                
     60
    6561                switch (ids[i]->xid.type) {
    6662                case ID_TYPE_UID:
     
    121117                }
    122118        }
    123 
    124 
    125         talloc_free(ctx);
    126119        return NT_STATUS_OK;
    127120}
     
    133126static NTSTATUS idmap_nss_sids_to_unixids(struct idmap_domain *dom, struct id_map **ids)
    134127{
    135         TALLOC_CTX *ctx;
    136128        int i;
    137129
     
    139131        for (i = 0; ids[i]; i++) {
    140132                ids[i]->status = ID_UNKNOWN;
    141         }
    142        
    143         ctx = talloc_new(dom);
    144         if ( ! ctx) {
    145                 DEBUG(0, ("Out of memory!\n"));
    146                 return NT_STATUS_NO_MEMORY;
    147133        }
    148134
     
    150136                struct group *gr;
    151137                enum lsa_SidType type;
    152                 const char *dom_name = NULL;
    153                 const char *name = NULL;
     138                char *name = NULL;
    154139                bool ret;
    155140
     
    157142                   the following call will not recurse so this is safe */
    158143                (void)winbind_on();
    159                 ret = winbind_lookup_sid(ctx, ids[i]->sid, &dom_name, &name, &type);
     144                ret = winbind_lookup_sid(talloc_tos(), ids[i]->sid, NULL,
     145                                         (const char **)&name, &type);
    160146                (void)winbind_off();
    161147
     
    199185                        break;
    200186                }
    201         }
    202 
    203         talloc_free(ctx);
     187                TALLOC_FREE(name);
     188        }
    204189        return NT_STATUS_OK;
    205190}
     
    209194**********************************/
    210195
    211 static NTSTATUS idmap_nss_close(struct idmap_domain *dom)
    212 {
    213         return NT_STATUS_OK;
    214 }
    215 
    216196static struct idmap_methods nss_methods = {
    217197
     
    219199        .unixids_to_sids = idmap_nss_unixids_to_sids,
    220200        .sids_to_unixids = idmap_nss_sids_to_unixids,
    221         .close_fn = idmap_nss_close
    222201};
    223202
  • vendor/current/source3/winbindd/idmap_passdb.c

    r414 r740  
    55
    66   Copyright (C) Simo Sorce 2006
    7    
     7
    88   This program is free software; you can redistribute it and/or modify
    99   it under the terms of the GNU General Public License as published by
    1010   the Free Software Foundation; either version 3 of the License, or
    1111   (at your option) any later version.
    12    
     12
    1313   This program is distributed in the hope that it will be useful,
    1414   but WITHOUT ANY WARRANTY; without even the implied warranty of
    1515   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1616   GNU General Public License for more details.
    17    
     17
    1818   You should have received a copy of the GNU General Public License
    1919   along with this program.  If not, see <http://www.gnu.org/licenses/>.
     
    2121
    2222#include "includes.h"
     23#include "idmap.h"
     24#include "passdb.h"
    2325
    2426#undef DBGC_CLASS
     
    2931*****************************/
    3032
    31 static NTSTATUS idmap_pdb_init(struct idmap_domain *dom, const char *params)
     33static NTSTATUS idmap_pdb_init(struct idmap_domain *dom)
    3234{       
    3335        return NT_STATUS_OK;
     
    7779                enum lsa_SidType type;
    7880                union unid_t id;
    79                
     81
    8082                if (pdb_sid_to_id(ids[i]->sid, &id, &type)) {
    8183                        switch (type) {
     
    112114**********************************/
    113115
    114 static NTSTATUS idmap_pdb_close(struct idmap_domain *dom)
    115 {
    116         return NT_STATUS_OK;
    117 }
    118 
    119116static struct idmap_methods passdb_methods = {
    120117
     
    122119        .unixids_to_sids = idmap_pdb_unixids_to_sids,
    123120        .sids_to_unixids = idmap_pdb_sids_to_unixids,
    124         .close_fn =idmap_pdb_close
    125121};
    126122
  • vendor/current/source3/winbindd/idmap_rid.c

    r414 r740  
    2121#include "includes.h"
    2222#include "winbindd.h"
     23#include "idmap.h"
     24#include "../libcli/security/dom_sid.h"
    2325
    2426#undef DBGC_CLASS
     
    2628
    2729struct idmap_rid_context {
    28         const char *domain_name;
    29         uint32_t low_id;
    30         uint32_t high_id;
    3130        uint32_t base_rid;
    3231};
     
    3736 *****************************************************************************/
    3837
    39 static NTSTATUS idmap_rid_initialize(struct idmap_domain *dom,
    40                                      const char *params)
     38static NTSTATUS idmap_rid_initialize(struct idmap_domain *dom)
    4139{
    4240        NTSTATUS ret;
    4341        struct idmap_rid_context *ctx;
    4442        char *config_option = NULL;
    45         const char *range;
    46         uid_t low_uid = 0;
    47         uid_t high_uid = 0;
    48         gid_t low_gid = 0;
    49         gid_t high_gid = 0;
    5043
    51         if ( (ctx = TALLOC_ZERO_P(dom, struct idmap_rid_context)) == NULL ) {
     44        ctx = TALLOC_ZERO_P(dom, struct idmap_rid_context);
     45        if (ctx == NULL) {
    5246                DEBUG(0, ("Out of memory!\n"));
    5347                return NT_STATUS_NO_MEMORY;
     
    6155        }
    6256
    63         range = lp_parm_const_string(-1, config_option, "range", NULL);
    64         if ( !range ||
    65             (sscanf(range, "%u - %u", &ctx->low_id, &ctx->high_id) != 2) ||
    66             (ctx->low_id > ctx->high_id))
    67         {
    68                 ctx->low_id = 0;
    69                 ctx->high_id = 0;
    70         }
     57        ctx->base_rid = lp_parm_int(-1, config_option, "base_rid", 0);
    7158
    72         /* lets see if the range is defined by the old idmap uid/idmap gid */
    73         if (!ctx->low_id && !ctx->high_id) {
    74                 if (lp_idmap_uid(&low_uid, &high_uid)) {
    75                         ctx->low_id = low_uid;
    76                         ctx->high_id = high_uid;
    77                 }
    78 
    79                 if (lp_idmap_gid(&low_gid, &high_gid)) {
    80                         if ((ctx->low_id != low_gid) ||
    81                             (ctx->high_id != high_uid)) {
    82                                 DEBUG(1, ("ERROR: idmap uid range must match idmap gid range\n"));
    83                                 ret = NT_STATUS_UNSUCCESSFUL;
    84                                 goto failed;
    85                         }
    86                 }
    87         }
    88 
    89         if (!ctx->low_id || !ctx->high_id) {
    90                 DEBUG(1, ("ERROR: Invalid configuration, ID range missing or invalid\n"));
    91                 ret = NT_STATUS_UNSUCCESSFUL;
    92                 goto failed;
    93         }
    94 
    95         ctx->base_rid = lp_parm_int(-1, config_option, "base_rid", 0);
    96         ctx->domain_name = talloc_strdup( ctx, dom->name );
    97        
    9859        dom->private_data = ctx;
    9960
     
    10667}
    10768
    108 static NTSTATUS idmap_rid_id_to_sid(TALLOC_CTX *memctx, struct idmap_rid_context *ctx, struct id_map *map)
     69static NTSTATUS idmap_rid_id_to_sid(struct idmap_domain *dom, struct id_map *map)
    10970{
    110         struct winbindd_domain *domain;
     71        struct winbindd_domain *domain;
     72        struct idmap_rid_context *ctx;
     73
     74        ctx = talloc_get_type(dom->private_data, struct idmap_rid_context);
    11175
    11276        /* apply filters before checking */
    113         if ((map->xid.id < ctx->low_id) || (map->xid.id > ctx->high_id)) {
     77        if (!idmap_unix_id_is_in_range(map->xid.id, dom)) {
    11478                DEBUG(5, ("Requested id (%u) out of range (%u - %u). Filtered!\n",
    115                                 map->xid.id, ctx->low_id, ctx->high_id));
     79                                map->xid.id, dom->low_id, dom->high_id));
    11680                return NT_STATUS_NONE_MAPPED;
    11781        }
    11882
    119         if ( (domain = find_domain_from_name_noinit(ctx->domain_name)) == NULL ) {
     83        domain = find_domain_from_name_noinit(dom->name);
     84        if (domain == NULL ) {
    12085                return NT_STATUS_NO_SUCH_DOMAIN;
    12186        }
    122        
    123         sid_compose(map->sid, &domain->sid, map->xid.id - ctx->low_id + ctx->base_rid);
     87
     88        sid_compose(map->sid, &domain->sid, map->xid.id - dom->low_id + ctx->base_rid);
    12489
    12590        /* We **really** should have some way of validating
     
    136101**********************************/
    137102
    138 static NTSTATUS idmap_rid_sid_to_id(TALLOC_CTX *memctx, struct idmap_rid_context *ctx, struct id_map *map)
     103static NTSTATUS idmap_rid_sid_to_id(struct idmap_domain *dom, struct id_map *map)
    139104{
    140105        uint32_t rid;
     106        struct idmap_rid_context *ctx;
     107
     108        ctx = talloc_get_type(dom->private_data, struct idmap_rid_context);
    141109
    142110        sid_peek_rid(map->sid, &rid);
    143         map->xid.id = rid - ctx->base_rid + ctx->low_id;
     111        map->xid.id = rid - ctx->base_rid + dom->low_id;
    144112
    145113        /* apply filters before returning result */
    146114
    147         if ((map->xid.id < ctx->low_id) || (map->xid.id > ctx->high_id)) {
     115        if (!idmap_unix_id_is_in_range(map->xid.id, dom)) {
    148116                DEBUG(5, ("Requested id (%u) out of range (%u - %u). Filtered!\n",
    149                                 map->xid.id, ctx->low_id, ctx->high_id));
     117                                map->xid.id, dom->low_id, dom->high_id));
    150118                map->status = ID_UNMAPPED;
    151119                return NT_STATUS_NONE_MAPPED;
    152120        }
    153 
    154         /* We **really** should have some way of validating
    155            the SID exists and is the correct type here.  But
    156            that is a deficiency in the idmap_rid design. */
    157121
    158122        map->status = ID_MAPPED;
     
    167131static NTSTATUS idmap_rid_unixids_to_sids(struct idmap_domain *dom, struct id_map **ids)
    168132{
    169         struct idmap_rid_context *ridctx;
    170         TALLOC_CTX *ctx;
    171133        NTSTATUS ret;
    172134        int i;
     
    176138                ids[i]->status = ID_UNKNOWN;
    177139        }
    178        
    179         ridctx = talloc_get_type(dom->private_data, struct idmap_rid_context);
    180 
    181         ctx = talloc_new(dom);
    182         if ( ! ctx) {
    183                 DEBUG(0, ("Out of memory!\n"));
    184                 return NT_STATUS_NO_MEMORY;
    185         }
    186140
    187141        for (i = 0; ids[i]; i++) {
    188142
    189                 ret = idmap_rid_id_to_sid(ctx, ridctx, ids[i]);
     143                ret = idmap_rid_id_to_sid(dom, ids[i]);
    190144
    191145                if (( ! NT_STATUS_IS_OK(ret)) &&
     
    196150        }
    197151
    198         talloc_free(ctx);
    199152        return NT_STATUS_OK;
    200153}
     
    206159static NTSTATUS idmap_rid_sids_to_unixids(struct idmap_domain *dom, struct id_map **ids)
    207160{
    208         struct idmap_rid_context *ridctx;
    209         TALLOC_CTX *ctx;
    210161        NTSTATUS ret;
    211162        int i;
     
    215166                ids[i]->status = ID_UNKNOWN;
    216167        }
    217        
    218         ridctx = talloc_get_type(dom->private_data, struct idmap_rid_context);
    219 
    220         ctx = talloc_new(dom);
    221         if ( ! ctx) {
    222                 DEBUG(0, ("Out of memory!\n"));
    223                 return NT_STATUS_NO_MEMORY;
    224         }
    225168
    226169        for (i = 0; ids[i]; i++) {
    227170
    228                 ret = idmap_rid_sid_to_id(ctx, ridctx, ids[i]);
     171                ret = idmap_rid_sid_to_id(dom, ids[i]);
    229172
    230173                if (( ! NT_STATUS_IS_OK(ret)) &&
     
    236179        }
    237180
    238         talloc_free(ctx);
    239         return NT_STATUS_OK;
    240 }
    241 
    242 static NTSTATUS idmap_rid_close(struct idmap_domain *dom)
    243 {
    244         if (dom->private_data) {
    245                 TALLOC_FREE(dom->private_data);
    246         }
    247181        return NT_STATUS_OK;
    248182}
     
    252186        .unixids_to_sids = idmap_rid_unixids_to_sids,
    253187        .sids_to_unixids = idmap_rid_sids_to_unixids,
    254         .close_fn = idmap_rid_close
    255188};
    256189
  • vendor/current/source3/winbindd/idmap_tdb.c

    r414 r740  
    88   Copyright (C) Jeremy Allison 2006
    99   Copyright (C) Simo Sorce 2003-2006
    10    
     10   Copyright (C) Michael Adam 2009-2010
     11
    1112   This program is free software; you can redistribute it and/or modify
    1213   it under the terms of the GNU General Public License as published by
    1314   the Free Software Foundation; either version 3 of the License, or
    1415   (at your option) any later version.
    15    
     16
    1617   This program is distributed in the hope that it will be useful,
    1718   but WITHOUT ANY WARRANTY; without even the implied warranty of
    1819   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1920   GNU General Public License for more details.
    20    
     21
    2122   You should have received a copy of the GNU General Public License
    2223   along with this program.  If not, see <http://www.gnu.org/licenses/>.
     
    2425
    2526#include "includes.h"
     27#include "system/filesys.h"
    2628#include "winbindd.h"
     29#include "idmap.h"
     30#include "idmap_rw.h"
     31#include "dbwrap.h"
     32#include "../libcli/security/security.h"
     33#include "util_tdb.h"
    2734
    2835#undef DBGC_CLASS
     
    3340
    3441#define IDMAP_VERSION 2
     42
     43struct idmap_tdb_context {
     44        struct db_context *db;
     45        struct idmap_rw_ops *rw_ops;
     46};
    3547
    3648/* High water mark keys */
    3749#define HWM_GROUP  "GROUP HWM"
    3850#define HWM_USER   "USER HWM"
    39 
    40 static struct idmap_tdb_state {
    41 
    42         /* User and group id pool */
    43         uid_t low_uid, high_uid;               /* Range of uids to allocate */
    44         gid_t low_gid, high_gid;               /* Range of gids to allocate */
    45 
    46 } idmap_tdb_state;
    4751
    4852struct convert_fn_state {
     
    6165        char *p;
    6266        NTSTATUS status;
    63         DOM_SID sid;
     67        struct dom_sid sid;
    6468        uint32 rid;
    6569        fstring keystr;
     
    98102        rid = atoi(p);
    99103
    100         sid_copy(&sid, &domain->sid);
    101         sid_append_rid(&sid, rid);
     104        sid_compose(&sid, &domain->sid, rid);
    102105
    103106        sid_to_fstring(keystr, &sid);
     
    138141*****************************************************************************/
    139142
    140 static bool idmap_tdb_upgrade(struct db_context *db)
     143static bool idmap_tdb_upgrade(struct idmap_domain *dom, struct db_context *db)
    141144{
    142145        int32 vers;
     
    164167                        wm = IREV(wm);
    165168                }  else {
    166                         wm = idmap_tdb_state.low_uid;
     169                        wm = dom->low_id;
    167170                }
    168171
     
    176179                        wm = IREV(wm);
    177180                } else {
    178                         wm = idmap_tdb_state.low_gid;
     181                        wm = dom->low_id;
    179182                }
    180183
     
    197200
    198201        if (dbwrap_store_int32(db, "IDMAP_VERSION", IDMAP_VERSION) == -1) {
    199                 DEBUG(0, ("Unable to store idmap version in databse\n"));
     202                DEBUG(0, ("Unable to store idmap version in database\n"));
    200203                return False;
    201204        }
     
    204207}
    205208
    206 static NTSTATUS idmap_tdb_load_ranges(void)
    207 {
    208         uid_t low_uid = 0;
    209         uid_t high_uid = 0;
    210         gid_t low_gid = 0;
    211         gid_t high_gid = 0;
    212 
    213         if (!lp_idmap_uid(&low_uid, &high_uid)) {
    214                 DEBUG(1, ("idmap uid missing\n"));
    215                 return NT_STATUS_UNSUCCESSFUL;
    216         }
    217 
    218         if (!lp_idmap_gid(&low_gid, &high_gid)) {
    219                 DEBUG(1, ("idmap gid missing\n"));
    220                 return NT_STATUS_UNSUCCESSFUL;
    221         }
    222 
    223         idmap_tdb_state.low_uid = low_uid;
    224         idmap_tdb_state.high_uid = high_uid;
    225         idmap_tdb_state.low_gid = low_gid;
    226         idmap_tdb_state.high_gid = high_gid;
    227 
    228         if (idmap_tdb_state.high_uid <= idmap_tdb_state.low_uid) {
    229                 DEBUG(1, ("idmap uid range missing or invalid\n"));
    230                 return NT_STATUS_UNSUCCESSFUL;
    231         }
    232 
    233         if (idmap_tdb_state.high_gid <= idmap_tdb_state.low_gid) {
    234                 DEBUG(1, ("idmap gid range missing or invalid\n"));
    235                 return NT_STATUS_UNSUCCESSFUL;
     209static NTSTATUS idmap_tdb_init_hwm(struct idmap_domain *dom)
     210{
     211        int ret;
     212        uint32_t low_uid;
     213        uint32_t low_gid;
     214        bool update_uid = false;
     215        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) {
     222                update_uid = true;
     223        }
     224
     225        low_gid = dbwrap_fetch_int32(ctx->db, HWM_GROUP);
     226        if (low_gid == -1 || low_gid < dom->low_id) {
     227                update_gid = true;
     228        }
     229
     230        if (!update_uid && !update_gid) {
     231                return NT_STATUS_OK;
     232        }
     233
     234        if (ctx->db->transaction_start(ctx->db) != 0) {
     235                DEBUG(0, ("Unable to start upgrade transaction!\n"));
     236                return NT_STATUS_INTERNAL_DB_ERROR;
     237        }
     238
     239        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);
     243                        DEBUG(0, ("Unable to initialise user hwm in idmap "
     244                                  "database\n"));
     245                        return NT_STATUS_INTERNAL_DB_ERROR;
     246                }
     247        }
     248
     249        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);
     253                        DEBUG(0, ("Unable to initialise group hwm in idmap "
     254                                  "database\n"));
     255                        return NT_STATUS_INTERNAL_DB_ERROR;
     256                }
     257        }
     258
     259        if (ctx->db->transaction_commit(ctx->db) != 0) {
     260                DEBUG(0, ("Unable to commit upgrade transaction!\n"));
     261                return NT_STATUS_INTERNAL_DB_ERROR;
    236262        }
    237263
     
    239265}
    240266
    241 static NTSTATUS idmap_tdb_open_db(TALLOC_CTX *memctx,
    242                                   bool check_config,
    243                                   struct db_context **dbctx)
    244 {
    245         NTSTATUS ret;
    246         TALLOC_CTX *ctx;
     267static NTSTATUS idmap_tdb_open_db(struct idmap_domain *dom)
     268{
     269        NTSTATUS ret;
     270        TALLOC_CTX *mem_ctx;
    247271        char *tdbfile = NULL;
    248272        struct db_context *db = NULL;
    249273        int32_t version;
    250274        bool config_error = false;
    251 
    252         ret = idmap_tdb_load_ranges();
    253         if (!NT_STATUS_IS_OK(ret)) {
    254                 config_error = true;
    255                 if (check_config) {
    256                         return ret;
    257                 }
     275        struct idmap_tdb_context *ctx;
     276
     277        ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context);
     278
     279        if (ctx->db) {
     280                /* it is already open */
     281                return NT_STATUS_OK;
    258282        }
    259283
    260284        /* use our own context here */
    261         ctx = talloc_stackframe();
     285        mem_ctx = talloc_stackframe();
    262286
    263287        /* use the old database if present */
     
    272296
    273297        /* Open idmap repository */
    274         db = db_open(ctx, tdbfile, 0, TDB_DEFAULT, O_RDWR | O_CREAT, 0644);
     298        db = db_open(mem_ctx, tdbfile, 0, TDB_DEFAULT, O_RDWR | O_CREAT, 0644);
    275299        if (!db) {
    276300                DEBUG(0, ("Unable to open idmap database\n"));
     
    295319                }
    296320
    297                 if (!idmap_tdb_upgrade(db)) {
     321                if (!idmap_tdb_upgrade(dom, db)) {
    298322                        db->transaction_cancel(db);
    299323                        DEBUG(0, ("Unable to open idmap database, it's in an old format, and upgrade failed!\n"));
     
    309333        }
    310334
    311         *dbctx = talloc_move(memctx, &db);
    312         ret = NT_STATUS_OK;
     335        ctx->db = talloc_move(ctx, &db);
     336
     337        ret = idmap_tdb_init_hwm(dom);
    313338
    314339done:
    315         talloc_free(ctx);
     340        talloc_free(mem_ctx);
    316341        return ret;
    317342}
     
    320345 IDMAP ALLOC TDB BACKEND
    321346**********************************************************************/
    322  
    323 static struct db_context *idmap_alloc_db;
    324 
    325 /**********************************
    326  Initialise idmap alloc database.
    327 **********************************/
    328 
    329 static NTSTATUS idmap_tdb_alloc_init( const char *params )
    330 {
    331         int ret;
    332         NTSTATUS status;
    333         uint32_t low_uid;
    334         uint32_t low_gid;
    335         bool update_uid = false;
    336         bool update_gid = false;
    337 
    338         status = idmap_tdb_open_db(NULL, true, &idmap_alloc_db);
    339         if (!NT_STATUS_IS_OK(status)) {
    340                 DEBUG(0, ("idmap will be unable to map foreign SIDs: %s\n",
    341                           nt_errstr(status)));
    342                 return status;
    343         }
    344 
    345         low_uid = dbwrap_fetch_int32(idmap_alloc_db, HWM_USER);
    346         if (low_uid == -1 || low_uid < idmap_tdb_state.low_uid) {
    347                 update_uid = true;
    348         }
    349 
    350         low_gid = dbwrap_fetch_int32(idmap_alloc_db, HWM_GROUP);
    351         if (low_gid == -1 || low_gid < idmap_tdb_state.low_gid) {
    352                 update_gid = true;
    353         }
    354 
    355         if (!update_uid && !update_gid) {
    356                 return NT_STATUS_OK;
    357         }
    358 
    359         if (idmap_alloc_db->transaction_start(idmap_alloc_db) != 0) {
    360                 TALLOC_FREE(idmap_alloc_db);
    361                 DEBUG(0, ("Unable to start upgrade transaction!\n"));
    362                 return NT_STATUS_INTERNAL_DB_ERROR;
    363         }
    364 
    365         if (update_uid) {
    366                 ret = dbwrap_store_int32(idmap_alloc_db, HWM_USER,
    367                                          idmap_tdb_state.low_uid);
    368                 if (ret == -1) {
    369                         idmap_alloc_db->transaction_cancel(idmap_alloc_db);
    370                         TALLOC_FREE(idmap_alloc_db);
    371                         DEBUG(0, ("Unable to initialise user hwm in idmap "
    372                                   "database\n"));
    373                         return NT_STATUS_INTERNAL_DB_ERROR;
    374                 }
    375         }
    376 
    377         if (update_gid) {
    378                 ret = dbwrap_store_int32(idmap_alloc_db, HWM_GROUP,
    379                                          idmap_tdb_state.low_gid);
    380                 if (ret == -1) {
    381                         idmap_alloc_db->transaction_cancel(idmap_alloc_db);
    382                         TALLOC_FREE(idmap_alloc_db);
    383                         DEBUG(0, ("Unable to initialise group hwm in idmap "
    384                                   "database\n"));
    385                         return NT_STATUS_INTERNAL_DB_ERROR;
    386                 }
    387         }
    388 
    389         if (idmap_alloc_db->transaction_commit(idmap_alloc_db) != 0) {
    390                 TALLOC_FREE(idmap_alloc_db);
    391                 DEBUG(0, ("Unable to commit upgrade transaction!\n"));
    392                 return NT_STATUS_INTERNAL_DB_ERROR;
    393         }
    394 
    395         return NT_STATUS_OK;
    396 }
    397347
    398348/**********************************
     
    400350**********************************/
    401351
    402 static NTSTATUS idmap_tdb_allocate_id(struct unixid *xid)
    403 {
    404         NTSTATUS ret;
     352struct idmap_tdb_allocate_id_context {
    405353        const char *hwmkey;
    406354        const char *hwmtype;
    407355        uint32_t high_hwm;
    408356        uint32_t hwm;
    409         int res;
     357};
     358
     359static 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
     401done:
     402        return ret;
     403}
     404
     405static 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);
    410417
    411418        /* Get current high water mark */
     
    415422                hwmkey = HWM_USER;
    416423                hwmtype = "UID";
    417                 high_hwm = idmap_tdb_state.high_uid;
    418424                break;
    419425
     
    421427                hwmkey = HWM_GROUP;
    422428                hwmtype = "GID";
    423                 high_hwm = idmap_tdb_state.high_gid;
    424429                break;
    425430
     
    429434        }
    430435
    431         res = idmap_alloc_db->transaction_start(idmap_alloc_db);
    432         if (res != 0) {
    433                 DEBUG(1, (__location__ " Failed to start transaction.\n"));
    434                 return NT_STATUS_UNSUCCESSFUL;
    435         }
    436 
    437         if ((hwm = dbwrap_fetch_int32(idmap_alloc_db, hwmkey)) == -1) {
    438                 idmap_alloc_db->transaction_cancel(idmap_alloc_db);
    439                 return NT_STATUS_INTERNAL_DB_ERROR;
    440         }
    441 
    442         /* check it is in the range */
    443         if (hwm > high_hwm) {
    444                 DEBUG(1, ("Fatal Error: %s range full!! (max: %lu)\n",
    445                           hwmtype, (unsigned long)high_hwm));
    446                 idmap_alloc_db->transaction_cancel(idmap_alloc_db);
    447                 return NT_STATUS_UNSUCCESSFUL;
    448         }
    449 
    450         /* fetch a new id and increment it */
    451         ret = dbwrap_change_uint32_atomic(idmap_alloc_db, hwmkey, &hwm, 1);
    452         if (!NT_STATUS_IS_OK(ret)) {
    453                 DEBUG(0, ("Fatal error while fetching a new %s value: %s\n!",
    454                           hwmtype, nt_errstr(ret)));
    455                 idmap_alloc_db->transaction_cancel(idmap_alloc_db);
    456                 return ret;
    457         }
    458 
    459         /* recheck it is in the range */
    460         if (hwm > high_hwm) {
    461                 DEBUG(1, ("Fatal Error: %s range full!! (max: %lu)\n",
    462                           hwmtype, (unsigned long)high_hwm));
    463                 idmap_alloc_db->transaction_cancel(idmap_alloc_db);
    464                 return NT_STATUS_UNSUCCESSFUL;
    465         }
    466 
    467         res = idmap_alloc_db->transaction_commit(idmap_alloc_db);
    468         if (res != 0) {
    469                 DEBUG(1, (__location__ " Failed to commit transaction.\n"));
    470                 return NT_STATUS_UNSUCCESSFUL;
    471         }
    472 
    473         xid->id = hwm;
    474         DEBUG(10,("New %s = %d\n", hwmtype, hwm));
    475 
    476         return NT_STATUS_OK;
    477 }
    478 
    479 /**********************************
    480  Get current highest id.
    481 **********************************/
    482 
    483 static NTSTATUS idmap_tdb_get_hwm(struct unixid *xid)
    484 {
    485         const char *hwmkey;
    486         const char *hwmtype;
    487         uint32_t hwm;
    488         uint32_t high_hwm;
    489 
    490         /* Get current high water mark */
    491         switch (xid->type) {
    492 
    493         case ID_TYPE_UID:
    494                 hwmkey = HWM_USER;
    495                 hwmtype = "UID";
    496                 high_hwm = idmap_tdb_state.high_uid;
    497                 break;
    498 
    499         case ID_TYPE_GID:
    500                 hwmkey = HWM_GROUP;
    501                 hwmtype = "GID";
    502                 high_hwm = idmap_tdb_state.high_gid;
    503                 break;
    504 
    505         default:
    506                 return NT_STATUS_INVALID_PARAMETER;
    507         }
    508 
    509         if ((hwm = dbwrap_fetch_int32(idmap_alloc_db, hwmkey)) == -1) {
    510                 return NT_STATUS_INTERNAL_DB_ERROR;
    511         }
    512 
    513         xid->id = hwm;
    514 
    515         /* Warn if it is out of range */
    516         if (hwm >= high_hwm) {
    517                 DEBUG(0, ("Warning: %s range full!! (max: %lu)\n",
    518                           hwmtype, (unsigned long)high_hwm));
    519         }
    520 
    521         return NT_STATUS_OK;
    522 }
    523 
    524 /**********************************
    525  Set high id.
    526 **********************************/
    527 
    528 static NTSTATUS idmap_tdb_set_hwm(struct unixid *xid)
    529 {
    530         const char *hwmkey;
    531         const char *hwmtype;
    532         uint32_t hwm;
    533         uint32_t high_hwm;
    534         NTSTATUS ret;
    535 
    536         /* Get current high water mark */
    537         switch (xid->type) {
    538 
    539         case ID_TYPE_UID:
    540                 hwmkey = HWM_USER;
    541                 hwmtype = "UID";
    542                 high_hwm = idmap_tdb_state.high_uid;
    543                 break;
    544 
    545         case ID_TYPE_GID:
    546                 hwmkey = HWM_GROUP;
    547                 hwmtype = "GID";
    548                 high_hwm = idmap_tdb_state.high_gid;
    549                 break;
    550 
    551         default:
    552                 return NT_STATUS_INVALID_PARAMETER;
    553         }
    554 
    555         hwm = xid->id;
    556 
    557         /* Warn if it is out of range */
    558         if (hwm >= high_hwm) {
    559                 DEBUG(0, ("Warning: %s range full!! (max: %lu)\n",
    560                           hwmtype, (unsigned long)high_hwm));
    561         }
    562 
    563         ret = dbwrap_trans_store_uint32(idmap_alloc_db, hwmkey, hwm);
    564 
    565         return ret;
    566 }
    567 
    568 /**********************************
    569  Close the alloc tdb
    570 **********************************/
    571 
    572 static NTSTATUS idmap_tdb_alloc_close(void)
    573 {
    574         TALLOC_FREE(idmap_alloc_db);
    575         return NT_STATUS_OK;
     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 */
     461static 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;
    576478}
    577479
     
    579481 IDMAP MAPPING TDB BACKEND
    580482**********************************************************************/
    581  
    582 struct idmap_tdb_context {
    583         struct db_context *db;
    584         uint32_t filter_low_id;
    585         uint32_t filter_high_id;
    586 };
    587483
    588484/*****************************
     
    590486*****************************/
    591487
    592 static NTSTATUS idmap_tdb_db_init(struct idmap_domain *dom, const char *params)
     488static NTSTATUS idmap_tdb_set_mapping(struct idmap_domain *dom,
     489                                      const struct id_map *map);
     490
     491static NTSTATUS idmap_tdb_db_init(struct idmap_domain *dom)
    593492{
    594493        NTSTATUS ret;
     
    597496        DEBUG(10, ("idmap_tdb_db_init called for domain '%s'\n", dom->name));
    598497
    599         ctx = talloc(dom, struct idmap_tdb_context);
     498        ctx = talloc_zero(dom, struct idmap_tdb_context);
    600499        if ( ! ctx) {
    601500                DEBUG(0, ("Out of memory!\n"));
     
    603502        }
    604503
     504        /* load backend specific configuration here: */
     505#if 0
    605506        if (strequal(dom->name, "*")) {
    606                 uid_t low_uid = 0;
    607                 uid_t high_uid = 0;
    608                 gid_t low_gid = 0;
    609                 gid_t high_gid = 0;
    610 
    611                 ctx->filter_low_id = 0;
    612                 ctx->filter_high_id = 0;
    613 
    614                 if (lp_idmap_uid(&low_uid, &high_uid)) {
    615                         ctx->filter_low_id = low_uid;
    616                         ctx->filter_high_id = high_uid;
    617                 } else {
    618                         DEBUG(3, ("Warning: 'idmap uid' not set!\n"));
    619                 }
    620 
    621                 if (lp_idmap_gid(&low_gid, &high_gid)) {
    622                         if ((low_gid != low_uid) || (high_gid != high_uid)) {
    623                                 DEBUG(1, ("Warning: 'idmap uid' and 'idmap gid'"
    624                                       " ranges do not agree -- building "
    625                                       "intersection\n"));
    626                                 ctx->filter_low_id = MAX(ctx->filter_low_id,
    627                                                          low_gid);
    628                                 ctx->filter_high_id = MIN(ctx->filter_high_id,
    629                                                           high_gid);
    630                         }
    631                 } else {
    632                         DEBUG(3, ("Warning: 'idmap gid' not set!\n"));
    633                 }
    634507        } else {
    635                 char *config_option = NULL;
    636                 const char *range;
    637 
    638                 config_option = talloc_asprintf(ctx, "idmap config %s", dom->name);
    639                 if ( ! config_option) {
    640                         DEBUG(0, ("Out of memory!\n"));
    641                         ret = NT_STATUS_NO_MEMORY;
    642                         goto failed;
    643                 }
    644 
    645                 range = lp_parm_const_string(-1, config_option, "range", NULL);
    646                 if (( ! range) ||
    647                     (sscanf(range, "%u - %u", &ctx->filter_low_id, &ctx->filter_high_id) != 2))
    648                 {
    649                         ctx->filter_low_id = 0;
    650                         ctx->filter_high_id = 0;
    651                 }
    652 
    653                 talloc_free(config_option);
    654         }
    655 
    656         if (ctx->filter_low_id > ctx->filter_high_id) {
    657                 ctx->filter_low_id = 0;
    658                 ctx->filter_high_id = 0;
    659         }
    660 
    661         DEBUG(10, ("idmap_tdb_db_init: filter range %u-%u loaded for domain "
    662               "'%s'\n", ctx->filter_low_id, ctx->filter_high_id, dom->name));
    663 
    664         ret = idmap_tdb_open_db(ctx, false, &ctx->db);
     508        }
     509#endif
     510
     511        ctx->rw_ops = talloc_zero(ctx, struct idmap_rw_ops);
     512        if (ctx->rw_ops == NULL) {
     513                DEBUG(0, ("Out of memory!\n"));
     514                ret = NT_STATUS_NO_MEMORY;
     515                goto failed;
     516        }
     517
     518        ctx->rw_ops->get_new_id = idmap_tdb_get_new_id;
     519        ctx->rw_ops->set_mapping = idmap_tdb_set_mapping;
     520
     521        dom->private_data = ctx;
     522
     523        ret = idmap_tdb_open_db(dom);
    665524        if ( ! NT_STATUS_IS_OK(ret)) {
    666525                goto failed;
    667526        }
    668527
    669         dom->private_data = ctx;
    670 
    671528        return NT_STATUS_OK;
    672529
     
    675532        return ret;
    676533}
     534
     535
     536/**
     537 * store a mapping in the database
     538 */
     539
     540struct idmap_tdb_set_mapping_context {
     541        const char *ksidstr;
     542        const char *kidstr;
     543};
     544
     545static 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
     576done:
     577        return ret;
     578}
     579
     580static 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
     633done:
     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 */
     647static 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
    677659
    678660/**********************************
     
    680662**********************************/
    681663
    682 static NTSTATUS idmap_tdb_id_to_sid(struct idmap_tdb_context *ctx, struct id_map *map)
     664static NTSTATUS idmap_tdb_id_to_sid(struct idmap_domain *dom, struct id_map *map)
    683665{
    684666        NTSTATUS ret;
    685667        TDB_DATA data;
    686668        char *keystr;
    687 
    688         if (!ctx || !map) {
     669        struct idmap_tdb_context *ctx;
     670
     671        if (!dom || !map) {
    689672                return NT_STATUS_INVALID_PARAMETER;
    690673        }
    691674
     675        ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context);
     676
    692677        /* apply filters before checking */
    693         if ((ctx->filter_low_id && (map->xid.id < ctx->filter_low_id)) ||
    694             (ctx->filter_high_id && (map->xid.id > ctx->filter_high_id))) {
     678        if (!idmap_unix_id_is_in_range(map->xid.id, dom)) {
    695679                DEBUG(5, ("Requested id (%u) out of range (%u - %u). Filtered!\n",
    696                                 map->xid.id, ctx->filter_low_id, ctx->filter_high_id));
     680                                map->xid.id, dom->low_id, dom->high_id));
    697681                return NT_STATUS_NONE_MAPPED;
    698682        }
     
    703687                keystr = talloc_asprintf(ctx, "UID %lu", (unsigned long)map->xid.id);
    704688                break;
    705                
     689
    706690        case ID_TYPE_GID:
    707691                keystr = talloc_asprintf(ctx, "GID %lu", (unsigned long)map->xid.id);
     
    732716                goto done;
    733717        }
    734                
     718
    735719        if (!string_to_sid(map->sid, (const char *)data.dptr)) {
    736720                DEBUG(10,("INVALID SID (%s) in record %s\n",
     
    753737**********************************/
    754738
    755 static NTSTATUS idmap_tdb_sid_to_id(struct idmap_tdb_context *ctx, struct id_map *map)
     739static NTSTATUS idmap_tdb_sid_to_id(struct idmap_domain *dom, struct id_map *map)
    756740{
    757741        NTSTATUS ret;
     
    759743        char *keystr;
    760744        unsigned long rec_id = 0;
     745        struct idmap_tdb_context *ctx;
    761746        TALLOC_CTX *tmp_ctx = talloc_stackframe();
     747
     748        ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context);
    762749
    763750        keystr = sid_string_talloc(tmp_ctx, map->sid);
     
    794781                DEBUG(2, ("Found INVALID record %s -> %s\n", keystr, (const char *)data.dptr));
    795782                ret = NT_STATUS_INTERNAL_DB_ERROR;
     783                goto done;
    796784        }
    797785
    798786        /* apply filters before returning result */
    799         if ((ctx->filter_low_id && (map->xid.id < ctx->filter_low_id)) ||
    800             (ctx->filter_high_id && (map->xid.id > ctx->filter_high_id))) {
     787        if (!idmap_unix_id_is_in_range(map->xid.id, dom)) {
    801788                DEBUG(5, ("Requested id (%u) out of range (%u - %u). Filtered!\n",
    802                                 map->xid.id, ctx->filter_low_id, ctx->filter_high_id));
     789                                map->xid.id, dom->low_id, dom->high_id));
    803790                ret = NT_STATUS_NONE_MAPPED;
    804791        }
     
    815802static NTSTATUS idmap_tdb_unixids_to_sids(struct idmap_domain *dom, struct id_map **ids)
    816803{
    817         struct idmap_tdb_context *ctx;
    818804        NTSTATUS ret;
    819805        int i;
     
    823809                ids[i]->status = ID_UNKNOWN;
    824810        }
    825        
    826         ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context);
    827811
    828812        for (i = 0; ids[i]; i++) {
    829                 ret = idmap_tdb_id_to_sid(ctx, ids[i]);
     813                ret = idmap_tdb_id_to_sid(dom, ids[i]);
    830814                if ( ! NT_STATUS_IS_OK(ret)) {
    831815
     
    837821                                continue;
    838822                        }
    839                        
     823
    840824                        /* some fatal error occurred, return immediately */
    841825                        goto done;
     
    856840**********************************/
    857841
     842struct idmap_tdb_sids_to_unixids_context {
     843        struct idmap_domain *dom;
     844        struct id_map **ids;
     845        bool allocate_unmapped;
     846};
     847
     848static 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
     899done:
     900        return ret;
     901}
     902
    858903static NTSTATUS idmap_tdb_sids_to_unixids(struct idmap_domain *dom, struct id_map **ids)
    859904{
     
    861906        NTSTATUS ret;
    862907        int i;
     908        struct idmap_tdb_sids_to_unixids_context state;
    863909
    864910        /* initialize the status to avoid suprise */
     
    866912                ids[i]->status = ID_UNKNOWN;
    867913        }
    868        
     914
    869915        ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context);
    870916
    871         for (i = 0; ids[i]; i++) {
    872                 ret = idmap_tdb_sid_to_id(ctx, ids[i]);
    873                 if ( ! NT_STATUS_IS_OK(ret)) {
    874 
    875                         /* if it is just a failed mapping continue */
    876                         if (NT_STATUS_EQUAL(ret, NT_STATUS_NONE_MAPPED)) {
    877 
    878                                 /* make sure it is marked as unmapped */
    879                                 ids[i]->status = ID_UNMAPPED;
    880                                 continue;
    881                         }
    882                        
    883                         /* some fatal error occurred, return immediately */
    884                         goto done;
    885                 }
    886 
    887                 /* all ok, id is mapped */
    888                 ids[i]->status = ID_MAPPED;
    889         }
    890 
    891         ret = NT_STATUS_OK;
    892 
    893 done:
    894         return ret;
    895 }
    896 
    897 /**********************************
    898  set a mapping.
    899 **********************************/
    900 
    901 static NTSTATUS idmap_tdb_set_mapping(struct idmap_domain *dom,
    902                                       const struct id_map *map)
    903 {
    904         struct idmap_tdb_context *ctx;
    905         NTSTATUS ret;
    906         TDB_DATA ksid, kid;
    907         char *ksidstr, *kidstr;
    908         fstring tmp;
    909 
    910         if (!map || !map->sid) {
    911                 return NT_STATUS_INVALID_PARAMETER;
    912         }
    913 
    914         ksidstr = kidstr = NULL;
    915 
    916         /* TODO: should we filter a set_mapping using low/high filters ? */
    917 
    918         ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context);
    919 
    920         switch (map->xid.type) {
    921 
    922         case ID_TYPE_UID:
    923                 kidstr = talloc_asprintf(ctx, "UID %lu",
    924                                          (unsigned long)map->xid.id);
    925                 break;
    926 
    927         case ID_TYPE_GID:
    928                 kidstr = talloc_asprintf(ctx, "GID %lu",
    929                                          (unsigned long)map->xid.id);
    930                 break;
    931 
    932         default:
    933                 DEBUG(2, ("INVALID unix ID type: 0x02%x\n", map->xid.type));
    934                 return NT_STATUS_INVALID_PARAMETER;
    935         }
    936 
    937         if (kidstr == NULL) {
    938                 DEBUG(0, ("ERROR: Out of memory!\n"));
    939                 ret = NT_STATUS_NO_MEMORY;
    940                 goto done;
    941         }
    942 
    943         if ((ksidstr = talloc_asprintf(
    944                      ctx, "%s", sid_to_fstring(tmp, map->sid))) == NULL) {
    945                 DEBUG(0, ("Out of memory!\n"));
    946                 ret = NT_STATUS_NO_MEMORY;
    947                 goto done;
    948         }
    949 
    950         DEBUG(10, ("Storing %s <-> %s map\n", ksidstr, kidstr));
    951         kid = string_term_tdb_data(kidstr);
    952         ksid = string_term_tdb_data(ksidstr);
    953 
    954         if (ctx->db->transaction_start(ctx->db) != 0) {
    955                 DEBUG(0, ("Failed to start transaction for %s\n",
    956                           ksidstr));
    957                 ret = NT_STATUS_INTERNAL_DB_ERROR;
    958                 goto done;
    959         }
    960 
    961         ret = dbwrap_store(ctx->db, ksid, kid, TDB_REPLACE);
    962         if (!NT_STATUS_IS_OK(ret)) {
    963                 ctx->db->transaction_cancel(ctx->db);
    964                 DEBUG(0, ("Error storing SID -> ID (%s -> %s): %s\n",
    965                           ksidstr, kidstr, nt_errstr(ret)));
    966                 goto done;
    967         }
    968         ret = dbwrap_store(ctx->db, kid, ksid, TDB_REPLACE);
    969         if (!NT_STATUS_IS_OK(ret)) {
    970                 ctx->db->transaction_cancel(ctx->db);
    971                 DEBUG(0, ("Error storing ID -> SID (%s -> %s): %s\n",
    972                           kidstr, ksidstr, nt_errstr(ret)));
    973                 goto done;
    974         }
    975 
    976         if (ctx->db->transaction_commit(ctx->db) != 0) {
    977                 DEBUG(0, ("Failed to commit transaction for (%s -> %s)\n",
    978                           ksidstr, kidstr));
    979                 ret = NT_STATUS_INTERNAL_DB_ERROR;
    980                 goto done;
    981         }
    982 
    983         DEBUG(10,("Stored %s <-> %s\n", ksidstr, kidstr));
    984         ret = NT_STATUS_OK;
    985 
    986 done:
    987         talloc_free(ksidstr);
    988         talloc_free(kidstr);
    989         return ret;
    990 }
    991 
    992 /**********************************
    993  remove a mapping.
    994 **********************************/
    995 
    996 static NTSTATUS idmap_tdb_remove_mapping(struct idmap_domain *dom,
    997                                          const struct id_map *map)
    998 {
    999         struct idmap_tdb_context *ctx;
    1000         NTSTATUS ret;
    1001         TDB_DATA ksid, kid, data;
    1002         char *ksidstr, *kidstr;
    1003         fstring tmp;
    1004 
    1005         if (!map || !map->sid) {
    1006                 return NT_STATUS_INVALID_PARAMETER;
    1007         }
    1008 
    1009         ksidstr = kidstr = NULL;
    1010         data.dptr = NULL;
    1011 
    1012         /* TODO: should we filter a remove_mapping using low/high filters ? */
    1013 
    1014         ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context);
    1015 
    1016         switch (map->xid.type) {
    1017 
    1018         case ID_TYPE_UID:
    1019                 kidstr = talloc_asprintf(ctx, "UID %lu",
    1020                                          (unsigned long)map->xid.id);
    1021                 break;
    1022 
    1023         case ID_TYPE_GID:
    1024                 kidstr = talloc_asprintf(ctx, "GID %lu",
    1025                                          (unsigned long)map->xid.id);
    1026                 break;
    1027 
    1028         default:
    1029                 DEBUG(2, ("INVALID unix ID type: 0x02%x\n", map->xid.type));
    1030                 return NT_STATUS_INVALID_PARAMETER;
    1031         }
    1032 
    1033         if (kidstr == NULL) {
    1034                 DEBUG(0, ("ERROR: Out of memory!\n"));
    1035                 ret = NT_STATUS_NO_MEMORY;
    1036                 goto done;
    1037         }
    1038 
    1039         if ((ksidstr = talloc_asprintf(
    1040                      ctx, "%s", sid_to_fstring(tmp, map->sid))) == NULL) {
    1041                 DEBUG(0, ("Out of memory!\n"));
    1042                 ret = NT_STATUS_NO_MEMORY;
    1043                 goto done;
    1044         }
    1045 
    1046         DEBUG(10, ("Checking %s <-> %s map\n", ksidstr, kidstr));
    1047         ksid = string_term_tdb_data(ksidstr);
    1048         kid = string_term_tdb_data(kidstr);
    1049 
    1050         if (ctx->db->transaction_start(ctx->db) != 0) {
    1051                 DEBUG(0, ("Failed to start transaction for %s\n",
    1052                           ksidstr));
    1053                 return NT_STATUS_INTERNAL_DB_ERROR;
    1054         }
    1055 
    1056         /* Check if sid is present in database */
    1057         data = dbwrap_fetch(ctx->db, NULL, ksid);
    1058         if (!data.dptr) {
    1059                 ctx->db->transaction_cancel(ctx->db);
    1060                 DEBUG(10,("Record %s not found\n", ksidstr));
    1061                 ret = NT_STATUS_NONE_MAPPED;
    1062                 goto done;
    1063         }
    1064 
    1065         /* Check if sid is mapped to the specified ID */
    1066         if ((data.dsize != kid.dsize) ||
    1067             (memcmp(data.dptr, kid.dptr, data.dsize) != 0)) {
    1068                 ctx->db->transaction_cancel(ctx->db);
    1069                 DEBUG(10,("Specified SID does not map to specified ID\n"));
    1070                 DEBUGADD(10,("Actual mapping is %s -> %s\n", ksidstr,
    1071                          (const char *)data.dptr));
    1072                 ret = NT_STATUS_NONE_MAPPED;
    1073                 goto done;
    1074         }
    1075 
    1076         DEBUG(10, ("Removing %s <-> %s map\n", ksidstr, kidstr));
    1077 
    1078         /* Delete previous mappings. */
    1079 
    1080         DEBUG(10, ("Deleting existing mapping %s -> %s\n", ksidstr, kidstr ));
    1081         ret = dbwrap_delete(ctx->db, ksid);
    1082         if (!NT_STATUS_IS_OK(ret)) {
    1083                 DEBUG(0,("Warning: Failed to delete %s: %s\n",
    1084                          ksidstr, nt_errstr(ret)));
    1085         }
    1086 
    1087         DEBUG(10,("Deleting existing mapping %s -> %s\n", kidstr, ksidstr ));
    1088         ret = dbwrap_delete(ctx->db, kid);
    1089         if (!NT_STATUS_IS_OK(ret)) {
    1090                 DEBUG(0,("Warning: Failed to delete %s: %s\n",
    1091                          kidstr, nt_errstr(ret)));
    1092         }
    1093 
    1094         if (ctx->db->transaction_commit(ctx->db) != 0) {
    1095                 DEBUG(0, ("Failed to commit transaction for (%s -> %s)\n",
    1096                           ksidstr, kidstr));
    1097                 ret = NT_STATUS_INTERNAL_DB_ERROR;
    1098                 goto done;
    1099         }
    1100 
    1101         ret = NT_STATUS_OK;
    1102 
    1103 done:
    1104         talloc_free(ksidstr);
    1105         talloc_free(kidstr);
    1106         talloc_free(data.dptr);
    1107         return ret;
    1108 }
     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
    1109933
    1110934/**********************************
     
    1112936**********************************/
    1113937
    1114 static NTSTATUS idmap_tdb_close(struct idmap_domain *dom)
    1115 {
    1116         struct idmap_tdb_context *ctx;
    1117 
    1118         if (dom->private_data) {
    1119                 ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context);
    1120 
    1121                 TALLOC_FREE(ctx->db);
    1122         }
    1123         return NT_STATUS_OK;
    1124 }
    1125 
    1126 struct dump_data {
    1127         TALLOC_CTX *memctx;
    1128         struct id_map **maps;
    1129         int *num_maps;
    1130         NTSTATUS ret;
    1131 };
    1132 
    1133 static int idmap_tdb_dump_one_entry(struct db_record *rec, void *pdata)
    1134 {
    1135         struct dump_data *data = talloc_get_type(pdata, struct dump_data);
    1136         struct id_map *maps;
    1137         int num_maps = *data->num_maps;
    1138 
    1139         /* ignore any record but the ones with a SID as key */
    1140         if (strncmp((const char *)rec->key.dptr, "S-", 2) == 0) {
    1141 
    1142                 maps = talloc_realloc(NULL, *data->maps, struct id_map, num_maps+1);
    1143                 if ( ! maps) {
    1144                         DEBUG(0, ("Out of memory!\n"));
    1145                         data->ret = NT_STATUS_NO_MEMORY;
    1146                         return -1;
    1147                 }
    1148                 *data->maps = maps;
    1149                 maps[num_maps].sid = talloc(maps, DOM_SID);
    1150                 if ( ! maps[num_maps].sid) {
    1151                         DEBUG(0, ("Out of memory!\n"));
    1152                         data->ret = NT_STATUS_NO_MEMORY;
    1153                         return -1;
    1154                 }
    1155 
    1156                 if (!string_to_sid(maps[num_maps].sid, (const char *)rec->key.dptr)) {
    1157                         DEBUG(10,("INVALID record %s\n", (const char *)rec->key.dptr));
    1158                         /* continue even with errors */
    1159                         return 0;
    1160                 }
    1161 
    1162                 /* Try a UID record. */
    1163                 if (sscanf((const char *)rec->value.dptr, "UID %u", &(maps[num_maps].xid.id)) == 1) {
    1164                         maps[num_maps].xid.type = ID_TYPE_UID;
    1165                         maps[num_maps].status = ID_MAPPED;
    1166                         *data->num_maps = num_maps + 1;
    1167 
    1168                 /* Try a GID record. */
    1169                 } else
    1170                 if (sscanf((const char *)rec->value.dptr, "GID %u", &(maps[num_maps].xid.id)) == 1) {
    1171                         maps[num_maps].xid.type = ID_TYPE_GID;
    1172                         maps[num_maps].status = ID_MAPPED;
    1173                         *data->num_maps = num_maps + 1;
    1174 
    1175                 /* Unknown record type ! */
    1176                 } else {
    1177                         maps[num_maps].status = ID_UNKNOWN;
    1178                         DEBUG(2, ("Found INVALID record %s -> %s\n",
    1179                                 (const char *)rec->key.dptr,
    1180                                 (const char *)rec->value.dptr));
    1181                         /* do not increment num_maps */
    1182                 }
    1183         }
    1184 
    1185         return 0;
    1186 }
    1187 
    1188 /**********************************
    1189  Dump all mappings out
    1190 **********************************/
    1191 
    1192 static NTSTATUS idmap_tdb_dump_data(struct idmap_domain *dom, struct id_map **maps, int *num_maps)
    1193 {
    1194         struct idmap_tdb_context *ctx;
    1195         struct dump_data *data;
    1196         NTSTATUS ret = NT_STATUS_OK;
    1197 
    1198         ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context);
    1199 
    1200         data = TALLOC_ZERO_P(ctx, struct dump_data);
    1201         if ( ! data) {
    1202                 DEBUG(0, ("Out of memory!\n"));
    1203                 return NT_STATUS_NO_MEMORY;
    1204         }
    1205         data->maps = maps;
    1206         data->num_maps = num_maps;
    1207         data->ret = NT_STATUS_OK;
    1208 
    1209         ctx->db->traverse_read(ctx->db, idmap_tdb_dump_one_entry, data);
    1210 
    1211         if ( ! NT_STATUS_IS_OK(data->ret)) {
    1212                 ret = data->ret;
    1213         }
    1214 
    1215         talloc_free(data);
    1216         return ret;
    1217 }
    1218 
    1219938static struct idmap_methods db_methods = {
    1220 
    1221939        .init = idmap_tdb_db_init,
    1222940        .unixids_to_sids = idmap_tdb_unixids_to_sids,
    1223941        .sids_to_unixids = idmap_tdb_sids_to_unixids,
    1224         .set_mapping = idmap_tdb_set_mapping,
    1225         .remove_mapping = idmap_tdb_remove_mapping,
    1226         .dump_data = idmap_tdb_dump_data,
    1227         .close_fn = idmap_tdb_close
     942        .allocate_id = idmap_tdb_get_new_id,
    1228943};
    1229944
    1230 static struct idmap_alloc_methods db_alloc_methods = {
    1231 
    1232         .init = idmap_tdb_alloc_init,
    1233         .allocate_id = idmap_tdb_allocate_id,
    1234         .get_id_hwm = idmap_tdb_get_hwm,
    1235         .set_id_hwm = idmap_tdb_set_hwm,
    1236         .close_fn = idmap_tdb_alloc_close
    1237 };
    1238 
    1239 NTSTATUS idmap_alloc_tdb_init(void)
    1240 {
    1241         return smb_register_idmap_alloc(SMB_IDMAP_INTERFACE_VERSION, "tdb", &db_alloc_methods);
    1242 }
    1243 
    1244945NTSTATUS idmap_tdb_init(void)
    1245946{
    1246         NTSTATUS ret;
    1247 
    1248947        DEBUG(10, ("calling idmap_tdb_init\n"));
    1249948
    1250         /* FIXME: bad hack to actually register also the alloc_tdb module without changining configure.in */
    1251         ret = idmap_alloc_tdb_init();
    1252         if (! NT_STATUS_IS_OK(ret)) {
    1253                 return ret;
    1254         }
    1255949        return smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION, "tdb", &db_methods);
    1256950}
  • vendor/current/source3/winbindd/idmap_tdb2.c

    r414 r740  
    1515   Copyright (C) Jeremy Allison 2006
    1616   Copyright (C) Simo Sorce 2003-2006
    17    
     17   Copyright (C) Michael Adam 2009-2010
     18
    1819   This program is free software; you can redistribute it and/or modify
    1920   it under the terms of the GNU General Public License as published by
    2021   the Free Software Foundation; either version 2 of the License, or
    2122   (at your option) any later version.
    22    
     23
    2324   This program is distributed in the hope that it will be useful,
    2425   but WITHOUT ANY WARRANTY; without even the implied warranty of
    2526   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    2627   GNU General Public License for more details.
    27    
     28
    2829   You should have received a copy of the GNU General Public License
    2930   along with this program; if not, write to the Free Software
     
    3233
    3334#include "includes.h"
     35#include "system/filesys.h"
    3436#include "winbindd.h"
     37#include "idmap.h"
     38#include "idmap_rw.h"
     39#include "dbwrap.h"
     40#include "../libcli/security/dom_sid.h"
     41#include "util_tdb.h"
    3542
    3643#undef DBGC_CLASS
    3744#define DBGC_CLASS DBGC_IDMAP
     45
     46struct idmap_tdb2_context {
     47        struct db_context *db;
     48        const char *script; /* script to provide idmaps */
     49        struct idmap_rw_ops *rw_ops;
     50};
    3851
    3952/* High water mark keys */
     
    4154#define HWM_USER   "USER HWM"
    4255
    43 static struct idmap_tdb2_state {
    44         /* User and group id pool */
    45         uid_t low_uid, high_uid;               /* Range of uids to allocate */
    46         gid_t low_gid, high_gid;               /* Range of gids to allocate */
    47         const char *idmap_script;
    48 } idmap_tdb2_state;
    49 
    50 
    51 
    52 /* handle to the permanent tdb */
    53 static struct db_context *idmap_tdb2;
    54 
    55 static NTSTATUS idmap_tdb2_alloc_load(void);
    56 
    57 static NTSTATUS idmap_tdb2_load_ranges(void)
    58 {
    59         uid_t low_uid = 0;
    60         uid_t high_uid = 0;
    61         gid_t low_gid = 0;
    62         gid_t high_gid = 0;
    63 
    64         if (!lp_idmap_uid(&low_uid, &high_uid)) {
    65                 DEBUG(1, ("idmap uid missing\n"));
    66                 return NT_STATUS_UNSUCCESSFUL;
    67         }
    68 
    69         if (!lp_idmap_gid(&low_gid, &high_gid)) {
    70                 DEBUG(1, ("idmap gid missing\n"));
    71                 return NT_STATUS_UNSUCCESSFUL;
    72         }
    73 
    74         idmap_tdb2_state.low_uid = low_uid;
    75         idmap_tdb2_state.high_uid = high_uid;
    76         idmap_tdb2_state.low_gid = low_gid;
    77         idmap_tdb2_state.high_gid = high_gid;
    78 
    79         if (idmap_tdb2_state.high_uid <= idmap_tdb2_state.low_uid) {
    80                 DEBUG(1, ("idmap uid range missing or invalid\n"));
    81                 DEBUGADD(1, ("idmap will be unable to map foreign SIDs\n"));
    82                 return NT_STATUS_UNSUCCESSFUL;
    83         }
    84 
    85         if (idmap_tdb2_state.high_gid <= idmap_tdb2_state.low_gid) {
    86                 DEBUG(1, ("idmap gid range missing or invalid\n"));
    87                 DEBUGADD(1, ("idmap will be unable to map foreign SIDs\n"));
    88                 return NT_STATUS_UNSUCCESSFUL;
     56
     57/*
     58 * check and initialize high/low water marks in the db
     59 */
     60static NTSTATUS idmap_tdb2_init_hwm(struct idmap_domain *dom)
     61{
     62        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);
     67
     68        /* Create high water marks for group and user id */
     69
     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);
     74                if (!NT_STATUS_IS_OK(status)) {
     75                        DEBUG(0, ("Unable to initialise user hwm in idmap "
     76                                  "database: %s\n", nt_errstr(status)));
     77                        return NT_STATUS_INTERNAL_DB_ERROR;
     78                }
     79        }
     80
     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);
     85                if (!NT_STATUS_IS_OK(status)) {
     86                        DEBUG(0, ("Unable to initialise group hwm in idmap "
     87                                  "database: %s\n", nt_errstr(status)));
     88                        return NT_STATUS_INTERNAL_DB_ERROR;
     89                }
    8990        }
    9091
    9192        return NT_STATUS_OK;
    9293}
     94
    9395
    9496/*
    9597  open the permanent tdb
    9698 */
    97 static NTSTATUS idmap_tdb2_open_db(void)
     99static NTSTATUS idmap_tdb2_open_db(struct idmap_domain *dom)
    98100{
    99101        char *db_path;
    100        
    101         if (idmap_tdb2) {
     102        struct idmap_tdb2_context *ctx;
     103
     104        ctx = talloc_get_type(dom->private_data, struct idmap_tdb2_context);
     105
     106        if (ctx->db) {
    102107                /* its already open */
    103108                return NT_STATUS_OK;
    104109        }
    105110
    106         db_path = lp_parm_talloc_string(-1, "tdb", "idmap2.tdb", NULL);
    107         if (db_path == NULL) {
    108                 /* fall back to the private directory, which, despite
    109                    its name, is usually on shared storage */
    110                 db_path = talloc_asprintf(NULL, "%s/idmap2.tdb", lp_private_dir());
    111         }
     111        db_path = talloc_asprintf(NULL, "%s/idmap2.tdb", lp_private_dir());
    112112        NT_STATUS_HAVE_NO_MEMORY(db_path);
    113113
    114114        /* Open idmap repository */
    115         idmap_tdb2 = db_open(NULL, db_path, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0644);
     115        ctx->db = db_open(ctx, db_path, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0644);
    116116        TALLOC_FREE(db_path);
    117117
    118         if (idmap_tdb2 == NULL) {
     118        if (ctx->db == NULL) {
    119119                DEBUG(0, ("Unable to open idmap_tdb2 database '%s'\n",
    120120                          db_path));
     
    122122        }
    123123
    124         /* load the ranges and high/low water marks */
    125         return idmap_tdb2_alloc_load();
    126 }
    127 
    128 
    129 /*
    130   load the idmap allocation ranges and high/low water marks
    131 */
    132 static NTSTATUS idmap_tdb2_alloc_load(void)
    133 {
    134         NTSTATUS status;
    135         uint32 low_id;
    136 
    137         /* see if a idmap script is configured */
    138         idmap_tdb2_state.idmap_script = lp_parm_const_string(-1, "idmap",
    139                                                              "script", NULL);
    140 
    141         if (idmap_tdb2_state.idmap_script) {
    142                 DEBUG(1, ("using idmap script '%s'\n",
    143                           idmap_tdb2_state.idmap_script));
    144         }
    145 
    146         /* load ranges */
    147 
    148         status = idmap_tdb2_load_ranges();
    149         if (!NT_STATUS_IS_OK(status)) {
    150                 return status;
    151         }
    152 
    153         /* Create high water marks for group and user id */
    154 
    155         low_id = dbwrap_fetch_int32(idmap_tdb2, HWM_USER);
    156         if ((low_id == -1) || (low_id < idmap_tdb2_state.low_uid)) {
    157                 if (!NT_STATUS_IS_OK(dbwrap_trans_store_int32(
    158                                              idmap_tdb2, HWM_USER,
    159                                              idmap_tdb2_state.low_uid))) {
    160                         DEBUG(0, ("Unable to initialise user hwm in idmap "
    161                                   "database\n"));
    162                         return NT_STATUS_INTERNAL_DB_ERROR;
    163                 }
    164         }
    165 
    166         low_id = dbwrap_fetch_int32(idmap_tdb2, HWM_GROUP);
    167         if ((low_id == -1) || (low_id < idmap_tdb2_state.low_gid)) {
    168                 if (!NT_STATUS_IS_OK(dbwrap_trans_store_int32(
    169                                              idmap_tdb2, HWM_GROUP,
    170                                              idmap_tdb2_state.low_gid))) {
    171                         DEBUG(0, ("Unable to initialise group hwm in idmap "
    172                                   "database\n"));
    173                         return NT_STATUS_INTERNAL_DB_ERROR;
    174                 }
    175         }
    176 
    177         return NT_STATUS_OK;
    178 }
    179 
    180 
    181 /*
    182   Initialise idmap alloc database.
    183 */
    184 static NTSTATUS idmap_tdb2_alloc_init(const char *params)
    185 {
    186         /* nothing to do - we want to avoid opening the permanent
    187            database if possible. Instead we load the params when we
    188            first need it. */
    189         return NT_STATUS_OK;
     124        return idmap_tdb2_init_hwm(dom);
    190125}
    191126
     
    248183}
    249184
    250 static NTSTATUS idmap_tdb2_allocate_id(struct unixid *xid)
     185static NTSTATUS idmap_tdb2_allocate_id(struct idmap_domain *dom,
     186                                       struct unixid *xid)
    251187{
    252188        const char *hwmkey;
     
    256192        NTSTATUS status;
    257193        struct idmap_tdb2_allocate_id_context state;
    258 
    259         status = idmap_tdb2_open_db();
     194        struct idmap_tdb2_context *ctx;
     195
     196        status = idmap_tdb2_open_db(dom);
    260197        NT_STATUS_NOT_OK_RETURN(status);
     198
     199        ctx = talloc_get_type(dom->private_data, struct idmap_tdb2_context);
    261200
    262201        /* Get current high water mark */
     
    266205                hwmkey = HWM_USER;
    267206                hwmtype = "UID";
    268                 high_hwm = idmap_tdb2_state.high_uid;
    269207                break;
    270208
     
    272210                hwmkey = HWM_GROUP;
    273211                hwmtype = "GID";
    274                 high_hwm = idmap_tdb2_state.high_gid;
    275212                break;
    276213
     
    279216                return NT_STATUS_INVALID_PARAMETER;
    280217        }
     218
     219        high_hwm = dom->high_id;
    281220
    282221        state.hwm = hwm;
     
    285224        state.hwmkey = hwmkey;
    286225
    287         status = dbwrap_trans_do(idmap_tdb2, idmap_tdb2_allocate_id_action,
     226        status = dbwrap_trans_do(ctx->db, idmap_tdb2_allocate_id_action,
    288227                                 &state);
    289228
    290229        if (NT_STATUS_IS_OK(status)) {
    291230                xid->id = state.hwm;
    292                 DEBUG(10,("New %s = %d\n", hwmtype, hwm));
     231                DEBUG(10,("New %s = %d\n", hwmtype, state.hwm));
    293232        } else {
    294233                DEBUG(1, ("Error allocating a new %s\n", hwmtype));
     
    298237}
    299238
    300 /*
    301   Get current highest id.
    302 */
    303 static NTSTATUS idmap_tdb2_get_hwm(struct unixid *xid)
    304 {
    305         const char *hwmkey;
    306         const char *hwmtype;
    307         uint32_t hwm;
    308         uint32_t high_hwm;
    309         NTSTATUS status;
    310 
    311         status = idmap_tdb2_open_db();
    312         NT_STATUS_NOT_OK_RETURN(status);
    313 
    314         /* Get current high water mark */
    315         switch (xid->type) {
    316 
    317         case ID_TYPE_UID:
    318                 hwmkey = HWM_USER;
    319                 hwmtype = "UID";
    320                 high_hwm = idmap_tdb2_state.high_uid;
    321                 break;
    322 
    323         case ID_TYPE_GID:
    324                 hwmkey = HWM_GROUP;
    325                 hwmtype = "GID";
    326                 high_hwm = idmap_tdb2_state.high_gid;
    327                 break;
    328 
    329         default:
    330                 return NT_STATUS_INVALID_PARAMETER;
    331         }
    332 
    333         if ((hwm = dbwrap_fetch_int32(idmap_tdb2, hwmkey)) == -1) {
    334                 return NT_STATUS_INTERNAL_DB_ERROR;
    335         }
    336 
    337         xid->id = hwm;
    338 
    339         /* Warn if it is out of range */
    340         if (hwm >= high_hwm) {
    341                 DEBUG(0, ("Warning: %s range full!! (max: %lu)\n",
    342                           hwmtype, (unsigned long)high_hwm));
    343         }
    344 
    345         return NT_STATUS_OK;
    346 }
    347 
    348 /*
    349   Set high id.
    350 */
    351 static NTSTATUS idmap_tdb2_set_hwm(struct unixid *xid)
    352 {
    353         /* not supported, or we would invalidate the cache tdb on
    354            other nodes */
    355         DEBUG(0,("idmap_tdb2_set_hwm not supported\n"));
    356         return NT_STATUS_NOT_SUPPORTED;
    357 }
    358 
    359 /*
    360   Close the alloc tdb
    361 */
    362 static NTSTATUS idmap_tdb2_alloc_close(void)
    363 {
    364         /* don't actually close it */
    365         return NT_STATUS_OK;
     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 */
     244static 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;
    366261}
    367262
     
    369264  IDMAP MAPPING TDB BACKEND
    370265*/
    371 struct idmap_tdb2_context {
    372         uint32_t filter_low_id;
    373         uint32_t filter_high_id;
    374 };
     266
     267static NTSTATUS idmap_tdb2_set_mapping(struct idmap_domain *dom,
     268                                       const struct id_map *map);
    375269
    376270/*
    377271  Initialise idmap database.
    378272*/
    379 static NTSTATUS idmap_tdb2_db_init(struct idmap_domain *dom,
    380                                    const char *params)
     273static NTSTATUS idmap_tdb2_db_init(struct idmap_domain *dom)
    381274{
    382275        NTSTATUS ret;
    383276        struct idmap_tdb2_context *ctx;
    384         NTSTATUS status;
    385 
    386         status = idmap_tdb2_open_db();
    387         NT_STATUS_NOT_OK_RETURN(status);
    388 
    389         ctx = talloc(dom, struct idmap_tdb2_context);
     277        char *config_option = NULL;
     278        const char * idmap_script = NULL;
     279
     280        ctx = talloc_zero(dom, struct idmap_tdb2_context);
    390281        if ( ! ctx) {
    391282                DEBUG(0, ("Out of memory!\n"));
     
    393284        }
    394285
    395         if (strequal(dom->name, "*")) {
    396                 uid_t low_uid = 0;
    397                 uid_t high_uid = 0;
    398                 gid_t low_gid = 0;
    399                 gid_t high_gid = 0;
    400 
    401                 ctx->filter_low_id = 0;
    402                 ctx->filter_high_id = 0;
    403 
    404                 if (lp_idmap_uid(&low_uid, &high_uid)) {
    405                         ctx->filter_low_id = low_uid;
    406                         ctx->filter_high_id = high_uid;
    407                 } else {
    408                         DEBUG(3, ("Warning: 'idmap uid' not set!\n"));
    409                 }
    410 
    411                 if (lp_idmap_gid(&low_gid, &high_gid)) {
    412                         if ((low_gid != low_uid) || (high_gid != high_uid)) {
    413                                 DEBUG(1, ("Warning: 'idmap uid' and 'idmap gid'"
    414                                       " ranges do not agree -- building "
    415                                       "intersection\n"));
    416                                 ctx->filter_low_id = MAX(ctx->filter_low_id,
    417                                                          low_gid);
    418                                 ctx->filter_high_id = MIN(ctx->filter_high_id,
    419                                                           high_gid);
    420                         }
    421                 } else {
    422                         DEBUG(3, ("Warning: 'idmap gid' not set!\n"));
    423                 }
    424         } else {
    425                 char *config_option = NULL;
    426                 const char *range;
    427                 config_option = talloc_asprintf(ctx, "idmap config %s", dom->name);
    428                 if ( ! config_option) {
    429                         DEBUG(0, ("Out of memory!\n"));
    430                         ret = NT_STATUS_NO_MEMORY;
    431                         goto failed;
    432                 }
    433 
    434                 range = lp_parm_const_string(-1, config_option, "range", NULL);
    435                 if (( ! range) ||
    436                     (sscanf(range, "%u - %u", &ctx->filter_low_id, &ctx->filter_high_id) != 2))
    437                 {
    438                         ctx->filter_low_id = 0;
    439                         ctx->filter_high_id = 0;
    440                 }
    441 
    442                 talloc_free(config_option);
    443         }
    444 
    445         if (ctx->filter_low_id > ctx->filter_high_id) {
    446                 ctx->filter_low_id = 0;
    447                 ctx->filter_high_id = 0;
    448         }
     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;
    449319
    450320        dom->private_data = ctx;
     321
     322        ret = idmap_tdb2_open_db(dom);
     323        if (!NT_STATUS_IS_OK(ret)) {
     324                goto failed;
     325        }
    451326
    452327        return NT_STATUS_OK;
     
    456331        return ret;
    457332}
     333
     334
     335/**
     336 * store a mapping in the database.
     337 */
    458338
    459339struct idmap_tdb2_set_mapping_context {
     
    503383done:
    504384        talloc_free(tmp_ctx);
     385        return ret;
     386}
     387
     388static NTSTATUS idmap_tdb2_set_mapping(struct idmap_domain *dom, const struct id_map *map)
     389{
     390        struct idmap_tdb2_context *ctx;
     391        NTSTATUS ret;
     392        char *ksidstr, *kidstr;
     393        struct idmap_tdb2_set_mapping_context state;
     394
     395        if (!map || !map->sid) {
     396                return NT_STATUS_INVALID_PARAMETER;
     397        }
     398
     399        ksidstr = kidstr = NULL;
     400
     401        /* TODO: should we filter a set_mapping using low/high filters ? */
     402
     403        ctx = talloc_get_type(dom->private_data, struct idmap_tdb2_context);
     404
     405        switch (map->xid.type) {
     406
     407        case ID_TYPE_UID:
     408                kidstr = talloc_asprintf(ctx, "UID %lu", (unsigned long)map->xid.id);
     409                break;
     410
     411        case ID_TYPE_GID:
     412                kidstr = talloc_asprintf(ctx, "GID %lu", (unsigned long)map->xid.id);
     413                break;
     414
     415        default:
     416                DEBUG(2, ("INVALID unix ID type: 0x02%x\n", map->xid.type));
     417                return NT_STATUS_INVALID_PARAMETER;
     418        }
     419
     420        if (kidstr == NULL) {
     421                DEBUG(0, ("ERROR: Out of memory!\n"));
     422                ret = NT_STATUS_NO_MEMORY;
     423                goto done;
     424        }
     425
     426        ksidstr = sid_string_talloc(ctx, map->sid);
     427        if (ksidstr == NULL) {
     428                DEBUG(0, ("Out of memory!\n"));
     429                ret = NT_STATUS_NO_MEMORY;
     430                goto done;
     431        }
     432
     433        state.ksidstr = ksidstr;
     434        state.kidstr = kidstr;
     435
     436        ret = dbwrap_trans_do(ctx->db, idmap_tdb2_set_mapping_action,
     437                              &state);
     438
     439done:
     440        talloc_free(ksidstr);
     441        talloc_free(kidstr);
     442        return ret;
     443}
     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 */
     453static 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
    505462        return ret;
    506463}
     
    531488        unsigned long v;
    532489
    533         cmd = talloc_asprintf(ctx, "%s ", idmap_tdb2_state.idmap_script);
     490        cmd = talloc_asprintf(ctx, "%s ", ctx->script);
    534491        NT_STATUS_HAVE_NO_MEMORY(cmd); 
    535492
     
    562519                if (!string_to_sid(map->sid, &line[4])) {
    563520                        DEBUG(0,("Bad SID in '%s' from idmap script %s\n",
    564                                  line, idmap_tdb2_state.idmap_script));
     521                                 line, ctx->script));
    565522                        return NT_STATUS_NONE_MAPPED;                   
    566523                }
    567524        } else {
    568525                DEBUG(0,("Bad reply '%s' from idmap script %s\n",
    569                          line, idmap_tdb2_state.idmap_script));
     526                         line, ctx->script));
    570527                return NT_STATUS_NONE_MAPPED;
    571528        }
     
    579536  Single id to sid lookup function.
    580537*/
    581 static NTSTATUS idmap_tdb2_id_to_sid(struct idmap_tdb2_context *ctx, struct id_map *map)
     538static NTSTATUS idmap_tdb2_id_to_sid(struct idmap_domain *dom, struct id_map *map)
    582539{
    583540        NTSTATUS ret;
     
    585542        char *keystr;
    586543        NTSTATUS status;
    587 
    588         status = idmap_tdb2_open_db();
     544        struct idmap_tdb2_context *ctx;
     545
     546
     547        if (!dom || !map) {
     548                return NT_STATUS_INVALID_PARAMETER;
     549        }
     550
     551        status = idmap_tdb2_open_db(dom);
    589552        NT_STATUS_NOT_OK_RETURN(status);
    590553
    591         if (!ctx || !map) {
    592                 return NT_STATUS_INVALID_PARAMETER;
    593         }
     554        ctx = talloc_get_type(dom->private_data, struct idmap_tdb2_context);
    594555
    595556        /* apply filters before checking */
    596         if ((ctx->filter_low_id && (map->xid.id < ctx->filter_low_id)) ||
    597             (ctx->filter_high_id && (map->xid.id > ctx->filter_high_id))) {
     557        if (!idmap_unix_id_is_in_range(map->xid.id, dom)) {
    598558                DEBUG(5, ("Requested id (%u) out of range (%u - %u). Filtered!\n",
    599                                 map->xid.id, ctx->filter_low_id, ctx->filter_high_id));
     559                                map->xid.id, dom->low_id, dom->high_id));
    600560                return NT_STATUS_NONE_MAPPED;
    601561        }
     
    606566                keystr = talloc_asprintf(ctx, "UID %lu", (unsigned long)map->xid.id);
    607567                break;
    608                
     568
    609569        case ID_TYPE_GID:
    610570                keystr = talloc_asprintf(ctx, "GID %lu", (unsigned long)map->xid.id);
     
    616576        }
    617577
    618         /* final SAFE_FREE safe */
    619         data.dptr = NULL;
    620 
    621578        if (keystr == NULL) {
    622579                DEBUG(0, ("Out of memory!\n"));
     
    628585
    629586        /* Check if the mapping exists */
    630         data = dbwrap_fetch_bystring(idmap_tdb2, keystr, keystr);
     587        data = dbwrap_fetch_bystring(ctx->db, keystr, keystr);
    631588
    632589        if (!data.dptr) {
     
    635592
    636593                DEBUG(10,("Record %s not found\n", keystr));
    637                 if (idmap_tdb2_state.idmap_script == NULL) {
     594                if (ctx->script == NULL) {
    638595                        ret = NT_STATUS_NONE_MAPPED;
    639596                        goto done;
     
    641598
    642599                ret = idmap_tdb2_script(ctx, map, "IDTOSID %s", keystr);
    643 
    644                 /* store it on shared storage */
    645600                if (!NT_STATUS_IS_OK(ret)) {
    646601                        goto done;
     
    656611                store_state.kidstr = keystr;
    657612
    658                 ret = dbwrap_trans_do(idmap_tdb2, idmap_tdb2_set_mapping_action,
     613                ret = dbwrap_trans_do(ctx->db, idmap_tdb2_set_mapping_action,
    659614                                      &store_state);
    660615                goto done;
    661616        }
    662                
     617
    663618        if (!string_to_sid(map->sid, (const char *)data.dptr)) {
    664619                DEBUG(10,("INVALID SID (%s) in record %s\n",
     
    680635 Single sid to id lookup function.
    681636*/
    682 static NTSTATUS idmap_tdb2_sid_to_id(struct idmap_tdb2_context *ctx, struct id_map *map)
     637static NTSTATUS idmap_tdb2_sid_to_id(struct idmap_domain *dom, struct id_map *map)
    683638{
    684639        NTSTATUS ret;
     
    686641        char *keystr;
    687642        unsigned long rec_id = 0;
     643        struct idmap_tdb2_context *ctx;
    688644        TALLOC_CTX *tmp_ctx = talloc_stackframe();
    689645
    690         ret = idmap_tdb2_open_db();
     646        ret = idmap_tdb2_open_db(dom);
    691647        NT_STATUS_NOT_OK_RETURN(ret);
     648
     649        ctx = talloc_get_type(dom->private_data, struct idmap_tdb2_context);
    692650
    693651        keystr = sid_string_talloc(tmp_ctx, map->sid);
     
    701659
    702660        /* Check if sid is present in database */
    703         data = dbwrap_fetch_bystring(idmap_tdb2, tmp_ctx, keystr);
     661        data = dbwrap_fetch_bystring(ctx->db, tmp_ctx, keystr);
    704662        if (!data.dptr) {
    705663                char *idstr;
     
    708666                DEBUG(10,(__location__ " Record %s not found\n", keystr));
    709667
    710                 if (idmap_tdb2_state.idmap_script == NULL) {
     668                if (ctx->script == NULL) {
    711669                        ret = NT_STATUS_NONE_MAPPED;
    712670                        goto done;
    713671                }
    714                        
     672
    715673                ret = idmap_tdb2_script(ctx, map, "SIDTOID %s", keystr);
    716                 /* store it on shared storage */
    717674                if (!NT_STATUS_IS_OK(ret)) {
     675                        goto done;
     676                }
     677
     678                /* apply filters before returning result */
     679                if (!idmap_unix_id_is_in_range(map->xid.id, dom)) {
     680                        DEBUG(5, ("Script returned id (%u) out of range "
     681                                  "(%u - %u). Filtered!\n",
     682                                  map->xid.id, dom->low_id, dom->high_id));
     683                        ret = NT_STATUS_NONE_MAPPED;
    718684                        goto done;
    719685                }
     
    730696                store_state.kidstr = idstr;
    731697
    732                 ret = dbwrap_trans_do(idmap_tdb2, idmap_tdb2_set_mapping_action,
     698                ret = dbwrap_trans_do(ctx->db, idmap_tdb2_set_mapping_action,
    733699                                      &store_state);
    734700                goto done;
     
    751717                DEBUG(2, ("Found INVALID record %s -> %s\n", keystr, (const char *)data.dptr));
    752718                ret = NT_STATUS_INTERNAL_DB_ERROR;
    753         }
    754        
     719                goto done;
     720        }
     721
    755722        /* apply filters before returning result */
    756         if ((ctx->filter_low_id && (map->xid.id < ctx->filter_low_id)) ||
    757             (ctx->filter_high_id && (map->xid.id > ctx->filter_high_id))) {
     723        if (!idmap_unix_id_is_in_range(map->xid.id, dom)) {
    758724                DEBUG(5, ("Requested id (%u) out of range (%u - %u). Filtered!\n",
    759                                 map->xid.id, ctx->filter_low_id, ctx->filter_high_id));
     725                                map->xid.id, dom->low_id, dom->high_id));
    760726                ret = NT_STATUS_NONE_MAPPED;
    761727        }
     
    771737static NTSTATUS idmap_tdb2_unixids_to_sids(struct idmap_domain *dom, struct id_map **ids)
    772738{
    773         struct idmap_tdb2_context *ctx;
    774739        NTSTATUS ret;
    775740        int i;
     
    779744                ids[i]->status = ID_UNKNOWN;
    780745        }
    781        
    782         ctx = talloc_get_type(dom->private_data, struct idmap_tdb2_context);
    783746
    784747        for (i = 0; ids[i]; i++) {
    785                 ret = idmap_tdb2_id_to_sid(ctx, ids[i]);
     748                ret = idmap_tdb2_id_to_sid(dom, ids[i]);
    786749                if ( ! NT_STATUS_IS_OK(ret)) {
    787750
     
    793756                                continue;
    794757                        }
    795                        
     758
    796759                        /* some fatal error occurred, return immediately */
    797760                        goto done;
     
    811774  lookup a set of sids.
    812775*/
     776
     777struct idmap_tdb2_sids_to_unixids_context {
     778        struct idmap_domain *dom;
     779        struct id_map **ids;
     780        bool allocate_unmapped;
     781};
     782
     783static 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
     834done:
     835        return ret;
     836}
     837
    813838static NTSTATUS idmap_tdb2_sids_to_unixids(struct idmap_domain *dom, struct id_map **ids)
    814839{
     840        NTSTATUS ret;
     841        int i;
     842        struct idmap_tdb2_sids_to_unixids_context state;
    815843        struct idmap_tdb2_context *ctx;
    816         NTSTATUS ret;
    817         int i;
     844
     845        ctx = talloc_get_type(dom->private_data, struct idmap_tdb2_context);
    818846
    819847        /* initialize the status to avoid suprise */
     
    821849                ids[i]->status = ID_UNKNOWN;
    822850        }
    823        
    824         ctx = talloc_get_type(dom->private_data, struct idmap_tdb2_context);
    825 
    826         for (i = 0; ids[i]; i++) {
    827                 ret = idmap_tdb2_sid_to_id(ctx, ids[i]);
    828                 if ( ! NT_STATUS_IS_OK(ret)) {
    829 
    830                         /* if it is just a failed mapping continue */
    831                         if (NT_STATUS_EQUAL(ret, NT_STATUS_NONE_MAPPED)) {
    832 
    833                                 /* make sure it is marked as unmapped */
    834                                 ids[i]->status = ID_UNMAPPED;
    835                                 continue;
    836                         }
    837                        
    838                         /* some fatal error occurred, return immediately */
    839                         goto done;
    840                 }
    841 
    842                 /* all ok, id is mapped */
    843                 ids[i]->status = ID_MAPPED;
    844         }
    845 
    846         ret = NT_STATUS_OK;
    847 
    848 done:
    849         return ret;
    850 }
    851 
    852 
    853 /*
    854   set a mapping.
    855 */
    856 
    857 static NTSTATUS idmap_tdb2_set_mapping(struct idmap_domain *dom, const struct id_map *map)
    858 {
    859         struct idmap_tdb2_context *ctx;
    860         NTSTATUS ret;
    861         char *ksidstr, *kidstr;
    862         struct idmap_tdb2_set_mapping_context state;
    863 
    864         if (!map || !map->sid) {
    865                 return NT_STATUS_INVALID_PARAMETER;
    866         }
    867 
    868         ksidstr = kidstr = NULL;
    869 
    870         /* TODO: should we filter a set_mapping using low/high filters ? */
    871        
    872         ctx = talloc_get_type(dom->private_data, struct idmap_tdb2_context);
    873 
    874         switch (map->xid.type) {
    875 
    876         case ID_TYPE_UID:
    877                 kidstr = talloc_asprintf(ctx, "UID %lu", (unsigned long)map->xid.id);
    878                 break;
    879                
    880         case ID_TYPE_GID:
    881                 kidstr = talloc_asprintf(ctx, "GID %lu", (unsigned long)map->xid.id);
    882                 break;
    883 
    884         default:
    885                 DEBUG(2, ("INVALID unix ID type: 0x02%x\n", map->xid.type));
    886                 return NT_STATUS_INVALID_PARAMETER;
    887         }
    888 
    889         if (kidstr == NULL) {
    890                 DEBUG(0, ("ERROR: Out of memory!\n"));
    891                 ret = NT_STATUS_NO_MEMORY;
    892                 goto done;
    893         }
    894 
    895         if (!(ksidstr = sid_string_talloc(ctx, map->sid))) {
    896                 DEBUG(0, ("Out of memory!\n"));
    897                 ret = NT_STATUS_NO_MEMORY;
    898                 goto done;
    899         }
    900 
    901         state.ksidstr = ksidstr;
    902         state.kidstr = kidstr;
    903 
    904         ret = dbwrap_trans_do(idmap_tdb2, idmap_tdb2_set_mapping_action,
    905                               &state);
    906 
    907 done:
    908         talloc_free(ksidstr);
    909         talloc_free(kidstr);
    910         return ret;
    911 }
    912 
    913 /*
    914   remove a mapping.
    915 */
    916 static NTSTATUS idmap_tdb2_remove_mapping(struct idmap_domain *dom, const struct id_map *map)
    917 {
    918         /* not supported as it would invalidate the cache tdb on other
    919            nodes */
    920         DEBUG(0,("idmap_tdb2_remove_mapping not supported\n"));
    921         return NT_STATUS_NOT_SUPPORTED;
    922 }
    923 
    924 /*
    925   Close the idmap tdb instance
    926 */
    927 static NTSTATUS idmap_tdb2_close(struct idmap_domain *dom)
    928 {
    929         /* don't do anything */
    930         return NT_STATUS_OK;
    931 }
    932 
    933 
    934 /*
    935   Dump all mappings out
    936 */
    937 static NTSTATUS idmap_tdb2_dump_data(struct idmap_domain *dom, struct id_map **maps, int *num_maps)
    938 {
    939         DEBUG(0,("idmap_tdb2_dump_data not supported\n"));
    940         return NT_STATUS_NOT_SUPPORTED;
    941 }
     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
     865        return ret;
     866}
     867
    942868
    943869static struct idmap_methods db_methods = {
     
    945871        .unixids_to_sids = idmap_tdb2_unixids_to_sids,
    946872        .sids_to_unixids = idmap_tdb2_sids_to_unixids,
    947         .set_mapping     = idmap_tdb2_set_mapping,
    948         .remove_mapping  = idmap_tdb2_remove_mapping,
    949         .dump_data       = idmap_tdb2_dump_data,
    950         .close_fn        = idmap_tdb2_close
     873        .allocate_id     = idmap_tdb2_get_new_id
    951874};
    952875
    953 static struct idmap_alloc_methods db_alloc_methods = {
    954         .init        = idmap_tdb2_alloc_init,
    955         .allocate_id = idmap_tdb2_allocate_id,
    956         .get_id_hwm  = idmap_tdb2_get_hwm,
    957         .set_id_hwm  = idmap_tdb2_set_hwm,
    958         .close_fn    = idmap_tdb2_alloc_close
    959 };
    960 
    961876NTSTATUS idmap_tdb2_init(void)
    962877{
    963         NTSTATUS ret;
    964 
    965         /* register both backends */
    966         ret = smb_register_idmap_alloc(SMB_IDMAP_INTERFACE_VERSION, "tdb2", &db_alloc_methods);
    967         if (! NT_STATUS_IS_OK(ret)) {
    968                 DEBUG(0, ("Unable to register idmap alloc tdb2 module: %s\n", get_friendly_nt_error_msg(ret)));
    969                 return ret;
    970         }
    971 
    972878        return smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION, "tdb2", &db_methods);
    973879}
  • vendor/current/source3/winbindd/idmap_util.c

    r594 r740  
    44   Copyright (C) Simo Sorce 2003
    55   Copyright (C) Jeremy Allison 2006
     6   Copyright (C) Michael Adam 2010
    67
    78   This program is free software; you can redistribute it and/or modify
     
    2122#include "winbindd.h"
    2223#include "winbindd_proto.h"
     24#include "idmap.h"
     25#include "idmap_cache.h"
     26#include "../libcli/security/security.h"
    2327
    2428#undef DBGC_CLASS
    2529#define DBGC_CLASS DBGC_IDMAP
    26 
    27 /*****************************************************************
    28  Returns true if the request was for a specific domain, or
    29  for a sid we are authoritative for - BUILTIN, or our own domain.
    30 *****************************************************************/
    31 
    32 static bool is_specific_domain_request(const char *dom_name, DOM_SID *sid)
    33 {
    34         if (dom_name && dom_name[0] != '\0') {
    35                 return true;
    36         }
    37         if (sid_check_is_in_builtin(sid) ||
    38                         sid_check_is_in_our_domain(sid)) {
    39                 return true;
    40         }
    41         return false;
    42 }
    4330
    4431/*****************************************************************
     
    4734*****************************************************************/ 
    4835
    49 NTSTATUS idmap_uid_to_sid(const char *domname, DOM_SID *sid, uid_t uid)
     36NTSTATUS idmap_uid_to_sid(const char *domname, struct dom_sid *sid, uid_t uid)
    5037{
    5138        NTSTATUS ret;
     
    10693*****************************************************************/ 
    10794
    108 NTSTATUS idmap_gid_to_sid(const char *domname, DOM_SID *sid, gid_t gid)
     95NTSTATUS idmap_gid_to_sid(const char *domname, struct dom_sid *sid, gid_t gid)
    10996{
    11097        NTSTATUS ret;
     
    147134                        struct dom_sid null_sid;
    148135                        ZERO_STRUCT(null_sid);
    149                         idmap_cache_set_sid2uid(&null_sid, gid);
     136                        idmap_cache_set_sid2gid(&null_sid, gid);
    150137                }
    151138                DEBUG(10, ("gid [%lu] not mapped\n", (unsigned long)gid));
     
    165152*****************************************************************/ 
    166153
    167 NTSTATUS idmap_sid_to_uid(const char *dom_name, DOM_SID *sid, uid_t *uid)
     154NTSTATUS idmap_sid_to_uid(const char *dom_name, struct dom_sid *sid, uid_t *uid)
    168155{
    169156        NTSTATUS ret;
     
    196183        ret = idmap_backends_sid_to_unixid(dom_name, &map);
    197184
    198         if (NT_STATUS_IS_OK(ret) && (map.status == ID_MAPPED)) {
    199                 if (map.xid.type != ID_TYPE_UID) {
    200                         DEBUG(10, ("sid [%s] not mapped to a uid "
    201                                    "[%u,%u,%u]\n",
    202                                    sid_string_dbg(sid),
    203                                    map.status,
    204                                    map.xid.type,
    205                                    map.xid.id));
    206                         if (winbindd_use_idmap_cache()) {
    207                                 idmap_cache_set_sid2uid(sid, -1);
    208                         }
    209                         return NT_STATUS_NONE_MAPPED;
    210                 }
    211                 goto done;
    212         }
    213 
    214         if (is_specific_domain_request(dom_name, sid)) {
    215                 /*
    216                  * We had the task to go to a specific domain or
    217                  * a domain for which we are authoritative for and
    218                  * it could not answer our request. Fail.
    219                  */
     185        if (!NT_STATUS_IS_OK(ret)) {
     186                DEBUG(10, ("idmap_backends_sid_to_unixid failed: %s\n",
     187                           nt_errstr(ret)));
    220188                if (winbindd_use_idmap_cache()) {
    221189                        idmap_cache_set_sid2uid(sid, -1);
    222190                }
    223                 return NT_STATUS_NONE_MAPPED;
    224         }
    225 
    226         ret = idmap_new_mapping(sid, ID_TYPE_UID, &map.xid);
    227 
    228         if (!NT_STATUS_IS_OK(ret)) {
    229                 DEBUG(10, ("idmap_new_mapping failed: %s\n",
    230                            nt_errstr(ret)));
     191                return ret;
     192        }
     193
     194        if (map.status != ID_MAPPED) {
     195                DEBUG(10, ("sid [%s] is not mapped\n", sid_string_dbg(sid)));
    231196                if (winbindd_use_idmap_cache()) {
    232197                        idmap_cache_set_sid2uid(sid, -1);
    233198                }
    234                 return ret;
    235         }
    236 
    237 done:
     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
    238215        *uid = (uid_t)map.xid.id;
    239216        if (winbindd_use_idmap_cache()) {
     
    248225*****************************************************************/ 
    249226
    250 NTSTATUS idmap_sid_to_gid(const char *domname, DOM_SID *sid, gid_t *gid)
     227NTSTATUS idmap_sid_to_gid(const char *domname, struct dom_sid *sid, gid_t *gid)
    251228{
    252229        NTSTATUS ret;
     
    278255
    279256        ret = idmap_backends_sid_to_unixid(domname, &map);
    280         if (NT_STATUS_IS_OK(ret) && (map.status == ID_MAPPED)) {
    281                 if (map.xid.type != ID_TYPE_GID) {
    282                         DEBUG(10, ("sid [%s] not mapped to a gid "
    283                                    "[%u,%u,%u]\n",
    284                                    sid_string_dbg(sid),
    285                                    map.status,
    286                                    map.xid.type,
    287                                    map.xid.id));
    288                         if (winbindd_use_idmap_cache()) {
    289                                 idmap_cache_set_sid2gid(sid, -1);
    290                         }
    291                         return NT_STATUS_NONE_MAPPED;
    292                 }
    293                 goto done;
    294         }
    295 
    296         if (is_specific_domain_request(domname, sid)) {
    297                 /*
    298                  * We had the task to go to a specific domain or
    299                  * a domain for which we are authoritative for and
    300                  * it could not answer our request. Fail.
    301                  */
    302                 if (winbindd_use_idmap_cache()) {
    303                         idmap_cache_set_sid2uid(sid, -1);
    304                 }
    305                 return NT_STATUS_NONE_MAPPED;
    306         }
    307 
    308         ret = idmap_new_mapping(sid, ID_TYPE_GID, &map.xid);
    309257
    310258        if (!NT_STATUS_IS_OK(ret)) {
    311                 DEBUG(10, ("idmap_new_mapping failed: %s\n",
     259                DEBUG(10, ("idmap_backends_sid_to_unixid failed: %s\n",
    312260                           nt_errstr(ret)));
    313261                if (winbindd_use_idmap_cache()) {
     
    317265        }
    318266
    319 done:
     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
    320288        *gid = map.xid.id;
    321289        if (winbindd_use_idmap_cache()) {
     
    324292        return NT_STATUS_OK;
    325293}
     294
     295/**
     296 * check whether a given unix id is inside the filter range of an idmap domain
     297 */
     298bool idmap_unix_id_is_in_range(uint32_t id, struct idmap_domain *dom)
     299{
     300        if (id == 0) {
     301                /* 0 is not an allowed unix id for id mapping */
     302                return false;
     303        }
     304
     305        if ((dom->low_id && (id < dom->low_id)) ||
     306            (dom->high_id && (id > dom->high_id)))
     307        {
     308                return false;
     309        }
     310
     311        return true;
     312}
  • vendor/current/source3/winbindd/nss_info.c

    r414 r740  
    2121
    2222#include "includes.h"
     23#include "ads.h"
    2324#include "nss_info.h"
    2425
     
    8889{
    8990        char *p;
    90         char *q;
    91         int len;
    9291
    9392        *backend = *domain = NULL;
     
    111110        }
    112111
    113         len = PTR_DIFF(p,config)+1;
    114         if ( (q = SMB_MALLOC_ARRAY( char, len )) == NULL ) {
    115                 SAFE_FREE( *backend );
    116                 return False;
    117         }
    118 
    119         StrnCpy( q, config, len-1);
    120         q[len-1] = '\0';
    121         *backend = q;
    122 
    123         return True;
     112        *backend = SMB_STRNDUP(config, PTR_DIFF(p, config));
     113        return (*backend != NULL);
    124114}
    125115
     
    165155 *******************************************************************/
    166156
    167  NTSTATUS nss_init( const char **nss_list )
     157static NTSTATUS nss_init(const char **nss_list)
    168158{
    169159        NTSTATUS status;
    170         static NTSTATUS nss_initialized = NT_STATUS_UNSUCCESSFUL;
     160        static bool nss_initialized = false;
    171161        int i;
    172162        char *backend, *domain;
     
    175165        /* check for previous successful initializations */
    176166
    177         if ( NT_STATUS_IS_OK(nss_initialized) )
     167        if (nss_initialized) {
    178168                return NT_STATUS_OK;
    179 
    180         /* The "template" backend should alqays be registered as it
     169        }
     170
     171        /* The "template" backend should always be registered as it
    181172           is a static module */
    182173
    183         if ( (nss_backend = nss_get_backend( "template" )) == NULL ) {
     174        nss_backend = nss_get_backend("template");
     175        if (nss_backend == NULL) {
    184176                static_init_nss_info;
    185177        }
     
    201193                /* validate the backend */
    202194
    203                 if ( (nss_backend = nss_get_backend( backend )) == NULL ) {
     195                nss_backend = nss_get_backend(backend);
     196                if (nss_backend == NULL) {
     197                        /*
     198                         * This is a freaking hack. We don't have proper
     199                         * modules for nss_info backends. Right now we have
     200                         * our standard nss_info backends in the ad backend.
     201                         */
     202                        status = smb_probe_module("idmap", "ad");
     203                        if ( !NT_STATUS_IS_OK(status) ) {
     204                                continue;
     205                        }
     206                }
     207
     208                nss_backend = nss_get_backend(backend);
     209                if (nss_backend == NULL) {
    204210                        /* attempt to register the backend */
    205211                        status = smb_probe_module( "nss_info", backend );
     
    207213                                continue;
    208214                        }
    209 
    210                         /* try again */
    211                         if ( (nss_backend = nss_get_backend( backend )) == NULL ) {
    212                                 DEBUG(0,("nss_init: unregistered backend %s!.  Skipping\n",
    213                                          backend));
    214                                 continue;
    215                         }
     215                }
     216
     217                /* try again */
     218                nss_backend = nss_get_backend(backend);
     219                if (nss_backend == NULL) {
     220                        DEBUG(0, ("nss_init: unregistered backend %s!. "
     221                                  "Skipping\n", backend));
     222                        continue;
    216223                }
    217224
     
    242249
    243250
    244                 /* we shouild default to use template here */
    245         }
    246 
    247         nss_initialized = NT_STATUS_OK;
     251                /* we should default to use template here */
     252        }
     253
     254        nss_initialized = true;
    248255
    249256        return NT_STATUS_OK;
     
    260267        status = nss_init( lp_winbind_nss_info() );
    261268        if ( !NT_STATUS_IS_OK(status) ) {
    262                 DEBUG(4,("nss_get_info: Failed to init nss_info API (%s)!\n",
    263                          nt_errstr(status)));
     269                DEBUG(4,("find_nss_domain: Failed to init nss_info API "
     270                         "(%s)!\n", nt_errstr(status)));
    264271                return NULL;
    265272        }
     
    300307 *******************************************************************/
    301308
    302 NTSTATUS nss_get_info( const char *domain, const DOM_SID *user_sid,
     309NTSTATUS nss_get_info( const char *domain, const struct dom_sid *user_sid,
    303310                       TALLOC_CTX *ctx,
    304                        ADS_STRUCT *ads, LDAPMessage *msg,
    305311                       const char **homedir, const char **shell,
    306312                       const char **gecos, gid_t *p_gid)
     
    320326        m = p->backend->methods;
    321327
    322         return m->get_nss_info( p, user_sid, ctx, ads, msg,
     328        return m->get_nss_info( p, user_sid, ctx,
    323329                                homedir, shell, gecos, p_gid );
    324330}
  • vendor/current/source3/winbindd/nss_info_template.c

    r414 r740  
    99   License as published by the Free Software Foundation; either
    1010   version 3 of the License, or (at your option) any later version.
    11    
     11
    1212   This library is distributed in the hope that it will be useful,
    1313   but WITHOUT ANY WARRANTY; without even the implied warranty of
    1414   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    1515   Library General Public License for more details.
    16    
     16
    1717   You should have received a copy of the GNU Lesser General Public License
    1818   along with this program.  If not, see <http://www.gnu.org/licenses/>.
     
    2020
    2121#include "includes.h"
     22#include "ads.h"
    2223#include "nss_info.h"
    2324
     
    3435
    3536static NTSTATUS nss_template_get_info( struct nss_domain_entry *e,
    36                                        const DOM_SID *sid,
     37                                       const struct dom_sid *sid,
    3738                                       TALLOC_CTX *ctx,
    38                                        ADS_STRUCT *ads,
    39                                        LDAPMessage *msg,
    4039                                       const char **homedir,
    4140                                       const char **shell,
     
    4544        if ( !homedir || !shell || !gecos )
    4645                return NT_STATUS_INVALID_PARAMETER;
    47        
     46
    4847        /* protect against home directories using whitespace in the
    4948          username */
     
    5554                return NT_STATUS_NO_MEMORY;
    5655        }
    57        
     56
    5857        return NT_STATUS_OK;
    5958}
     
    10099        .close_fn       = nss_template_close
    101100};
    102                
     101
    103102NTSTATUS nss_info_template_init( void )
    104103{
  • vendor/current/source3/winbindd/wb_dsgetdcname.c

    r594 r740  
    2020#include "includes.h"
    2121#include "winbindd.h"
    22 #include "librpc/gen_ndr/cli_wbint.h"
     22#include "librpc/gen_ndr/ndr_wbint_c.h"
    2323
    2424struct wb_dsgetdcname_state {
     
    6565        } else {
    6666                struct winbindd_domain *domain = find_our_domain();
    67                 child = &domain->child;
     67                child = choose_domain_child(domain);
    6868        }
    6969
     
    7474        }
    7575
    76         subreq = rpccli_wbint_DsGetDcName_send(
    77                 state, ev, child->rpccli, domain_name, guid_ptr, site_name,
     76        subreq = dcerpc_wbint_DsGetDcName_send(
     77                state, ev, child->binding_handle, domain_name, guid_ptr, site_name,
    7878                flags, &state->dcinfo);
    7979        if (tevent_req_nomem(subreq, req)) {
     
    9292        NTSTATUS status, result;
    9393
    94         status = rpccli_wbint_DsGetDcName_recv(subreq, state, &result);
     94        status = dcerpc_wbint_DsGetDcName_recv(subreq, state, &result);
    9595        TALLOC_FREE(subreq);
    96         if (!NT_STATUS_IS_OK(status)) {
     96        if (any_nt_status_not_ok(status, result, &status)) {
    9797                tevent_req_nterror(req, status);
    98                 return;
    99         }
    100         if (!NT_STATUS_IS_OK(result)) {
    101                 tevent_req_nterror(req, result);
    10298                return;
    10399        }
  • vendor/current/source3/winbindd/wb_fill_pwent.c

    r414 r740  
    2020#include "includes.h"
    2121#include "winbindd.h"
    22 #include "librpc/gen_ndr/cli_wbint.h"
     22#include "librpc/gen_ndr/ndr_wbint_c.h"
    2323
    2424struct wb_fill_pwent_state {
     
    7373        status = wb_sid2uid_recv(subreq, &state->pw->pw_uid);
    7474        TALLOC_FREE(subreq);
    75         if (!NT_STATUS_IS_OK(status)) {
    76                 tevent_req_nterror(req, status);
     75        if (tevent_req_nterror(req, status)) {
    7776                return;
    7877        }
     
    9998        status = wb_sid2gid_recv(subreq, &state->pw->pw_gid);
    10099        TALLOC_FREE(subreq);
    101         if (!NT_STATUS_IS_OK(status)) {
    102                 tevent_req_nterror(req, status);
     100        if (tevent_req_nterror(req, status)) {
    103101                return;
    104102        }
  • vendor/current/source3/winbindd/wb_getgrsid.c

    r414 r740  
    2020#include "includes.h"
    2121#include "winbindd.h"
    22 #include "librpc/gen_ndr/cli_wbint.h"
     22#include "librpc/gen_ndr/ndr_wbint_c.h"
     23#include "../libcli/security/security.h"
    2324
    2425struct wb_getgrsid_state {
     
    5657                struct winbindd_domain *our_domain = find_our_domain();
    5758
    58                 if (sid_compare_domain(group_sid, &our_domain->sid) == 0) {
     59                if (dom_sid_compare_domain(group_sid, &our_domain->sid) == 0) {
    5960                        DEBUG(7, ("winbindd_getgrsid: My domain -- rejecting "
    6061                                  "getgrsid() for %s\n", sid_string_tos(group_sid)));
     
    8384                                   &state->domname, &state->name);
    8485        TALLOC_FREE(subreq);
    85         if (!NT_STATUS_IS_OK(status)) {
    86                 tevent_req_nterror(req, status);
     86        if (tevent_req_nterror(req, status)) {
    8787                return;
    8888        }
     
    115115        status = wb_sid2gid_recv(subreq, &state->gid);
    116116        TALLOC_FREE(subreq);
    117         if (!NT_STATUS_IS_OK(status)) {
    118                 tevent_req_nterror(req, status);
     117        if (tevent_req_nterror(req, status)) {
    119118                return;
    120119        }
     
    137136        status = wb_group_members_recv(subreq, state, &state->members);
    138137        TALLOC_FREE(subreq);
    139         if (!NT_STATUS_IS_OK(status)) {
    140                 tevent_req_nterror(req, status);
     138        if (tevent_req_nterror(req, status)) {
    141139                return;
    142140        }
  • vendor/current/source3/winbindd/wb_getpwsid.c

    r414 r740  
    2020#include "includes.h"
    2121#include "winbindd.h"
    22 #include "librpc/gen_ndr/cli_wbint.h"
     22#include "librpc/gen_ndr/ndr_wbint_c.h"
     23#include "../libcli/security/security.h"
    2324
    2425struct wb_getpwsid_state {
     
    7475        status = wb_queryuser_recv(subreq, state, &state->userinfo);
    7576        TALLOC_FREE(subreq);
    76         if (!NT_STATUS_IS_OK(status)) {
    77                 tevent_req_nterror(req, status);
     77        if (tevent_req_nterror(req, status)) {
    7878                return;
    7979        }
     
    118118                                   &state->userinfo->acct_name);
    119119        TALLOC_FREE(subreq);
    120         if (!NT_STATUS_IS_OK(status)) {
    121                 tevent_req_nterror(req, status);
     120        if (tevent_req_nterror(req, status)) {
    122121                return;
    123122        }
     
    137136
    138137        status = wb_fill_pwent_recv(subreq);
    139         if (!NT_STATUS_IS_OK(status)) {
    140                 tevent_req_nterror(req, status);
     138        if (tevent_req_nterror(req, status)) {
    141139                return;
    142140        }
  • vendor/current/source3/winbindd/wb_gettoken.c

    r594 r740  
    2020#include "includes.h"
    2121#include "winbindd.h"
    22 #include "librpc/gen_ndr/cli_wbint.h"
     22#include "librpc/gen_ndr/ndr_wbint_c.h"
     23#include "../libcli/security/security.h"
     24#include "passdb/machine_sid.h"
    2325
    2426struct wb_gettoken_state {
     
    8991                                          &state->sids);
    9092        TALLOC_FREE(subreq);
    91         if (!NT_STATUS_IS_OK(status)) {
    92                 tevent_req_nterror(req, status);
     93        if (tevent_req_nterror(req, status)) {
    9394                return;
    9495        }
     
    134135        status = wb_lookupuseraliases_recv(subreq, state, &num_rids, &rids);
    135136        TALLOC_FREE(subreq);
    136         if (!NT_STATUS_IS_OK(status)) {
    137                 tevent_req_nterror(req, status);
     137        if (tevent_req_nterror(req, status)) {
    138138                return;
    139139        }
    140140        domain = find_domain_from_sid_noinit(get_global_sam_sid());
     141        if (domain == NULL) {
     142                tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
     143                return;
     144        }
    141145        if (!wb_add_rids_to_sids(state, &state->num_sids, &state->sids,
    142146                                 &domain->sid, num_rids, rids)) {
     
    176180        status = wb_lookupuseraliases_recv(subreq, state, &num_rids, &rids);
    177181        TALLOC_FREE(subreq);
    178         if (!NT_STATUS_IS_OK(status)) {
    179                 tevent_req_nterror(req, status);
     182        if (tevent_req_nterror(req, status)) {
    180183                return;
    181184        }
  • vendor/current/source3/winbindd/wb_gid2sid.c

    r414 r740  
    2020#include "includes.h"
    2121#include "winbindd.h"
    22 #include "librpc/gen_ndr/cli_wbint.h"
     22#include "librpc/gen_ndr/ndr_wbint_c.h"
     23#include "idmap_cache.h"
     24#include "idmap.h"
     25#include "../libcli/security/security.h"
    2326
    2427struct wb_gid2sid_state {
     
    7578        child = idmap_child();
    7679
    77         subreq = rpccli_wbint_Gid2Sid_send(
    78                 state, ev, child->rpccli, state->dom_name,
     80        subreq = dcerpc_wbint_Gid2Sid_send(
     81                state, ev, child->binding_handle, state->dom_name,
    7982                gid, &state->sid);
    8083        if (tevent_req_nomem(subreq, req)) {
     
    9396        NTSTATUS status, result;
    9497
    95         status = rpccli_wbint_Gid2Sid_recv(subreq, state, &result);
     98        status = dcerpc_wbint_Gid2Sid_recv(subreq, state, &result);
    9699        TALLOC_FREE(subreq);
    97         if (!NT_STATUS_IS_OK(status)) {
     100        if (any_nt_status_not_ok(status, result, &status)) {
    98101                tevent_req_nterror(req, status);
    99                 return;
    100         }
    101         if (!NT_STATUS_IS_OK(result)) {
    102                 tevent_req_nterror(req, result);
    103102                return;
    104103        }
  • vendor/current/source3/winbindd/wb_group_members.c

    r414 r740  
    2020#include "includes.h"
    2121#include "winbindd.h"
    22 #include "librpc/gen_ndr/cli_wbint.h"
     22#include "librpc/gen_ndr/ndr_wbint_c.h"
     23#include "../librpc/gen_ndr/ndr_security.h"
     24#include "../libcli/security/security.h"
    2325
    2426/*
     
    7173        }
    7274
    73         subreq = rpccli_wbint_LookupGroupMembers_send(
    74                 state, ev, domain->child.rpccli, &state->sid, type,
     75        subreq = dcerpc_wbint_LookupGroupMembers_send(
     76                state, ev, dom_child_handle(domain), &state->sid, type,
    7577                &state->members);
    7678        if (tevent_req_nomem(subreq, req)) {
     
    8991        NTSTATUS status, result;
    9092
    91         status = rpccli_wbint_LookupGroupMembers_recv(subreq, state, &result);
     93        status = dcerpc_wbint_LookupGroupMembers_recv(subreq, state, &result);
    9294        TALLOC_FREE(subreq);
    93         if (!NT_STATUS_IS_OK(status)) {
     95        if (any_nt_status_not_ok(status, result, &status)) {
    9496                tevent_req_nterror(req, status);
    95                 return;
    96         }
    97         if (!NT_STATUS_IS_OK(result)) {
    98                 tevent_req_nterror(req, result);
    9997                return;
    10098        }
     
    158156
    159157        status = wb_groups_members_next_subreq(state, state, &subreq);
    160         if (!NT_STATUS_IS_OK(status)) {
    161                 tevent_req_nterror(req, status);
     158        if (tevent_req_nterror(req, status)) {
    162159                return tevent_req_post(req, ev);
    163160        }
     
    213210         */
    214211
    215         if (!NT_STATUS_IS_OK(status)) {
    216                 tevent_req_nterror(req, status);
     212        if (tevent_req_nterror(req, status)) {
    217213                return;
    218214        }
     
    238234
    239235        status = wb_groups_members_next_subreq(state, state, &subreq);
    240         if (!NT_STATUS_IS_OK(status)) {
    241                 tevent_req_nterror(req, status);
     236        if (tevent_req_nterror(req, status)) {
    242237                return;
    243238        }
     
    270265 * This is the routine expanding a list of groups up to a certain level. We
    271266 * collect the users in a talloc_dict: We have to add them without duplicates,
    272  * and and talloc_dict is an indexed (here indexed by SID) data structure.
     267 * and talloc_dict is an indexed (here indexed by SID) data structure.
    273268 */
    274269
     
    316311
    317312        status = wb_group_members_next_subreq(state, state, &subreq);
    318         if (!NT_STATUS_IS_OK(status)) {
    319                 tevent_req_nterror(req, status);
     313        if (tevent_req_nterror(req, status)) {
    320314                return tevent_req_post(req, ev);
    321315        }
     
    364358        status = wb_groups_members_recv(subreq, state, &num_members, &members);
    365359        TALLOC_FREE(subreq);
    366         if (!NT_STATUS_IS_OK(status)) {
    367                 tevent_req_nterror(req, status);
     360        if (tevent_req_nterror(req, status)) {
    368361                return;
    369362        }
     
    414407                        sid = &members[i].sid;
    415408                        key = data_blob_const(
    416                                 sid, ndr_size_dom_sid(sid, NULL, 0));
     409                                sid, ndr_size_dom_sid(sid, 0));
    417410
    418411                        if (!talloc_dict_set(state->users, key, &m)) {
     
    443436
    444437        status = wb_group_members_next_subreq(state, state, &subreq);
    445         if (!NT_STATUS_IS_OK(status)) {
    446                 tevent_req_nterror(req, status);
     438        if (tevent_req_nterror(req, status)) {
    447439                return;
    448440        }
  • vendor/current/source3/winbindd/wb_lookupname.c

    r414 r740  
    2020#include "includes.h"
    2121#include "winbindd.h"
    22 #include "librpc/gen_ndr/cli_wbint.h"
     22#include "librpc/gen_ndr/ndr_wbint_c.h"
     23#include "../libcli/security/security.h"
    2324
    2425struct wb_lookupname_state {
     
    6970        }
    7071
    71         subreq = rpccli_wbint_LookupName_send(
    72                 state, ev, domain->child.rpccli, state->dom_name, state->name,
     72        subreq = dcerpc_wbint_LookupName_send(
     73                state, ev, dom_child_handle(domain),
     74                state->dom_name, state->name,
    7375                flags, &state->type, &state->sid);
    7476        if (tevent_req_nomem(subreq, req)) {
     
    8890        NTSTATUS status, result;
    8991
    90         status = rpccli_wbint_LookupName_recv(subreq, state, &result);
     92        status = dcerpc_wbint_LookupName_recv(subreq, state, &result);
    9193        TALLOC_FREE(subreq);
    92         if (!NT_STATUS_IS_OK(status)) {
    93                 tevent_req_nterror(req, status);
     94        if (tevent_req_nterror(req, status)) {
    9495                return;
    9596        }
     
    110111        }
    111112
    112         subreq = rpccli_wbint_LookupName_send(
    113                 state, state->ev, root_domain->child.rpccli, state->dom_name,
     113        subreq = dcerpc_wbint_LookupName_send(
     114                state, state->ev, dom_child_handle(root_domain),
     115                state->dom_name,
    114116                state->name, state->flags, &state->type, &state->sid);
    115117        if (tevent_req_nomem(subreq, req)) {
     
    127129        NTSTATUS status, result;
    128130
    129         status = rpccli_wbint_LookupName_recv(subreq, state, &result);
     131        status = dcerpc_wbint_LookupName_recv(subreq, state, &result);
    130132        TALLOC_FREE(subreq);
    131         if (!NT_STATUS_IS_OK(status)) {
     133        if (any_nt_status_not_ok(status, result, &status)) {
    132134                tevent_req_nterror(req, status);
    133                 return;
    134         }
    135         if (!NT_STATUS_IS_OK(result)) {
    136                 tevent_req_nterror(req, result);
    137135                return;
    138136        }
  • vendor/current/source3/winbindd/wb_lookupsid.c

    r414 r740  
    2020#include "includes.h"
    2121#include "winbindd.h"
    22 #include "librpc/gen_ndr/cli_wbint.h"
     22#include "librpc/gen_ndr/ndr_wbint_c.h"
     23#include "../libcli/security/security.h"
    2324
    2425struct wb_lookupsid_state {
     
    5556        }
    5657
    57         subreq = rpccli_wbint_LookupSid_send(
    58                 state, ev, state->lookup_domain->child.rpccli,
     58        subreq = dcerpc_wbint_LookupSid_send(
     59                state, ev, dom_child_handle(state->lookup_domain),
    5960                &state->sid, &state->type, &state->domname, &state->name);
    6061        if (tevent_req_nomem(subreq, req)) {
     
    7475        NTSTATUS status, result;
    7576
    76         status = rpccli_wbint_LookupSid_recv(subreq, state, &result);
     77        status = dcerpc_wbint_LookupSid_recv(subreq, state, &result);
    7778        TALLOC_FREE(subreq);
    78         if (!NT_STATUS_IS_OK(status)) {
    79                 tevent_req_nterror(req, status);
     79        if (tevent_req_nterror(req, status)) {
    8080                return;
    8181        }
     
    9595        state->lookup_domain = forest_root;
    9696
    97         subreq = rpccli_wbint_LookupSid_send(
    98                 state, state->ev, state->lookup_domain->child.rpccli,
     97        subreq = dcerpc_wbint_LookupSid_send(
     98                state, state->ev, dom_child_handle(state->lookup_domain),
    9999                &state->sid, &state->type, &state->domname, &state->name);
    100100        if (tevent_req_nomem(subreq, req)) {
  • vendor/current/source3/winbindd/wb_lookupuseraliases.c

    r414 r740  
    2020#include "includes.h"
    2121#include "winbindd.h"
    22 #include "librpc/gen_ndr/cli_wbint.h"
     22#include "librpc/gen_ndr/ndr_wbint_c.h"
    2323
    2424struct wb_lookupuseraliases_state {
     
    4747        state->sids.sids = CONST_DISCARD(struct dom_sid *, sids);
    4848
    49         subreq = rpccli_wbint_LookupUserAliases_send(
    50                 state, ev, domain->child.rpccli, &state->sids, &state->rids);
     49        subreq = dcerpc_wbint_LookupUserAliases_send(
     50                state, ev, dom_child_handle(domain), &state->sids, &state->rids);
    5151        if (tevent_req_nomem(subreq, req)) {
    5252                return tevent_req_post(req, ev);
     
    6464        NTSTATUS status, result;
    6565
    66         status = rpccli_wbint_LookupUserAliases_recv(subreq, state, &result);
     66        status = dcerpc_wbint_LookupUserAliases_recv(subreq, state, &result);
    6767        TALLOC_FREE(subreq);
    68         if (!NT_STATUS_IS_OK(status)) {
     68        if (any_nt_status_not_ok(status, result, &status)) {
    6969                tevent_req_nterror(req, status);
    70                 return;
    71         }
    72         if (!NT_STATUS_IS_OK(result)) {
    73                 tevent_req_nterror(req, result);
    7470                return;
    7571        }
  • vendor/current/source3/winbindd/wb_lookupusergroups.c

    r414 r740  
    2020#include "includes.h"
    2121#include "winbindd.h"
    22 #include "librpc/gen_ndr/cli_wbint.h"
     22#include "librpc/gen_ndr/ndr_wbint_c.h"
     23#include "../libcli/security/security.h"
    2324
    2425struct wb_lookupusergroups_state {
     
    4546        sid_copy(&state->sid, sid);
    4647
    47         subreq = rpccli_wbint_LookupUserGroups_send(
    48                 state, ev, domain->child.rpccli, &state->sid, &state->sids);
     48        subreq = dcerpc_wbint_LookupUserGroups_send(
     49                state, ev, dom_child_handle(domain), &state->sid, &state->sids);
    4950        if (tevent_req_nomem(subreq, req)) {
    5051                return tevent_req_post(req, ev);
     
    6263        NTSTATUS status, result;
    6364
    64         status = rpccli_wbint_LookupUserGroups_recv(subreq, state, &result);
     65        status = dcerpc_wbint_LookupUserGroups_recv(subreq, state, &result);
    6566        TALLOC_FREE(subreq);
    66         if (!NT_STATUS_IS_OK(status)) {
     67        if (any_nt_status_not_ok(status, result, &status)) {
    6768                tevent_req_nterror(req, status);
    68                 return;
    69         }
    70         if (!NT_STATUS_IS_OK(result)) {
    71                 tevent_req_nterror(req, result);
    7269                return;
    7370        }
  • vendor/current/source3/winbindd/wb_next_grent.c

    r427 r740  
    2020#include "includes.h"
    2121#include "winbindd.h"
    22 #include "librpc/gen_ndr/cli_wbint.h"
     22#include "librpc/gen_ndr/ndr_wbint_c.h"
     23#include "passdb/machine_sid.h"
    2324
    2425struct wb_next_grent_state {
     
    7071                        return tevent_req_post(req, ev);
    7172                }
    72                 subreq = rpccli_wbint_QueryGroupList_send(
    73                         state, state->ev, state->gstate->domain->child.rpccli,
     73                subreq = dcerpc_wbint_QueryGroupList_send(
     74                        state, state->ev, dom_child_handle(state->gstate->domain),
    7475                        &state->next_groups);
    7576                if (tevent_req_nomem(subreq, req)) {
     
    99100        NTSTATUS status, result;
    100101
    101         status = rpccli_wbint_QueryGroupList_recv(subreq, state, &result);
     102        status = dcerpc_wbint_QueryGroupList_recv(subreq, state, &result);
    102103        TALLOC_FREE(subreq);
    103         if (!NT_STATUS_IS_OK(status) || !NT_STATUS_IS_OK(result)) {
     104        if (tevent_req_nterror(req, status)) {
     105                /* 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)) {
    104112                /* Ignore errors here, just log it */
    105113                DEBUG(10, ("query_user_list for domain %s returned %s/%s\n",
     
    126134                        return;
    127135                }
    128                 subreq = rpccli_wbint_QueryGroupList_send(
    129                         state, state->ev, state->gstate->domain->child.rpccli,
     136                subreq = dcerpc_wbint_QueryGroupList_send(
     137                        state, state->ev, dom_child_handle(state->gstate->domain),
    130138                        &state->next_groups);
    131139                if (tevent_req_nomem(subreq, req)) {
     
    161169                                  &state->gr->gr_gid, &state->members);
    162170        TALLOC_FREE(subreq);
    163         if (!NT_STATUS_IS_OK(status)) {
    164                 tevent_req_nterror(req, status);
     171        if (tevent_req_nterror(req, status)) {
    165172                return;
    166173        }
  • vendor/current/source3/winbindd/wb_next_pwent.c

    r414 r740  
    2020#include "includes.h"
    2121#include "winbindd.h"
    22 #include "librpc/gen_ndr/cli_wbint.h"
     22#include "librpc/gen_ndr/ndr_wbint_c.h"
     23#include "passdb/machine_sid.h"
    2324
    2425struct wb_next_pwent_state {
     
    148149        status = wb_fill_pwent_recv(subreq);
    149150        TALLOC_FREE(subreq);
    150         if (!NT_STATUS_IS_OK(status)) {
    151                 tevent_req_nterror(req, status);
     151        if (tevent_req_nterror(req, status)) {
    152152                return;
    153153        }
  • vendor/current/source3/winbindd/wb_query_user_list.c

    r414 r740  
    2020#include "includes.h"
    2121#include "winbindd.h"
    22 #include "librpc/gen_ndr/cli_wbint.h"
     22#include "librpc/gen_ndr/ndr_wbint_c.h"
    2323
    2424struct wb_query_user_list_state {
     
    4141        }
    4242
    43         subreq = rpccli_wbint_QueryUserList_send(state, ev,
    44                                                  domain->child.rpccli,
     43        subreq = dcerpc_wbint_QueryUserList_send(state, ev,
     44                                                 dom_child_handle(domain),
    4545                                                 &state->users);
    4646        if (tevent_req_nomem(subreq, req)) {
     
    5959        NTSTATUS status, result;
    6060
    61         status = rpccli_wbint_QueryUserList_recv(subreq, state, &result);
     61        status = dcerpc_wbint_QueryUserList_recv(subreq, state, &result);
    6262        TALLOC_FREE(subreq);
    63         if (!NT_STATUS_IS_OK(status)) {
     63        if (any_nt_status_not_ok(status, result, &status)) {
    6464                tevent_req_nterror(req, status);
    6565                return;
    6666        }
    67         if (!NT_STATUS_IS_OK(result)) {
    68                 tevent_req_nterror(req, result);
    69                 return;
    70         }
    7167
    72         DEBUG(10, ("rpccli_wbint_QueryUserList returned %d users\n",
     68        DEBUG(10, ("dcerpc_wbint_QueryUserList returned %d users\n",
    7369                   state->users.num_userinfos));
    7470
  • vendor/current/source3/winbindd/wb_queryuser.c

    r414 r740  
    2020#include "includes.h"
    2121#include "winbindd.h"
    22 #include "librpc/gen_ndr/cli_wbint.h"
     22#include "librpc/gen_ndr/ndr_wbint_c.h"
     23#include "../libcli/security/security.h"
    2324
    2425struct wb_queryuser_state {
     
    5455        }
    5556
    56         subreq = rpccli_wbint_QueryUser_send(state, ev, domain->child.rpccli,
     57        subreq = dcerpc_wbint_QueryUser_send(state, ev, dom_child_handle(domain),
    5758                                             &state->sid, state->info);
    5859        if (tevent_req_nomem(subreq, req)) {
     
    7172        NTSTATUS status, result;
    7273
    73         status = rpccli_wbint_QueryUser_recv(subreq, state->info, &result);
     74        status = dcerpc_wbint_QueryUser_recv(subreq, state->info, &result);
    7475        TALLOC_FREE(subreq);
    75         if (!NT_STATUS_IS_OK(status)) {
     76        if (any_nt_status_not_ok(status, result, &status)) {
    7677                tevent_req_nterror(req, status);
    77                 return;
    78         }
    79         if (!NT_STATUS_IS_OK(result)) {
    80                 tevent_req_nterror(req, result);
    8178                return;
    8279        }
  • vendor/current/source3/winbindd/wb_seqnum.c

    r414 r740  
    2020#include "includes.h"
    2121#include "winbindd.h"
    22 #include "librpc/gen_ndr/cli_wbint.h"
     22#include "librpc/gen_ndr/ndr_wbint_c.h"
    2323
    2424struct wb_seqnum_state {
     
    3939                return NULL;
    4040        }
    41         subreq = rpccli_wbint_QuerySequenceNumber_send(
    42                 state, ev, domain->child.rpccli, &state->seqnum);
     41        subreq = dcerpc_wbint_QuerySequenceNumber_send(
     42                state, ev, dom_child_handle(domain), &state->seqnum);
    4343        if (tevent_req_nomem(subreq, req)) {
    4444                return tevent_req_post(req, ev);
     
    5656        NTSTATUS status, result;
    5757
    58         status = rpccli_wbint_QuerySequenceNumber_recv(subreq, state, &result);
     58        status = dcerpc_wbint_QuerySequenceNumber_recv(subreq, state, &result);
    5959        TALLOC_FREE(subreq);
    60         if (!NT_STATUS_IS_OK(status)) {
     60        if (any_nt_status_not_ok(status, result, &status)) {
    6161                tevent_req_nterror(req, status);
    62                 return;
    63         }
    64         if (!NT_STATUS_IS_OK(result)) {
    65                 tevent_req_nterror(req, result);
    6662                return;
    6763        }
  • vendor/current/source3/winbindd/wb_seqnums.c

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

    r414 r740  
    2020#include "includes.h"
    2121#include "winbindd.h"
    22 #include "librpc/gen_ndr/cli_wbint.h"
     22#include "librpc/gen_ndr/ndr_wbint_c.h"
     23#include "idmap_cache.h"
     24#include "../libcli/security/security.h"
    2325
    2426struct wb_sid2gid_state {
     
    9395        status = wb_lookupsid_recv(subreq, talloc_tos(), &type, &domname,
    9496                                   &name);
    95         if (!NT_STATUS_IS_OK(status)) {
    96                 tevent_req_nterror(req, status);
     97        if (tevent_req_nterror(req, status)) {
    9798                return;
    9899        }
     
    125126        child = idmap_child();
    126127
    127         subreq = rpccli_wbint_Sid2Gid_send(state, state->ev, child->rpccli,
     128        subreq = dcerpc_wbint_Sid2Gid_send(state, state->ev, child->binding_handle,
    128129                                           state->dom_name, &state->sid,
    129130                                           &state->gid64);
     
    142143        NTSTATUS status, result;
    143144
    144         status = rpccli_wbint_Sid2Gid_recv(subreq, state, &result);
     145        status = dcerpc_wbint_Sid2Gid_recv(subreq, state, &result);
    145146        TALLOC_FREE(subreq);
    146         if (!NT_STATUS_IS_OK(status)) {
     147        if (any_nt_status_not_ok(status, result, &status)) {
    147148                tevent_req_nterror(req, status);
    148                 return;
    149         }
    150         if (!NT_STATUS_IS_OK(result)) {
    151                 tevent_req_nterror(req, result);
    152149                return;
    153150        }
  • vendor/current/source3/winbindd/wb_sid2uid.c

    r414 r740  
    2020#include "includes.h"
    2121#include "winbindd.h"
    22 #include "librpc/gen_ndr/cli_wbint.h"
     22#include "librpc/gen_ndr/ndr_wbint_c.h"
     23#include "idmap_cache.h"
     24#include "../libcli/security/security.h"
    2325
    2426struct wb_sid2uid_state {
     
    9294        status = wb_lookupsid_recv(subreq, talloc_tos(), &type, &domname,
    9395                                   &name);
    94         if (!NT_STATUS_IS_OK(status)) {
    95                 tevent_req_nterror(req, status);
     96        if (tevent_req_nterror(req, status)) {
    9697                return;
    9798        }
     
    123124        child = idmap_child();
    124125
    125         subreq = rpccli_wbint_Sid2Uid_send(state, state->ev, child->rpccli,
     126        subreq = dcerpc_wbint_Sid2Uid_send(state, state->ev, child->binding_handle,
    126127                                           state->dom_name, &state->sid,
    127128                                           &state->uid64);
     
    140141        NTSTATUS status, result;
    141142
    142         status = rpccli_wbint_Sid2Uid_recv(subreq, state, &result);
     143        status = dcerpc_wbint_Sid2Uid_recv(subreq, state, &result);
    143144        TALLOC_FREE(subreq);
    144         if (!NT_STATUS_IS_OK(status)) {
     145        if (any_nt_status_not_ok(status, result, &status)) {
    145146                tevent_req_nterror(req, status);
    146                 return;
    147         }
    148         if (!NT_STATUS_IS_OK(result)) {
    149                 tevent_req_nterror(req, result);
    150147                return;
    151148        }
  • vendor/current/source3/winbindd/wb_uid2sid.c

    r414 r740  
    2020#include "includes.h"
    2121#include "winbindd.h"
    22 #include "librpc/gen_ndr/cli_wbint.h"
     22#include "librpc/gen_ndr/ndr_wbint_c.h"
     23#include "idmap_cache.h"
     24#include "idmap.h"
     25#include "../libcli/security/security.h"
    2326
    2427struct wb_uid2sid_state {
     
    7578        child = idmap_child();
    7679
    77         subreq = rpccli_wbint_Uid2Sid_send(
    78                 state, ev, child->rpccli, state->dom_name,
     80        subreq = dcerpc_wbint_Uid2Sid_send(
     81                state, ev, child->binding_handle, state->dom_name,
    7982                uid, &state->sid);
    8083        if (tevent_req_nomem(subreq, req)) {
     
    9396        NTSTATUS status, result;
    9497
    95         status = rpccli_wbint_Uid2Sid_recv(subreq, state, &result);
     98        status = dcerpc_wbint_Uid2Sid_recv(subreq, state, &result);
    9699        TALLOC_FREE(subreq);
    97         if (!NT_STATUS_IS_OK(status)) {
     100        if (any_nt_status_not_ok(status, result, &status)) {
    98101                tevent_req_nterror(req, status);
    99                 return;
    100         }
    101         if (!NT_STATUS_IS_OK(result)) {
    102                 tevent_req_nterror(req, result);
    103102                return;
    104103        }
  • vendor/current/source3/winbindd/winbindd.c

    r597 r740  
    2424
    2525#include "includes.h"
     26#include "popt_common.h"
    2627#include "winbindd.h"
    27 #include "../../nsswitch/libwbclient/wbc_async.h"
     28#include "nsswitch/winbind_client.h"
     29#include "nsswitch/wb_reqtrans.h"
     30#include "ntdomain.h"
     31#include "../librpc/gen_ndr/srv_lsa.h"
     32#include "../librpc/gen_ndr/srv_samr.h"
     33#include "secrets.h"
     34#include "idmap.h"
     35#include "lib/addrchange.h"
     36#include "serverid.h"
     37#include "auth.h"
     38#include "messages.h"
    2839
    2940#undef DBGC_CLASS
    3041#define DBGC_CLASS DBGC_WINBIND
    3142
     43static bool client_is_idle(struct winbindd_cli_state *state);
    3244static void remove_client(struct winbindd_cli_state *state);
    3345
     
    3749extern bool override_logfile;
    3850
    39 struct event_context *winbind_event_context(void)
    40 {
    41         static struct event_context *ctx;
    42 
    43         if (!ctx && !(ctx = event_context_init(NULL))) {
    44                 smb_panic("Could not init winbind event context");
    45         }
    46         return ctx;
    47 }
    48 
    4951struct messaging_context *winbind_messaging_context(void)
    5052{
    51         static struct messaging_context *ctx;
    52 
    53         if (ctx == NULL) {
    54                 ctx = messaging_init(NULL, server_id_self(),
    55                                      winbind_event_context());
    56         }
    57         if (ctx == NULL) {
    58                 DEBUG(0, ("Could not init winbind messaging context.\n"));
    59         }
    60         return ctx;
     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;
    6159}
    6260
     
    113111                DEBUG(2, ("\tclient list:\n"));
    114112                for(tmp = winbindd_client_list(); tmp; tmp = tmp->next) {
    115                         DEBUGADD(2, ("\t\tpid %lu, sock %d\n",
    116                                   (unsigned long)tmp->pid, tmp->sock));
    117                 }
    118         }
    119 }
    120 
    121 /* Print winbindd status to log file */
    122 
    123 static void print_winbindd_status(void)
    124 {
    125         winbindd_status();
     113                        DEBUGADD(2, ("\t\tpid %lu, sock %d (%s)\n",
     114                                     (unsigned long)tmp->pid, tmp->sock,
     115                                     client_is_idle(tmp) ? "idle" : "active"));
     116                }
     117        }
    126118}
    127119
     
    135127
    136128        if (!wcache_invalidate_cache()) {
     129                DEBUG(0, ("invalidating the cache failed; revalidate the cache\n"));
     130                if (!winbindd_cache_validate_and_initialize()) {
     131                        exit(1);
     132                }
     133        }
     134}
     135
     136static void flush_caches_noinit(void)
     137{
     138        /*
     139         * We need to invalidate cached user list entries on a SIGHUP
     140         * otherwise cached access denied errors due to restrict anonymous
     141         * hang around until the sequence number changes.
     142         * NB
     143         * Skip uninitialized domains when flush cache.
     144         * If domain is not initialized, it means it is never
     145         * used or never become online. look, wcache_invalidate_cache()
     146         * -> get_cache() -> init_dc_connection(). It causes a lot of traffic
     147         * for unused domains and large traffic for primay domain's DC if there
     148         * are many domains..
     149         */
     150
     151        if (!wcache_invalidate_cache_noinit()) {
    137152                DEBUG(0, ("invalidating the cache failed; revalidate the cache\n"));
    138153                if (!winbindd_cache_validate_and_initialize()) {
     
    177192
    178193        if (is_parent) {
     194                serverid_deregister(procid_self());
    179195                pidfile_unlink();
    180196        }
     
    255271
    256272        DEBUG(1,("Reloading services after SIGHUP\n"));
    257         flush_caches();
     273        flush_caches_noinit();
    258274        reload_services_file(file);
    259275}
     
    321337                                      void *private_data)
    322338{
    323         print_winbindd_status();
     339        winbindd_status();
    324340}
    325341
     
    373389        uint8 ret;
    374390        pid_t child_pid;
     391        NTSTATUS status;
    375392
    376393        DEBUG(10, ("winbindd_msg_validate_cache: got validate-cache "
     
    399416        /* child */
    400417
    401         if (!winbindd_reinit_after_fork(NULL)) {
     418        status = winbindd_reinit_after_fork(NULL, NULL);
     419        if (!NT_STATUS_IS_OK(status)) {
     420                DEBUG(1, ("winbindd_reinit_after_fork failed: %s\n",
     421                          nt_errstr(status)));
    402422                _exit(0);
    403423        }
     
    419439} dispatch_table[] = {
    420440
    421         /* PAM auth functions */
    422 
    423         { WINBINDD_PAM_AUTH, winbindd_pam_auth, "PAM_AUTH" },
    424         { WINBINDD_PAM_AUTH_CRAP, winbindd_pam_auth_crap, "AUTH_CRAP" },
    425         { WINBINDD_PAM_CHAUTHTOK, winbindd_pam_chauthtok, "CHAUTHTOK" },
    426         { WINBINDD_PAM_LOGOFF, winbindd_pam_logoff, "PAM_LOGOFF" },
    427         { WINBINDD_PAM_CHNG_PSWD_AUTH_CRAP, winbindd_pam_chng_pswd_auth_crap, "CHNG_PSWD_AUTH_CRAP" },
    428 
    429441        /* Enumeration functions */
    430442
     
    439451        { WINBINDD_DOMAIN_NAME, winbindd_domain_name, "DOMAIN_NAME" },
    440452        { WINBINDD_DOMAIN_INFO, winbindd_domain_info, "DOMAIN_INFO" },
     453        { WINBINDD_DC_INFO, winbindd_dc_info, "DC_INFO" },
    441454        { WINBINDD_NETBIOS_NAME, winbindd_netbios_name, "NETBIOS_NAME" },
    442455        { WINBINDD_PRIV_PIPE_DIR, winbindd_priv_pipe_dir,
     
    473486        { WINBINDD_LOOKUPSID, "LOOKUPSID",
    474487          winbindd_lookupsid_send, winbindd_lookupsid_recv },
     488        { WINBINDD_LOOKUPSIDS, "LOOKUPSIDS",
     489          winbindd_lookupsids_send, winbindd_lookupsids_recv },
    475490        { WINBINDD_LOOKUPNAME, "LOOKUPNAME",
    476491          winbindd_lookupname_send, winbindd_lookupname_recv },
     
    483498        { WINBINDD_GID_TO_SID, "GID_TO_SID",
    484499          winbindd_gid_to_sid_send, winbindd_gid_to_sid_recv },
     500        { WINBINDD_SIDS_TO_XIDS, "SIDS_TO_XIDS",
     501          winbindd_sids_to_xids_send, winbindd_sids_to_xids_recv },
    485502        { WINBINDD_GETPWSID, "GETPWSID",
    486503          winbindd_getpwsid_send, winbindd_getpwsid_recv },
     
    529546        { WINBINDD_PING_DC, "PING_DC",
    530547          winbindd_ping_dc_send, winbindd_ping_dc_recv },
     548        { WINBINDD_PAM_AUTH, "PAM_AUTH",
     549          winbindd_pam_auth_send, winbindd_pam_auth_recv },
     550        { WINBINDD_PAM_LOGOFF, "PAM_LOGOFF",
     551          winbindd_pam_logoff_send, winbindd_pam_logoff_recv },
     552        { WINBINDD_PAM_CHAUTHTOK, "PAM_CHAUTHTOK",
     553          winbindd_pam_chauthtok_send, winbindd_pam_chauthtok_recv },
     554        { WINBINDD_PAM_CHNG_PSWD_AUTH_CRAP, "PAM_CHNG_PSWD_AUTH_CRAP",
     555          winbindd_pam_chng_pswd_auth_crap_send,
     556          winbindd_pam_chng_pswd_auth_crap_recv },
    531557
    532558        { 0, NULL, NULL, NULL }
     
    538564        { WINBINDD_ALLOCATE_GID, "ALLOCATE_GID",
    539565          winbindd_allocate_gid_send, winbindd_allocate_gid_recv },
    540         { WINBINDD_SET_MAPPING, "SET_MAPPING",
    541           winbindd_set_mapping_send, winbindd_set_mapping_recv },
    542         { WINBINDD_REMOVE_MAPPING, "SET_MAPPING",
    543           winbindd_remove_mapping_send, winbindd_remove_mapping_recv },
    544         { WINBINDD_SET_HWM, "SET_HWM",
    545           winbindd_set_hwm_send, winbindd_set_hwm_recv },
    546566        { WINBINDD_CHANGE_MACHACC, "CHANGE_MACHACC",
    547567          winbindd_change_machine_acct_send, winbindd_change_machine_acct_recv },
     568        { WINBINDD_PAM_AUTH_CRAP, "PAM_AUTH_CRAP",
     569          winbindd_pam_auth_crap_send, winbindd_pam_auth_crap_recv },
    548570
    549571        { 0, NULL, NULL, NULL }
     
    557579        struct winbindd_async_dispatch_table *atable;
    558580
    559         state->mem_ctx = talloc_init("winbind request");
     581        state->mem_ctx = talloc_named(state, 0, "winbind request");
    560582        if (state->mem_ctx == NULL)
    561583                return;
     
    713735        }
    714736
    715         DEBUG(10,("winbind_client_response_written[%d:%s]: deliverd response to client\n",
    716                   (int)state->pid, state->cmd_name));
     737        DEBUG(10,("winbind_client_response_written[%d:%s]: delivered response "
     738                  "to client\n", (int)state->pid, state->cmd_name));
    717739
    718740        TALLOC_FREE(state->mem_ctx);
     
    758780        len = sizeof(sunaddr);
    759781
    760         do {
    761                 sock = accept(listen_sock, (struct sockaddr *)(void *)&sunaddr,
    762                               &len);
    763         } while (sock == -1 && errno == EINTR);
    764 
    765         if (sock == -1)
    766                 return;
     782        sock = accept(listen_sock, (struct sockaddr *)(void *)&sunaddr, &len);
     783
     784        if (sock == -1) {
     785                if (errno != EINTR) {
     786                        DEBUG(0, ("Faild to accept socket - %s\n",
     787                                  strerror(errno)));
     788                }
     789                return;
     790        }
    767791
    768792        DEBUG(6,("accepted socket %d\n", sock));
     
    862886}
    863887
     888/* Is a client idle? */
     889
     890static bool client_is_idle(struct winbindd_cli_state *state) {
     891  return (state->response == NULL &&
     892          !state->pwent_state && !state->grent_state);
     893}
     894
    864895/* Shutdown client connection which has been idle for the longest time */
    865896
     
    871902
    872903        for (state = winbindd_client_list(); state; state = state->next) {
    873                 if (state->response == NULL &&
    874                     !state->pwent_state && !state->grent_state) {
     904                if (client_is_idle(state)) {
    875905                        nidle++;
    876906                        if (!last_access || state->last_access < last_access) {
     
    904934                                          struct winbindd_listen_state);
    905935
    906         while (winbindd_num_clients() >
    907                WINBINDD_MAX_SIMULTANEOUS_CLIENTS - 1) {
     936        while (winbindd_num_clients() > lp_winbind_max_clients() - 1) {
    908937                DEBUG(5,("winbindd: Exceeding %d client "
    909938                         "connections, removing idle "
    910                          "connection.\n",
    911                          WINBINDD_MAX_SIMULTANEOUS_CLIENTS));
     939                         "connection.\n", lp_winbind_max_clients()));
    912940                if (!remove_idle_client()) {
    913941                        DEBUG(0,("winbindd: Exceeding %d "
    914942                                 "client connections, no idle "
    915943                                 "connection found\n",
    916                                  WINBINDD_MAX_SIMULTANEOUS_CLIENTS));
     944                                 lp_winbind_max_clients()));
    917945                        break;
    918946                }
    919947        }
    920948        new_connection(s->fd, s->privileged);
     949}
     950
     951/*
     952 * Winbindd socket accessor functions
     953 */
     954
     955const char *get_winbind_pipe_dir(void)
     956{
     957        return lp_parm_const_string(-1, "winbindd", "socket dir", WINBINDD_SOCKET_DIR);
     958}
     959
     960char *get_winbind_priv_pipe_dir(void)
     961{
     962        return lock_path(WINBINDD_PRIV_SOCKET_SUBDIR);
    921963}
    922964
     
    934976
    935977        pub_state->privileged = false;
    936         pub_state->fd = open_winbindd_socket();
     978        pub_state->fd = create_pipe_sock(
     979                get_winbind_pipe_dir(), WINBINDD_SOCKET_NAME, 0755);
    937980        if (pub_state->fd == -1) {
    938981                goto failed;
     
    955998
    956999        priv_state->privileged = true;
    957         priv_state->fd = open_winbindd_priv_socket();
     1000        priv_state->fd = create_pipe_sock(
     1001                get_winbind_priv_pipe_dir(), WINBINDD_SOCKET_NAME, 0750);
    9581002        if (priv_state->fd == -1) {
    9591003                goto failed;
     
    9841028{
    9851029        return !opt_nocache;
     1030}
     1031
     1032void winbindd_register_handlers(void)
     1033{
     1034        /* Setup signal handlers */
     1035
     1036        if (!winbindd_setup_sig_term_handler(true))
     1037                exit(1);
     1038        if (!winbindd_setup_sig_hup_handler(NULL))
     1039                exit(1);
     1040        if (!winbindd_setup_sig_chld_handler())
     1041                exit(1);
     1042        if (!winbindd_setup_sig_usr2_handler())
     1043                exit(1);
     1044
     1045        CatchSignal(SIGPIPE, SIG_IGN);                 /* Ignore sigpipe */
     1046
     1047        /*
     1048         * Ensure all cache and idmap caches are consistent
     1049         * and initialized before we startup.
     1050         */
     1051        if (!winbindd_cache_validate_and_initialize()) {
     1052                exit(1);
     1053        }
     1054
     1055        /* get broadcast messages */
     1056
     1057        if (!serverid_register(procid_self(),
     1058                               FLAG_MSG_GENERAL|FLAG_MSG_DBWRAP)) {
     1059                DEBUG(1, ("Could not register myself in serverid.tdb\n"));
     1060                exit(1);
     1061        }
     1062
     1063        /* React on 'smbcontrol winbindd reload-config' in the same way
     1064           as to SIGHUP signal */
     1065        messaging_register(winbind_messaging_context(), NULL,
     1066                           MSG_SMB_CONF_UPDATED, msg_reload_services);
     1067        messaging_register(winbind_messaging_context(), NULL,
     1068                           MSG_SHUTDOWN, msg_shutdown);
     1069
     1070        /* Handle online/offline messages. */
     1071        messaging_register(winbind_messaging_context(), NULL,
     1072                           MSG_WINBIND_OFFLINE, winbind_msg_offline);
     1073        messaging_register(winbind_messaging_context(), NULL,
     1074                           MSG_WINBIND_ONLINE, winbind_msg_online);
     1075        messaging_register(winbind_messaging_context(), NULL,
     1076                           MSG_WINBIND_ONLINESTATUS, winbind_msg_onlinestatus);
     1077
     1078        messaging_register(winbind_messaging_context(), NULL,
     1079                           MSG_DUMP_EVENT_LIST, winbind_msg_dump_event_list);
     1080
     1081        messaging_register(winbind_messaging_context(), NULL,
     1082                           MSG_WINBIND_VALIDATE_CACHE,
     1083                           winbind_msg_validate_cache);
     1084
     1085        messaging_register(winbind_messaging_context(), NULL,
     1086                           MSG_WINBIND_DUMP_DOMAIN_LIST,
     1087                           winbind_msg_dump_domain_list);
     1088
     1089        messaging_register(winbind_messaging_context(), NULL,
     1090                           MSG_WINBIND_IP_DROPPED,
     1091                           winbind_msg_ip_dropped_parent);
     1092
     1093        /* Register handler for MSG_DEBUG. */
     1094        messaging_register(winbind_messaging_context(), NULL,
     1095                           MSG_DEBUG,
     1096                           winbind_msg_debug);
     1097
     1098        netsamlogon_cache_init(); /* Non-critical */
     1099
     1100        /* clear the cached list of trusted domains */
     1101
     1102        wcache_tdc_clear();
     1103
     1104        if (!init_domain_list()) {
     1105                DEBUG(0,("unable to initialize domain list\n"));
     1106                exit(1);
     1107        }
     1108
     1109        init_idmap_child();
     1110        init_locator_child();
     1111
     1112        smb_nscd_flush_user_cache();
     1113        smb_nscd_flush_group_cache();
     1114
     1115        if (lp_allow_trusted_domains()) {
     1116                if (tevent_add_timer(winbind_event_context(), NULL, timeval_zero(),
     1117                              rescan_trusted_domains, NULL) == NULL) {
     1118                        DEBUG(0, ("Could not trigger rescan_trusted_domains()\n"));
     1119                        exit(1);
     1120                }
     1121        }
     1122
     1123}
     1124
     1125struct winbindd_addrchanged_state {
     1126        struct addrchange_context *ctx;
     1127        struct tevent_context *ev;
     1128        struct messaging_context *msg_ctx;
     1129};
     1130
     1131static void winbindd_addr_changed(struct tevent_req *req);
     1132
     1133static void winbindd_init_addrchange(TALLOC_CTX *mem_ctx,
     1134                                     struct tevent_context *ev,
     1135                                     struct messaging_context *msg_ctx)
     1136{
     1137        struct winbindd_addrchanged_state *state;
     1138        struct tevent_req *req;
     1139        NTSTATUS status;
     1140
     1141        state = talloc(mem_ctx, struct winbindd_addrchanged_state);
     1142        if (state == NULL) {
     1143                DEBUG(10, ("talloc failed\n"));
     1144                return;
     1145        }
     1146        state->ev = ev;
     1147        state->msg_ctx = msg_ctx;
     1148
     1149        status = addrchange_context_create(state, &state->ctx);
     1150        if (!NT_STATUS_IS_OK(status)) {
     1151                DEBUG(10, ("addrchange_context_create failed: %s\n",
     1152                           nt_errstr(status)));
     1153                TALLOC_FREE(state);
     1154                return;
     1155        }
     1156        req = addrchange_send(state, ev, state->ctx);
     1157        if (req == NULL) {
     1158                DEBUG(0, ("addrchange_send failed\n"));
     1159                TALLOC_FREE(state);
     1160                return;
     1161        }
     1162        tevent_req_set_callback(req, winbindd_addr_changed, state);
     1163}
     1164
     1165static void winbindd_addr_changed(struct tevent_req *req)
     1166{
     1167        struct winbindd_addrchanged_state *state = tevent_req_callback_data(
     1168                req, struct winbindd_addrchanged_state);
     1169        enum addrchange_type type;
     1170        struct sockaddr_storage addr;
     1171        NTSTATUS status;
     1172
     1173        status = addrchange_recv(req, &type, &addr);
     1174        TALLOC_FREE(req);
     1175        if (!NT_STATUS_IS_OK(status)) {
     1176                DEBUG(10, ("addrchange_recv failed: %s, stop listening\n",
     1177                           nt_errstr(status)));
     1178                TALLOC_FREE(state);
     1179                return;
     1180        }
     1181        if (type == ADDRCHANGE_DEL) {
     1182                char addrstr[INET6_ADDRSTRLEN];
     1183                DATA_BLOB blob;
     1184
     1185                print_sockaddr(addrstr, sizeof(addrstr), &addr);
     1186
     1187                DEBUG(3, ("winbindd: kernel (AF_NETLINK) dropped ip %s\n",
     1188                          addrstr));
     1189
     1190                blob = data_blob_const(addrstr, strlen(addrstr)+1);
     1191
     1192                status = messaging_send(state->msg_ctx,
     1193                                        messaging_server_id(state->msg_ctx),
     1194                                        MSG_WINBIND_IP_DROPPED, &blob);
     1195                if (!NT_STATUS_IS_OK(status)) {
     1196                        DEBUG(10, ("messaging_send failed: %s - ignoring\n",
     1197                                   nt_errstr(status)));
     1198                }
     1199        }
     1200        req = addrchange_send(state, state->ev, state->ctx);
     1201        if (req == NULL) {
     1202                DEBUG(0, ("addrchange_send failed\n"));
     1203                TALLOC_FREE(state);
     1204                return;
     1205        }
     1206        tevent_req_set_callback(req, winbindd_addr_changed, state);
    9861207}
    9871208
     
    10131234        poptContext pc;
    10141235        int opt;
    1015         TALLOC_CTX *frame = talloc_stackframe();
     1236        TALLOC_CTX *frame;
     1237        NTSTATUS status;
     1238
     1239        /*
     1240         * Do this before any other talloc operation
     1241         */
     1242        talloc_enable_null_tracking();
     1243        frame = talloc_stackframe();
    10161244
    10171245        /* glibc (?) likes to print "User defined signal 1" and exit if a
     
    10991327                }
    11001328        }
    1101         setup_logging("winbindd", log_stdout);
     1329        if (log_stdout) {
     1330                setup_logging("winbindd", DEBUG_STDOUT);
     1331        } else {
     1332                setup_logging("winbindd", DEBUG_FILE);
     1333        }
    11021334        reopen_logs();
    11031335
     
    11371369                return False;
    11381370        }
    1139 
    1140         /* Enable netbios namecache */
    1141 
    1142         namecache_enable();
    11431371
    11441372        /* Unblock all signals we are interested in as they may have been
     
    11541382
    11551383        if (!interactive)
    1156                 become_daemon(Fork, no_process_group);
     1384                become_daemon(Fork, no_process_group, log_stdout);
    11571385
    11581386        pidfile_create("winbindd");
     
    11741402         */
    11751403
    1176         if (!NT_STATUS_IS_OK(reinit_after_fork(winbind_messaging_context(),
    1177                                                winbind_event_context(),
    1178                                                false))) {
     1404        status = reinit_after_fork(winbind_messaging_context(),
     1405                                   winbind_event_context(),
     1406                                   procid_self(), false);
     1407        if (!NT_STATUS_IS_OK(status)) {
    11791408                DEBUG(0,("reinit_after_fork() failed\n"));
    11801409                exit(1);
    11811410        }
    11821411
    1183         /* Setup signal handlers */
    1184 
    1185         if (!winbindd_setup_sig_term_handler(true))
    1186                 exit(1);
    1187         if (!winbindd_setup_sig_hup_handler(NULL))
    1188                 exit(1);
    1189         if (!winbindd_setup_sig_chld_handler())
    1190                 exit(1);
    1191         if (!winbindd_setup_sig_usr2_handler())
    1192                 exit(1);
    1193 
    1194         CatchSignal(SIGPIPE, SIG_IGN);                 /* Ignore sigpipe */
    1195 
    1196         /*
    1197          * Ensure all cache and idmap caches are consistent
    1198          * and initialized before we startup.
    1199          */
    1200         if (!winbindd_cache_validate_and_initialize()) {
    1201                 exit(1);
    1202         }
    1203 
    1204         /* get broadcast messages */
    1205         claim_connection(NULL,"",FLAG_MSG_GENERAL|FLAG_MSG_DBWRAP);
    1206 
    1207         /* React on 'smbcontrol winbindd reload-config' in the same way
    1208            as to SIGHUP signal */
    1209         messaging_register(winbind_messaging_context(), NULL,
    1210                            MSG_SMB_CONF_UPDATED, msg_reload_services);
    1211         messaging_register(winbind_messaging_context(), NULL,
    1212                            MSG_SHUTDOWN, msg_shutdown);
    1213 
    1214         /* Handle online/offline messages. */
    1215         messaging_register(winbind_messaging_context(), NULL,
    1216                            MSG_WINBIND_OFFLINE, winbind_msg_offline);
    1217         messaging_register(winbind_messaging_context(), NULL,
    1218                            MSG_WINBIND_ONLINE, winbind_msg_online);
    1219         messaging_register(winbind_messaging_context(), NULL,
    1220                            MSG_WINBIND_ONLINESTATUS, winbind_msg_onlinestatus);
    1221 
    1222         messaging_register(winbind_messaging_context(), NULL,
    1223                            MSG_DUMP_EVENT_LIST, winbind_msg_dump_event_list);
    1224 
    1225         messaging_register(winbind_messaging_context(), NULL,
    1226                            MSG_WINBIND_VALIDATE_CACHE,
    1227                            winbind_msg_validate_cache);
    1228 
    1229         messaging_register(winbind_messaging_context(), NULL,
    1230                            MSG_WINBIND_DUMP_DOMAIN_LIST,
    1231                            winbind_msg_dump_domain_list);
    1232 
    1233         /* Register handler for MSG_DEBUG. */
    1234         messaging_register(winbind_messaging_context(), NULL,
    1235                            MSG_DEBUG,
    1236                            winbind_msg_debug);
    1237 
    1238         netsamlogon_cache_init(); /* Non-critical */
    1239 
    1240         /* clear the cached list of trusted domains */
    1241 
    1242         wcache_tdc_clear();     
    1243 
    1244         if (!init_domain_list()) {
    1245                 DEBUG(0,("unable to initialize domain list\n"));
    1246                 exit(1);
    1247         }
    1248 
    1249         init_idmap_child();
    1250         init_locator_child();
    1251 
    1252         smb_nscd_flush_user_cache();
    1253         smb_nscd_flush_group_cache();
     1412        winbindd_register_handlers();
     1413
     1414        status = init_system_info();
     1415        if (!NT_STATUS_IS_OK(status)) {
     1416                DEBUG(1, ("ERROR: failed to setup system user info: %s.\n",
     1417                          nt_errstr(status)));
     1418                exit(1);
     1419        }
     1420
     1421        rpc_lsarpc_init(NULL);
     1422        rpc_samr_init(NULL);
     1423
     1424        winbindd_init_addrchange(NULL, winbind_event_context(),
     1425                                 winbind_messaging_context());
    12541426
    12551427        /* setup listen sockets */
     
    12581430                DEBUG(0,("winbindd_setup_listeners() failed\n"));
    12591431                exit(1);
    1260         }
    1261 
    1262         if (lp_allow_trusted_domains()) {
    1263                 if (tevent_add_timer(winbind_event_context(), NULL, timeval_zero(),
    1264                               rescan_trusted_domains, NULL) == NULL) {
    1265                         DEBUG(0, ("Could not trigger rescan_trusted_domains()\n"));
    1266                         exit(1);
    1267                 }
    12681432        }
    12691433
  • vendor/current/source3/winbindd/winbindd.h

    r594 r740  
    2828#include "librpc/gen_ndr/wbint.h"
    2929
     30#include "talloc_dict.h"
     31#include "smb_ldap.h"
     32
     33#include "../lib/util/tevent_ntstatus.h"
     34
    3035#ifdef HAVE_LIBNSCD
    3136#include <libnscd.h>
     
    4247
    4348struct sid_ctr {
    44         DOM_SID *sid;
     49        struct dom_sid *sid;
    4550        bool finished;
    4651        const char *domain;
     
    9398        fstring homedir;                     /* User Home Directory */
    9499        fstring shell;                       /* User Login Shell */
    95         DOM_SID user_sid;                    /* NT user and primary group SIDs */
    96         DOM_SID group_sid;
     100        struct dom_sid user_sid;                    /* NT user and primary group SIDs */
     101        struct dom_sid group_sid;
    97102};
    98103
     
    132137        int sock;
    133138        struct tevent_queue *queue;
    134         struct rpc_pipe_client *rpccli;
     139        struct dcerpc_binding_handle *binding_handle;
    135140
    136141        struct timed_event *lockout_policy_event;
     
    146151        fstring alt_name;                      /* alt Domain name, if any (FQDN for ADS) */
    147152        fstring forest_name;                   /* Name of the AD forest we're in */
    148         DOM_SID sid;                           /* SID for this domain */
     153        struct dom_sid sid;                           /* SID for this domain */
    149154        uint32 domain_flags;                   /* Domain flags from netlogon.h */
    150155        uint32 domain_type;                    /* Domain type from netlogon.h */
     
    156161        bool internal;                         /* BUILTIN and member SAM */
    157162        bool online;                           /* is this domain available ? */
    158         time_t startup_time;                   /* When we set "startup" true. */
     163        time_t startup_time;                   /* When we set "startup" true. monotonic clock */
    159164        bool startup;                          /* are we in the first 30 seconds after startup_time ? */
    160165
     
    205210        /* The child pid we're talking to */
    206211
    207         struct winbindd_child child;
     212        struct winbindd_child *children;
    208213
    209214        /* Callback we use to try put us back online. */
     
    215220
    216221        struct winbindd_domain *prev, *next;
     222};
     223
     224struct wb_acct_info {
     225        fstring acct_name; /* account name */
     226        fstring acct_desc; /* account name */
     227        uint32_t rid; /* domain-relative RID */
    217228};
    218229
     
    234245                                    TALLOC_CTX *mem_ctx,
    235246                                    uint32 *num_entries,
    236                                     struct acct_info **info);
     247                                    struct wb_acct_info **info);
    237248
    238249        /* get a list of domain local groups */
     
    240251                                    TALLOC_CTX *mem_ctx,
    241252                                    uint32 *num_entries,
    242                                     struct acct_info **info);
     253                                    struct wb_acct_info **info);
    243254
    244255        /* convert one user or group name to a sid */
     
    248259                                const char *name,
    249260                                uint32_t flags,
    250                                 DOM_SID *sid,
     261                                struct dom_sid *sid,
    251262                                enum lsa_SidType *type);
    252263
     
    254265        NTSTATUS (*sid_to_name)(struct winbindd_domain *domain,
    255266                                TALLOC_CTX *mem_ctx,
    256                                 const DOM_SID *sid,
     267                                const struct dom_sid *sid,
    257268                                char **domain_name,
    258269                                char **name,
     
    261272        NTSTATUS (*rids_to_names)(struct winbindd_domain *domain,
    262273                                  TALLOC_CTX *mem_ctx,
    263                                   const DOM_SID *domain_sid,
     274                                  const struct dom_sid *domain_sid,
    264275                                  uint32 *rids,
    265276                                  size_t num_rids,
     
    271282        NTSTATUS (*query_user)(struct winbindd_domain *domain,
    272283                               TALLOC_CTX *mem_ctx,
    273                                const DOM_SID *user_sid,
     284                               const struct dom_sid *user_sid,
    274285                               struct wbint_userinfo *user_info);
    275286
     
    279290        NTSTATUS (*lookup_usergroups)(struct winbindd_domain *domain,
    280291                                      TALLOC_CTX *mem_ctx,
    281                                       const DOM_SID *user_sid,
    282                                       uint32 *num_groups, DOM_SID **user_gids);
     292                                      const struct dom_sid *user_sid,
     293                                      uint32 *num_groups, struct dom_sid **user_gids);
    283294
    284295        /* Lookup all aliases that the sids delivered are member of. This is
     
    287298                                       TALLOC_CTX *mem_ctx,
    288299                                       uint32 num_sids,
    289                                        const DOM_SID *sids,
     300                                       const struct dom_sid *sids,
    290301                                       uint32 *num_aliases,
    291302                                       uint32 **alias_rids);
     
    294305        NTSTATUS (*lookup_groupmem)(struct winbindd_domain *domain,
    295306                                    TALLOC_CTX *mem_ctx,
    296                                     const DOM_SID *group_sid,
     307                                    const struct dom_sid *group_sid,
    297308                                    enum lsa_SidType type,
    298309                                    uint32 *num_names,
    299                                     DOM_SID **sid_mem, char ***names,
     310                                    struct dom_sid **sid_mem, char ***names,
    300311                                    uint32 **name_types);
    301312
     
    324335  bool (*init)(void);
    325336
    326   bool (*get_sid_from_uid)(uid_t uid, DOM_SID *sid);
    327   bool (*get_sid_from_gid)(gid_t gid, DOM_SID *sid);
    328 
    329   bool (*get_uid_from_sid)(DOM_SID *sid, uid_t *uid);
    330   bool (*get_gid_from_sid)(DOM_SID *sid, gid_t *gid);
     337  bool (*get_sid_from_uid)(uid_t uid, struct dom_sid *sid);
     338  bool (*get_sid_from_gid)(gid_t gid, struct dom_sid *sid);
     339
     340  bool (*get_uid_from_sid)(struct dom_sid *sid, uid_t *uid);
     341  bool (*get_gid_from_sid)(struct dom_sid *sid, gid_t *gid);
    331342
    332343  /* Called when backend is unloaded */
     
    341352        const char *domain_name;
    342353        const char *dns_name;
    343         DOM_SID sid;
     354        struct dom_sid sid;
    344355        uint32 trust_flags;
    345356        uint32 trust_attribs;
     
    387398#define DOM_SEQUENCE_NONE ((uint32)-1)
    388399
     400#define winbind_event_context server_event_context
     401
    389402#endif /* _WINBINDD_H */
  • vendor/current/source3/winbindd/winbindd_ads.c

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

    r414 r740  
    2020#include "includes.h"
    2121#include "winbindd.h"
    22 #include "librpc/gen_ndr/cli_wbint.h"
     22#include "librpc/gen_ndr/ndr_wbint_c.h"
    2323
    2424struct winbindd_allocate_gid_state {
     
    4747        child = idmap_child();
    4848
    49         subreq = rpccli_wbint_AllocateGid_send(state, ev, child->rpccli,
     49        subreq = dcerpc_wbint_AllocateGid_send(state, ev, child->binding_handle,
    5050                                               &state->gid);
    5151        if (tevent_req_nomem(subreq, req)) {
     
    6464        NTSTATUS status, result;
    6565
    66         status = rpccli_wbint_AllocateGid_recv(subreq, state, &result);
     66        status = dcerpc_wbint_AllocateGid_recv(subreq, state, &result);
    6767        TALLOC_FREE(subreq);
    68         if (!NT_STATUS_IS_OK(status)) {
     68        if (any_nt_status_not_ok(status, result, &status)) {
    6969                tevent_req_nterror(req, status);
    70                 return;
    71         }
    72         if (!NT_STATUS_IS_OK(result)) {
    73                 tevent_req_nterror(req, result);
    7470                return;
    7571        }
  • vendor/current/source3/winbindd/winbindd_allocate_uid.c

    r414 r740  
    2020#include "includes.h"
    2121#include "winbindd.h"
    22 #include "librpc/gen_ndr/cli_wbint.h"
     22#include "librpc/gen_ndr/ndr_wbint_c.h"
    2323
    2424struct winbindd_allocate_uid_state {
     
    4747        child = idmap_child();
    4848
    49         subreq = rpccli_wbint_AllocateUid_send(state, ev, child->rpccli,
     49        subreq = dcerpc_wbint_AllocateUid_send(state, ev, child->binding_handle,
    5050                                               &state->uid);
    5151        if (tevent_req_nomem(subreq, req)) {
     
    6464        NTSTATUS status, result;
    6565
    66         status = rpccli_wbint_AllocateUid_recv(subreq, state, &result);
     66        status = dcerpc_wbint_AllocateUid_recv(subreq, state, &result);
    6767        TALLOC_FREE(subreq);
    68         if (!NT_STATUS_IS_OK(status)) {
     68        if (any_nt_status_not_ok(status, result, &status)) {
    6969                tevent_req_nterror(req, status);
    70                 return;
    71         }
    72         if (!NT_STATUS_IS_OK(result)) {
    73                 tevent_req_nterror(req, result);
    7470                return;
    7571        }
  • vendor/current/source3/winbindd/winbindd_async.c

    r414 r740  
    2323#include "includes.h"
    2424#include "winbindd.h"
     25#include "../libcli/security/security.h"
    2526
    2627#undef DBGC_CLASS
    2728#define DBGC_CLASS DBGC_WINBIND
    28 
    29 bool print_sidlist(TALLOC_CTX *mem_ctx, const DOM_SID *sids,
    30                    size_t num_sids, char **result, ssize_t *len)
    31 {
    32         size_t i;
    33         size_t buflen = 0;
    34 
    35         *len = 0;
    36         *result = NULL;
    37         for (i=0; i<num_sids; i++) {
    38                 fstring tmp;
    39                 sprintf_append(mem_ctx, result, len, &buflen,
    40                                "%s\n", sid_to_fstring(tmp, &sids[i]));
    41         }
    42 
    43         if ((num_sids != 0) && (*result == NULL)) {
    44                 return False;
    45         }
    46 
    47         return True;
    48 }
    49 
    50 bool parse_sidlist(TALLOC_CTX *mem_ctx, const char *sidstr,
    51                    DOM_SID **sids, size_t *num_sids)
    52 {
    53         const char *p, *q;
    54 
    55         p = sidstr;
    56         if (p == NULL)
    57                 return False;
    58 
    59         while (p[0] != '\0') {
    60                 fstring tmp;
    61                 size_t sidlen;
    62                 DOM_SID sid;
    63                 q = strchr(p, '\n');
    64                 if (q == NULL) {
    65                         DEBUG(0, ("Got invalid sidstr: %s\n", p));
    66                         return False;
    67                 }
    68                 sidlen = PTR_DIFF(q, p);
    69                 if (sidlen >= sizeof(tmp)-1) {
    70                         return false;
    71                 }
    72                 memcpy(tmp, p, sidlen);
    73                 tmp[sidlen] = '\0';
    74                 q += 1;
    75                 if (!string_to_sid(&sid, tmp)) {
    76                         DEBUG(0, ("Could not parse sid %s\n", p));
    77                         return False;
    78                 }
    79                 if (!NT_STATUS_IS_OK(add_sid_to_array(mem_ctx, &sid, sids,
    80                                                       num_sids)))
    81                 {
    82                         return False;
    83                 }
    84                 p = q;
    85         }
    86         return True;
    87 }
    8829
    8930enum winbindd_result winbindd_dual_ping(struct winbindd_domain *domain,
  • vendor/current/source3/winbindd/winbindd_cache.c

    r597 r740  
    2525
    2626#include "includes.h"
     27#include "system/filesys.h"
    2728#include "winbindd.h"
    2829#include "tdb_validate.h"
    2930#include "../libcli/auth/libcli_auth.h"
    3031#include "../librpc/gen_ndr/ndr_wbint.h"
     32#include "ads.h"
     33#include "nss_info.h"
     34#include "../libcli/security/security.h"
     35#include "passdb/machine_sid.h"
     36#include "util_tdb.h"
    3137
    3238#undef DBGC_CLASS
    3339#define DBGC_CLASS DBGC_WINBIND
    3440
    35 #define WINBINDD_CACHE_VERSION 1
     41#define WINBINDD_CACHE_VERSION 2
    3642#define WINBINDD_CACHE_VERSION_KEYSTR "WINBINDD_CACHE_VERSION"
    3743
     
    4147#endif
    4248extern struct winbindd_methods builtin_passdb_methods;
     49extern struct winbindd_methods sam_passdb_methods;
    4350
    4451/*
     
    93100        NTSTATUS status;
    94101        uint32 sequence_number;
     102        uint64_t timeout;
    95103        uint8 *data;
    96104        uint32 len, ofs;
     
    103111static struct winbind_cache *wcache;
    104112
    105 void winbindd_check_cache_size(time_t t)
    106 {
    107         static time_t last_check_time;
    108         struct stat st;
    109 
    110         if (last_check_time == (time_t)0)
    111                 last_check_time = t;
    112 
    113         if (t - last_check_time < 60 && t - last_check_time > 0)
    114                 return;
    115 
    116         if (wcache == NULL || wcache->tdb == NULL) {
    117                 DEBUG(0, ("Unable to check size of tdb cache - cache not open !\n"));
    118                 return;
    119         }
    120 
    121         if (fstat(tdb_fd(wcache->tdb), &st) == -1) {
    122                 DEBUG(0, ("Unable to check size of tdb cache %s!\n", strerror(errno) ));
    123                 return;
    124         }
    125 
    126         if (st.st_size > WINBINDD_MAX_CACHE_SIZE) {
    127                 DEBUG(10,("flushing cache due to size (%lu) > (%lu)\n",
    128                         (unsigned long)st.st_size,
    129                         (unsigned long)WINBINDD_MAX_CACHE_SIZE));
    130                 wcache_flush_cache();
    131         }
    132 }
    133 
    134113/* get the winbind_cache structure */
    135114static struct winbind_cache *get_cache(struct winbindd_domain *domain)
     
    143122                domain->initialized = True;
    144123        }
     124
     125        if (strequal(domain->name, get_global_sam_name()) &&
     126            sid_check_is_domain(&domain->sid)) {
     127                domain->backend = &sam_passdb_methods;
     128                domain->initialized = True;
     129        }
     130
    145131        if ( !domain->initialized ) {
    146132                init_dc_connection( domain );
     
    224210
    225211/*
     212  pull a uint64_t from a cache entry
     213*/
     214static uint64_t centry_uint64_t(struct cache_entry *centry)
     215{
     216        uint64_t ret;
     217
     218        if (!centry_check_bytes(centry, 8)) {
     219                smb_panic_fn("centry_uint64_t");
     220        }
     221        ret = BVAL(centry->data, centry->ofs);
     222        centry->ofs += 8;
     223        return ret;
     224}
     225
     226/*
    226227  pull a uint32 from a cache entry
    227228*/
     
    277278        ret = IVAL(centry->data, centry->ofs);
    278279        centry->ofs += 4;
    279         ret += (uint64_t)IVAL(centry->data, centry->ofs) << 32;
     280        ret += (uint64)IVAL(centry->data, centry->ofs) << 32;
    280281        centry->ofs += 4;
    281282        return ret;
     
    615616
    616617        /* if the server is down or the cache entry is not older than the
    617            current sequence number then it is OK */
    618         if (wcache_server_down(domain) ||
    619             centry->sequence_number == domain->sequence_number) {
     618           current sequence number or it did not timeout then it is OK */
     619        if (wcache_server_down(domain)
     620            || ((centry->sequence_number == domain->sequence_number)
     621                && (centry->timeout > time(NULL)))) {
    620622                DEBUG(10,("centry_expired: Key %s for domain %s is good.\n",
    621623                        keystr, domain->name ));
     
    648650        centry->ofs = 0;
    649651
    650         if (centry->len < 8) {
     652        if (centry->len < 16) {
    651653                /* huh? corrupt cache? */
    652                 DEBUG(10,("wcache_fetch_raw: Corrupt cache for key %s (len < 8) ?\n", kstr));
     654                DEBUG(10,("wcache_fetch_raw: Corrupt cache for key %s "
     655                          "(len < 16)?\n", kstr));
    653656                centry_free(centry);
    654657                return NULL;
     
    657660        centry->status = centry_ntstatus(centry);
    658661        centry->sequence_number = centry_uint32(centry);
     662        centry->timeout = centry_uint64_t(centry);
    659663
    660664        return centry;
     665}
     666
     667static bool is_my_own_sam_domain(struct winbindd_domain *domain)
     668{
     669        if (strequal(domain->name, get_global_sam_name()) &&
     670            sid_check_is_domain(&domain->sid)) {
     671                return true;
     672        }
     673
     674        return false;
     675}
     676
     677static bool is_builtin_domain(struct winbindd_domain *domain)
     678{
     679        if (strequal(domain->name, "BUILTIN") &&
     680            sid_check_is_builtin(&domain->sid)) {
     681                return true;
     682        }
     683
     684        return false;
    661685}
    662686
     
    676700        struct cache_entry *centry;
    677701
    678         if (!winbindd_use_cache()) {
     702        if (!winbindd_use_cache() ||
     703            is_my_own_sam_domain(domain) ||
     704            is_builtin_domain(domain)) {
    679705                return NULL;
    680706        }
     
    743769
    744770/*
     771  push a uint64_t into a centry
     772*/
     773static void centry_put_uint64_t(struct cache_entry *centry, uint64_t v)
     774{
     775        centry_expand(centry, 8);
     776        SBVAL(centry->data, centry->ofs, v);
     777        centry->ofs += 8;
     778}
     779
     780/*
    745781  push a uint32 into a centry
    746782*/
     
    808844}
    809845
    810 static void centry_put_sid(struct cache_entry *centry, const DOM_SID *sid)
     846static void centry_put_sid(struct cache_entry *centry, const struct dom_sid *sid)
    811847{
    812848        fstring sid_string;
     
    863899        centry->ofs = 0;
    864900        centry->sequence_number = domain->sequence_number;
     901        centry->timeout = lp_winbind_cache_time() + time(NULL);
    865902        centry_put_ntstatus(centry, status);
    866903        centry_put_uint32(centry, centry->sequence_number);
     904        centry_put_uint64_t(centry, centry->timeout);
    867905        return centry;
    868906}
     
    896934static void wcache_save_name_to_sid(struct winbindd_domain *domain,
    897935                                    NTSTATUS status, const char *domain_name,
    898                                     const char *name, const DOM_SID *sid,
     936                                    const char *name, const struct dom_sid *sid,
    899937                                    enum lsa_SidType type)
    900938{
     
    916954
    917955static void wcache_save_sid_to_name(struct winbindd_domain *domain, NTSTATUS status,
    918                                     const DOM_SID *sid, const char *domain_name, const char *name, enum lsa_SidType type)
     956                                    const struct dom_sid *sid, const char *domain_name, const char *name, enum lsa_SidType type)
    919957{
    920958        struct cache_entry *centry;
     
    12131251}
    12141252
    1215 NTSTATUS wcache_cached_creds_exist(struct winbindd_domain *domain, const DOM_SID *sid)
     1253NTSTATUS wcache_cached_creds_exist(struct winbindd_domain *domain, const struct dom_sid *sid)
    12161254{
    12171255        struct winbind_cache *cache = get_cache(domain);
     
    12481286NTSTATUS wcache_get_creds(struct winbindd_domain *domain,
    12491287                          TALLOC_CTX *mem_ctx,
    1250                           const DOM_SID *sid,
     1288                          const struct dom_sid *sid,
    12511289                          const uint8 **cached_nt_pass,
    12521290                          const uint8 **cached_salt)
     
    13281366
    13291367NTSTATUS wcache_save_creds(struct winbindd_domain *domain,
    1330                            TALLOC_CTX *mem_ctx,
    1331                            const DOM_SID *sid,
     1368                           const struct dom_sid *sid,
    13321369                           const uint8 nt_pass[NT_HASH_LEN])
    13331370{
     
    15261563                                TALLOC_CTX *mem_ctx,
    15271564                                uint32 *num_entries,
    1528                                 struct acct_info **info)
     1565                                struct wb_acct_info **info)
    15291566{
    15301567        struct winbind_cache *cache = get_cache(domain);
     
    15481585                goto do_cached;
    15491586
    1550         (*info) = TALLOC_ARRAY(mem_ctx, struct acct_info, *num_entries);
     1587        (*info) = TALLOC_ARRAY(mem_ctx, struct wb_acct_info, *num_entries);
    15511588        if (! (*info)) {
    15521589                smb_panic_fn("enum_dom_groups out of memory");
     
    16211658                                TALLOC_CTX *mem_ctx,
    16221659                                uint32 *num_entries,
    1623                                 struct acct_info **info)
     1660                                struct wb_acct_info **info)
    16241661{
    16251662        struct winbind_cache *cache = get_cache(domain);
     
    16431680                goto do_cached;
    16441681
    1645         (*info) = TALLOC_ARRAY(mem_ctx, struct acct_info, *num_entries);
     1682        (*info) = TALLOC_ARRAY(mem_ctx, struct wb_acct_info, *num_entries);
    16461683        if (! (*info)) {
    16471684                smb_panic_fn("enum_dom_groups out of memory");
     
    17671804                            const char *name,
    17681805                            uint32_t flags,
    1769                             DOM_SID *sid,
     1806                            struct dom_sid *sid,
    17701807                            enum lsa_SidType *type)
    17711808{
     
    18761913static NTSTATUS sid_to_name(struct winbindd_domain *domain,
    18771914                            TALLOC_CTX *mem_ctx,
    1878                             const DOM_SID *sid,
     1915                            const struct dom_sid *sid,
    18791916                            char **domain_name,
    18801917                            char **name,
     
    19391976static NTSTATUS rids_to_names(struct winbindd_domain *domain,
    19401977                              TALLOC_CTX *mem_ctx,
    1941                               const DOM_SID *domain_sid,
     1978                              const struct dom_sid *domain_sid,
    19421979                              uint32 *rids,
    19431980                              size_t num_rids,
     
    19772014
    19782015        for (i=0; i<num_rids; i++) {
    1979                 DOM_SID sid;
     2016                struct dom_sid sid;
    19802017                struct cache_entry *centry;
    19812018                fstring tmp;
     
    20092046                        (*names)[i] = centry_string(centry, *names);
    20102047
    2011                 } else if (NT_STATUS_EQUAL(centry->status, NT_STATUS_NONE_MAPPED)) {
     2048                } else if (NT_STATUS_EQUAL(centry->status, NT_STATUS_NONE_MAPPED)
     2049                           || NT_STATUS_EQUAL(centry->status, STATUS_SOME_UNMAPPED)) {
    20122050                        have_unmapped = true;
    20132051
     
    20502088
    20512089                        for (i=0; i<num_rids; i++) {
    2052                                 DOM_SID sid;
     2090                                struct dom_sid sid;
    20532091                                struct cache_entry *centry;
    20542092                                fstring tmp;
     
    21102148        if (NT_STATUS_EQUAL(result, NT_STATUS_NONE_MAPPED)) {
    21112149                for (i = 0; i < num_rids; i++) {
    2112                         DOM_SID sid;
     2150                        struct dom_sid sid;
    21132151                        const char *name = "";
    21142152                        const enum lsa_SidType type = SID_NAME_UNKNOWN;
     
    21372175
    21382176        for (i=0; i<num_rids; i++) {
    2139                 DOM_SID sid;
     2177                struct dom_sid sid;
    21402178                NTSTATUS status;
    21412179
     
    22232261static NTSTATUS query_user(struct winbindd_domain *domain,
    22242262                           TALLOC_CTX *mem_ctx,
    2225                            const DOM_SID *user_sid,
     2263                           const struct dom_sid *user_sid,
    22262264                           struct wbint_userinfo *info)
    22272265{
     
    23322370static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
    23332371                                  TALLOC_CTX *mem_ctx,
    2334                                   const DOM_SID *user_sid,
    2335                                   uint32 *num_groups, DOM_SID **user_gids)
     2372                                  const struct dom_sid *user_sid,
     2373                                  uint32 *num_groups, struct dom_sid **user_gids)
    23362374{
    23372375        struct cache_entry *centry = NULL;
     
    24832521static NTSTATUS lookup_useraliases(struct winbindd_domain *domain,
    24842522                                   TALLOC_CTX *mem_ctx,
    2485                                    uint32 num_sids, const DOM_SID *sids,
     2523                                   uint32 num_sids, const struct dom_sid *sids,
    24862524                                   uint32 *num_aliases, uint32 **alias_rids)
    24872525{
     
    25872625        }
    25882626
    2589         *sid_mem = talloc_array(mem_ctx, DOM_SID, *num_names);
     2627        *sid_mem = talloc_array(mem_ctx, struct dom_sid, *num_names);
    25902628        *names = talloc_array(mem_ctx, char *, *num_names);
    25912629        *name_types = talloc_array(mem_ctx, uint32, *num_names);
     
    26162654static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
    26172655                                TALLOC_CTX *mem_ctx,
    2618                                 const DOM_SID *group_sid,
     2656                                const struct dom_sid *group_sid,
    26192657                                enum lsa_SidType type,
    26202658                                uint32 *num_names,
    2621                                 DOM_SID **sid_mem, char ***names,
     2659                                struct dom_sid **sid_mem, char ***names,
    26222660                                uint32 **name_types)
    26232661{
     
    29663004
    29673005void wcache_invalidate_samlogon(struct winbindd_domain *domain,
    2968                                 struct netr_SamInfo3 *info3)
    2969 {
    2970         DOM_SID sid;
     3006                                const struct dom_sid *sid)
     3007{
    29713008        fstring key_str, sid_string;
    29723009        struct winbind_cache *cache;
     
    29883025        }
    29893026
    2990         sid_copy(&sid, info3->base.domain_sid);
    2991         sid_append_rid(&sid, info3->base.rid);
    2992 
    29933027        /* Clear U/SID cache entry */
    2994         fstr_sprintf(key_str, "U/%s", sid_to_fstring(sid_string, &sid));
     3028        fstr_sprintf(key_str, "U/%s", sid_to_fstring(sid_string, sid));
    29953029        DEBUG(10, ("wcache_invalidate_samlogon: clearing %s\n", key_str));
    29963030        tdb_delete(cache->tdb, string_tdb_data(key_str));
    29973031
    29983032        /* Clear UG/SID cache entry */
    2999         fstr_sprintf(key_str, "UG/%s", sid_to_fstring(sid_string, &sid));
     3033        fstr_sprintf(key_str, "UG/%s", sid_to_fstring(sid_string, sid));
    30003034        DEBUG(10, ("wcache_invalidate_samlogon: clearing %s\n", key_str));
    30013035        tdb_delete(cache->tdb, string_tdb_data(key_str));
    30023036
    30033037        /* Samba/winbindd never needs this. */
    3004         netsamlogon_clear_cached_user(info3);
     3038        netsamlogon_clear_cached_user(sid);
    30053039}
    30063040
     
    30253059}
    30263060
     3061bool wcache_invalidate_cache_noinit(void)
     3062{
     3063        struct winbindd_domain *domain;
     3064
     3065        for (domain = domain_list(); domain; domain = domain->next) {
     3066                struct winbind_cache *cache;
     3067
     3068                /* Skip uninitialized domains. */
     3069                if (!domain->initialized && !domain->internal) {
     3070                        continue;
     3071                }
     3072
     3073                cache = get_cache(domain);
     3074
     3075                DEBUG(10, ("wcache_invalidate_cache: invalidating cache "
     3076                           "entries for %s\n", domain->name));
     3077                if (cache) {
     3078                        if (cache->tdb) {
     3079                                tdb_traverse(cache->tdb, traverse_fn, NULL);
     3080                                /*
     3081                                 * Flushing cache has nothing to with domains.
     3082                                 * return here if we successfully flushed once.
     3083                                 * To avoid unnecessary traversing the cache.
     3084                                 */
     3085                                return true;
     3086                        } else {
     3087                                return false;
     3088                        }
     3089                }
     3090        }
     3091        return true;
     3092}
     3093
    30273094bool init_wcache(void)
    30283095{
     
    30383105        wcache->tdb = tdb_open_log(cache_path("winbindd_cache.tdb"),
    30393106                                WINBINDD_CACHE_TDB_DEFAULT_HASH_SIZE,
    3040                                 lp_winbind_offline_logon() ? TDB_DEFAULT : (TDB_DEFAULT | TDB_CLEAR_IF_FIRST),
     3107                                TDB_INCOMPATIBLE_HASH |
     3108                                        (lp_winbind_offline_logon() ? TDB_DEFAULT : (TDB_DEFAULT | TDB_CLEAR_IF_FIRST)),
    30413109                                O_RDWR|O_CREAT, 0600);
    30423110
     
    31153183}
    31163184
    3117 bool lookup_cached_sid(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
     3185bool lookup_cached_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid,
    31183186                       char **domain_name, char **name,
    31193187                       enum lsa_SidType *type)
     
    31313199}
    31323200
    3133 bool lookup_cached_name(TALLOC_CTX *mem_ctx,
    3134                         const char *domain_name,
     3201bool lookup_cached_name(const char *domain_name,
    31353202                        const char *name,
    3136                         DOM_SID *sid,
     3203                        struct dom_sid *sid,
    31373204                        enum lsa_SidType *type)
    31383205{
     
    31593226void cache_name2sid(struct winbindd_domain *domain,
    31603227                    const char *domain_name, const char *name,
    3161                     enum lsa_SidType type, const DOM_SID *sid)
     3228                    enum lsa_SidType type, const struct dom_sid *sid)
    31623229{
    31633230        refresh_sequence_number(domain, false);
     
    32113278        wcache->tdb = tdb_open_log(cache_path("winbindd_cache.tdb"),
    32123279                                WINBINDD_CACHE_TDB_DEFAULT_HASH_SIZE,
    3213                                 lp_winbind_offline_logon() ? TDB_DEFAULT : (TDB_DEFAULT | TDB_CLEAR_IF_FIRST),
     3280                                TDB_INCOMPATIBLE_HASH |
     3281                                (lp_winbind_offline_logon() ? TDB_DEFAULT : (TDB_DEFAULT | TDB_CLEAR_IF_FIRST)),
    32143282                                O_RDWR|O_CREAT, 0600);
    32153283
     
    32843352}
    32853353
    3286 NTSTATUS wcache_remove_oldest_cached_creds(struct winbindd_domain *domain, const DOM_SID *sid)
     3354NTSTATUS wcache_remove_oldest_cached_creds(struct winbindd_domain *domain, const struct dom_sid *sid)
    32873355{
    32883356        struct winbind_cache *cache = get_cache(domain);
     
    34493517        centry->ofs = 0;
    34503518
    3451         if (centry->len < 8) {
     3519        if (centry->len < 16) {
    34523520                /* huh? corrupt cache? */
    3453                 DEBUG(0,("create_centry_validate: Corrupt cache for key %s (len < 8) ?\n", kstr));
     3521                DEBUG(0,("create_centry_validate: Corrupt cache for key %s "
     3522                         "(len < 16) ?\n", kstr));
    34543523                centry_free(centry);
    34553524                state->bad_entry = true;
     
    34603529        centry->status = NT_STATUS(centry_uint32(centry));
    34613530        centry->sequence_number = centry_uint32(centry);
     3531        centry->timeout = centry_uint64_t(centry);
    34623532        return centry;
    34633533}
     
    34853555        (void)centry_uint32(centry);
    34863556        if (NT_STATUS_IS_OK(centry->status)) {
    3487                 DOM_SID sid;
     3557                struct dom_sid sid;
    34883558                (void)centry_sid(centry, &sid);
    34893559        }
     
    35253595{
    35263596        struct cache_entry *centry = create_centry_validate(keystr, dbuf, state);
    3527         DOM_SID sid;
     3597        struct dom_sid sid;
    35283598
    35293599        if (!centry) {
     
    36333703
    36343704        for (i=0; i< num_entries; i++) {
    3635                 DOM_SID sid;
     3705                struct dom_sid sid;
    36363706                (void)centry_string(centry, mem_ctx);
    36373707                (void)centry_string(centry, mem_ctx);
     
    36913761
    36923762        for (i=0; i< num_groups; i++) {
    3693                 DOM_SID sid;
     3763                struct dom_sid sid;
    36943764                centry_sid(centry, &sid);
    36953765        }
     
    37423812
    37433813        for (i=0; i< num_names; i++) {
    3744                 DOM_SID sid;
     3814                struct dom_sid sid;
    37453815                centry_sid(centry, &sid);
    37463816                (void)centry_string(centry, mem_ctx);
     
    40294099        tdb = tdb_open_log(tdb_path,
    40304100                           WINBINDD_CACHE_TDB_DEFAULT_HASH_SIZE,
     4101                           TDB_INCOMPATIBLE_HASH |
    40314102                           ( lp_winbind_offline_logon()
    40324103                             ? TDB_DEFAULT
     
    44734544}
    44744545
    4475 
    44764546/*********************************************************************
    44774547 ********************************************************************/
    44784548
     4549struct winbindd_tdc_domain*
     4550        wcache_tdc_fetch_domainbysid(TALLOC_CTX *ctx,
     4551                                     const struct dom_sid *sid)
     4552{
     4553        struct winbindd_tdc_domain *dom_list = NULL;
     4554        size_t num_domains = 0;
     4555        int i;
     4556        struct winbindd_tdc_domain *d = NULL;
     4557
     4558        DEBUG(10,("wcache_tdc_fetch_domainbysid: Searching for domain %s\n",
     4559                  sid_string_dbg(sid)));
     4560
     4561        if (!init_wcache()) {
     4562                return false;
     4563        }
     4564
     4565        /* fetch the list */
     4566
     4567        wcache_tdc_fetch_list(&dom_list, &num_domains);
     4568
     4569        for (i = 0; i<num_domains; i++) {
     4570                if (sid_equal(sid, &(dom_list[i].sid))) {
     4571                        DEBUG(10, ("wcache_tdc_fetch_domainbysid: "
     4572                                   "Found domain %s for SID %s\n",
     4573                                   dom_list[i].domain_name,
     4574                                   sid_string_dbg(sid)));
     4575
     4576                        d = TALLOC_P(ctx, struct winbindd_tdc_domain);
     4577                        if (!d)
     4578                                break;
     4579
     4580                        d->domain_name = talloc_strdup(d,
     4581                                                       dom_list[i].domain_name);
     4582
     4583                        d->dns_name = talloc_strdup(d, dom_list[i].dns_name);
     4584                        sid_copy(&d->sid, &dom_list[i].sid);
     4585                        d->trust_flags = dom_list[i].trust_flags;
     4586                        d->trust_type = dom_list[i].trust_type;
     4587                        d->trust_attribs = dom_list[i].trust_attribs;
     4588
     4589                        break;
     4590                }
     4591        }
     4592
     4593        TALLOC_FREE(dom_list);
     4594
     4595        return d;
     4596}
     4597
     4598
     4599/*********************************************************************
     4600 ********************************************************************/
     4601
    44794602void wcache_tdc_clear( void )
    44804603{
     
    44934616static void wcache_save_user_pwinfo(struct winbindd_domain *domain,
    44944617                                    NTSTATUS status,
    4495                                     const DOM_SID *user_sid,
     4618                                    const struct dom_sid *user_sid,
    44964619                                    const char *homedir,
    44974620                                    const char *shell,
     
    45174640}
    45184641
     4642#ifdef HAVE_ADS
     4643
    45194644NTSTATUS nss_get_info_cached( struct winbindd_domain *domain,
    4520                               const DOM_SID *user_sid,
     4645                              const struct dom_sid *user_sid,
    45214646                              TALLOC_CTX *ctx,
    4522                               ADS_STRUCT *ads, LDAPMessage *msg,
    45234647                              const char **homedir, const char **shell,
    45244648                              const char **gecos, gid_t *p_gid)
     
    45524676do_query:
    45534677
    4554         nt_status = nss_get_info( domain->name, user_sid, ctx, ads, msg,
     4678        nt_status = nss_get_info( domain->name, user_sid, ctx,
    45554679                                  homedir, shell, gecos, p_gid );
    45564680
     
    45764700}
    45774701
     4702#endif
    45784703
    45794704/* the cache backend methods are exposed via this structure */
     
    46414766        bool ret = false;
    46424767
    4643         if (!wcache_opnum_cacheable(opnum)) {
     4768        if (!wcache_opnum_cacheable(opnum) ||
     4769            is_my_own_sam_domain(domain) ||
     4770            is_builtin_domain(domain)) {
    46444771                return false;
    46454772        }
     
    46584785                return false;
    46594786        }
    4660         if (data.dsize < 4) {
     4787        if (data.dsize < 12) {
    46614788                goto fail;
    46624789        }
     
    46644791        if (!is_domain_offline(domain)) {
    46654792                uint32_t entry_seqnum, dom_seqnum, last_check;
     4793                uint64_t entry_timeout;
    46664794
    46674795                if (!wcache_fetch_seqnum(domain->name, &dom_seqnum,
     
    46754803                        goto fail;
    46764804                }
    4677         }
    4678 
    4679         resp->data = (uint8_t *)talloc_memdup(mem_ctx, data.dptr + 4,
    4680                                               data.dsize - 4);
     4805                entry_timeout = BVAL(data.dptr, 4);
     4806                if (entry_timeout > time(NULL)) {
     4807                        DEBUG(10, ("Entry has timed out\n"));
     4808                        goto fail;
     4809                }
     4810        }
     4811
     4812        resp->data = (uint8_t *)talloc_memdup(mem_ctx, data.dptr + 12,
     4813                                              data.dsize - 12);
    46814814        if (resp->data == NULL) {
    46824815                DEBUG(10, ("talloc failed\n"));
    46834816                goto fail;
    46844817        }
    4685         resp->length = data.dsize - 4;
     4818        resp->length = data.dsize - 12;
    46864819
    46874820        ret = true;
     
    46964829        TDB_DATA key, data;
    46974830        uint32_t dom_seqnum, last_check;
    4698 
    4699         if (!wcache_opnum_cacheable(opnum)) {
     4831        uint64_t timeout;
     4832
     4833        if (!wcache_opnum_cacheable(opnum) ||
     4834            is_my_own_sam_domain(domain) ||
     4835            is_builtin_domain(domain)) {
    47004836                return;
    47014837        }
     
    47154851        }
    47164852
    4717         data.dsize = resp->length + 4;
     4853        timeout = time(NULL) + lp_winbind_cache_time();
     4854
     4855        data.dsize = resp->length + 12;
    47184856        data.dptr = talloc_array(key.dptr, uint8_t, data.dsize);
    47194857        if (data.dptr == NULL) {
     
    47224860
    47234861        SIVAL(data.dptr, 0, dom_seqnum);
    4724         memcpy(data.dptr+4, resp->data, resp->length);
     4862        SBVAL(data.dptr, 4, timeout);
     4863        memcpy(data.dptr + 12, resp->data, resp->length);
    47254864
    47264865        tdb_store(wcache->tdb, key, data, 0);
  • vendor/current/source3/winbindd/winbindd_ccache_access.c

    r414 r740  
    2424#include "includes.h"
    2525#include "winbindd.h"
     26#include "../libcli/auth/ntlmssp.h"
    2627
    2728#undef DBGC_CLASS
     
    5152{
    5253        NTSTATUS status;
    53         NTLMSSP_STATE *ntlmssp_state = NULL;
     54        struct ntlmssp_state *ntlmssp_state = NULL;
    5455        DATA_BLOB dummy_msg, reply;
    5556
    56         status = ntlmssp_client_start(&ntlmssp_state);
     57        status = ntlmssp_client_start(NULL,
     58                                      global_myname(),
     59                                      lp_workgroup(),
     60                                      lp_client_ntlmv2_auth(),
     61                                      &ntlmssp_state);
    5762
    5863        if (!NT_STATUS_IS_OK(status)) {
     
    132137
    133138done:
    134         ntlmssp_end(&ntlmssp_state);
     139        TALLOC_FREE(ntlmssp_state);
    135140        return status;
    136141}
     
    164169        struct winbindd_domain *domain;
    165170        fstring name_domain, name_user;
     171        NTSTATUS result = NT_STATUS_NOT_SUPPORTED;
     172        struct WINBINDD_MEMORY_CREDS *entry;
     173        DATA_BLOB initial, challenge, auth;
     174        uint32 initial_blob_len, challenge_blob_len, extra_len;
    166175
    167176        /* Ensure null termination */
     
    195204                return;
    196205        }
    197 
    198         sendto_domain(state, domain);
    199 }
    200 
    201 enum winbindd_result winbindd_dual_ccache_ntlm_auth(struct winbindd_domain *domain,
    202                                                 struct winbindd_cli_state *state)
    203 {
    204         NTSTATUS result = NT_STATUS_NOT_SUPPORTED;
    205         struct WINBINDD_MEMORY_CREDS *entry;
    206         DATA_BLOB initial, challenge, auth;
    207         fstring name_domain, name_user;
    208         uint32 initial_blob_len, challenge_blob_len, extra_len;
    209 
    210         /* Ensure null termination */
    211         state->request->data.ccache_ntlm_auth.user[
    212                 sizeof(state->request->data.ccache_ntlm_auth.user)-1]='\0';
    213 
    214         DEBUG(3, ("winbindd_dual_ccache_ntlm_auth: [%5lu]: perform NTLM auth on "
    215                 "behalf of user %s (dual)\n", (unsigned long)state->pid,
    216                 state->request->data.ccache_ntlm_auth.user));
    217206
    218207        /* validate blob lengths */
     
    263252        }
    264253
    265         initial = data_blob(state->request->extra_data.data, initial_blob_len);
    266         challenge = data_blob(state->request->extra_data.data + initial_blob_len,
    267                                 state->request->data.ccache_ntlm_auth.challenge_blob_len);
    268 
    269         if (!initial.data || !challenge.data) {
    270                 result = NT_STATUS_NO_MEMORY;
    271         } else {
    272                 result = do_ntlm_auth_with_hashes(
    273                         name_user, name_domain, entry->lm_hash, entry->nt_hash,
    274                         initial, challenge, &auth,
    275                         state->response->data.ccache_ntlm_auth.session_key);
    276         }
    277 
    278         data_blob_free(&initial);
    279         data_blob_free(&challenge);
     254        initial = data_blob_const(state->request->extra_data.data,
     255                                  initial_blob_len);
     256        challenge = data_blob_const(
     257                state->request->extra_data.data + initial_blob_len,
     258                state->request->data.ccache_ntlm_auth.challenge_blob_len);
     259
     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);
    280264
    281265        if (!NT_STATUS_IS_OK(result)) {
     
    295279
    296280  process_result:
    297         return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
     281        if (!NT_STATUS_IS_OK(result)) {
     282                request_error(state);
     283                return;
     284        }
     285        request_ok(state);
    298286}
    299287
     
    302290        struct winbindd_domain *domain;
    303291        fstring name_domain, name_user;
     292        NTSTATUS status;
    304293
    305294        /* Ensure null termination */
     
    315304        /* Parse domain and username */
    316305
    317         if (!canonicalize_username(state->request->data.ccache_ntlm_auth.user,
     306        if (!canonicalize_username(state->request->data.ccache_save.user,
    318307                                   name_domain, name_user)) {
    319308                DEBUG(5,("winbindd_ccache_save: cannot parse domain and user "
     
    324313        }
    325314
     315        /*
     316         * The domain is checked here only for compatibility
     317         * reasons. We used to do the winbindd memory ccache for
     318         * ntlm_auth in the domain child. With that code, we had to
     319         * make sure that we do have a domain around to send this
     320         * to. Now we do the memory cache in the parent winbindd,
     321         * where it would not matter if we have a domain or not.
     322         */
     323
    326324        domain = find_auth_domain(state->request->flags, name_domain);
    327 
    328325        if (domain == NULL) {
    329326                DEBUG(5, ("winbindd_ccache_save: can't get domain [%s]\n",
     
    337334                return;
    338335        }
    339 
    340         sendto_domain(state, domain);
    341 }
    342 
    343 enum winbindd_result winbindd_dual_ccache_save(
    344         struct winbindd_domain *domain, struct winbindd_cli_state *state)
    345 {
    346         NTSTATUS status = NT_STATUS_NOT_SUPPORTED;
    347 
    348         /* Ensure null termination */
    349         state->request->data.ccache_save.user[
    350                 sizeof(state->request->data.ccache_save.user)-1]='\0';
    351         state->request->data.ccache_save.pass[
    352                 sizeof(state->request->data.ccache_save.pass)-1]='\0';
    353 
    354         DEBUG(3, ("winbindd_dual_ccache_save: [%5lu]: save password of user "
    355                   "%s\n", (unsigned long)state->pid,
    356                   state->request->data.ccache_save.user));
    357336
    358337        status = winbindd_add_memory_creds(
     
    364343                DEBUG(1, ("winbindd_add_memory_creds failed %s\n",
    365344                          nt_errstr(status)));
    366                 return WINBINDD_ERROR;
    367         }
    368 
    369         return WINBINDD_OK;
    370 }
     345                request_error(state);
     346                return;
     347        }
     348        request_ok(state);
     349}
  • vendor/current/source3/winbindd/winbindd_change_machine_acct.c

    r414 r740  
    2121#include "includes.h"
    2222#include "winbindd.h"
    23 #include "librpc/gen_ndr/cli_wbint.h"
     23#include "librpc/gen_ndr/ndr_wbint_c.h"
    2424
    2525struct winbindd_change_machine_acct_state {
     
    5858        }
    5959
    60         subreq = rpccli_wbint_ChangeMachineAccount_send(state, ev,
    61                                                         domain->child.rpccli);
     60        subreq = dcerpc_wbint_ChangeMachineAccount_send(state, ev,
     61                                                        dom_child_handle(domain));
    6262        if (tevent_req_nomem(subreq, req)) {
    6363                return tevent_req_post(req, ev);
     
    7575        NTSTATUS status, result;
    7676
    77         status = rpccli_wbint_ChangeMachineAccount_recv(subreq, state, &result);
    78         if (!NT_STATUS_IS_OK(status)) {
     77        status = dcerpc_wbint_ChangeMachineAccount_recv(subreq, state, &result);
     78        if (any_nt_status_not_ok(status, result, &status)) {
    7979                tevent_req_nterror(req, status);
    80                 return;
    81         }
    82         if (!NT_STATUS_IS_OK(result)) {
    83                 tevent_req_nterror(req, result);
    8480                return;
    8581        }
  • vendor/current/source3/winbindd/winbindd_check_machine_acct.c

    r414 r740  
    2020#include "includes.h"
    2121#include "winbindd.h"
    22 #include "librpc/gen_ndr/cli_wbint.h"
     22#include "librpc/gen_ndr/ndr_wbint_c.h"
    2323
    2424struct winbindd_check_machine_acct_state {
     
    6262        }
    6363
    64         subreq = rpccli_wbint_CheckMachineAccount_send(state, ev,
    65                                                        domain->child.rpccli);
     64        subreq = dcerpc_wbint_CheckMachineAccount_send(state, ev,
     65                                                       dom_child_handle(domain));
    6666        if (tevent_req_nomem(subreq, req)) {
    6767                return tevent_req_post(req, ev);
     
    7979        NTSTATUS status, result;
    8080
    81         status = rpccli_wbint_CheckMachineAccount_recv(subreq, state, &result);
    82         if (!NT_STATUS_IS_OK(status)) {
     81        status = dcerpc_wbint_CheckMachineAccount_recv(subreq, state, &result);
     82        if (any_nt_status_not_ok(status, result, &status)) {
    8383                tevent_req_nterror(req, status);
    84                 return;
    85         }
    86         if (!NT_STATUS_IS_OK(result)) {
    87                 tevent_req_nterror(req, result);
    8884                return;
    8985        }
     
    9490                                          struct winbindd_response *presp)
    9591{
    96         return tevent_req_simple_recv_ntstatus(req);
     92        NTSTATUS status = tevent_req_simple_recv_ntstatus(req);
     93
     94        set_auth_errors(presp, status);
     95        return status;
    9796}
  • vendor/current/source3/winbindd/winbindd_cm.c

    r594 r740  
    6262#include "winbindd.h"
    6363#include "../libcli/auth/libcli_auth.h"
    64 #include "../librpc/gen_ndr/cli_netlogon.h"
    65 #include "../librpc/gen_ndr/cli_samr.h"
    66 #include "../librpc/gen_ndr/cli_lsa.h"
    67 #include "../librpc/gen_ndr/cli_dssetup.h"
     64#include "../librpc/gen_ndr/ndr_netlogon_c.h"
     65#include "rpc_client/cli_pipe.h"
     66#include "rpc_client/cli_netlogon.h"
     67#include "../librpc/gen_ndr/ndr_samr_c.h"
     68#include "../librpc/gen_ndr/ndr_lsa_c.h"
     69#include "rpc_client/cli_lsarpc.h"
     70#include "../librpc/gen_ndr/ndr_dssetup_c.h"
     71#include "libads/sitename_cache.h"
     72#include "libsmb/libsmb.h"
     73#include "libsmb/clidgram.h"
     74#include "ads.h"
     75#include "secrets.h"
     76#include "../libcli/security/security.h"
     77#include "passdb.h"
     78#include "messages.h"
    6879
    6980#undef DBGC_CLASS
     
    179190        pid_t parent_pid = sys_getpid();
    180191        char *lfile = NULL;
     192        NTSTATUS status;
    181193
    182194        if (domain->dc_probe_pid != (pid_t)-1) {
     
    223235        }
    224236
    225         if (!winbindd_reinit_after_fork(lfile)) {
     237        status = winbindd_reinit_after_fork(NULL, lfile);
     238        if (!NT_STATUS_IS_OK(status)) {
     239                DEBUG(1, ("winbindd_reinit_after_fork failed: %s\n",
     240                          nt_errstr(status)));
    226241                messaging_send_buf(winbind_messaging_context(),
    227242                                   pid_to_procid(parent_pid),
     
    285300        /* Are we still in "startup" mode ? */
    286301
    287         if (domain->startup && (now.tv_sec > domain->startup_time + 30)) {
     302        if (domain->startup && (time_mono(NULL) > domain->startup_time + 30)) {
    288303                /* No longer in "startup" mode. */
    289304                DEBUG(10,("check_domain_online_handler: domain %s no longer in 'startup' mode.\n",
     
    502517
    503518        /* Go into "startup" mode again. */
    504         domain->startup_time = tev.tv_sec;
     519        domain->startup_time = time_mono(NULL);
    505520        domain->startup = True;
    506521
     
    535550****************************************************************/
    536551
    537 void winbind_add_failed_connection_entry(const struct winbindd_domain *domain,
    538                                         const char *server,
    539                                         NTSTATUS result)
     552static void winbind_add_failed_connection_entry(
     553        const struct winbindd_domain *domain,
     554        const char *server,
     555        NTSTATUS result)
    540556{
    541557        add_failed_connection_entry(domain->name, server, result);
     
    595611        const char *tmp = NULL;
    596612        const char *p;
     613        struct dcerpc_binding_handle *b;
    597614
    598615        /* Hmmmm. We can only open one connection to the NETLOGON pipe at the
     
    619636        }
    620637
     638        b = netlogon_pipe->binding_handle;
     639
    621640        /* This call can take a long time - allow the server to time out.
    622641           35 seconds should do it. */
     
    627646                struct netr_DsRGetDCNameInfo *domain_info = NULL;
    628647
    629                 result = rpccli_netr_DsRGetDCName(netlogon_pipe,
     648                result = dcerpc_netr_DsRGetDCName(b,
    630649                                                  mem_ctx,
    631650                                                  our_domain->dcname,
     
    654673                }
    655674        } else {
    656                 result = rpccli_netr_GetAnyDCName(netlogon_pipe, mem_ctx,
     675                result = dcerpc_netr_GetAnyDCName(b, mem_ctx,
    657676                                                  our_domain->dcname,
    658677                                                  domain->name,
     
    665684
    666685        if (!NT_STATUS_IS_OK(result)) {
    667                 DEBUG(10,("rpccli_netr_GetAnyDCName failed: %s\n",
     686                DEBUG(10,("dcerpc_netr_GetAnyDCName failed: %s\n",
    668687                        nt_errstr(result)));
    669688                talloc_destroy(mem_ctx);
     
    672691
    673692        if (!W_ERROR_IS_OK(werr)) {
    674                 DEBUG(10,("rpccli_netr_GetAnyDCName failed: %s\n",
     693                DEBUG(10,("dcerpc_netr_GetAnyDCName failed: %s\n",
    675694                           win_errstr(werr)));
    676695                talloc_destroy(mem_ctx);
     
    678697        }
    679698
    680         /* rpccli_netr_GetAnyDCName gives us a name with \\ */
     699        /* dcerpc_netr_GetAnyDCName gives us a name with \\ */
    681700        p = strip_hostname(tmp);
    682701
     
    685704        talloc_destroy(mem_ctx);
    686705
    687         DEBUG(10,("rpccli_netr_GetAnyDCName returned %s\n", dcname));
     706        DEBUG(10,("dcerpc_netr_GetAnyDCName returned %s\n", dcname));
    688707
    689708        if (!resolve_name(dcname, dc_ss, 0x20, true)) {
     
    802821        (*cli)->timeout = 10000;        /* 10 seconds */
    803822        (*cli)->fd = sockfd;
    804         fstrcpy((*cli)->desthost, controller);
     823        (*cli)->desthost = talloc_strdup((*cli), controller);
     824        if ((*cli)->desthost == NULL) {
     825                result = NT_STATUS_NO_MEMORY;
     826                goto done;
     827        }
     828
    805829        (*cli)->use_kerberos = True;
    806830
     
    10991123        struct ip_service ip_list;
    11001124        uint32_t nt_version = NETLOGON_NT_VERSION_1;
     1125        NTSTATUS status;
     1126        const char *dc_name;
    11011127
    11021128        ip_list.ss = *pss;
    11031129        ip_list.port = 0;
    11041130
    1105 #ifdef WITH_ADS
     1131#ifdef HAVE_ADS
    11061132        /* For active directory servers, try to get the ldap server name.
    11071133           None of these failures should be considered critical for now */
     
    11631189#endif
    11641190
    1165         /* try GETDC requests next */
    1166 
    1167         if (send_getdc_request(mem_ctx, winbind_messaging_context(),
    1168                                pss, domain->name, &domain->sid,
    1169                                nt_version)) {
    1170                 const char *dc_name = NULL;
    1171                 int i;
    1172                 smb_msleep(100);
    1173                 for (i=0; i<5; i++) {
    1174                         if (receive_getdc_response(mem_ctx, pss, domain->name,
    1175                                                    &nt_version,
    1176                                                    &dc_name, NULL)) {
    1177                                 fstrcpy(name, dc_name);
    1178                                 namecache_store(name, 0x20, 1, &ip_list);
    1179                                 return True;
    1180                         }
    1181                         smb_msleep(500);
    1182                 }
     1191        status = nbt_getdc(winbind_messaging_context(), pss, domain->name,
     1192                           &domain->sid, nt_version, mem_ctx, &nt_version,
     1193                           &dc_name, NULL);
     1194        if (NT_STATUS_IS_OK(status)) {
     1195                fstrcpy(name, dc_name);
     1196                namecache_store(name, 0x20, 1, &ip_list);
     1197                return True;
    11831198        }
    11841199
     
    13691384                return False;
    13701385
    1371         status = smbsock_any_connect(addrs, dcnames, num_addrs,
    1372                                      fd, &fd_index, NULL);
     1386        status = smbsock_any_connect(addrs, dcnames, NULL, NULL, NULL,
     1387                                     num_addrs, 0, 10, fd, &fd_index, NULL);
    13731388        if (!NT_STATUS_IS_OK(status)) {
    13741389                for (i=0; i<num_dcs; i++) {
     
    14171432}
    14181433
     1434static char *current_dc_key(TALLOC_CTX *mem_ctx, const char *domain_name)
     1435{
     1436        return talloc_asprintf_strupper_m(mem_ctx, "CURRENT_DCNAME/%s",
     1437                                          domain_name);
     1438}
     1439
     1440static void store_current_dc_in_gencache(const char *domain_name,
     1441                                         const char *dc_name,
     1442                                         struct cli_state *cli)
     1443{
     1444        char addr[INET6_ADDRSTRLEN];
     1445        char *key = NULL;
     1446        char *value = NULL;
     1447
     1448        if (cli == NULL) {
     1449                return;
     1450        }
     1451        if (cli->fd == -1) {
     1452                return;
     1453        }
     1454        get_peer_addr(cli->fd, addr, sizeof(addr));
     1455
     1456        key = current_dc_key(talloc_tos(), domain_name);
     1457        if (key == NULL) {
     1458                goto done;
     1459        }
     1460
     1461        value = talloc_asprintf(talloc_tos(), "%s %s", addr, dc_name);
     1462        if (value == NULL) {
     1463                goto done;
     1464        }
     1465
     1466        gencache_set(key, value, 0x7fffffff);
     1467done:
     1468        TALLOC_FREE(value);
     1469        TALLOC_FREE(key);
     1470}
     1471
     1472bool fetch_current_dc_from_gencache(TALLOC_CTX *mem_ctx,
     1473                                    const char *domain_name,
     1474                                    char **p_dc_name, char **p_dc_ip)
     1475{
     1476        char *key, *value, *p;
     1477        bool ret = false;
     1478        char *dc_name = NULL;
     1479        char *dc_ip = NULL;
     1480
     1481        key = current_dc_key(talloc_tos(), domain_name);
     1482        if (key == NULL) {
     1483                goto done;
     1484        }
     1485        if (!gencache_get(key, &value, NULL)) {
     1486                goto done;
     1487        }
     1488        p = strchr(value, ' ');
     1489        if (p == NULL) {
     1490                goto done;
     1491        }
     1492        dc_ip = talloc_strndup(mem_ctx, value, p - value);
     1493        if (dc_ip == NULL) {
     1494                goto done;
     1495        }
     1496        dc_name = talloc_strdup(mem_ctx, p+1);
     1497        if (dc_name == NULL) {
     1498                goto done;
     1499        }
     1500
     1501        if (p_dc_ip != NULL) {
     1502                *p_dc_ip = dc_ip;
     1503                dc_ip = NULL;
     1504        }
     1505        if (p_dc_name != NULL) {
     1506                *p_dc_name = dc_name;
     1507                dc_name = NULL;
     1508        }
     1509        ret = true;
     1510done:
     1511        TALLOC_FREE(dc_name);
     1512        TALLOC_FREE(dc_ip);
     1513        TALLOC_FREE(key);
     1514        return ret;
     1515}
     1516
    14191517static NTSTATUS cm_open_connection(struct winbindd_domain *domain,
    14201518                                   struct winbindd_cm_conn *new_conn)
     
    14321530
    14331531        /* we have to check the server affinity cache here since
    1434            later we selecte a DC based on response time and not preference */
     1532           later we select a DC based on response time and not preference */
    14351533
    14361534        /* Check the negative connection cache
     
    14811579                        NTSTATUS status;
    14821580
    1483                         status = smbsock_connect(&domain->dcaddr, NULL, NULL,
    1484                                                  &fd, NULL);
     1581                        status = smbsock_connect(&domain->dcaddr, 0,
     1582                                                 NULL, -1, NULL, -1,
     1583                                                 &fd, NULL, 10);
    14851584                        if (!NT_STATUS_IS_OK(status)) {
    14861585                                fd = -1;
     
    15171616                }
    15181617                set_domain_online(domain);
     1618
     1619                /*
     1620                 * Much as I hate global state, this seems to be the point
     1621                 * where we can be certain that we have a proper connection to
     1622                 * a DC. wbinfo --dc-info needs that information, store it in
     1623                 * gencache with a looong timeout. This will need revisiting
     1624                 * once we start to connect to multiple DCs, wbcDcInfo is
     1625                 * already prepared for that.
     1626                 */
     1627                store_current_dc_in_gencache(domain->name, domain->dcname,
     1628                                             new_conn->cli);
    15191629        } else {
    15201630                /* Ensure we setup the retry handler. */
     
    15301640void invalidate_cm_connection(struct winbindd_cm_conn *conn)
    15311641{
     1642        NTSTATUS result;
     1643
    15321644        /* We're closing down a possibly dead
    15331645           connection. Don't have impossibly long (10s) timeouts. */
     
    15381650
    15391651        if (conn->samr_pipe != NULL) {
     1652                if (is_valid_policy_hnd(&conn->sam_connect_handle)) {
     1653                        dcerpc_samr_Close(conn->samr_pipe->binding_handle,
     1654                                          talloc_tos(),
     1655                                          &conn->sam_connect_handle,
     1656                                          &result);
     1657                }
    15401658                TALLOC_FREE(conn->samr_pipe);
    15411659                /* Ok, it must be dead. Drop timeout to 0.5 sec. */
     
    15461664
    15471665        if (conn->lsa_pipe != NULL) {
     1666                if (is_valid_policy_hnd(&conn->lsa_policy)) {
     1667                        dcerpc_lsa_Close(conn->lsa_pipe->binding_handle,
     1668                                         talloc_tos(),
     1669                                         &conn->lsa_policy,
     1670                                         &result);
     1671                }
    15481672                TALLOC_FREE(conn->lsa_pipe);
    15491673                /* Ok, it must be dead. Drop timeout to 0.5 sec. */
     
    15541678
    15551679        if (conn->lsa_pipe_tcp != NULL) {
     1680                if (is_valid_policy_hnd(&conn->lsa_policy)) {
     1681                        dcerpc_lsa_Close(conn->lsa_pipe_tcp->binding_handle,
     1682                                         talloc_tos(),
     1683                                         &conn->lsa_policy,
     1684                                         &result);
     1685                }
    15561686                TALLOC_FREE(conn->lsa_pipe_tcp);
    15571687                /* Ok, it must be dead. Drop timeout to 0.5 sec. */
     
    15791709{
    15801710        struct winbindd_domain *domain;
     1711        struct winbindd_cli_state *cli_state;
    15811712
    15821713        for (domain = domain_list(); domain; domain = domain->next) {
    1583                 if (domain->conn.cli == NULL)
    1584                         continue;
    1585 
    1586                 if (domain->conn.cli->fd == -1)
    1587                         continue;
    1588 
    1589                 close(domain->conn.cli->fd);
    1590                 domain->conn.cli->fd = -1;
     1714                struct cli_state *cli = domain->conn.cli;
     1715
     1716                /*
     1717                 * first close the low level SMB TCP connection
     1718                 * so that we don't generate any SMBclose
     1719                 * requests in invalidate_cm_connection()
     1720                 */
     1721                if (cli && cli->fd != -1) {
     1722                        close(domain->conn.cli->fd);
     1723                        domain->conn.cli->fd = -1;
     1724                }
     1725
     1726                invalidate_cm_connection(&domain->conn);
     1727        }
     1728
     1729        for (cli_state = winbindd_client_list();
     1730             cli_state != NULL;
     1731             cli_state = cli_state->next) {
     1732                if (cli_state->sock >= 0) {
     1733                        close(cli_state->sock);
     1734                        cli_state->sock = -1;
     1735                }
    15911736        }
    15921737}
     
    16501795NTSTATUS init_dc_connection(struct winbindd_domain *domain)
    16511796{
     1797        if (domain->internal) {
     1798                return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
     1799        }
     1800
    16521801        if (domain->initialized && !domain->online) {
    16531802                /* We check for online status elsewhere. */
     
    16831832        struct winbindd_domain *our_domain;
    16841833        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
     1834        WERROR werr;
    16851835        struct netr_DomainTrustList trusts;
    16861836        int i;
     
    16901840        struct rpc_pipe_client *cli;
    16911841        TALLOC_CTX *mem_ctx = NULL;
     1842        struct dcerpc_binding_handle *b;
    16921843
    16931844        DEBUG(5, ("set_dc_type_and_flags_trustinfo: domain %s\n", domain->name ));
     
    17241875        }
    17251876
     1877        b = cli->binding_handle;
     1878
    17261879        if ( (mem_ctx = talloc_init("set_dc_type_and_flags_trustinfo")) == NULL ) {
    17271880                DEBUG(0,("set_dc_type_and_flags_trustinfo: talloc_init() failed!\n"));
     
    17291882        }       
    17301883
    1731         result = rpccli_netr_DsrEnumerateDomainTrusts(cli, mem_ctx,
     1884        result = dcerpc_netr_DsrEnumerateDomainTrusts(b, mem_ctx,
    17321885                                                      cli->desthost,
    17331886                                                      flags,
    17341887                                                      &trusts,
    1735                                                       NULL);
     1888                                                      &werr);
    17361889        if (!NT_STATUS_IS_OK(result)) {
    17371890                DEBUG(0,("set_dc_type_and_flags_trustinfo: "
     
    17411894                return false;
    17421895        }
     1896        if (!W_ERROR_IS_OK(werr)) {
     1897                DEBUG(0,("set_dc_type_and_flags_trustinfo: "
     1898                        "failed to query trusted domain list: %s\n",
     1899                        win_errstr(werr)));
     1900                talloc_destroy(mem_ctx);
     1901                return false;
     1902        }
    17431903
    17441904        /* Now find the domain name and get the flags */
     
    17891949static void set_dc_type_and_flags_connect( struct winbindd_domain *domain )
    17901950{
    1791         NTSTATUS                result;
     1951        NTSTATUS status, result;
    17921952        WERROR werr;
    17931953        TALLOC_CTX              *mem_ctx = NULL;
     
    18101970        DEBUG(5, ("set_dc_type_and_flags_connect: domain %s\n", domain->name ));
    18111971
    1812         result = cli_rpc_pipe_open_noauth(domain->conn.cli,
     1972        status = cli_rpc_pipe_open_noauth(domain->conn.cli,
    18131973                                          &ndr_table_dssetup.syntax_id,
    18141974                                          &cli);
    18151975
    1816         if (!NT_STATUS_IS_OK(result)) {
     1976        if (!NT_STATUS_IS_OK(status)) {
    18171977                DEBUG(5, ("set_dc_type_and_flags_connect: Could not bind to "
    18181978                          "PI_DSSETUP on domain %s: (%s)\n",
    1819                           domain->name, nt_errstr(result)));
     1979                          domain->name, nt_errstr(status)));
    18201980
    18211981                /* if this is just a non-AD domain we need to continue
     
    18261986        }
    18271987
    1828         result = rpccli_dssetup_DsRoleGetPrimaryDomainInformation(cli, mem_ctx,
     1988        status = dcerpc_dssetup_DsRoleGetPrimaryDomainInformation(cli->binding_handle, mem_ctx,
    18291989                                                                  DS_ROLE_BASIC_INFORMATION,
    18301990                                                                  &info,
     
    18321992        TALLOC_FREE(cli);
    18331993
    1834         if (!NT_STATUS_IS_OK(result)) {
     1994        if (NT_STATUS_IS_OK(status)) {
     1995                result = werror_to_ntstatus(werr);
     1996        }
     1997        if (!NT_STATUS_IS_OK(status)) {
    18351998                DEBUG(5, ("set_dc_type_and_flags_connect: rpccli_ds_getprimarydominfo "
    18361999                          "on domain %s failed: (%s)\n",
    1837                           domain->name, nt_errstr(result)));
     2000                          domain->name, nt_errstr(status)));
    18382001
    18392002                /* older samba3 DCs will return DCERPC_FAULT_OP_RNG_ERROR for
     
    18422005                 * set - gd */
    18432006
    1844                 if (NT_STATUS_V(result) == DCERPC_FAULT_OP_RNG_ERROR) {
     2007                if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) {
    18452008                        goto no_dssetup;
    18462009                }
     
    18582021
    18592022no_dssetup:
    1860         result = cli_rpc_pipe_open_noauth(domain->conn.cli,
     2023        status = cli_rpc_pipe_open_noauth(domain->conn.cli,
    18612024                                          &ndr_table_lsarpc.syntax_id, &cli);
    18622025
    1863         if (!NT_STATUS_IS_OK(result)) {
     2026        if (!NT_STATUS_IS_OK(status)) {
    18642027                DEBUG(5, ("set_dc_type_and_flags_connect: Could not bind to "
    18652028                          "PI_LSARPC on domain %s: (%s)\n",
    1866                           domain->name, nt_errstr(result)));
     2029                          domain->name, nt_errstr(status)));
    18672030                TALLOC_FREE(cli);
    18682031                TALLOC_FREE(mem_ctx);
     
    18702033        }
    18712034
    1872         result = rpccli_lsa_open_policy2(cli, mem_ctx, True,
     2035        status = rpccli_lsa_open_policy2(cli, mem_ctx, True,
    18732036                                         SEC_FLAG_MAXIMUM_ALLOWED, &pol);
    18742037
    1875         if (NT_STATUS_IS_OK(result)) {
     2038        if (NT_STATUS_IS_OK(status)) {
    18762039                /* This particular query is exactly what Win2k clients use
    18772040                   to determine that the DC is active directory */
    1878                 result = rpccli_lsa_QueryInfoPolicy2(cli, mem_ctx,
     2041                status = dcerpc_lsa_QueryInfoPolicy2(cli->binding_handle, mem_ctx,
    18792042                                                     &pol,
    18802043                                                     LSA_POLICY_INFO_DNS,
    1881                                                      &lsa_info);
    1882         }
    1883 
    1884         if (NT_STATUS_IS_OK(result)) {
     2044                                                     &lsa_info,
     2045                                                     &result);
     2046        }
     2047
     2048        if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) {
    18852049                domain->active_directory = True;
    18862050
     
    19122076                domain->active_directory = False;
    19132077
    1914                 result = rpccli_lsa_open_policy(cli, mem_ctx, True,
     2078                status = rpccli_lsa_open_policy(cli, mem_ctx, True,
    19152079                                                SEC_FLAG_MAXIMUM_ALLOWED,
    19162080                                                &pol);
    19172081
    1918                 if (!NT_STATUS_IS_OK(result)) {
     2082                if (!NT_STATUS_IS_OK(status)) {
    19192083                        goto done;
    19202084                }
    19212085
    1922                 result = rpccli_lsa_QueryInfoPolicy(cli, mem_ctx,
     2086                status = dcerpc_lsa_QueryInfoPolicy(cli->binding_handle, mem_ctx,
    19232087                                                    &pol,
    19242088                                                    LSA_POLICY_INFO_ACCOUNT_DOMAIN,
    1925                                                     &lsa_info);
    1926 
    1927                 if (NT_STATUS_IS_OK(result)) {
     2089                                                    &lsa_info,
     2090                                                    &result);
     2091                if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) {
    19282092
    19292093                        if (lsa_info->account_domain.name.string) {
     
    19932157
    19942158        if (lp_client_schannel() == False) {
    1995                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;;
     2159                return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
    19962160        }
    19972161
     
    20162180{
    20172181        struct winbindd_cm_conn *conn;
    2018         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
     2182        NTSTATUS status, result;
    20192183        struct netlogon_creds_CredentialState *p_creds;
    20202184        char *machine_password = NULL;
     
    20222186        char *domain_name = NULL;
    20232187
    2024         result = init_dc_connection_rpc(domain);
    2025         if (!NT_STATUS_IS_OK(result)) {
    2026                 return result;
     2188        if (sid_check_is_domain(&domain->sid)) {
     2189                return open_internal_samr_conn(mem_ctx, domain, cli, sam_handle);
     2190        }
     2191
     2192        status = init_dc_connection_rpc(domain);
     2193        if (!NT_STATUS_IS_OK(status)) {
     2194                return status;
    20272195        }
    20282196
     
    20462214            (conn->cli->password == NULL || conn->cli->password[0] == '\0'))
    20472215        {
    2048                 result = get_trust_creds(domain, &machine_password,
     2216                status = get_trust_creds(domain, &machine_password,
    20492217                                         &machine_account, NULL);
    2050                 if (!NT_STATUS_IS_OK(result)) {
     2218                if (!NT_STATUS_IS_OK(status)) {
    20512219                        DEBUG(10, ("cm_connect_sam: No no user available for "
    20522220                                   "domain %s, trying schannel\n", conn->cli->domain));
     
    20612229
    20622230        if (!machine_password || !machine_account) {
    2063                 result = NT_STATUS_NO_MEMORY;
     2231                status = NT_STATUS_NO_MEMORY;
    20642232                goto done;
    20652233        }
     
    20672235        /* We have an authenticated connection. Use a NTLMSSP SPNEGO
    20682236           authenticated SAMR pipe with sign & seal. */
    2069         result = cli_rpc_pipe_open_spnego_ntlmssp(conn->cli,
     2237        status = cli_rpc_pipe_open_spnego_ntlmssp(conn->cli,
    20702238                                                  &ndr_table_samr.syntax_id,
    20712239                                                  NCACN_NP,
     
    20762244                                                  &conn->samr_pipe);
    20772245
    2078         if (!NT_STATUS_IS_OK(result)) {
     2246        if (!NT_STATUS_IS_OK(status)) {
    20792247                DEBUG(10,("cm_connect_sam: failed to connect to SAMR "
    20802248                          "pipe for domain %s using NTLMSSP "
    20812249                          "authenticated pipe: user %s\\%s. Error was "
    20822250                          "%s\n", domain->name, domain_name,
    2083                           machine_account, nt_errstr(result)));
     2251                          machine_account, nt_errstr(status)));
    20842252                goto schannel;
    20852253        }
     
    20902258                  domain_name, machine_account));
    20912259
    2092         result = rpccli_samr_Connect2(conn->samr_pipe, mem_ctx,
     2260        status = dcerpc_samr_Connect2(conn->samr_pipe->binding_handle, mem_ctx,
    20932261                                      conn->samr_pipe->desthost,
    20942262                                      SEC_FLAG_MAXIMUM_ALLOWED,
    2095                                       &conn->sam_connect_handle);
    2096         if (NT_STATUS_IS_OK(result)) {
     2263                                      &conn->sam_connect_handle,
     2264                                      &result);
     2265        if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) {
    20972266                goto open_domain;
    20982267        }
    2099         DEBUG(10,("cm_connect_sam: ntlmssp-sealed rpccli_samr_Connect2 "
     2268        if (NT_STATUS_IS_OK(status)) {
     2269                status = result;
     2270        }
     2271
     2272        DEBUG(10,("cm_connect_sam: ntlmssp-sealed dcerpc_samr_Connect2 "
    21002273                  "failed for domain %s, error was %s. Trying schannel\n",
    2101                   domain->name, nt_errstr(result) ));
     2274                  domain->name, nt_errstr(status) ));
    21022275        TALLOC_FREE(conn->samr_pipe);
    21032276
     
    21062279        /* Fall back to schannel if it's a W2K pre-SP1 box. */
    21072280
    2108         result = cm_get_schannel_creds(domain, &p_creds);
    2109         if (!NT_STATUS_IS_OK(result)) {
     2281        status = cm_get_schannel_creds(domain, &p_creds);
     2282        if (!NT_STATUS_IS_OK(status)) {
    21102283                /* If this call fails - conn->cli can now be NULL ! */
    21112284                DEBUG(10, ("cm_connect_sam: Could not get schannel auth info "
    21122285                           "for domain %s (error %s), trying anon\n",
    21132286                        domain->name,
    2114                         nt_errstr(result) ));
     2287                        nt_errstr(status) ));
    21152288                goto anonymous;
    21162289        }
    2117         result = cli_rpc_pipe_open_schannel_with_key
     2290        status = cli_rpc_pipe_open_schannel_with_key
    21182291                (conn->cli, &ndr_table_samr.syntax_id, NCACN_NP,
    21192292                 DCERPC_AUTH_LEVEL_PRIVACY,
    21202293                 domain->name, &p_creds, &conn->samr_pipe);
    21212294
    2122         if (!NT_STATUS_IS_OK(result)) {
     2295        if (!NT_STATUS_IS_OK(status)) {
    21232296                DEBUG(10,("cm_connect_sam: failed to connect to SAMR pipe for "
    21242297                          "domain %s using schannel. Error was %s\n",
    2125                           domain->name, nt_errstr(result) ));
     2298                          domain->name, nt_errstr(status) ));
    21262299                goto anonymous;
    21272300        }
     
    21292302                  "schannel.\n", domain->name ));
    21302303
    2131         result = rpccli_samr_Connect2(conn->samr_pipe, mem_ctx,
     2304        status = dcerpc_samr_Connect2(conn->samr_pipe->binding_handle, mem_ctx,
    21322305                                      conn->samr_pipe->desthost,
    21332306                                      SEC_FLAG_MAXIMUM_ALLOWED,
    2134                                       &conn->sam_connect_handle);
    2135         if (NT_STATUS_IS_OK(result)) {
     2307                                      &conn->sam_connect_handle,
     2308                                      &result);
     2309        if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) {
    21362310                goto open_domain;
    21372311        }
    2138         DEBUG(10,("cm_connect_sam: schannel-sealed rpccli_samr_Connect2 failed "
     2312        if (NT_STATUS_IS_OK(status)) {
     2313                status = result;
     2314        }
     2315        DEBUG(10,("cm_connect_sam: schannel-sealed dcerpc_samr_Connect2 failed "
    21392316                  "for domain %s, error was %s. Trying anonymous\n",
    2140                   domain->name, nt_errstr(result) ));
     2317                  domain->name, nt_errstr(status) ));
    21412318        TALLOC_FREE(conn->samr_pipe);
    21422319
     
    21442321
    21452322        /* Finally fall back to anonymous. */
    2146         result = cli_rpc_pipe_open_noauth(conn->cli, &ndr_table_samr.syntax_id,
     2323        status = cli_rpc_pipe_open_noauth(conn->cli, &ndr_table_samr.syntax_id,
    21472324                                          &conn->samr_pipe);
    21482325
    2149         if (!NT_STATUS_IS_OK(result)) {
     2326        if (!NT_STATUS_IS_OK(status)) {
    21502327                goto done;
    21512328        }
    21522329
    2153         result = rpccli_samr_Connect2(conn->samr_pipe, mem_ctx,
     2330        status = dcerpc_samr_Connect2(conn->samr_pipe->binding_handle, mem_ctx,
    21542331                                      conn->samr_pipe->desthost,
    21552332                                      SEC_FLAG_MAXIMUM_ALLOWED,
    2156                                       &conn->sam_connect_handle);
    2157         if (!NT_STATUS_IS_OK(result)) {
     2333                                      &conn->sam_connect_handle,
     2334                                      &result);
     2335        if (!NT_STATUS_IS_OK(status)) {
    21582336                DEBUG(10,("cm_connect_sam: rpccli_samr_Connect2 failed "
    21592337                          "for domain %s Error was %s\n",
    2160                           domain->name, nt_errstr(result) ));
     2338                          domain->name, nt_errstr(status) ));
    21612339                goto done;
    21622340        }
     2341        if (!NT_STATUS_IS_OK(result)) {
     2342                status = result;
     2343                DEBUG(10,("cm_connect_sam: dcerpc_samr_Connect2 failed "
     2344                          "for domain %s Error was %s\n",
     2345                          domain->name, nt_errstr(result)));
     2346                goto done;
     2347        }
    21632348
    21642349 open_domain:
    2165         result = rpccli_samr_OpenDomain(conn->samr_pipe,
     2350        status = dcerpc_samr_OpenDomain(conn->samr_pipe->binding_handle,
    21662351                                        mem_ctx,
    21672352                                        &conn->sam_connect_handle,
    21682353                                        SEC_FLAG_MAXIMUM_ALLOWED,
    21692354                                        &domain->sid,
    2170                                         &conn->sam_domain_handle);
    2171 
     2355                                        &conn->sam_domain_handle,
     2356                                        &result);
     2357        if (!NT_STATUS_IS_OK(status)) {
     2358                goto done;
     2359        }
     2360
     2361        status = result;
    21722362 done:
    21732363
    2174         if (NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED)) {
     2364        if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
    21752365                /*
    21762366                 * if we got access denied, we might just have no access rights
     
    21822372                TALLOC_FREE(conn->samr_pipe);
    21832373                ZERO_STRUCT(conn->sam_domain_handle);
    2184                 return result;
    2185         } else if (!NT_STATUS_IS_OK(result)) {
     2374                return status;
     2375        } else if (!NT_STATUS_IS_OK(status)) {
    21862376                invalidate_cm_connection(conn);
    2187                 return result;
     2377                return status;
    21882378        }
    21892379
     
    21922382        SAFE_FREE(machine_password);
    21932383        SAFE_FREE(machine_account);
    2194         return result;
     2384        return status;
    21952385}
    21962386
     
    25042694        return NT_STATUS_OK;
    25052695}
     2696
     2697void winbind_msg_ip_dropped(struct messaging_context *msg_ctx,
     2698                            void *private_data,
     2699                            uint32_t msg_type,
     2700                            struct server_id server_id,
     2701                            DATA_BLOB *data)
     2702{
     2703        struct winbindd_domain *domain;
     2704        char *freeit = NULL;
     2705        char *addr;
     2706
     2707        if ((data == NULL)
     2708            || (data->data == NULL)
     2709            || (data->length == 0)
     2710            || (data->data[data->length-1] != '\0')) {
     2711                DEBUG(1, ("invalid msg_ip_dropped message: not a valid "
     2712                          "string\n"));
     2713                return;
     2714        }
     2715
     2716        addr = (char *)data->data;
     2717        DEBUG(10, ("IP %s dropped\n", addr));
     2718
     2719        if (!is_ipaddress(addr)) {
     2720                char *slash;
     2721                /*
     2722                 * Some code sends us ip addresses with the /netmask
     2723                 * suffix
     2724                 */
     2725                slash = strchr(addr, '/');
     2726                if (slash == NULL) {
     2727                        DEBUG(1, ("invalid msg_ip_dropped message: %s",
     2728                                  addr));
     2729                        return;
     2730                }
     2731                freeit = talloc_strndup(talloc_tos(), addr, slash-addr);
     2732                if (freeit == NULL) {
     2733                        DEBUG(1, ("talloc failed\n"));
     2734                        return;
     2735                }
     2736                addr = freeit;
     2737                DEBUG(10, ("Stripped /netmask to IP %s\n", addr));
     2738        }
     2739
     2740        for (domain = domain_list(); domain != NULL; domain = domain->next) {
     2741                char sockaddr[INET6_ADDRSTRLEN];
     2742                if (domain->conn.cli == NULL) {
     2743                        continue;
     2744                }
     2745                if (domain->conn.cli->fd == -1) {
     2746                        continue;
     2747                }
     2748                client_socket_addr(domain->conn.cli->fd, sockaddr,
     2749                                   sizeof(sockaddr));
     2750                if (strequal(sockaddr, addr)) {
     2751                        close(domain->conn.cli->fd);
     2752                        domain->conn.cli->fd = -1;
     2753                }
     2754        }
     2755        TALLOC_FREE(freeit);
     2756}
  • vendor/current/source3/winbindd/winbindd_cred_cache.c

    r414 r740  
    2626#include "../libcli/auth/libcli_auth.h"
    2727#include "smb_krb5.h"
     28#include "libads/kerberos_proto.h"
    2829
    2930#undef DBGC_CLASS
     
    4849   at one-half of the period from now till the tkt
    4950   expiration */
    50 #define KRB5_EVENT_REFRESH_TIME(x) ((x) - (((x) - time(NULL))/2))
     51
     52static time_t krb5_event_refresh_time(time_t end_time)
     53{
     54        time_t rest = end_time - time(NULL);
     55        return end_time - rest/2;
     56}
    5157
    5258/****************************************************************
     
    184190                           from now to the expiration time */
    185191                        expire_time = entry->refresh_time;
    186                         new_start = KRB5_EVENT_REFRESH_TIME(entry->refresh_time);
     192                        new_start = krb5_event_refresh_time(entry->refresh_time);
    187193#endif
    188194                        goto done;
     
    208214#else
    209215        expire_time = new_start;
    210         new_start = KRB5_EVENT_REFRESH_TIME(new_start);
     216        new_start = krb5_event_refresh_time(new_start);
    211217#endif
    212218
     
    270276        if (entry->renew_until && expire_time
    271277             && (entry->renew_until <= expire_time)) {
    272                 /* try to regain ticket 10 seconds beforre expiration */
     278                /* try to regain ticket 10 seconds before expiration */
    273279                expire_time -= 10;
    274280                add_krb5_ticket_gain_handler_event(entry,
     
    360366  retry_later:
    361367 
    362 #if defined(DEBUG_KRB5_TKT_REGAIN)
     368#if defined(DEBUG_KRB5_TKT_RENEWAL)
    363369        t = timeval_set(time(NULL) + 30, 0);
    364370#else
     
    374380        t = timeval_set(time(NULL) + 30, 0);
    375381#else
    376         t = timeval_set(KRB5_EVENT_REFRESH_TIME(entry->refresh_time), 0);
     382        t = timeval_set(krb5_event_refresh_time(entry->refresh_time), 0);
    377383#endif
    378384
     
    524530                                   error_message(ret)));
    525531                        return krb5_to_nt_status(ret);
    526                 } else {
    527                         DEBUG(10, ("add_ccache_to_list: successfully destroyed "
    528                                    "krb5 ccache %s for user %s\n", ccname,
    529                                    username));
    530                 }
     532                }
     533                DEBUG(10, ("add_ccache_to_list: successfully destroyed "
     534                           "krb5 ccache %s for user %s\n", ccname,
     535                           username));
    531536        }
    532537#endif
     
    546551                 * event handler created - gd
    547552                 * Add ticket refresh handler here */
    548                
     553
    549554                if (!lp_winbind_refresh_tickets() || renew_until <= 0) {
    550555                        return NT_STATUS_OK;
    551556                }
    552                
     557
    553558                if (!entry->event) {
    554559                        if (postponed_request) {
     
    560565                                t = timeval_set(time(NULL)+30, 0);
    561566#else
    562                                 t = timeval_set(KRB5_EVENT_REFRESH_TIME(ticket_end), 0);
     567                                t = timeval_set(krb5_event_refresh_time(ticket_end),
     568                                                0);
    563569#endif
    564570                                if (!entry->refresh_time) {
     
    587593                        DEBUG(10,("add_ccache_to_list: added krb5_ticket handler\n"));
    588594                }
    589                  
     595
    590596                return NT_STATUS_OK;
    591597        }
     
    644650                t = timeval_set(time(NULL)+30, 0);
    645651#else
    646                 t = timeval_set(KRB5_EVENT_REFRESH_TIME(ticket_end), 0);
     652                t = timeval_set(krb5_event_refresh_time(ticket_end), 0);
    647653#endif
    648654                if (entry->refresh_time == 0) {
     
    687693        struct WINBINDD_CCACHE_ENTRY *entry = get_ccache_by_username(username);
    688694        NTSTATUS status = NT_STATUS_OK;
    689         #ifdef HAVE_KRB5
     695#ifdef HAVE_KRB5
    690696        krb5_error_code ret;
    691697#endif
  • vendor/current/source3/winbindd/winbindd_creds.c

    r414 r740  
    55
    66   Copyright (C) Guenther Deschner 2005
    7    
     7
    88   This program is free software; you can redistribute it and/or modify
    99   it under the terms of the GNU General Public License as published by
    1010   the Free Software Foundation; either version 3 of the License, or
    1111   (at your option) any later version.
    12    
     12
    1313   This program is distributed in the hope that it will be useful,
    1414   but WITHOUT ANY WARRANTY; without even the implied warranty of
    1515   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1616   GNU General Public License for more details.
    17    
     17
    1818   You should have received a copy of the GNU General Public License
    1919   along with this program.  If not, see <http://www.gnu.org/licenses/>.
     
    2323#include "winbindd.h"
    2424#include "../libcli/auth/libcli_auth.h"
     25#include "../libcli/security/security.h"
    2526#undef DBGC_CLASS
    2627#define DBGC_CLASS DBGC_WINBIND
     
    3031NTSTATUS winbindd_get_creds(struct winbindd_domain *domain,
    3132                            TALLOC_CTX *mem_ctx,
    32                             const DOM_SID *sid,
     33                            const struct dom_sid *sid,
    3334                            struct netr_SamInfo3 **info3,
    3435                            const uint8 *cached_nt_pass[NT_HASH_LEN],
     
    5556
    5657NTSTATUS winbindd_store_creds(struct winbindd_domain *domain,
    57                               TALLOC_CTX *mem_ctx,
    5858                              const char *user,
    5959                              const char *pass,
    60                               struct netr_SamInfo3 *info3,
    61                               const DOM_SID *user_sid)
     60                              struct netr_SamInfo3 *info3)
    6261{
    6362        NTSTATUS status;
    6463        uchar nt_pass[NT_HASH_LEN];
    65         DOM_SID cred_sid;
     64        struct dom_sid cred_sid;
    6665
    6766        if (info3 != NULL) {
    6867
    69                 DOM_SID sid;
    70                 sid_copy(&sid, info3->base.domain_sid);
    71                 sid_append_rid(&sid, info3->base.rid);
    72                 sid_copy(&cred_sid, &sid);
     68                sid_compose(&cred_sid, info3->base.domain_sid,
     69                            info3->base.rid);
    7370                info3->base.user_flags |= NETLOGON_CACHED_ACCOUNT;
    74 
    75         } else if (user_sid != NULL) {
    76 
    77                 sid_copy(&cred_sid, user_sid);
    7871
    7972        } else if (user != NULL) {
     
    8376                enum lsa_SidType type;
    8477
    85                 if (!lookup_cached_name(mem_ctx,
    86                                         domain->name,
     78                if (!lookup_cached_name(domain->name,
    8779                                        user,
    8880                                        &cred_sid,
     
    121113                dump_data_pw("nt_pass", nt_pass, NT_HASH_LEN);
    122114
    123                 status = wcache_save_creds(domain, mem_ctx, &cred_sid, nt_pass);
     115                status = wcache_save_creds(domain, &cred_sid, nt_pass);
    124116                if (!NT_STATUS_IS_OK(status)) {
    125117                        return status;
     
    137129
    138130NTSTATUS winbindd_update_creds_by_info3(struct winbindd_domain *domain,
    139                                         TALLOC_CTX *mem_ctx,
    140131                                        const char *user,
    141132                                        const char *pass,
    142133                                        struct netr_SamInfo3 *info3)
    143134{
    144         return winbindd_store_creds(domain, mem_ctx, user, pass, info3, NULL);
    145 }
    146 
    147 NTSTATUS winbindd_update_creds_by_sid(struct winbindd_domain *domain,
    148                                       TALLOC_CTX *mem_ctx,
    149                                       const DOM_SID *sid,
    150                                       const char *pass)
    151 {
    152         return winbindd_store_creds(domain, mem_ctx, NULL, pass, NULL, sid);
     135        return winbindd_store_creds(domain, user, pass, info3);
    153136}
    154137
    155138NTSTATUS winbindd_update_creds_by_name(struct winbindd_domain *domain,
    156                                        TALLOC_CTX *mem_ctx,
    157139                                       const char *user,
    158140                                       const char *pass)
    159141{
    160         return winbindd_store_creds(domain, mem_ctx, user, pass, NULL, NULL);
     142        return winbindd_store_creds(domain, user, pass, NULL);
    161143}
    162144
  • vendor/current/source3/winbindd/winbindd_domain.c

    r414 r740  
    4040                .struct_fn      = winbindd_dual_init_connection,
    4141        },{
    42                 .name           = "SHOW_SEQUENCE",
    43                 .struct_cmd     = WINBINDD_SHOW_SEQUENCE,
    44                 .struct_fn      = winbindd_dual_show_sequence,
    45         },{
    4642                .name           = "PAM_AUTH",
    4743                .struct_cmd     = WINBINDD_PAM_AUTH,
     
    6460                .struct_fn      = winbindd_dual_pam_chauthtok,
    6561        },{
    66                 .name           = "CCACHE_NTLM_AUTH",
    67                 .struct_cmd     = WINBINDD_CCACHE_NTLMAUTH,
    68                 .struct_fn      = winbindd_dual_ccache_ntlm_auth,
    69         },{
    70                 .name           = "CCACHE_SAVE",
    71                 .struct_cmd     = WINBINDD_CCACHE_SAVE,
    72                 .struct_fn      = winbindd_dual_ccache_save,
    73         },{
    7462                .name           = "NDRCMD",
    7563                .struct_cmd     = WINBINDD_DUAL_NDRCMD,
     
    8068};
    8169
    82 void setup_domain_child(struct winbindd_domain *domain,
    83                         struct winbindd_child *child)
     70void setup_domain_child(struct winbindd_domain *domain)
    8471{
    85         setup_child(domain, child, domain_dispatch_table,
    86                     "log.wb", domain->name);
     72        int i;
     73
     74        for (i=0; i<lp_winbind_max_domain_connections(); i++) {
     75                setup_child(domain, &domain->children[i],
     76                            domain_dispatch_table,
     77                            "log.wb", domain->name);
     78                domain->children[i].domain = domain;
     79        }
    8780}
  • vendor/current/source3/winbindd/winbindd_dsgetdcname.c

    r414 r740  
    2020#include "includes.h"
    2121#include "winbindd.h"
    22 #include "librpc/gen_ndr/cli_wbint.h"
     22#include "librpc/gen_ndr/ndr_wbint_c.h"
    2323
    2424struct winbindd_dsgetdcname_state {
     
    6868        child = locator_child();
    6969
    70         subreq = rpccli_wbint_DsGetDcName_send(
    71                 state, ev, child->rpccli,
     70        subreq = dcerpc_wbint_DsGetDcName_send(
     71                state, ev, child->binding_handle,
    7272                request->data.dsgetdcname.domain_name, guid_ptr,
    7373                request->data.dsgetdcname.site_name,
     
    8888        NTSTATUS status, result;
    8989
    90         status = rpccli_wbint_DsGetDcName_recv(subreq, state, &result);
     90        status = dcerpc_wbint_DsGetDcName_recv(subreq, state, &result);
    9191        TALLOC_FREE(subreq);
    92         if (!NT_STATUS_IS_OK(status)) {
     92        if (any_nt_status_not_ok(status, result, &status)) {
    9393                tevent_req_nterror(req, status);
    94                 return;
    95         }
    96         if (!NT_STATUS_IS_OK(result)) {
    97                 tevent_req_nterror(req, result);
    9894                return;
    9995        }
  • vendor/current/source3/winbindd/winbindd_dual.c

    r591 r740  
    3030#include "includes.h"
    3131#include "winbindd.h"
    32 #include "../../nsswitch/libwbclient/wbc_async.h"
     32#include "nsswitch/wb_reqtrans.h"
     33#include "secrets.h"
     34#include "../lib/util/select.h"
     35#include "../libcli/security/security.h"
     36#include "system/select.h"
     37#include "messages.h"
     38#include "../lib/util/tevent_unix.h"
    3339
    3440#undef DBGC_CLASS
     
    135141        struct tevent_req *subreq;
    136142
    137         if ((state->child->pid == 0) && (!fork_domain_child(state->child))) {
     143        if ((state->child->sock == -1) && (!fork_domain_child(state->child))) {
    138144                tevent_req_error(req, errno);
    139145                return;
     
    146152        }
    147153        tevent_req_set_callback(subreq, wb_child_request_done, req);
    148 
    149         if (!tevent_req_set_endtime(req, state->ev,
    150                                     timeval_current_ofs(300, 0))) {
    151                 tevent_req_nomem(NULL, req);
    152                 return;
    153         }
     154        tevent_req_set_endtime(req, state->ev, timeval_current_ofs(300, 0));
    154155}
    155156
     
    165166        TALLOC_FREE(subreq);
    166167        if (ret == -1) {
     168                /*
     169                 * The basic parent/child communication broke, close
     170                 * our socket
     171                 */
     172                close(state->child->sock);
     173                state->child->sock = -1;
    167174                tevent_req_error(req, err);
    168175                return;
     
    182189        *presponse = talloc_move(mem_ctx, &state->response);
    183190        return 0;
     191}
     192
     193static bool winbindd_child_busy(struct winbindd_child *child)
     194{
     195        return tevent_queue_length(child->queue) > 0;
     196}
     197
     198static struct winbindd_child *find_idle_child(struct winbindd_domain *domain)
     199{
     200        int i;
     201
     202        for (i=0; i<lp_winbind_max_domain_connections(); i++) {
     203                if (!winbindd_child_busy(&domain->children[i])) {
     204                        return &domain->children[i];
     205                }
     206        }
     207
     208        return NULL;
     209}
     210
     211struct winbindd_child *choose_domain_child(struct winbindd_domain *domain)
     212{
     213        struct winbindd_child *result;
     214
     215        result = find_idle_child(domain);
     216        if (result != NULL) {
     217                return result;
     218        }
     219        return &domain->children[rand() % lp_winbind_max_domain_connections()];
     220}
     221
     222struct dcerpc_binding_handle *dom_child_handle(struct winbindd_domain *domain)
     223{
     224        struct winbindd_child *child;
     225
     226        child = choose_domain_child(domain);
     227        return child->binding_handle;
    184228}
    185229
     
    187231        struct tevent_context *ev;
    188232        struct winbindd_domain *domain;
     233        struct winbindd_child *child;
    189234        struct winbindd_request *request;
    190235        struct winbindd_request *init_req;
     
    210255        }
    211256
     257        state->child = choose_domain_child(domain);
     258
    212259        if (domain->initialized) {
    213                 subreq = wb_child_request_send(state, ev, &domain->child,
     260                subreq = wb_child_request_send(state, ev, state->child,
    214261                                               request);
    215262                if (tevent_req_nomem(subreq, req)) {
     
    233280                state->init_req->cmd = WINBINDD_INIT_CONNECTION;
    234281                fstrcpy(state->init_req->domain_name, domain->name);
    235                 state->init_req->data.init_conn.is_primary =
    236                         domain->primary ? true : false;
     282                state->init_req->data.init_conn.is_primary = domain->primary;
    237283                fstrcpy(state->init_req->data.init_conn.dcname, "");
    238284
    239                 subreq = wb_child_request_send(state, ev, &domain->child,
     285                subreq = wb_child_request_send(state, ev, state->child,
    240286                                               state->init_req);
    241287                if (tevent_req_nomem(subreq, req)) {
     
    258304        fstrcpy(state->init_req->domain_name, domain->name);
    259305
    260         subreq = wb_child_request_send(state, ev, &domain->child, request);
     306        subreq = wb_child_request_send(state, ev, state->child, request);
    261307        if (tevent_req_nomem(subreq, req)) {
    262308                return tevent_req_post(req, ev);
     
    289335        TALLOC_FREE(response);
    290336
    291         subreq = wb_child_request_send(state, state->ev, &state->domain->child,
     337        subreq = wb_child_request_send(state, state->ev, state->child,
    292338                                       state->init_req);
    293339        if (tevent_req_nomem(subreq, req)) {
     
    329375        TALLOC_FREE(response);
    330376
    331         subreq = wb_child_request_send(state, state->ev, &state->domain->child,
     377        subreq = wb_child_request_send(state, state->ev, state->child,
    332378                                       state->request);
    333379        if (tevent_req_nomem(subreq, req)) {
     
    366412        *presponse = talloc_move(mem_ctx, &state->response);
    367413        return 0;
    368 }
    369 
    370 struct domain_request_state {
    371         struct winbindd_domain *domain;
    372         struct winbindd_request *request;
    373         struct winbindd_response *response;
    374         void (*continuation)(void *private_data_data, bool success);
    375         void *private_data_data;
    376 };
    377 
    378 static void async_domain_request_done(struct tevent_req *req);
    379 
    380 void async_domain_request(TALLOC_CTX *mem_ctx,
    381                           struct winbindd_domain *domain,
    382                           struct winbindd_request *request,
    383                           struct winbindd_response *response,
    384                           void (*continuation)(void *private_data_data, bool success),
    385                           void *private_data_data)
    386 {
    387         struct tevent_req *subreq;
    388         struct domain_request_state *state;
    389 
    390         state = TALLOC_P(mem_ctx, struct domain_request_state);
    391         if (state == NULL) {
    392                 DEBUG(0, ("talloc failed\n"));
    393                 continuation(private_data_data, False);
    394                 return;
    395         }
    396 
    397         state->domain = domain;
    398         state->request = request;
    399         state->response = response;
    400         state->continuation = continuation;
    401         state->private_data_data = private_data_data;
    402 
    403         subreq = wb_domain_request_send(state, winbind_event_context(),
    404                                         domain, request);
    405         if (subreq == NULL) {
    406                 DEBUG(5, ("wb_domain_request_send failed\n"));
    407                 continuation(private_data_data, false);
    408                 return;
    409         }
    410         tevent_req_set_callback(subreq, async_domain_request_done, state);
    411 }
    412 
    413 static void async_domain_request_done(struct tevent_req *req)
    414 {
    415         struct domain_request_state *state = tevent_req_callback_data(
    416                 req, struct domain_request_state);
    417         struct winbindd_response *response;
    418         int ret, err;
    419 
    420         ret = wb_domain_request_recv(req, state, &response, &err);
    421         TALLOC_FREE(req);
    422         if (ret == -1) {
    423                 DEBUG(5, ("wb_domain_request returned %s\n", strerror(err)));
    424                 state->continuation(state->private_data_data, false);
    425                 return;
    426         }
    427         *(state->response) = *response;
    428         state->continuation(state->private_data_data, true);
    429 }
    430 
    431 static void recvfrom_child(void *private_data_data, bool success)
    432 {
    433         struct winbindd_cli_state *state =
    434                 talloc_get_type_abort(private_data_data, struct winbindd_cli_state);
    435         enum winbindd_result result = state->response->result;
    436 
    437         /* This is an optimization: The child has written directly to the
    438          * response buffer. The request itself is still in pending state,
    439          * state that in the result code. */
    440 
    441         state->response->result = WINBINDD_PENDING;
    442 
    443         if ((!success) || (result != WINBINDD_OK)) {
    444                 request_error(state);
    445                 return;
    446         }
    447 
    448         request_ok(state);
    449 }
    450 
    451 void sendto_domain(struct winbindd_cli_state *state,
    452                    struct winbindd_domain *domain)
    453 {
    454         async_domain_request(state->mem_ctx, domain,
    455                              state->request, state->response,
    456                              recvfrom_child, state);
    457414}
    458415
     
    483440        }
    484441
    485         DEBUG(1 ,("child_process_request: unknown request fn number %d\n",
     442        DEBUG(1, ("child_process_request: unknown request fn number %d\n",
    486443                  (int)state->request->cmd));
    487444        state->response->result = WINBINDD_ERROR;
     
    494451{
    495452        if (logprefix && logname) {
     453                char *logbase = NULL;
     454
     455                if (*lp_logfile()) {
     456                        char *end = NULL;
     457
     458                        if (asprintf(&logbase, "%s", lp_logfile()) < 0) {
     459                                smb_panic("Internal error: asprintf failed");
     460                        }
     461
     462                        if ((end = strrchr_m(logbase, '/'))) {
     463                                *end = '\0';
     464                        }
     465                } else {
     466                        if (asprintf(&logbase, "%s", get_dyn_LOGFILEBASE()) < 0) {
     467                                smb_panic("Internal error: asprintf failed");
     468                        }
     469                }
     470
    496471                if (asprintf(&child->logfilename, "%s/%s-%s",
    497                              get_dyn_LOGFILEBASE(), logprefix, logname) < 0) {
     472                             logbase, logprefix, logname) < 0) {
     473                        SAFE_FREE(logbase);
    498474                        smb_panic("Internal error: asprintf failed");
    499475                }
     476
     477                SAFE_FREE(logbase);
    500478        } else {
    501479                smb_panic("Internal error: logprefix == NULL && "
     
    503481        }
    504482
     483        child->sock = -1;
    505484        child->domain = domain;
    506485        child->table = table;
    507486        child->queue = tevent_queue_create(NULL, "winbind_child");
    508487        SMB_ASSERT(child->queue != NULL);
    509         child->rpccli = wbint_rpccli_create(NULL, domain, child);
    510         SMB_ASSERT(child->rpccli != NULL);
    511 }
    512 
    513 struct winbindd_child *children = NULL;
     488        child->binding_handle = wbint_binding_handle(NULL, domain, child);
     489        SMB_ASSERT(child->binding_handle != NULL);
     490}
     491
     492static struct winbindd_child *winbindd_children = NULL;
    514493
    515494void winbind_child_died(pid_t pid)
     
    517496        struct winbindd_child *child;
    518497
    519         for (child = children; child != NULL; child = child->next) {
     498        for (child = winbindd_children; child != NULL; child = child->next) {
    520499                if (child->pid == pid) {
    521500                        break;
     
    530509        /* This will be re-added in fork_domain_child() */
    531510
    532         DLIST_REMOVE(children, child);
    533 
    534         close(child->sock);
    535         child->sock = -1;
     511        DLIST_REMOVE(winbindd_children, child);
    536512        child->pid = 0;
     513
     514        if (child->sock != -1) {
     515                close(child->sock);
     516                child->sock = -1;
     517        }
    537518}
    538519
     
    565546        debug_message(msg_ctx, private_data, MSG_DEBUG, server_id, data);
    566547
    567         for (child = children; child != NULL; child = child->next) {
     548        for (child = winbindd_children; child != NULL; child = child->next) {
    568549
    569550                DEBUG(10,("winbind_msg_debug: sending message to pid %u.\n",
     
    610591        }
    611592
    612         for (child = children; child != NULL; child = child->next) {
    613                 /* Don't send message to internal childs.  We've already
     593        for (child = winbindd_children; child != NULL; child = child->next) {
     594                /* Don't send message to internal children.  We've already
    614595                   done so above. */
    615596                if (!child->domain || winbindd_internal_child(child)) {
     
    685666        }
    686667
    687         for (child = children; child != NULL; child = child->next) {
     668        for (child = winbindd_children; child != NULL; child = child->next) {
    688669                /* Don't send message to internal childs. */
    689670                if (!child->domain || winbindd_internal_child(child)) {
     
    783764        dump_event_list(winbind_event_context());
    784765
    785         for (child = children; child != NULL; child = child->next) {
     766        for (child = winbindd_children; child != NULL; child = child->next) {
    786767
    787768                DEBUG(10,("winbind_msg_dump_event_list: sending message to pid %u\n",
     
    11911172}
    11921173
    1193 bool winbindd_reinit_after_fork(const char *logfilename)
     1174NTSTATUS winbindd_reinit_after_fork(const struct winbindd_child *myself,
     1175                                    const char *logfilename)
    11941176{
    11951177        struct winbindd_domain *domain;
    11961178        struct winbindd_child *cl;
    1197 
    1198         if (!NT_STATUS_IS_OK(reinit_after_fork(winbind_messaging_context(),
    1199                                                winbind_event_context(),
    1200                                                true))) {
     1179        NTSTATUS status;
     1180
     1181        status = reinit_after_fork(
     1182                winbind_messaging_context(),
     1183                winbind_event_context(),
     1184                procid_self(),
     1185                true);
     1186        if (!NT_STATUS_IS_OK(status)) {
    12011187                DEBUG(0,("reinit_after_fork() failed\n"));
    1202                 return false;
     1188                return status;
    12031189        }
    12041190
     
    12111197
    12121198        if (!winbindd_setup_sig_term_handler(false))
    1213                 return false;
     1199                return NT_STATUS_NO_MEMORY;
    12141200        if (!winbindd_setup_sig_hup_handler(override_logfile ? NULL :
    12151201                                            logfilename))
    1216                 return false;
     1202                return NT_STATUS_NO_MEMORY;
    12171203
    12181204        /* Stop zombies in children */
     
    12531239
    12541240        /* Destroy all possible events in child list. */
    1255         for (cl = children; cl != NULL; cl = cl->next) {
     1241        for (cl = winbindd_children; cl != NULL; cl = cl->next) {
    12561242                TALLOC_FREE(cl->lockout_policy_event);
    12571243                TALLOC_FREE(cl->machine_password_change_event);
     
    12621248                 */
    12631249                cl->pid = (pid_t)0;
     1250
     1251                /*
     1252                 * Close service sockets to all other children
     1253                 */
     1254                if ((cl != myself) && (cl->sock != -1)) {
     1255                        close(cl->sock);
     1256                        cl->sock = -1;
     1257                }
    12641258        }
    12651259        /*
     
    12821276        cl->pid = (pid_t)0;
    12831277
    1284         return true;
     1278        return NT_STATUS_OK;
    12851279}
    12861280
     
    13021296        struct winbindd_response response;
    13031297        struct winbindd_domain *primary_domain = NULL;
     1298        NTSTATUS status;
     1299        ssize_t nwritten;
    13041300
    13051301        if (child->domain) {
     
    13091305                DEBUG(10, ("fork_domain_child called without domain.\n"));
    13101306        }
    1311         child_domain = child->domain;
    13121307
    13131308        if (socketpair(AF_UNIX, SOCK_STREAM, 0, fdpair) != 0) {
     
    13311326        if (child->pid != 0) {
    13321327                /* Parent */
     1328                ssize_t nread;
     1329
    13331330                close(fdpair[0]);
     1331
     1332                nread = read(fdpair[1], &status, sizeof(status));
     1333                if (nread != sizeof(status)) {
     1334                        DEBUG(1, ("fork_domain_child: Could not read child status: "
     1335                                  "nread=%d, error=%s\n", (int)nread,
     1336                                  strerror(errno)));
     1337                        close(fdpair[1]);
     1338                        return false;
     1339                }
     1340                if (!NT_STATUS_IS_OK(status)) {
     1341                        DEBUG(1, ("fork_domain_child: Child status is %s\n",
     1342                                  nt_errstr(status)));
     1343                        close(fdpair[1]);
     1344                        return false;
     1345                }
     1346
    13341347                child->next = child->prev = NULL;
    1335                 DLIST_ADD(children, child);
     1348                DLIST_ADD(winbindd_children, child);
    13361349                child->sock = fdpair[1];
    13371350                return True;
     
    13391352
    13401353        /* Child */
     1354        child_domain = child->domain;
    13411355
    13421356        DEBUG(10, ("Child process %d\n", (int)sys_getpid()));
     
    13451359        close(fdpair[1]);
    13461360
    1347         if (!winbindd_reinit_after_fork(child->logfilename)) {
     1361        status = winbindd_reinit_after_fork(child, child->logfilename);
     1362
     1363        nwritten = write(state.sock, &status, sizeof(status));
     1364        if (nwritten != sizeof(status)) {
     1365                DEBUG(1, ("fork_domain_child: Could not write status: "
     1366                          "nwritten=%d, error=%s\n", (int)nwritten,
     1367                          strerror(errno)));
     1368                _exit(0);
     1369        }
     1370        if (!NT_STATUS_IS_OK(status)) {
     1371                DEBUG(1, ("winbindd_reinit_after_fork failed: %s\n",
     1372                          nt_errstr(status)));
    13481373                _exit(0);
    13491374        }
     
    13581383        messaging_register(winbind_messaging_context(), NULL,
    13591384                           MSG_DEBUG, debug_message);
     1385        messaging_register(winbind_messaging_context(), NULL,
     1386                           MSG_WINBIND_IP_DROPPED,
     1387                           winbind_msg_ip_dropped);
     1388
    13601389
    13611390        primary_domain = find_our_domain();
     
    13691398        if ( child->domain ) {
    13701399                child->domain->startup = True;
    1371                 child->domain->startup_time = time(NULL);
     1400                child->domain->startup_time = time_mono(NULL);
    13721401                /* we can be in primary domain or in trusted domain
    13731402                 * If we are in trusted domain, set the primary domain
     
    13771406                        if (!(child->domain->primary)) {
    13781407                                primary_domain->startup = True;
    1379                                 primary_domain->startup_time = time(NULL);
     1408                                primary_domain->startup_time = time_mono(NULL);
    13801409                                set_domain_online_request(primary_domain);
    13811410                        }
     
    14331462
    14341463                int ret;
    1435                 fd_set r_fds;
    1436                 fd_set w_fds;
    1437                 int maxfd;
     1464                struct pollfd *pfds;
     1465                int num_pfds;
     1466                int timeout;
    14381467                struct timeval t;
    14391468                struct timeval *tp;
    1440                 struct timeval now;
    14411469                TALLOC_CTX *frame = talloc_stackframe();
    14421470                struct iovec iov[2];
    14431471                int iov_count;
    1444                 NTSTATUS status;
    1445 
    1446                 if (run_events(winbind_event_context(), 0, NULL, NULL)) {
     1472
     1473                if (run_events_poll(winbind_event_context(), 0, NULL, 0)) {
    14471474                        TALLOC_FREE(frame);
    14481475                        continue;
    14491476                }
    14501477
    1451                 GetTimeOfDay(&now);
    1452 
    14531478                if (child->domain && child->domain->startup &&
    1454                                 (now.tv_sec > child->domain->startup_time + 30)) {
     1479                                (time_mono(NULL) > child->domain->startup_time + 30)) {
    14551480                        /* No longer in "startup" mode. */
    14561481                        DEBUG(10,("fork_domain_child: domain %s no longer in 'startup' mode.\n",
     
    14591484                }
    14601485
    1461                 FD_ZERO(&r_fds);
    1462                 FD_ZERO(&w_fds);
    1463 
    1464                 if (state.sock < 0 || state.sock >= FD_SETSIZE) {
    1465                         TALLOC_FREE(frame);
    1466                         perror("EBADF");
     1486                pfds = TALLOC_ZERO_P(talloc_tos(), struct pollfd);
     1487                if (pfds == NULL) {
     1488                        DEBUG(1, ("talloc failed\n"));
    14671489                        _exit(1);
    14681490                }
    14691491
    1470                 FD_SET(state.sock, &r_fds);
    1471                 maxfd = state.sock;
    1472 
    1473                 /*
    1474                  * Initialize this high as event_add_to_select_args()
    1475                  * uses a timeval_min() on this and next_event. Fix
    1476                  * from Roel van Meer <rolek@alt001.com>.
    1477                  */
    1478                 t.tv_sec = 999999;
    1479                 t.tv_usec = 0;
    1480 
    1481                 event_add_to_select_args(winbind_event_context(), &now,
    1482                                          &r_fds, &w_fds, &t, &maxfd);
     1492                pfds->fd = state.sock;
     1493                pfds->events = POLLIN|POLLHUP;
     1494                num_pfds = 1;
     1495
     1496                timeout = INT_MAX;
     1497
     1498                if (!event_add_to_poll_args(
     1499                            winbind_event_context(), talloc_tos(),
     1500                            &pfds, &num_pfds, &timeout)) {
     1501                        DEBUG(1, ("event_add_to_poll_args failed\n"));
     1502                        _exit(1);
     1503                }
    14831504                tp = get_timed_events_timeout(winbind_event_context(), &t);
    14841505                if (tp) {
     
    14871508                }
    14881509
    1489                 ret = sys_select(maxfd + 1, &r_fds, &w_fds, NULL, tp);
    1490 
    1491                 if (run_events(winbind_event_context(), ret, &r_fds, &w_fds)) {
     1510                ret = sys_poll(pfds, num_pfds, timeout);
     1511
     1512                if (run_events_poll(winbind_event_context(), ret,
     1513                                    pfds, num_pfds)) {
    14921514                        /* We got a signal - continue. */
    14931515                        TALLOC_FREE(frame);
    14941516                        continue;
    14951517                }
     1518
     1519                TALLOC_FREE(pfds);
    14961520
    14971521                if (ret == 0) {
     
    15081532
    15091533                if (ret == -1 && errno != EINTR) {
    1510                         DEBUG(0,("select error occured\n"));
     1534                        DEBUG(0,("poll error occured\n"));
    15111535                        TALLOC_FREE(frame);
    1512                         perror("select");
     1536                        perror("poll");
    15131537                        _exit(1);
    15141538                }
     
    15561580        }
    15571581}
     1582
     1583void winbind_msg_ip_dropped_parent(struct messaging_context *msg_ctx,
     1584                                   void *private_data,
     1585                                   uint32_t msg_type,
     1586                                   struct server_id server_id,
     1587                                   DATA_BLOB *data)
     1588{
     1589        struct winbindd_child *child;
     1590
     1591        winbind_msg_ip_dropped(msg_ctx, private_data, msg_type,
     1592                               server_id, data);
     1593
     1594
     1595        for (child = winbindd_children; child != NULL; child = child->next) {
     1596                messaging_send_buf(msg_ctx, pid_to_procid(child->pid),
     1597                                   msg_type, data->data, data->length);
     1598        }
     1599}
  • vendor/current/source3/winbindd/winbindd_dual_ndr.c

    r414 r740  
    3030#include "winbindd/winbindd.h"
    3131#include "winbindd/winbindd_proto.h"
     32#include "ntdomain.h"
    3233#include "librpc/gen_ndr/srv_wbint.h"
    3334
    34 struct wb_ndr_transport_priv {
     35struct wbint_bh_state {
    3536        struct winbindd_domain *domain;
    3637        struct winbindd_child *child;
    3738};
    3839
    39 struct wb_ndr_dispatch_state {
    40         struct wb_ndr_transport_priv *transport;
     40static bool wbint_bh_is_connected(struct dcerpc_binding_handle *h)
     41{
     42        struct wbint_bh_state *hs = dcerpc_binding_handle_data(h,
     43                                     struct wbint_bh_state);
     44
     45        if (!hs->child) {
     46                return false;
     47        }
     48
     49        return true;
     50}
     51
     52static uint32_t wbint_bh_set_timeout(struct dcerpc_binding_handle *h,
     53                                     uint32_t timeout)
     54{
     55        /* TODO: implement timeouts */
     56        return UINT32_MAX;
     57}
     58
     59struct wbint_bh_raw_call_state {
     60        struct winbindd_domain *domain;
    4161        uint32_t opnum;
    42         const struct ndr_interface_call *call;
    43         void *r;
    44         DATA_BLOB req_blob, resp_blob;
     62        DATA_BLOB in_data;
    4563        struct winbindd_request request;
    4664        struct winbindd_response *response;
     65        DATA_BLOB out_data;
    4766};
    4867
    49 static void wb_ndr_dispatch_done(struct tevent_req *subreq);
    50 
    51 static struct tevent_req *wb_ndr_dispatch_send(TALLOC_CTX *mem_ctx,
    52                                                struct tevent_context *ev,
    53                                                struct rpc_pipe_client *cli,
    54                                                const struct ndr_interface_table *table,
    55                                                uint32_t opnum,
    56                                                void *r)
    57 {
    58         struct tevent_req *req, *subreq;
    59         struct wb_ndr_dispatch_state *state;
    60         struct wb_ndr_transport_priv *transport = talloc_get_type_abort(
    61                 cli->transport->priv, struct wb_ndr_transport_priv);
    62         struct ndr_push *push;
    63         enum ndr_err_code ndr_err;
     68static void wbint_bh_raw_call_done(struct tevent_req *subreq);
     69
     70static struct tevent_req *wbint_bh_raw_call_send(TALLOC_CTX *mem_ctx,
     71                                                  struct tevent_context *ev,
     72                                                  struct dcerpc_binding_handle *h,
     73                                                  const struct GUID *object,
     74                                                  uint32_t opnum,
     75                                                  uint32_t in_flags,
     76                                                  const uint8_t *in_data,
     77                                                  size_t in_length)
     78{
     79        struct wbint_bh_state *hs =
     80                dcerpc_binding_handle_data(h,
     81                struct wbint_bh_state);
     82        struct tevent_req *req;
     83        struct wbint_bh_raw_call_state *state;
     84        bool ok;
     85        struct tevent_req *subreq;
    6486
    6587        req = tevent_req_create(mem_ctx, &state,
    66                                 struct wb_ndr_dispatch_state);
     88                                struct wbint_bh_raw_call_state);
    6789        if (req == NULL) {
    6890                return NULL;
    6991        }
    70 
    71         state->r = r;
    72         state->call = &table->calls[opnum];
    73         state->transport = transport;
     92        state->domain = hs->domain;
    7493        state->opnum = opnum;
    75 
    76         push = ndr_push_init_ctx(state, NULL);
    77         if (tevent_req_nomem(push, req)) {
     94        state->in_data.data = discard_const_p(uint8_t, in_data);
     95        state->in_data.length = in_length;
     96
     97        ok = wbint_bh_is_connected(h);
     98        if (!ok) {
     99                tevent_req_nterror(req, NT_STATUS_INVALID_CONNECTION);
    78100                return tevent_req_post(req, ev);
    79101        }
    80102
    81         ndr_err = state->call->ndr_push(push, NDR_IN, r);
    82         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    83                 tevent_req_nterror(req, ndr_map_error2ntstatus(ndr_err));
    84                 TALLOC_FREE(push);
    85                 return tevent_req_post(req, ev);
    86         }
    87 
    88         state->req_blob = ndr_push_blob(push);
    89 
    90         if ((transport->domain != NULL)
    91             && wcache_fetch_ndr(state, transport->domain, opnum,
    92                                 &state->req_blob, &state->resp_blob)) {
     103        if ((state->domain != NULL)
     104            && wcache_fetch_ndr(state, state->domain, state->opnum,
     105                                &state->in_data, &state->out_data)) {
    93106                tevent_req_done(req);
    94107                return tevent_req_post(req, ev);
     
    96109
    97110        state->request.cmd = WINBINDD_DUAL_NDRCMD;
    98         state->request.data.ndrcmd = opnum;
    99         state->request.extra_data.data = (char *)state->req_blob.data;
    100         state->request.extra_len = state->req_blob.length;
    101 
    102         subreq = wb_child_request_send(state, ev, transport->child,
     111        state->request.data.ndrcmd = state->opnum;
     112        state->request.extra_data.data = (char *)state->in_data.data;
     113        state->request.extra_len = state->in_data.length;
     114
     115        subreq = wb_child_request_send(state, ev, hs->child,
    103116                                       &state->request);
    104117        if (tevent_req_nomem(subreq, req)) {
    105118                return tevent_req_post(req, ev);
    106119        }
    107         tevent_req_set_callback(subreq, wb_ndr_dispatch_done, req);
     120        tevent_req_set_callback(subreq, wbint_bh_raw_call_done, req);
     121
    108122        return req;
    109123}
    110124
    111 static void wb_ndr_dispatch_done(struct tevent_req *subreq)
    112 {
    113         struct tevent_req *req = tevent_req_callback_data(
    114                 subreq, struct tevent_req);
    115         struct wb_ndr_dispatch_state *state = tevent_req_data(
    116                 req, struct wb_ndr_dispatch_state);
     125static void wbint_bh_raw_call_done(struct tevent_req *subreq)
     126{
     127        struct tevent_req *req =
     128                tevent_req_callback_data(subreq,
     129                struct tevent_req);
     130        struct wbint_bh_raw_call_state *state =
     131                tevent_req_data(req,
     132                struct wbint_bh_raw_call_state);
    117133        int ret, err;
    118134
     
    120136        TALLOC_FREE(subreq);
    121137        if (ret == -1) {
    122                 tevent_req_nterror(req, map_nt_error_from_unix(err));
     138                NTSTATUS status = map_nt_error_from_unix(err);
     139                tevent_req_nterror(req, status);
    123140                return;
    124141        }
    125142
    126         state->resp_blob = data_blob_const(
     143        state->out_data = data_blob_talloc(state,
    127144                state->response->extra_data.data,
    128                 state->response->length - sizeof(struct winbindd_response));
    129 
    130         if (state->transport->domain != NULL) {
    131                 wcache_store_ndr(state->transport->domain, state->opnum,
    132                                  &state->req_blob, &state->resp_blob);
     145                state->response->length - sizeof(struct winbindd_response));
     146        if (state->response->extra_data.data && !state->out_data.data) {
     147                tevent_req_nomem(NULL, req);
     148                return;
     149        }
     150
     151        if (state->domain != NULL) {
     152                wcache_store_ndr(state->domain, state->opnum,
     153                                 &state->in_data, &state->out_data);
    133154        }
    134155
     
    136157}
    137158
    138 static NTSTATUS wb_ndr_dispatch_recv(struct tevent_req *req,
    139                                      TALLOC_CTX *mem_ctx)
    140 {
    141         struct wb_ndr_dispatch_state *state = tevent_req_data(
    142                 req, struct wb_ndr_dispatch_state);
     159static NTSTATUS wbint_bh_raw_call_recv(struct tevent_req *req,
     160                                        TALLOC_CTX *mem_ctx,
     161                                        uint8_t **out_data,
     162                                        size_t *out_length,
     163                                        uint32_t *out_flags)
     164{
     165        struct wbint_bh_raw_call_state *state =
     166                tevent_req_data(req,
     167                struct wbint_bh_raw_call_state);
    143168        NTSTATUS status;
    144         struct ndr_pull *pull;
    145         enum ndr_err_code ndr_err;
    146169
    147170        if (tevent_req_is_nterror(req, &status)) {
     171                tevent_req_received(req);
    148172                return status;
    149173        }
    150174
    151         pull = ndr_pull_init_blob(&state->resp_blob, mem_ctx, NULL);
    152         if (pull == NULL) {
    153                 return NT_STATUS_NO_MEMORY;
    154         }
    155 
    156         /* have the ndr parser alloc memory for us */
    157         pull->flags |= LIBNDR_FLAG_REF_ALLOC;
    158         ndr_err = state->call->ndr_pull(pull, NDR_OUT, state->r);
    159         TALLOC_FREE(pull);
    160 
    161         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    162                 return ndr_map_error2ntstatus(ndr_err);
    163         }
    164 
     175        *out_data = talloc_move(mem_ctx, &state->out_data.data);
     176        *out_length = state->out_data.length;
     177        *out_flags = 0;
     178        tevent_req_received(req);
    165179        return NT_STATUS_OK;
    166180}
    167181
    168 static NTSTATUS wb_ndr_dispatch(struct rpc_pipe_client *cli,
    169                                 TALLOC_CTX *mem_ctx,
    170                                 const struct ndr_interface_table *table,
    171                                 uint32_t opnum, void *r)
    172 {
    173         TALLOC_CTX *frame = talloc_stackframe();
    174         struct event_context *ev;
     182struct wbint_bh_disconnect_state {
     183        uint8_t _dummy;
     184};
     185
     186static struct tevent_req *wbint_bh_disconnect_send(TALLOC_CTX *mem_ctx,
     187                                                struct tevent_context *ev,
     188                                                struct dcerpc_binding_handle *h)
     189{
     190        struct wbint_bh_state *hs = dcerpc_binding_handle_data(h,
     191                                     struct wbint_bh_state);
    175192        struct tevent_req *req;
    176         NTSTATUS status = NT_STATUS_OK;
    177 
    178         ev = event_context_init(frame);
    179         if (ev == NULL) {
    180                 status = NT_STATUS_NO_MEMORY;
    181                 goto fail;
    182         }
    183 
    184         req = wb_ndr_dispatch_send(frame, ev, cli, table, opnum, r);
     193        struct wbint_bh_disconnect_state *state;
     194        bool ok;
     195
     196        req = tevent_req_create(mem_ctx, &state,
     197                                struct wbint_bh_disconnect_state);
    185198        if (req == NULL) {
    186                 status = NT_STATUS_NO_MEMORY;
    187                 goto fail;
    188         }
    189 
    190         if (!tevent_req_poll(req, ev)) {
    191                 status = map_nt_error_from_unix(errno);
    192                 goto fail;
    193         }
    194 
    195         status = wb_ndr_dispatch_recv(req, mem_ctx);
    196  fail:
    197         TALLOC_FREE(frame);
    198         return status;
    199 }
    200 
    201 struct rpc_pipe_client *wbint_rpccli_create(TALLOC_CTX *mem_ctx,
    202                                             struct winbindd_domain *domain,
    203                                             struct winbindd_child *child)
    204 {
    205         struct rpc_pipe_client *result;
    206         struct wb_ndr_transport_priv *transp;
    207 
    208         result = talloc(mem_ctx, struct rpc_pipe_client);
    209         if (result == NULL) {
    210199                return NULL;
    211200        }
    212         result->abstract_syntax = ndr_table_wbint.syntax_id;
    213         result->transfer_syntax = ndr_transfer_syntax;
    214         result->dispatch = wb_ndr_dispatch;
    215         result->dispatch_send = wb_ndr_dispatch_send;
    216         result->dispatch_recv = wb_ndr_dispatch_recv;
    217         result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
    218         result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
    219         result->desthost = NULL;
    220         result->srv_name_slash = NULL;
     201
     202        ok = wbint_bh_is_connected(h);
     203        if (!ok) {
     204                tevent_req_nterror(req, NT_STATUS_INVALID_CONNECTION);
     205                return tevent_req_post(req, ev);
     206        }
    221207
    222208        /*
    223          * Initialize a fake transport. Due to our own wb_ndr_dispatch
    224          * function we don't use all the fragmentation engine in
    225          * cli_pipe, which would use all the _read and _write
    226          * functions in rpc_cli_transport. But we need a place to
    227          * store the child struct in, and we're re-using
    228          * result->transport->priv for that.
     209         * TODO: do a real async disconnect ...
     210         *
     211         * For now the caller needs to free rpc_cli
    229212         */
    230 
    231         result->transport = talloc_zero(result, struct rpc_cli_transport);
    232         if (result->transport == NULL) {
    233                 TALLOC_FREE(result);
     213        hs->child = NULL;
     214
     215        tevent_req_done(req);
     216        return tevent_req_post(req, ev);
     217}
     218
     219static NTSTATUS wbint_bh_disconnect_recv(struct tevent_req *req)
     220{
     221        NTSTATUS status;
     222
     223        if (tevent_req_is_nterror(req, &status)) {
     224                tevent_req_received(req);
     225                return status;
     226        }
     227
     228        tevent_req_received(req);
     229        return NT_STATUS_OK;
     230}
     231
     232static bool wbint_bh_ref_alloc(struct dcerpc_binding_handle *h)
     233{
     234        return true;
     235}
     236
     237static void wbint_bh_do_ndr_print(struct dcerpc_binding_handle *h,
     238                                  int ndr_flags,
     239                                  const void *_struct_ptr,
     240                                  const struct ndr_interface_call *call)
     241{
     242        void *struct_ptr = discard_const(_struct_ptr);
     243
     244        if (DEBUGLEVEL < 10) {
     245                return;
     246        }
     247
     248        if (ndr_flags & NDR_IN) {
     249                ndr_print_function_debug(call->ndr_print,
     250                                         call->name,
     251                                         ndr_flags,
     252                                         struct_ptr);
     253        }
     254        if (ndr_flags & NDR_OUT) {
     255                ndr_print_function_debug(call->ndr_print,
     256                                         call->name,
     257                                         ndr_flags,
     258                                         struct_ptr);
     259        }
     260}
     261
     262static const struct dcerpc_binding_handle_ops wbint_bh_ops = {
     263        .name                   = "wbint",
     264        .is_connected           = wbint_bh_is_connected,
     265        .set_timeout            = wbint_bh_set_timeout,
     266        .raw_call_send          = wbint_bh_raw_call_send,
     267        .raw_call_recv          = wbint_bh_raw_call_recv,
     268        .disconnect_send        = wbint_bh_disconnect_send,
     269        .disconnect_recv        = wbint_bh_disconnect_recv,
     270
     271        .ref_alloc              = wbint_bh_ref_alloc,
     272        .do_ndr_print           = wbint_bh_do_ndr_print,
     273};
     274
     275/* initialise a wbint binding handle */
     276struct dcerpc_binding_handle *wbint_binding_handle(TALLOC_CTX *mem_ctx,
     277                                                struct winbindd_domain *domain,
     278                                                struct winbindd_child *child)
     279{
     280        struct dcerpc_binding_handle *h;
     281        struct wbint_bh_state *hs;
     282
     283        h = dcerpc_binding_handle_create(mem_ctx,
     284                                         &wbint_bh_ops,
     285                                         NULL,
     286                                         &ndr_table_wbint,
     287                                         &hs,
     288                                         struct wbint_bh_state,
     289                                         __location__);
     290        if (h == NULL) {
    234291                return NULL;
    235292        }
    236         transp = talloc(result->transport, struct wb_ndr_transport_priv);
    237         if (transp == NULL) {
    238                 TALLOC_FREE(result);
    239                 return NULL;
    240         }
    241         transp->domain = domain;
    242         transp->child = child;
    243         result->transport->priv = transp;
    244         return result;
     293        hs->domain = domain;
     294        hs->child = child;
     295
     296        return h;
    245297}
    246298
     
    248300                                          struct winbindd_cli_state *state)
    249301{
    250         pipes_struct p;
     302        struct pipes_struct p;
    251303        struct api_struct *fns;
    252304        int num_fns;
     
    265317        ZERO_STRUCT(p);
    266318        p.mem_ctx = talloc_stackframe();
    267         p.in_data.data.buffer_size = state->request->extra_len;
    268         p.in_data.data.data_p = state->request->extra_data.data;
    269         prs_init(&p.out_data.rdata, 0, state->mem_ctx, false);
     319        p.in_data.data = data_blob_const(state->request->extra_data.data,
     320                                         state->request->extra_len);
    270321
    271322        ret = fns[state->request->data.ndrcmd].fn(&p);
     323        if (!ret) {
     324                TALLOC_FREE(p.mem_ctx);
     325                return WINBINDD_ERROR;
     326        }
     327
     328        state->response->extra_data.data =
     329                talloc_move(state->mem_ctx, &p.out_data.rdata.data);
     330        state->response->length += p.out_data.rdata.length;
     331        p.out_data.rdata.length = 0;
     332
    272333        TALLOC_FREE(p.mem_ctx);
    273         if (!ret) {
    274                 return WINBINDD_ERROR;
    275         }
    276 
    277         state->response->extra_data.data =
    278                 talloc_memdup(state->mem_ctx, p.out_data.rdata.data_p,
    279                               p.out_data.rdata.data_offset);
    280         state->response->length += p.out_data.rdata.data_offset;
    281         prs_mem_free(&p.out_data.rdata);
     334
    282335        if (state->response->extra_data.data == NULL) {
    283336                return WINBINDD_ERROR;
     
    285338        return WINBINDD_OK;
    286339}
    287 
    288 /*
    289  * Just a dummy to make srv_wbint.c happy
    290  */
    291 NTSTATUS rpc_srv_register(int version, const char *clnt, const char *srv,
    292                           const struct ndr_interface_table *iface,
    293                           const struct api_struct *cmds, int size)
    294 {
    295         return NT_STATUS_OK;
    296 }
  • vendor/current/source3/winbindd/winbindd_dual_srv.c

    r618 r740  
    2424#include "winbindd/winbindd.h"
    2525#include "winbindd/winbindd_proto.h"
     26#include "rpc_client/cli_pipe.h"
     27#include "ntdomain.h"
    2628#include "librpc/gen_ndr/srv_wbint.h"
    27 #include "../librpc/gen_ndr/cli_netlogon.h"
    28 
    29 void _wbint_Ping(pipes_struct *p, struct wbint_Ping *r)
     29#include "../librpc/gen_ndr/ndr_netlogon_c.h"
     30#include "idmap.h"
     31#include "../libcli/security/security.h"
     32
     33void _wbint_Ping(struct pipes_struct *p, struct wbint_Ping *r)
    3034{
    3135        *r->out.out_data = r->in.in_data;
    3236}
    3337
    34 NTSTATUS _wbint_LookupSid(pipes_struct *p, struct wbint_LookupSid *r)
     38static bool reset_cm_connection_on_error(struct winbindd_domain *domain,
     39                                        NTSTATUS status)
     40{
     41        if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
     42                invalidate_cm_connection(&domain->conn);
     43                /* We invalidated the connection. */
     44                return true;
     45        }
     46        return false;
     47}
     48
     49NTSTATUS _wbint_LookupSid(struct pipes_struct *p, struct wbint_LookupSid *r)
    3550{
    3651        struct winbindd_domain *domain = wb_child_domain();
     
    4661        status = domain->methods->sid_to_name(domain, p->mem_ctx, r->in.sid,
    4762                                              &dom_name, &name, &type);
     63        reset_cm_connection_on_error(domain, status);
    4864        if (!NT_STATUS_IS_OK(status)) {
    4965                return status;
     
    5672}
    5773
    58 NTSTATUS _wbint_LookupName(pipes_struct *p, struct wbint_LookupName *r)
    59 {
    60         struct winbindd_domain *domain = wb_child_domain();
    61 
    62         if (domain == NULL) {
    63                 return NT_STATUS_REQUEST_NOT_ACCEPTED;
    64         }
    65 
    66         return domain->methods->name_to_sid(
     74NTSTATUS _wbint_LookupSids(struct pipes_struct *p, struct wbint_LookupSids *r)
     75{
     76        struct winbindd_domain *domain = wb_child_domain();
     77        NTSTATUS status;
     78
     79        if (domain == NULL) {
     80                return NT_STATUS_REQUEST_NOT_ACCEPTED;
     81        }
     82
     83        /*
     84         * This breaks the winbindd_domain->methods abstraction: This
     85         * is only called for remote domains, and both winbindd_msrpc
     86         * and winbindd_ad call into lsa_lookupsids anyway. Caching is
     87         * done at the wbint RPC layer.
     88         */
     89        status = rpc_lookup_sids(p->mem_ctx, domain, r->in.sids,
     90                                 &r->out.domains, &r->out.names);
     91        reset_cm_connection_on_error(domain, status);
     92        return status;
     93}
     94
     95NTSTATUS _wbint_LookupName(struct pipes_struct *p, struct wbint_LookupName *r)
     96{
     97        struct winbindd_domain *domain = wb_child_domain();
     98        NTSTATUS status;
     99
     100        if (domain == NULL) {
     101                return NT_STATUS_REQUEST_NOT_ACCEPTED;
     102        }
     103
     104        status = domain->methods->name_to_sid(
    67105                domain, p->mem_ctx, r->in.domain, r->in.name, r->in.flags,
    68106                r->out.sid, r->out.type);
    69 }
    70 
    71 NTSTATUS _wbint_Sid2Uid(pipes_struct *p, struct wbint_Sid2Uid *r)
     107        reset_cm_connection_on_error(domain, status);
     108        return status;
     109}
     110
     111NTSTATUS _wbint_Sid2Uid(struct pipes_struct *p, struct wbint_Sid2Uid *r)
    72112{
    73113        uid_t uid;
     
    83123}
    84124
    85 NTSTATUS _wbint_Sid2Gid(pipes_struct *p, struct wbint_Sid2Gid *r)
     125NTSTATUS _wbint_Sid2Gid(struct pipes_struct *p, struct wbint_Sid2Gid *r)
    86126{
    87127        gid_t gid;
     
    97137}
    98138
    99 NTSTATUS _wbint_Uid2Sid(pipes_struct *p, struct wbint_Uid2Sid *r)
     139NTSTATUS _wbint_Sids2UnixIDs(struct pipes_struct *p,
     140                             struct wbint_Sids2UnixIDs *r)
     141{
     142        uint32_t i, j;
     143        struct id_map *ids = NULL;
     144        struct id_map **id_ptrs = NULL;
     145        struct dom_sid *sids = NULL;
     146        uint32_t *id_idx = NULL;
     147        NTSTATUS status = NT_STATUS_NO_MEMORY;
     148
     149        for (i=0; i<r->in.domains->count; i++) {
     150                struct lsa_DomainInfo *d = &r->in.domains->domains[i];
     151                struct idmap_domain *dom;
     152                uint32_t num_ids;
     153
     154                dom = idmap_find_domain(d->name.string);
     155                if (dom == NULL) {
     156                        DEBUG(10, ("idmap domain %s not found\n",
     157                                   d->name.string));
     158                        continue;
     159                }
     160
     161                num_ids = 0;
     162
     163                for (j=0; j<r->in.ids->num_ids; j++) {
     164                        if (r->in.ids->ids[j].domain_index == i) {
     165                                num_ids += 1;
     166                        }
     167                }
     168
     169                ids = TALLOC_REALLOC_ARRAY(talloc_tos(), ids,
     170                                           struct id_map, num_ids);
     171                if (ids == NULL) {
     172                        goto nomem;
     173                }
     174                id_ptrs = TALLOC_REALLOC_ARRAY(talloc_tos(), id_ptrs,
     175                                               struct id_map *, num_ids+1);
     176                if (id_ptrs == NULL) {
     177                        goto nomem;
     178                }
     179                id_idx = TALLOC_REALLOC_ARRAY(talloc_tos(), id_idx,
     180                                              uint32_t, num_ids);
     181                if (id_idx == NULL) {
     182                        goto nomem;
     183                }
     184                sids = TALLOC_REALLOC_ARRAY(talloc_tos(), sids,
     185                                            struct dom_sid, num_ids);
     186                if (sids == NULL) {
     187                        goto nomem;
     188                }
     189
     190                num_ids = 0;
     191
     192                for (j=0; j<r->in.ids->num_ids; j++) {
     193                        struct wbint_TransID *id = &r->in.ids->ids[j];
     194
     195                        if (id->domain_index != i) {
     196                                continue;
     197                        }
     198                        id_idx[num_ids] = j;
     199                        id_ptrs[num_ids] = &ids[num_ids];
     200
     201                        ids[num_ids].sid = &sids[num_ids];
     202                        sid_compose(ids[num_ids].sid, d->sid, id->rid);
     203                        ids[num_ids].xid.type = id->type;
     204                        ids[num_ids].status = ID_UNKNOWN;
     205                        num_ids += 1;
     206                }
     207                id_ptrs[num_ids] = NULL;
     208
     209                status = dom->methods->sids_to_unixids(dom, id_ptrs);
     210                DEBUG(10, ("sids_to_unixids returned %s\n",
     211                           nt_errstr(status)));
     212
     213                for (j=0; j<num_ids; j++) {
     214                        struct wbint_TransID *id = &r->in.ids->ids[id_idx[j]];
     215
     216                        if (ids[j].status != ID_MAPPED) {
     217                                continue;
     218                        }
     219                        id->unix_id = ids[j].xid.id;
     220                }
     221        }
     222        status = NT_STATUS_OK;
     223nomem:
     224        TALLOC_FREE(ids);
     225        TALLOC_FREE(id_ptrs);
     226        TALLOC_FREE(id_idx);
     227        TALLOC_FREE(sids);
     228        return status;
     229}
     230
     231NTSTATUS _wbint_Uid2Sid(struct pipes_struct *p, struct wbint_Uid2Sid *r)
    100232{
    101233        return idmap_uid_to_sid(r->in.dom_name ? r->in.dom_name : "",
     
    103235}
    104236
    105 NTSTATUS _wbint_Gid2Sid(pipes_struct *p, struct wbint_Gid2Sid *r)
     237NTSTATUS _wbint_Gid2Sid(struct pipes_struct *p, struct wbint_Gid2Sid *r)
    106238{
    107239        return idmap_gid_to_sid(r->in.dom_name ? r->in.dom_name : "",
     
    109241}
    110242
    111 NTSTATUS _wbint_AllocateUid(pipes_struct *p, struct wbint_AllocateUid *r)
     243NTSTATUS _wbint_AllocateUid(struct pipes_struct *p, struct wbint_AllocateUid *r)
    112244{
    113245        struct unixid xid;
     
    122254}
    123255
    124 NTSTATUS _wbint_AllocateGid(pipes_struct *p, struct wbint_AllocateGid *r)
     256NTSTATUS _wbint_AllocateGid(struct pipes_struct *p, struct wbint_AllocateGid *r)
    125257{
    126258        struct unixid xid;
     
    135267}
    136268
    137 NTSTATUS _wbint_QueryUser(pipes_struct *p, struct wbint_QueryUser *r)
    138 {
    139         struct winbindd_domain *domain = wb_child_domain();
    140 
    141         if (domain == NULL) {
    142                 return NT_STATUS_REQUEST_NOT_ACCEPTED;
    143         }
    144 
    145         return domain->methods->query_user(domain, p->mem_ctx, r->in.sid,
    146                                            r->out.info);
    147 }
    148 
    149 NTSTATUS _wbint_LookupUserAliases(pipes_struct *p,
     269NTSTATUS _wbint_QueryUser(struct pipes_struct *p, struct wbint_QueryUser *r)
     270{
     271        struct winbindd_domain *domain = wb_child_domain();
     272        NTSTATUS status;
     273
     274        if (domain == NULL) {
     275                return NT_STATUS_REQUEST_NOT_ACCEPTED;
     276        }
     277
     278        status = domain->methods->query_user(domain, p->mem_ctx, r->in.sid,
     279                                             r->out.info);
     280        reset_cm_connection_on_error(domain, status);
     281        return status;
     282}
     283
     284NTSTATUS _wbint_LookupUserAliases(struct pipes_struct *p,
    150285                                  struct wbint_LookupUserAliases *r)
    151286{
    152287        struct winbindd_domain *domain = wb_child_domain();
    153 
    154         if (domain == NULL) {
    155                 return NT_STATUS_REQUEST_NOT_ACCEPTED;
    156         }
    157 
    158         return domain->methods->lookup_useraliases(
     288        NTSTATUS status;
     289
     290        if (domain == NULL) {
     291                return NT_STATUS_REQUEST_NOT_ACCEPTED;
     292        }
     293
     294        status = domain->methods->lookup_useraliases(
    159295                domain, p->mem_ctx, r->in.sids->num_sids, r->in.sids->sids,
    160296                &r->out.rids->num_rids, &r->out.rids->rids);
    161 }
    162 
    163 NTSTATUS _wbint_LookupUserGroups(pipes_struct *p,
     297        reset_cm_connection_on_error(domain, status);
     298        return status;
     299}
     300
     301NTSTATUS _wbint_LookupUserGroups(struct pipes_struct *p,
    164302                                 struct wbint_LookupUserGroups *r)
    165303{
    166304        struct winbindd_domain *domain = wb_child_domain();
    167 
    168         if (domain == NULL) {
    169                 return NT_STATUS_REQUEST_NOT_ACCEPTED;
    170         }
    171 
    172         return domain->methods->lookup_usergroups(
     305        NTSTATUS status;
     306
     307        if (domain == NULL) {
     308                return NT_STATUS_REQUEST_NOT_ACCEPTED;
     309        }
     310
     311        status = domain->methods->lookup_usergroups(
    173312                domain, p->mem_ctx, r->in.sid,
    174313                &r->out.sids->num_sids, &r->out.sids->sids);
    175 }
    176 
    177 NTSTATUS _wbint_QuerySequenceNumber(pipes_struct *p,
     314        reset_cm_connection_on_error(domain, status);
     315        return status;
     316}
     317
     318NTSTATUS _wbint_QuerySequenceNumber(struct pipes_struct *p,
    178319                                    struct wbint_QuerySequenceNumber *r)
    179320{
    180321        struct winbindd_domain *domain = wb_child_domain();
    181 
    182         if (domain == NULL) {
    183                 return NT_STATUS_REQUEST_NOT_ACCEPTED;
    184         }
    185 
    186         return domain->methods->sequence_number(domain, r->out.sequence);
    187 }
    188 
    189 NTSTATUS _wbint_LookupGroupMembers(pipes_struct *p,
     322        NTSTATUS status;
     323
     324        if (domain == NULL) {
     325                return NT_STATUS_REQUEST_NOT_ACCEPTED;
     326        }
     327
     328        status = domain->methods->sequence_number(domain, r->out.sequence);
     329        reset_cm_connection_on_error(domain, status);
     330        return status;
     331}
     332
     333NTSTATUS _wbint_LookupGroupMembers(struct pipes_struct *p,
    190334                                   struct wbint_LookupGroupMembers *r)
    191335{
     
    204348                domain, p->mem_ctx, r->in.sid, r->in.type,
    205349                &num_names, &sid_mem, &names, &name_types);
     350        reset_cm_connection_on_error(domain, status);
    206351        if (!NT_STATUS_IS_OK(status)) {
    207352                return status;
     
    225370}
    226371
    227 NTSTATUS _wbint_QueryUserList(pipes_struct *p, struct wbint_QueryUserList *r)
    228 {
    229         struct winbindd_domain *domain = wb_child_domain();
    230 
    231         if (domain == NULL) {
    232                 return NT_STATUS_REQUEST_NOT_ACCEPTED;
    233         }
    234 
    235         return domain->methods->query_user_list(
     372NTSTATUS _wbint_QueryUserList(struct pipes_struct *p,
     373                              struct wbint_QueryUserList *r)
     374{
     375        struct winbindd_domain *domain = wb_child_domain();
     376        NTSTATUS status;
     377
     378        if (domain == NULL) {
     379                return NT_STATUS_REQUEST_NOT_ACCEPTED;
     380        }
     381
     382        status = domain->methods->query_user_list(
    236383                domain, p->mem_ctx, &r->out.users->num_userinfos,
    237384                &r->out.users->userinfos);
    238 }
    239 
    240 NTSTATUS _wbint_QueryGroupList(pipes_struct *p, struct wbint_QueryGroupList *r)
     385        reset_cm_connection_on_error(domain, status);
     386        return status;
     387}
     388
     389NTSTATUS _wbint_QueryGroupList(struct pipes_struct *p,
     390                               struct wbint_QueryGroupList *r)
    241391{
    242392        struct winbindd_domain *domain = wb_child_domain();
    243393        uint32_t i, num_groups;
    244         struct acct_info *groups;
     394        struct wb_acct_info *groups;
    245395        struct wbint_Principal *result;
    246396        NTSTATUS status;
     
    252402        status = domain->methods->enum_dom_groups(domain, talloc_tos(),
    253403                                                  &num_groups, &groups);
     404        reset_cm_connection_on_error(domain, status);
    254405        if (!NT_STATUS_IS_OK(status)) {
    255406                return status;
     
    275426        r->out.groups->num_principals = num_groups;
    276427        r->out.groups->principals = result;
    277         return NT_STATUS_OK;
    278 }
    279 
    280 NTSTATUS _wbint_DsGetDcName(pipes_struct *p, struct wbint_DsGetDcName *r)
     428
     429        TALLOC_FREE(groups);
     430        return NT_STATUS_OK;
     431}
     432
     433NTSTATUS _wbint_DsGetDcName(struct pipes_struct *p, struct wbint_DsGetDcName *r)
    281434{
    282435        struct winbindd_domain *domain = wb_child_domain();
     
    286439        WERROR werr;
    287440        unsigned int orig_timeout;
     441        struct dcerpc_binding_handle *b;
    288442
    289443        if (domain == NULL) {
     
    297451        status = cm_connect_netlogon(domain, &netlogon_pipe);
    298452
     453        reset_cm_connection_on_error(domain, status);
    299454        if (!NT_STATUS_IS_OK(status)) {
    300455                DEBUG(10, ("Can't contact the NETLOGON pipe\n"));
    301456                return status;
    302457        }
     458
     459        b = netlogon_pipe->binding_handle;
    303460
    304461        /* This call can take a long time - allow the server to time out.
     
    308465
    309466        if (domain->active_directory) {
    310                 status = rpccli_netr_DsRGetDCName(
    311                         netlogon_pipe, p->mem_ctx, domain->dcname,
     467                status = dcerpc_netr_DsRGetDCName(b,
     468                        p->mem_ctx, domain->dcname,
    312469                        r->in.domain_name, NULL, r->in.domain_guid,
    313470                        r->in.flags, r->out.dc_info, &werr);
     
    315472                        goto done;
    316473                }
     474                if (reset_cm_connection_on_error(domain, status)) {
     475                        /* Re-initialize. */
     476                        status = cm_connect_netlogon(domain, &netlogon_pipe);
     477
     478                        reset_cm_connection_on_error(domain, status);
     479                        if (!NT_STATUS_IS_OK(status)) {
     480                                DEBUG(10, ("Can't contact the NETLOGON pipe\n"));
     481                                return status;
     482                        }
     483
     484                        b = netlogon_pipe->binding_handle;
     485
     486                        /* This call can take a long time - allow the server to time out.
     487                           35 seconds should do it. */
     488
     489                        orig_timeout = rpccli_set_timeout(netlogon_pipe, 35000);
     490                }
    317491        }
    318492
     
    328502
    329503        if (r->in.flags & DS_PDC_REQUIRED) {
    330                 status = rpccli_netr_GetDcName(
    331                         netlogon_pipe, p->mem_ctx, domain->dcname,
     504                status = dcerpc_netr_GetDcName(b,
     505                        p->mem_ctx, domain->dcname,
    332506                        r->in.domain_name, &dc_info->dc_unc, &werr);
    333507        } else {
    334                 status = rpccli_netr_GetAnyDCName(
    335                         netlogon_pipe, p->mem_ctx, domain->dcname,
     508                status = dcerpc_netr_GetAnyDCName(b,
     509                        p->mem_ctx, domain->dcname,
    336510                        r->in.domain_name, &dc_info->dc_unc, &werr);
    337511        }
    338512
    339         if (!NT_STATUS_IS_OK(status)) {
    340                 DEBUG(10, ("rpccli_netr_Get[Any]DCName failed: %s\n",
     513        reset_cm_connection_on_error(domain, status);
     514        if (!NT_STATUS_IS_OK(status)) {
     515                DEBUG(10, ("dcerpc_netr_Get[Any]DCName failed: %s\n",
    341516                           nt_errstr(status)));
    342517                goto done;
    343518        }
    344519        if (!W_ERROR_IS_OK(werr)) {
    345                 DEBUG(10, ("rpccli_netr_Get[Any]DCName failed: %s\n",
     520                DEBUG(10, ("dcerpc_netr_Get[Any]DCName failed: %s\n",
    346521                           win_errstr(werr)));
    347522                status = werror_to_ntstatus(werr);
     
    359534}
    360535
    361 NTSTATUS _wbint_LookupRids(pipes_struct *p, struct wbint_LookupRids *r)
     536NTSTATUS _wbint_LookupRids(struct pipes_struct *p, struct wbint_LookupRids *r)
    362537{
    363538        struct winbindd_domain *domain = wb_child_domain();
     
    376551                domain, talloc_tos(), r->in.domain_sid, r->in.rids->rids,
    377552                r->in.rids->num_rids, &domain_name, &names, &types);
     553        reset_cm_connection_on_error(domain, status);
    378554        if (!NT_STATUS_IS_OK(status)) {
    379555                return status;
     
    402578}
    403579
    404 NTSTATUS _wbint_CheckMachineAccount(pipes_struct *p,
     580NTSTATUS _wbint_CheckMachineAccount(struct pipes_struct *p,
    405581                                    struct wbint_CheckMachineAccount *r)
    406582{
     
    454630}
    455631
    456 NTSTATUS _wbint_ChangeMachineAccount(pipes_struct *p,
     632NTSTATUS _wbint_ChangeMachineAccount(struct pipes_struct *p,
    457633                                     struct wbint_ChangeMachineAccount *r)
    458634{
     
    514690}
    515691
    516 NTSTATUS _wbint_PingDc(pipes_struct *p, struct wbint_PingDc *r)
     692NTSTATUS _wbint_PingDc(struct pipes_struct *p, struct wbint_PingDc *r)
    517693{
    518694        NTSTATUS status;
     
    522698        WERROR werr;
    523699        fstring logon_server;
     700        struct dcerpc_binding_handle *b;
    524701
    525702        domain = wb_child_domain();
     
    529706
    530707        status = cm_connect_netlogon(domain, &netlogon_pipe);
     708        reset_cm_connection_on_error(domain, status);
    531709        if (!NT_STATUS_IS_OK(status)) {
    532710                DEBUG(3, ("could not open handle to NETLOGON pipe\n"));
    533711                return status;
    534712        }
     713
     714        b = netlogon_pipe->binding_handle;
    535715
    536716        fstr_sprintf(logon_server, "\\\\%s", domain->dcname);
     
    542722         * netlogon pipe works.
    543723         */
    544         status = rpccli_netr_LogonControl(netlogon_pipe, p->mem_ctx,
     724        status = dcerpc_netr_LogonControl(b, p->mem_ctx,
    545725                                          logon_server, NETLOGON_CONTROL_QUERY,
    546726                                          2, &info, &werr);
    547727
    548         if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
    549                 DEBUG(2, ("rpccli_netr_LogonControl timed out\n"));
    550                 invalidate_cm_connection(&domain->conn);
    551                 return status;
    552         }
    553 
    554         if (!NT_STATUS_EQUAL(status, NT_STATUS_CTL_FILE_NOT_SUPPORTED)) {
    555                 DEBUG(2, ("rpccli_netr_LogonControl returned %s, expected "
    556                           "NT_STATUS_CTL_FILE_NOT_SUPPORTED\n",
    557                           nt_errstr(status)));
    558                 return status;
     728        reset_cm_connection_on_error(domain, status);
     729        if (!NT_STATUS_IS_OK(status)) {
     730                DEBUG(2, ("dcerpc_netr_LogonControl failed: %s\n",
     731                        nt_errstr(status)));
     732                return status;
     733        }
     734
     735        if (!W_ERROR_EQUAL(werr, WERR_NOT_SUPPORTED)) {
     736                DEBUG(2, ("dcerpc_netr_LogonControl returned %s, expected "
     737                          "WERR_NOT_SUPPORTED\n",
     738                          win_errstr(werr)));
     739                return werror_to_ntstatus(werr);
    559740        }
    560741
     
    562743        return NT_STATUS_OK;
    563744}
    564 
    565 NTSTATUS _wbint_SetMapping(pipes_struct *p, struct wbint_SetMapping *r)
    566 {
    567         struct id_map map;
    568 
    569         map.sid = r->in.sid;
    570         map.xid.id = r->in.id;
    571         map.status = ID_MAPPED;
    572 
    573         switch (r->in.type) {
    574         case WBINT_ID_TYPE_UID:
    575                 map.xid.type = ID_TYPE_UID;
    576                 break;
    577         case WBINT_ID_TYPE_GID:
    578                 map.xid.type = ID_TYPE_GID;
    579                 break;
    580         default:
    581                 return NT_STATUS_INVALID_PARAMETER;
    582         }
    583 
    584         return idmap_set_mapping(&map);
    585 }
    586 
    587 NTSTATUS _wbint_RemoveMapping(pipes_struct *p, struct wbint_RemoveMapping *r)
    588 {
    589         struct id_map map;
    590 
    591         map.sid = r->in.sid;
    592         map.xid.id = r->in.id;
    593         map.status = ID_MAPPED;
    594 
    595         switch (r->in.type) {
    596         case WBINT_ID_TYPE_UID:
    597                 map.xid.type = ID_TYPE_UID;
    598                 break;
    599         case WBINT_ID_TYPE_GID:
    600                 map.xid.type = ID_TYPE_GID;
    601                 break;
    602         default:
    603                 return NT_STATUS_INVALID_PARAMETER;
    604         }
    605 
    606         return idmap_remove_mapping(&map);
    607 }
    608 
    609 NTSTATUS _wbint_SetHWM(pipes_struct *p, struct wbint_SetHWM *r)
    610 {
    611         struct unixid id;
    612         NTSTATUS status;
    613 
    614         id.id = r->in.id;
    615 
    616         switch (r->in.type) {
    617         case WBINT_ID_TYPE_UID:
    618                 id.type = ID_TYPE_UID;
    619                 status = idmap_set_uid_hwm(&id);
    620                 break;
    621         case WBINT_ID_TYPE_GID:
    622                 id.type = ID_TYPE_GID;
    623                 status = idmap_set_gid_hwm(&id);
    624                 break;
    625         default:
    626                 status = NT_STATUS_INVALID_PARAMETER;
    627                 break;
    628         }
    629         return status;
    630 }
  • vendor/current/source3/winbindd/winbindd_getdcname.c

    r414 r740  
    2020#include "includes.h"
    2121#include "winbindd.h"
    22 #include "librpc/gen_ndr/cli_wbint.h"
     22#include "librpc/gen_ndr/ndr_wbint_c.h"
    2323
    2424struct winbindd_getdcname_state {
     
    6666        status = wb_dsgetdcname_recv(subreq, state, &state->dcinfo);
    6767        TALLOC_FREE(subreq);
    68         if (!NT_STATUS_IS_OK(status)) {
    69                 tevent_req_nterror(req, status);
     68        if (tevent_req_nterror(req, status)) {
    7069                return;
    7170        }
  • vendor/current/source3/winbindd/winbindd_getgrgid.c

    r414 r740  
    6969        status = wb_gid2sid_recv(subreq, &state->sid);
    7070        TALLOC_FREE(subreq);
    71         if (!NT_STATUS_IS_OK(status)) {
    72                 tevent_req_nterror(req, status);
     71        if (tevent_req_nterror(req, status)) {
    7372                return;
    7473        }
     
    9392                                  &state->gid, &state->members);
    9493        TALLOC_FREE(subreq);
    95         if (!NT_STATUS_IS_OK(status)) {
    96                 tevent_req_nterror(req, status);
     94        if (tevent_req_nterror(req, status)) {
    9795                return;
    9896        }
  • vendor/current/source3/winbindd/winbindd_getgrnam.c

    r414 r740  
    9898        status = wb_lookupname_recv(subreq, &state->sid, &type);
    9999        TALLOC_FREE(subreq);
    100         if (!NT_STATUS_IS_OK(status)) {
    101                 tevent_req_nterror(req, status);
     100        if (tevent_req_nterror(req, status)) {
    102101                return;
    103102        }
     
    128127                                  &state->gid, &state->members);
    129128        TALLOC_FREE(subreq);
    130         if (!NT_STATUS_IS_OK(status)) {
    131                 tevent_req_nterror(req, status);
     129        if (tevent_req_nterror(req, status)) {
    132130                return;
    133131        }
  • vendor/current/source3/winbindd/winbindd_getgroups.c

    r414 r740  
    2020#include "includes.h"
    2121#include "winbindd.h"
     22#include "passdb/lookup_sid.h" /* only for LOOKUP_NAME_NO_NSS flag */
    2223
    2324struct winbindd_getgroups_state {
     
    9697        status = wb_lookupname_recv(subreq, &state->sid, &state->type);
    9798        TALLOC_FREE(subreq);
    98         if (!NT_STATUS_IS_OK(status)) {
    99                 tevent_req_nterror(req, status);
     99        if (tevent_req_nterror(req, status)) {
    100100                return;
    101101        }
     
    119119                                  &state->sids);
    120120        TALLOC_FREE(subreq);
    121         if (!NT_STATUS_IS_OK(status)) {
    122                 tevent_req_nterror(req, status);
     121        if (tevent_req_nterror(req, status)) {
    123122                return;
    124123        }
  • vendor/current/source3/winbindd/winbindd_getpwent.c

    r414 r740  
    9898                return;
    9999        }
    100         if (!NT_STATUS_IS_OK(status)) {
    101                 tevent_req_nterror(req, status);
     100        if (tevent_req_nterror(req, status)) {
    102101                return;
    103102        }
  • vendor/current/source3/winbindd/winbindd_getpwnam.c

    r414 r740  
    2020#include "includes.h"
    2121#include "winbindd.h"
     22#include "passdb/lookup_sid.h" /* only for LOOKUP_NAME_NO_NSS flag */
    2223
    2324struct winbindd_getpwnam_state {
     
    100101        status = wb_lookupname_recv(subreq, &state->sid, &state->type);
    101102        TALLOC_FREE(subreq);
    102         if (!NT_STATUS_IS_OK(status)) {
    103                 tevent_req_nterror(req, status);
     103        if (tevent_req_nterror(req, status)) {
    104104                return;
    105105        }
     
    120120        status = wb_getpwsid_recv(subreq);
    121121        TALLOC_FREE(subreq);
    122         if (!NT_STATUS_IS_OK(status)) {
    123                 tevent_req_nterror(req, status);
     122        if (tevent_req_nterror(req, status)) {
    124123                return;
    125124        }
  • vendor/current/source3/winbindd/winbindd_getpwsid.c

    r414 r740  
    2020#include "includes.h"
    2121#include "winbindd.h"
     22#include "../libcli/security/security.h"
    2223
    2324struct winbindd_getpwsid_state {
     
    7071        status = wb_getpwsid_recv(subreq);
    7172        TALLOC_FREE(subreq);
    72         if (!NT_STATUS_IS_OK(status)) {
    73                 tevent_req_nterror(req, status);
     73        if (tevent_req_nterror(req, status)) {
    7474                return;
    7575        }
  • vendor/current/source3/winbindd/winbindd_getpwuid.c

    r414 r740  
    6666        status = wb_uid2sid_recv(subreq, &state->sid);
    6767        TALLOC_FREE(subreq);
    68         if (!NT_STATUS_IS_OK(status)) {
    69                 tevent_req_nterror(req, status);
     68        if (tevent_req_nterror(req, status)) {
    7069                return;
    7170        }
     
    8685        status = wb_getpwsid_recv(subreq);
    8786        TALLOC_FREE(subreq);
    88         if (!NT_STATUS_IS_OK(status)) {
    89                 tevent_req_nterror(req, status);
     87        if (tevent_req_nterror(req, status)) {
    9088                return;
    9189        }
  • vendor/current/source3/winbindd/winbindd_getsidaliases.c

    r414 r740  
    2020#include "includes.h"
    2121#include "winbindd.h"
     22#include "../libcli/security/security.h"
    2223
    2324struct winbindd_getsidaliases_state {
     
    3738        struct winbindd_getsidaliases_state *state;
    3839        struct winbindd_domain *domain;
    39         size_t num_sids;
     40        uint32_t num_sids;
    4041        struct dom_sid *sids;
    4142
     
    6970        sids = NULL;
    7071
    71         if ((request->extra_data.data != NULL)
    72             && !parse_sidlist(state, request->extra_data.data,
    73                               &sids, &num_sids)) {
    74                 DEBUG(1, ("Could not parse SID list: %s\n",
    75                           request->extra_data.data));
    76                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
    77                 return tevent_req_post(req, ev);
     72        if (request->extra_data.data != NULL) {
     73                if (request->extra_data.data[request->extra_len-1] != '\0') {
     74                        DEBUG(1, ("Got non-NULL terminated sidlist\n"));
     75                        tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
     76                        return tevent_req_post(req, ev);
     77                }
     78                if (!parse_sidlist(state, request->extra_data.data,
     79                                   &sids, &num_sids)) {
     80                        DEBUG(1, ("Could not parse SID list: %s\n",
     81                                  request->extra_data.data));
     82                        tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
     83                        return tevent_req_post(req, ev);
     84                }
     85        }
     86
     87        if (DEBUGLEVEL >= 10) {
     88                size_t i;
     89                for (i=0; i<num_sids; i++) {
     90                        fstring sidstr;
     91                        sid_to_fstring(sidstr, &sids[i]);
     92                        DEBUGADD(10, ("%s\n", sidstr));
     93                }
    7894        }
    7995
     
    97113                                           &state->aliases);
    98114        TALLOC_FREE(subreq);
    99         if (!NT_STATUS_IS_OK(status)) {
    100                 tevent_req_nterror(req, status);
     115        if (tevent_req_nterror(req, status)) {
    101116                return;
    102117        }
  • vendor/current/source3/winbindd/winbindd_getuserdomgroups.c

    r414 r740  
    2020#include "includes.h"
    2121#include "winbindd.h"
     22#include "../libcli/security/security.h"
    2223
    2324struct winbindd_getuserdomgroups_state {
     
    8384                                          &state->sids);
    8485        TALLOC_FREE(subreq);
    85         if (!NT_STATUS_IS_OK(status)) {
    86                 tevent_req_nterror(req, status);
     86        if (tevent_req_nterror(req, status)) {
    8787                return;
    8888        }
  • vendor/current/source3/winbindd/winbindd_getusersids.c

    r414 r740  
    2020#include "includes.h"
    2121#include "winbindd.h"
     22#include "../libcli/security/security.h"
    2223
    2324struct winbindd_getusersids_state {
     
    7475                                  &state->sids);
    7576        TALLOC_FREE(subreq);
    76         if (!NT_STATUS_IS_OK(status)) {
    77                 tevent_req_nterror(req, status);
     77        if (tevent_req_nterror(req, status)) {
    7878                return;
    7979        }
  • vendor/current/source3/winbindd/winbindd_gid_to_sid.c

    r414 r740  
    6464        status = wb_gid2sid_recv(subreq, &state->sid);
    6565        TALLOC_FREE(subreq);
    66         if (!NT_STATUS_IS_OK(status)) {
    67                 tevent_req_nterror(req, status);
     66        if (tevent_req_nterror(req, status)) {
    6867                return;
    6968        }
  • vendor/current/source3/winbindd/winbindd_list_groups.c

    r414 r740  
    2020#include "includes.h"
    2121#include "winbindd.h"
    22 #include "librpc/gen_ndr/cli_wbint.h"
     22#include "librpc/gen_ndr/ndr_wbint_c.h"
    2323
    2424struct winbindd_list_groups_domstate {
     
    9191                struct winbindd_list_groups_domstate *d = &state->domains[i];
    9292
    93                 d->subreq = rpccli_wbint_QueryGroupList_send(
    94                         state->domains, ev, d->domain->child.rpccli,
     93                d->subreq = dcerpc_wbint_QueryGroupList_send(
     94                        state->domains, ev, dom_child_handle(d->domain),
    9595                        &d->groups);
    9696                if (tevent_req_nomem(d->subreq, req)) {
     
    114114        int i;
    115115
    116         status = rpccli_wbint_QueryGroupList_recv(subreq, state->domains,
     116        status = dcerpc_wbint_QueryGroupList_recv(subreq, state->domains,
    117117                                                  &result);
    118118
     
    125125                struct winbindd_list_groups_domstate *d = &state->domains[i];
    126126
    127                 DEBUG(10, ("Domain %s returned %d users\n", d->domain->name,
     127                DEBUG(10, ("Domain %s returned %d groups\n", d->domain->name,
    128128                           d->groups.num_principals));
    129129
     
    154154        char *result;
    155155        int i;
    156         uint32_t j;
     156        uint32_t j, num_entries = 0;
    157157        size_t len;
    158158
     
    162162
    163163        len = 0;
     164        response->data.num_entries = 0;
    164165        for (i=0; i<state->num_domains; i++) {
    165166                struct winbindd_list_groups_domstate *d = &state->domains[i];
     
    172173                        len += strlen(name)+1;
    173174                }
     175                response->data.num_entries += d->groups.num_principals;
    174176        }
    175177
     
    194196                        result[len] = ',';
    195197                        len += 1;
     198                        num_entries++;
    196199                }
    197200        }
    198201        result[len-1] = '\0';
    199202
     203        response->data.num_entries = num_entries;
    200204        response->extra_data.data = result;
    201205        response->length += len;
  • vendor/current/source3/winbindd/winbindd_list_users.c

    r414 r740  
    2020#include "includes.h"
    2121#include "winbindd.h"
    22 #include "librpc/gen_ndr/cli_wbint.h"
     22#include "librpc/gen_ndr/ndr_wbint_c.h"
    2323
    2424struct winbindd_list_users_domstate {
     
    9191                struct winbindd_list_users_domstate *d = &state->domains[i];
    9292
    93                 d->subreq = rpccli_wbint_QueryUserList_send(
    94                         state->domains, ev, d->domain->child.rpccli,
     93                d->subreq = dcerpc_wbint_QueryUserList_send(
     94                        state->domains, ev, dom_child_handle(d->domain),
    9595                        &d->users);
    9696                if (tevent_req_nomem(d->subreq, req)) {
     
    114114        int i;
    115115
    116         status = rpccli_wbint_QueryUserList_recv(subreq, state->domains,
     116        status = dcerpc_wbint_QueryUserList_recv(subreq, state->domains,
    117117                                                 &result);
    118118
     
    162162
    163163        len = 0;
     164        response->data.num_entries = 0;
    164165        for (i=0; i<state->num_domains; i++) {
    165166                struct winbindd_list_users_domstate *d = &state->domains[i];
     
    172173                        len += strlen(name)+1;
    173174                }
     175                response->data.num_entries += d->users.num_userinfos;
    174176        }
    175177
  • vendor/current/source3/winbindd/winbindd_lookupname.c

    r414 r740  
    8787        status = wb_lookupname_recv(subreq, &state->sid, &state->type);
    8888        TALLOC_FREE(subreq);
    89         if (!NT_STATUS_IS_OK(status)) {
    90                 tevent_req_nterror(req, status);
     89        if (tevent_req_nterror(req, status)) {
    9190                return;
    9291        }
  • vendor/current/source3/winbindd/winbindd_lookuprids.c

    r618 r740  
    2020#include "includes.h"
    2121#include "winbindd.h"
    22 #include "librpc/gen_ndr/cli_wbint.h"
     22#include "librpc/gen_ndr/ndr_wbint_c.h"
     23#include "../libcli/security/security.h"
    2324
    2425struct winbindd_lookuprids_state {
     
    8384        }
    8485
    85         subreq = rpccli_wbint_LookupRids_send(
    86                 state, ev, domain->child.rpccli, &state->domain_sid,
     86        subreq = dcerpc_wbint_LookupRids_send(
     87                state, ev, dom_child_handle(domain), &state->domain_sid,
    8788                &state->rids, &state->domain_name, &state->names);
    8889        if (tevent_req_nomem(subreq, req)) {
     
    101102        NTSTATUS status, result;
    102103
    103         status = rpccli_wbint_LookupRids_recv(subreq, state, &result);
     104        status = dcerpc_wbint_LookupRids_recv(subreq, state, &result);
    104105        TALLOC_FREE(subreq);
    105         if (!NT_STATUS_IS_OK(status)) {
     106        if (any_nt_status_not_ok(status, result, &status)) {
    106107                tevent_req_nterror(req, status);
    107                 return;
    108         }
    109         if (!NT_STATUS_IS_OK(result)) {
    110                 tevent_req_nterror(req, result);
    111108                return;
    112109        }
  • vendor/current/source3/winbindd/winbindd_lookupsid.c

    r414 r740  
    2020#include "includes.h"
    2121#include "winbindd.h"
     22#include "../libcli/security/security.h"
    2223
    2324struct winbindd_lookupsid_state {
    24         struct tevent_context *ev;
    2525        struct dom_sid sid;
    2626        enum lsa_SidType type;
     
    4444                return NULL;
    4545        }
    46         state->ev = ev;
    4746
    4847        /* Ensure null termination */
     
    5453                DEBUG(5, ("%s not a SID\n", request->data.sid));
    5554                tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
    56                 return tevent_req_post(req, ev);;
     55                return tevent_req_post(req, ev);
    5756        }
    5857
  • vendor/current/source3/winbindd/winbindd_misc.c

    r414 r740  
    2323#include "includes.h"
    2424#include "winbindd.h"
    25 #include "../librpc/gen_ndr/cli_netlogon.h"
    2625
    2726#undef DBGC_CLASS
     
    131130        }
    132131
     132        state->response->data.num_entries = num_domains;
     133
    133134        extra_data_len = strlen(extra_data);
    134135        if (extra_data_len > 0) {
     
    204205                state->response->length += extra_data_len+1;
    205206        }
    206 
    207         return WINBINDD_OK;
    208 }
    209 
    210 /* This is the child-only version of --sequence. It only allows for a single
    211  * domain (ie "our" one) to be displayed. */
    212 
    213 enum winbindd_result winbindd_dual_show_sequence(struct winbindd_domain *domain,
    214                                                  struct winbindd_cli_state *state)
    215 {
    216         DEBUG(3, ("[%5lu]: show sequence\n", (unsigned long)state->pid));
    217 
    218         /* Ensure null termination */
    219         state->request->domain_name[sizeof(state->request->domain_name)-1]='\0';
    220 
    221         domain->methods->sequence_number(domain, &domain->sequence_number);
    222 
    223         state->response->data.sequence_number =
    224                 domain->sequence_number;
    225207
    226208        return WINBINDD_OK;
     
    333315}
    334316
     317void winbindd_dc_info(struct winbindd_cli_state *cli)
     318{
     319        struct winbindd_domain *domain;
     320        char *dc_name, *dc_ip;
     321
     322        cli->request->domain_name[sizeof(cli->request->domain_name)-1] = '\0';
     323
     324        DEBUG(3, ("[%5lu]: domain_info [%s]\n", (unsigned long)cli->pid,
     325                  cli->request->domain_name));
     326
     327        if (cli->request->domain_name[0] != '\0') {
     328                domain = find_domain_from_name_noinit(
     329                        cli->request->domain_name);
     330                DEBUG(10, ("Could not find domain %s\n",
     331                           cli->request->domain_name));
     332                if (domain == NULL) {
     333                        request_error(cli);
     334                        return;
     335                }
     336        } else {
     337                domain = find_our_domain();
     338        }
     339
     340        if (!fetch_current_dc_from_gencache(
     341                    talloc_tos(), domain->name, &dc_name, &dc_ip)) {
     342                DEBUG(10, ("fetch_current_dc_from_gencache(%s) failed\n",
     343                           domain->name));
     344                request_error(cli);
     345                return;
     346        }
     347
     348        cli->response->data.num_entries = 1;
     349        cli->response->extra_data.data = talloc_asprintf(
     350                cli->mem_ctx, "%s\n%s\n", dc_name, dc_ip);
     351
     352        TALLOC_FREE(dc_name);
     353        TALLOC_FREE(dc_ip);
     354
     355        if (cli->response->extra_data.data == NULL) {
     356                request_error(cli);
     357                return;
     358        }
     359
     360        /* must add one to length to copy the 0 for string termination */
     361        cli->response->length +=
     362                strlen((char *)cli->response->extra_data.data) + 1;
     363
     364        request_ok(cli);
     365}
     366
    335367/* List various tidbits of information */
    336368
  • vendor/current/source3/winbindd/winbindd_ndr.c

    r414 r740  
    2020#include "includes.h"
    2121#include "winbindd.h"
     22#include "../librpc/gen_ndr/ndr_netlogon.h"
     23#include "../librpc/gen_ndr/ndr_security.h"
     24#include "librpc/ndr/util.h"
    2225
    2326#undef DBGC_CLASS
     
    119122                               const struct winbindd_domain *r)
    120123{
     124        int i;
    121125        if (!r) {
    122126                return;
     
    149153        ndr_print_NTSTATUS(ndr, "last_status", r->last_status);
    150154        ndr_print_winbindd_cm_conn(ndr, "conn", &r->conn);
    151         ndr_print_winbindd_child(ndr, "child", &r->child);
     155        for (i=0; i<lp_winbind_max_domain_connections(); i++) {
     156                ndr_print_winbindd_child(ndr, "children", &r->children[i]);
     157        }
    152158        ndr_print_uint32(ndr, "check_online_timeout", r->check_online_timeout);
    153159        ndr_print_ptr(ndr, "check_online_event", r->check_online_event);
  • vendor/current/source3/winbindd/winbindd_pam.c

    r597 r740  
    2626#include "winbindd.h"
    2727#include "../libcli/auth/libcli_auth.h"
    28 #include "../librpc/gen_ndr/cli_samr.h"
     28#include "../librpc/gen_ndr/ndr_samr_c.h"
     29#include "rpc_client/cli_pipe.h"
     30#include "rpc_client/cli_samr.h"
     31#include "../librpc/gen_ndr/ndr_netlogon.h"
     32#include "rpc_client/cli_netlogon.h"
    2933#include "smb_krb5.h"
     34#include "../lib/crypto/arcfour.h"
     35#include "../libcli/security/security.h"
     36#include "ads.h"
     37#include "../librpc/gen_ndr/krb5pac.h"
     38#include "passdb/machine_sid.h"
     39#include "auth.h"
    3040
    3141#undef DBGC_CLASS
     
    3545
    3646static NTSTATUS append_info3_as_txt(TALLOC_CTX *mem_ctx,
    37                                     struct winbindd_cli_state *state,
     47                                    struct winbindd_response *resp,
    3848                                    struct netr_SamInfo3 *info3)
    3949{
     
    4151        uint32_t i;
    4252
    43         state->response->data.auth.info3.logon_time =
     53        resp->data.auth.info3.logon_time =
    4454                nt_time_to_unix(info3->base.last_logon);
    45         state->response->data.auth.info3.logoff_time =
     55        resp->data.auth.info3.logoff_time =
    4656                nt_time_to_unix(info3->base.last_logoff);
    47         state->response->data.auth.info3.kickoff_time =
     57        resp->data.auth.info3.kickoff_time =
    4858                nt_time_to_unix(info3->base.acct_expiry);
    49         state->response->data.auth.info3.pass_last_set_time =
     59        resp->data.auth.info3.pass_last_set_time =
    5060                nt_time_to_unix(info3->base.last_password_change);
    51         state->response->data.auth.info3.pass_can_change_time =
     61        resp->data.auth.info3.pass_can_change_time =
    5262                nt_time_to_unix(info3->base.allow_password_change);
    53         state->response->data.auth.info3.pass_must_change_time =
     63        resp->data.auth.info3.pass_must_change_time =
    5464                nt_time_to_unix(info3->base.force_password_change);
    5565
    56         state->response->data.auth.info3.logon_count = info3->base.logon_count;
    57         state->response->data.auth.info3.bad_pw_count = info3->base.bad_password_count;
    58 
    59         state->response->data.auth.info3.user_rid = info3->base.rid;
    60         state->response->data.auth.info3.group_rid = info3->base.primary_gid;
    61         sid_to_fstring(state->response->data.auth.info3.dom_sid, info3->base.domain_sid);
    62 
    63         state->response->data.auth.info3.num_groups = info3->base.groups.count;
    64         state->response->data.auth.info3.user_flgs = info3->base.user_flags;
    65 
    66         state->response->data.auth.info3.acct_flags = info3->base.acct_flags;
    67         state->response->data.auth.info3.num_other_sids = info3->sidcount;
    68 
    69         fstrcpy(state->response->data.auth.info3.user_name,
     66        resp->data.auth.info3.logon_count = info3->base.logon_count;
     67        resp->data.auth.info3.bad_pw_count = info3->base.bad_password_count;
     68
     69        resp->data.auth.info3.user_rid = info3->base.rid;
     70        resp->data.auth.info3.group_rid = info3->base.primary_gid;
     71        sid_to_fstring(resp->data.auth.info3.dom_sid, info3->base.domain_sid);
     72
     73        resp->data.auth.info3.num_groups = info3->base.groups.count;
     74        resp->data.auth.info3.user_flgs = info3->base.user_flags;
     75
     76        resp->data.auth.info3.acct_flags = info3->base.acct_flags;
     77        resp->data.auth.info3.num_other_sids = info3->sidcount;
     78
     79        fstrcpy(resp->data.auth.info3.user_name,
    7080                info3->base.account_name.string);
    71         fstrcpy(state->response->data.auth.info3.full_name,
     81        fstrcpy(resp->data.auth.info3.full_name,
    7282                info3->base.full_name.string);
    73         fstrcpy(state->response->data.auth.info3.logon_script,
     83        fstrcpy(resp->data.auth.info3.logon_script,
    7484                info3->base.logon_script.string);
    75         fstrcpy(state->response->data.auth.info3.profile_path,
     85        fstrcpy(resp->data.auth.info3.profile_path,
    7686                info3->base.profile_path.string);
    77         fstrcpy(state->response->data.auth.info3.home_dir,
     87        fstrcpy(resp->data.auth.info3.home_dir,
    7888                info3->base.home_directory.string);
    79         fstrcpy(state->response->data.auth.info3.dir_drive,
     89        fstrcpy(resp->data.auth.info3.dir_drive,
    8090                info3->base.home_drive.string);
    8191
    82         fstrcpy(state->response->data.auth.info3.logon_srv,
     92        fstrcpy(resp->data.auth.info3.logon_srv,
    8393                info3->base.logon_server.string);
    84         fstrcpy(state->response->data.auth.info3.logon_dom,
     94        fstrcpy(resp->data.auth.info3.logon_dom,
    8595                info3->base.domain.string);
    8696
    87         ex = talloc_strdup(state->mem_ctx, "");
     97        ex = talloc_strdup(mem_ctx, "");
    8898        NT_STATUS_HAVE_NO_MEMORY(ex);
    8999
     
    109119        }
    110120
    111         state->response->extra_data.data = ex;
    112         state->response->length += talloc_get_size(ex);
     121        resp->extra_data.data = ex;
     122        resp->length += talloc_get_size(ex);
    113123
    114124        return NT_STATUS_OK;
     
    116126
    117127static NTSTATUS append_info3_as_ndr(TALLOC_CTX *mem_ctx,
    118                                     struct winbindd_cli_state *state,
     128                                    struct winbindd_response *resp,
    119129                                    struct netr_SamInfo3 *info3)
    120130{
     
    122132        enum ndr_err_code ndr_err;
    123133
    124         ndr_err = ndr_push_struct_blob(&blob, mem_ctx, NULL, info3,
     134        ndr_err = ndr_push_struct_blob(&blob, mem_ctx, info3,
    125135                                       (ndr_push_flags_fn_t)ndr_push_netr_SamInfo3);
    126136        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     
    129139        }
    130140
    131         state->response->extra_data.data = blob.data;
    132         state->response->length += blob.length;
     141        resp->extra_data.data = blob.data;
     142        resp->length += blob.length;
    133143
    134144        return NT_STATUS_OK;
     
    136146
    137147static NTSTATUS append_unix_username(TALLOC_CTX *mem_ctx,
    138                                      struct winbindd_cli_state *state,
     148                                     struct winbindd_response *resp,
    139149                                     const struct netr_SamInfo3 *info3,
    140150                                     const char *name_domain,
     
    160170        }
    161171
    162         fill_domain_username(state->response->data.auth.unix_username,
     172        fill_domain_username(resp->data.auth.unix_username,
    163173                             nt_domain, nt_username, true);
    164174
    165         DEBUG(5,("Setting unix username to [%s]\n",
    166                 state->response->data.auth.unix_username));
     175        DEBUG(5, ("Setting unix username to [%s]\n",
     176                  resp->data.auth.unix_username));
    167177
    168178        return NT_STATUS_OK;
     
    170180
    171181static NTSTATUS append_afs_token(TALLOC_CTX *mem_ctx,
    172                                  struct winbindd_cli_state *state,
     182                                 struct winbindd_response *resp,
    173183                                 const struct netr_SamInfo3 *info3,
    174184                                 const char *name_domain,
     
    193203
    194204        {
    195                 DOM_SID user_sid;
     205                struct dom_sid user_sid;
    196206                fstring sidstr;
    197207
    198                 sid_copy(&user_sid, info3->base.domain_sid);
    199                 sid_append_rid(&user_sid, info3->base.rid);
     208                sid_compose(&user_sid, info3->base.domain_sid,
     209                            info3->base.rid);
    200210                sid_to_fstring(sidstr, &user_sid);
    201211                afsname = talloc_string_sub(mem_ctx, afsname,
     
    224234                return NT_STATUS_OK;
    225235        }
    226         state->response->extra_data.data = talloc_strdup(state->mem_ctx,
    227                                                          token);
    228         if (state->response->extra_data.data == NULL) {
     236        resp->extra_data.data = talloc_strdup(mem_ctx, token);
     237        if (resp->extra_data.data == NULL) {
    229238                return NT_STATUS_NO_MEMORY;
    230239        }
    231         state->response->length +=
    232                 strlen((const char *)state->response->extra_data.data)+1;
     240        resp->length += strlen((const char *)resp->extra_data.data)+1;
    233241
    234242        return NT_STATUS_OK;
    235243}
    236244
    237 NTSTATUS check_info3_in_group(struct netr_SamInfo3 *info3,
    238                               const char *group_sid)
     245static NTSTATUS check_info3_in_group(struct netr_SamInfo3 *info3,
     246                                     const char *group_sid)
    239247/**
    240248 * Check whether a user belongs to a group or list of groups.
     
    249257 */
    250258{
    251         DOM_SID *require_membership_of_sid;
    252         size_t num_require_membership_of_sid;
     259        struct dom_sid *require_membership_of_sid;
     260        uint32_t num_require_membership_of_sid;
    253261        char *req_sid;
    254262        const char *p;
    255         DOM_SID sid;
     263        struct dom_sid sid;
    256264        size_t i;
    257         struct nt_user_token *token;
     265        struct security_token *token;
    258266        TALLOC_CTX *frame = talloc_stackframe();
    259267        NTSTATUS status;
     
    266274        }
    267275
    268         token = talloc_zero(talloc_tos(), struct nt_user_token);
     276        token = talloc_zero(talloc_tos(), struct security_token);
    269277        if (token == NULL) {
    270278                DEBUG(0, ("talloc failed\n"));
     
    297305
    298306        status = sid_array_from_info3(talloc_tos(), info3,
    299                                       &token->user_sids,
     307                                      &token->sids,
    300308                                      &token->num_sids,
    301309                                      true, false);
     
    315323        }
    316324
    317         debug_nt_user_token(DBGC_CLASS, 10, token);
     325        security_token_debug(DBGC_CLASS, 10, token);
    318326
    319327        for (i=0; i<num_require_membership_of_sid; i++) {
     
    349357        }
    350358
    351         if (is_myname(domain_name)) {
    352                 DEBUG(3, ("Authentication for domain %s (local domain "
    353                           "to this server) not supported at this "
    354                           "stage\n", domain_name));
    355                 return NULL;
     359        if (strequal(domain_name, get_global_sam_name())) {
     360                return find_domain_from_name_noinit(domain_name);
    356361        }
    357362
     
    387392
    388393static NTSTATUS fillup_password_policy(struct winbindd_domain *domain,
    389                                        struct winbindd_cli_state *state)
     394                                       struct winbindd_response *response)
     395{
     396        TALLOC_CTX *frame = talloc_stackframe();
     397        struct winbindd_methods *methods;
     398        NTSTATUS status;
     399        struct samr_DomInfo1 password_policy;
     400
     401        if ( !winbindd_can_contact_domain( domain ) ) {
     402                DEBUG(5,("fillup_password_policy: No inbound trust to "
     403                         "contact domain %s\n", domain->name));
     404                status = NT_STATUS_NOT_SUPPORTED;
     405                goto done;
     406        }
     407
     408        methods = domain->methods;
     409
     410        status = methods->password_policy(domain, talloc_tos(), &password_policy);
     411        if (NT_STATUS_IS_ERR(status)) {
     412                goto done;
     413        }
     414
     415        fill_in_password_policy(response, &password_policy);
     416
     417done:
     418        TALLOC_FREE(frame);
     419        return NT_STATUS_OK;
     420}
     421
     422static NTSTATUS get_max_bad_attempts_from_lockout_policy(struct winbindd_domain *domain,
     423                                                         TALLOC_CTX *mem_ctx,
     424                                                         uint16 *lockout_threshold)
     425{
     426        struct winbindd_methods *methods;
     427        NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
     428        struct samr_DomInfo12 lockout_policy;
     429
     430        *lockout_threshold = 0;
     431
     432        methods = domain->methods;
     433
     434        status = methods->lockout_policy(domain, mem_ctx, &lockout_policy);
     435        if (NT_STATUS_IS_ERR(status)) {
     436                return status;
     437        }
     438
     439        *lockout_threshold = lockout_policy.lockout_threshold;
     440
     441        return NT_STATUS_OK;
     442}
     443
     444static NTSTATUS get_pwd_properties(struct winbindd_domain *domain,
     445                                   TALLOC_CTX *mem_ctx,
     446                                   uint32 *password_properties)
    390447{
    391448        struct winbindd_methods *methods;
     
    393450        struct samr_DomInfo1 password_policy;
    394451
    395         if ( !winbindd_can_contact_domain( domain ) ) {
    396                 DEBUG(5,("fillup_password_policy: No inbound trust to "
    397                          "contact domain %s\n", domain->name));
    398                 return NT_STATUS_NOT_SUPPORTED;
    399         }
    400 
    401         methods = domain->methods;
    402 
    403         status = methods->password_policy(domain, state->mem_ctx, &password_policy);
    404         if (NT_STATUS_IS_ERR(status)) {
    405                 return status;
    406         }
    407 
    408         fill_in_password_policy(state->response, &password_policy);
    409 
    410         return NT_STATUS_OK;
    411 }
    412 
    413 static NTSTATUS get_max_bad_attempts_from_lockout_policy(struct winbindd_domain *domain,
    414                                                          TALLOC_CTX *mem_ctx,
    415                                                          uint16 *lockout_threshold)
    416 {
    417         struct winbindd_methods *methods;
    418         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
    419         struct samr_DomInfo12 lockout_policy;
    420 
    421         *lockout_threshold = 0;
    422 
    423         methods = domain->methods;
    424 
    425         status = methods->lockout_policy(domain, mem_ctx, &lockout_policy);
    426         if (NT_STATUS_IS_ERR(status)) {
    427                 return status;
    428         }
    429 
    430         *lockout_threshold = lockout_policy.lockout_threshold;
    431 
    432         return NT_STATUS_OK;
    433 }
    434 
    435 static NTSTATUS get_pwd_properties(struct winbindd_domain *domain,
    436                                    TALLOC_CTX *mem_ctx,
    437                                    uint32 *password_properties)
    438 {
    439         struct winbindd_methods *methods;
    440         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
    441         struct samr_DomInfo1 password_policy;
    442 
    443452        *password_properties = 0;
    444453
     
    460469                                        const char *type,
    461470                                        uid_t uid,
    462                                         bool *internal_ccache)
     471                                        const char **user_ccache_file)
    463472{
    464473        /* accept FILE and WRFILE as krb5_cc_type from the client and then
     
    468477        const char *gen_cc = NULL;
    469478
    470         *internal_ccache = true;
    471 
    472         if (uid == -1) {
    473                 goto memory_ccache;
    474         }
    475 
    476         if (!type || type[0] == '\0') {
    477                 goto memory_ccache;
    478         }
    479 
    480         if (strequal(type, "FILE")) {
    481                 gen_cc = talloc_asprintf(mem_ctx, "FILE:/tmp/krb5cc_%d", uid);
    482         } else if (strequal(type, "WRFILE")) {
    483                 gen_cc = talloc_asprintf(mem_ctx, "WRFILE:/tmp/krb5cc_%d", uid);
    484         } else {
    485                 DEBUG(10,("we don't allow to set a %s type ccache\n", type));
    486                 goto memory_ccache;
    487         }
    488 
    489         *internal_ccache = false;
    490         goto done;
    491 
    492   memory_ccache:
    493         gen_cc = talloc_strdup(mem_ctx, "MEMORY:winbindd_pam_ccache");
    494 
    495   done:
     479        if (uid != -1) {
     480                if (strequal(type, "FILE")) {
     481                        gen_cc = talloc_asprintf(
     482                                mem_ctx, "FILE:/tmp/krb5cc_%d", uid);
     483                }
     484                if (strequal(type, "WRFILE")) {
     485                        gen_cc = talloc_asprintf(
     486                                mem_ctx, "WRFILE:/tmp/krb5cc_%d", uid);
     487                }
     488        }
     489
     490        *user_ccache_file = gen_cc;
     491
     492        if (gen_cc == NULL) {
     493                gen_cc = talloc_strdup(mem_ctx, "MEMORY:winbindd_pam_ccache");
     494        }
    496495        if (gen_cc == NULL) {
    497496                DEBUG(0,("out of memory\n"));
     
    499498        }
    500499
    501         DEBUG(10,("using ccache: %s %s\n", gen_cc, *internal_ccache ? "(internal)":""));
     500        DEBUG(10, ("using ccache: %s%s\n", gen_cc,
     501                   (*user_ccache_file == NULL) ? " (internal)":""));
    502502
    503503        return gen_cc;
    504504}
    505505
    506 static void setup_return_cc_name(struct winbindd_cli_state *state, const char *cc)
    507 {
    508         const char *type = state->request->data.auth.krb5_cc_type;
    509 
    510         state->response->data.auth.krb5ccname[0] = '\0';
    511 
    512         if (type[0] == '\0') {
    513                 return;
    514         }
    515 
    516         if (!strequal(type, "FILE") &&
    517             !strequal(type, "WRFILE")) {
    518                 DEBUG(10,("won't return krbccname for a %s type ccache\n",
    519                         type));
    520                 return;
    521         }
    522 
    523         fstrcpy(state->response->data.auth.krb5ccname, cc);
    524 }
    525 
    526506#endif
    527507
    528 static uid_t get_uid_from_state(struct winbindd_cli_state *state)
     508uid_t get_uid_from_request(struct winbindd_request *request)
    529509{
    530510        uid_t uid;
    531511
    532         uid = state->request->data.auth.uid;
     512        uid = request->data.auth.uid;
    533513
    534514        if (uid < 0) {
     
    544524 **********************************************************************/
    545525
    546 static NTSTATUS winbindd_raw_kerberos_login(struct winbindd_domain *domain,
    547                                             struct winbindd_cli_state *state,
    548                                             struct netr_SamInfo3 **info3)
     526static NTSTATUS winbindd_raw_kerberos_login(TALLOC_CTX *mem_ctx,
     527                                            struct winbindd_domain *domain,
     528                                            const char *user,
     529                                            const char *pass,
     530                                            const char *krb5_cc_type,
     531                                            uid_t uid,
     532                                            struct netr_SamInfo3 **info3,
     533                                            fstring krb5ccname)
    549534{
    550535#ifdef HAVE_KRB5
     
    558543        time_t ticket_lifetime = 0;
    559544        time_t renewal_until = 0;
    560         uid_t uid = -1;
    561545        ADS_STRUCT *ads;
    562546        time_t time_offset = 0;
    563         bool internal_ccache = true;
    564 
    565         ZERO_STRUCTP(info3);
     547        const char *user_ccache_file;
     548        struct PAC_LOGON_INFO *logon_info = NULL;
    566549
    567550        *info3 = NULL;
     
    570553         * prepare a krb5_cc_cache string for the user */
    571554
    572         uid = get_uid_from_state(state);
    573555        if (uid == -1) {
    574556                DEBUG(0,("no valid uid\n"));
    575557        }
    576558
    577         cc = generate_krb5_ccache(state->mem_ctx,
    578                                   state->request->data.auth.krb5_cc_type,
    579                                   state->request->data.auth.uid,
    580                                   &internal_ccache);
     559        cc = generate_krb5_ccache(mem_ctx,
     560                                  krb5_cc_type,
     561                                  uid,
     562                                  &user_ccache_file);
    581563        if (cc == NULL) {
    582564                return NT_STATUS_NO_MEMORY;
     
    596578         * do kerberos auth and setup ccache as the user */
    597579
    598         parse_domain_user(state->request->data.auth.user, name_domain, name_user);
     580        parse_domain_user(user, name_domain, name_user);
    599581
    600582        realm = domain->alt_name;
    601583        strupper_m(realm);
    602584
    603         principal_s = talloc_asprintf(state->mem_ctx, "%s@%s", name_user, realm);
     585        principal_s = talloc_asprintf(mem_ctx, "%s@%s", name_user, realm);
    604586        if (principal_s == NULL) {
    605587                return NT_STATUS_NO_MEMORY;
    606588        }
    607589
    608         service = talloc_asprintf(state->mem_ctx, "%s/%s@%s", KRB5_TGS_NAME, realm, realm);
     590        service = talloc_asprintf(mem_ctx, "%s/%s@%s", KRB5_TGS_NAME, realm, realm);
    609591        if (service == NULL) {
    610592                return NT_STATUS_NO_MEMORY;
     
    616598        /************************ ENTERING NON-ROOT **********************/
    617599
    618         if (!internal_ccache) {
     600        if (user_ccache_file != NULL) {
    619601                set_effective_uid(uid);
    620602                DEBUG(10,("winbindd_raw_kerberos_login: uid is %d\n", uid));
    621603        }
    622604
    623         result = kerberos_return_info3_from_pac(state->mem_ctx,
    624                                                 principal_s,
    625                                                 state->request->data.auth.pass,
    626                                                 time_offset,
    627                                                 &ticket_lifetime,
    628                                                 &renewal_until,
    629                                                 cc,
    630                                                 true,
    631                                                 true,
    632                                                 WINBINDD_PAM_AUTH_KRB5_RENEW_TIME,
    633                                                 NULL,
    634                                                 info3);
    635         if (!internal_ccache) {
     605        result = kerberos_return_pac(mem_ctx,
     606                                     principal_s,
     607                                     pass,
     608                                     time_offset,
     609                                     &ticket_lifetime,
     610                                     &renewal_until,
     611                                     cc,
     612                                     true,
     613                                     true,
     614                                     WINBINDD_PAM_AUTH_KRB5_RENEW_TIME,
     615                                     NULL,
     616                                     &logon_info);
     617        if (user_ccache_file != NULL) {
    636618                gain_root_privilege();
    637619        }
     
    643625        }
    644626
     627        *info3 = &logon_info->info3;
     628
    645629        DEBUG(10,("winbindd_raw_kerberos_login: winbindd validated ticket of %s\n",
    646630                principal_s));
     
    649633         * environment */
    650634
    651         if (!internal_ccache) {
    652 
    653                 setup_return_cc_name(state, cc);
     635        if (user_ccache_file != NULL) {
     636
     637                fstrcpy(krb5ccname, user_ccache_file);
    654638
    655639                result = add_ccache_to_list(principal_s,
    656640                                            cc,
    657641                                            service,
    658                                             state->request->data.auth.user,
     642                                            user,
    659643                                            realm,
    660644                                            uid,
     
    697681        }
    698682
    699         if (!NT_STATUS_IS_OK(remove_ccache(state->request->data.auth.user))) {
     683        if (!NT_STATUS_IS_OK(remove_ccache(user))) {
    700684                DEBUG(3,("winbindd_raw_kerberos_login: "
    701685                          "could not remove ccache for user %s\n",
    702                         state->request->data.auth.user));
     686                        user));
    703687        }
    704688
     
    734718****************************************************************/
    735719
    736 NTSTATUS append_auth_data(struct winbindd_cli_state *state,
    737                           struct netr_SamInfo3 *info3,
    738                           const char *name_domain,
    739                           const char *name_user)
     720static NTSTATUS append_auth_data(TALLOC_CTX *mem_ctx,
     721                                 struct winbindd_response *resp,
     722                                 uint32_t request_flags,
     723                                 struct netr_SamInfo3 *info3,
     724                                 const char *name_domain,
     725                                 const char *name_user)
    740726{
    741727        NTSTATUS result;
    742         uint32_t flags = state->request->flags;
    743 
    744         if (flags & WBFLAG_PAM_USER_SESSION_KEY) {
    745                 memcpy(state->response->data.auth.user_session_key,
     728
     729        if (request_flags & WBFLAG_PAM_USER_SESSION_KEY) {
     730                memcpy(resp->data.auth.user_session_key,
    746731                       info3->base.key.key,
    747                        sizeof(state->response->data.auth.user_session_key)
     732                       sizeof(resp->data.auth.user_session_key)
    748733                       /* 16 */);
    749734        }
    750735
    751         if (flags & WBFLAG_PAM_LMKEY) {
    752                 memcpy(state->response->data.auth.first_8_lm_hash,
     736        if (request_flags & WBFLAG_PAM_LMKEY) {
     737                memcpy(resp->data.auth.first_8_lm_hash,
    753738                       info3->base.LMSessKey.key,
    754                        sizeof(state->response->data.auth.first_8_lm_hash)
     739                       sizeof(resp->data.auth.first_8_lm_hash)
    755740                       /* 8 */);
    756741        }
    757742
    758         if (flags & WBFLAG_PAM_INFO3_TEXT) {
    759                 result = append_info3_as_txt(state->mem_ctx, state, info3);
     743        if (request_flags & WBFLAG_PAM_UNIX_NAME) {
     744                result = append_unix_username(mem_ctx, resp,
     745                                              info3, name_domain, name_user);
     746                if (!NT_STATUS_IS_OK(result)) {
     747                        DEBUG(10,("Failed to append Unix Username: %s\n",
     748                                nt_errstr(result)));
     749                        return result;
     750                }
     751        }
     752
     753        /* currently, anything from here on potentially overwrites extra_data. */
     754
     755        if (request_flags & WBFLAG_PAM_INFO3_NDR) {
     756                result = append_info3_as_ndr(mem_ctx, resp, info3);
     757                if (!NT_STATUS_IS_OK(result)) {
     758                        DEBUG(10,("Failed to append INFO3 (NDR): %s\n",
     759                                nt_errstr(result)));
     760                        return result;
     761                }
     762        }
     763
     764        if (request_flags & WBFLAG_PAM_INFO3_TEXT) {
     765                result = append_info3_as_txt(mem_ctx, resp, info3);
    760766                if (!NT_STATUS_IS_OK(result)) {
    761767                        DEBUG(10,("Failed to append INFO3 (TXT): %s\n",
     
    765771        }
    766772
    767         /* currently, anything from here on potentially overwrites extra_data. */
    768 
    769         if (flags & WBFLAG_PAM_INFO3_NDR) {
    770                 result = append_info3_as_ndr(state->mem_ctx, state, info3);
    771                 if (!NT_STATUS_IS_OK(result)) {
    772                         DEBUG(10,("Failed to append INFO3 (NDR): %s\n",
    773                                 nt_errstr(result)));
    774                         return result;
    775                 }
    776         }
    777 
    778         if (flags & WBFLAG_PAM_UNIX_NAME) {
    779                 result = append_unix_username(state->mem_ctx, state, info3,
    780                                               name_domain, name_user);
    781                 if (!NT_STATUS_IS_OK(result)) {
    782                         DEBUG(10,("Failed to append Unix Username: %s\n",
    783                                 nt_errstr(result)));
    784                         return result;
    785                 }
    786         }
    787 
    788         if (flags & WBFLAG_PAM_AFS_TOKEN) {
    789                 result = append_afs_token(state->mem_ctx, state, info3,
    790                                           name_domain, name_user);
     773        if (request_flags & WBFLAG_PAM_AFS_TOKEN) {
     774                result = append_afs_token(mem_ctx, resp,
     775                                          info3, name_domain, name_user);
    791776                if (!NT_STATUS_IS_OK(result)) {
    792777                        DEBUG(10,("Failed to append AFS token: %s\n",
     
    799784}
    800785
    801 void winbindd_pam_auth(struct winbindd_cli_state *state)
    802 {
    803         struct winbindd_domain *domain;
    804         fstring name_domain, name_user;
    805         char *mapped = NULL;
    806         NTSTATUS result;
    807         NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
    808 
    809         /* Ensure null termination */
    810         state->request->data.auth.user
    811                 [sizeof(state->request->data.auth.user)-1]='\0';
    812 
    813         /* Ensure null termination */
    814         state->request->data.auth.pass
    815                 [sizeof(state->request->data.auth.pass)-1]='\0';
    816 
    817         DEBUG(3, ("[%5lu]: pam auth %s\n", (unsigned long)state->pid,
    818                   state->request->data.auth.user));
    819 
    820         if (!check_request_flags(state->request->flags)) {
    821                 result = NT_STATUS_INVALID_PARAMETER_MIX;
    822                 goto done;
    823         }
    824 
    825         /* Parse domain and username */
    826 
    827         name_map_status = normalize_name_unmap(state->mem_ctx,
    828                                                state->request->data.auth.user,
    829                                                &mapped);
    830 
    831         /* Update the auth name if we did any mapping */
    832 
    833         if (NT_STATUS_IS_OK(name_map_status) ||
    834             NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))
    835         {
    836                 fstrcpy(state->request->data.auth.user, mapped);
    837         }
    838 
    839         if (!canonicalize_username(state->request->data.auth.user, name_domain, name_user)) {
    840                 result = NT_STATUS_NO_SUCH_USER;
    841                 goto done;
    842         }
    843 
    844         domain = find_auth_domain(state->request->flags, name_domain);
    845 
    846         if (domain == NULL) {
    847                 result = NT_STATUS_NO_SUCH_USER;
    848                 goto done;
    849         }
    850 
    851         sendto_domain(state, domain);
    852         return;
    853  done:
    854         set_auth_errors(state->response, result);
    855         DEBUG(5, ("Plain text authentication for %s returned %s "
    856                   "(PAM: %d)\n",
    857                   state->request->data.auth.user,
    858                   state->response->data.auth.nt_status_string,
    859                   state->response->data.auth.pam_error));
    860         request_error(state);
    861 }
    862 
    863786static NTSTATUS winbindd_dual_pam_auth_cached(struct winbindd_domain *domain,
    864787                                              struct winbindd_cli_state *state,
     
    868791        uint16 max_allowed_bad_attempts;
    869792        fstring name_domain, name_user;
    870         DOM_SID sid;
     793        struct dom_sid sid;
    871794        enum lsa_SidType type;
    872795        uchar new_nt_pass[NT_HASH_LEN];
     
    891814
    892815
    893         if (!lookup_cached_name(state->mem_ctx,
    894                                 name_domain,
     816        if (!lookup_cached_name(name_domain,
    895817                                name_user,
    896818                                &sid,
     
    998920                        const char *principal_s = NULL;
    999921                        const char *service = NULL;
    1000                         bool internal_ccache = false;
    1001 
    1002                         uid = get_uid_from_state(state);
     922                        const char *user_ccache_file;
     923
     924                        uid = get_uid_from_request(state->request);
    1003925                        if (uid == -1) {
    1004926                                DEBUG(0,("winbindd_dual_pam_auth_cached: invalid uid\n"));
     
    1009931                                                state->request->data.auth.krb5_cc_type,
    1010932                                                state->request->data.auth.uid,
    1011                                                 &internal_ccache);
     933                                                &user_ccache_file);
    1012934                        if (cc == NULL) {
    1013935                                return NT_STATUS_NO_MEMORY;
     
    1027949                        }
    1028950
    1029                         if (!internal_ccache) {
    1030 
    1031                                 setup_return_cc_name(state, cc);
     951                        if (user_ccache_file != NULL) {
     952
     953                                fstrcpy(state->response->data.auth.krb5ccname,
     954                                        user_ccache_file);
    1032955
    1033956                                result = add_ccache_to_list(principal_s,
     
    1058981
    1059982                result = winbindd_update_creds_by_info3(domain,
    1060                                                         state->mem_ctx,
    1061983                                                        state->request->data.auth.user,
    1062984                                                        state->request->data.auth.pass,
     
    11011023                }
    11021024
    1103                 if ((my_info3->base.rid != DOMAIN_USER_RID_ADMIN) ||
     1025                if ((my_info3->base.rid != DOMAIN_RID_ADMINISTRATOR) ||
    11041026                    (password_properties & DOMAIN_PASSWORD_LOCKOUT_ADMINS)) {
    11051027                        my_info3->base.acct_flags |= ACB_AUTOLOCK;
     
    11091031failed:
    11101032        result = winbindd_update_creds_by_info3(domain,
    1111                                                 state->mem_ctx,
    11121033                                                state->request->data.auth.user,
    11131034                                                NULL,
     
    11761097        }
    11771098try_login:
    1178         result = winbindd_raw_kerberos_login(contact_domain, state, info3);
     1099        result = winbindd_raw_kerberos_login(
     1100                state->mem_ctx, contact_domain,
     1101                state->request->data.auth.user,
     1102                state->request->data.auth.pass,
     1103                state->request->data.auth.krb5_cc_type,
     1104                get_uid_from_request(state->request),
     1105                info3, state->response->data.auth.krb5ccname);
    11791106done:
    11801107        return result;
    11811108}
    11821109
    1183 typedef NTSTATUS (*netlogon_fn_t)(struct rpc_pipe_client *cli,
    1184                                   TALLOC_CTX *mem_ctx,
    1185                                   uint32 logon_parameters,
    1186                                   const char *server,
    1187                                   const char *username,
    1188                                   const char *domain,
    1189                                   const char *workstation,
    1190                                   const uint8 chal[8],
    1191                                   uint16_t validation_level,
    1192                                   DATA_BLOB lm_response,
    1193                                   DATA_BLOB nt_response,
    1194                                   struct netr_SamInfo3 **info3);
    1195 
    1196 static NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain,
    1197                                                 struct winbindd_cli_state *state,
    1198                                                 struct netr_SamInfo3 **info3)
    1199 {
    1200 
    1201         struct rpc_pipe_client *netlogon_pipe;
    1202         uchar chal[8];
    1203         DATA_BLOB lm_resp;
    1204         DATA_BLOB nt_resp;
     1110static NTSTATUS winbindd_dual_auth_passdb(TALLOC_CTX *mem_ctx,
     1111                                          const char *domain, const char *user,
     1112                                          const DATA_BLOB *challenge,
     1113                                          const DATA_BLOB *lm_resp,
     1114                                          const DATA_BLOB *nt_resp,
     1115                                          struct netr_SamInfo3 **pinfo3)
     1116{
     1117        struct auth_usersupplied_info *user_info = NULL;
     1118        NTSTATUS status;
     1119
     1120        status = make_user_info(&user_info, user, user, domain, domain,
     1121                                global_myname(), lm_resp, nt_resp, NULL, NULL,
     1122                                NULL, AUTH_PASSWORD_RESPONSE);
     1123        if (!NT_STATUS_IS_OK(status)) {
     1124                DEBUG(10, ("make_user_info failed: %s\n", nt_errstr(status)));
     1125                return status;
     1126        }
     1127
     1128        /* We don't want any more mapping of the username */
     1129        user_info->mapped_state = True;
     1130
     1131        status = check_sam_security_info3(challenge, talloc_tos(), user_info,
     1132                                          pinfo3);
     1133        free_user_info(&user_info);
     1134        DEBUG(10, ("Authenticaticating user %s\\%s returned %s\n", domain,
     1135                   user, nt_errstr(status)));
     1136        return status;
     1137}
     1138
     1139static NTSTATUS winbind_samlogon_retry_loop(struct winbindd_domain *domain,
     1140                                            TALLOC_CTX *mem_ctx,
     1141                                            uint32_t logon_parameters,
     1142                                            const char *server,
     1143                                            const char *username,
     1144                                            const char *domainname,
     1145                                            const char *workstation,
     1146                                            const uint8_t chal[8],
     1147                                            DATA_BLOB lm_response,
     1148                                            DATA_BLOB nt_response,
     1149                                            struct netr_SamInfo3 **info3)
     1150{
    12051151        int attempts = 0;
    1206         unsigned char local_lm_response[24];
    1207         unsigned char local_nt_response[24];
    1208         struct winbindd_domain *contact_domain;
    1209         fstring name_domain, name_user;
    1210         bool retry;
     1152        bool retry = false;
    12111153        NTSTATUS result;
    1212         struct netr_SamInfo3 *my_info3 = NULL;
    1213 
    1214         *info3 = NULL;
    1215 
    1216         DEBUG(10,("winbindd_dual_pam_auth_samlogon\n"));
    1217 
    1218         /* Parse domain and username */
    1219 
    1220         parse_domain_user(state->request->data.auth.user, name_domain, name_user);
    1221 
    1222         /* do password magic */
    1223 
    1224 
    1225         generate_random_buffer(chal, 8);
    1226         if (lp_client_ntlmv2_auth()) {
    1227                 DATA_BLOB server_chal;
    1228                 DATA_BLOB names_blob;
    1229                 DATA_BLOB nt_response;
    1230                 DATA_BLOB lm_response;
    1231                 server_chal = data_blob_talloc(state->mem_ctx, chal, 8);
    1232 
    1233                 /* note that the 'workgroup' here is a best guess - we don't know
    1234                    the server's domain at this point.  The 'server name' is also
    1235                    dodgy...
    1236                 */
    1237                 names_blob = NTLMv2_generate_names_blob(state->mem_ctx, global_myname(), lp_workgroup());
    1238 
    1239                 if (!SMBNTLMv2encrypt(NULL, name_user, name_domain,
    1240                                       state->request->data.auth.pass,
    1241                                       &server_chal,
    1242                                       &names_blob,
    1243                                       &lm_response, &nt_response, NULL, NULL)) {
    1244                         data_blob_free(&names_blob);
    1245                         data_blob_free(&server_chal);
    1246                         DEBUG(0, ("winbindd_pam_auth: SMBNTLMv2encrypt() failed!\n"));
    1247                         result = NT_STATUS_NO_MEMORY;
    1248                         goto done;
    1249                 }
    1250                 data_blob_free(&names_blob);
    1251                 data_blob_free(&server_chal);
    1252                 lm_resp = data_blob_talloc(state->mem_ctx, lm_response.data,
    1253                                            lm_response.length);
    1254                 nt_resp = data_blob_talloc(state->mem_ctx, nt_response.data,
    1255                                            nt_response.length);
    1256                 data_blob_free(&lm_response);
    1257                 data_blob_free(&nt_response);
    1258 
    1259         } else {
    1260                 if (lp_client_lanman_auth()
    1261                     && SMBencrypt(state->request->data.auth.pass,
    1262                                   chal,
    1263                                   local_lm_response)) {
    1264                         lm_resp = data_blob_talloc(state->mem_ctx,
    1265                                                    local_lm_response,
    1266                                                    sizeof(local_lm_response));
    1267                 } else {
    1268                         lm_resp = data_blob_null;
    1269                 }
    1270                 SMBNTencrypt(state->request->data.auth.pass,
    1271                              chal,
    1272                              local_nt_response);
    1273 
    1274                 nt_resp = data_blob_talloc(state->mem_ctx,
    1275                                            local_nt_response,
    1276                                            sizeof(local_nt_response));
    1277         }
    1278 
    1279         /* what domain should we contact? */
    1280 
    1281         if ( IS_DC ) {
    1282                 if (!(contact_domain = find_domain_from_name(name_domain))) {
    1283                         DEBUG(3, ("Authentication for domain for [%s] -> [%s]\\[%s] failed as %s is not a trusted domain\n",
    1284                                   state->request->data.auth.user, name_domain, name_user, name_domain));
    1285                         result = NT_STATUS_NO_SUCH_USER;
    1286                         goto done;
    1287                 }
    1288 
    1289         } else {
    1290                 if (is_myname(name_domain)) {
    1291                         DEBUG(3, ("Authentication for domain %s (local domain to this server) not supported at this stage\n", name_domain));
    1292                         result =  NT_STATUS_NO_SUCH_USER;
    1293                         goto done;
    1294                 }
    1295 
    1296                 contact_domain = find_our_domain();
    1297         }
    1298 
    1299         /* check authentication loop */
    13001154
    13011155        do {
    1302                 netlogon_fn_t logon_fn;
    1303                 const struct cli_pipe_auth_data *auth;
     1156                struct rpc_pipe_client *netlogon_pipe;
     1157                const struct pipe_auth_data *auth;
    13041158                uint32_t neg_flags = 0;
    13051159
    1306                 ZERO_STRUCTP(my_info3);
     1160                ZERO_STRUCTP(info3);
    13071161                retry = false;
    13081162
    1309                 result = cm_connect_netlogon(contact_domain, &netlogon_pipe);
     1163                result = cm_connect_netlogon(domain, &netlogon_pipe);
    13101164
    13111165                if (!NT_STATUS_IS_OK(result)) {
    1312                         DEBUG(3, ("could not open handle to NETLOGON pipe\n"));
    1313                         goto done;
     1166                        DEBUG(3,("could not open handle to NETLOGON pipe (error: %s)\n",
     1167                                  nt_errstr(result)));
     1168                        return result;
    13141169                }
    13151170                auth = netlogon_pipe->auth;
     
    13481203                 * NETLOGON_NEG_AUTHENTICATED_RPC set together
    13491204                 * are the indication that the server supports
    1350                  * NetlogonValidationSamInfo4 (6). And must only
     1205                 * NetlogonValidationSamInfo4 (6). And it must only
    13511206                 * be used if "SealSecureChannel" is used.
    13521207                 *
     
    13561211                if (auth == NULL) {
    13571212                        domain->can_do_validation6 = false;
    1358                 } else if (auth->auth_type != PIPE_AUTH_TYPE_SCHANNEL) {
     1213                } else if (auth->auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
    13591214                        domain->can_do_validation6 = false;
    13601215                } else if (auth->auth_level != DCERPC_AUTH_LEVEL_PRIVACY) {
     
    13661221                }
    13671222
    1368                 logon_fn = contact_domain->can_do_samlogon_ex
    1369                         ? rpccli_netlogon_sam_network_logon_ex
    1370                         : rpccli_netlogon_sam_network_logon;
    1371 
    1372                 result = logon_fn(netlogon_pipe,
    1373                                   state->mem_ctx,
    1374                                   0,
    1375                                   contact_domain->dcname, /* server name */
    1376                                   name_user,              /* user name */
    1377                                   name_domain,            /* target domain */
    1378                                   global_myname(),        /* workstation */
    1379                                   chal,
    1380                                   domain->can_do_validation6 ? 6 : 3,
    1381                                   lm_resp,
    1382                                   nt_resp,
    1383                                   &my_info3);
    1384 
    1385                 if ((NT_STATUS_V(result) == DCERPC_FAULT_OP_RNG_ERROR)
    1386                     && contact_domain->can_do_samlogon_ex) {
    1387                         DEBUG(3, ("Got a DC that can not do NetSamLogonEx, "
    1388                                   "retrying with NetSamLogon\n"));
    1389                         contact_domain->can_do_samlogon_ex = false;
     1223                if (domain->can_do_samlogon_ex) {
     1224                        result = rpccli_netlogon_sam_network_logon_ex(
     1225                                        netlogon_pipe,
     1226                                        mem_ctx,
     1227                                        0,
     1228                                        server,         /* server name */
     1229                                        username,       /* user name */
     1230                                        domainname,     /* target domain */
     1231                                        workstation,    /* workstation */
     1232                                        chal,
     1233                                        domain->can_do_validation6 ? 6 : 3,
     1234                                        lm_response,
     1235                                        nt_response,
     1236                                        info3);
     1237                } else {
     1238                        result = rpccli_netlogon_sam_network_logon(
     1239                                        netlogon_pipe,
     1240                                        mem_ctx,
     1241                                        0,
     1242                                        server,         /* server name */
     1243                                        username,       /* user name */
     1244                                        domainname,     /* target domain */
     1245                                        workstation,    /* workstation */
     1246                                        chal,
     1247                                        domain->can_do_validation6 ? 6 : 3,
     1248                                        lm_response,
     1249                                        nt_response,
     1250                                        info3);
     1251                }
     1252
     1253                if (NT_STATUS_EQUAL(result, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) {
     1254
    13901255                        /*
    13911256                         * It's likely that the server also does not support
     
    13931258                         */
    13941259                        domain->can_do_validation6 = false;
    1395                         retry = true;
    1396                         continue;
     1260
     1261                        if (domain->can_do_samlogon_ex) {
     1262                                DEBUG(3, ("Got a DC that can not do NetSamLogonEx, "
     1263                                          "retrying with NetSamLogon\n"));
     1264                                domain->can_do_samlogon_ex = false;
     1265                                retry = true;
     1266                                continue;
     1267                        }
     1268
     1269
     1270                        /* Got DCERPC_FAULT_OP_RNG_ERROR for SamLogon
     1271                         * (no Ex). This happens against old Samba
     1272                         * DCs. Drop the connection.
     1273                         */
     1274                        invalidate_cm_connection(&domain->conn);
     1275                        result = NT_STATUS_LOGON_FAILURE;
     1276                        break;
    13971277                }
    13981278
     
    14331313                                "password was changed and we didn't know it. "
    14341314                                 "Killing connections to domain %s\n",
    1435                                 name_domain));
    1436                         invalidate_cm_connection(&contact_domain->conn);
     1315                                domainname));
     1316                        invalidate_cm_connection(&domain->conn);
    14371317                        retry = true;
    14381318                }
    14391319
    14401320        } while ( (attempts < 2) && retry );
     1321
     1322        return result;
     1323}
     1324
     1325static NTSTATUS winbindd_dual_pam_auth_samlogon(TALLOC_CTX *mem_ctx,
     1326                                                struct winbindd_domain *domain,
     1327                                                const char *user,
     1328                                                const char *pass,
     1329                                                uint32_t request_flags,
     1330                                                struct netr_SamInfo3 **info3)
     1331{
     1332
     1333        uchar chal[8];
     1334        DATA_BLOB lm_resp;
     1335        DATA_BLOB nt_resp;
     1336        unsigned char local_nt_response[24];
     1337        fstring name_domain, name_user;
     1338        NTSTATUS result;
     1339        struct netr_SamInfo3 *my_info3 = NULL;
     1340
     1341        *info3 = NULL;
     1342
     1343        DEBUG(10,("winbindd_dual_pam_auth_samlogon\n"));
     1344
     1345        /* Parse domain and username */
     1346
     1347        parse_domain_user(user, name_domain, name_user);
     1348
     1349        /* do password magic */
     1350
     1351        generate_random_buffer(chal, sizeof(chal));
     1352
     1353        if (lp_client_ntlmv2_auth()) {
     1354                DATA_BLOB server_chal;
     1355                DATA_BLOB names_blob;
     1356                server_chal = data_blob_const(chal, 8);
     1357
     1358                /* note that the 'workgroup' here is for the local
     1359                   machine.  The 'server name' must match the
     1360                   'workstation' passed to the actual SamLogon call.
     1361                */
     1362                names_blob = NTLMv2_generate_names_blob(
     1363                        mem_ctx, global_myname(), lp_workgroup());
     1364
     1365                if (!SMBNTLMv2encrypt(mem_ctx, name_user, name_domain,
     1366                                      pass,
     1367                                      &server_chal,
     1368                                      &names_blob,
     1369                                      &lm_resp, &nt_resp, NULL, NULL)) {
     1370                        data_blob_free(&names_blob);
     1371                        DEBUG(0, ("winbindd_pam_auth: SMBNTLMv2encrypt() failed!\n"));
     1372                        result = NT_STATUS_NO_MEMORY;
     1373                        goto done;
     1374                }
     1375                data_blob_free(&names_blob);
     1376        } else {
     1377                lm_resp = data_blob_null;
     1378                SMBNTencrypt(pass, chal, local_nt_response);
     1379
     1380                nt_resp = data_blob_talloc(mem_ctx, local_nt_response,
     1381                                           sizeof(local_nt_response));
     1382        }
     1383
     1384        if (strequal(name_domain, get_global_sam_name())) {
     1385                DATA_BLOB chal_blob = data_blob_const(chal, sizeof(chal));
     1386
     1387                result = winbindd_dual_auth_passdb(
     1388                        mem_ctx, name_domain, name_user,
     1389                        &chal_blob, &lm_resp, &nt_resp, info3);
     1390                goto done;
     1391        }
     1392
     1393        /* check authentication loop */
     1394
     1395        result = winbind_samlogon_retry_loop(domain,
     1396                                             mem_ctx,
     1397                                             0,
     1398                                             domain->dcname,
     1399                                             name_user,
     1400                                             name_domain,
     1401                                             global_myname(),
     1402                                             chal,
     1403                                             lm_resp,
     1404                                             nt_resp,
     1405                                             &my_info3);
     1406        if (!NT_STATUS_IS_OK(result)) {
     1407                goto done;
     1408        }
    14411409
    14421410        /* handle the case where a NT4 DC does not fill in the acct_flags in
     
    14441412         * caller, we look up the account flags ourselve - gd */
    14451413
    1446         if ((state->request->flags & WBFLAG_PAM_INFO3_TEXT) &&
     1414        if ((request_flags & WBFLAG_PAM_INFO3_TEXT) &&
    14471415            NT_STATUS_IS_OK(result) && (my_info3->base.acct_flags == 0)) {
    14481416
     
    14501418                struct policy_handle samr_domain_handle, user_pol;
    14511419                union samr_UserInfo *info = NULL;
    1452                 NTSTATUS status_tmp;
     1420                NTSTATUS status_tmp, result_tmp;
    14531421                uint32 acct_flags;
    1454 
    1455                 status_tmp = cm_connect_sam(contact_domain, state->mem_ctx,
     1422                struct dcerpc_binding_handle *b;
     1423
     1424                status_tmp = cm_connect_sam(domain, mem_ctx,
    14561425                                            &samr_pipe, &samr_domain_handle);
    14571426
     
    14621431                }
    14631432
    1464                 status_tmp = rpccli_samr_OpenUser(samr_pipe, state->mem_ctx,
     1433                b = samr_pipe->binding_handle;
     1434
     1435                status_tmp = dcerpc_samr_OpenUser(b, mem_ctx,
    14651436                                                  &samr_domain_handle,
    14661437                                                  MAXIMUM_ALLOWED_ACCESS,
    14671438                                                  my_info3->base.rid,
    1468                                                   &user_pol);
     1439                                                  &user_pol,
     1440                                                  &result_tmp);
    14691441
    14701442                if (!NT_STATUS_IS_OK(status_tmp)) {
     
    14731445                        goto done;
    14741446                }
    1475 
    1476                 status_tmp = rpccli_samr_QueryUserInfo(samr_pipe, state->mem_ctx,
     1447                if (!NT_STATUS_IS_OK(result_tmp)) {
     1448                        DEBUG(3, ("could not open user handle on SAMR pipe: %s\n",
     1449                                nt_errstr(result_tmp)));
     1450                        goto done;
     1451                }
     1452
     1453                status_tmp = dcerpc_samr_QueryUserInfo(b, mem_ctx,
    14771454                                                       &user_pol,
    14781455                                                       16,
    1479                                                        &info);
     1456                                                       &info,
     1457                                                       &result_tmp);
    14801458
    14811459                if (!NT_STATUS_IS_OK(status_tmp)) {
    14821460                        DEBUG(3, ("could not query user info on SAMR pipe: %s\n",
    14831461                                nt_errstr(status_tmp)));
    1484                         rpccli_samr_Close(samr_pipe, state->mem_ctx, &user_pol);
     1462                        dcerpc_samr_Close(b, mem_ctx, &user_pol, &result_tmp);
    14851463                        goto done;
    14861464                }
     1465                if (!NT_STATUS_IS_OK(result_tmp)) {
     1466                        DEBUG(3, ("could not query user info on SAMR pipe: %s\n",
     1467                                nt_errstr(result_tmp)));
     1468                        dcerpc_samr_Close(b, mem_ctx, &user_pol, &result_tmp);
     1469                        goto done;
     1470                }
    14871471
    14881472                acct_flags = info->info16.acct_flags;
    14891473
    14901474                if (acct_flags == 0) {
    1491                         rpccli_samr_Close(samr_pipe, state->mem_ctx, &user_pol);
     1475                        dcerpc_samr_Close(b, mem_ctx, &user_pol, &result_tmp);
    14921476                        goto done;
    14931477                }
     
    14971481                DEBUG(10,("successfully retrieved acct_flags 0x%x\n", acct_flags));
    14981482
    1499                 rpccli_samr_Close(samr_pipe, state->mem_ctx, &user_pol);
     1483                dcerpc_samr_Close(b, mem_ctx, &user_pol, &result_tmp);
    15001484        }
    15011485
     
    15251509                  state->request->data.auth.user));
    15261510
    1527         if (!check_request_flags(state->request->flags)) {
    1528                 result = NT_STATUS_INVALID_PARAMETER_MIX;
    1529                 goto done;
    1530         }
    1531 
    15321511        /* Parse domain and username */
    15331512
     
    15481527
    15491528        if ( mapped_user != state->request->data.auth.user ) {
    1550                 fstr_sprintf( domain_user, "%s\\%s", name_domain, name_user );
     1529                fstr_sprintf( domain_user, "%s%c%s", name_domain,
     1530                        *lp_winbind_separator(),
     1531                        name_user );
    15511532                safe_strcpy( state->request->data.auth.user, domain_user,
    15521533                             sizeof(state->request->data.auth.user)-1 );
    15531534        }
    15541535
    1555         if (domain->online == false) {
     1536        if (!domain->online) {
    15561537                result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
    15571538                if (domain->startup) {
     
    16071588                    NT_STATUS_EQUAL(result, NT_STATUS_PASSWORD_MUST_CHANGE) ||
    16081589                    NT_STATUS_EQUAL(result, NT_STATUS_WRONG_PASSWORD)) {
    1609                         goto process_result;
     1590                        goto done;
    16101591                }
    16111592
     
    16211602        /* Check for Samlogon authentication */
    16221603        if (domain->online) {
    1623                 result = winbindd_dual_pam_auth_samlogon(domain, state, &info3);
     1604                result = winbindd_dual_pam_auth_samlogon(
     1605                        state->mem_ctx, domain,
     1606                        state->request->data.auth.user,
     1607                        state->request->data.auth.pass,
     1608                        state->request->flags,
     1609                        &info3);
    16241610
    16251611                if (NT_STATUS_IS_OK(result)) {
     
    16701656        if (NT_STATUS_IS_OK(result)) {
    16711657
    1672                 DOM_SID user_sid;
     1658                struct dom_sid user_sid;
    16731659
    16741660                /* In all codepaths where result == NT_STATUS_OK info3 must have
     
    16791665                }
    16801666
    1681                 wcache_invalidate_samlogon(find_domain_from_name(name_domain), info3);
     1667                sid_compose(&user_sid, info3->base.domain_sid,
     1668                            info3->base.rid);
     1669
     1670                wcache_invalidate_samlogon(find_domain_from_name(name_domain),
     1671                                           &user_sid);
    16821672                netsamlogon_cache_store(name_user, info3);
    16831673
     
    16871677                   domain). */
    16881678                if ( domain->primary ) {
    1689                         sid_compose(&user_sid, info3->base.domain_sid,
    1690                                     info3->base.rid);
    16911679                        cache_name2sid(domain, name_domain, name_user,
    16921680                                       SID_NAME_USER, &user_sid);
     
    17051693                }
    17061694
    1707                 result = append_auth_data(state, info3, name_domain,
    1708                                           name_user);
     1695                result = append_auth_data(state->mem_ctx, state->response,
     1696                                          state->request->flags, info3,
     1697                                          name_domain, name_user);
    17091698                if (!NT_STATUS_IS_OK(result)) {
    17101699                        goto done;
    17111700                }
    17121701
    1713                 if ((state->request->flags & WBFLAG_PAM_CACHED_LOGIN)) {
    1714 
    1715                         /* Store in-memory creds for single-signon using ntlm_auth. */
    1716                         result = winbindd_add_memory_creds(state->request->data.auth.user,
    1717                                                         get_uid_from_state(state),
    1718                                                         state->request->data.auth.pass);
    1719 
    1720                         if (!NT_STATUS_IS_OK(result)) {
    1721                                 DEBUG(10,("Failed to store memory creds: %s\n", nt_errstr(result)));
    1722                                 goto done;
    1723                         }
    1724 
    1725                         if (lp_winbind_offline_logon()) {
    1726                                 result = winbindd_store_creds(domain,
    1727                                                       state->mem_ctx,
     1702                if ((state->request->flags & WBFLAG_PAM_CACHED_LOGIN)
     1703                    && lp_winbind_offline_logon()) {
     1704
     1705                        result = winbindd_store_creds(domain,
    17281706                                                      state->request->data.auth.user,
    17291707                                                      state->request->data.auth.pass,
    1730                                                       info3, NULL);
    1731                                 if (!NT_STATUS_IS_OK(result)) {
    1732 
    1733                                         /* Release refcount. */
    1734                                         winbindd_delete_memory_creds(state->request->data.auth.user);
    1735 
    1736                                         DEBUG(10,("Failed to store creds: %s\n", nt_errstr(result)));
    1737                                         goto done;
    1738                                 }
    1739                         }
    1740                 }
    1741 
     1708                                                      info3);
     1709                }
    17421710
    17431711                if (state->request->flags & WBFLAG_PAM_GET_PWD_POLICY) {
     
    17521720                        result = NT_STATUS_NOT_SUPPORTED;
    17531721                        if (our_domain == domain ) {
    1754                                 result = fillup_password_policy(our_domain, state);
     1722                                result = fillup_password_policy(
     1723                                        our_domain, state->response);
    17551724                        }
    17561725
     
    17841753}
    17851754
    1786 
    1787 /**********************************************************************
    1788  Challenge Response Authentication Protocol
    1789 **********************************************************************/
    1790 
    1791 void winbindd_pam_auth_crap(struct winbindd_cli_state *state)
    1792 {
    1793         struct winbindd_domain *domain = NULL;
    1794         const char *domain_name = NULL;
    1795         NTSTATUS result;
    1796 
    1797         if (!check_request_flags(state->request->flags)) {
    1798                 result = NT_STATUS_INVALID_PARAMETER_MIX;
    1799                 goto done;
    1800         }
    1801 
    1802         if (!state->privileged) {
    1803                 DEBUG(2, ("winbindd_pam_auth_crap: non-privileged access "
    1804                           "denied.  !\n"));
    1805                 DEBUGADD(2, ("winbindd_pam_auth_crap: Ensure permissions "
    1806                              "on %s are set correctly.\n",
    1807                              get_winbind_priv_pipe_dir()));
    1808                 /* send a better message than ACCESS_DENIED */
    1809                 fstr_sprintf(state->response->data.auth.error_string,
    1810                              "winbind client not authorized to use "
    1811                              "winbindd_pam_auth_crap. Ensure permissions on "
    1812                              "%s are set correctly.",
    1813                              get_winbind_priv_pipe_dir());
    1814                 result = NT_STATUS_ACCESS_DENIED;
    1815                 goto done;
    1816         }
    1817 
    1818         /* Ensure null termination */
    1819         state->request->data.auth_crap.user
    1820                 [sizeof(state->request->data.auth_crap.user)-1]=0;
    1821         state->request->data.auth_crap.domain
    1822                 [sizeof(state->request->data.auth_crap.domain)-1]=0;
    1823 
    1824         DEBUG(3, ("[%5lu]: pam auth crap domain: [%s] user: %s\n",
    1825                   (unsigned long)state->pid,
    1826                   state->request->data.auth_crap.domain,
    1827                   state->request->data.auth_crap.user));
    1828 
    1829         if (*state->request->data.auth_crap.domain != '\0') {
    1830                 domain_name = state->request->data.auth_crap.domain;
    1831         } else if (lp_winbind_use_default_domain()) {
    1832                 domain_name = lp_workgroup();
    1833         }
    1834 
    1835         if (domain_name != NULL)
    1836                 domain = find_auth_domain(state->request->flags, domain_name);
    1837 
    1838         if (domain != NULL) {
    1839                 sendto_domain(state, domain);
    1840                 return;
    1841         }
    1842 
    1843         result = NT_STATUS_NO_SUCH_USER;
    1844 
    1845  done:
    1846         set_auth_errors(state->response, result);
    1847         DEBUG(5, ("CRAP authentication for %s\\%s returned %s (PAM: %d)\n",
    1848                   state->request->data.auth_crap.domain,
    1849                   state->request->data.auth_crap.user,
    1850                   state->response->data.auth.nt_status_string,
    1851                   state->response->data.auth.pam_error));
    1852         request_error(state);
    1853         return;
    1854 }
    1855 
    1856 
    18571755enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
    18581756                                                 struct winbindd_cli_state *state)
     
    18601758        NTSTATUS result;
    18611759        struct netr_SamInfo3 *info3 = NULL;
    1862         struct rpc_pipe_client *netlogon_pipe;
    18631760        const char *name_user = NULL;
    18641761        const char *name_domain = NULL;
    18651762        const char *workstation;
    1866         struct winbindd_domain *contact_domain;
    1867         int attempts = 0;
    1868         bool retry;
    18691763
    18701764        DATA_BLOB lm_resp, nt_resp;
     
    18771771        state->request->data.auth_crap.domain[sizeof(state->request->data.auth_crap.domain)-1]=0;
    18781772
    1879         if (!check_request_flags(state->request->flags)) {
    1880                 result = NT_STATUS_INVALID_PARAMETER_MIX;
    1881                 goto done;
    1882         }
    1883 
    18841773        name_user = state->request->data.auth_crap.user;
    1885 
    1886         if (*state->request->data.auth_crap.domain) {
    1887                 name_domain = state->request->data.auth_crap.domain;
    1888         } else if (lp_winbind_use_default_domain()) {
    1889                 name_domain = lp_workgroup();
    1890         } else {
    1891                 DEBUG(5,("no domain specified with username (%s) - failing auth\n",
    1892                          name_user));
    1893                 result = NT_STATUS_NO_SUCH_USER;
    1894                 goto done;
    1895         }
     1774        name_domain = state->request->data.auth_crap.domain;
     1775        workstation = state->request->data.auth_crap.workstation;
    18961776
    18971777        DEBUG(3, ("[%5lu]: pam auth crap domain: %s user: %s\n", (unsigned long)state->pid,
    18981778                  name_domain, name_user));
    1899 
    1900         if (*state->request->data.auth_crap.workstation) {
    1901                 workstation = state->request->data.auth_crap.workstation;
    1902         } else {
    1903                 workstation = global_myname();
    1904         }
    19051779
    19061780        if (state->request->data.auth_crap.lm_resp_len > sizeof(state->request->data.auth_crap.lm_resp)
     
    19291803        }
    19301804
    1931         /* what domain should we contact? */
    1932 
    1933         if ( IS_DC ) {
    1934                 if (!(contact_domain = find_domain_from_name(name_domain))) {
    1935                         DEBUG(3, ("Authentication for domain for [%s] -> [%s]\\[%s] failed as %s is not a trusted domain\n",
    1936                                   state->request->data.auth_crap.user, name_domain, name_user, name_domain));
    1937                         result = NT_STATUS_NO_SUCH_USER;
    1938                         goto done;
    1939                 }
    1940         } else {
    1941                 if (is_myname(name_domain)) {
    1942                         DEBUG(3, ("Authentication for domain %s (local domain to this server) not supported at this stage\n", name_domain));
    1943                         result =  NT_STATUS_NO_SUCH_USER;
    1944                         goto done;
    1945                 }
    1946                 contact_domain = find_our_domain();
    1947         }
    1948 
    1949         do {
    1950                 netlogon_fn_t logon_fn;
    1951                 const struct cli_pipe_auth_data *auth;
    1952                 uint32_t neg_flags = 0;
    1953 
    1954                 retry = false;
    1955 
    1956                 netlogon_pipe = NULL;
    1957                 result = cm_connect_netlogon(contact_domain, &netlogon_pipe);
    1958 
    1959                 if (!NT_STATUS_IS_OK(result)) {
    1960                         DEBUG(3, ("could not open handle to NETLOGON pipe (error: %s)\n",
    1961                                   nt_errstr(result)));
    1962                         goto done;
    1963                 }
    1964                 auth = netlogon_pipe->auth;
    1965                 if (netlogon_pipe->dc) {
    1966                         neg_flags = netlogon_pipe->dc->negotiate_flags;
    1967                 }
    1968 
    1969                 if (auth == NULL) {
    1970                         domain->can_do_validation6 = false;
    1971                 } else if (auth->auth_type != PIPE_AUTH_TYPE_SCHANNEL) {
    1972                         domain->can_do_validation6 = false;
    1973                 } else if (auth->auth_level != DCERPC_AUTH_LEVEL_PRIVACY) {
    1974                         domain->can_do_validation6 = false;
    1975                 } else if (!(neg_flags & NETLOGON_NEG_CROSS_FOREST_TRUSTS)) {
    1976                         domain->can_do_validation6 = false;
    1977                 } else if (!(neg_flags & NETLOGON_NEG_AUTHENTICATED_RPC)) {
    1978                         domain->can_do_validation6 = false;
    1979                 }
    1980 
    1981                 logon_fn = contact_domain->can_do_samlogon_ex
    1982                         ? rpccli_netlogon_sam_network_logon_ex
    1983                         : rpccli_netlogon_sam_network_logon;
    1984 
    1985                 result = logon_fn(netlogon_pipe,
    1986                                   state->mem_ctx,
    1987                                   state->request->data.auth_crap.logon_parameters,
    1988                                   contact_domain->dcname,
    1989                                   name_user,
    1990                                   name_domain,
    1991                                   /* Bug #3248 - found by Stefan Burkei. */
    1992                                   workstation, /* We carefully set this above so use it... */
    1993                                   state->request->data.auth_crap.chal,
    1994                                   domain->can_do_validation6 ? 6 : 3,
    1995                                   lm_resp,
    1996                                   nt_resp,
    1997                                   &info3);
    1998 
    1999                 if ((NT_STATUS_V(result) == DCERPC_FAULT_OP_RNG_ERROR)
    2000                     && contact_domain->can_do_samlogon_ex) {
    2001                         DEBUG(3, ("Got a DC that can not do NetSamLogonEx, "
    2002                                   "retrying with NetSamLogon\n"));
    2003                         contact_domain->can_do_samlogon_ex = false;
    2004                         /*
    2005                          * It's likely that the server also does not support
    2006                          * validation level 6
    2007                          */
    2008                         domain->can_do_validation6 = false;
    2009                         retry = true;
    2010                         continue;
    2011                 }
    2012 
    2013                 if (domain->can_do_validation6 &&
    2014                     (NT_STATUS_EQUAL(result, NT_STATUS_INVALID_INFO_CLASS) ||
    2015                      NT_STATUS_EQUAL(result, NT_STATUS_INVALID_PARAMETER) ||
    2016                      NT_STATUS_EQUAL(result, NT_STATUS_BUFFER_TOO_SMALL))) {
    2017                         DEBUG(3,("Got a DC that can not do validation level 6, "
    2018                                   "retrying with level 3\n"));
    2019                         domain->can_do_validation6 = false;
    2020                         retry = true;
    2021                         continue;
    2022                 }
    2023 
    2024                 /*
    2025                  * we increment this after the "feature negotiation"
    2026                  * for can_do_samlogon_ex and can_do_validation6
    2027                  */
    2028                 attempts += 1;
    2029 
    2030                 /* We have to try a second time as cm_connect_netlogon
    2031                    might not yet have noticed that the DC has killed
    2032                    our connection. */
    2033 
    2034                 if (!rpccli_is_connected(netlogon_pipe)) {
    2035                         retry = true;
    2036                         continue;
    2037                 }
    2038 
    2039                 /* if we get access denied, a possible cause was that we had and open
    2040                    connection to the DC, but someone changed our machine account password
    2041                    out from underneath us using 'net rpc changetrustpw' */
    2042 
    2043                 if ( NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED) ) {
    2044                         DEBUG(3,("winbindd_pam_auth: sam_logon returned "
    2045                                  "ACCESS_DENIED.  Maybe the trust account "
    2046                                 "password was changed and we didn't know it. "
    2047                                  "Killing connections to domain %s\n",
    2048                                 name_domain));
    2049                         invalidate_cm_connection(&contact_domain->conn);
    2050                         retry = true;
    2051                 }
    2052 
    2053         } while ( (attempts < 2) && retry );
     1805        if (strequal(name_domain, get_global_sam_name())) {
     1806                DATA_BLOB chal_blob = data_blob_const(
     1807                        state->request->data.auth_crap.chal,
     1808                        sizeof(state->request->data.auth_crap.chal));
     1809
     1810                result = winbindd_dual_auth_passdb(
     1811                        state->mem_ctx, name_domain, name_user,
     1812                        &chal_blob, &lm_resp, &nt_resp, &info3);
     1813                goto process_result;
     1814        }
     1815
     1816        result = winbind_samlogon_retry_loop(domain,
     1817                                             state->mem_ctx,
     1818                                             state->request->data.auth_crap.logon_parameters,
     1819                                             domain->dcname,
     1820                                             name_user,
     1821                                             name_domain,
     1822                                             /* Bug #3248 - found by Stefan Burkei. */
     1823                                             workstation, /* We carefully set this above so use it... */
     1824                                             state->request->data.auth_crap.chal,
     1825                                             lm_resp,
     1826                                             nt_resp,
     1827                                             &info3);
     1828        if (!NT_STATUS_IS_OK(result)) {
     1829                goto done;
     1830        }
     1831
     1832process_result:
    20541833
    20551834        if (NT_STATUS_IS_OK(result)) {
    2056 
    2057                 wcache_invalidate_samlogon(find_domain_from_name(name_domain), info3);
     1835                struct dom_sid user_sid;
     1836
     1837                sid_compose(&user_sid, info3->base.domain_sid,
     1838                            info3->base.rid);
     1839                wcache_invalidate_samlogon(find_domain_from_name(name_domain),
     1840                                           &user_sid);
    20581841                netsamlogon_cache_store(name_user, info3);
    20591842
     
    20711854                }
    20721855
    2073                 result = append_auth_data(state, info3, name_domain,
    2074                                           name_user);
     1856                result = append_auth_data(state->mem_ctx, state->response,
     1857                                          state->request->flags, info3,
     1858                                          name_domain, name_user);
    20751859                if (!NT_STATUS_IS_OK(result)) {
    20761860                        goto done;
     
    21021886}
    21031887
    2104 /* Change a user password */
    2105 
    2106 void winbindd_pam_chauthtok(struct winbindd_cli_state *state)
    2107 {
    2108         fstring domain, user;
    2109         char *mapped_user;
    2110         struct winbindd_domain *contact_domain;
    2111         NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
    2112 
    2113         DEBUG(3, ("[%5lu]: pam chauthtok %s\n", (unsigned long)state->pid,
    2114                 state->request->data.chauthtok.user));
    2115 
    2116         /* Setup crap */
    2117 
    2118         nt_status = normalize_name_unmap(state->mem_ctx,
    2119                                          state->request->data.chauthtok.user,
    2120                                          &mapped_user);
    2121 
    2122         /* Update the chauthtok name if we did any mapping */
    2123 
    2124         if (NT_STATUS_IS_OK(nt_status) ||
    2125             NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_RENAMED))
    2126         {
    2127                 fstrcpy(state->request->data.chauthtok.user, mapped_user);
    2128         }
    2129 
    2130         /* Must pass in state->...chauthtok.user because
    2131            canonicalize_username() assumes an fstring().  Since
    2132            we have already copied it (if necessary), this is ok. */
    2133 
    2134         if (!canonicalize_username(state->request->data.chauthtok.user, domain, user)) {
    2135                 set_auth_errors(state->response, NT_STATUS_NO_SUCH_USER);
    2136                 DEBUG(5, ("winbindd_pam_chauthtok: canonicalize_username %s failed with %s"
    2137                           "(PAM: %d)\n",
    2138                           state->request->data.auth.user,
    2139                           state->response->data.auth.nt_status_string,
    2140                           state->response->data.auth.pam_error));
    2141                 request_error(state);
    2142                 return;
    2143         }
    2144 
    2145         contact_domain = find_domain_from_name(domain);
    2146         if (!contact_domain) {
    2147                 set_auth_errors(state->response, NT_STATUS_NO_SUCH_USER);
    2148                 DEBUG(3, ("Cannot change password for [%s] -> [%s]\\[%s] as %s is not a trusted domain\n",
    2149                           state->request->data.chauthtok.user, domain, user, domain));
    2150                 request_error(state);
    2151                 return;
    2152         }
    2153 
    2154         sendto_domain(state, contact_domain);
    2155 }
    2156 
    21571888enum winbindd_result winbindd_dual_pam_chauthtok(struct winbindd_domain *contact_domain,
    21581889                                                 struct winbindd_cli_state *state)
     
    21611892        char *newpass = NULL;
    21621893        struct policy_handle dom_pol;
    2163         struct rpc_pipe_client *cli;
     1894        struct rpc_pipe_client *cli = NULL;
    21641895        bool got_info = false;
    21651896        struct samr_DomInfo1 *info = NULL;
    2166         struct samr_ChangeReject *reject = NULL;
     1897        struct userPwdChangeFailureInformation *reject = NULL;
    21671898        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
    21681899        fstring domain, user;
     1900        struct dcerpc_binding_handle *b = NULL;
     1901
     1902        ZERO_STRUCT(dom_pol);
    21691903
    21701904        DEBUG(3, ("[%5lu]: dual pam chauthtok %s\n", (unsigned long)state->pid,
     
    21911925                goto done;
    21921926        }
     1927
     1928        b = cli->binding_handle;
    21931929
    21941930        result = rpccli_samr_chgpasswd_user3(cli, state->mem_ctx,
     
    22061942
    22071943                state->response->data.auth.reject_reason =
    2208                         reject->reason;
     1944                        reject->extendedFailureReason;
    22091945
    22101946                got_info = true;
     
    22171953
    22181954        /* only fallback when the chgpasswd_user3 call is not supported */
    2219         if ((NT_STATUS_EQUAL(result, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR))) ||
    2220                    (NT_STATUS_EQUAL(result, NT_STATUS_NOT_SUPPORTED)) ||
    2221                    (NT_STATUS_EQUAL(result, NT_STATUS_BUFFER_TOO_SMALL)) ||
    2222                    (NT_STATUS_EQUAL(result, NT_STATUS_NOT_IMPLEMENTED))) {
     1955        if (NT_STATUS_EQUAL(result, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE) ||
     1956            NT_STATUS_EQUAL(result, NT_STATUS_NOT_SUPPORTED) ||
     1957            NT_STATUS_EQUAL(result, NT_STATUS_BUFFER_TOO_SMALL) ||
     1958            NT_STATUS_EQUAL(result, NT_STATUS_NOT_IMPLEMENTED)) {
    22231959
    22241960                DEBUG(10,("Password change with chgpasswd_user3 failed with: %s, retrying chgpasswd_user2\n",
     
    22371973done:
    22381974
    2239         if (NT_STATUS_IS_OK(result) && (state->request->flags & WBFLAG_PAM_CACHED_LOGIN)) {
    2240 
    2241                 /* Update the single sign-on memory creds. */
    2242                 result = winbindd_replace_memory_creds(state->request->data.chauthtok.user,
    2243                                                         newpass);
    2244 
    2245                 /* When we login from gdm or xdm and password expires,
    2246                  * we change password, but there are no memory crendentials
    2247                  * So, winbindd_replace_memory_creds() returns
    2248                  * NT_STATUS_OBJECT_NAME_NOT_FOUND. This is not a failure.
     1975        if (NT_STATUS_IS_OK(result)
     1976            && (state->request->flags & WBFLAG_PAM_CACHED_LOGIN)
     1977            && lp_winbind_offline_logon()) {
     1978                result = winbindd_update_creds_by_name(contact_domain, user,
     1979                                                       newpass);
     1980                /* Again, this happens when we login from gdm or xdm
     1981                 * and the password expires, *BUT* cached crendentials
     1982                 * doesn't exist. winbindd_update_creds_by_name()
     1983                 * returns NT_STATUS_NO_SUCH_USER.
     1984                 * This is not a failure.
    22491985                 * --- BoYang
    22501986                 * */
    2251                 if (NT_STATUS_EQUAL(result, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
     1987                if (NT_STATUS_EQUAL(result, NT_STATUS_NO_SUCH_USER)) {
    22521988                        result = NT_STATUS_OK;
    22531989                }
    22541990
    22551991                if (!NT_STATUS_IS_OK(result)) {
    2256                         DEBUG(10,("Failed to replace memory creds: %s\n", nt_errstr(result)));
     1992                        DEBUG(10, ("Failed to store creds: %s\n",
     1993                                   nt_errstr(result)));
    22571994                        goto process_result;
    22581995                }
    2259 
    2260                 if (lp_winbind_offline_logon()) {
    2261                         result = winbindd_update_creds_by_name(contact_domain,
    2262                                                          state->mem_ctx, user,
    2263                                                          newpass);
    2264                         /* Again, this happens when we login from gdm or xdm
    2265                          * and the password expires, *BUT* cached crendentials
    2266                          * doesn't exist. winbindd_update_creds_by_name()
    2267                          * returns NT_STATUS_NO_SUCH_USER.
    2268                          * This is not a failure.
    2269                          * --- BoYang
    2270                          * */
    2271                         if (NT_STATUS_EQUAL(result, NT_STATUS_NO_SUCH_USER)) {
    2272                                 result = NT_STATUS_OK;
    2273                         }
    2274 
    2275                         if (!NT_STATUS_IS_OK(result)) {
    2276                                 DEBUG(10,("Failed to store creds: %s\n", nt_errstr(result)));
    2277                                 goto process_result;
    2278                         }
    2279                 }
    22801996        }
    22811997
     
    22842000                NTSTATUS policy_ret;
    22852001
    2286                 policy_ret = fillup_password_policy(contact_domain, state);
     2002                policy_ret = fillup_password_policy(
     2003                        contact_domain, state->response);
    22872004
    22882005                /* failure of this is non critical, it will just provide no
     
    22972014
    22982015process_result:
     2016
     2017        if (strequal(contact_domain->name, get_global_sam_name())) {
     2018                /* FIXME: internal rpc pipe does not cache handles yet */
     2019                if (b) {
     2020                        if (is_valid_policy_hnd(&dom_pol)) {
     2021                                NTSTATUS _result;
     2022                                dcerpc_samr_Close(b, state->mem_ctx, &dom_pol, &_result);
     2023                        }
     2024                        TALLOC_FREE(cli);
     2025                }
     2026        }
    22992027
    23002028        set_auth_errors(state->response, result);
     
    23102038}
    23112039
    2312 void winbindd_pam_logoff(struct winbindd_cli_state *state)
    2313 {
    2314         struct winbindd_domain *domain;
    2315         fstring name_domain, user;
    2316         uid_t caller_uid = (uid_t)-1;
    2317         uid_t request_uid = state->request->data.logoff.uid;
    2318 
    2319         DEBUG(3, ("[%5lu]: pam logoff %s\n", (unsigned long)state->pid,
    2320                 state->request->data.logoff.user));
    2321 
    2322         /* Ensure null termination */
    2323         state->request->data.logoff.user
    2324                 [sizeof(state->request->data.logoff.user)-1]='\0';
    2325 
    2326         state->request->data.logoff.krb5ccname
    2327                 [sizeof(state->request->data.logoff.krb5ccname)-1]='\0';
    2328 
    2329         if (request_uid == (gid_t)-1) {
    2330                 goto failed;
    2331         }
    2332 
    2333         if (!canonicalize_username(state->request->data.logoff.user, name_domain, user)) {
    2334                 goto failed;
    2335         }
    2336 
    2337         if ((domain = find_auth_domain(state->request->flags,
    2338                                        name_domain)) == NULL) {
    2339                 goto failed;
    2340         }
    2341 
    2342         if ((sys_getpeereid(state->sock, &caller_uid)) != 0) {
    2343                 DEBUG(1,("winbindd_pam_logoff: failed to check peerid: %s\n",
    2344                         strerror(errno)));
    2345                 goto failed;
    2346         }
    2347 
    2348         switch (caller_uid) {
    2349                 case -1:
    2350                         goto failed;
    2351                 case 0:
    2352                         /* root must be able to logoff any user - gd */
    2353                         state->request->data.logoff.uid = request_uid;
    2354                         break;
    2355                 default:
    2356                         if (caller_uid != request_uid) {
    2357                                 DEBUG(1,("winbindd_pam_logoff: caller requested invalid uid\n"));
    2358                                 goto failed;
    2359                         }
    2360                         state->request->data.logoff.uid = caller_uid;
    2361                         break;
    2362         }
    2363 
    2364         sendto_domain(state, domain);
    2365         return;
    2366 
    2367  failed:
    2368         set_auth_errors(state->response, NT_STATUS_NO_SUCH_USER);
    2369         DEBUG(5, ("Pam Logoff for %s returned %s "
    2370                   "(PAM: %d)\n",
    2371                   state->request->data.logoff.user,
    2372                   state->response->data.auth.nt_status_string,
    2373                   state->response->data.auth.pam_error));
    2374         request_error(state);
    2375         return;
    2376 }
    2377 
    23782040enum winbindd_result winbindd_dual_pam_logoff(struct winbindd_domain *domain,
    23792041                                              struct winbindd_cli_state *state)
     
    24302092process_result:
    24312093
    2432         winbindd_delete_memory_creds(state->request->data.logoff.user);
    24332094
    24342095        set_auth_errors(state->response, result);
     
    24382099
    24392100/* Change user password with auth crap*/
    2440 
    2441 void winbindd_pam_chng_pswd_auth_crap(struct winbindd_cli_state *state)
    2442 {
    2443         struct winbindd_domain *domain = NULL;
    2444         const char *domain_name = NULL;
    2445 
    2446         /* Ensure null termination */
    2447         state->request->data.chng_pswd_auth_crap.user[
    2448                 sizeof(state->request->data.chng_pswd_auth_crap.user)-1]=0;
    2449         state->request->data.chng_pswd_auth_crap.domain[
    2450                 sizeof(state->request->data.chng_pswd_auth_crap.domain)-1]=0;
    2451 
    2452         DEBUG(3, ("[%5lu]: pam change pswd auth crap domain: %s user: %s\n",
    2453                   (unsigned long)state->pid,
    2454                   state->request->data.chng_pswd_auth_crap.domain,
    2455                   state->request->data.chng_pswd_auth_crap.user));
    2456 
    2457         if (*state->request->data.chng_pswd_auth_crap.domain != '\0') {
    2458                 domain_name = state->request->data.chng_pswd_auth_crap.domain;
    2459         } else if (lp_winbind_use_default_domain()) {
    2460                 domain_name = lp_workgroup();
    2461         }
    2462 
    2463         if (domain_name != NULL)
    2464                 domain = find_domain_from_name(domain_name);
    2465 
    2466         if (domain != NULL) {
    2467                 DEBUG(7, ("[%5lu]: pam auth crap changing pswd in domain: "
    2468                           "%s\n", (unsigned long)state->pid,domain->name));
    2469                 sendto_domain(state, domain);
    2470                 return;
    2471         }
    2472 
    2473         set_auth_errors(state->response, NT_STATUS_NO_SUCH_USER);
    2474         DEBUG(5, ("CRAP change password  for %s\\%s returned %s (PAM: %d)\n",
    2475                   state->request->data.chng_pswd_auth_crap.domain,
    2476                   state->request->data.chng_pswd_auth_crap.user,
    2477                   state->response->data.auth.nt_status_string,
    2478                   state->response->data.auth.pam_error));
    2479         request_error(state);
    2480         return;
    2481 }
    24822101
    24832102enum winbindd_result winbindd_dual_pam_chng_pswd_auth_crap(struct winbindd_domain *domainSt, struct winbindd_cli_state *state)
     
    24912110        struct policy_handle dom_pol;
    24922111        struct winbindd_domain *contact_domain = domainSt;
    2493         struct rpc_pipe_client *cli;
     2112        struct rpc_pipe_client *cli = NULL;
     2113        struct dcerpc_binding_handle *b = NULL;
     2114
     2115        ZERO_STRUCT(dom_pol);
    24942116
    24952117        /* Ensure null termination */
     
    25402162
    25412163        /* Change password */
    2542         new_nt_password = data_blob_talloc(
    2543                 state->mem_ctx,
     2164        new_nt_password = data_blob_const(
    25442165                state->request->data.chng_pswd_auth_crap.new_nt_pswd,
    25452166                state->request->data.chng_pswd_auth_crap.new_nt_pswd_len);
    25462167
    2547         old_nt_hash_enc = data_blob_talloc(
    2548                 state->mem_ctx,
     2168        old_nt_hash_enc = data_blob_const(
    25492169                state->request->data.chng_pswd_auth_crap.old_nt_hash_enc,
    25502170                state->request->data.chng_pswd_auth_crap.old_nt_hash_enc_len);
    25512171
    25522172        if(state->request->data.chng_pswd_auth_crap.new_lm_pswd_len > 0)        {
    2553                 new_lm_password = data_blob_talloc(
    2554                         state->mem_ctx,
     2173                new_lm_password = data_blob_const(
    25552174                        state->request->data.chng_pswd_auth_crap.new_lm_pswd,
    25562175                        state->request->data.chng_pswd_auth_crap.new_lm_pswd_len);
    25572176
    2558                 old_lm_hash_enc = data_blob_talloc(
    2559                         state->mem_ctx,
     2177                old_lm_hash_enc = data_blob_const(
    25602178                        state->request->data.chng_pswd_auth_crap.old_lm_hash_enc,
    25612179                        state->request->data.chng_pswd_auth_crap.old_lm_hash_enc_len);
     
    25732191        }
    25742192
     2193        b = cli->binding_handle;
     2194
    25752195        result = rpccli_samr_chng_pswd_auth_crap(
    25762196                cli, state->mem_ctx, user, new_nt_password, old_nt_hash_enc,
     
    25782198
    25792199 done:
     2200
     2201        if (strequal(contact_domain->name, get_global_sam_name())) {
     2202                /* FIXME: internal rpc pipe does not cache handles yet */
     2203                if (b) {
     2204                        if (is_valid_policy_hnd(&dom_pol)) {
     2205                                NTSTATUS _result;
     2206                                dcerpc_samr_Close(b, state->mem_ctx, &dom_pol, &_result);
     2207                        }
     2208                        TALLOC_FREE(cli);
     2209                }
     2210        }
    25802211
    25812212        set_auth_errors(state->response, result);
  • vendor/current/source3/winbindd/winbindd_ping_dc.c

    r414 r740  
    2020#include "includes.h"
    2121#include "winbindd.h"
    22 #include "librpc/gen_ndr/cli_wbint.h"
     22#include "librpc/gen_ndr/ndr_wbint_c.h"
    2323
    2424struct winbindd_ping_dc_state {
     
    6262        }
    6363
    64         subreq = rpccli_wbint_PingDc_send(state, ev, domain->child.rpccli);
     64        subreq = dcerpc_wbint_PingDc_send(state, ev, dom_child_handle(domain));
    6565        if (tevent_req_nomem(subreq, req)) {
    6666                return tevent_req_post(req, ev);
     
    7878        NTSTATUS status, result;
    7979
    80         status = rpccli_wbint_PingDc_recv(subreq, state, &result);
    81         if (!NT_STATUS_IS_OK(status)) {
     80        status = dcerpc_wbint_PingDc_recv(subreq, state, &result);
     81        if (any_nt_status_not_ok(status, result, &status)) {
    8282                tevent_req_nterror(req, status);
    83                 return;
    84         }
    85         if (!NT_STATUS_IS_OK(result)) {
    86                 tevent_req_nterror(req, result);
    8783                return;
    8884        }
  • vendor/current/source3/winbindd/winbindd_proto.h

    r414 r740  
    2424#define _WINBINDD_PROTO_H_
    2525
    26 
    27 /* The following definitions come from auth/token_util.c  */
    28 
    29 bool nt_token_check_sid ( const DOM_SID *sid, const NT_USER_TOKEN *token );
    30 bool nt_token_check_domain_rid( NT_USER_TOKEN *token, uint32 rid );
    31 NT_USER_TOKEN *get_root_nt_token( void );
    32 NTSTATUS add_aliases(const DOM_SID *domain_sid,
    33                      struct nt_user_token *token);
    34 struct nt_user_token *create_local_nt_token(TALLOC_CTX *mem_ctx,
    35                                             const DOM_SID *user_sid,
    36                                             bool is_guest,
    37                                             int num_groupsids,
    38                                             const DOM_SID *groupsids);
    39 void debug_nt_user_token(int dbg_class, int dbg_lev, NT_USER_TOKEN *token);
    40 void debug_unix_user_token(int dbg_class, int dbg_lev, uid_t uid, gid_t gid,
    41                            int n_groups, gid_t *groups);
    42 
    43 /* The following definitions come from smbd/connection.c  */
    44 
    45 bool yield_connection(connection_struct *conn, const char *name);
    46 int count_current_connections( const char *sharename, bool clear  );
    47 int count_all_current_connections(void);
    48 bool claim_connection(connection_struct *conn, const char *name,
    49                       uint32 msg_flags);
    50 bool register_message_flags(bool doreg, uint32 msg_flags);
    51 
    5226/* The following definitions come from winbindd/winbindd.c  */
    53 
    54 struct event_context *winbind_event_context(void);
    5527struct messaging_context *winbind_messaging_context(void);
    5628void request_error(struct winbindd_cli_state *state);
     
    6032bool winbindd_use_idmap_cache(void);
    6133bool winbindd_use_cache(void);
     34void winbindd_register_handlers(void);
     35const char *get_winbind_pipe_dir(void);
     36char *get_winbind_priv_pipe_dir(void);
    6237int main(int argc, char **argv, char **envp);
    6338
     
    8055                               struct dom_sid **sids,
    8156                               enum lsa_SidType **types);
    82 
    83 /* The following definitions come from winbindd/winbindd_async.c  */
    84 
    85 bool print_sidlist(TALLOC_CTX *mem_ctx, const DOM_SID *sids,
    86                    size_t num_sids, char **result, ssize_t *len);
    87 bool parse_sidlist(TALLOC_CTX *mem_ctx, const char *sidstr,
    88                    DOM_SID **sids, size_t *num_sids);
     57NTSTATUS rpc_lookup_sids(TALLOC_CTX *mem_ctx,
     58                         struct winbindd_domain *domain,
     59                         struct lsa_SidArray *sids,
     60                         struct lsa_RefDomainList **pdomains,
     61                         struct lsa_TransNameArray **pnames);
    8962
    9063/* The following definitions come from winbindd/winbindd_cache.c  */
    9164
    92 void winbindd_check_cache_size(time_t t);
    9365struct cache_entry *centry_start(struct winbindd_domain *domain, NTSTATUS status);
    94 NTSTATUS wcache_cached_creds_exist(struct winbindd_domain *domain, const DOM_SID *sid);
     66NTSTATUS wcache_cached_creds_exist(struct winbindd_domain *domain, const struct dom_sid *sid);
    9567NTSTATUS wcache_get_creds(struct winbindd_domain *domain,
    9668                          TALLOC_CTX *mem_ctx,
    97                           const DOM_SID *sid,
     69                          const struct dom_sid *sid,
    9870                          const uint8 **cached_nt_pass,
    9971                          const uint8 **cached_salt);
    10072NTSTATUS wcache_save_creds(struct winbindd_domain *domain,
    101                            TALLOC_CTX *mem_ctx,
    102                            const DOM_SID *sid,
     73                           const struct dom_sid *sid,
    10374                           const uint8 nt_pass[NT_HASH_LEN]);
    10475void wcache_invalidate_samlogon(struct winbindd_domain *domain,
    105                                 struct netr_SamInfo3 *info3);
     76                                const struct dom_sid *user_sid);
    10677bool wcache_invalidate_cache(void);
     78bool wcache_invalidate_cache_noinit(void);
    10779bool init_wcache(void);
    10880bool initialize_winbindd_cache(void);
     
    12092                                struct dom_sid **sid_mem, char ***names,
    12193                                uint32_t **name_types);
    122 bool lookup_cached_sid(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
     94bool lookup_cached_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid,
    12395                       char **domain_name, char **name,
    12496                       enum lsa_SidType *type);
    125 bool lookup_cached_name(TALLOC_CTX *mem_ctx,
    126                         const char *domain_name,
     97bool lookup_cached_name(const char *domain_name,
    12798                        const char *name,
    128                         DOM_SID *sid,
     99                        struct dom_sid *sid,
    129100                        enum lsa_SidType *type);
    130101void cache_name2sid(struct winbindd_domain *domain,
    131102                    const char *domain_name, const char *name,
    132                     enum lsa_SidType type, const DOM_SID *sid);
     103                    enum lsa_SidType type, const struct dom_sid *sid);
    133104NTSTATUS wcache_name_to_sid(struct winbindd_domain *domain,
    134105                            const char *domain_name,
     
    142113NTSTATUS wcache_lookup_useraliases(struct winbindd_domain *domain,
    143114                                   TALLOC_CTX *mem_ctx,
    144                                    uint32 num_sids, const DOM_SID *sids,
     115                                   uint32 num_sids, const struct dom_sid *sids,
    145116                                   uint32 *pnum_aliases, uint32 **paliases);
    146117NTSTATUS wcache_lookup_usergroups(struct winbindd_domain *domain,
     
    152123void wcache_flush_cache(void);
    153124NTSTATUS wcache_count_cached_creds(struct winbindd_domain *domain, int *count);
    154 NTSTATUS wcache_remove_oldest_cached_creds(struct winbindd_domain *domain, const DOM_SID *sid) ;
     125NTSTATUS wcache_remove_oldest_cached_creds(struct winbindd_domain *domain, const struct dom_sid *sid) ;
    155126bool set_global_winbindd_state_offline(void);
    156127void set_global_winbindd_state_online(void);
     
    162133bool wcache_tdc_add_domain( struct winbindd_domain *domain );
    163134struct winbindd_tdc_domain * wcache_tdc_fetch_domain( TALLOC_CTX *ctx, const char *name );
     135struct winbindd_tdc_domain* wcache_tdc_fetch_domainbysid(TALLOC_CTX *ctx, const struct dom_sid *sid);
    164136void wcache_tdc_clear( void );
     137#ifdef HAVE_ADS
     138struct ads_struct;
    165139NTSTATUS nss_get_info_cached( struct winbindd_domain *domain,
    166                               const DOM_SID *user_sid,
     140                              const struct dom_sid *user_sid,
    167141                              TALLOC_CTX *ctx,
    168                               ADS_STRUCT *ads, LDAPMessage *msg,
    169142                              const char **homedir, const char **shell,
    170143                              const char **gecos, gid_t *p_gid);
     144#endif
    171145bool wcache_store_seqnum(const char *domain_name, uint32_t seqnum,
    172146                         time_t last_seq_check);
     
    182156                                                struct winbindd_cli_state *state);
    183157void winbindd_ccache_save(struct winbindd_cli_state *state);
    184 enum winbindd_result winbindd_dual_ccache_save(
    185         struct winbindd_domain *domain, struct winbindd_cli_state *state);
    186158
    187159/* The following definitions come from winbindd/winbindd_cm.c  */
     
    189161void set_domain_offline(struct winbindd_domain *domain);
    190162void set_domain_online_request(struct winbindd_domain *domain);
    191 void winbind_add_failed_connection_entry(const struct winbindd_domain *domain,
    192                                         const char *server,
    193                                         NTSTATUS result);
    194163void invalidate_cm_connection(struct winbindd_cm_conn *conn);
    195164void close_conns_after_fork(void);
     
    204173NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain,
    205174                             struct rpc_pipe_client **cli);
     175bool fetch_current_dc_from_gencache(TALLOC_CTX *mem_ctx,
     176                                    const char *domain_name,
     177                                    char **p_dc_name, char **p_dc_ip);
    206178
    207179/* The following definitions come from winbindd/winbindd_cred_cache.c  */
     
    236208NTSTATUS winbindd_get_creds(struct winbindd_domain *domain,
    237209                            TALLOC_CTX *mem_ctx,
    238                             const DOM_SID *sid,
     210                            const struct dom_sid *sid,
    239211                            struct netr_SamInfo3 **info3,
    240212                            const uint8 *cached_nt_pass[NT_HASH_LEN],
    241213                            const uint8 *cred_salt[NT_HASH_LEN]);
    242214NTSTATUS winbindd_store_creds(struct winbindd_domain *domain,
    243                               TALLOC_CTX *mem_ctx,
    244215                              const char *user,
    245216                              const char *pass,
    246                               struct netr_SamInfo3 *info3,
    247                               const DOM_SID *user_sid);
     217                              struct netr_SamInfo3 *info3);
    248218NTSTATUS winbindd_update_creds_by_info3(struct winbindd_domain *domain,
    249                                         TALLOC_CTX *mem_ctx,
    250219                                        const char *user,
    251220                                        const char *pass,
    252221                                        struct netr_SamInfo3 *info3);
    253 NTSTATUS winbindd_update_creds_by_sid(struct winbindd_domain *domain,
    254                                       TALLOC_CTX *mem_ctx,
    255                                       const DOM_SID *sid,
    256                                       const char *pass);
    257222NTSTATUS winbindd_update_creds_by_name(struct winbindd_domain *domain,
    258                                        TALLOC_CTX *mem_ctx,
    259223                                       const char *user,
    260224                                       const char *pass);
     
    262226/* The following definitions come from winbindd/winbindd_domain.c  */
    263227
    264 void setup_domain_child(struct winbindd_domain *domain,
    265                         struct winbindd_child *child);
     228void setup_domain_child(struct winbindd_domain *domain);
    266229
    267230/* The following definitions come from winbindd/winbindd_dual.c  */
     231
     232struct dcerpc_binding_handle *dom_child_handle(struct winbindd_domain *domain);
     233struct winbindd_child *choose_domain_child(struct winbindd_domain *domain);
    268234
    269235struct tevent_req *wb_child_request_send(TALLOC_CTX *mem_ctx,
     
    280246                           struct winbindd_response **presponse, int *err);
    281247
    282 void async_domain_request(TALLOC_CTX *mem_ctx,
    283                           struct winbindd_domain *domain,
    284                           struct winbindd_request *request,
    285                           struct winbindd_response *response,
    286                           void (*continuation)(void *private_data_data, bool success),
    287                           void *private_data_data);
    288 void sendto_domain(struct winbindd_cli_state *state,
    289                    struct winbindd_domain *domain);
    290248void setup_child(struct winbindd_domain *domain, struct winbindd_child *child,
    291249                 const struct winbindd_child_dispatch_table *table,
     
    324282                                  struct server_id server_id,
    325283                                  DATA_BLOB *data);
    326 bool winbindd_reinit_after_fork(const char *logfilename);
     284void winbind_msg_ip_dropped(struct messaging_context *msg_ctx,
     285                            void *private_data,
     286                            uint32_t msg_type,
     287                            struct server_id server_id,
     288                            DATA_BLOB *data);
     289void winbind_msg_ip_dropped_parent(struct messaging_context *msg_ctx,
     290                                   void *private_data,
     291                                   uint32_t msg_type,
     292                                   struct server_id server_id,
     293                                   DATA_BLOB *data);
     294NTSTATUS winbindd_reinit_after_fork(const struct winbindd_child *myself,
     295                                    const char *logfilename);
    327296struct winbindd_domain *wb_child_domain(void);
    328297
     
    350319void init_idmap_child(void);
    351320struct winbindd_child *idmap_child(void);
     321struct idmap_domain *idmap_find_domain(const char *domname);
    352322
    353323/* The following definitions come from winbindd/winbindd_locator.c  */
     
    362332                                                        struct winbindd_cli_state *state);
    363333void winbindd_show_sequence(struct winbindd_cli_state *state);
    364 enum winbindd_result winbindd_dual_show_sequence(struct winbindd_domain *domain,
    365                                                  struct winbindd_cli_state *state);
    366334void winbindd_domain_info(struct winbindd_cli_state *state);
     335void winbindd_dc_info(struct winbindd_cli_state *state);
    367336void winbindd_ping(struct winbindd_cli_state *state);
    368337void winbindd_info(struct winbindd_cli_state *state);
     
    373342
    374343/* The following definitions come from winbindd/winbindd_ndr.c  */
    375 
     344struct ndr_print;
    376345void ndr_print_winbindd_child(struct ndr_print *ndr,
    377346                              const char *name,
     
    390359
    391360bool check_request_flags(uint32_t flags);
     361uid_t get_uid_from_request(struct winbindd_request *request);
    392362struct winbindd_domain *find_auth_domain(uint8_t flags,
    393363                                         const char *domain_name);
    394 NTSTATUS check_info3_in_group(struct netr_SamInfo3 *info3,
    395                               const char *group_sid);
    396 NTSTATUS append_auth_data(struct winbindd_cli_state *state,
    397                           struct netr_SamInfo3 *info3,
    398                           const char *name_domain,
    399                           const char *name_user);
    400 void winbindd_pam_auth(struct winbindd_cli_state *state);
    401364enum winbindd_result winbindd_dual_pam_auth(struct winbindd_domain *domain,
    402365                                            struct winbindd_cli_state *state) ;
    403 void winbindd_pam_auth_crap(struct winbindd_cli_state *state);
    404366enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
    405367                                                 struct winbindd_cli_state *state) ;
    406 void winbindd_pam_chauthtok(struct winbindd_cli_state *state);
    407368enum winbindd_result winbindd_dual_pam_chauthtok(struct winbindd_domain *contact_domain,
    408369                                                 struct winbindd_cli_state *state);
    409 void winbindd_pam_logoff(struct winbindd_cli_state *state);
    410370enum winbindd_result winbindd_dual_pam_logoff(struct winbindd_domain *domain,
    411371                                              struct winbindd_cli_state *state) ;
    412 void winbindd_pam_chng_pswd_auth_crap(struct winbindd_cli_state *state);
    413372enum winbindd_result winbindd_dual_pam_chng_pswd_auth_crap(struct winbindd_domain *domainSt, struct winbindd_cli_state *state);
    414373
     
    416375
    417376struct winbindd_domain *domain_list(void);
    418 void free_domain_list(void);
     377bool domain_is_forest_root(const struct winbindd_domain *domain);
    419378void rescan_trusted_domains(struct tevent_context *ev, struct tevent_timer *te,
    420379                            struct timeval now, void *private_data);
     
    422381                                                   struct winbindd_cli_state *state);
    423382bool init_domain_list(void);
    424 void check_domain_trusted( const char *name, const DOM_SID *user_sid );
    425383struct winbindd_domain *find_domain_from_name_noinit(const char *domain_name);
    426384struct winbindd_domain *find_domain_from_name(const char *domain_name);
    427 struct winbindd_domain *find_domain_from_sid_noinit(const DOM_SID *sid);
    428 struct winbindd_domain *find_domain_from_sid(const DOM_SID *sid);
     385struct winbindd_domain *find_domain_from_sid_noinit(const struct dom_sid *sid);
     386struct winbindd_domain *find_domain_from_sid(const struct dom_sid *sid);
    429387struct winbindd_domain *find_our_domain(void);
    430388struct winbindd_domain *find_root_domain(void);
    431389struct winbindd_domain *find_builtin_domain(void);
    432 struct winbindd_domain *find_lookup_domain_from_sid(const DOM_SID *sid);
     390struct winbindd_domain *find_lookup_domain_from_sid(const struct dom_sid *sid);
    433391struct winbindd_domain *find_lookup_domain_from_name(const char *domain_name);
    434392bool parse_domain_user(const char *domuser, fstring domain, fstring user);
    435393bool parse_domain_user_talloc(TALLOC_CTX *mem_ctx, const char *domuser,
    436394                              char **domain, char **user);
    437 void parse_add_domuser(void *buf, char *domuser, int *len);
    438395bool canonicalize_username(fstring username_inout, fstring domain, fstring user);
    439396void fill_domain_username(fstring name, const char *domain, const char *user, bool can_assume);
     
    442399                                  const char *user,
    443400                                  bool can_assume);
    444 const char *get_winbind_pipe_dir(void) ;
    445 char *get_winbind_priv_pipe_dir(void) ;
    446 int open_winbindd_socket(void);
    447 int open_winbindd_priv_socket(void);
    448401struct winbindd_cli_state *winbindd_client_list(void);
    449402void winbindd_add_client(struct winbindd_cli_state *cli);
    450403void winbindd_remove_client(struct winbindd_cli_state *cli);
    451 void winbindd_kill_all_clients(void);
    452404int winbindd_num_clients(void);
    453405NTSTATUS lookup_usergroups_cached(struct winbindd_domain *domain,
    454406                                  TALLOC_CTX *mem_ctx,
    455                                   const DOM_SID *user_sid,
    456                                   uint32 *p_num_groups, DOM_SID **user_sids);
     407                                  const struct dom_sid *user_sid,
     408                                  uint32 *p_num_groups, struct dom_sid **user_sids);
    457409
    458410NTSTATUS normalize_name_map(TALLOC_CTX *mem_ctx,
     
    479431void set_auth_errors(struct winbindd_response *resp, NTSTATUS result);
    480432bool is_domain_offline(const struct winbindd_domain *domain);
     433bool is_domain_online(const struct winbindd_domain *domain);
     434bool parse_sidlist(TALLOC_CTX *mem_ctx, const char *sidstr,
     435                   struct dom_sid **sids, uint32_t *num_sids);
    481436
    482437/* The following definitions come from winbindd/winbindd_wins.c  */
     
    494449                                        struct winbindd_cli_state *state);
    495450
    496 struct rpc_pipe_client *wbint_rpccli_create(TALLOC_CTX *mem_ctx,
    497                                             struct winbindd_domain *domain,
    498                                             struct winbindd_child *child);
     451struct dcerpc_binding_handle *wbint_binding_handle(TALLOC_CTX *mem_ctx,
     452                                                struct winbindd_domain *domain,
     453                                                struct winbindd_child *child);
    499454enum winbindd_result winbindd_dual_ndrcmd(struct winbindd_domain *domain,
    500455                                          struct winbindd_cli_state *state);
     
    513468NTSTATUS winbindd_lookupsid_recv(struct tevent_req *req,
    514469                                 struct winbindd_response *response);
     470
     471struct tevent_req *winbindd_lookupsids_send(TALLOC_CTX *mem_ctx,
     472                                            struct tevent_context *ev,
     473                                            struct winbindd_cli_state *cli,
     474                                            struct winbindd_request *request);
     475NTSTATUS winbindd_lookupsids_recv(struct tevent_req *req,
     476                                  struct winbindd_response *response);
    515477
    516478struct tevent_req *wb_lookupname_send(TALLOC_CTX *mem_ctx,
     
    847809                                           struct winbindd_response *presp);
    848810
    849 struct tevent_req *winbindd_set_mapping_send(TALLOC_CTX *mem_ctx,
    850                                              struct tevent_context *ev,
    851                                              struct winbindd_cli_state *cli,
    852                                              struct winbindd_request *request);
    853 NTSTATUS winbindd_set_mapping_recv(struct tevent_req *req,
    854                                    struct winbindd_response *response);
    855 
    856 struct tevent_req *winbindd_remove_mapping_send(TALLOC_CTX *mem_ctx,
    857                                                 struct tevent_context *ev,
    858                                                 struct winbindd_cli_state *cli,
    859                                                 struct winbindd_request *request);
    860 NTSTATUS winbindd_remove_mapping_recv(struct tevent_req *req,
    861                                       struct winbindd_response *response);
    862 
    863 struct tevent_req *winbindd_set_hwm_send(TALLOC_CTX *mem_ctx,
    864                                          struct tevent_context *ev,
    865                                          struct winbindd_cli_state *cli,
    866                                          struct winbindd_request *request);
    867 NTSTATUS winbindd_set_hwm_recv(struct tevent_req *req,
    868                                struct winbindd_response *response);
     811struct tevent_req *winbindd_pam_auth_send(TALLOC_CTX *mem_ctx,
     812                                          struct tevent_context *ev,
     813                                          struct winbindd_cli_state *cli,
     814                                          struct winbindd_request *request);
     815NTSTATUS winbindd_pam_auth_recv(struct tevent_req *req,
     816                                struct winbindd_response *response);
     817
     818struct tevent_req *winbindd_pam_auth_crap_send(
     819        TALLOC_CTX *mem_ctx,
     820        struct tevent_context *ev,
     821        struct winbindd_cli_state *cli,
     822        struct winbindd_request *request);
     823NTSTATUS winbindd_pam_auth_crap_recv(struct tevent_req *req,
     824                                     struct winbindd_response *response);
     825
     826struct tevent_req *winbindd_pam_chauthtok_send(
     827        TALLOC_CTX *mem_ctx,
     828        struct tevent_context *ev,
     829        struct winbindd_cli_state *cli,
     830        struct winbindd_request *request);
     831NTSTATUS winbindd_pam_chauthtok_recv(struct tevent_req *req,
     832                                     struct winbindd_response *response);
     833
     834struct tevent_req *winbindd_pam_logoff_send(TALLOC_CTX *mem_ctx,
     835                                            struct tevent_context *ev,
     836                                            struct winbindd_cli_state *cli,
     837                                            struct winbindd_request *request);
     838NTSTATUS winbindd_pam_logoff_recv(struct tevent_req *req,
     839                                  struct winbindd_response *response);
     840
     841struct tevent_req *winbindd_pam_chng_pswd_auth_crap_send(
     842        TALLOC_CTX *mem_ctx,
     843        struct tevent_context *ev,
     844        struct winbindd_cli_state *cli,
     845        struct winbindd_request *request);
     846NTSTATUS winbindd_pam_chng_pswd_auth_crap_recv(
     847        struct tevent_req *req,
     848        struct winbindd_response *response);
     849
     850struct tevent_req *wb_lookupsids_send(TALLOC_CTX *mem_ctx,
     851                                      struct tevent_context *ev,
     852                                      struct dom_sid *sids,
     853                                      uint32_t num_sids);
     854NTSTATUS wb_lookupsids_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
     855                            struct lsa_RefDomainList **domains,
     856                            struct lsa_TransNameArray **names);
     857
     858struct tevent_req *winbindd_sids_to_xids_send(TALLOC_CTX *mem_ctx,
     859                                              struct tevent_context *ev,
     860                                              struct winbindd_cli_state *cli,
     861                                              struct winbindd_request *request);
     862NTSTATUS winbindd_sids_to_xids_recv(struct tevent_req *req,
     863                                    struct winbindd_response *response);
     864
     865
     866/* The following definitions come from winbindd/winbindd_samr.c  */
     867
     868NTSTATUS open_internal_samr_conn(TALLOC_CTX *mem_ctx,
     869                                 struct winbindd_domain *domain,
     870                                 struct rpc_pipe_client **samr_pipe,
     871                                 struct policy_handle *samr_domain_hnd);
    869872
    870873#endif /*  _WINBINDD_PROTO_H_  */
  • vendor/current/source3/winbindd/winbindd_reconnect.c

    r427 r740  
    9494                                TALLOC_CTX *mem_ctx,
    9595                                uint32 *num_entries,
    96                                 struct acct_info **info)
     96                                struct wb_acct_info **info)
    9797{
    9898        NTSTATUS result;
     
    112112                                  TALLOC_CTX *mem_ctx,
    113113                                  uint32 *num_entries,
    114                                   struct acct_info **info)
     114                                  struct wb_acct_info **info)
    115115{
    116116        NTSTATUS result;
     
    132132                            const char *name,
    133133                            uint32_t flags,
    134                             DOM_SID *sid,
     134                            struct dom_sid *sid,
    135135                            enum lsa_SidType *type)
    136136{
     
    153153static NTSTATUS sid_to_name(struct winbindd_domain *domain,
    154154                            TALLOC_CTX *mem_ctx,
    155                             const DOM_SID *sid,
     155                            const struct dom_sid *sid,
    156156                            char **domain_name,
    157157                            char **name,
     
    172172static NTSTATUS rids_to_names(struct winbindd_domain *domain,
    173173                              TALLOC_CTX *mem_ctx,
    174                               const DOM_SID *sid,
     174                              const struct dom_sid *sid,
    175175                              uint32 *rids,
    176176                              size_t num_rids,
     
    197197static NTSTATUS query_user(struct winbindd_domain *domain,
    198198                           TALLOC_CTX *mem_ctx,
    199                            const DOM_SID *user_sid,
     199                           const struct dom_sid *user_sid,
    200200                           struct wbint_userinfo *user_info)
    201201{
     
    215215static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
    216216                                  TALLOC_CTX *mem_ctx,
    217                                   const DOM_SID *user_sid,
    218                                   uint32 *num_groups, DOM_SID **user_gids)
     217                                  const struct dom_sid *user_sid,
     218                                  uint32 *num_groups, struct dom_sid **user_gids)
    219219{
    220220        NTSTATUS result;
     
    234234static NTSTATUS lookup_useraliases(struct winbindd_domain *domain,
    235235                                   TALLOC_CTX *mem_ctx,
    236                                    uint32 num_sids, const DOM_SID *sids,
     236                                   uint32 num_sids, const struct dom_sid *sids,
    237237                                   uint32 *num_aliases, uint32 **alias_rids)
    238238{
     
    256256static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
    257257                                TALLOC_CTX *mem_ctx,
    258                                 const DOM_SID *group_sid,
     258                                const struct dom_sid *group_sid,
    259259                                enum lsa_SidType type,
    260260                                uint32 *num_names,
    261                                 DOM_SID **sid_mem, char ***names,
     261                                struct dom_sid **sid_mem, char ***names,
    262262                                uint32 **name_types)
    263263{
  • vendor/current/source3/winbindd/winbindd_rpc.c

    r594 r740  
    1 /*
    2    Unix SMB/CIFS implementation.
    3 
    4    Winbind rpc backend functions
    5 
    6    Copyright (C) Tim Potter 2000-2001,2003
    7    Copyright (C) Andrew Tridgell 2001
    8    Copyright (C) Volker Lendecke 2005
    9    Copyright (C) Guenther Deschner 2008 (pidl conversion)
    10 
    11    This program is free software; you can redistribute it and/or modify
    12    it under the terms of the GNU General Public License as published by
    13    the Free Software Foundation; either version 3 of the License, or
    14    (at your option) any later version.
    15 
    16    This program is distributed in the hope that it will be useful,
    17    but WITHOUT ANY WARRANTY; without even the implied warranty of
    18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    19    GNU General Public License for more details.
    20 
    21    You should have received a copy of the GNU General Public License
    22    along with this program.  If not, see <http://www.gnu.org/licenses/>.
    23 */
     1/*
     2 * Unix SMB/CIFS implementation.
     3 *
     4 * Winbind rpc backend functions
     5 *
     6 * Copyright (c) 2000-2003 Tim Potter
     7 * Copyright (c) 2001      Andrew Tridgell
     8 * Copyright (c) 2005      Volker Lendecke
     9 * Copyright (c) 2008      Guenther Deschner (pidl conversion)
     10 * Copyright (c) 2010      Andreas Schneider <asn@samba.org>
     11 *
     12 * This program is free software; you can redistribute it and/or modify
     13 * it under the terms of the GNU General Public License as published by
     14 * the Free Software Foundation; either version 3 of the License, or
     15 * (at your option) any later version.
     16 *
     17 * This program is distributed in the hope that it will be useful,
     18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     20 * GNU General Public License for more details.
     21 *
     22 * You should have received a copy of the GNU General Public License
     23 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
     24 */
    2425
    2526#include "includes.h"
    2627#include "winbindd.h"
    27 #include "../librpc/gen_ndr/cli_samr.h"
    28 #include "../librpc/gen_ndr/cli_lsa.h"
    29 
    30 #undef DBGC_CLASS
    31 #define DBGC_CLASS DBGC_WINBIND
    32 
    33 
    34 /* Query display info for a domain.  This returns enough information plus a
    35    bit extra to give an overview of domain users for the User Manager
    36    application. */
    37 static NTSTATUS query_user_list(struct winbindd_domain *domain,
    38                                TALLOC_CTX *mem_ctx,
    39                                uint32 *num_entries,
    40                                struct wbint_userinfo **info)
    41 {
    42         NTSTATUS result;
    43         struct policy_handle dom_pol;
    44         unsigned int i, start_idx;
    45         uint32 loop_count;
    46         struct rpc_pipe_client *cli;
    47 
    48         DEBUG(3,("rpc: query_user_list\n"));
    49 
    50         *num_entries = 0;
    51         *info = NULL;
    52 
    53         if ( !winbindd_can_contact_domain( domain ) ) {
    54                 DEBUG(10,("query_user_list: No incoming trust for domain %s\n",
    55                           domain->name));
    56                 return NT_STATUS_OK;
    57         }
    58 
    59         result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
    60         if (!NT_STATUS_IS_OK(result))
    61                 return result;
    62 
    63         i = start_idx = 0;
    64         loop_count = 0;
     28#include "winbindd_rpc.h"
     29#include "rpc_client/rpc_client.h"
     30#include "librpc/gen_ndr/ndr_samr_c.h"
     31#include "librpc/gen_ndr/ndr_lsa_c.h"
     32#include "rpc_client/cli_samr.h"
     33#include "rpc_client/cli_lsarpc.h"
     34#include "../libcli/security/security.h"
     35
     36/* Query display info for a domain */
     37NTSTATUS rpc_query_user_list(TALLOC_CTX *mem_ctx,
     38                             struct rpc_pipe_client *samr_pipe,
     39                             struct policy_handle *samr_policy,
     40                             const struct dom_sid *domain_sid,
     41                             uint32_t *pnum_info,
     42                             struct wbint_userinfo **pinfo)
     43{
     44        struct wbint_userinfo *info = NULL;
     45        uint32_t num_info = 0;
     46        uint32_t loop_count = 0;
     47        uint32_t start_idx = 0;
     48        uint32_t i = 0;
     49        NTSTATUS status, result;
     50        struct dcerpc_binding_handle *b = samr_pipe->binding_handle;
     51
     52        *pnum_info = 0;
    6553
    6654        do {
    67                 uint32 num_dom_users, j;
    68                 uint32 max_entries, max_size;
     55                uint32_t j;
     56                uint32_t num_dom_users;
     57                uint32_t max_entries, max_size;
    6958                uint32_t total_size, returned_size;
    70 
    7159                union samr_DispInfo disp_info;
    7260
    73                 /* this next bit is copied from net_user_list_internal() */
    74 
    75                 get_query_dispinfo_params(loop_count, &max_entries,
    76                                           &max_size);
    77 
    78                 result = rpccli_samr_QueryDisplayInfo(cli, mem_ctx,
    79                                                       &dom_pol,
    80                                                       1,
     61                dcerpc_get_query_dispinfo_params(loop_count,
     62                                                 &max_entries,
     63                                                 &max_size);
     64
     65                status = dcerpc_samr_QueryDisplayInfo(b,
     66                                                      mem_ctx,
     67                                                      samr_policy,
     68                                                      1, /* level */
    8169                                                      start_idx,
    8270                                                      max_entries,
     
    8472                                                      &total_size,
    8573                                                      &returned_size,
    86                                                       &disp_info);
    87 
     74                                                      &disp_info,
     75                                                      &result);
     76                if (!NT_STATUS_IS_OK(status)) {
     77                        return status;
     78                }
    8879                if (!NT_STATUS_IS_OK(result)) {
    89                         if (!NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
    90                                 return result;
    91                         }
    92                 }
    93 
    94                 num_dom_users = disp_info.info1.count;
     80                        if (!NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
     81                                return result;
     82                        }
     83                }
     84
     85                /* increment required start query values */
    9586                start_idx += disp_info.info1.count;
    9687                loop_count++;
    97 
    98                 *num_entries += num_dom_users;
    99 
    100                 *info = TALLOC_REALLOC_ARRAY(mem_ctx, *info,
    101                                              struct wbint_userinfo,
    102                                              *num_entries);
    103 
    104                 if (!(*info)) {
     88                num_dom_users = disp_info.info1.count;
     89
     90                num_info += num_dom_users;
     91
     92                info = TALLOC_REALLOC_ARRAY(mem_ctx,
     93                                            info,
     94                                            struct wbint_userinfo,
     95                                            num_info);
     96                if (info == NULL) {
    10597                        return NT_STATUS_NO_MEMORY;
    10698                }
    10799
    108100                for (j = 0; j < num_dom_users; i++, j++) {
    109 
    110101                        uint32_t rid = disp_info.info1.entries[j].rid;
    111 
    112                         (*info)[i].acct_name = talloc_strdup(mem_ctx,
    113                                 disp_info.info1.entries[j].account_name.string);
    114                         (*info)[i].full_name = talloc_strdup(mem_ctx,
    115                                 disp_info.info1.entries[j].full_name.string);
    116                         (*info)[i].homedir = NULL;
    117                         (*info)[i].shell = NULL;
    118                         sid_compose(&(*info)[i].user_sid, &domain->sid, rid);
     102                        struct samr_DispEntryGeneral *src;
     103                        struct wbint_userinfo *dst;
     104
     105                        src = &(disp_info.info1.entries[j]);
     106                        dst = &(info[i]);
     107
     108                        dst->acct_name = talloc_strdup(info,
     109                                                       src->account_name.string);
     110                        if (dst->acct_name == NULL) {
     111                                return NT_STATUS_NO_MEMORY;
     112                        }
     113
     114                        dst->full_name = talloc_strdup(info, src->full_name.string);
     115                        if ((src->full_name.string != NULL) &&
     116                            (dst->full_name == NULL))
     117                        {
     118                                return NT_STATUS_NO_MEMORY;
     119                        }
     120
     121                        dst->homedir = NULL;
     122                        dst->shell = NULL;
     123
     124                        sid_compose(&dst->user_sid, domain_sid, rid);
    119125
    120126                        /* For the moment we set the primary group for
     
    125131                           force group' smb.conf parameter or
    126132                           something like that. */
    127 
    128                         sid_compose(&(*info)[i].group_sid, &domain->sid,
    129                                     DOMAIN_GROUP_RID_USERS);
    130                 }
    131 
     133                        sid_compose(&dst->group_sid, domain_sid,
     134                                    DOMAIN_RID_USERS);
     135                }
    132136        } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
    133137
    134         return result;
    135 }
    136 
    137 /* list all domain groups */
    138 static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
    139                                 TALLOC_CTX *mem_ctx,
    140                                 uint32 *num_entries,
    141                                 struct acct_info **info)
    142 {
    143         struct policy_handle dom_pol;
    144         NTSTATUS status;
    145         uint32 start = 0;
    146         struct rpc_pipe_client *cli;
    147 
    148         *num_entries = 0;
    149         *info = NULL;
    150 
    151         DEBUG(3,("rpc: enum_dom_groups\n"));
    152 
    153         if ( !winbindd_can_contact_domain( domain ) ) {
    154                 DEBUG(10,("enum_domain_groups: No incoming trust for domain %s\n",
    155                           domain->name));
    156                 return NT_STATUS_OK;
    157         }
    158 
    159         status = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
    160         if (!NT_STATUS_IS_OK(status))
    161                 return status;
     138        *pnum_info = num_info;
     139        *pinfo = info;
     140
     141        return NT_STATUS_OK;
     142}
     143
     144/* List all domain groups */
     145NTSTATUS rpc_enum_dom_groups(TALLOC_CTX *mem_ctx,
     146                             struct rpc_pipe_client *samr_pipe,
     147                             struct policy_handle *samr_policy,
     148                             uint32_t *pnum_info,
     149                             struct wb_acct_info **pinfo)
     150{
     151        struct wb_acct_info *info = NULL;
     152        uint32_t start = 0;
     153        uint32_t num_info = 0;
     154        NTSTATUS status, result;
     155        struct dcerpc_binding_handle *b = samr_pipe->binding_handle;
     156
     157        *pnum_info = 0;
    162158
    163159        do {
    164160                struct samr_SamArray *sam_array = NULL;
    165                 uint32 count = 0;
    166                 TALLOC_CTX *mem_ctx2;
    167                 int g;
    168 
    169                 mem_ctx2 = talloc_init("enum_dom_groups[rpc]");
     161                uint32_t count = 0;
     162                uint32_t g;
    170163
    171164                /* start is updated by this call. */
    172                 status = rpccli_samr_EnumDomainGroups(cli, mem_ctx2,
    173                                                       &dom_pol,
     165                status = dcerpc_samr_EnumDomainGroups(b,
     166                                                      mem_ctx,
     167                                                      samr_policy,
    174168                                                      &start,
    175169                                                      &sam_array,
    176170                                                      0xFFFF, /* buffer size? */
    177                                                       &count);
    178 
    179                 if (!NT_STATUS_IS_OK(status) &&
    180                     !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
    181                         talloc_destroy(mem_ctx2);
    182                         break;
    183                 }
    184 
    185                 (*info) = TALLOC_REALLOC_ARRAY(mem_ctx, *info,
    186                                                struct acct_info,
    187                                                (*num_entries) + count);
    188                 if (! *info) {
    189                         talloc_destroy(mem_ctx2);
     171                                                      &count,
     172                                                      &result);
     173                if (!NT_STATUS_IS_OK(status)) {
     174                        return status;
     175                }
     176                if (!NT_STATUS_IS_OK(result)) {
     177                        if (!NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
     178                                DEBUG(2,("query_user_list: failed to enum domain groups: %s\n",
     179                                         nt_errstr(result)));
     180                                return result;
     181                        }
     182                }
     183
     184                info = TALLOC_REALLOC_ARRAY(mem_ctx,
     185                                            info,
     186                                            struct wb_acct_info,
     187                                            num_info + count);
     188                if (info == NULL) {
    190189                        return NT_STATUS_NO_MEMORY;
    191190                }
    192191
    193                 for (g=0; g < count; g++) {
    194 
    195                         fstrcpy((*info)[*num_entries + g].acct_name,
     192                for (g = 0; g < count; g++) {
     193                        fstrcpy(info[num_info + g].acct_name,
    196194                                sam_array->entries[g].name.string);
    197                         (*info)[*num_entries + g].rid = sam_array->entries[g].idx;
    198                 }
    199 
    200                 (*num_entries) += count;
    201                 talloc_destroy(mem_ctx2);
    202         } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
    203 
    204         return status;
    205 }
    206 
    207 /* List all domain groups */
    208 
    209 static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
    210                                 TALLOC_CTX *mem_ctx,
    211                                 uint32 *num_entries,
    212                                 struct acct_info **info)
    213 {
    214         struct policy_handle dom_pol;
    215         NTSTATUS result;
    216         struct rpc_pipe_client *cli;
    217 
    218         *num_entries = 0;
    219         *info = NULL;
    220 
    221         DEBUG(3,("rpc: enum_local_groups\n"));
    222 
    223         if ( !winbindd_can_contact_domain( domain ) ) {
    224                 DEBUG(10,("enum_local_groups: No incoming trust for domain %s\n",
    225                           domain->name));
    226                 return NT_STATUS_OK;
    227         }
    228 
    229         result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
    230         if (!NT_STATUS_IS_OK(result))
    231                 return result;
     195
     196                        info[num_info + g].rid = sam_array->entries[g].idx;
     197                }
     198
     199                num_info += count;
     200        } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
     201
     202        *pnum_info = num_info;
     203        *pinfo = info;
     204
     205        return NT_STATUS_OK;
     206}
     207
     208NTSTATUS rpc_enum_local_groups(TALLOC_CTX *mem_ctx,
     209                               struct rpc_pipe_client *samr_pipe,
     210                               struct policy_handle *samr_policy,
     211                               uint32_t *pnum_info,
     212                               struct wb_acct_info **pinfo)
     213{
     214        struct wb_acct_info *info = NULL;
     215        uint32_t num_info = 0;
     216        NTSTATUS status, result;
     217        struct dcerpc_binding_handle *b = samr_pipe->binding_handle;
     218
     219        *pnum_info = 0;
    232220
    233221        do {
    234222                struct samr_SamArray *sam_array = NULL;
    235                 uint32 count = 0, start = *num_entries;
    236                 TALLOC_CTX *mem_ctx2;
    237                 int g;
    238 
    239                 mem_ctx2 = talloc_init("enum_dom_local_groups[rpc]");
    240 
    241                 result = rpccli_samr_EnumDomainAliases(cli, mem_ctx2,
    242                                                        &dom_pol,
     223                uint32_t count = 0;
     224                uint32_t start = num_info;
     225                uint32_t g;
     226
     227                status = dcerpc_samr_EnumDomainAliases(b,
     228                                                       mem_ctx,
     229                                                       samr_policy,
    243230                                                       &start,
    244231                                                       &sam_array,
    245232                                                       0xFFFF, /* buffer size? */
    246                                                        &count);
    247                 if (!NT_STATUS_IS_OK(result) &&
    248                     !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES) )
    249                 {
    250                         talloc_destroy(mem_ctx2);
    251                         return result;
    252                 }
    253 
    254                 (*info) = TALLOC_REALLOC_ARRAY(mem_ctx, *info,
    255                                                struct acct_info,
    256                                                (*num_entries) + count);
    257                 if (! *info) {
    258                         talloc_destroy(mem_ctx2);
    259                         return NT_STATUS_NO_MEMORY;
    260                 }
    261 
    262                 for (g=0; g < count; g++) {
    263 
    264                         fstrcpy((*info)[*num_entries + g].acct_name,
     233                                                       &count,
     234                                                       &result);
     235                if (!NT_STATUS_IS_OK(status)) {
     236                        return status;
     237                }
     238                if (!NT_STATUS_IS_OK(result)) {
     239                        if (!NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
     240                                return result;
     241                        }
     242                }
     243
     244                info = TALLOC_REALLOC_ARRAY(mem_ctx,
     245                                            info,
     246                                            struct wb_acct_info,
     247                                            num_info + count);
     248                if (info == NULL) {
     249                        return  NT_STATUS_NO_MEMORY;
     250                }
     251
     252                for (g = 0; g < count; g++) {
     253                        fstrcpy(info[num_info + g].acct_name,
    265254                                sam_array->entries[g].name.string);
    266                         (*info)[*num_entries + g].rid = sam_array->entries[g].idx;
    267                 }
    268 
    269                 (*num_entries) += count;
    270                 talloc_destroy(mem_ctx2);
    271 
     255                        info[num_info + g].rid = sam_array->entries[g].idx;
     256                }
     257
     258                num_info += count;
    272259        } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
    273260
    274         return result;
     261        *pnum_info = num_info;
     262        *pinfo = info;
     263
     264        return NT_STATUS_OK;
    275265}
    276266
    277267/* convert a single name to a sid in a domain */
    278 static NTSTATUS msrpc_name_to_sid(struct winbindd_domain *domain,
    279                                   TALLOC_CTX *mem_ctx,
    280                                   const char *domain_name,
    281                                   const char *name,
    282                                   uint32_t flags,
    283                                   DOM_SID *sid,
    284                                   enum lsa_SidType *type)
    285 {
    286         NTSTATUS result;
    287         DOM_SID *sids = NULL;
     268NTSTATUS rpc_name_to_sid(TALLOC_CTX *mem_ctx,
     269                         struct rpc_pipe_client *lsa_pipe,
     270                         struct policy_handle *lsa_policy,
     271                         const char *domain_name,
     272                         const char *name,
     273                         uint32_t flags,
     274                         struct dom_sid *sid,
     275                         enum lsa_SidType *type)
     276{
    288277        enum lsa_SidType *types = NULL;
     278        struct dom_sid *sids = NULL;
    289279        char *full_name = NULL;
    290         NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
    291280        char *mapped_name = NULL;
    292 
    293         if (name == NULL || *name=='\0') {
     281        NTSTATUS status;
     282
     283        if (name == NULL || name[0] == '\0') {
    294284                full_name = talloc_asprintf(mem_ctx, "%s", domain_name);
    295         } else if (domain_name == NULL || *domain_name == '\0') {
     285        } else if (domain_name == NULL || domain_name[0] == '\0') {
    296286                full_name = talloc_asprintf(mem_ctx, "%s", name);
    297287        } else {
    298288                full_name = talloc_asprintf(mem_ctx, "%s\\%s", domain_name, name);
    299289        }
    300         if (!full_name) {
    301                 DEBUG(0, ("talloc_asprintf failed!\n"));
     290
     291        if (full_name == NULL) {
    302292                return NT_STATUS_NO_MEMORY;
    303293        }
    304294
    305         DEBUG(3,("rpc: name_to_sid name=%s\n", full_name));
    306 
    307         name_map_status = normalize_name_unmap(mem_ctx, full_name,
    308                                                &mapped_name);
    309 
    310         /* Reset the full_name pointer if we mapped anytthing */
    311 
    312         if (NT_STATUS_IS_OK(name_map_status) ||
    313             NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))
    314         {
     295        status = normalize_name_unmap(mem_ctx, full_name, &mapped_name);
     296        /* Reset the full_name pointer if we mapped anything */
     297        if (NT_STATUS_IS_OK(status) ||
     298            NT_STATUS_EQUAL(status, NT_STATUS_FILE_RENAMED)) {
    315299                full_name = mapped_name;
    316300        }
    317301
    318         DEBUG(3,("name_to_sid [rpc] %s for domain %s\n",
    319                  full_name?full_name:"", domain_name ));
    320 
    321         result = winbindd_lookup_names(mem_ctx, domain, 1,
    322                                        (const char **)&full_name, NULL,
    323                                        &sids, &types);
    324         if (!NT_STATUS_IS_OK(result))
    325                 return result;
    326 
    327         /* Return rid and type if lookup successful */
     302        DEBUG(3,("name_to_sid: %s for domain %s\n",
     303                 full_name ? full_name : "", domain_name ));
     304
     305        /*
     306         * We don't run into deadlocks here, cause winbind_off() is
     307         * called in the main function.
     308         */
     309        status = rpccli_lsa_lookup_names(lsa_pipe,
     310                                         mem_ctx,
     311                                         lsa_policy,
     312                                         1, /* num_names */
     313                                         (const char **) &full_name,
     314                                         NULL, /* domains */
     315                                         1, /* level */
     316                                         &sids,
     317                                         &types);
     318        if (!NT_STATUS_IS_OK(status)) {
     319                DEBUG(2,("name_to_sid: failed to lookup name: %s\n",
     320                        nt_errstr(status)));
     321                return status;
     322        }
    328323
    329324        sid_copy(sid, &sids[0]);
     
    333328}
    334329
    335 /*
    336   convert a domain SID to a user or group name
    337 */
    338 static NTSTATUS msrpc_sid_to_name(struct winbindd_domain *domain,
    339                                   TALLOC_CTX *mem_ctx,
    340                                   const DOM_SID *sid,
    341                                   char **domain_name,
    342                                   char **name,
    343                                   enum lsa_SidType *type)
    344 {
    345         char **domains;
    346         char **names;
     330/* Convert a domain SID to a user or group name */
     331NTSTATUS rpc_sid_to_name(TALLOC_CTX *mem_ctx,
     332                         struct rpc_pipe_client *lsa_pipe,
     333                         struct policy_handle *lsa_policy,
     334                         struct winbindd_domain *domain,
     335                         const struct dom_sid *sid,
     336                         char **pdomain_name,
     337                         char **pname,
     338                         enum lsa_SidType *ptype)
     339{
     340        char *mapped_name = NULL;
     341        char **domains = NULL;
     342        char **names = NULL;
    347343        enum lsa_SidType *types = NULL;
    348         NTSTATUS result;
    349         NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
    350         char *mapped_name = NULL;
    351 
    352         DEBUG(3,("sid_to_name [rpc] %s for domain %s\n", sid_string_dbg(sid),
    353                  domain->name ));
    354 
    355         result = winbindd_lookup_sids(mem_ctx,
    356                                       domain,
    357                                       1,
    358                                       sid,
    359                                       &domains,
    360                                       &names,
    361                                       &types);
    362         if (!NT_STATUS_IS_OK(result)) {
    363                 DEBUG(2,("msrpc_sid_to_name: failed to lookup sids: %s\n",
    364                         nt_errstr(result)));
    365                 return result;
    366         }
    367 
    368 
    369         *type = (enum lsa_SidType)types[0];
    370         *domain_name = domains[0];
    371         *name = names[0];
    372 
    373         DEBUG(5,("Mapped sid to [%s]\\[%s]\n", domains[0], *name));
    374 
    375         name_map_status = normalize_name_map(mem_ctx, domain, *name,
    376                                              &mapped_name);
    377         if (NT_STATUS_IS_OK(name_map_status) ||
    378             NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))
    379         {
    380                 *name = mapped_name;
    381                 DEBUG(5,("returning mapped name -- %s\n", *name));
     344        NTSTATUS map_status;
     345        NTSTATUS status;
     346
     347        status = rpccli_lsa_lookup_sids(lsa_pipe,
     348                                        mem_ctx,
     349                                        lsa_policy,
     350                                        1, /* num_sids */
     351                                        sid,
     352                                        &domains,
     353                                        &names,
     354                                        &types);
     355        if (!NT_STATUS_IS_OK(status)) {
     356                DEBUG(2,("sid_to_name: failed to lookup sids: %s\n",
     357                        nt_errstr(status)));
     358                return status;
     359        }
     360
     361        *ptype = (enum lsa_SidType) types[0];
     362
     363        map_status = normalize_name_map(mem_ctx,
     364                                        domain,
     365                                        *pname,
     366                                        &mapped_name);
     367        if (NT_STATUS_IS_OK(map_status) ||
     368            NT_STATUS_EQUAL(map_status, NT_STATUS_FILE_RENAMED)) {
     369                *pname = talloc_strdup(mem_ctx, mapped_name);
     370                DEBUG(5,("returning mapped name -- %s\n", *pname));
     371        } else {
     372                *pname = talloc_strdup(mem_ctx, names[0]);
     373        }
     374        if (*pname == NULL) {
     375                return NT_STATUS_NO_MEMORY;
     376        }
     377
     378        *pdomain_name = talloc_strdup(mem_ctx, domains[0]);
     379        if (*pdomain_name == NULL) {
     380                return NT_STATUS_NO_MEMORY;
    382381        }
    383382
     
    385384}
    386385
    387 static NTSTATUS msrpc_rids_to_names(struct winbindd_domain *domain,
    388                                     TALLOC_CTX *mem_ctx,
    389                                     const DOM_SID *sid,
    390                                     uint32 *rids,
    391                                     size_t num_rids,
    392                                     char **domain_name,
    393                                     char ***names,
    394                                     enum lsa_SidType **types)
    395 {
    396         char **domains;
    397         NTSTATUS result;
    398         DOM_SID *sids;
     386/* Convert a bunch of rids to user or group names */
     387NTSTATUS rpc_rids_to_names(TALLOC_CTX *mem_ctx,
     388                           struct rpc_pipe_client *lsa_pipe,
     389                           struct policy_handle *lsa_policy,
     390                           struct winbindd_domain *domain,
     391                           const struct dom_sid *sid,
     392                           uint32_t *rids,
     393                           size_t num_rids,
     394                           char **pdomain_name,
     395                           char ***pnames,
     396                           enum lsa_SidType **ptypes)
     397{
     398        enum lsa_SidType *types = NULL;
     399        char *domain_name = NULL;
     400        char **domains = NULL;
     401        char **names = NULL;
     402        struct dom_sid *sids;
    399403        size_t i;
    400         char **ret_names;
    401 
    402         DEBUG(3, ("rids_to_names [rpc] for domain %s\n", domain->name ));
    403 
    404         if (num_rids) {
    405                 sids = TALLOC_ARRAY(mem_ctx, DOM_SID, num_rids);
     404        NTSTATUS status;
     405
     406        if (num_rids > 0) {
     407                sids = TALLOC_ARRAY(mem_ctx, struct dom_sid, num_rids);
    406408                if (sids == NULL) {
    407409                        return NT_STATUS_NO_MEMORY;
     
    411413        }
    412414
    413         for (i=0; i<num_rids; i++) {
     415        for (i = 0; i < num_rids; i++) {
    414416                if (!sid_compose(&sids[i], sid, rids[i])) {
    415417                        return NT_STATUS_INTERNAL_ERROR;
     
    417419        }
    418420
    419         result = winbindd_lookup_sids(mem_ctx,
    420                                       domain,
    421                                       num_rids,
    422                                       sids,
    423                                       &domains,
    424                                       names,
    425                                       types);
    426 
    427         if (!NT_STATUS_IS_OK(result) &&
    428             !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) {
     421        status = rpccli_lsa_lookup_sids(lsa_pipe,
     422                                        mem_ctx,
     423                                        lsa_policy,
     424                                        num_rids,
     425                                        sids,
     426                                        &domains,
     427                                        &names,
     428                                        &types);
     429        if (!NT_STATUS_IS_OK(status) &&
     430            !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
     431                DEBUG(2,("rids_to_names: failed to lookup sids: %s\n",
     432                        nt_errstr(status)));
     433                return status;
     434        }
     435
     436        for (i = 0; i < num_rids; i++) {
     437                char *mapped_name = NULL;
     438                NTSTATUS map_status;
     439
     440                if (types[i] != SID_NAME_UNKNOWN) {
     441                        map_status = normalize_name_map(mem_ctx,
     442                                                        domain,
     443                                                        names[i],
     444                                                        &mapped_name);
     445                        if (NT_STATUS_IS_OK(map_status) ||
     446                            NT_STATUS_EQUAL(map_status, NT_STATUS_FILE_RENAMED)) {
     447                                TALLOC_FREE(names[i]);
     448                                names[i] = talloc_strdup(names, mapped_name);
     449                                if (names[i] == NULL) {
     450                                        return NT_STATUS_NO_MEMORY;
     451                                }
     452                        }
     453
     454                        domain_name = domains[i];
     455                }
     456        }
     457
     458        *pdomain_name = domain_name;
     459        *ptypes = types;
     460        *pnames = names;
     461
     462        return NT_STATUS_OK;
     463}
     464
     465/* Lookup user information from a rid or username. */
     466NTSTATUS rpc_query_user(TALLOC_CTX *mem_ctx,
     467                        struct rpc_pipe_client *samr_pipe,
     468                        struct policy_handle *samr_policy,
     469                        const struct dom_sid *domain_sid,
     470                        const struct dom_sid *user_sid,
     471                        struct wbint_userinfo *user_info)
     472{
     473        struct policy_handle user_policy;
     474        union samr_UserInfo *info = NULL;
     475        uint32_t user_rid;
     476        NTSTATUS status, result;
     477        struct dcerpc_binding_handle *b = samr_pipe->binding_handle;
     478
     479        if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) {
     480                return NT_STATUS_UNSUCCESSFUL;
     481        }
     482
     483        /* Get user handle */
     484        status = dcerpc_samr_OpenUser(b,
     485                                      mem_ctx,
     486                                      samr_policy,
     487                                      SEC_FLAG_MAXIMUM_ALLOWED,
     488                                      user_rid,
     489                                      &user_policy,
     490                                      &result);
     491        if (!NT_STATUS_IS_OK(status)) {
     492                return status;
     493        }
     494        if (!NT_STATUS_IS_OK(result)) {
    429495                return result;
    430496        }
    431497
    432         ret_names = *names;
    433         for (i=0; i<num_rids; i++) {
    434                 NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
    435                 char *mapped_name = NULL;
    436 
    437                 if ((*types)[i] != SID_NAME_UNKNOWN) {
    438                         name_map_status = normalize_name_map(mem_ctx,
    439                                                              domain,
    440                                                              ret_names[i],
    441                                                              &mapped_name);
    442                         if (NT_STATUS_IS_OK(name_map_status) ||
    443                             NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))
    444                         {
    445                                 ret_names[i] = mapped_name;
    446                         }
    447 
    448                         *domain_name = domains[i];
    449                 }
    450         }
    451 
    452         return result;
    453 }
    454 
    455 /* Lookup user information from a rid or username. */
    456 static NTSTATUS query_user(struct winbindd_domain *domain,
    457                            TALLOC_CTX *mem_ctx,
    458                            const DOM_SID *user_sid,
    459                            struct wbint_userinfo *user_info)
    460 {
    461         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
    462         struct policy_handle dom_pol, user_pol;
    463         union samr_UserInfo *info = NULL;
    464         uint32 user_rid;
    465         struct netr_SamInfo3 *user;
    466         struct rpc_pipe_client *cli;
    467 
    468         DEBUG(3,("rpc: query_user sid=%s\n", sid_string_dbg(user_sid)));
    469 
    470         if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid))
    471                 return NT_STATUS_UNSUCCESSFUL;
     498        /* Get user info */
     499        status = dcerpc_samr_QueryUserInfo(b,
     500                                           mem_ctx,
     501                                           &user_policy,
     502                                           0x15,
     503                                           &info,
     504                                           &result);
     505        {
     506                NTSTATUS _result;
     507                dcerpc_samr_Close(b, mem_ctx, &user_policy, &_result);
     508        }
     509        if (!NT_STATUS_IS_OK(status)) {
     510                return status;
     511        }
     512        if (!NT_STATUS_IS_OK(result)) {
     513                return result;
     514        }
     515
     516        sid_compose(&user_info->user_sid, domain_sid, user_rid);
     517        sid_compose(&user_info->group_sid, domain_sid,
     518                    info->info21.primary_gid);
     519
     520        user_info->acct_name = talloc_strdup(user_info,
     521                                        info->info21.account_name.string);
     522        if (user_info->acct_name == NULL) {
     523                return NT_STATUS_NO_MEMORY;
     524        }
     525
     526        user_info->full_name = talloc_strdup(user_info,
     527                                        info->info21.full_name.string);
     528        if ((info->info21.full_name.string != NULL) &&
     529            (user_info->acct_name == NULL))
     530        {
     531                return NT_STATUS_NO_MEMORY;
     532        }
    472533
    473534        user_info->homedir = NULL;
     
    475536        user_info->primary_gid = (gid_t)-1;
    476537
    477         /* try netsamlogon cache first */
    478 
    479         if ( (user = netsamlogon_cache_get( mem_ctx, user_sid )) != NULL )
    480         {
    481 
    482                 DEBUG(5,("query_user: Cache lookup succeeded for %s\n",
    483                         sid_string_dbg(user_sid)));
    484 
    485                 sid_compose(&user_info->user_sid, &domain->sid, user->base.rid);
    486                 sid_compose(&user_info->group_sid, &domain->sid,
    487                             user->base.primary_gid);
    488 
    489                 user_info->acct_name = talloc_strdup(mem_ctx,
    490                                                      user->base.account_name.string);
    491                 user_info->full_name = talloc_strdup(mem_ctx,
    492                                                      user->base.full_name.string);
    493 
    494                 TALLOC_FREE(user);
    495 
    496                 return NT_STATUS_OK;
    497         }
    498 
    499         if ( !winbindd_can_contact_domain( domain ) ) {
    500                 DEBUG(10,("query_user: No incoming trust for domain %s\n",
    501                           domain->name));
    502                 return NT_STATUS_OK;
    503         }
    504 
    505         /* no cache; hit the wire */
    506 
    507         result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
    508         if (!NT_STATUS_IS_OK(result))
    509                 return result;
     538        return NT_STATUS_OK;
     539}
     540
     541/* Lookup groups a user is a member of. */
     542NTSTATUS rpc_lookup_usergroups(TALLOC_CTX *mem_ctx,
     543                               struct rpc_pipe_client *samr_pipe,
     544                               struct policy_handle *samr_policy,
     545                               const struct dom_sid *domain_sid,
     546                               const struct dom_sid *user_sid,
     547                               uint32_t *pnum_groups,
     548                               struct dom_sid **puser_grpsids)
     549{
     550        struct policy_handle user_policy;
     551        struct samr_RidWithAttributeArray *rid_array = NULL;
     552        struct dom_sid *user_grpsids = NULL;
     553        uint32_t num_groups = 0, i;
     554        uint32_t user_rid;
     555        NTSTATUS status, result;
     556        struct dcerpc_binding_handle *b = samr_pipe->binding_handle;
     557
     558        if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) {
     559                return NT_STATUS_UNSUCCESSFUL;
     560        }
    510561
    511562        /* Get user handle */
    512         result = rpccli_samr_OpenUser(cli, mem_ctx,
    513                                       &dom_pol,
     563        status = dcerpc_samr_OpenUser(b,
     564                                      mem_ctx,
     565                                      samr_policy,
    514566                                      SEC_FLAG_MAXIMUM_ALLOWED,
    515567                                      user_rid,
    516                                       &user_pol);
    517 
    518         if (!NT_STATUS_IS_OK(result))
     568                                      &user_policy,
     569                                      &result);
     570        if (!NT_STATUS_IS_OK(status)) {
     571                return status;
     572        }
     573        if (!NT_STATUS_IS_OK(result)) {
    519574                return result;
    520 
    521         /* Get user info */
    522         result = rpccli_samr_QueryUserInfo(cli, mem_ctx,
    523                                            &user_pol,
    524                                            0x15,
    525                                            &info);
    526 
    527         rpccli_samr_Close(cli, mem_ctx, &user_pol);
    528 
    529         if (!NT_STATUS_IS_OK(result))
     575        }
     576
     577        /* Query user rids */
     578        status = dcerpc_samr_GetGroupsForUser(b,
     579                                              mem_ctx,
     580                                              &user_policy,
     581                                              &rid_array,
     582                                              &result);
     583        num_groups = rid_array->count;
     584
     585        {
     586                NTSTATUS _result;
     587                dcerpc_samr_Close(b, mem_ctx, &user_policy, &_result);
     588        }
     589
     590        if (!NT_STATUS_IS_OK(status)) {
     591                return status;
     592        }
     593        if (!NT_STATUS_IS_OK(result) || num_groups == 0) {
    530594                return result;
    531 
    532         sid_compose(&user_info->user_sid, &domain->sid, user_rid);
    533         sid_compose(&user_info->group_sid, &domain->sid,
    534                     info->info21.primary_gid);
    535         user_info->acct_name = talloc_strdup(mem_ctx,
    536                                              info->info21.account_name.string);
    537         user_info->full_name = talloc_strdup(mem_ctx,
    538                                              info->info21.full_name.string);
    539         user_info->homedir = NULL;
    540         user_info->shell = NULL;
    541         user_info->primary_gid = (gid_t)-1;
     595        }
     596
     597        user_grpsids = TALLOC_ARRAY(mem_ctx, struct dom_sid, num_groups);
     598        if (user_grpsids == NULL) {
     599                status = NT_STATUS_NO_MEMORY;
     600                return status;
     601        }
     602
     603        for (i = 0; i < num_groups; i++) {
     604                sid_compose(&(user_grpsids[i]), domain_sid,
     605                            rid_array->rids[i].rid);
     606        }
     607
     608        *pnum_groups = num_groups;
     609
     610        *puser_grpsids = user_grpsids;
    542611
    543612        return NT_STATUS_OK;
    544 }                                   
    545 
    546 /* Lookup groups a user is a member of.  I wish Unix had a call like this! */
    547 static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
    548                                   TALLOC_CTX *mem_ctx,
    549                                   const DOM_SID *user_sid,
    550                                   uint32 *num_groups, DOM_SID **user_grpsids)
    551 {
    552         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
    553         struct policy_handle dom_pol, user_pol;
    554         uint32 des_access = SEC_FLAG_MAXIMUM_ALLOWED;
    555         struct samr_RidWithAttributeArray *rid_array = NULL;
    556         unsigned int i;
    557         uint32 user_rid;
    558         struct rpc_pipe_client *cli;
    559 
    560         DEBUG(3,("rpc: lookup_usergroups sid=%s\n", sid_string_dbg(user_sid)));
    561 
    562         if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid))
    563                 return NT_STATUS_UNSUCCESSFUL;
    564 
    565         *num_groups = 0;
    566         *user_grpsids = NULL;
    567 
    568         /* so lets see if we have a cached user_info_3 */
    569         result = lookup_usergroups_cached(domain, mem_ctx, user_sid,
    570                                           num_groups, user_grpsids);
    571 
    572         if (NT_STATUS_IS_OK(result)) {
    573                 return NT_STATUS_OK;
    574         }
    575 
    576         if ( !winbindd_can_contact_domain( domain ) ) {
    577                 DEBUG(10,("lookup_usergroups: No incoming trust for domain %s\n",
    578                           domain->name));
    579 
    580                 /* Tell the cache manager not to remember this one */
    581 
    582                 return NT_STATUS_SYNCHRONIZATION_REQUIRED;
    583         }
    584 
    585         /* no cache; hit the wire */
    586 
    587         result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
    588         if (!NT_STATUS_IS_OK(result))
    589                 return result;
    590 
    591         /* Get user handle */
    592         result = rpccli_samr_OpenUser(cli, mem_ctx,
    593                                       &dom_pol,
    594                                       des_access,
    595                                       user_rid,
    596                                       &user_pol);
    597 
    598         if (!NT_STATUS_IS_OK(result))
    599                 return result;
    600 
    601         /* Query user rids */
    602         result = rpccli_samr_GetGroupsForUser(cli, mem_ctx,
    603                                               &user_pol,
    604                                               &rid_array);
    605         *num_groups = rid_array->count;
    606 
    607         rpccli_samr_Close(cli, mem_ctx, &user_pol);
    608 
    609         if (!NT_STATUS_IS_OK(result) || (*num_groups) == 0)
    610                 return result;
    611 
    612         (*user_grpsids) = TALLOC_ARRAY(mem_ctx, DOM_SID, *num_groups);
    613         if (!(*user_grpsids))
    614                 return NT_STATUS_NO_MEMORY;
    615 
    616         for (i=0;i<(*num_groups);i++) {
    617                 sid_copy(&((*user_grpsids)[i]), &domain->sid);
    618                 sid_append_rid(&((*user_grpsids)[i]),
    619                                 rid_array->rids[i].rid);
    620         }
    621 
    622         return NT_STATUS_OK;
    623 }
    624 
     613}
     614
     615NTSTATUS rpc_lookup_useraliases(TALLOC_CTX *mem_ctx,
     616                                struct rpc_pipe_client *samr_pipe,
     617                                struct policy_handle *samr_policy,
     618                                uint32_t num_sids,
     619                                const struct dom_sid *sids,
     620                                uint32_t *pnum_aliases,
     621                                uint32_t **palias_rids)
     622{
    625623#define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
    626 
    627 static NTSTATUS msrpc_lookup_useraliases(struct winbindd_domain *domain,
    628                                          TALLOC_CTX *mem_ctx,
    629                                          uint32 num_sids, const DOM_SID *sids,
    630                                          uint32 *num_aliases,
    631                                          uint32 **alias_rids)
    632 {
    633         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
    634         struct policy_handle dom_pol;
    635         uint32 num_query_sids = 0;
    636         int i;
    637         struct rpc_pipe_client *cli;
     624        uint32_t num_query_sids = 0;
     625        uint32_t num_queries = 1;
     626        uint32_t num_aliases = 0;
     627        uint32_t total_sids = 0;
     628        uint32_t *alias_rids = NULL;
     629        uint32_t rangesize = MAX_SAM_ENTRIES_W2K;
     630        uint32_t i;
    638631        struct samr_Ids alias_rids_query;
    639         int rangesize = MAX_SAM_ENTRIES_W2K;
    640         uint32 total_sids = 0;
    641         int num_queries = 1;
    642 
    643         *num_aliases = 0;
    644         *alias_rids = NULL;
    645 
    646         DEBUG(3,("rpc: lookup_useraliases\n"));
    647 
    648         if ( !winbindd_can_contact_domain( domain ) ) {
    649                 DEBUG(10,("msrpc_lookup_useraliases: No incoming trust for domain %s\n",
    650                           domain->name));
    651                 return NT_STATUS_OK;
    652         }
    653 
    654         result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
    655         if (!NT_STATUS_IS_OK(result))
    656                 return result;
     632        NTSTATUS status, result;
     633        struct dcerpc_binding_handle *b = samr_pipe->binding_handle;
    657634
    658635        do {
     
    664641                num_query_sids = MIN(num_sids - total_sids, rangesize);
    665642
    666                 DEBUG(10,("rpc: lookup_useraliases: entering query %d for %d sids\n", 
    667                         num_queries, num_query_sids)); 
     643                DEBUG(10,("rpc: lookup_useraliases: entering query %d for %d sids\n",
     644                        num_queries, num_query_sids));
    668645
    669646                if (num_query_sids) {
     
    676653                }
    677654
    678                 for (i=0; i<num_query_sids; i++) {
    679                         sid_array.sids[i].sid = sid_dup_talloc(mem_ctx, &sids[total_sids++]);
    680                         if (!sid_array.sids[i].sid) {
    681                                 TALLOC_FREE(sid_array.sids);
     655                for (i = 0; i < num_query_sids; i++) {
     656                        sid_array.sids[i].sid = dom_sid_dup(mem_ctx, &sids[total_sids++]);
     657                        if (sid_array.sids[i].sid == NULL) {
    682658                                return NT_STATUS_NO_MEMORY;
    683659                        }
     
    686662
    687663                /* do request */
    688                 result = rpccli_samr_GetAliasMembership(cli, mem_ctx,
    689                                                         &dom_pol,
     664                status = dcerpc_samr_GetAliasMembership(b,
     665                                                        mem_ctx,
     666                                                        samr_policy,
    690667                                                        &sid_array,
    691                                                         &alias_rids_query);
    692 
     668                                                        &alias_rids_query,
     669                                                        &result);
     670                if (!NT_STATUS_IS_OK(status)) {
     671                        return status;
     672                }
    693673                if (!NT_STATUS_IS_OK(result)) {
    694                         *num_aliases = 0;
    695                         *alias_rids = NULL;
    696                         TALLOC_FREE(sid_array.sids);
    697                         goto done;
     674                        return result;
    698675                }
    699676
    700677                /* process output */
    701 
    702                 for (i=0; i<alias_rids_query.count; i++) {
    703                         size_t na = *num_aliases;
    704                         if (!add_rid_to_array_unique(mem_ctx, alias_rids_query.ids[i],
    705                                                 alias_rids, &na)) {
    706                                 return NT_STATUS_NO_MEMORY;
    707                         }
    708                         *num_aliases = na;
    709                 }
    710 
    711                 TALLOC_FREE(sid_array.sids);
     678                for (i = 0; i < alias_rids_query.count; i++) {
     679                        size_t na = num_aliases;
     680
     681                        if (!add_rid_to_array_unique(mem_ctx,
     682                                                     alias_rids_query.ids[i],
     683                                                     &alias_rids,
     684                                                     &na)) {
     685                                        return NT_STATUS_NO_MEMORY;
     686                                }
     687                                num_aliases = na;
     688                }
    712689
    713690                num_queries++;
     
    715692        } while (total_sids < num_sids);
    716693
    717  done:
    718         DEBUG(10,("rpc: lookup_useraliases: got %d aliases in %d queries "
    719                 "(rangesize: %d)\n", *num_aliases, num_queries, rangesize));
    720 
    721         return result;
    722 }
    723 
     694        DEBUG(10,("rpc: rpc_lookup_useraliases: got %d aliases in %d queries "
     695                  "(rangesize: %d)\n", num_aliases, num_queries, rangesize));
     696
     697        *pnum_aliases = num_aliases;
     698        *palias_rids = alias_rids;
     699
     700        return NT_STATUS_OK;
     701#undef MAX_SAM_ENTRIES_W2K
     702}
    724703
    725704/* Lookup group membership given a rid.   */
    726 static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
    727                                 TALLOC_CTX *mem_ctx,
    728                                 const DOM_SID *group_sid,
    729                                 enum lsa_SidType type,
    730                                 uint32 *num_names,
    731                                 DOM_SID **sid_mem, char ***names,
    732                                 uint32 **name_types)
    733 {
    734         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
    735         uint32 i, total_names = 0;
    736         struct policy_handle dom_pol, group_pol;
    737         uint32 des_access = SEC_FLAG_MAXIMUM_ALLOWED;
    738         uint32 *rid_mem = NULL;
    739         uint32 group_rid;
    740         unsigned int j, r;
    741         struct rpc_pipe_client *cli;
    742         unsigned int orig_timeout;
    743         struct samr_RidTypeArray *rids = NULL;
    744 
    745         DEBUG(10,("rpc: lookup_groupmem %s sid=%s\n", domain->name,
    746                   sid_string_dbg(group_sid)));
    747 
    748         if ( !winbindd_can_contact_domain( domain ) ) {
    749                 DEBUG(10,("lookup_groupmem: No incoming trust for domain %s\n",
    750                           domain->name));
    751                 return NT_STATUS_OK;
    752         }
    753 
    754         if (!sid_peek_check_rid(&domain->sid, group_sid, &group_rid))
     705NTSTATUS rpc_lookup_groupmem(TALLOC_CTX *mem_ctx,
     706                             struct rpc_pipe_client *samr_pipe,
     707                             struct policy_handle *samr_policy,
     708                             const char *domain_name,
     709                             const struct dom_sid *domain_sid,
     710                             const struct dom_sid *group_sid,
     711                             enum lsa_SidType type,
     712                             uint32_t *pnum_names,
     713                             struct dom_sid **psid_mem,
     714                             char ***pnames,
     715                             uint32_t **pname_types)
     716{
     717        struct policy_handle group_policy;
     718        uint32_t group_rid;
     719        uint32_t *rid_mem = NULL;
     720
     721        uint32_t num_names = 0;
     722        uint32_t total_names = 0;
     723        struct dom_sid *sid_mem = NULL;
     724        char **names = NULL;
     725        uint32_t *name_types = NULL;
     726
     727        struct lsa_Strings tmp_names;
     728        struct samr_Ids tmp_types;
     729
     730        uint32_t j, r;
     731        NTSTATUS status, result;
     732        struct dcerpc_binding_handle *b = samr_pipe->binding_handle;
     733
     734        if (!sid_peek_check_rid(domain_sid, group_sid, &group_rid)) {
    755735                return NT_STATUS_UNSUCCESSFUL;
    756 
    757         *num_names = 0;
    758 
    759         result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
    760         if (!NT_STATUS_IS_OK(result))
    761                 return result;
    762 
    763         result = rpccli_samr_OpenGroup(cli, mem_ctx,
    764                                        &dom_pol,
    765                                        des_access,
    766                                        group_rid,
    767                                        &group_pol);
    768 
    769         if (!NT_STATUS_IS_OK(result))
    770                 return result;
    771 
    772         /* Step #1: Get a list of user rids that are the members of the
    773            group. */
    774 
    775         /* This call can take a long time - allow the server to time out.
    776            35 seconds should do it. */
    777 
    778         orig_timeout = rpccli_set_timeout(cli, 35000);
    779 
    780         result = rpccli_samr_QueryGroupMember(cli, mem_ctx,
    781                                               &group_pol,
    782                                               &rids);
    783 
    784         /* And restore our original timeout. */
    785         rpccli_set_timeout(cli, orig_timeout);
    786 
    787         rpccli_samr_Close(cli, mem_ctx, &group_pol);
    788 
    789         if (!NT_STATUS_IS_OK(result))
    790                 return result;
    791 
    792         if (!rids || !rids->count) {
    793                 names = NULL;
    794                 name_types = NULL;
    795                 sid_mem = NULL;
    796                 return NT_STATUS_OK;
    797         }
    798 
    799         *num_names = rids->count;
    800         rid_mem = rids->rids;
    801 
    802         /* Step #2: Convert list of rids into list of usernames.  Do this
    803            in bunches of ~1000 to avoid crashing NT4.  It looks like there
    804            is a buffer overflow or something like that lurking around
    805            somewhere. */
    806 
    807 #define MAX_LOOKUP_RIDS 900
    808 
    809         *names = TALLOC_ZERO_ARRAY(mem_ctx, char *, *num_names);
    810         *name_types = TALLOC_ZERO_ARRAY(mem_ctx, uint32, *num_names);
    811         *sid_mem = TALLOC_ZERO_ARRAY(mem_ctx, DOM_SID, *num_names);
    812 
    813         for (j=0;j<(*num_names);j++)
    814                 sid_compose(&(*sid_mem)[j], &domain->sid, rid_mem[j]);
    815 
    816         if (*num_names>0 && (!*names || !*name_types))
    817                 return NT_STATUS_NO_MEMORY;
    818 
    819         for (i = 0; i < *num_names; i += MAX_LOOKUP_RIDS) {
    820                 int num_lookup_rids = MIN(*num_names - i, MAX_LOOKUP_RIDS);
    821                 struct lsa_Strings tmp_names;
    822                 struct samr_Ids tmp_types;
    823 
    824                 /* Lookup a chunk of rids */
    825 
    826                 result = rpccli_samr_LookupRids(cli, mem_ctx,
    827                                                 &dom_pol,
    828                                                 num_lookup_rids,
    829                                                 &rid_mem[i],
    830                                                 &tmp_names,
    831                                                 &tmp_types);
    832 
    833                 /* see if we have a real error (and yes the
    834                    STATUS_SOME_UNMAPPED is the one returned from 2k) */
    835 
    836                 if (!NT_STATUS_IS_OK(result) &&
    837                     !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
     736        }
     737
     738        switch(type) {
     739        case SID_NAME_DOM_GRP:
     740        {
     741                struct samr_RidAttrArray *rids = NULL;
     742
     743                status = dcerpc_samr_OpenGroup(b,
     744                                               mem_ctx,
     745                                               samr_policy,
     746                                               SEC_FLAG_MAXIMUM_ALLOWED,
     747                                               group_rid,
     748                                               &group_policy,
     749                                               &result);
     750                if (!NT_STATUS_IS_OK(status)) {
     751                        return status;
     752                }
     753                if (!NT_STATUS_IS_OK(result)) {
    838754                        return result;
    839 
    840                 /* Copy result into array.  The talloc system will take
    841                    care of freeing the temporary arrays later on. */
    842 
    843                 if (tmp_names.count != tmp_types.count) {
    844                         return NT_STATUS_UNSUCCESSFUL;
    845                 }
    846 
    847                 for (r=0; r<tmp_names.count; r++) {
    848                         if (tmp_types.ids[r] == SID_NAME_UNKNOWN) {
    849                                 continue;
    850                         }
    851                         (*names)[total_names] = fill_domain_username_talloc(
    852                                 mem_ctx, domain->name,
    853                                 tmp_names.names[r].string, true);
    854                         (*name_types)[total_names] = tmp_types.ids[r];
    855                         total_names += 1;
    856                 }
    857         }
    858 
    859         *num_names = total_names;
     755                }
     756
     757                /*
     758                 * Step #1: Get a list of user rids that are the members of the group.
     759                 */
     760                status = dcerpc_samr_QueryGroupMember(b,
     761                                                      mem_ctx,
     762                                                      &group_policy,
     763                                                      &rids,
     764                                                      &result);
     765                {
     766                        NTSTATUS _result;
     767                        dcerpc_samr_Close(b, mem_ctx, &group_policy, &_result);
     768                }
     769
     770                if (!NT_STATUS_IS_OK(status)) {
     771                        return status;
     772                }
     773                if (!NT_STATUS_IS_OK(result)) {
     774                        return result;
     775                }
     776
     777
     778                if (rids == NULL || rids->count == 0) {
     779                        pnum_names = 0;
     780                        pnames = NULL;
     781                        pname_types = NULL;
     782                        psid_mem = NULL;
     783
     784                        return NT_STATUS_OK;
     785                }
     786
     787                num_names = rids->count;
     788                rid_mem = rids->rids;
     789
     790                break;
     791        }
     792        case SID_NAME_WKN_GRP:
     793        case SID_NAME_ALIAS:
     794        {
     795                struct lsa_SidArray sid_array;
     796                struct lsa_SidPtr sid_ptr;
     797                struct samr_Ids rids_query;
     798
     799                sid_ptr.sid = dom_sid_dup(mem_ctx, group_sid);
     800                if (sid_ptr.sid == NULL) {
     801                        return NT_STATUS_NO_MEMORY;
     802                }
     803
     804                sid_array.num_sids = 1;
     805                sid_array.sids = &sid_ptr;
     806
     807                status = dcerpc_samr_GetAliasMembership(b,
     808                                                        mem_ctx,
     809                                                        samr_policy,
     810                                                        &sid_array,
     811                                                        &rids_query,
     812                                                        &result);
     813                if (!NT_STATUS_IS_OK(status)) {
     814                        return status;
     815                }
     816                if (!NT_STATUS_IS_OK(result)) {
     817                        return result;
     818                }
     819
     820                if (rids_query.count == 0) {
     821                        pnum_names = 0;
     822                        pnames = NULL;
     823                        pname_types = NULL;
     824                        psid_mem = NULL;
     825
     826                        return NT_STATUS_OK;
     827                }
     828
     829                num_names = rids_query.count;
     830                rid_mem = rids_query.ids;
     831
     832                break;
     833        }
     834        default:
     835                return NT_STATUS_UNSUCCESSFUL;
     836        }
     837
     838        /*
     839         * Step #2: Convert list of rids into list of usernames.
     840         */
     841        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);
     845                if (names == NULL || name_types == NULL || sid_mem == NULL) {
     846                        return NT_STATUS_NO_MEMORY;
     847                }
     848        }
     849
     850        for (j = 0; j < num_names; j++) {
     851                sid_compose(&sid_mem[j], domain_sid, rid_mem[j]);
     852        }
     853
     854        status = dcerpc_samr_LookupRids(b,
     855                                        mem_ctx,
     856                                        samr_policy,
     857                                        num_names,
     858                                        rid_mem,
     859                                        &tmp_names,
     860                                        &tmp_types,
     861                                        &result);
     862        if (!NT_STATUS_IS_OK(status)) {
     863                return status;
     864        }
     865
     866        if (!NT_STATUS_IS_OK(result)) {
     867                if (!NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) {
     868                        return result;
     869                }
     870        }
     871
     872        /* Copy result into array.  The talloc system will take
     873           care of freeing the temporary arrays later on. */
     874        if (tmp_names.count != tmp_types.count) {
     875                return NT_STATUS_UNSUCCESSFUL;
     876        }
     877
     878        for (r = 0; r < tmp_names.count; r++) {
     879                if (tmp_types.ids[r] == SID_NAME_UNKNOWN) {
     880                        continue;
     881                }
     882                names[total_names] = fill_domain_username_talloc(names,
     883                                                                 domain_name,
     884                                                                 tmp_names.names[r].string,
     885                                                                 true);
     886                if (names[total_names] == NULL) {
     887                        return NT_STATUS_NO_MEMORY;
     888                }
     889                name_types[total_names] = tmp_types.ids[r];
     890                total_names++;
     891        }
     892
     893        *pnum_names = total_names;
     894        *pnames = names;
     895        *pname_types = name_types;
     896        *psid_mem = sid_mem;
    860897
    861898        return NT_STATUS_OK;
    862899}
    863900
    864 #ifdef HAVE_LDAP
    865 
    866 #include <ldap.h>
    867 
    868 static int get_ldap_seq(const char *server, int port, uint32 *seq)
    869 {
    870         int ret = -1;
    871         struct timeval to;
    872         const char *attrs[] = {"highestCommittedUSN", NULL};
    873         LDAPMessage *res = NULL;
    874         char **values = NULL;
    875         LDAP *ldp = NULL;
    876 
    877         *seq = DOM_SEQUENCE_NONE;
    878 
    879         /*
    880          * Parameterised (5) second timeout on open. This is needed as the
    881          * search timeout doesn't seem to apply to doing an open as well. JRA.
    882          */
    883 
    884         ldp = ldap_open_with_timeout(server, port, lp_ldap_timeout());
    885         if (ldp == NULL)
    886                 return -1;
    887 
    888         /* Timeout if no response within 20 seconds. */
    889         to.tv_sec = 10;
    890         to.tv_usec = 0;
    891 
    892         if (ldap_search_st(ldp, "", LDAP_SCOPE_BASE, "(objectclass=*)",
    893                            CONST_DISCARD(char **, attrs), 0, &to, &res))
    894                 goto done;
    895 
    896         if (ldap_count_entries(ldp, res) != 1)
    897                 goto done;
    898 
    899         values = ldap_get_values(ldp, res, "highestCommittedUSN");
    900         if (!values || !values[0])
    901                 goto done;
    902 
    903         *seq = atoi(values[0]);
    904         ret = 0;
    905 
    906   done:
    907 
    908         if (values)
    909                 ldap_value_free(values);
    910         if (res)
    911                 ldap_msgfree(res);
    912         if (ldp)
    913                 ldap_unbind(ldp);
    914         return ret;
    915 }
    916 
    917 /**********************************************************************
    918  Get the sequence number for a Windows AD native mode domain using
    919  LDAP queries.
    920 **********************************************************************/
    921 
    922 static int get_ldap_sequence_number(struct winbindd_domain *domain, uint32 *seq)
    923 {
    924         int ret = -1;
    925         char addr[INET6_ADDRSTRLEN];
    926 
    927         print_sockaddr(addr, sizeof(addr), &domain->dcaddr);
    928         if ((ret = get_ldap_seq(addr, LDAP_PORT, seq)) == 0) {
    929                 DEBUG(3, ("get_ldap_sequence_number: Retrieved sequence "
    930                           "number for Domain (%s) from DC (%s)\n",
    931                         domain->name, addr));
    932         }
    933         return ret;
    934 }
    935 
    936 #endif /* HAVE_LDAP */
    937 
    938 /* find the sequence number for a domain */
    939 static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
    940 {
    941         TALLOC_CTX *mem_ctx;
     901/* Find the sequence number for a domain */
     902NTSTATUS rpc_sequence_number(TALLOC_CTX *mem_ctx,
     903                             struct rpc_pipe_client *samr_pipe,
     904                             struct policy_handle *samr_policy,
     905                             const char *domain_name,
     906                             uint32_t *pseq)
     907{
    942908        union samr_DomainInfo *info = NULL;
    943         NTSTATUS result;
    944         struct policy_handle dom_pol;
    945         bool got_seq_num = False;
    946         struct rpc_pipe_client *cli;
    947 
    948         DEBUG(10,("rpc: fetch sequence_number for %s\n", domain->name));
    949 
    950         if ( !winbindd_can_contact_domain( domain ) ) {
    951                 DEBUG(10,("sequence_number: No incoming trust for domain %s\n",
    952                           domain->name));
    953                 *seq = time(NULL);
    954                 return NT_STATUS_OK;
    955         }
    956 
    957         *seq = DOM_SEQUENCE_NONE;
    958 
    959         if (!(mem_ctx = talloc_init("sequence_number[rpc]")))
    960                 return NT_STATUS_NO_MEMORY;
    961 
    962 #ifdef HAVE_LDAP
    963         if ( domain->active_directory )
    964         {
    965                 int res;
    966 
    967                 DEBUG(8,("using get_ldap_seq() to retrieve the "
    968                          "sequence number\n"));
    969 
    970                 res =  get_ldap_sequence_number( domain, seq );
    971                 if (res == 0)
    972                 {                       
    973                         result = NT_STATUS_OK;
    974                         DEBUG(10,("domain_sequence_number: LDAP for "
    975                                   "domain %s is %u\n",
    976                                   domain->name, *seq));
    977                         goto done;
    978                 }
    979 
    980                 DEBUG(10,("domain_sequence_number: failed to get LDAP "
    981                           "sequence number for domain %s\n",
    982                           domain->name ));
    983         }
    984 #endif /* HAVE_LDAP */
    985 
    986         result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
    987         if (!NT_STATUS_IS_OK(result)) {
    988                 goto done;
    989         }
    990 
    991         /* Query domain info */
    992 
    993         result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
    994                                              &dom_pol,
     909        bool got_seq_num = false;
     910        NTSTATUS status, result;
     911        struct dcerpc_binding_handle *b = samr_pipe->binding_handle;
     912
     913        /* query domain info */
     914        status = dcerpc_samr_QueryDomainInfo(b,
     915                                             mem_ctx,
     916                                             samr_policy,
    995917                                             8,
    996                                              &info);
    997 
    998         if (NT_STATUS_IS_OK(result)) {
    999                 *seq = info->info8.sequence_num;
    1000                 got_seq_num = True;
     918                                             &info,
     919                                             &result);
     920        if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) {
     921                *pseq = info->info8.sequence_num;
     922                got_seq_num = true;
    1001923                goto seq_num;
    1002924        }
     
    1004926        /* retry with info-level 2 in case the dc does not support info-level 8
    1005927         * (like all older samba2 and samba3 dc's) - Guenther */
    1006 
    1007         result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
    1008                                              &dom_pol,
     928        status = dcerpc_samr_QueryDomainInfo(b,
     929                                            mem_ctx,
     930                                             samr_policy,
    1009931                                             2,
    1010                                              &info);
    1011 
    1012         if (NT_STATUS_IS_OK(result)) {
    1013                 *seq = info->general.sequence_num;
    1014                 got_seq_num = True;
    1015         }
    1016 
    1017  seq_num:
     932                                             &info,
     933                                             &result);
     934        if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) {
     935                *pseq = info->general.sequence_num;
     936                got_seq_num = true;
     937                goto seq_num;
     938        }
     939
     940        if (!NT_STATUS_IS_OK(status)) {
     941                goto seq_num;
     942        }
     943
     944        status = result;
     945
     946seq_num:
    1018947        if (got_seq_num) {
    1019948                DEBUG(10,("domain_sequence_number: for domain %s is %u\n",
    1020                           domain->name, (unsigned)*seq));
     949                          domain_name, (unsigned) *pseq));
    1021950        } else {
    1022951                DEBUG(10,("domain_sequence_number: failed to get sequence "
    1023952                          "number (%u) for domain %s\n",
    1024                           (unsigned)*seq, domain->name ));
    1025         }
    1026 
    1027   done:
    1028 
    1029         talloc_destroy(mem_ctx);
    1030 
    1031         return result;
    1032 }
    1033 
    1034 /* get a list of trusted domains */
    1035 static NTSTATUS trusted_domains(struct winbindd_domain *domain,
    1036                                 TALLOC_CTX *mem_ctx,
    1037                                 struct netr_DomainTrustList *trusts)
    1038 {
    1039         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
    1040         uint32 enum_ctx = 0;
    1041         struct rpc_pipe_client *cli;
    1042         struct policy_handle lsa_policy;
    1043 
    1044         DEBUG(3,("rpc: trusted_domains\n"));
    1045 
    1046         ZERO_STRUCTP(trusts);
    1047 
    1048         result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
    1049         if (!NT_STATUS_IS_OK(result))
    1050                 return result;
    1051 
    1052         result = STATUS_MORE_ENTRIES;
    1053 
    1054         while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
    1055                 uint32 start_idx;
    1056                 int i;
     953                          (unsigned) *pseq, domain_name ));
     954                status = NT_STATUS_OK;
     955        }
     956
     957        return status;
     958}
     959
     960/* Get a list of trusted domains */
     961NTSTATUS rpc_trusted_domains(TALLOC_CTX *mem_ctx,
     962                             struct rpc_pipe_client *lsa_pipe,
     963                             struct policy_handle *lsa_policy,
     964                             uint32_t *pnum_trusts,
     965                             struct netr_DomainTrust **ptrusts)
     966{
     967        struct netr_DomainTrust *array = NULL;
     968        uint32_t enum_ctx = 0;
     969        uint32_t count = 0;
     970        NTSTATUS status, result;
     971        struct dcerpc_binding_handle *b = lsa_pipe->binding_handle;
     972
     973        do {
    1057974                struct lsa_DomainList dom_list;
    1058 
    1059                 result = rpccli_lsa_EnumTrustDom(cli, mem_ctx,
    1060                                                  &lsa_policy,
     975                uint32_t start_idx;
     976                uint32_t i;
     977
     978                /*
     979                 * We don't run into deadlocks here, cause winbind_off() is
     980                 * called in the main function.
     981                 */
     982                status = dcerpc_lsa_EnumTrustDom(b,
     983                                                 mem_ctx,
     984                                                 lsa_policy,
    1061985                                                 &enum_ctx,
    1062986                                                 &dom_list,
    1063                                                  (uint32_t)-1);
    1064 
    1065                 if (!NT_STATUS_IS_OK(result) &&
    1066                     !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
    1067                         break;
    1068 
    1069                 start_idx = trusts->count;
    1070                 trusts->count += dom_list.count;
    1071 
    1072                 trusts->array = talloc_realloc(
    1073                         mem_ctx, trusts->array, struct netr_DomainTrust,
    1074                         trusts->count);
    1075                 if (trusts->array == NULL) {
     987                                                 (uint32_t) -1,
     988                                                 &result);
     989                if (!NT_STATUS_IS_OK(status)) {
     990                        return status;
     991                }
     992                if (!NT_STATUS_IS_OK(result)) {
     993                        if (!NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
     994                                return result;
     995                        }
     996                }
     997
     998                start_idx = count;
     999                count += dom_list.count;
     1000
     1001                array = talloc_realloc(mem_ctx,
     1002                                       array,
     1003                                       struct netr_DomainTrust,
     1004                                       count);
     1005                if (array == NULL) {
    10761006                        return NT_STATUS_NO_MEMORY;
    10771007                }
    10781008
    1079                 for (i=0; i<dom_list.count; i++) {
    1080                         struct netr_DomainTrust *trust = &trusts->array[i];
     1009                for (i = 0; i < dom_list.count; i++) {
     1010                        struct netr_DomainTrust *trust = &array[i];
    10811011                        struct dom_sid *sid;
    10821012
    10831013                        ZERO_STRUCTP(trust);
    10841014
    1085                         trust->netbios_name = talloc_move(
    1086                                 trusts->array,
    1087                                 &dom_list.domains[i].name.string);
     1015                        trust->netbios_name = talloc_move(array,
     1016                                                          &dom_list.domains[i].name.string);
    10881017                        trust->dns_name = NULL;
    10891018
    1090                         sid = talloc(trusts->array, struct dom_sid);
     1019                        sid = talloc(array, struct dom_sid);
    10911020                        if (sid == NULL) {
    10921021                                return NT_STATUS_NO_MEMORY;
     
    10951024                        trust->sid = sid;
    10961025                }
    1097         }
     1026        } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
     1027
     1028        *pnum_trusts = count;
     1029        *ptrusts = array;
     1030
     1031        return NT_STATUS_OK;
     1032}
     1033
     1034static NTSTATUS rpc_try_lookup_sids3(TALLOC_CTX *mem_ctx,
     1035                                     struct winbindd_domain *domain,
     1036                                     struct lsa_SidArray *sids,
     1037                                     struct lsa_RefDomainList **pdomains,
     1038                                     struct lsa_TransNameArray **pnames)
     1039{
     1040        struct lsa_TransNameArray2 lsa_names2;
     1041        struct lsa_TransNameArray *names;
     1042        uint32_t i, count;
     1043        struct rpc_pipe_client *cli;
     1044        NTSTATUS status, result;
     1045
     1046        status = cm_connect_lsa_tcp(domain, talloc_tos(), &cli);
     1047        if (!NT_STATUS_IS_OK(status)) {
     1048                domain->can_do_ncacn_ip_tcp = false;
     1049                return status;
     1050        }
     1051
     1052        ZERO_STRUCT(lsa_names2);
     1053        status = dcerpc_lsa_LookupSids3(cli->binding_handle,
     1054                                        mem_ctx,
     1055                                        sids,
     1056                                        pdomains,
     1057                                        &lsa_names2,
     1058                                        LSA_LOOKUP_NAMES_ALL,
     1059                                        &count,
     1060                                        LSA_LOOKUP_OPTION_SEARCH_ISOLATED_NAMES,
     1061                                        LSA_CLIENT_REVISION_2,
     1062                                        &result);
     1063        if (!NT_STATUS_IS_OK(status)) {
     1064                return status;
     1065        }
     1066        if (NT_STATUS_IS_ERR(result)) {
     1067                return result;
     1068        }
     1069        names = TALLOC_ZERO_P(mem_ctx, struct lsa_TransNameArray);
     1070        if (names == NULL) {
     1071                return NT_STATUS_NO_MEMORY;
     1072        }
     1073        names->count = lsa_names2.count;
     1074        names->names = talloc_array(names, struct lsa_TranslatedName,
     1075                                    names->count);
     1076        if (names->names == NULL) {
     1077                return NT_STATUS_NO_MEMORY;
     1078        }
     1079        for (i=0; i<names->count; i++) {
     1080                names->names[i].sid_type = lsa_names2.names[i].sid_type;
     1081                names->names[i].name.string = talloc_move(
     1082                        names->names, &lsa_names2.names[i].name.string);
     1083                names->names[i].sid_index = lsa_names2.names[i].sid_index;
     1084        }
     1085        *pnames = names;
    10981086        return result;
    10991087}
    11001088
    1101 /* find the lockout policy for a domain */
    1102 static NTSTATUS msrpc_lockout_policy(struct winbindd_domain *domain,
    1103                                      TALLOC_CTX *mem_ctx,
    1104                                      struct samr_DomInfo12 *lockout_policy)
    1105 {
    1106         NTSTATUS result;
    1107         struct rpc_pipe_client *cli;
    1108         struct policy_handle dom_pol;
    1109         union samr_DomainInfo *info = NULL;
    1110 
    1111         DEBUG(10,("rpc: fetch lockout policy for %s\n", domain->name));
    1112 
    1113         if ( !winbindd_can_contact_domain( domain ) ) {
    1114                 DEBUG(10,("msrpc_lockout_policy: No incoming trust for domain %s\n",
    1115                           domain->name));
    1116                 return NT_STATUS_NOT_SUPPORTED;
    1117         }
    1118 
    1119         result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
    1120         if (!NT_STATUS_IS_OK(result)) {
    1121                 goto done;
    1122         }
    1123 
    1124         result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
    1125                                              &dom_pol,
    1126                                              12,
    1127                                              &info);
    1128         if (!NT_STATUS_IS_OK(result)) {
    1129                 goto done;
    1130         }
    1131 
    1132         *lockout_policy = info->info12;
    1133 
    1134         DEBUG(10,("msrpc_lockout_policy: lockout_threshold %d\n",
    1135                 info->info12.lockout_threshold));
    1136 
    1137   done:
    1138 
    1139         return result;
    1140 }
    1141 
    1142 /* find the password policy for a domain */
    1143 static NTSTATUS msrpc_password_policy(struct winbindd_domain *domain,
    1144                                       TALLOC_CTX *mem_ctx,
    1145                                       struct samr_DomInfo1 *password_policy)
    1146 {
    1147         NTSTATUS result;
    1148         struct rpc_pipe_client *cli;
    1149         struct policy_handle dom_pol;
    1150         union samr_DomainInfo *info = NULL;
    1151 
    1152         DEBUG(10,("rpc: fetch password policy for %s\n", domain->name));
    1153 
    1154         if ( !winbindd_can_contact_domain( domain ) ) {
    1155                 DEBUG(10,("msrpc_password_policy: No incoming trust for domain %s\n",
    1156                           domain->name));
    1157                 return NT_STATUS_NOT_SUPPORTED;
    1158         }
    1159 
    1160         result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
    1161         if (!NT_STATUS_IS_OK(result)) {
    1162                 goto done;
    1163         }
    1164 
    1165         result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
    1166                                              &dom_pol,
    1167                                              1,
    1168                                              &info);
    1169         if (!NT_STATUS_IS_OK(result)) {
    1170                 goto done;
    1171         }
    1172 
    1173         *password_policy = info->info1;
    1174 
    1175         DEBUG(10,("msrpc_password_policy: min_length_password %d\n",
    1176                 info->info1.min_password_length));
    1177 
    1178   done:
    1179 
    1180         return result;
    1181 }
    1182 
    1183 typedef NTSTATUS (*lookup_sids_fn_t)(struct rpc_pipe_client *cli,
    1184                                      TALLOC_CTX *mem_ctx,
    1185                                      struct policy_handle *pol,
    1186                                      int num_sids,
    1187                                      const DOM_SID *sids,
    1188                                      char ***pdomains,
    1189                                      char ***pnames,
    1190                                      enum lsa_SidType **ptypes);
    1191 
    1192 NTSTATUS winbindd_lookup_sids(TALLOC_CTX *mem_ctx,
    1193                               struct winbindd_domain *domain,
    1194                               uint32_t num_sids,
    1195                               const struct dom_sid *sids,
    1196                               char ***domains,
    1197                               char ***names,
    1198                               enum lsa_SidType **types)
    1199 {
    1200         NTSTATUS status;
     1089NTSTATUS rpc_lookup_sids(TALLOC_CTX *mem_ctx,
     1090                         struct winbindd_domain *domain,
     1091                         struct lsa_SidArray *sids,
     1092                         struct lsa_RefDomainList **pdomains,
     1093                         struct lsa_TransNameArray **pnames)
     1094{
     1095        struct lsa_TransNameArray *names;
    12011096        struct rpc_pipe_client *cli = NULL;
    12021097        struct policy_handle lsa_policy;
    1203         unsigned int orig_timeout;
    1204         lookup_sids_fn_t lookup_sids_fn = rpccli_lsa_lookup_sids;
     1098        uint32_t count;
     1099        NTSTATUS status, result;
    12051100
    12061101        if (domain->can_do_ncacn_ip_tcp) {
    1207                 status = cm_connect_lsa_tcp(domain, mem_ctx, &cli);
    1208                 if (NT_STATUS_IS_OK(status)) {
    1209                         lookup_sids_fn = rpccli_lsa_lookup_sids3;
    1210                         goto lookup;
    1211                 }
    1212                 domain->can_do_ncacn_ip_tcp = false;
    1213         }
     1102                status = rpc_try_lookup_sids3(mem_ctx, domain, sids,
     1103                                              pdomains, pnames);
     1104                if (!NT_STATUS_IS_ERR(status)) {
     1105                        return status;
     1106                }
     1107        }
     1108
    12141109        status = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
    1215 
    12161110        if (!NT_STATUS_IS_OK(status)) {
    12171111                return status;
    12181112        }
    12191113
    1220  lookup:
    1221         /*
    1222          * This call can take a long time
    1223          * allow the server to time out.
    1224          * 35 seconds should do it.
    1225          */
    1226         orig_timeout = rpccli_set_timeout(cli, 35000);
    1227 
    1228         status = lookup_sids_fn(cli,
    1229                                 mem_ctx,
    1230                                 &lsa_policy,
    1231                                 num_sids,
    1232                                 sids,
    1233                                 domains,
    1234                                 names,
    1235                                 types);
    1236 
    1237         /* And restore our original timeout. */
    1238         rpccli_set_timeout(cli, orig_timeout);
    1239 
    1240         if (NT_STATUS_V(status) == DCERPC_FAULT_ACCESS_DENIED ||
    1241             NT_STATUS_V(status) == DCERPC_FAULT_SEC_PKG_ERROR) {
    1242                 /*
    1243                  * This can happen if the schannel key is not
    1244                  * valid anymore, we need to invalidate the
    1245                  * all connections to the dc and reestablish
    1246                  * a netlogon connection first.
    1247                  */
    1248                 invalidate_cm_connection(&domain->conn);
    1249                 status = NT_STATUS_ACCESS_DENIED;
    1250         }
    1251 
     1114        names = TALLOC_ZERO_P(mem_ctx, struct lsa_TransNameArray);
     1115        if (names == NULL) {
     1116                return NT_STATUS_NO_MEMORY;
     1117        }
     1118        status = dcerpc_lsa_LookupSids(cli->binding_handle, mem_ctx,
     1119                                       &lsa_policy, sids, pdomains,
     1120                                       names, LSA_LOOKUP_NAMES_ALL,
     1121                                       &count, &result);
    12521122        if (!NT_STATUS_IS_OK(status)) {
    12531123                return status;
    12541124        }
    1255 
    1256         return status;
    1257 }
    1258 
    1259 typedef NTSTATUS (*lookup_names_fn_t)(struct rpc_pipe_client *cli,
    1260                                       TALLOC_CTX *mem_ctx,
    1261                                       struct policy_handle *pol,
    1262                                       int num_names,
    1263                                       const char **names,
    1264                                       const char ***dom_names,
    1265                                       int level,
    1266                                       struct dom_sid **sids,
    1267                                       enum lsa_SidType **types);
    1268 
    1269 NTSTATUS winbindd_lookup_names(TALLOC_CTX *mem_ctx,
    1270                                struct winbindd_domain *domain,
    1271                                uint32_t num_names,
    1272                                const char **names,
    1273                                const char ***domains,
    1274                                struct dom_sid **sids,
    1275                                enum lsa_SidType **types)
    1276 {
    1277         NTSTATUS status;
    1278         struct rpc_pipe_client *cli = NULL;
    1279         struct policy_handle lsa_policy;
    1280         unsigned int orig_timeout = 0;
    1281         lookup_names_fn_t lookup_names_fn = rpccli_lsa_lookup_names;
    1282 
    1283         if (domain->can_do_ncacn_ip_tcp) {
    1284                 status = cm_connect_lsa_tcp(domain, mem_ctx, &cli);
    1285                 if (NT_STATUS_IS_OK(status)) {
    1286                         lookup_names_fn = rpccli_lsa_lookup_names4;
    1287                         goto lookup;
    1288                 }
    1289                 domain->can_do_ncacn_ip_tcp = false;
    1290         }
    1291         status = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
    1292 
    1293         if (!NT_STATUS_IS_OK(status)) {
    1294                 return status;
    1295         }
    1296 
    1297  lookup:
    1298 
    1299         /*
    1300          * This call can take a long time
    1301          * allow the server to time out.
    1302          * 35 seconds should do it.
    1303          */
    1304         orig_timeout = rpccli_set_timeout(cli, 35000);
    1305 
    1306         status = lookup_names_fn(cli,
    1307                                  mem_ctx,
    1308                                  &lsa_policy,
    1309                                  num_names,
    1310                                  (const char **) names,
    1311                                  domains,
    1312                                  1,
    1313                                  sids,
    1314                                  types);
    1315 
    1316         /* And restore our original timeout. */
    1317         rpccli_set_timeout(cli, orig_timeout);
    1318 
    1319         if (NT_STATUS_V(status) == DCERPC_FAULT_ACCESS_DENIED ||
    1320             NT_STATUS_V(status) == DCERPC_FAULT_SEC_PKG_ERROR) {
    1321                 /*
    1322                  * This can happen if the schannel key is not
    1323                  * valid anymore, we need to invalidate the
    1324                  * all connections to the dc and reestablish
    1325                  * a netlogon connection first.
    1326                  */
    1327                 invalidate_cm_connection(&domain->conn);
    1328                 status = NT_STATUS_ACCESS_DENIED;
    1329         }
    1330 
    1331         if (!NT_STATUS_IS_OK(status)) {
    1332                 return status;
    1333         }
    1334 
    1335         return status;
    1336 }
    1337 
    1338 /* the rpc backend methods are exposed via this structure */
    1339 struct winbindd_methods msrpc_methods = {
    1340         False,
    1341         query_user_list,
    1342         enum_dom_groups,
    1343         enum_local_groups,
    1344         msrpc_name_to_sid,
    1345         msrpc_sid_to_name,
    1346         msrpc_rids_to_names,
    1347         query_user,
    1348         lookup_usergroups,
    1349         msrpc_lookup_useraliases,
    1350         lookup_groupmem,
    1351         sequence_number,
    1352         msrpc_lockout_policy,
    1353         msrpc_password_policy,
    1354         trusted_domains,
    1355 };
     1125        if (NT_STATUS_IS_ERR(result)) {
     1126                return result;
     1127        }
     1128        *pnames = names;
     1129        return result;
     1130}
  • vendor/current/source3/winbindd/winbindd_show_sequence.c

    r414 r740  
    9898        status = wb_seqnum_recv(subreq, &state->seqnum);
    9999        TALLOC_FREE(subreq);
    100         if (!NT_STATUS_IS_OK(status)) {
    101                 tevent_req_nterror(req, status);
     100        if (tevent_req_nterror(req, status)) {
    102101                return;
    103102        }
     
    117116                                 &state->seqnums);
    118117        TALLOC_FREE(subreq);
    119         if (!NT_STATUS_IS_OK(status)) {
    120                 tevent_req_nterror(req, status);
     118        if (tevent_req_nterror(req, status)) {
    121119                return;
    122120        }
  • vendor/current/source3/winbindd/winbindd_sid_to_gid.c

    r414 r740  
    2020#include "includes.h"
    2121#include "winbindd.h"
     22#include "../libcli/security/security.h"
    2223
    2324struct winbindd_sid_to_gid_state {
     
    7273        status = wb_sid2gid_recv(subreq, &state->gid);
    7374        TALLOC_FREE(subreq);
    74         if (!NT_STATUS_IS_OK(status)) {
    75                 tevent_req_nterror(req, status);
     75        if (tevent_req_nterror(req, status)) {
    7676                return;
    7777        }
  • vendor/current/source3/winbindd/winbindd_sid_to_uid.c

    r414 r740  
    2020#include "includes.h"
    2121#include "winbindd.h"
     22#include "../libcli/security/security.h"
    2223
    2324struct winbindd_sid_to_uid_state {
     
    7273        status = wb_sid2uid_recv(subreq, &state->uid);
    7374        TALLOC_FREE(subreq);
    74         if (!NT_STATUS_IS_OK(status)) {
    75                 tevent_req_nterror(req, status);
     75        if (tevent_req_nterror(req, status)) {
    7676                return;
    7777        }
  • vendor/current/source3/winbindd/winbindd_uid_to_sid.c

    r414 r740  
    6464        status = wb_uid2sid_recv(subreq, &state->sid);
    6565        TALLOC_FREE(subreq);
    66         if (!NT_STATUS_IS_OK(status)) {
    67                 tevent_req_nterror(req, status);
     66        if (tevent_req_nterror(req, status)) {
    6867                return;
    6968        }
  • vendor/current/source3/winbindd/winbindd_util.c

    r478 r740  
    2323#include "includes.h"
    2424#include "winbindd.h"
     25#include "secrets.h"
     26#include "../libcli/security/security.h"
     27#include "../libcli/auth/pam_errors.h"
     28#include "passdb/machine_sid.h"
    2529
    2630#undef DBGC_CLASS
     
    2832
    2933extern struct winbindd_methods cache_methods;
    30 extern struct winbindd_methods builtin_passdb_methods;
    31 extern struct winbindd_methods sam_passdb_methods;
    32 
    3334
    3435/**
    35  * @file winbindd_util.c
     36 * @file winbindd_util.cq
    3637 *
    3738 * Winbind daemon for NT domain authentication nss module.
     
    5960/* Free all entries in the trusted domain list */
    6061
    61 void free_domain_list(void)
     62static void free_domain_list(void)
    6263{
    6364        struct winbindd_domain *domain = _domain_list;
     
    7273}
    7374
    74 static bool is_internal_domain(const DOM_SID *sid)
     75static bool is_internal_domain(const struct dom_sid *sid)
    7576{
    7677        if (sid == NULL)
     
    8081}
    8182
    82 static bool is_in_internal_domain(const DOM_SID *sid)
     83static bool is_in_internal_domain(const struct dom_sid *sid)
    8384{
    8485        if (sid == NULL)
     
    9293static struct winbindd_domain *add_trusted_domain(const char *domain_name, const char *alt_name,
    9394                                                  struct winbindd_methods *methods,
    94                                                   const DOM_SID *sid)
     95                                                  const struct dom_sid *sid)
    9596{
    9697        struct winbindd_domain *domain;
     
    138139                        }
    139140
    140                         if (sid_equal(sid, &domain->sid)) {
     141                        if (dom_sid_equal(sid, &domain->sid)) {
    141142                                break;
    142143                        }
     
    144145        }
    145146
    146         /* See if we found a match.  Check if we need to update the
    147            SID. */
    148 
    149         if ( domain && sid) {
    150                 if ( sid_equal( &domain->sid, &global_sid_NULL ) )
     147        if (domain != NULL) {
     148                /*
     149                 * We found a match. Possibly update the SID
     150                 */
     151                if ((sid != NULL)
     152                    && dom_sid_equal(&domain->sid, &global_sid_NULL)) {
    151153                        sid_copy( &domain->sid, sid );
    152 
     154                }
    153155                return domain;
    154156        }
     
    162164
    163165        ZERO_STRUCTP(domain);
     166
     167        domain->children = SMB_MALLOC_ARRAY(
     168                struct winbindd_child, lp_winbind_max_domain_connections());
     169        if (domain->children == NULL) {
     170                SAFE_FREE(domain);
     171                return NULL;
     172        }
     173        memset(domain->children, 0,
     174               sizeof(struct winbindd_child)
     175               * lp_winbind_max_domain_connections());
    164176
    165177        fstrcpy(domain->name, domain_name);
     
    224236}
    225237
     238bool domain_is_forest_root(const struct winbindd_domain *domain)
     239{
     240        const uint32_t fr_flags =
     241                (NETR_TRUST_FLAG_TREEROOT|NETR_TRUST_FLAG_IN_FOREST);
     242
     243        return ((domain->domain_flags & fr_flags) == fr_flags);
     244}
     245
    226246/********************************************************************
    227247  rescan our domains looking for new trusted domains
     
    229249
    230250struct trustdom_state {
    231         TALLOC_CTX *mem_ctx;
    232         bool primary;
    233         bool forest_root;
    234         struct winbindd_response *response;
     251        struct winbindd_domain *domain;
     252        struct winbindd_request request;
    235253};
    236254
    237 static void trustdom_recv(void *private_data, bool success);
     255static void trustdom_list_done(struct tevent_req *req);
    238256static void rescan_forest_root_trusts( void );
    239257static void rescan_forest_trusts( void );
     
    241259static void add_trusted_domains( struct winbindd_domain *domain )
    242260{
    243         TALLOC_CTX *mem_ctx;
    244         struct winbindd_request *request;
     261        struct trustdom_state *state;
     262        struct tevent_req *req;
     263
     264        state = TALLOC_ZERO_P(NULL, struct trustdom_state);
     265        if (state == NULL) {
     266                DEBUG(0, ("talloc failed\n"));
     267                return;
     268        }
     269        state->domain = domain;
     270
     271        state->request.length = sizeof(state->request);
     272        state->request.cmd = WINBINDD_LIST_TRUSTDOM;
     273
     274        req = wb_domain_request_send(state, winbind_event_context(),
     275                                     domain, &state->request);
     276        if (req == NULL) {
     277                DEBUG(1, ("wb_domain_request_send failed\n"));
     278                TALLOC_FREE(state);
     279                return;
     280        }
     281        tevent_req_set_callback(req, trustdom_list_done, state);
     282}
     283
     284static void trustdom_list_done(struct tevent_req *req)
     285{
     286        struct trustdom_state *state = tevent_req_callback_data(
     287                req, struct trustdom_state);
    245288        struct winbindd_response *response;
    246         uint32 fr_flags = (NETR_TRUST_FLAG_TREEROOT|NETR_TRUST_FLAG_IN_FOREST);
    247 
    248         struct trustdom_state *state;
    249 
    250         mem_ctx = talloc_init("add_trusted_domains");
    251         if (mem_ctx == NULL) {
    252                 DEBUG(0, ("talloc_init failed\n"));
    253                 return;
    254         }
    255 
    256         request = TALLOC_ZERO_P(mem_ctx, struct winbindd_request);
    257         response = TALLOC_P(mem_ctx, struct winbindd_response);
    258         state = TALLOC_P(mem_ctx, struct trustdom_state);
    259 
    260         if ((request == NULL) || (response == NULL) || (state == NULL)) {
    261                 DEBUG(0, ("talloc failed\n"));
    262                 talloc_destroy(mem_ctx);
    263                 return;
    264         }
    265 
    266         state->mem_ctx = mem_ctx;
    267         state->response = response;
    268 
    269         /* Flags used to know how to continue the forest trust search */
    270 
    271         state->primary = domain->primary;
    272         state->forest_root = ((domain->domain_flags & fr_flags) == fr_flags );
    273 
    274         request->length = sizeof(*request);
    275         request->cmd = WINBINDD_LIST_TRUSTDOM;
    276 
    277         async_domain_request(mem_ctx, domain, request, response,
    278                              trustdom_recv, state);
    279 }
    280 
    281 static void trustdom_recv(void *private_data, bool success)
    282 {
    283         struct trustdom_state *state =
    284                 talloc_get_type_abort(private_data, struct trustdom_state);
    285         struct winbindd_response *response = state->response;
     289        int res, err;
    286290        char *p;
    287291
    288         if ((!success) || (response->result != WINBINDD_OK)) {
     292        res = wb_domain_request_recv(req, state, &response, &err);
     293        if ((res == -1) || (response->result != WINBINDD_OK)) {
    289294                DEBUG(1, ("Could not receive trustdoms\n"));
    290                 talloc_destroy(state->mem_ctx);
     295                TALLOC_FREE(state);
    291296                return;
    292297        }
     
    296301        while ((p != NULL) && (*p != '\0')) {
    297302                char *q, *sidstr, *alt_name;
    298                 DOM_SID sid;
     303                struct dom_sid sid;
    299304                struct winbindd_domain *domain;
    300305                char *alternate_name = NULL;
     
    346351                                                    &sid);
    347352                        if (domain) {
    348                                 setup_domain_child(domain,
    349                                                    &domain->child);
     353                                setup_domain_child(domain);
    350354                        }
    351355                }
     
    363367        */
    364368
    365         if ( state->primary ) {
     369        if (state->domain->primary) {
    366370                /* If this is our primary domain and we are not in the
    367371                   forest root, we have to scan the root trusts first */
    368372
    369                 if ( !state->forest_root )
     373                if (!domain_is_forest_root(state->domain))
    370374                        rescan_forest_root_trusts();
    371375                else
    372376                        rescan_forest_trusts();
    373377
    374         } else if ( state->forest_root ) {
     378        } else if (domain_is_forest_root(state->domain)) {
    375379                /* Once we have done root forest trust search, we can
    376380                   go on to search the trusted forests */
     
    379383        }
    380384
    381         talloc_destroy(state->mem_ctx);
     385        TALLOC_FREE(state);
    382386
    383387        return;
     
    424428                                                &dom_list[i].sid );
    425429                        if (d != NULL) {
    426                                 setup_domain_child(d, &d->child);
     430                                setup_domain_child(d);
    427431                        }
    428432                }
     
    496500                                                        &dom_list[i].sid );
    497501                                if (d != NULL) {
    498                                         setup_domain_child(d, &d->child);
     502                                        setup_domain_child(d);
    499503                                }
    500504                        }
     
    606610        /* BUILTIN domain */
    607611
    608         domain = add_trusted_domain("BUILTIN", NULL, &builtin_passdb_methods,
     612        domain = add_trusted_domain("BUILTIN", NULL, &cache_methods,
    609613                                    &global_sid_Builtin);
    610614        if (domain) {
    611                 setup_domain_child(domain,
    612                                    &domain->child);
     615                setup_domain_child(domain);
    613616        }
    614617
     
    616619
    617620        domain = add_trusted_domain(get_global_sam_name(), NULL,
    618                                     &sam_passdb_methods, get_global_sam_sid());
     621                                    &cache_methods, get_global_sam_sid());
    619622        if (domain) {
    620623                if ( role != ROLE_DOMAIN_MEMBER ) {
    621624                        domain->primary = True;
    622625                }
    623                 setup_domain_child(domain,
    624                                    &domain->child);
     626                setup_domain_child(domain);
    625627        }
    626628
     
    628630
    629631        if ( role == ROLE_DOMAIN_MEMBER ) {
    630                 DOM_SID our_sid;
     632                struct dom_sid our_sid;
    631633
    632634                if (!secrets_fetch_domain_sid(lp_workgroup(), &our_sid)) {
     
    639641                if (domain) {
    640642                        domain->primary = True;
    641                         setup_domain_child(domain,
    642                                            &domain->child);
     643                        setup_domain_child(domain);
    643644
    644645                        /* Even in the parent winbindd we'll need to
     
    653654
    654655        return True;
    655 }
    656 
    657 void check_domain_trusted( const char *name, const DOM_SID *user_sid )
    658 {
    659         struct winbindd_domain *domain;
    660         DOM_SID dom_sid;
    661         uint32 rid;
    662 
    663         /* Check if we even care */
    664 
    665         if (!lp_allow_trusted_domains())
    666                 return;
    667 
    668         domain = find_domain_from_name_noinit( name );
    669         if ( domain )
    670                 return;
    671 
    672         sid_copy( &dom_sid, user_sid );
    673         if ( !sid_split_rid( &dom_sid, &rid ) )
    674                 return;
    675 
    676         /* add the newly discovered trusted domain */
    677 
    678         domain = add_trusted_domain( name, NULL, &cache_methods,
    679                                      &dom_sid);
    680 
    681         if ( !domain )
    682                 return;
    683 
    684         /* assume this is a trust from a one-way transitive
    685            forest trust */
    686 
    687         domain->active_directory = True;
    688         domain->domain_flags = NETR_TRUST_FLAG_OUTBOUND;
    689         domain->domain_type  = NETR_TRUST_TYPE_UPLEVEL;
    690         domain->internal = False;
    691         domain->online = True;
    692 
    693         setup_domain_child(domain,
    694                            &domain->child);
    695 
    696         wcache_tdc_add_domain( domain );
    697 
    698         return;
    699656}
    700657
     
    747704/* Given a domain sid, return the struct winbindd domain info for it */
    748705
    749 struct winbindd_domain *find_domain_from_sid_noinit(const DOM_SID *sid)
     706struct winbindd_domain *find_domain_from_sid_noinit(const struct dom_sid *sid)
    750707{
    751708        struct winbindd_domain *domain;
     
    754711
    755712        for (domain = domain_list(); domain != NULL; domain = domain->next) {
    756                 if (sid_compare_domain(sid, &domain->sid) == 0)
     713                if (dom_sid_compare_domain(sid, &domain->sid) == 0)
    757714                        return domain;
    758715        }
     
    765722/* Given a domain sid, return the struct winbindd domain info for it */
    766723
    767 struct winbindd_domain *find_domain_from_sid(const DOM_SID *sid)
     724struct winbindd_domain *find_domain_from_sid(const struct dom_sid *sid)
    768725{
    769726        struct winbindd_domain *domain;
     
    799756        struct winbindd_domain *ours = find_our_domain();
    800757
    801         if ( !ours )
     758        if (ours->forest_name[0] == '\0') {
    802759                return NULL;
    803 
    804         if ( strlen(ours->forest_name) == 0 )
    805                 return NULL;
     760        }
    806761
    807762        return find_domain_from_name( ours->forest_name );
     
    810765struct winbindd_domain *find_builtin_domain(void)
    811766{
    812         DOM_SID sid;
    813767        struct winbindd_domain *domain;
    814768
    815         string_to_sid(&sid, "S-1-5-32");
    816         domain = find_domain_from_sid(&sid);
    817 
     769        domain = find_domain_from_sid(&global_sid_Builtin);
    818770        if (domain == NULL) {
    819771                smb_panic("Could not find BUILTIN domain");
     
    825777/* Find the appropriate domain to lookup a name or SID */
    826778
    827 struct winbindd_domain *find_lookup_domain_from_sid(const DOM_SID *sid)
     779struct winbindd_domain *find_lookup_domain_from_sid(const struct dom_sid *sid)
    828780{
    829781        /* SIDs in the S-1-22-{1,2} domain should be handled by our passdb */
     
    943895}
    944896
    945 /* add a domain user name to a buffer */
    946 void parse_add_domuser(void *buf, char *domuser, int *len)
    947 {
    948         fstring domain;
    949         char *p, *user;
    950 
    951         user = domuser;
    952         p = strchr(domuser, *lp_winbind_separator());
    953 
    954         if (p) {
    955 
    956                 fstrcpy(domain, domuser);
    957                 domain[PTR_DIFF(p, domuser)] = 0;
    958                 p++;
    959 
    960                 if (assume_domain(domain)) {
    961 
    962                         user = p;
    963                         *len -= (PTR_DIFF(p, domuser));
    964                 }
    965         }
    966 
    967         safe_strcpy((char *)buf, user, *len);
    968 }
    969 
    970897/* Ensure an incoming username from NSS is fully qualified. Replace the
    971898   incoming fstring with DOMAIN <separator> user. Returns the same
     
    1046973
    1047974/*
    1048  * Winbindd socket accessor functions
    1049  */
    1050 
    1051 const char *get_winbind_pipe_dir(void)
    1052 {
    1053         return lp_parm_const_string(-1, "winbindd", "socket dir", WINBINDD_SOCKET_DIR);
    1054 }
    1055 
    1056 char *get_winbind_priv_pipe_dir(void)
    1057 {
    1058         return lock_path(WINBINDD_PRIV_SOCKET_SUBDIR);
    1059 }
    1060 
    1061 /* Open the winbindd socket */
    1062 
    1063 static int _winbindd_socket = -1;
    1064 static int _winbindd_priv_socket = -1;
    1065 
    1066 int open_winbindd_socket(void)
    1067 {
    1068         if (_winbindd_socket == -1) {
    1069                 _winbindd_socket = create_pipe_sock(
    1070                         get_winbind_pipe_dir(), WINBINDD_SOCKET_NAME, 0755);
    1071                 DEBUG(10, ("open_winbindd_socket: opened socket fd %d\n",
    1072                            _winbindd_socket));
    1073         }
    1074 
    1075         return _winbindd_socket;
    1076 }
    1077 
    1078 int open_winbindd_priv_socket(void)
    1079 {
    1080         if (_winbindd_priv_socket == -1) {
    1081                 _winbindd_priv_socket = create_pipe_sock(
    1082                         get_winbind_priv_pipe_dir(), WINBINDD_SOCKET_NAME, 0750);
    1083                 DEBUG(10, ("open_winbindd_priv_socket: opened socket fd %d\n",
    1084                            _winbindd_priv_socket));
    1085         }
    1086 
    1087         return _winbindd_priv_socket;
    1088 }
    1089 
    1090 /*
    1091975 * Client list accessor functions
    1092976 */
     
    11181002}
    11191003
    1120 /* Close all open clients */
    1121 
    1122 void winbindd_kill_all_clients(void)
    1123 {
    1124         struct winbindd_cli_state *cl = winbindd_client_list();
    1125 
    1126         DEBUG(10, ("winbindd_kill_all_clients: going postal\n"));
    1127 
    1128         while (cl) {
    1129                 struct winbindd_cli_state *next;
    1130 
    1131                 next = cl->next;
    1132                 winbindd_remove_client(cl);
    1133                 cl = next;
    1134         }
    1135 }
    1136 
    11371004/* Return number of open clients */
    11381005
     
    11441011NTSTATUS lookup_usergroups_cached(struct winbindd_domain *domain,
    11451012                                  TALLOC_CTX *mem_ctx,
    1146                                   const DOM_SID *user_sid,
    1147                                   uint32 *p_num_groups, DOM_SID **user_sids)
     1013                                  const struct dom_sid *user_sid,
     1014                                  uint32_t *p_num_groups, struct dom_sid **user_sids)
    11481015{
    11491016        struct netr_SamInfo3 *info3 = NULL;
    11501017        NTSTATUS status = NT_STATUS_NO_MEMORY;
    1151         size_t num_groups = 0;
     1018        uint32_t num_groups = 0;
    11521019
    11531020        DEBUG(3,(": lookup_usergroups_cached\n"));
     
    14791346        return !domain->online;
    14801347}
     1348
     1349bool is_domain_online(const struct winbindd_domain *domain)
     1350{
     1351        return !is_domain_offline(domain);
     1352}
     1353
     1354bool parse_sidlist(TALLOC_CTX *mem_ctx, const char *sidstr,
     1355                   struct dom_sid **sids, uint32_t *num_sids)
     1356{
     1357        const char *p;
     1358
     1359        p = sidstr;
     1360        if (p == NULL)
     1361                return False;
     1362
     1363        while (p[0] != '\0') {
     1364                struct dom_sid sid;
     1365                const char *q = NULL;
     1366
     1367                if (!dom_sid_parse_endp(p, &sid, &q)) {
     1368                        DEBUG(1, ("Could not parse sid %s\n", p));
     1369                        return false;
     1370                }
     1371                if ((q == NULL) || (q[0] != '\n')) {
     1372                        DEBUG(1, ("Got invalid sidstr: %s\n", p));
     1373                        return false;
     1374                }
     1375                if (!NT_STATUS_IS_OK(add_sid_to_array(mem_ctx, &sid, sids,
     1376                                                      num_sids)))
     1377                {
     1378                        return False;
     1379                }
     1380                p = q+1;
     1381        }
     1382        return True;
     1383}
  • vendor/current/source3/winbindd/winbindd_wins.c

    r414 r740  
    2323#include "includes.h"
    2424#include "winbindd.h"
     25#include "libsmb/nmblib.h"
    2526
    2627#undef DBGC_CLASS
    2728#define DBGC_CLASS DBGC_WINBIND
    2829
    29 /* Use our own create socket code so we don't recurse.... */
    30 
    31 static int wins_lookup_open_socket_in(void)
    32 {
    33         struct sockaddr_in sock;
    34         int val=1;
    35         int res;
    36 
    37         memset((char *)&sock,'\0',sizeof(sock));
    38 
    39 #ifdef HAVE_SOCK_SIN_LEN
    40         sock.sin_len = sizeof(sock);
    41 #endif
    42         sock.sin_port = 0;
    43         sock.sin_family = AF_INET;
    44         sock.sin_addr.s_addr = interpret_addr("0.0.0.0");
    45         res = socket(AF_INET, SOCK_DGRAM, 0);
    46         if (res == -1)
    47                 return -1;
    48 
    49         if (setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&val,sizeof(val))) {
    50                 close(res);
    51                 return -1;
    52         }
    53 #ifdef SO_REUSEPORT
    54         if (setsockopt(res,SOL_SOCKET,SO_REUSEPORT,(char *)&val,sizeof(val))) {
    55                 close(res);
    56                 return -1;
    57         }
    58 #endif /* SO_REUSEPORT */
    59 
    60         /* now we've got a socket - we need to bind it */
    61 
    62         if (bind(res, (struct sockaddr *)(void *)&sock, sizeof(sock)) < 0) {
    63                 close(res);
    64                 return(-1);
    65         }
    66 
    67         set_socket_options(res,"SO_BROADCAST");
    68 
    69         return res;
    70 }
    71 
    72 
    73 static NODE_STATUS_STRUCT *lookup_byaddr_backend(const char *addr, int *count)
    74 {
    75         int fd;
     30static struct node_status *lookup_byaddr_backend(TALLOC_CTX *mem_ctx,
     31                                                 const char *addr, int *count)
     32{
    7633        struct sockaddr_storage ss;
    7734        struct nmb_name nname;
    78         NODE_STATUS_STRUCT *status;
    79 
    80         fd = wins_lookup_open_socket_in();
    81         if (fd == -1)
    82                 return NULL;
     35        struct node_status *result;
     36        NTSTATUS status;
    8337
    8438        make_nmb_name(&nname, "*", 0);
     
    8640                return NULL;
    8741        }
    88         status = node_status_query(fd, &nname, &ss, count, NULL);
    89 
    90         close(fd);
    91         return status;
    92 }
    93 
    94 static struct sockaddr_storage *lookup_byname_backend(const char *name,
    95                                         int *count)
    96 {
    97         int fd;
     42        status = node_status_query(mem_ctx, &nname, &ss,
     43                                   &result, count, NULL);
     44        if (!NT_STATUS_IS_OK(status)) {
     45                return NULL;
     46        }
     47        return result;
     48}
     49
     50static struct sockaddr_storage *lookup_byname_backend(TALLOC_CTX *mem_ctx,
     51                                                      const char *name,
     52                                                      int *count)
     53{
    9854        struct ip_service *ret = NULL;
    9955        struct sockaddr_storage *return_ss = NULL;
    100         int j, i, flags = 0;
     56        int j, i;
     57        NTSTATUS status;
    10158
    10259        *count = 0;
     
    10663                if ( *count == 0 )
    10764                        return NULL;
    108                 if ( (return_ss = SMB_MALLOC_ARRAY(struct sockaddr_storage, *count)) == NULL ) {
     65                return_ss = TALLOC_ARRAY(mem_ctx, struct sockaddr_storage,
     66                                         *count);
     67                if (return_ss == NULL ) {
    10968                        free( ret );
    11069                        return NULL;
     
    11776                free( ret );
    11877                return return_ss;
    119         }
    120 
    121         fd = wins_lookup_open_socket_in();
    122         if (fd == -1) {
    123                 return NULL;
    12478        }
    12579
     
    13286                        continue;
    13387                }
    134                 return_ss = name_query(fd,name,0x20,True,True,bcast_ss,count, &flags, NULL);
    135                 if (return_ss) {
     88                status = name_query(name, 0x20, True, True,bcast_ss,
     89                                    mem_ctx, &return_ss, count, NULL);
     90                if (NT_STATUS_IS_OK(status)) {
    13691                        break;
    13792                }
    13893        }
    13994
    140         close(fd);
    14195        return return_ss;
    14296}
     
    148102        fstring response;
    149103        int i, count, maxlen, size;
    150         NODE_STATUS_STRUCT *status;
     104        struct node_status *status;
    151105
    152106        /* Ensure null termination */
     
    159113        maxlen = sizeof(response) - 1;
    160114
    161         if ((status = lookup_byaddr_backend(state->request->data.winsreq, &count))){
     115        if ((status = lookup_byaddr_backend(
     116                     state->mem_ctx, state->request->data.winsreq, &count))) {
    162117            size = strlen(state->request->data.winsreq);
    163118            if (size > maxlen) {
    164                 SAFE_FREE(status);
     119                TALLOC_FREE(status);
    165120                request_error(state);
    166121                return;
     
    174129                        size = sizeof(status[i].name) + strlen(response);
    175130                        if (size > maxlen) {
    176                             SAFE_FREE(status);
     131                            TALLOC_FREE(status);
    177132                            request_error(state);
    178133                            return;
     
    184139            /* make last character a newline */
    185140            response[strlen(response)-1] = '\n';
    186             SAFE_FREE(status);
     141            TALLOC_FREE(status);
    187142        }
    188143        fstrcpy(state->response->data.winsresp,response);
     
    208163        maxlen = sizeof(response) - 1;
    209164
    210         if ((ip_list = lookup_byname_backend(state->request->data.winsreq,&count))){
     165        ip_list = lookup_byname_backend(
     166                state->mem_ctx, state->request->data.winsreq, &count);
     167        if (ip_list != NULL){
    211168                for (i = count; i ; i--) {
    212169                        print_sockaddr(addr, sizeof(addr), &ip_list[i-1]);
    213170                        size = strlen(addr);
    214171                        if (size > maxlen) {
    215                                 SAFE_FREE(ip_list);
     172                                TALLOC_FREE(ip_list);
    216173                                request_error(state);
    217174                                return;
     
    230187                size = strlen(state->request->data.winsreq) + strlen(response);
    231188                if (size > maxlen) {
    232                     SAFE_FREE(ip_list);
     189                    TALLOC_FREE(ip_list);
    233190                    request_error(state);
    234191                    return;
     
    236193                fstrcat(response,state->request->data.winsreq);
    237194                fstrcat(response,"\n");
    238                 SAFE_FREE(ip_list);
     195                TALLOC_FREE(ip_list);
    239196        } else {
    240197                request_error(state);
Note: See TracChangeset for help on using the changeset viewer.