LCOV - code coverage report
Current view: top level - source3/winbindd - winbindd_util.c (source / functions) Hit Total Coverage
Test: coverage report for fix-15632 9995c5c2 Lines: 446 961 46.4 %
Date: 2024-04-13 12:30:31 Functions: 39 52 75.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    Winbind daemon for ntdom nss module
       5             : 
       6             :    Copyright (C) Tim Potter 2000-2001
       7             :    Copyright (C) 2001 by Martin Pool <mbp@samba.org>
       8             : 
       9             :    This program is free software; you can redistribute it and/or modify
      10             :    it under the terms of the GNU General Public License as published by
      11             :    the Free Software Foundation; either version 3 of the License, or
      12             :    (at your option) any later version.
      13             : 
      14             :    This program is distributed in the hope that it will be useful,
      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             :    GNU General Public License for more details.
      18             : 
      19             :    You should have received a copy of the GNU General Public License
      20             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      21             : */
      22             : 
      23             : #include "includes.h"
      24             : #include "winbindd.h"
      25             : #include "lib/util_unixsids.h"
      26             : #include "secrets.h"
      27             : #include "../libcli/security/security.h"
      28             : #include "../libcli/auth/pam_errors.h"
      29             : #include "passdb/machine_sid.h"
      30             : #include "passdb.h"
      31             : #include "source4/lib/messaging/messaging.h"
      32             : #include "librpc/gen_ndr/ndr_lsa.h"
      33             : #include "librpc/gen_ndr/ndr_drsblobs.h"
      34             : #include "auth/credentials/credentials.h"
      35             : #include "libsmb/samlogon_cache.h"
      36             : #include "lib/util/smb_strtox.h"
      37             : #include "lib/util/string_wrappers.h"
      38             : #include "lib/global_contexts.h"
      39             : #include "librpc/gen_ndr/ndr_winbind_c.h"
      40             : 
      41             : #undef DBGC_CLASS
      42             : #define DBGC_CLASS DBGC_WINBIND
      43             : 
      44             : /**
      45             :  * @file winbindd_util.c
      46             :  *
      47             :  * Winbind daemon for NT domain authentication nss module.
      48             :  **/
      49             : 
      50             : static bool add_trusted_domains_dc(void);
      51             : 
      52             : /* The list of trusted domains.  Note that the list can be deleted and
      53             :    recreated using the init_domain_list() function so pointers to
      54             :    individual winbindd_domain structures cannot be made.  Keep a copy of
      55             :    the domain name instead. */
      56             : 
      57             : static struct winbindd_domain *_domain_list = NULL;
      58             : 
      59      229627 : struct winbindd_domain *domain_list(void)
      60             : {
      61             :         /* Initialise list */
      62             : 
      63      229627 :         if ((!_domain_list) && (!init_domain_list())) {
      64           0 :                 smb_panic("Init_domain_list failed");
      65             :         }
      66             : 
      67      229627 :         return _domain_list;
      68             : }
      69             : 
      70             : /* Free all entries in the trusted domain list */
      71             : 
      72          41 : static void free_domain_list(void)
      73             : {
      74          41 :         struct winbindd_domain *domain = _domain_list;
      75             : 
      76          41 :         while(domain) {
      77           0 :                 struct winbindd_domain *next = domain->next;
      78             : 
      79           0 :                 DLIST_REMOVE(_domain_list, domain);
      80           0 :                 TALLOC_FREE(domain);
      81           0 :                 domain = next;
      82             :         }
      83          41 : }
      84             : 
      85             : /**
      86             :  * Iterator for winbindd's domain list.
      87             :  * To be used (e.g.) in tevent based loops.
      88             :  */
      89         208 : struct winbindd_domain *wb_next_domain(struct winbindd_domain *domain)
      90             : {
      91         208 :         if (domain == NULL) {
      92          64 :                 domain = domain_list();
      93             :         } else {
      94         144 :                 domain = domain->next;
      95             :         }
      96             : 
      97         376 :         if ((domain != NULL) &&
      98         336 :             (lp_server_role() != ROLE_ACTIVE_DIRECTORY_DC) &&
      99         168 :             sid_check_is_our_sam(&domain->sid))
     100             :         {
     101          64 :                 domain = domain->next;
     102             :         }
     103             : 
     104         208 :         return domain;
     105             : }
     106             : 
     107         242 : static bool is_internal_domain(const struct dom_sid *sid)
     108             : {
     109         242 :         if (sid == NULL)
     110           0 :                 return False;
     111             : 
     112         242 :         return (sid_check_is_our_sam(sid) || sid_check_is_builtin(sid));
     113             : }
     114             : 
     115             : /* Add a trusted domain to our list of domains.
     116             :    If the domain already exists in the list,
     117             :    return it and don't re-initialize.  */
     118             : 
     119        1509 : static NTSTATUS add_trusted_domain(const char *domain_name,
     120             :                                    const char *dns_name,
     121             :                                    const struct dom_sid *sid,
     122             :                                    uint32_t trust_type,
     123             :                                    uint32_t trust_flags,
     124             :                                    uint32_t trust_attribs,
     125             :                                    enum netr_SchannelType secure_channel_type,
     126             :                                    struct winbindd_domain *routing_domain,
     127             :                                    struct winbindd_domain **_d)
     128             : {
     129        1509 :         struct winbindd_domain *domain = NULL;
     130        1509 :         int role = lp_server_role();
     131           0 :         struct dom_sid_buf buf;
     132             : 
     133        1509 :         if (is_null_sid(sid)) {
     134           0 :                 DBG_ERR("Got null SID for domain [%s]\n", domain_name);
     135           0 :                 return NT_STATUS_INVALID_PARAMETER;
     136             :         }
     137             : 
     138        1509 :         if (secure_channel_type == SEC_CHAN_NULL && !is_allowed_domain(domain_name)) {
     139           0 :                 return NT_STATUS_NO_SUCH_DOMAIN;
     140             :         }
     141             : 
     142             :         /*
     143             :          * We can't call domain_list() as this function is called from
     144             :          * init_domain_list() and we'll get stuck in a loop.
     145             :          */
     146        4546 :         for (domain = _domain_list; domain; domain = domain->next) {
     147        4425 :                 if (strequal(domain_name, domain->name)) {
     148        1388 :                         break;
     149             :                 }
     150             :         }
     151             : 
     152        1509 :         if (domain != NULL) {
     153        1388 :                 struct winbindd_domain *check_domain = NULL;
     154             : 
     155        1388 :                 for (check_domain = _domain_list;
     156        7148 :                      check_domain != NULL;
     157        5760 :                      check_domain = check_domain->next)
     158             :                 {
     159        5760 :                         if (check_domain == domain) {
     160        1388 :                                 continue;
     161             :                         }
     162             : 
     163        4372 :                         if (dom_sid_equal(&check_domain->sid, sid)) {
     164           0 :                                 break;
     165             :                         }
     166             :                 }
     167             : 
     168        1388 :                 if (check_domain != NULL) {
     169           0 :                         DBG_ERR("SID [%s] already used by domain [%s], "
     170             :                                 "expected [%s]\n",
     171             :                                 dom_sid_str_buf(sid, &buf),
     172             :                                 check_domain->name,
     173             :                                 domain->name);
     174           0 :                         return NT_STATUS_INVALID_PARAMETER;
     175             :                 }
     176             :         }
     177             : 
     178        1509 :         if ((domain != NULL) && (dns_name != NULL)) {
     179        1142 :                 struct winbindd_domain *check_domain = NULL;
     180             : 
     181        1142 :                 for (check_domain = _domain_list;
     182        6140 :                      check_domain != NULL;
     183        4998 :                      check_domain = check_domain->next)
     184             :                 {
     185        4998 :                         if (check_domain == domain) {
     186        1142 :                                 continue;
     187             :                         }
     188             : 
     189        3856 :                         if (strequal(check_domain->alt_name, dns_name)) {
     190           0 :                                 break;
     191             :                         }
     192             :                 }
     193             : 
     194        1142 :                 if (check_domain != NULL) {
     195           0 :                         DBG_ERR("DNS name [%s] used by domain [%s], "
     196             :                                 "expected [%s]\n",
     197             :                                 dns_name, check_domain->name,
     198             :                                 domain->name);
     199           0 :                         return NT_STATUS_INVALID_PARAMETER;
     200             :                 }
     201             :         }
     202             : 
     203        1509 :         if (domain != NULL) {
     204        1388 :                 *_d = domain;
     205        1388 :                 return NT_STATUS_OK;
     206             :         }
     207             : 
     208             :         /* Create new domain entry */
     209         121 :         domain = talloc_zero(NULL, struct winbindd_domain);
     210         121 :         if (domain == NULL) {
     211           0 :                 return NT_STATUS_NO_MEMORY;
     212             :         }
     213             : 
     214         121 :         domain->children = talloc_zero_array(domain,
     215             :                                              struct winbindd_child,
     216             :                                              lp_winbind_max_domain_connections());
     217         121 :         if (domain->children == NULL) {
     218           0 :                 TALLOC_FREE(domain);
     219           0 :                 return NT_STATUS_NO_MEMORY;
     220             :         }
     221             : 
     222         121 :         domain->queue = tevent_queue_create(domain, "winbind_domain");
     223         121 :         if (domain->queue == NULL) {
     224           0 :                 TALLOC_FREE(domain);
     225           0 :                 return NT_STATUS_NO_MEMORY;
     226             :         }
     227             : 
     228         121 :         domain->binding_handle = wbint_binding_handle(domain, domain, NULL);
     229         121 :         if (domain->binding_handle == NULL) {
     230           0 :                 TALLOC_FREE(domain);
     231           0 :                 return NT_STATUS_NO_MEMORY;
     232             :         }
     233             : 
     234         121 :         domain->name = talloc_strdup(domain, domain_name);
     235         121 :         if (domain->name == NULL) {
     236           0 :                 TALLOC_FREE(domain);
     237           0 :                 return NT_STATUS_NO_MEMORY;
     238             :         }
     239             : 
     240         121 :         if (dns_name != NULL) {
     241          39 :                 domain->alt_name = talloc_strdup(domain, dns_name);
     242          39 :                 if (domain->alt_name == NULL) {
     243           0 :                         TALLOC_FREE(domain);
     244           0 :                         return NT_STATUS_NO_MEMORY;
     245             :                 }
     246             :         }
     247             : 
     248         121 :         domain->backend = NULL;
     249         121 :         domain->internal = is_internal_domain(sid);
     250         121 :         domain->secure_channel_type = secure_channel_type;
     251         121 :         domain->sequence_number = DOM_SEQUENCE_NONE;
     252         121 :         domain->last_seq_check = 0;
     253         121 :         domain->initialized = false;
     254         121 :         domain->online = is_internal_domain(sid);
     255         121 :         domain->domain_flags = trust_flags;
     256         121 :         domain->domain_type = trust_type;
     257         121 :         domain->domain_trust_attribs = trust_attribs;
     258         121 :         domain->secure_channel_type = secure_channel_type;
     259         121 :         domain->routing_domain = routing_domain;
     260         121 :         sid_copy(&domain->sid, sid);
     261             : 
     262             :         /* Is this our primary domain ? */
     263         121 :         if (role == ROLE_DOMAIN_MEMBER) {
     264         101 :                 domain->primary = strequal(domain_name, lp_workgroup());
     265             :         } else {
     266          20 :                 domain->primary = strequal(domain_name, get_global_sam_name());
     267             :         }
     268             : 
     269         121 :         if (domain->primary) {
     270          41 :                 if (role == ROLE_ACTIVE_DIRECTORY_DC) {
     271           0 :                         domain->active_directory = true;
     272             :                 }
     273          41 :                 if (lp_security() == SEC_ADS) {
     274          28 :                         domain->active_directory = true;
     275             :                 }
     276          80 :         } else if (!domain->internal) {
     277           8 :                 if (domain->domain_type == LSA_TRUST_TYPE_UPLEVEL) {
     278           0 :                         domain->active_directory = true;
     279             :                 }
     280             :         }
     281             : 
     282         121 :         domain->can_do_ncacn_ip_tcp = domain->active_directory;
     283             : 
     284             :         /* Link to domain list */
     285         121 :         DLIST_ADD_END(_domain_list, domain);
     286             : 
     287         121 :         wcache_tdc_add_domain( domain );
     288             : 
     289         121 :         setup_domain_child(domain);
     290             : 
     291         121 :         DBG_NOTICE("Added domain [%s] [%s] [%s]\n",
     292             :                    domain->name, domain->alt_name,
     293             :                    dom_sid_str_buf(&domain->sid, &buf));
     294             : 
     295         121 :         *_d = domain;
     296         121 :         return NT_STATUS_OK;
     297             : }
     298             : 
     299           0 : bool set_routing_domain(struct winbindd_domain *domain,
     300             :                         struct winbindd_domain *routing_domain)
     301             : {
     302           0 :         if (domain->routing_domain == NULL) {
     303           0 :                 domain->routing_domain = routing_domain;
     304           0 :                 return true;
     305             :         }
     306           0 :         if (domain->routing_domain != routing_domain) {
     307           0 :                 return false;
     308             :         }
     309           0 :         return true;
     310             : }
     311             : 
     312        1420 : bool add_trusted_domain_from_auth(uint16_t validation_level,
     313             :                                   struct info3_text *info3,
     314             :                                   struct info6_text *info6)
     315             : {
     316        1420 :         struct winbindd_domain *domain = NULL;
     317           0 :         struct dom_sid domain_sid;
     318        1420 :         const char *dns_domainname = NULL;
     319           0 :         NTSTATUS status;
     320           0 :         bool ok;
     321             : 
     322             :         /*
     323             :          * We got a successful auth from a domain that might not yet be in our
     324             :          * domain list. If we're a member we trust our DC who authenticated the
     325             :          * user from that domain and add the domain to our list on-the-fly. If
     326             :          * we're a DC we rely on configured trusts and don't add on-the-fly.
     327             :          */
     328             : 
     329        1420 :         if (IS_DC) {
     330          24 :                 return true;
     331             :         }
     332             : 
     333        1396 :         ok = dom_sid_parse(info3->dom_sid, &domain_sid);
     334        1396 :         if (!ok) {
     335           0 :                 DBG_NOTICE("dom_sid_parse [%s] failed\n", info3->dom_sid);
     336           0 :                 return false;
     337             :         }
     338             : 
     339        1396 :         if (validation_level == 6) {
     340        1274 :                 if (!strequal(info6->dns_domainname, "")) {
     341        1150 :                         dns_domainname = info6->dns_domainname;
     342             :                 }
     343             :         }
     344             : 
     345        1396 :         status = add_trusted_domain(info3->logon_dom,
     346             :                                     dns_domainname,
     347             :                                     &domain_sid,
     348             :                                     0,
     349             :                                     NETR_TRUST_FLAG_OUTBOUND,
     350             :                                     0,
     351             :                                     SEC_CHAN_NULL,
     352             :                                     find_default_route_domain(),
     353             :                                     &domain);
     354        1396 :         if (!NT_STATUS_IS_OK(status) &&
     355           0 :             !NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_DOMAIN))
     356             :         {
     357           0 :                 DBG_DEBUG("Adding domain [%s] with sid [%s] failed\n",
     358             :                           info3->logon_dom, info3->dom_sid);
     359           0 :                 return false;
     360             :         }
     361             : 
     362        1396 :         return true;
     363             : }
     364             : 
     365           0 : bool domain_is_forest_root(const struct winbindd_domain *domain)
     366             : {
     367           0 :         const uint32_t fr_flags =
     368             :                 (NETR_TRUST_FLAG_TREEROOT|NETR_TRUST_FLAG_IN_FOREST);
     369             : 
     370           0 :         return ((domain->domain_flags & fr_flags) == fr_flags);
     371             : }
     372             : 
     373             : /********************************************************************
     374             :   rescan our domains looking for new trusted domains
     375             : ********************************************************************/
     376             : 
     377             : struct trustdom_state {
     378             :         struct winbindd_domain *domain;
     379             :         struct netr_DomainTrustList trusts;
     380             : };
     381             : 
     382             : static void trustdom_list_done(struct tevent_req *req);
     383             : static void rescan_forest_root_trusts( void );
     384             : static void rescan_forest_trusts( void );
     385             : 
     386           0 : static void add_trusted_domains( struct winbindd_domain *domain )
     387             : {
     388           0 :         struct tevent_context *ev = global_event_context();
     389           0 :         struct trustdom_state *state;
     390           0 :         struct tevent_req *req;
     391           0 :         const char *client_name = NULL;
     392           0 :         pid_t client_pid;
     393             : 
     394           0 :         state = talloc_zero(NULL, struct trustdom_state);
     395           0 :         if (state == NULL) {
     396           0 :                 DEBUG(0, ("talloc failed\n"));
     397           0 :                 return;
     398             :         }
     399           0 :         state->domain = domain;
     400             : 
     401             :         /* Called from timer, not from a real client */
     402           0 :         client_name = getprogname();
     403           0 :         client_pid = getpid();
     404             : 
     405           0 :         req = dcerpc_wbint_ListTrustedDomains_send(state,
     406             :                                                    ev,
     407             :                                                    dom_child_handle(domain),
     408             :                                                    client_name,
     409             :                                                    client_pid,
     410             :                                                    &state->trusts);
     411           0 :         if (req == NULL) {
     412           0 :                 DBG_ERR("dcerpc_wbint_ListTrustedDomains_send failed\n");
     413           0 :                 TALLOC_FREE(state);
     414           0 :                 return;
     415             :         }
     416           0 :         tevent_req_set_callback(req, trustdom_list_done, state);
     417             : }
     418             : 
     419           0 : static void trustdom_list_done(struct tevent_req *req)
     420             : {
     421           0 :         struct trustdom_state *state = tevent_req_callback_data(
     422             :                 req, struct trustdom_state);
     423           0 :         bool within_forest = false;
     424           0 :         NTSTATUS status, result;
     425           0 :         uint32_t i;
     426             : 
     427             :         /*
     428             :          * Only when we enumerate our primary domain
     429             :          * or our forest root domain, we should keep
     430             :          * the NETR_TRUST_FLAG_IN_FOREST flag, in
     431             :          * all other cases we need to clear it as the domain
     432             :          * is not part of our forest.
     433             :          */
     434           0 :         if (state->domain->primary) {
     435           0 :                 within_forest = true;
     436           0 :         } else if (domain_is_forest_root(state->domain)) {
     437           0 :                 within_forest = true;
     438             :         }
     439             : 
     440           0 :         status = dcerpc_wbint_ListTrustedDomains_recv(req, state, &result);
     441           0 :         if (any_nt_status_not_ok(status, result, &status)) {
     442           0 :                 DBG_WARNING("Could not receive trusts for domain %s: %s-%s\n",
     443             :                             state->domain->name, nt_errstr(status),
     444             :                             nt_errstr(result));
     445           0 :                 TALLOC_FREE(state);
     446           0 :                 return;
     447             :         }
     448             : 
     449           0 :         for (i=0; i<state->trusts.count; i++) {
     450           0 :                 struct netr_DomainTrust *trust = &state->trusts.array[i];
     451           0 :                 struct winbindd_domain *domain = NULL;
     452             : 
     453           0 :                 if (!within_forest) {
     454           0 :                         trust->trust_flags &= ~NETR_TRUST_FLAG_IN_FOREST;
     455             :                 }
     456             : 
     457           0 :                 if (!state->domain->primary) {
     458           0 :                         trust->trust_flags &= ~NETR_TRUST_FLAG_PRIMARY;
     459             :                 }
     460             : 
     461             :                 /*
     462             :                  * We always call add_trusted_domain() cause on an existing
     463             :                  * domain structure, it will update the SID if necessary.
     464             :                  * This is important because we need the SID for sibling
     465             :                  * domains.
     466             :                  */
     467           0 :                 status = add_trusted_domain(trust->netbios_name,
     468             :                                             trust->dns_name,
     469           0 :                                             trust->sid,
     470           0 :                                             trust->trust_type,
     471             :                                             trust->trust_flags,
     472             :                                             trust->trust_attributes,
     473             :                                             SEC_CHAN_NULL,
     474             :                                             find_default_route_domain(),
     475             :                                             &domain);
     476           0 :                 if (!NT_STATUS_IS_OK(status) &&
     477           0 :                     !NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_DOMAIN))
     478             :                 {
     479           0 :                         DBG_NOTICE("add_trusted_domain returned %s\n",
     480             :                                    nt_errstr(status));
     481           0 :                         return;
     482             :                 }
     483             :         }
     484             : 
     485             :         /*
     486             :            Cases to consider when scanning trusts:
     487             :            (a) we are calling from a child domain (primary && !forest_root)
     488             :            (b) we are calling from the root of the forest (primary && forest_root)
     489             :            (c) we are calling from a trusted forest domain (!primary
     490             :                && !forest_root)
     491             :         */
     492             : 
     493           0 :         if (state->domain->primary) {
     494             :                 /* If this is our primary domain and we are not in the
     495             :                    forest root, we have to scan the root trusts first */
     496             : 
     497           0 :                 if (!domain_is_forest_root(state->domain))
     498           0 :                         rescan_forest_root_trusts();
     499             :                 else
     500           0 :                         rescan_forest_trusts();
     501             : 
     502           0 :         } else if (domain_is_forest_root(state->domain)) {
     503             :                 /* Once we have done root forest trust search, we can
     504             :                    go on to search the trusted forests */
     505             : 
     506           0 :                 rescan_forest_trusts();
     507             :         }
     508             : 
     509           0 :         TALLOC_FREE(state);
     510             : 
     511           0 :         return;
     512             : }
     513             : 
     514             : /********************************************************************
     515             :  Scan the trusts of our forest root
     516             : ********************************************************************/
     517             : 
     518           0 : static void rescan_forest_root_trusts( void )
     519             : {
     520           0 :         struct winbindd_tdc_domain *dom_list = NULL;
     521           0 :         size_t num_trusts = 0;
     522           0 :         size_t i;
     523           0 :         NTSTATUS status;
     524             : 
     525             :         /* The only transitive trusts supported by Windows 2003 AD are
     526             :            (a) Parent-Child, (b) Tree-Root, and (c) Forest.   The
     527             :            first two are handled in forest and listed by
     528             :            DsEnumerateDomainTrusts().  Forest trusts are not so we
     529             :            have to do that ourselves. */
     530             : 
     531           0 :         if ( !wcache_tdc_fetch_list( &dom_list, &num_trusts ) )
     532           0 :                 return;
     533             : 
     534           0 :         for ( i=0; i<num_trusts; i++ ) {
     535           0 :                 struct winbindd_domain *d = NULL;
     536             : 
     537             :                 /* Find the forest root.  Don't necessarily trust
     538             :                    the domain_list() as our primary domain may not
     539             :                    have been initialized. */
     540             : 
     541           0 :                 if ( !(dom_list[i].trust_flags & NETR_TRUST_FLAG_TREEROOT) ) {
     542           0 :                         continue;
     543             :                 }
     544             : 
     545             :                 /* Here's the forest root */
     546             : 
     547           0 :                 d = find_domain_from_name_noinit( dom_list[i].domain_name );
     548           0 :                 if (d == NULL) {
     549           0 :                         status = add_trusted_domain(dom_list[i].domain_name,
     550           0 :                                                     dom_list[i].dns_name,
     551           0 :                                                     &dom_list[i].sid,
     552           0 :                                                     dom_list[i].trust_type,
     553           0 :                                                     dom_list[i].trust_flags,
     554           0 :                                                     dom_list[i].trust_attribs,
     555             :                                                     SEC_CHAN_NULL,
     556             :                                                     find_default_route_domain(),
     557             :                                                     &d);
     558             : 
     559           0 :                         if (!NT_STATUS_IS_OK(status) &&
     560           0 :                             NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_DOMAIN))
     561             :                         {
     562           0 :                                 DBG_ERR("add_trusted_domain returned %s\n",
     563             :                                         nt_errstr(status));
     564           0 :                                 return;
     565             :                         }
     566             :                 }
     567           0 :                 if (d == NULL) {
     568           0 :                         continue;
     569             :                 }
     570             : 
     571           0 :                 DEBUG(10,("rescan_forest_root_trusts: Following trust path "
     572             :                           "for domain tree root %s (%s)\n",
     573             :                           d->name, d->alt_name ));
     574             : 
     575           0 :                 d->domain_flags = dom_list[i].trust_flags;
     576           0 :                 d->domain_type  = dom_list[i].trust_type;
     577           0 :                 d->domain_trust_attribs = dom_list[i].trust_attribs;
     578             : 
     579           0 :                 add_trusted_domains( d );
     580             : 
     581           0 :                 break;
     582             :         }
     583             : 
     584           0 :         TALLOC_FREE( dom_list );
     585             : 
     586           0 :         return;
     587             : }
     588             : 
     589             : /********************************************************************
     590             :  scan the transitive forest trusts (not our own)
     591             : ********************************************************************/
     592             : 
     593             : 
     594           0 : static void rescan_forest_trusts( void )
     595             : {
     596           0 :         struct winbindd_domain *d = NULL;
     597           0 :         struct winbindd_tdc_domain *dom_list = NULL;
     598           0 :         size_t num_trusts = 0;
     599           0 :         size_t i;
     600           0 :         NTSTATUS status;
     601             : 
     602             :         /* The only transitive trusts supported by Windows 2003 AD are
     603             :            (a) Parent-Child, (b) Tree-Root, and (c) Forest.   The
     604             :            first two are handled in forest and listed by
     605             :            DsEnumerateDomainTrusts().  Forest trusts are not so we
     606             :            have to do that ourselves. */
     607             : 
     608           0 :         if ( !wcache_tdc_fetch_list( &dom_list, &num_trusts ) )
     609           0 :                 return;
     610             : 
     611           0 :         for ( i=0; i<num_trusts; i++ ) {
     612           0 :                 uint32_t flags   = dom_list[i].trust_flags;
     613           0 :                 uint32_t type    = dom_list[i].trust_type;
     614           0 :                 uint32_t attribs = dom_list[i].trust_attribs;
     615             : 
     616           0 :                 d = find_domain_from_name_noinit( dom_list[i].domain_name );
     617             : 
     618             :                 /* ignore our primary and internal domains */
     619             : 
     620           0 :                 if ( d && (d->internal || d->primary ) )
     621           0 :                         continue;
     622             : 
     623           0 :                 if ( (flags & NETR_TRUST_FLAG_INBOUND) &&
     624           0 :                      (type == LSA_TRUST_TYPE_UPLEVEL) &&
     625           0 :                      (attribs & LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) )
     626             :                 {
     627             :                         /* add the trusted domain if we don't know
     628             :                            about it */
     629             : 
     630           0 :                         if (d == NULL) {
     631           0 :                                 status = add_trusted_domain(
     632           0 :                                         dom_list[i].domain_name,
     633           0 :                                         dom_list[i].dns_name,
     634           0 :                                         &dom_list[i].sid,
     635             :                                         type,
     636             :                                         flags,
     637             :                                         attribs,
     638             :                                         SEC_CHAN_NULL,
     639             :                                         find_default_route_domain(),
     640             :                                         &d);
     641           0 :                                 if (!NT_STATUS_IS_OK(status) &&
     642           0 :                                     NT_STATUS_EQUAL(status,
     643             :                                                     NT_STATUS_NO_SUCH_DOMAIN))
     644             :                                 {
     645           0 :                                         DBG_ERR("add_trusted_domain: %s\n",
     646             :                                                 nt_errstr(status));
     647           0 :                                         return;
     648             :                                 }
     649             :                         }
     650             : 
     651           0 :                         if (d == NULL) {
     652           0 :                                 continue;
     653             :                         }
     654             : 
     655           0 :                         DEBUG(10,("Following trust path for domain %s (%s)\n",
     656             :                                   d->name, d->alt_name ));
     657           0 :                         add_trusted_domains( d );
     658             :                 }
     659             :         }
     660             : 
     661           0 :         TALLOC_FREE( dom_list );
     662             : 
     663           0 :         return;
     664             : }
     665             : 
     666             : /*********************************************************************
     667             :  The process of updating the trusted domain list is a three step
     668             :  async process:
     669             :  (a) ask our domain
     670             :  (b) ask the root domain in our forest
     671             :  (c) ask a DC in any Win2003 trusted forests
     672             : *********************************************************************/
     673             : 
     674           0 : void rescan_trusted_domains(struct tevent_context *ev, struct tevent_timer *te,
     675             :                             struct timeval now, void *private_data)
     676             : {
     677           0 :         TALLOC_FREE(te);
     678             : 
     679             :         /* I used to clear the cache here and start over but that
     680             :            caused problems in child processes that needed the
     681             :            trust dom list early on.  Removing it means we
     682             :            could have some trusted domains listed that have been
     683             :            removed from our primary domain's DC until a full
     684             :            restart.  This should be ok since I think this is what
     685             :            Windows does as well. */
     686             : 
     687             :         /* this will only add new domains we didn't already know about
     688             :            in the domain_list()*/
     689             : 
     690           0 :         add_trusted_domains( find_our_domain() );
     691             : 
     692           0 :         te = tevent_add_timer(
     693             :                 ev, NULL, timeval_current_ofs(WINBINDD_RESCAN_FREQ, 0),
     694             :                 rescan_trusted_domains, NULL);
     695             :         /*
     696             :          * If te == NULL, there's not much we can do here. Don't fail, the
     697             :          * only thing we miss is new trusted domains.
     698             :          */
     699             : 
     700           0 :         return;
     701             : }
     702             : 
     703             : static void wbd_ping_dc_done(struct tevent_req *subreq);
     704             : 
     705         777 : void winbindd_ping_offline_domains(struct tevent_context *ev,
     706             :                                    struct tevent_timer *te,
     707             :                                    struct timeval now,
     708             :                                    void *private_data)
     709             : {
     710         777 :         struct winbindd_domain *domain = NULL;
     711             : 
     712         777 :         TALLOC_FREE(te);
     713             : 
     714        2783 :         for (domain = domain_list(); domain != NULL; domain = domain->next) {
     715        2010 :                 DBG_DEBUG("Domain %s is %s\n",
     716             :                           domain->name,
     717             :                           domain->online ? "online" : "offline");
     718             : 
     719        2010 :                 if (get_global_winbindd_state_offline()) {
     720           4 :                         DBG_DEBUG("We are globally offline, do nothing.\n");
     721           4 :                         break;
     722             :                 }
     723             : 
     724        2006 :                 if (domain->online ||
     725         133 :                     domain->check_online_event != NULL ||
     726         133 :                     domain->secure_channel_type == SEC_CHAN_NULL) {
     727        1961 :                         continue;
     728             :                 }
     729             : 
     730          45 :                 winbindd_flush_negative_conn_cache(domain);
     731             : 
     732          45 :                 domain->check_online_event =
     733          45 :                         dcerpc_wbint_PingDc_send(domain,
     734             :                                                  ev,
     735             :                                                  dom_child_handle(domain),
     736             :                                                  &domain->ping_dcname);
     737          45 :                 if (domain->check_online_event == NULL) {
     738           0 :                         DBG_WARNING("Failed to schedule ping, no-memory\n");
     739           0 :                         continue;
     740             :                 }
     741             : 
     742          45 :                 tevent_req_set_callback(domain->check_online_event,
     743             :                                         wbd_ping_dc_done, domain);
     744             :         }
     745             : 
     746         777 :         te = tevent_add_timer(ev,
     747             :                               NULL,
     748             :                               timeval_current_ofs(lp_winbind_reconnect_delay(),
     749             :                                                   0),
     750             :                               winbindd_ping_offline_domains,
     751             :                               NULL);
     752         777 :         if (te == NULL) {
     753           0 :                 DBG_ERR("Failed to schedule winbindd_ping_offline_domains()\n");
     754             :         }
     755             : 
     756         777 :         return;
     757             : }
     758             : 
     759          45 : static void wbd_ping_dc_done(struct tevent_req *subreq)
     760             : {
     761           0 :         struct winbindd_domain *domain =
     762          45 :                 tevent_req_callback_data(subreq,
     763             :                 struct winbindd_domain);
     764           0 :         NTSTATUS status, result;
     765             : 
     766          45 :         SMB_ASSERT(subreq == domain->check_online_event);
     767          45 :         domain->check_online_event = NULL;
     768             : 
     769          45 :         status = dcerpc_wbint_PingDc_recv(subreq, domain, &result);
     770          45 :         TALLOC_FREE(subreq);
     771          45 :         if (any_nt_status_not_ok(status, result, &status)) {
     772          22 :                 DBG_WARNING("dcerpc_wbint_PingDc_recv failed for domain: "
     773             :                             "%s - %s\n",
     774             :                             domain->name,
     775             :                             nt_errstr(status));
     776          22 :                 return;
     777             :         }
     778             : 
     779          23 :         DBG_DEBUG("dcerpc_wbint_PingDc_recv() succeeded, "
     780             :                   "domain: %s, dc-name: %s\n",
     781             :                   domain->name,
     782             :                   domain->ping_dcname);
     783             : 
     784          23 :         talloc_free(discard_const(domain->ping_dcname));
     785          23 :         domain->ping_dcname = NULL;
     786             : 
     787          23 :         return;
     788             : }
     789             : 
     790           0 : static void wb_imsg_new_trusted_domain(struct imessaging_context *msg,
     791             :                                        void *private_data,
     792             :                                        uint32_t msg_type,
     793             :                                        struct server_id server_id,
     794             :                                        size_t num_fds,
     795             :                                        int *fds,
     796             :                                        DATA_BLOB *data)
     797             : {
     798           0 :         bool ok;
     799             : 
     800           0 :         if (num_fds != 0) {
     801           0 :                 DBG_WARNING("Received %zu fds, ignoring message\n", num_fds);
     802           0 :                 return;
     803             :         }
     804             : 
     805           0 :         DBG_NOTICE("Rescanning trusted domains\n");
     806             : 
     807           0 :         ok = add_trusted_domains_dc();
     808           0 :         if (!ok) {
     809           0 :                 DBG_ERR("Failed to reload trusted domains\n");
     810             :         }
     811             : }
     812             : 
     813             : /*
     814             :  * We did not get the secret when we queried secrets.tdb, so read it
     815             :  * from secrets.tdb and re-sync the databases
     816             :  */
     817           0 : static bool migrate_secrets_tdb_to_ldb(struct winbindd_domain *domain)
     818             : {
     819           0 :         bool ok;
     820           0 :         struct cli_credentials *creds;
     821           0 :         NTSTATUS can_migrate = pdb_get_trust_credentials(domain->name,
     822             :                                                          NULL, domain, &creds);
     823           0 :         if (!NT_STATUS_IS_OK(can_migrate)) {
     824           0 :                 DEBUG(0, ("Failed to fetch our own local AD domain join "
     825             :                         "password for winbindd's internal use, both from "
     826             :                         "secrets.tdb and secrets.ldb: %s\n",
     827             :                         nt_errstr(can_migrate)));
     828           0 :                 return false;
     829             :         }
     830             : 
     831             :         /*
     832             :          * NOTE: It is very unlikely we end up here if there is an
     833             :          * oldpass, because a new password is created at
     834             :          * classicupgrade, so this is not a concern.
     835             :          */
     836           0 :         ok = secrets_store_machine_pw_sync(cli_credentials_get_password(creds),
     837             :                    NULL /* oldpass */,
     838             :                    cli_credentials_get_domain(creds),
     839             :                    cli_credentials_get_realm(creds),
     840             :                    cli_credentials_get_salt_principal(creds),
     841             :                    0, /* Supported enc types, unused */
     842           0 :                    &domain->sid,
     843           0 :                    cli_credentials_get_password_last_changed_time(creds),
     844           0 :                    cli_credentials_get_secure_channel_type(creds),
     845             :                    false /* do_delete: Do not delete */);
     846           0 :         TALLOC_FREE(creds);
     847           0 :         if (ok == false) {
     848           0 :                 DEBUG(0, ("Failed to write our own "
     849             :                           "local AD domain join password for "
     850             :                           "winbindd's internal use into secrets.tdb\n"));
     851           0 :                 return false;
     852             :         }
     853           0 :         return true;
     854             : }
     855             : 
     856          10 : static bool add_trusted_domains_dc(void)
     857             : {
     858          10 :         struct winbindd_domain *domain =  NULL;
     859          10 :         struct pdb_trusted_domain **domains = NULL;
     860          10 :         uint32_t num_domains = 0;
     861           0 :         uint32_t i;
     862           0 :         NTSTATUS status;
     863             : 
     864          10 :         if (!(pdb_capabilities() & PDB_CAP_TRUSTED_DOMAINS_EX)) {
     865          10 :                 struct trustdom_info **ti = NULL;
     866             : 
     867          10 :                 status = pdb_enum_trusteddoms(talloc_tos(), &num_domains, &ti);
     868          10 :                 if (!NT_STATUS_IS_OK(status)) {
     869           0 :                         DBG_ERR("pdb_enum_trusteddoms() failed - %s\n",
     870             :                                 nt_errstr(status));
     871           0 :                         return false;
     872             :                 }
     873             : 
     874          10 :                 for (i = 0; i < num_domains; i++) {
     875           0 :                         status = add_trusted_domain(ti[i]->name,
     876             :                                                     NULL,
     877           0 :                                                     &ti[i]->sid,
     878             :                                                     LSA_TRUST_TYPE_DOWNLEVEL,
     879             :                                                     NETR_TRUST_FLAG_OUTBOUND,
     880             :                                                     0,
     881             :                                                     SEC_CHAN_DOMAIN,
     882             :                                                     NULL,
     883             :                                                     &domain);
     884           0 :                         if (!NT_STATUS_IS_OK(status)) {
     885           0 :                                 DBG_NOTICE("add_trusted_domain returned %s\n",
     886             :                                            nt_errstr(status));
     887           0 :                                 return false;
     888             :                         }
     889             :                 }
     890             : 
     891          10 :                 return true;
     892             :         }
     893             : 
     894           0 :         status = pdb_enum_trusted_domains(talloc_tos(), &num_domains, &domains);
     895           0 :         if (!NT_STATUS_IS_OK(status)) {
     896           0 :                 DBG_ERR("pdb_enum_trusted_domains() failed - %s\n",
     897             :                         nt_errstr(status));
     898           0 :                 return false;
     899             :         }
     900             : 
     901           0 :         for (i = 0; i < num_domains; i++) {
     902           0 :                 enum netr_SchannelType sec_chan_type = SEC_CHAN_DOMAIN;
     903           0 :                 uint32_t trust_flags = 0;
     904             : 
     905           0 :                 if (domains[i]->trust_type == LSA_TRUST_TYPE_UPLEVEL) {
     906           0 :                         sec_chan_type = SEC_CHAN_DNS_DOMAIN;
     907             :                 }
     908             : 
     909           0 :                 if (!(domains[i]->trust_direction & LSA_TRUST_DIRECTION_OUTBOUND)) {
     910           0 :                         sec_chan_type = SEC_CHAN_NULL;
     911             :                 }
     912             : 
     913           0 :                 if (domains[i]->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
     914           0 :                         trust_flags |= NETR_TRUST_FLAG_INBOUND;
     915             :                 }
     916           0 :                 if (domains[i]->trust_direction & LSA_TRUST_DIRECTION_OUTBOUND) {
     917           0 :                         trust_flags |= NETR_TRUST_FLAG_OUTBOUND;
     918             :                 }
     919           0 :                 if (domains[i]->trust_attributes & LSA_TRUST_ATTRIBUTE_WITHIN_FOREST) {
     920           0 :                         trust_flags |= NETR_TRUST_FLAG_IN_FOREST;
     921             :                 }
     922             : 
     923           0 :                 if (domains[i]->trust_attributes & LSA_TRUST_ATTRIBUTE_CROSS_ORGANIZATION) {
     924             :                         /*
     925             :                          * We don't support selective authentication yet.
     926             :                          */
     927           0 :                         DBG_WARNING("Ignoring CROSS_ORGANIZATION trust to "
     928             :                                     "domain[%s/%s]\n",
     929             :                                     domains[i]->netbios_name,
     930             :                                     domains[i]->domain_name);
     931           0 :                         continue;
     932             :                 }
     933             : 
     934           0 :                 status = add_trusted_domain(domains[i]->netbios_name,
     935           0 :                                             domains[i]->domain_name,
     936           0 :                                             &domains[i]->security_identifier,
     937           0 :                                             domains[i]->trust_type,
     938             :                                             trust_flags,
     939           0 :                                             domains[i]->trust_attributes,
     940             :                                             sec_chan_type,
     941             :                                             NULL,
     942             :                                             &domain);
     943           0 :                 if (!NT_STATUS_IS_OK(status)) {
     944           0 :                         DBG_NOTICE("add_trusted_domain returned %s\n",
     945             :                                    nt_errstr(status));
     946           0 :                         return false;
     947             :                 }
     948             : 
     949           0 :                 if (domains[i]->trust_type == LSA_TRUST_TYPE_UPLEVEL) {
     950           0 :                         domain->active_directory = true;
     951             :                 }
     952           0 :                 domain->domain_type = domains[i]->trust_type;
     953           0 :                 domain->domain_trust_attribs = domains[i]->trust_attributes;
     954             :         }
     955             : 
     956           0 :         for (i = 0; i < num_domains; i++) {
     957           0 :                 struct ForestTrustInfo fti;
     958           0 :                 uint32_t fi;
     959           0 :                 enum ndr_err_code ndr_err;
     960           0 :                 struct winbindd_domain *routing_domain = NULL;
     961             : 
     962           0 :                 if (domains[i]->trust_type != LSA_TRUST_TYPE_UPLEVEL) {
     963           0 :                         continue;
     964             :                 }
     965             : 
     966           0 :                 if (!(domains[i]->trust_attributes & LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)) {
     967           0 :                         continue;
     968             :                 }
     969             : 
     970           0 :                 if (domains[i]->trust_forest_trust_info.length == 0) {
     971           0 :                         continue;
     972             :                 }
     973             : 
     974           0 :                 routing_domain = find_domain_from_name_noinit(
     975           0 :                         domains[i]->netbios_name);
     976           0 :                 if (routing_domain == NULL) {
     977           0 :                         DBG_ERR("Can't find winbindd domain [%s]\n",
     978             :                                 domains[i]->netbios_name);
     979           0 :                         return false;
     980             :                 }
     981             : 
     982           0 :                 ndr_err = ndr_pull_struct_blob_all(
     983           0 :                         &domains[i]->trust_forest_trust_info,
     984             :                         talloc_tos(), &fti,
     985             :                         (ndr_pull_flags_fn_t)ndr_pull_ForestTrustInfo);
     986           0 :                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     987           0 :                         DBG_ERR("ndr_pull_ForestTrustInfo(%s) - %s\n",
     988             :                                 domains[i]->netbios_name,
     989             :                                 ndr_map_error2string(ndr_err));
     990           0 :                         return false;
     991             :                 }
     992             : 
     993           0 :                 for (fi = 0; fi < fti.count; fi++) {
     994           0 :                         struct ForestTrustInfoRecord *rec =
     995           0 :                                 &fti.records[fi].record;
     996           0 :                         struct ForestTrustDataDomainInfo *drec = NULL;
     997             : 
     998           0 :                         if (rec->type != FOREST_TRUST_DOMAIN_INFO) {
     999           0 :                                 continue;
    1000             :                         }
    1001           0 :                         drec = &rec->data.info;
    1002             : 
    1003           0 :                         if (rec->flags & LSA_NB_DISABLED_MASK) {
    1004           0 :                                 continue;
    1005             :                         }
    1006             : 
    1007           0 :                         if (rec->flags & LSA_SID_DISABLED_MASK) {
    1008           0 :                                 continue;
    1009             :                         }
    1010             : 
    1011             :                         /*
    1012             :                          * TODO:
    1013             :                          * also try to find a matching
    1014             :                          * LSA_TLN_DISABLED_MASK ???
    1015             :                          */
    1016             : 
    1017           0 :                         domain = find_domain_from_name_noinit(drec->netbios_name.string);
    1018           0 :                         if (domain != NULL) {
    1019           0 :                                 continue;
    1020             :                         }
    1021             : 
    1022           0 :                         status = add_trusted_domain(drec->netbios_name.string,
    1023             :                                                     drec->dns_name.string,
    1024           0 :                                                     &drec->sid,
    1025             :                                                     LSA_TRUST_TYPE_UPLEVEL,
    1026             :                                                     NETR_TRUST_FLAG_OUTBOUND,
    1027             :                                                     0,
    1028             :                                                     SEC_CHAN_NULL,
    1029             :                                                     routing_domain,
    1030             :                                                     &domain);
    1031           0 :                         if (!NT_STATUS_IS_OK(status)) {
    1032           0 :                                 DBG_NOTICE("add_trusted_domain returned %s\n",
    1033             :                                            nt_errstr(status));
    1034           0 :                                 return false;
    1035             :                         }
    1036           0 :                         if (domain == NULL) {
    1037           0 :                                 continue;
    1038             :                         }
    1039             :                 }
    1040             :         }
    1041             : 
    1042           0 :         return true;
    1043             : }
    1044             : 
    1045             : 
    1046             : /* Look up global info for the winbind daemon */
    1047          41 : bool init_domain_list(void)
    1048             : {
    1049          41 :         int role = lp_server_role();
    1050          41 :         struct pdb_domain_info *pdb_domain_info = NULL;
    1051          41 :         struct winbindd_domain *domain =  NULL;
    1052           0 :         NTSTATUS status;
    1053           0 :         bool ok;
    1054             : 
    1055             :         /* Free existing list */
    1056          41 :         free_domain_list();
    1057             : 
    1058             :         /* BUILTIN domain */
    1059             : 
    1060          41 :         status = add_trusted_domain("BUILTIN",
    1061             :                                     NULL,
    1062             :                                     &global_sid_Builtin,
    1063             :                                     LSA_TRUST_TYPE_DOWNLEVEL,
    1064             :                                     0, /* trust_flags */
    1065             :                                     0, /* trust_attribs */
    1066             :                                     SEC_CHAN_LOCAL,
    1067             :                                     NULL,
    1068             :                                     &domain);
    1069          41 :         if (!NT_STATUS_IS_OK(status)) {
    1070           0 :                 DBG_ERR("add_trusted_domain BUILTIN returned %s\n",
    1071             :                         nt_errstr(status));
    1072           0 :                 return false;
    1073             :         }
    1074             : 
    1075             :         /* Local SAM */
    1076             : 
    1077             :         /*
    1078             :          * In case the passdb backend is passdb_dsdb the domain SID comes from
    1079             :          * dsdb, not from secrets.tdb. As we use the domain SID in various
    1080             :          * places, we must ensure the domain SID is migrated from dsdb to
    1081             :          * secrets.tdb before get_global_sam_sid() is called the first time.
    1082             :          *
    1083             :          * The migration is done as part of the passdb_dsdb initialisation,
    1084             :          * calling pdb_get_domain_info() triggers it.
    1085             :          */
    1086          41 :         pdb_domain_info = pdb_get_domain_info(talloc_tos());
    1087             : 
    1088          41 :         if ( role == ROLE_ACTIVE_DIRECTORY_DC ) {
    1089           0 :                 uint32_t trust_flags;
    1090           0 :                 bool is_root;
    1091           0 :                 enum netr_SchannelType sec_chan_type;
    1092           0 :                 const char *account_name;
    1093           0 :                 struct samr_Password current_nt_hash;
    1094             : 
    1095           0 :                 if (pdb_domain_info == NULL) {
    1096           0 :                         DEBUG(0, ("Failed to fetch our own local AD "
    1097             :                                 "domain info from sam.ldb\n"));
    1098           0 :                         return false;
    1099             :                 }
    1100             : 
    1101           0 :                 trust_flags = NETR_TRUST_FLAG_PRIMARY;
    1102           0 :                 trust_flags |= NETR_TRUST_FLAG_IN_FOREST;
    1103           0 :                 trust_flags |= NETR_TRUST_FLAG_NATIVE;
    1104           0 :                 trust_flags |= NETR_TRUST_FLAG_OUTBOUND;
    1105             : 
    1106           0 :                 is_root = strequal(pdb_domain_info->dns_domain,
    1107           0 :                                    pdb_domain_info->dns_forest);
    1108           0 :                 if (is_root) {
    1109           0 :                         trust_flags |= NETR_TRUST_FLAG_TREEROOT;
    1110             :                 }
    1111             : 
    1112           0 :                 status = add_trusted_domain(pdb_domain_info->name,
    1113           0 :                                             pdb_domain_info->dns_domain,
    1114           0 :                                             &pdb_domain_info->sid,
    1115             :                                             LSA_TRUST_TYPE_UPLEVEL,
    1116             :                                             trust_flags,
    1117             :                                             LSA_TRUST_ATTRIBUTE_WITHIN_FOREST,
    1118             :                                             SEC_CHAN_BDC,
    1119             :                                             NULL,
    1120             :                                             &domain);
    1121           0 :                 TALLOC_FREE(pdb_domain_info);
    1122           0 :                 if (!NT_STATUS_IS_OK(status)) {
    1123           0 :                         DBG_ERR("Failed to add our own local AD "
    1124             :                                 "domain to winbindd's internal list\n");
    1125           0 :                         return false;
    1126             :                 }
    1127             : 
    1128             :                 /*
    1129             :                  * We need to call this to find out if we are an RODC
    1130             :                  */
    1131           0 :                 ok = get_trust_pw_hash(domain->name,
    1132             :                                        current_nt_hash.hash,
    1133             :                                        &account_name,
    1134             :                                        &sec_chan_type);
    1135           0 :                 if (!ok) {
    1136             :                         /*
    1137             :                          * If get_trust_pw_hash() fails, then try and
    1138             :                          * fetch the password from the more recent of
    1139             :                          * secrets.{ldb,tdb} using the
    1140             :                          * pdb_get_trust_credentials()
    1141             :                          */
    1142           0 :                         ok = migrate_secrets_tdb_to_ldb(domain);
    1143             : 
    1144           0 :                         if (!ok) {
    1145           0 :                                 DEBUG(0, ("Failed to migrate our own "
    1146             :                                           "local AD domain join password for "
    1147             :                                           "winbindd's internal use into "
    1148             :                                           "secrets.tdb\n"));
    1149           0 :                                 return false;
    1150             :                         }
    1151           0 :                         ok = get_trust_pw_hash(domain->name,
    1152             :                                                current_nt_hash.hash,
    1153             :                                                &account_name,
    1154             :                                                &sec_chan_type);
    1155           0 :                         if (!ok) {
    1156           0 :                                 DEBUG(0, ("Failed to find our own just "
    1157             :                                           "written local AD domain join "
    1158             :                                           "password for winbindd's internal "
    1159             :                                           "use in secrets.tdb\n"));
    1160           0 :                                 return false;
    1161             :                         }
    1162             :                 }
    1163             : 
    1164           0 :                 domain->secure_channel_type = sec_chan_type;
    1165           0 :                 if (sec_chan_type == SEC_CHAN_RODC) {
    1166           0 :                         domain->rodc = true;
    1167             :                 }
    1168             : 
    1169             :         } else {
    1170           0 :                 uint32_t trust_flags;
    1171           0 :                 enum netr_SchannelType secure_channel_type;
    1172             : 
    1173          41 :                 trust_flags = NETR_TRUST_FLAG_OUTBOUND;
    1174          41 :                 if (role != ROLE_DOMAIN_MEMBER) {
    1175          10 :                         trust_flags |= NETR_TRUST_FLAG_PRIMARY;
    1176             :                 }
    1177             : 
    1178          41 :                 if (role > ROLE_DOMAIN_MEMBER) {
    1179          10 :                         secure_channel_type = SEC_CHAN_BDC;
    1180             :                 } else {
    1181          31 :                         secure_channel_type = SEC_CHAN_LOCAL;
    1182             :                 }
    1183             : 
    1184          41 :                 if ((pdb_domain_info != NULL) && (role == ROLE_IPA_DC)) {
    1185             :                         /* This is IPA DC that presents itself as
    1186             :                          * an Active Directory domain controller to trusted AD
    1187             :                          * forests but in fact is a classic domain controller.
    1188             :                          */
    1189           0 :                         trust_flags = NETR_TRUST_FLAG_PRIMARY;
    1190           0 :                         trust_flags |= NETR_TRUST_FLAG_IN_FOREST;
    1191           0 :                         trust_flags |= NETR_TRUST_FLAG_NATIVE;
    1192           0 :                         trust_flags |= NETR_TRUST_FLAG_OUTBOUND;
    1193           0 :                         trust_flags |= NETR_TRUST_FLAG_TREEROOT;
    1194           0 :                         status = add_trusted_domain(pdb_domain_info->name,
    1195           0 :                                                     pdb_domain_info->dns_domain,
    1196           0 :                                                     &pdb_domain_info->sid,
    1197             :                                                     LSA_TRUST_TYPE_UPLEVEL,
    1198             :                                                     trust_flags,
    1199             :                                                     LSA_TRUST_ATTRIBUTE_WITHIN_FOREST,
    1200             :                                                     secure_channel_type,
    1201             :                                                     NULL,
    1202             :                                                     &domain);
    1203           0 :                         TALLOC_FREE(pdb_domain_info);
    1204             :                 } else {
    1205          41 :                         status = add_trusted_domain(get_global_sam_name(),
    1206             :                                                     NULL,
    1207          41 :                                                     get_global_sam_sid(),
    1208             :                                                     LSA_TRUST_TYPE_DOWNLEVEL,
    1209             :                                                     trust_flags,
    1210             :                                                     0, /* trust_attribs */
    1211             :                                                     secure_channel_type,
    1212             :                                                     NULL,
    1213             :                                                     &domain);
    1214             :                 }
    1215          41 :                 if (!NT_STATUS_IS_OK(status)) {
    1216           0 :                         DBG_ERR("Failed to add local SAM to "
    1217             :                                 "domain to winbindd's internal list\n");
    1218           0 :                         return false;
    1219             :                 }
    1220             :         }
    1221             : 
    1222          41 :         if (IS_DC) {
    1223          10 :                 ok = add_trusted_domains_dc();
    1224          10 :                 if (!ok) {
    1225           0 :                         DBG_ERR("init_domain_list_dc failed\n");
    1226           0 :                         return false;
    1227             :                 }
    1228             :         }
    1229             : 
    1230          41 :         if ( role == ROLE_DOMAIN_MEMBER ) {
    1231           0 :                 struct dom_sid our_sid;
    1232           0 :                 uint32_t trust_type;
    1233             : 
    1234          31 :                 if (!secrets_fetch_domain_sid(lp_workgroup(), &our_sid)) {
    1235           0 :                         DEBUG(0, ("Could not fetch our SID - did we join?\n"));
    1236           0 :                         return False;
    1237             :                 }
    1238             : 
    1239          31 :                 if (lp_realm() != NULL) {
    1240          31 :                         trust_type = LSA_TRUST_TYPE_UPLEVEL;
    1241             :                 } else {
    1242           0 :                         trust_type = LSA_TRUST_TYPE_DOWNLEVEL;
    1243             :                 }
    1244             : 
    1245          31 :                 status = add_trusted_domain(lp_workgroup(),
    1246             :                                             lp_realm(),
    1247             :                                             &our_sid,
    1248             :                                             trust_type,
    1249             :                                             NETR_TRUST_FLAG_PRIMARY|
    1250             :                                             NETR_TRUST_FLAG_OUTBOUND,
    1251             :                                             0, /* trust_attribs */
    1252             :                                             SEC_CHAN_WKSTA,
    1253             :                                             NULL,
    1254             :                                             &domain);
    1255          31 :                 if (!NT_STATUS_IS_OK(status)) {
    1256           0 :                         DBG_ERR("Failed to add local SAM to "
    1257             :                                 "domain to winbindd's internal list\n");
    1258           0 :                         return false;
    1259             :                 }
    1260             :         }
    1261             : 
    1262          41 :         status = imessaging_register(winbind_imessaging_context(), NULL,
    1263             :                                      MSG_WINBIND_RELOAD_TRUSTED_DOMAINS,
    1264             :                                      wb_imsg_new_trusted_domain);
    1265          41 :         if (!NT_STATUS_IS_OK(status)) {
    1266           0 :                 DBG_ERR("imessaging_register failed %s\n", nt_errstr(status));
    1267           0 :                 return false;
    1268             :         }
    1269             : 
    1270          41 :         return True;
    1271             : }
    1272             : 
    1273             : /**
    1274             :  * Given a domain name, return the struct winbindd domain info for it
    1275             :  *
    1276             :  * @note Do *not* pass lp_workgroup() to this function.  domain_list
    1277             :  *       may modify it's value, and free that pointer.  Instead, our local
    1278             :  *       domain may be found by calling find_our_domain().
    1279             :  *       directly.
    1280             :  *
    1281             :  *
    1282             :  * @return The domain structure for the named domain, if it is working.
    1283             :  */
    1284             : 
    1285        9132 : struct winbindd_domain *find_domain_from_name_noinit(const char *domain_name)
    1286             : {
    1287           0 :         struct winbindd_domain *domain;
    1288             : 
    1289             :         /* Search through list */
    1290             : 
    1291       21651 :         for (domain = domain_list(); domain != NULL; domain = domain->next) {
    1292       19098 :                 if (strequal(domain_name, domain->name)) {
    1293        6579 :                         return domain;
    1294             :                 }
    1295       12519 :                 if (domain->alt_name == NULL) {
    1296       12417 :                         continue;
    1297             :                 }
    1298         102 :                 if (strequal(domain_name, domain->alt_name)) {
    1299           0 :                         return domain;
    1300             :                 }
    1301             :         }
    1302             : 
    1303             :         /* Not found */
    1304             : 
    1305        2553 :         return NULL;
    1306             : }
    1307             : 
    1308             : /**
    1309             :  * Given a domain name, return the struct winbindd domain if it's a direct
    1310             :  * outgoing trust
    1311             :  *
    1312             :  * @return The domain structure for the named domain, if it is a direct outgoing trust
    1313             :  */
    1314          53 : struct winbindd_domain *find_trust_from_name_noinit(const char *domain_name)
    1315             : {
    1316          53 :         struct winbindd_domain *domain = NULL;
    1317             : 
    1318          53 :         domain = find_domain_from_name_noinit(domain_name);
    1319          53 :         if (domain == NULL) {
    1320           4 :                 return NULL;
    1321             :         }
    1322             : 
    1323          49 :         if (domain->secure_channel_type != SEC_CHAN_NULL) {
    1324          49 :                 return domain;
    1325             :         }
    1326             : 
    1327           0 :         return NULL;
    1328             : }
    1329             : 
    1330          52 : struct winbindd_domain *find_domain_from_name(const char *domain_name)
    1331             : {
    1332           0 :         struct winbindd_domain *domain;
    1333             : 
    1334          52 :         domain = find_domain_from_name_noinit(domain_name);
    1335             : 
    1336          52 :         if (domain == NULL)
    1337           0 :                 return NULL;
    1338             : 
    1339          52 :         if (!domain->initialized)
    1340           0 :                 init_dc_connection(domain, false);
    1341             : 
    1342          52 :         return domain;
    1343             : }
    1344             : 
    1345             : /* Given a domain sid, return the struct winbindd domain info for it */
    1346             : 
    1347       12491 : struct winbindd_domain *find_domain_from_sid_noinit(const struct dom_sid *sid)
    1348             : {
    1349           0 :         struct winbindd_domain *domain;
    1350             : 
    1351             :         /* Search through list */
    1352             : 
    1353       27854 :         for (domain = domain_list(); domain != NULL; domain = domain->next) {
    1354       26309 :                 if (dom_sid_compare_domain(sid, &domain->sid) == 0)
    1355       10946 :                         return domain;
    1356             :         }
    1357             : 
    1358             :         /* Not found */
    1359             : 
    1360        1545 :         return NULL;
    1361             : }
    1362             : 
    1363             : /**
    1364             :  * Given a domain sid, return the struct winbindd domain if it's a direct
    1365             :  * outgoing trust
    1366             :  *
    1367             :  * @return The domain structure for the specified domain, if it is a direct outgoing trust
    1368             :  */
    1369           0 : struct winbindd_domain *find_trust_from_sid_noinit(const struct dom_sid *sid)
    1370             : {
    1371           0 :         struct winbindd_domain *domain = NULL;
    1372             : 
    1373           0 :         domain = find_domain_from_sid_noinit(sid);
    1374           0 :         if (domain == NULL) {
    1375           0 :                 return NULL;
    1376             :         }
    1377             : 
    1378           0 :         if (domain->secure_channel_type != SEC_CHAN_NULL) {
    1379           0 :                 return domain;
    1380             :         }
    1381             : 
    1382           0 :         return NULL;
    1383             : }
    1384             : 
    1385             : /* Given a domain sid, return the struct winbindd domain info for it */
    1386             : 
    1387        5610 : struct winbindd_domain *find_domain_from_sid(const struct dom_sid *sid)
    1388             : {
    1389           0 :         struct winbindd_domain *domain;
    1390             : 
    1391        5610 :         domain = find_domain_from_sid_noinit(sid);
    1392             : 
    1393        5610 :         if (domain == NULL)
    1394           0 :                 return NULL;
    1395             : 
    1396        5610 :         if (!domain->initialized)
    1397          11 :                 init_dc_connection(domain, false);
    1398             : 
    1399        5610 :         return domain;
    1400             : }
    1401             : 
    1402      206910 : struct winbindd_domain *find_our_domain(void)
    1403             : {
    1404           0 :         struct winbindd_domain *domain;
    1405             : 
    1406             :         /* Search through list */
    1407             : 
    1408      618572 :         for (domain = domain_list(); domain != NULL; domain = domain->next) {
    1409      618572 :                 if (domain->primary)
    1410      206910 :                         return domain;
    1411             :         }
    1412             : 
    1413           0 :         smb_panic("Could not find our domain");
    1414             :         return NULL;
    1415             : }
    1416             : 
    1417        1396 : struct winbindd_domain *find_default_route_domain(void)
    1418             : {
    1419        1396 :         if (!IS_DC) {
    1420        1396 :                 return find_our_domain();
    1421             :         }
    1422           0 :         DBG_DEBUG("Routing logic not yet implemented on a DC\n");
    1423           0 :         return NULL;
    1424             : }
    1425             : 
    1426             : /* Find the appropriate domain to lookup a name or SID */
    1427             : 
    1428       19064 : struct winbindd_domain *find_lookup_domain_from_sid(const struct dom_sid *sid)
    1429             : {
    1430           0 :         struct dom_sid_buf buf;
    1431             : 
    1432       19064 :         DBG_DEBUG("SID [%s]\n", dom_sid_str_buf(sid, &buf));
    1433             : 
    1434             :         /*
    1435             :          * SIDs in the S-1-22-{1,2} domain and well-known SIDs should be handled
    1436             :          * by our passdb.
    1437             :          */
    1438             : 
    1439       38128 :         if ( sid_check_is_in_unix_groups(sid) ||
    1440       38128 :              sid_check_is_unix_groups(sid) ||
    1441       38020 :              sid_check_is_in_unix_users(sid) ||
    1442       37912 :              sid_check_is_unix_users(sid) ||
    1443       37912 :              sid_check_is_our_sam(sid) ||
    1444       18956 :              sid_check_is_in_our_sam(sid) )
    1445             :         {
    1446        3210 :                 return find_domain_from_sid(get_global_sam_sid());
    1447             :         }
    1448             : 
    1449       31700 :         if ( sid_check_is_builtin(sid) ||
    1450       31494 :              sid_check_is_in_builtin(sid) ||
    1451       31296 :              sid_check_is_wellknown_domain(sid, NULL) ||
    1452       15648 :              sid_check_is_in_wellknown_domain(sid) )
    1453             :         {
    1454         290 :                 return find_domain_from_sid(&global_sid_Builtin);
    1455             :         }
    1456             : 
    1457       15564 :         if (IS_DC) {
    1458         124 :                 struct winbindd_domain *domain = NULL;
    1459             : 
    1460         124 :                 domain = find_domain_from_sid_noinit(sid);
    1461         124 :                 if (domain == NULL) {
    1462         124 :                         return NULL;
    1463             :                 }
    1464             : 
    1465           0 :                 if (domain->secure_channel_type != SEC_CHAN_NULL) {
    1466           0 :                         return domain;
    1467             :                 }
    1468             : 
    1469           0 :                 return domain->routing_domain;
    1470             :         }
    1471             : 
    1472             :         /* On a member server a query for SID or name can always go to our
    1473             :          * primary DC. */
    1474             : 
    1475       15440 :         DEBUG(10, ("calling find_our_domain\n"));
    1476       15440 :         return find_our_domain();
    1477             : }
    1478             : 
    1479       99193 : struct winbindd_domain *find_lookup_domain_from_name(const char *domain_name)
    1480             : {
    1481           0 :         bool predefined;
    1482             : 
    1483      198146 :         if ( strequal(domain_name, unix_users_domain_name() ) ||
    1484       98953 :              strequal(domain_name, unix_groups_domain_name() ) )
    1485             :         {
    1486             :                 /*
    1487             :                  * The "Unix User" and "Unix Group" domain are handled by
    1488             :                  * passdb
    1489             :                  */
    1490         368 :                 return find_domain_from_name_noinit( get_global_sam_name() );
    1491             :         }
    1492             : 
    1493      197578 :         if (strequal(domain_name, "BUILTIN") ||
    1494       98753 :             strequal(domain_name, get_global_sam_name())) {
    1495        4473 :                 return find_domain_from_name_noinit(domain_name);
    1496             :         }
    1497             : 
    1498       94352 :         predefined = dom_sid_lookup_is_predefined_domain(domain_name);
    1499       94352 :         if (predefined) {
    1500          98 :                 return find_domain_from_name_noinit(builtin_domain_name());
    1501             :         }
    1502             : 
    1503       94254 :         if (IS_DC) {
    1504           2 :                 struct winbindd_domain *domain = NULL;
    1505             : 
    1506           2 :                 domain = find_domain_from_name_noinit(domain_name);
    1507           2 :                 if (domain == NULL) {
    1508           2 :                         return NULL;
    1509             :                 }
    1510             : 
    1511           0 :                 if (domain->secure_channel_type != SEC_CHAN_NULL) {
    1512           0 :                         return domain;
    1513             :                 }
    1514             : 
    1515           0 :                 return domain->routing_domain;
    1516             :         }
    1517             : 
    1518       94252 :         return find_our_domain();
    1519             : }
    1520             : 
    1521             : /* Is this a domain which we may assume no DOMAIN\ prefix? */
    1522             : 
    1523      108208 : static bool assume_domain(const char *domain)
    1524             : {
    1525             :         /* never assume the domain on a standalone server */
    1526             : 
    1527      108208 :         if ( lp_server_role() == ROLE_STANDALONE )
    1528           0 :                 return False;
    1529             : 
    1530             :         /* domain member servers may possibly assume for the domain name */
    1531             : 
    1532      108208 :         if ( lp_server_role() == ROLE_DOMAIN_MEMBER ) {
    1533      103616 :                 if ( !strequal(lp_workgroup(), domain) )
    1534         516 :                         return False;
    1535             : 
    1536      103100 :                 if ( lp_winbind_use_default_domain() )
    1537           0 :                         return True;
    1538             :         }
    1539             : 
    1540             :         /* only left with a domain controller */
    1541             : 
    1542      107692 :         if ( strequal(get_global_sam_name(), domain) )  {
    1543        4518 :                 return True;
    1544             :         }
    1545             : 
    1546      103174 :         return False;
    1547             : }
    1548             : 
    1549             : /* Parse a DOMAIN\user or UPN string into a domain, namespace and a user */
    1550       95039 : bool parse_domain_user(TALLOC_CTX *ctx,
    1551             :                        const char *domuser,
    1552             :                        char **pnamespace,
    1553             :                        char **pdomain,
    1554             :                        char **puser)
    1555             : {
    1556       95039 :         char *p = NULL;
    1557       95039 :         char *namespace = NULL;
    1558       95039 :         char *domain = NULL;
    1559       95039 :         char *user = NULL;
    1560             : 
    1561       95039 :         if (strlen(domuser) == 0) {
    1562           0 :                 return false;
    1563             :         }
    1564             : 
    1565       95039 :         p = strchr(domuser, *lp_winbind_separator());
    1566       95039 :         if (p != NULL) {
    1567       94355 :                 user = talloc_strdup(ctx, p + 1);
    1568       94355 :                 if (user == NULL) {
    1569           0 :                         goto fail;
    1570             :                 }
    1571       94355 :                 domain = talloc_strdup(ctx,
    1572             :                                 domuser);
    1573       94355 :                 if (domain == NULL) {
    1574           0 :                         goto fail;
    1575             :                 }
    1576       94355 :                 domain[PTR_DIFF(p, domuser)] = '\0';
    1577       94355 :                 namespace = talloc_strdup(ctx, domain);
    1578       94355 :                 if (namespace == NULL) {
    1579           0 :                         goto fail;
    1580             :                 }
    1581             :         } else {
    1582         684 :                 user = talloc_strdup(ctx, domuser);
    1583         684 :                 if (user == NULL) {
    1584           0 :                         goto fail;
    1585             :                 }
    1586         684 :                 p = strchr(domuser, '@');
    1587         684 :                 if (p != NULL) {
    1588             :                         /* upn */
    1589          10 :                         namespace = talloc_strdup(ctx, p + 1);
    1590          10 :                         if (namespace == NULL) {
    1591           0 :                                 goto fail;
    1592             :                         }
    1593          10 :                         domain = talloc_strdup(ctx, "");
    1594          10 :                         if (domain == NULL) {
    1595           0 :                                 goto fail;
    1596             :                         }
    1597             : 
    1598         674 :                 } else if (assume_domain(lp_workgroup())) {
    1599         530 :                         domain = talloc_strdup(ctx, lp_workgroup());
    1600         530 :                         if (domain == NULL) {
    1601           0 :                                 goto fail;
    1602             :                         }
    1603         530 :                         namespace = talloc_strdup(ctx, domain);
    1604         530 :                         if (namespace == NULL) {
    1605           0 :                                 goto fail;
    1606             :                         }
    1607             :                 } else {
    1608         144 :                         namespace = talloc_strdup(ctx, lp_netbios_name());
    1609         144 :                         if (namespace == NULL) {
    1610           0 :                                 goto fail;
    1611             :                         }
    1612         144 :                         domain = talloc_strdup(ctx, "");
    1613         144 :                         if (domain == NULL) {
    1614           0 :                                 goto fail;
    1615             :                         }
    1616             :                 }
    1617             :         }
    1618             : 
    1619       95039 :         if (!strupper_m(domain)) {
    1620           0 :                 goto fail;
    1621             :         }
    1622             : 
    1623       95039 :         *pnamespace = namespace;
    1624       95039 :         *pdomain = domain;
    1625       95039 :         *puser = user;
    1626       95039 :         return true;
    1627           0 : fail:
    1628           0 :         TALLOC_FREE(user);
    1629           0 :         TALLOC_FREE(domain);
    1630           0 :         TALLOC_FREE(namespace);
    1631           0 :         return false;
    1632             : }
    1633             : 
    1634         543 : bool canonicalize_username(TALLOC_CTX *mem_ctx,
    1635             :                            char **pusername_inout,
    1636             :                            char **pnamespace,
    1637             :                            char **pdomain,
    1638             :                            char **puser)
    1639             : {
    1640           0 :         bool ok;
    1641         543 :         char *namespace = NULL;
    1642         543 :         char *domain = NULL;
    1643         543 :         char *user = NULL;
    1644         543 :         char *username_inout = NULL;
    1645             : 
    1646         543 :         ok = parse_domain_user(mem_ctx,
    1647             :                         *pusername_inout,
    1648             :                         &namespace, &domain, &user);
    1649             : 
    1650         543 :         if (!ok) {
    1651           0 :                 return False;
    1652             :         }
    1653             : 
    1654        1086 :         username_inout = talloc_asprintf(mem_ctx, "%s%c%s",
    1655         543 :                  domain, *lp_winbind_separator(),
    1656             :                  user);
    1657             : 
    1658         543 :         if (username_inout == NULL) {
    1659           0 :                 goto fail;
    1660             :         }
    1661             : 
    1662         543 :         *pnamespace = namespace;
    1663         543 :         *puser = user;
    1664         543 :         *pdomain = domain;
    1665         543 :         *pusername_inout = username_inout;
    1666         543 :         return True;
    1667           0 : fail:
    1668           0 :         TALLOC_FREE(username_inout);
    1669           0 :         TALLOC_FREE(namespace);
    1670           0 :         TALLOC_FREE(domain);
    1671           0 :         TALLOC_FREE(user);
    1672           0 :         return false;
    1673             : }
    1674             : 
    1675             : /*
    1676             :     Fill DOMAIN\\USERNAME entry accounting 'winbind use default domain' and
    1677             :     'winbind separator' options.
    1678             :     This means:
    1679             :         - omit DOMAIN when 'winbind use default domain = true' and DOMAIN is
    1680             :         lp_workgroup()
    1681             : 
    1682             :     If we are a PDC or BDC, and this is for our domain, do likewise.
    1683             : 
    1684             :     On an AD DC we always fill DOMAIN\\USERNAME.
    1685             : 
    1686             :     We always canonicalize as UPPERCASE DOMAIN, lowercase username.
    1687             : */
    1688             : /**
    1689             :  * talloc version of fill_domain_username()
    1690             :  * return NULL on talloc failure.
    1691             :  */
    1692      107540 : char *fill_domain_username_talloc(TALLOC_CTX *mem_ctx,
    1693             :                                   const char *domain,
    1694             :                                   const char *user,
    1695             :                                   bool can_assume)
    1696             : {
    1697           0 :         char *tmp_user, *name;
    1698             : 
    1699      107540 :         if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
    1700           2 :                 can_assume = false;
    1701             :         }
    1702             : 
    1703      107540 :         if (user == NULL) {
    1704           0 :                 return NULL;
    1705             :         }
    1706             : 
    1707      107540 :         tmp_user = talloc_strdup(mem_ctx, user);
    1708      107540 :         if (tmp_user == NULL) {
    1709           0 :                 return NULL;
    1710             :         }
    1711      107540 :         if (!strlower_m(tmp_user)) {
    1712           0 :                 TALLOC_FREE(tmp_user);
    1713           0 :                 return NULL;
    1714             :         }
    1715             : 
    1716      107540 :         if (can_assume && assume_domain(domain)) {
    1717        3988 :                 name = tmp_user;
    1718             :         } else {
    1719      103552 :                 name = talloc_asprintf(mem_ctx, "%s%c%s",
    1720             :                                        domain,
    1721      103552 :                                        *lp_winbind_separator(),
    1722             :                                        tmp_user);
    1723      103552 :                 TALLOC_FREE(tmp_user);
    1724             :         }
    1725             : 
    1726      107540 :         return name;
    1727             : }
    1728             : 
    1729             : /*
    1730             :  * Client list accessor functions
    1731             :  */
    1732             : 
    1733             : static struct winbindd_cli_state *_client_list;
    1734             : static int _num_clients;
    1735             : 
    1736             : /* Return list of all connected clients */
    1737             : 
    1738           0 : struct winbindd_cli_state *winbindd_client_list(void)
    1739             : {
    1740           0 :         return _client_list;
    1741             : }
    1742             : 
    1743             : /* Return list-tail of all connected clients */
    1744             : 
    1745       12528 : struct winbindd_cli_state *winbindd_client_list_tail(void)
    1746             : {
    1747       12528 :         return DLIST_TAIL(_client_list);
    1748             : }
    1749             : 
    1750             : /* Return previous (read:newer) client in list */
    1751             : 
    1752             : struct winbindd_cli_state *
    1753        8656 : winbindd_client_list_prev(struct winbindd_cli_state *cli)
    1754             : {
    1755        8656 :         return DLIST_PREV(cli);
    1756             : }
    1757             : 
    1758             : /* Add a connection to the list */
    1759             : 
    1760        8003 : void winbindd_add_client(struct winbindd_cli_state *cli)
    1761             : {
    1762        8003 :         cli->last_access = time(NULL);
    1763        8003 :         DLIST_ADD(_client_list, cli);
    1764        8003 :         _num_clients++;
    1765        8003 : }
    1766             : 
    1767             : /* Remove a client from the list */
    1768             : 
    1769        7970 : void winbindd_remove_client(struct winbindd_cli_state *cli)
    1770             : {
    1771        7970 :         DLIST_REMOVE(_client_list, cli);
    1772        7970 :         _num_clients--;
    1773        7970 : }
    1774             : 
    1775             : /* Move a client to head or list */
    1776             : 
    1777      243890 : void winbindd_promote_client(struct winbindd_cli_state *cli)
    1778             : {
    1779      243890 :         cli->last_access = time(NULL);
    1780      243890 :         DLIST_PROMOTE(_client_list, cli);
    1781      243890 : }
    1782             : 
    1783             : /* Return number of open clients */
    1784             : 
    1785        8003 : int winbindd_num_clients(void)
    1786             : {
    1787        8003 :         return _num_clients;
    1788             : }
    1789             : 
    1790        2314 : NTSTATUS lookup_usergroups_cached(TALLOC_CTX *mem_ctx,
    1791             :                                   const struct dom_sid *user_sid,
    1792             :                                   uint32_t *p_num_groups, struct dom_sid **user_sids)
    1793             : {
    1794        2314 :         struct netr_SamInfo3 *info3 = NULL;
    1795        2314 :         NTSTATUS status = NT_STATUS_NO_MEMORY;
    1796        2314 :         uint32_t num_groups = 0;
    1797             : 
    1798        2314 :         DEBUG(3,(": lookup_usergroups_cached\n"));
    1799             : 
    1800        2314 :         *user_sids = NULL;
    1801        2314 :         *p_num_groups = 0;
    1802             : 
    1803        2314 :         info3 = netsamlogon_cache_get(mem_ctx, user_sid);
    1804             : 
    1805        2314 :         if (info3 == NULL) {
    1806        2252 :                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
    1807             :         }
    1808             : 
    1809             :         /*
    1810             :          * Before bug #7843 the "Domain Local" groups were added with a
    1811             :          * lookupuseraliases call, but this isn't done anymore for our domain
    1812             :          * so we need to resolve resource groups here.
    1813             :          *
    1814             :          * When to use Resource Groups:
    1815             :          * http://technet.microsoft.com/en-us/library/cc753670%28v=WS.10%29.aspx
    1816             :          */
    1817          62 :         status = sid_array_from_info3(mem_ctx, info3,
    1818             :                                       user_sids,
    1819             :                                       &num_groups,
    1820             :                                       false);
    1821             : 
    1822          62 :         if (!NT_STATUS_IS_OK(status)) {
    1823           0 :                 TALLOC_FREE(info3);
    1824           0 :                 return status;
    1825             :         }
    1826             : 
    1827          62 :         TALLOC_FREE(info3);
    1828          62 :         *p_num_groups = num_groups;
    1829          62 :         status = (user_sids != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
    1830             : 
    1831          62 :         DEBUG(3,(": lookup_usergroups_cached succeeded\n"));
    1832             : 
    1833          62 :         return status;
    1834             : }
    1835             : 
    1836             : /*********************************************************************
    1837             :  We use this to remove spaces from user and group names
    1838             : ********************************************************************/
    1839             : 
    1840      100552 : NTSTATUS normalize_name_map(TALLOC_CTX *mem_ctx,
    1841             :                              const char *domain_name,
    1842             :                              const char *name,
    1843             :                              char **normalized)
    1844             : {
    1845      100552 :         struct winbindd_domain *domain = NULL;
    1846           0 :         NTSTATUS nt_status;
    1847             : 
    1848      100552 :         if (!name || !normalized) {
    1849           0 :                 return NT_STATUS_INVALID_PARAMETER;
    1850             :         }
    1851             : 
    1852      100552 :         if (!lp_winbind_normalize_names()) {
    1853      100552 :                 return NT_STATUS_PROCEDURE_NOT_FOUND;
    1854             :         }
    1855             : 
    1856           0 :         domain = find_domain_from_name_noinit(domain_name);
    1857           0 :         if (domain == NULL) {
    1858           0 :                 DBG_ERR("Failed to find domain '%s'\n",       domain_name);
    1859           0 :                 return NT_STATUS_NO_SUCH_DOMAIN;
    1860             :         }
    1861             : 
    1862             :         /* Alias support and whitespace replacement are mutually
    1863             :            exclusive */
    1864             : 
    1865           0 :         nt_status = resolve_username_to_alias(mem_ctx, domain,
    1866             :                                               name, normalized );
    1867           0 :         if (NT_STATUS_IS_OK(nt_status)) {
    1868             :                 /* special return code to let the caller know we
    1869             :                    mapped to an alias */
    1870           0 :                 return NT_STATUS_FILE_RENAMED;
    1871             :         }
    1872             : 
    1873             :         /* check for an unreachable domain */
    1874             : 
    1875           0 :         if (NT_STATUS_EQUAL(nt_status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) {
    1876           0 :                 DEBUG(5,("normalize_name_map: Setting domain %s offline\n",
    1877             :                          domain->name));
    1878           0 :                 set_domain_offline(domain);
    1879           0 :                 return nt_status;
    1880             :         }
    1881             : 
    1882             :         /* deal with whitespace */
    1883             : 
    1884           0 :         *normalized = talloc_strdup(mem_ctx, name);
    1885           0 :         if (!(*normalized)) {
    1886           0 :                 return NT_STATUS_NO_MEMORY;
    1887             :         }
    1888             : 
    1889           0 :         all_string_sub( *normalized, " ", "_", 0 );
    1890             : 
    1891           0 :         return NT_STATUS_OK;
    1892             : }
    1893             : 
    1894             : /*********************************************************************
    1895             :  We use this to do the inverse of normalize_name_map()
    1896             : ********************************************************************/
    1897             : 
    1898       94845 : NTSTATUS normalize_name_unmap(TALLOC_CTX *mem_ctx,
    1899             :                               const char *name,
    1900             :                               char **normalized)
    1901             : {
    1902           0 :         NTSTATUS nt_status;
    1903       94845 :         struct winbindd_domain *domain = find_our_domain();
    1904             : 
    1905       94845 :         if (!name || !normalized) {
    1906           0 :                 return NT_STATUS_INVALID_PARAMETER;
    1907             :         }
    1908             : 
    1909       94845 :         if (!lp_winbind_normalize_names()) {
    1910       94845 :                 return NT_STATUS_PROCEDURE_NOT_FOUND;
    1911             :         }
    1912             : 
    1913             :         /* Alias support and whitespace replacement are mutally
    1914             :            exclusive */
    1915             : 
    1916             :         /* When mapping from an alias to a username, we don't know the
    1917             :            domain.  But we only need a domain structure to cache
    1918             :            a successful lookup , so just our own domain structure for
    1919             :            the seqnum. */
    1920             : 
    1921           0 :         nt_status = resolve_alias_to_username(mem_ctx, domain,
    1922             :                                               name, normalized);
    1923           0 :         if (NT_STATUS_IS_OK(nt_status)) {
    1924             :                 /* Special return code to let the caller know we mapped
    1925             :                    from an alias */
    1926           0 :                 return NT_STATUS_FILE_RENAMED;
    1927             :         }
    1928             : 
    1929             :         /* check for an unreachable domain */
    1930             : 
    1931           0 :         if (NT_STATUS_EQUAL(nt_status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) {
    1932           0 :                 DEBUG(5,("normalize_name_unmap: Setting domain %s offline\n",
    1933             :                          domain->name));
    1934           0 :                 set_domain_offline(domain);
    1935           0 :                 return nt_status;
    1936             :         }
    1937             : 
    1938             :         /* deal with whitespace */
    1939             : 
    1940           0 :         *normalized = talloc_strdup(mem_ctx, name);
    1941           0 :         if (!(*normalized)) {
    1942           0 :                 return NT_STATUS_NO_MEMORY;
    1943             :         }
    1944             : 
    1945           0 :         all_string_sub(*normalized, "_", " ", 0);
    1946             : 
    1947           0 :         return NT_STATUS_OK;
    1948             : }
    1949             : 
    1950             : /*********************************************************************
    1951             :  ********************************************************************/
    1952             : 
    1953           0 : bool winbindd_can_contact_domain(struct winbindd_domain *domain)
    1954             : {
    1955           0 :         struct winbindd_tdc_domain *tdc = NULL;
    1956           0 :         TALLOC_CTX *frame = talloc_stackframe();
    1957           0 :         bool ret = false;
    1958             : 
    1959             :         /* We can contact the domain if it is our primary domain */
    1960             : 
    1961           0 :         if (domain->primary) {
    1962           0 :                 ret = true;
    1963           0 :                 goto done;
    1964             :         }
    1965             : 
    1966             :         /* Trust the TDC cache and not the winbindd_domain flags */
    1967             : 
    1968           0 :         if ((tdc = wcache_tdc_fetch_domain(frame, domain->name)) == NULL) {
    1969           0 :                 DEBUG(10,("winbindd_can_contact_domain: %s not found in cache\n",
    1970             :                           domain->name));
    1971           0 :                 ret = false;
    1972           0 :                 goto done;
    1973             :         }
    1974             : 
    1975             :         /* Can always contact a domain that is in out forest */
    1976             : 
    1977           0 :         if (tdc->trust_flags & NETR_TRUST_FLAG_IN_FOREST) {
    1978           0 :                 ret = true;
    1979           0 :                 goto done;
    1980             :         }
    1981             : 
    1982             :         /*
    1983             :          * On a _member_ server, we cannot contact the domain if it
    1984             :          * is running AD and we have no inbound trust.
    1985             :          */
    1986             : 
    1987           0 :         if (!IS_DC &&
    1988           0 :              domain->active_directory &&
    1989           0 :             ((tdc->trust_flags & NETR_TRUST_FLAG_INBOUND) != NETR_TRUST_FLAG_INBOUND))
    1990             :         {
    1991           0 :                 DEBUG(10, ("winbindd_can_contact_domain: %s is an AD domain "
    1992             :                            "and we have no inbound trust.\n", domain->name));
    1993           0 :                 goto done;
    1994             :         }
    1995             : 
    1996             :         /* Assume everything else is ok (probably not true but what
    1997             :            can you do?) */
    1998             : 
    1999           0 :         ret = true;
    2000             : 
    2001           0 : done:
    2002           0 :         talloc_destroy(frame);
    2003             : 
    2004           0 :         return ret;
    2005             : }
    2006             : 
    2007             : #ifdef HAVE_KRB5_LOCATE_PLUGIN_H
    2008             : 
    2009             : /*********************************************************************
    2010             :  ********************************************************************/
    2011             : 
    2012          26 : static void winbindd_set_locator_kdc_env(const struct winbindd_domain *domain)
    2013             : {
    2014          26 :         char *var = NULL;
    2015           0 :         char addr[INET6_ADDRSTRLEN];
    2016          26 :         const char *kdc = NULL;
    2017          26 :         int lvl = 11;
    2018             : 
    2019          26 :         if (!domain || !domain->alt_name || !*domain->alt_name) {
    2020           0 :                 return;
    2021             :         }
    2022             : 
    2023          26 :         if (domain->initialized && !domain->active_directory) {
    2024           0 :                 DEBUG(lvl,("winbindd_set_locator_kdc_env: %s not AD\n",
    2025             :                         domain->alt_name));
    2026           0 :                 return;
    2027             :         }
    2028             : 
    2029          26 :         print_sockaddr(addr, sizeof(addr), &domain->dcaddr);
    2030          26 :         kdc = addr;
    2031          26 :         if (!*kdc) {
    2032           0 :                 DEBUG(lvl,("winbindd_set_locator_kdc_env: %s no DC IP\n",
    2033             :                         domain->alt_name));
    2034           0 :                 kdc = domain->dcname;
    2035             :         }
    2036             : 
    2037          26 :         if (!kdc || !*kdc) {
    2038           0 :                 DEBUG(lvl,("winbindd_set_locator_kdc_env: %s no DC at all\n",
    2039             :                         domain->alt_name));
    2040           0 :                 return;
    2041             :         }
    2042             : 
    2043          26 :         var = talloc_asprintf_strupper_m(
    2044             :                 talloc_tos(),
    2045             :                 "%s_%s",
    2046             :                 WINBINDD_LOCATOR_KDC_ADDRESS,
    2047          26 :                 domain->alt_name);
    2048          26 :         if (var == NULL) {
    2049           0 :                 return;
    2050             :         }
    2051             : 
    2052          26 :         DEBUG(lvl,("winbindd_set_locator_kdc_env: setting var: %s to: %s\n",
    2053             :                 var, kdc));
    2054             : 
    2055          26 :         setenv(var, kdc, 1);
    2056          26 :         TALLOC_FREE(var);
    2057             : }
    2058             : 
    2059             : /*********************************************************************
    2060             :  ********************************************************************/
    2061             : 
    2062          18 : void winbindd_set_locator_kdc_envs(const struct winbindd_domain *domain)
    2063             : {
    2064          18 :         struct winbindd_domain *our_dom = find_our_domain();
    2065             : 
    2066          18 :         winbindd_set_locator_kdc_env(domain);
    2067             : 
    2068          18 :         if (domain != our_dom) {
    2069           8 :                 winbindd_set_locator_kdc_env(our_dom);
    2070             :         }
    2071          18 : }
    2072             : 
    2073             : /*********************************************************************
    2074             :  ********************************************************************/
    2075             : 
    2076           0 : void winbindd_unset_locator_kdc_env(const struct winbindd_domain *domain)
    2077             : {
    2078           0 :         char *var = NULL;
    2079             : 
    2080           0 :         if (!domain || !domain->alt_name || !*domain->alt_name) {
    2081           0 :                 return;
    2082             :         }
    2083             : 
    2084           0 :         var = talloc_asprintf_strupper_m(
    2085             :                 talloc_tos(),
    2086             :                 "%s_%s",
    2087             :                 WINBINDD_LOCATOR_KDC_ADDRESS,
    2088           0 :                 domain->alt_name);
    2089           0 :         if (var == NULL) {
    2090           0 :                 return;
    2091             :         }
    2092             : 
    2093           0 :         unsetenv(var);
    2094           0 :         TALLOC_FREE(var);
    2095             : }
    2096             : #else
    2097             : 
    2098             : void winbindd_set_locator_kdc_envs(const struct winbindd_domain *domain)
    2099             : {
    2100             :         return;
    2101             : }
    2102             : 
    2103             : void winbindd_unset_locator_kdc_env(const struct winbindd_domain *domain)
    2104             : {
    2105             :         return;
    2106             : }
    2107             : 
    2108             : #endif /* HAVE_KRB5_LOCATE_PLUGIN_H */
    2109             : 
    2110        4303 : void set_auth_errors(struct winbindd_response *resp, NTSTATUS result)
    2111             : {
    2112             :         /*
    2113             :          * Make sure we start with authoritative=true,
    2114             :          * it will only set to false if we don't know the
    2115             :          * domain.
    2116             :          */
    2117        4303 :         resp->data.auth.authoritative = true;
    2118             : 
    2119        4303 :         resp->data.auth.nt_status = NT_STATUS_V(result);
    2120        4303 :         fstrcpy(resp->data.auth.nt_status_string, nt_errstr(result));
    2121             : 
    2122             :         /* we might have given a more useful error above */
    2123        4303 :         if (*resp->data.auth.error_string == '\0')
    2124        4303 :                 fstrcpy(resp->data.auth.error_string,
    2125             :                         get_friendly_nt_error_msg(result));
    2126        4303 :         resp->data.auth.pam_error = nt_status_to_pam(result);
    2127        4303 : }
    2128             : 
    2129      104974 : bool is_domain_offline(const struct winbindd_domain *domain)
    2130             : {
    2131      104974 :         if (get_global_winbindd_state_offline()) {
    2132           0 :                 return true;
    2133             :         }
    2134      104974 :         return !domain->online;
    2135             : }
    2136             : 
    2137      104974 : bool is_domain_online(const struct winbindd_domain *domain)
    2138             : {
    2139      104974 :         return !is_domain_offline(domain);
    2140             : }
    2141             : 
    2142             : /**
    2143             :  * Parse an char array into a list of sids.
    2144             :  *
    2145             :  * The input sidstr should consist of 0-terminated strings
    2146             :  * representing sids, separated by newline characters '\n'.
    2147             :  * The list is terminated by an empty string, i.e.
    2148             :  * character '\0' directly following a character '\n'
    2149             :  * (or '\0' right at the start of sidstr).
    2150             :  */
    2151        1978 : bool parse_sidlist(TALLOC_CTX *mem_ctx, const char *sidstr,
    2152             :                    struct dom_sid **sids, uint32_t *num_sids)
    2153             : {
    2154           0 :         const char *p;
    2155             : 
    2156        1978 :         p = sidstr;
    2157        1978 :         if (p == NULL)
    2158           0 :                 return False;
    2159             : 
    2160        4731 :         while (p[0] != '\0') {
    2161           0 :                 struct dom_sid sid;
    2162        2753 :                 const char *q = NULL;
    2163             : 
    2164        2753 :                 if (!dom_sid_parse_endp(p, &sid, &q)) {
    2165           0 :                         DEBUG(1, ("Could not parse sid %s\n", p));
    2166           0 :                         return false;
    2167             :                 }
    2168        2753 :                 if (q[0] != '\n') {
    2169           0 :                         DEBUG(1, ("Got invalid sidstr: %s\n", p));
    2170           0 :                         return false;
    2171             :                 }
    2172        2753 :                 if (!NT_STATUS_IS_OK(add_sid_to_array(mem_ctx, &sid, sids,
    2173             :                                                       num_sids)))
    2174             :                 {
    2175           0 :                         return False;
    2176             :                 }
    2177        2753 :                 p = q+1;
    2178             :         }
    2179        1978 :         return True;
    2180             : }
    2181             : 
    2182        1978 : bool parse_xidlist(TALLOC_CTX *mem_ctx, const char *xidstr,
    2183             :                    struct unixid **pxids, uint32_t *pnum_xids)
    2184             : {
    2185           0 :         const char *p;
    2186        1978 :         struct unixid *xids = NULL;
    2187        1978 :         uint32_t num_xids = 0;
    2188             : 
    2189        1978 :         p = xidstr;
    2190        1978 :         if (p == NULL) {
    2191           0 :                 return false;
    2192             :         }
    2193             : 
    2194        4024 :         while (p[0] != '\0') {
    2195           0 :                 struct unixid *tmp;
    2196           0 :                 struct unixid xid;
    2197           0 :                 unsigned long long id;
    2198           0 :                 char *endp;
    2199        2046 :                 int error = 0;
    2200             : 
    2201        2046 :                 switch (p[0]) {
    2202          42 :                 case 'U':
    2203          42 :                         xid = (struct unixid) { .type = ID_TYPE_UID };
    2204          42 :                         break;
    2205        2004 :                 case 'G':
    2206        2004 :                         xid = (struct unixid) { .type = ID_TYPE_GID };
    2207        2004 :                         break;
    2208           0 :                 default:
    2209           0 :                         return false;
    2210             :                 }
    2211             : 
    2212        2046 :                 p += 1;
    2213             : 
    2214        2046 :                 id = smb_strtoull(p, &endp, 10, &error, SMB_STR_STANDARD);
    2215        2046 :                 if (error != 0) {
    2216           0 :                         goto fail;
    2217             :                 }
    2218        2046 :                 if (*endp != '\n') {
    2219           0 :                         goto fail;
    2220             :                 }
    2221        2046 :                 p = endp+1;
    2222             : 
    2223        2046 :                 xid.id = id;
    2224        2046 :                 if ((unsigned long long)xid.id != id) {
    2225           0 :                         goto fail;
    2226             :                 }
    2227             : 
    2228        2046 :                 tmp = talloc_realloc(mem_ctx, xids, struct unixid, num_xids+1);
    2229        2046 :                 if (tmp == NULL) {
    2230           0 :                         return 0;
    2231             :                 }
    2232        2046 :                 xids = tmp;
    2233             : 
    2234        2046 :                 xids[num_xids] = xid;
    2235        2046 :                 num_xids += 1;
    2236             :         }
    2237             : 
    2238        1978 :         *pxids = xids;
    2239        1978 :         *pnum_xids = num_xids;
    2240        1978 :         return true;
    2241             : 
    2242           0 : fail:
    2243           0 :         TALLOC_FREE(xids);
    2244           0 :         return false;
    2245             : }

Generated by: LCOV version 1.14