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