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