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