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