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