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