winbind: avoid using fstrcpy(dcname,...) in _dual_init_connection
[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                 TALLOC_FREE(domain->dcname);
785                 domain->dcname = talloc_strdup(domain,
786                                 state->request->data.init_conn.dcname);
787                 if (domain->dcname == NULL) {
788                         return WINBINDD_ERROR;
789                 }
790         }
791
792         init_dc_connection(domain, false);
793
794         if (!domain->initialized) {
795                 /* If we return error here we can't do any cached authentication,
796                    but we may be in disconnected mode and can't initialize correctly.
797                    Do what the previous code did and just return without initialization,
798                    once we go online we'll re-initialize.
799                 */
800                 DEBUG(5, ("winbindd_dual_init_connection: %s returning without initialization "
801                         "online = %d\n", domain->name, (int)domain->online ));
802         }
803
804         fstrcpy(state->response->data.domain_info.name, domain->name);
805         fstrcpy(state->response->data.domain_info.alt_name, domain->alt_name);
806         sid_to_fstring(state->response->data.domain_info.sid, &domain->sid);
807
808         state->response->data.domain_info.native_mode
809                 = domain->native_mode;
810         state->response->data.domain_info.active_directory
811                 = domain->active_directory;
812         state->response->data.domain_info.primary
813                 = domain->primary;
814
815         return WINBINDD_OK;
816 }
817
818 static void wb_imsg_new_trusted_domain(struct imessaging_context *msg,
819                                        void *private_data,
820                                        uint32_t msg_type,
821                                        struct server_id server_id,
822                                        DATA_BLOB *data)
823 {
824         bool ok;
825
826         DBG_NOTICE("Rescanning trusted domains\n");
827
828         ok = add_trusted_domains_dc();
829         if (!ok) {
830                 DBG_ERR("Failed to reload trusted domains\n");
831         }
832 }
833
834 /*
835  * We did not get the secret when we queried secrets.tdb, so read it
836  * from secrets.tdb and re-sync the databases
837  */
838 static bool migrate_secrets_tdb_to_ldb(struct winbindd_domain *domain)
839 {
840         bool ok;
841         struct cli_credentials *creds;
842         NTSTATUS can_migrate = pdb_get_trust_credentials(domain->name,
843                                                          NULL, domain, &creds);
844         if (!NT_STATUS_IS_OK(can_migrate)) {
845                 DEBUG(0, ("Failed to fetch our own, local AD domain join "
846                         "password for winbindd's internal use, both from "
847                         "secrets.tdb and secrets.ldb: %s\n",
848                         nt_errstr(can_migrate)));
849                 return false;
850         }
851
852         /*
853          * NOTE: It is very unlikely we end up here if there is an
854          * oldpass, because a new password is created at
855          * classicupgrade, so this is not a concern.
856          */
857         ok = secrets_store_machine_pw_sync(cli_credentials_get_password(creds),
858                    NULL /* oldpass */,
859                    cli_credentials_get_domain(creds),
860                    cli_credentials_get_realm(creds),
861                    cli_credentials_get_salt_principal(creds),
862                    0, /* Supported enc types, unused */
863                    &domain->sid,
864                    cli_credentials_get_password_last_changed_time(creds),
865                    cli_credentials_get_secure_channel_type(creds),
866                    false /* do_delete: Do not delete */);
867         TALLOC_FREE(creds);
868         if (ok == false) {
869                 DEBUG(0, ("Failed to write our our own, "
870                           "local AD domain join password for "
871                           "winbindd's internal use into secrets.tdb\n"));
872                 return false;
873         }
874         return true;
875 }
876
877 static bool add_trusted_domains_dc(void)
878 {
879         struct winbindd_domain *domain =  NULL;
880         struct pdb_trusted_domain **domains = NULL;
881         uint32_t num_domains = 0;
882         uint32_t i;
883         NTSTATUS status;
884
885         if (!(pdb_capabilities() & PDB_CAP_TRUSTED_DOMAINS_EX)) {
886                 struct trustdom_info **ti = NULL;
887
888                 status = pdb_enum_trusteddoms(talloc_tos(), &num_domains, &ti);
889                 if (!NT_STATUS_IS_OK(status)) {
890                         DBG_ERR("pdb_enum_trusteddoms() failed - %s\n",
891                                 nt_errstr(status));
892                         return false;
893                 }
894
895                 for (i = 0; i < num_domains; i++) {
896                         status = add_trusted_domain(ti[i]->name,
897                                                     NULL,
898                                                     &ti[i]->sid,
899                                                     LSA_TRUST_TYPE_DOWNLEVEL,
900                                                     NETR_TRUST_FLAG_OUTBOUND,
901                                                     0,
902                                                     SEC_CHAN_DOMAIN,
903                                                     NULL,
904                                                     &domain);
905                         if (!NT_STATUS_IS_OK(status)) {
906                                 DBG_NOTICE("add_trusted_domain returned %s\n",
907                                            nt_errstr(status));
908                                 return false;
909                         }
910
911                         /* Even in the parent winbindd we'll need to
912                            talk to the DC, so try and see if we can
913                            contact it. Theoretically this isn't neccessary
914                            as the init_dc_connection() in init_child_recv()
915                            will do this, but we can start detecting the DC
916                            early here. */
917                         set_domain_online_request(domain);
918                 }
919
920                 return true;
921         }
922
923         status = pdb_enum_trusted_domains(talloc_tos(), &num_domains, &domains);
924         if (!NT_STATUS_IS_OK(status)) {
925                 DBG_ERR("pdb_enum_trusted_domains() failed - %s\n",
926                         nt_errstr(status));
927                 return false;
928         }
929
930         for (i = 0; i < num_domains; i++) {
931                 enum netr_SchannelType sec_chan_type = SEC_CHAN_DOMAIN;
932                 uint32_t trust_flags = 0;
933
934                 if (domains[i]->trust_type == LSA_TRUST_TYPE_UPLEVEL) {
935                         sec_chan_type = SEC_CHAN_DNS_DOMAIN;
936                 }
937
938                 if (!(domains[i]->trust_direction & LSA_TRUST_DIRECTION_OUTBOUND)) {
939                         sec_chan_type = SEC_CHAN_NULL;
940                 }
941
942                 if (domains[i]->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
943                         trust_flags |= NETR_TRUST_FLAG_INBOUND;
944                 }
945                 if (domains[i]->trust_direction & LSA_TRUST_DIRECTION_OUTBOUND) {
946                         trust_flags |= NETR_TRUST_FLAG_OUTBOUND;
947                 }
948                 if (domains[i]->trust_attributes & LSA_TRUST_ATTRIBUTE_WITHIN_FOREST) {
949                         trust_flags |= NETR_TRUST_FLAG_IN_FOREST;
950                 }
951
952                 status = add_trusted_domain(domains[i]->netbios_name,
953                                             domains[i]->domain_name,
954                                             &domains[i]->security_identifier,
955                                             domains[i]->trust_type,
956                                             trust_flags,
957                                             domains[i]->trust_attributes,
958                                             sec_chan_type,
959                                             NULL,
960                                             &domain);
961                 if (!NT_STATUS_IS_OK(status)) {
962                         DBG_NOTICE("add_trusted_domain returned %s\n",
963                                    nt_errstr(status));
964                         return false;
965                 }
966
967                 if (domains[i]->trust_type == LSA_TRUST_TYPE_UPLEVEL) {
968                         domain->active_directory = true;
969                 }
970                 domain->domain_type = domains[i]->trust_type;
971                 domain->domain_trust_attribs = domains[i]->trust_attributes;
972
973                 if (sec_chan_type != SEC_CHAN_NULL) {
974                         /* Even in the parent winbindd we'll need to
975                            talk to the DC, so try and see if we can
976                            contact it. Theoretically this isn't neccessary
977                            as the init_dc_connection() in init_child_recv()
978                            will do this, but we can start detecting the DC
979                            early here. */
980                         set_domain_online_request(domain);
981                 }
982         }
983
984         for (i = 0; i < num_domains; i++) {
985                 struct ForestTrustInfo fti;
986                 uint32_t fi;
987                 enum ndr_err_code ndr_err;
988                 struct winbindd_domain *routing_domain = NULL;
989
990                 if (domains[i]->trust_type != LSA_TRUST_TYPE_UPLEVEL) {
991                         continue;
992                 }
993
994                 if (!(domains[i]->trust_attributes & LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)) {
995                         continue;
996                 }
997
998                 if (domains[i]->trust_forest_trust_info.length == 0) {
999                         continue;
1000                 }
1001
1002                 routing_domain = find_domain_from_name_noinit(
1003                         domains[i]->netbios_name);
1004                 if (routing_domain == NULL) {
1005                         DBG_ERR("Can't find winbindd domain [%s]\n",
1006                                 domains[i]->netbios_name);
1007                         return false;
1008                 }
1009
1010                 ndr_err = ndr_pull_struct_blob_all(
1011                         &domains[i]->trust_forest_trust_info,
1012                         talloc_tos(), &fti,
1013                         (ndr_pull_flags_fn_t)ndr_pull_ForestTrustInfo);
1014                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1015                         DBG_ERR("ndr_pull_ForestTrustInfo(%s) - %s\n",
1016                                 domains[i]->netbios_name,
1017                                 ndr_map_error2string(ndr_err));
1018                         return false;
1019                 }
1020
1021                 for (fi = 0; fi < fti.count; fi++) {
1022                         struct ForestTrustInfoRecord *rec =
1023                                 &fti.records[fi].record;
1024                         struct ForestTrustDataDomainInfo *drec = NULL;
1025
1026                         if (rec->type != FOREST_TRUST_DOMAIN_INFO) {
1027                                 continue;
1028                         }
1029                         drec = &rec->data.info;
1030
1031                         if (rec->flags & LSA_NB_DISABLED_MASK) {
1032                                 continue;
1033                         }
1034
1035                         if (rec->flags & LSA_SID_DISABLED_MASK) {
1036                                 continue;
1037                         }
1038
1039                         /*
1040                          * TODO:
1041                          * also try to find a matching
1042                          * LSA_TLN_DISABLED_MASK ???
1043                          */
1044
1045                         domain = find_domain_from_name_noinit(drec->netbios_name.string);
1046                         if (domain != NULL) {
1047                                 continue;
1048                         }
1049
1050                         status = add_trusted_domain(drec->netbios_name.string,
1051                                                     drec->dns_name.string,
1052                                                     &drec->sid,
1053                                                     LSA_TRUST_TYPE_UPLEVEL,
1054                                                     NETR_TRUST_FLAG_OUTBOUND,
1055                                                     0,
1056                                                     SEC_CHAN_NULL,
1057                                                     routing_domain,
1058                                                     &domain);
1059                         if (!NT_STATUS_IS_OK(status)) {
1060                                 DBG_NOTICE("add_trusted_domain returned %s\n",
1061                                            nt_errstr(status));
1062                                 return false;
1063                         }
1064                         if (domain == NULL) {
1065                                 continue;
1066                         }
1067                 }
1068         }
1069
1070         return true;
1071 }
1072
1073
1074 /* Look up global info for the winbind daemon */
1075 bool init_domain_list(void)
1076 {
1077         int role = lp_server_role();
1078         struct pdb_domain_info *pdb_domain_info = NULL;
1079         struct winbindd_domain *domain =  NULL;
1080         NTSTATUS status;
1081         bool ok;
1082
1083         /* Free existing list */
1084         free_domain_list();
1085
1086         /* BUILTIN domain */
1087
1088         status = add_trusted_domain("BUILTIN",
1089                                     NULL,
1090                                     &global_sid_Builtin,
1091                                     LSA_TRUST_TYPE_DOWNLEVEL,
1092                                     0, /* trust_flags */
1093                                     0, /* trust_attribs */
1094                                     SEC_CHAN_LOCAL,
1095                                     NULL,
1096                                     &domain);
1097         if (!NT_STATUS_IS_OK(status)) {
1098                 DBG_ERR("add_trusted_domain BUILTIN returned %s\n",
1099                         nt_errstr(status));
1100                 return false;
1101         }
1102
1103         /* Local SAM */
1104
1105         /*
1106          * In case the passdb backend is passdb_dsdb the domain SID comes from
1107          * dsdb, not from secrets.tdb. As we use the domain SID in various
1108          * places, we must ensure the domain SID is migrated from dsdb to
1109          * secrets.tdb before get_global_sam_sid() is called the first time.
1110          *
1111          * The migration is done as part of the passdb_dsdb initialisation,
1112          * calling pdb_get_domain_info() triggers it.
1113          */
1114         pdb_domain_info = pdb_get_domain_info(talloc_tos());
1115
1116         if ( role == ROLE_ACTIVE_DIRECTORY_DC ) {
1117                 uint32_t trust_flags;
1118                 bool is_root;
1119                 enum netr_SchannelType sec_chan_type;
1120                 const char *account_name;
1121                 struct samr_Password current_nt_hash;
1122
1123                 if (pdb_domain_info == NULL) {
1124                         DEBUG(0, ("Failed to fetch our own, local AD "
1125                                 "domain info from sam.ldb\n"));
1126                         return false;
1127                 }
1128
1129                 trust_flags = NETR_TRUST_FLAG_PRIMARY;
1130                 trust_flags |= NETR_TRUST_FLAG_IN_FOREST;
1131                 trust_flags |= NETR_TRUST_FLAG_NATIVE;
1132                 trust_flags |= NETR_TRUST_FLAG_OUTBOUND;
1133
1134                 is_root = strequal(pdb_domain_info->dns_domain,
1135                                    pdb_domain_info->dns_forest);
1136                 if (is_root) {
1137                         trust_flags |= NETR_TRUST_FLAG_TREEROOT;
1138                 }
1139
1140                 status = add_trusted_domain(pdb_domain_info->name,
1141                                             pdb_domain_info->dns_domain,
1142                                             &pdb_domain_info->sid,
1143                                             LSA_TRUST_TYPE_UPLEVEL,
1144                                             trust_flags,
1145                                             LSA_TRUST_ATTRIBUTE_WITHIN_FOREST,
1146                                             SEC_CHAN_BDC,
1147                                             NULL,
1148                                             &domain);
1149                 TALLOC_FREE(pdb_domain_info);
1150                 if (!NT_STATUS_IS_OK(status)) {
1151                         DBG_ERR("Failed to add our own, local AD "
1152                                 "domain to winbindd's internal list\n");
1153                         return false;
1154                 }
1155
1156                 /*
1157                  * We need to call this to find out if we are an RODC
1158                  */
1159                 ok = get_trust_pw_hash(domain->name,
1160                                        current_nt_hash.hash,
1161                                        &account_name,
1162                                        &sec_chan_type);
1163                 if (!ok) {
1164                         /*
1165                          * If get_trust_pw_hash() fails, then try and
1166                          * fetch the password from the more recent of
1167                          * secrets.{ldb,tdb} using the
1168                          * pdb_get_trust_credentials()
1169                          */
1170                         ok = migrate_secrets_tdb_to_ldb(domain);
1171
1172                         if (!ok) {
1173                                 DEBUG(0, ("Failed to migrate our own, "
1174                                           "local AD domain join password for "
1175                                           "winbindd's internal use into "
1176                                           "secrets.tdb\n"));
1177                                 return false;
1178                         }
1179                         ok = get_trust_pw_hash(domain->name,
1180                                                current_nt_hash.hash,
1181                                                &account_name,
1182                                                &sec_chan_type);
1183                         if (!ok) {
1184                                 DEBUG(0, ("Failed to find our our own, just "
1185                                           "written local AD domain join "
1186                                           "password for winbindd's internal "
1187                                           "use in secrets.tdb\n"));
1188                                 return false;
1189                         }
1190                 }
1191
1192                 domain->secure_channel_type = sec_chan_type;
1193                 if (sec_chan_type == SEC_CHAN_RODC) {
1194                         domain->rodc = true;
1195                 }
1196
1197         } else {
1198                 uint32_t trust_flags;
1199                 enum netr_SchannelType secure_channel_type;
1200
1201                 trust_flags = NETR_TRUST_FLAG_OUTBOUND;
1202                 if (role != ROLE_DOMAIN_MEMBER) {
1203                         trust_flags |= NETR_TRUST_FLAG_PRIMARY;
1204                 }
1205
1206                 if (role > ROLE_DOMAIN_MEMBER) {
1207                         secure_channel_type = SEC_CHAN_BDC;
1208                 } else {
1209                         secure_channel_type = SEC_CHAN_LOCAL;
1210                 }
1211
1212                 status = add_trusted_domain(get_global_sam_name(),
1213                                             NULL,
1214                                             get_global_sam_sid(),
1215                                             LSA_TRUST_TYPE_DOWNLEVEL,
1216                                             trust_flags,
1217                                             0, /* trust_attribs */
1218                                             secure_channel_type,
1219                                             NULL,
1220                                             &domain);
1221                 if (!NT_STATUS_IS_OK(status)) {
1222                         DBG_ERR("Failed to add local SAM to "
1223                                 "domain to winbindd's internal list\n");
1224                         return false;
1225                 }
1226         }
1227
1228         if (IS_DC) {
1229                 ok = add_trusted_domains_dc();
1230                 if (!ok) {
1231                         DBG_ERR("init_domain_list_dc failed\n");
1232                         return false;
1233                 }
1234         }
1235
1236         if ( role == ROLE_DOMAIN_MEMBER ) {
1237                 struct dom_sid our_sid;
1238                 uint32_t trust_type;
1239
1240                 if (!secrets_fetch_domain_sid(lp_workgroup(), &our_sid)) {
1241                         DEBUG(0, ("Could not fetch our SID - did we join?\n"));
1242                         return False;
1243                 }
1244
1245                 if (lp_realm() != NULL) {
1246                         trust_type = LSA_TRUST_TYPE_UPLEVEL;
1247                 } else {
1248                         trust_type = LSA_TRUST_TYPE_DOWNLEVEL;
1249                 }
1250
1251                 status = add_trusted_domain(lp_workgroup(),
1252                                             lp_realm(),
1253                                             &our_sid,
1254                                             trust_type,
1255                                             NETR_TRUST_FLAG_PRIMARY|
1256                                             NETR_TRUST_FLAG_OUTBOUND,
1257                                             0, /* trust_attribs */
1258                                             SEC_CHAN_WKSTA,
1259                                             NULL,
1260                                             &domain);
1261                 if (!NT_STATUS_IS_OK(status)) {
1262                         DBG_ERR("Failed to add local SAM to "
1263                                 "domain to winbindd's internal list\n");
1264                         return false;
1265                 }
1266                 /* Even in the parent winbindd we'll need to
1267                    talk to the DC, so try and see if we can
1268                    contact it. Theoretically this isn't neccessary
1269                    as the init_dc_connection() in init_child_recv()
1270                    will do this, but we can start detecting the DC
1271                    early here. */
1272                 set_domain_online_request(domain);
1273
1274         }
1275
1276         status = imessaging_register(winbind_imessaging_context(), NULL,
1277                                      MSG_WINBIND_RELOAD_TRUSTED_DOMAINS,
1278                                      wb_imsg_new_trusted_domain);
1279         if (!NT_STATUS_IS_OK(status)) {
1280                 DBG_ERR("imessaging_register failed %s\n", nt_errstr(status));
1281                 return false;
1282         }
1283
1284         return True;
1285 }
1286
1287 /**
1288  * Given a domain name, return the struct winbindd domain info for it
1289  *
1290  * @note Do *not* pass lp_workgroup() to this function.  domain_list
1291  *       may modify it's value, and free that pointer.  Instead, our local
1292  *       domain may be found by calling find_our_domain().
1293  *       directly.
1294  *
1295  *
1296  * @return The domain structure for the named domain, if it is working.
1297  */
1298
1299 struct winbindd_domain *find_domain_from_name_noinit(const char *domain_name)
1300 {
1301         struct winbindd_domain *domain;
1302
1303         /* Search through list */
1304
1305         for (domain = domain_list(); domain != NULL; domain = domain->next) {
1306                 if (strequal(domain_name, domain->name)) {
1307                         return domain;
1308                 }
1309                 if (domain->alt_name == NULL) {
1310                         continue;
1311                 }
1312                 if (strequal(domain_name, domain->alt_name)) {
1313                         return domain;
1314                 }
1315         }
1316
1317         /* Not found */
1318
1319         return NULL;
1320 }
1321
1322 /**
1323  * Given a domain name, return the struct winbindd domain if it's a direct
1324  * outgoing trust
1325  *
1326  * @return The domain structure for the named domain, if it is a direct outgoing trust
1327  */
1328 struct winbindd_domain *find_trust_from_name_noinit(const char *domain_name)
1329 {
1330         struct winbindd_domain *domain = NULL;
1331
1332         domain = find_domain_from_name_noinit(domain_name);
1333         if (domain == NULL) {
1334                 return NULL;
1335         }
1336
1337         if (domain->secure_channel_type != SEC_CHAN_NULL) {
1338                 return domain;
1339         }
1340
1341         return NULL;
1342 }
1343
1344 struct winbindd_domain *find_domain_from_name(const char *domain_name)
1345 {
1346         struct winbindd_domain *domain;
1347
1348         domain = find_domain_from_name_noinit(domain_name);
1349
1350         if (domain == NULL)
1351                 return NULL;
1352
1353         if (!domain->initialized)
1354                 init_dc_connection(domain, false);
1355
1356         return domain;
1357 }
1358
1359 /* Given a domain sid, return the struct winbindd domain info for it */
1360
1361 struct winbindd_domain *find_domain_from_sid_noinit(const struct dom_sid *sid)
1362 {
1363         struct winbindd_domain *domain;
1364
1365         /* Search through list */
1366
1367         for (domain = domain_list(); domain != NULL; domain = domain->next) {
1368                 if (dom_sid_compare_domain(sid, &domain->sid) == 0)
1369                         return domain;
1370         }
1371
1372         /* Not found */
1373
1374         return NULL;
1375 }
1376
1377 /**
1378  * Given a domain sid, return the struct winbindd domain if it's a direct
1379  * outgoing trust
1380  *
1381  * @return The domain structure for the specified domain, if it is a direct outgoing trust
1382  */
1383 struct winbindd_domain *find_trust_from_sid_noinit(const struct dom_sid *sid)
1384 {
1385         struct winbindd_domain *domain = NULL;
1386
1387         domain = find_domain_from_sid_noinit(sid);
1388         if (domain == NULL) {
1389                 return NULL;
1390         }
1391
1392         if (domain->secure_channel_type != SEC_CHAN_NULL) {
1393                 return domain;
1394         }
1395
1396         return NULL;
1397 }
1398
1399 /* Given a domain sid, return the struct winbindd domain info for it */
1400
1401 struct winbindd_domain *find_domain_from_sid(const struct dom_sid *sid)
1402 {
1403         struct winbindd_domain *domain;
1404
1405         domain = find_domain_from_sid_noinit(sid);
1406
1407         if (domain == NULL)
1408                 return NULL;
1409
1410         if (!domain->initialized)
1411                 init_dc_connection(domain, false);
1412
1413         return domain;
1414 }
1415
1416 struct winbindd_domain *find_our_domain(void)
1417 {
1418         struct winbindd_domain *domain;
1419
1420         /* Search through list */
1421
1422         for (domain = domain_list(); domain != NULL; domain = domain->next) {
1423                 if (domain->primary)
1424                         return domain;
1425         }
1426
1427         smb_panic("Could not find our domain");
1428         return NULL;
1429 }
1430
1431 struct winbindd_domain *find_default_route_domain(void)
1432 {
1433         if (!IS_DC) {
1434                 return find_our_domain();
1435         }
1436         DBG_DEBUG("Routing logic not yet implemented on a DC\n");
1437         return NULL;
1438 }
1439
1440 /* Find the appropriate domain to lookup a name or SID */
1441
1442 struct winbindd_domain *find_lookup_domain_from_sid(const struct dom_sid *sid)
1443 {
1444         DBG_DEBUG("SID [%s]\n", sid_string_dbg(sid));
1445
1446         /*
1447          * SIDs in the S-1-22-{1,2} domain and well-known SIDs should be handled
1448          * by our passdb.
1449          */
1450
1451         if ( sid_check_is_in_unix_groups(sid) ||
1452              sid_check_is_unix_groups(sid) ||
1453              sid_check_is_in_unix_users(sid) ||
1454              sid_check_is_unix_users(sid) ||
1455              sid_check_is_wellknown_domain(sid, NULL) ||
1456              sid_check_is_in_wellknown_domain(sid) )
1457         {
1458                 return find_domain_from_sid(get_global_sam_sid());
1459         }
1460
1461         /*
1462          * On member servers the internal domains are different: These are part
1463          * of the local SAM.
1464          */
1465
1466         if (is_internal_domain(sid) || is_in_internal_domain(sid)) {
1467                 DEBUG(10, ("calling find_domain_from_sid\n"));
1468                 return find_domain_from_sid(sid);
1469         }
1470
1471         if (IS_DC) {
1472                 struct winbindd_domain *domain = NULL;
1473
1474                 domain = find_domain_from_sid_noinit(sid);
1475                 if (domain == NULL) {
1476                         return NULL;
1477                 }
1478
1479                 if (domain->secure_channel_type != SEC_CHAN_NULL) {
1480                         return domain;
1481                 }
1482
1483                 return domain->routing_domain;
1484         }
1485
1486         /* On a member server a query for SID or name can always go to our
1487          * primary DC. */
1488
1489         DEBUG(10, ("calling find_our_domain\n"));
1490         return find_our_domain();
1491 }
1492
1493 struct winbindd_domain *find_lookup_domain_from_name(const char *domain_name)
1494 {
1495         if ( strequal(domain_name, unix_users_domain_name() ) ||
1496              strequal(domain_name, unix_groups_domain_name() ) )
1497         {
1498                 /*
1499                  * The "Unix User" and "Unix Group" domain our handled by
1500                  * passdb
1501                  */
1502                 return find_domain_from_name_noinit( get_global_sam_name() );
1503         }
1504
1505         if (strequal(domain_name, "BUILTIN") ||
1506             strequal(domain_name, get_global_sam_name()))
1507                 return find_domain_from_name_noinit(domain_name);
1508
1509         if (IS_DC) {
1510                 struct winbindd_domain *domain = NULL;
1511
1512                 domain = find_domain_from_name_noinit(domain_name);
1513                 if (domain == NULL) {
1514                         return NULL;
1515                 }
1516
1517                 if (domain->secure_channel_type != SEC_CHAN_NULL) {
1518                         return domain;
1519                 }
1520
1521                 return domain->routing_domain;
1522         }
1523
1524         return find_our_domain();
1525 }
1526
1527 /* Is this a domain which we may assume no DOMAIN\ prefix? */
1528
1529 static bool assume_domain(const char *domain)
1530 {
1531         /* never assume the domain on a standalone server */
1532
1533         if ( lp_server_role() == ROLE_STANDALONE )
1534                 return False;
1535
1536         /* domain member servers may possibly assume for the domain name */
1537
1538         if ( lp_server_role() == ROLE_DOMAIN_MEMBER ) {
1539                 if ( !strequal(lp_workgroup(), domain) )
1540                         return False;
1541
1542                 if ( lp_winbind_use_default_domain() )
1543                         return True;
1544         }
1545
1546         /* only left with a domain controller */
1547
1548         if ( strequal(get_global_sam_name(), domain) )  {
1549                 return True;
1550         }
1551
1552         return False;
1553 }
1554
1555 /* Parse a string of the form DOMAIN\user into a domain and a user */
1556
1557 bool parse_domain_user(const char *domuser, fstring domain, fstring user)
1558 {
1559         char *p = strchr(domuser,*lp_winbind_separator());
1560
1561         if ( !p ) {
1562                 fstrcpy(user, domuser);
1563                 p = strchr(domuser, '@');
1564
1565                 if ( assume_domain(lp_workgroup()) && p == NULL) {
1566                         fstrcpy(domain, lp_workgroup());
1567                 } else if (p != NULL) {
1568                         fstrcpy(domain, p + 1);
1569                         user[PTR_DIFF(p, domuser)] = 0;
1570                 } else {
1571                         return False;
1572                 }
1573         } else {
1574                 fstrcpy(user, p+1);
1575                 fstrcpy(domain, domuser);
1576                 domain[PTR_DIFF(p, domuser)] = 0;
1577         }
1578
1579         return strupper_m(domain);
1580 }
1581
1582 bool parse_domain_user_talloc(TALLOC_CTX *mem_ctx, const char *domuser,
1583                               char **domain, char **user)
1584 {
1585         fstring fstr_domain, fstr_user;
1586         if (!parse_domain_user(domuser, fstr_domain, fstr_user)) {
1587                 return False;
1588         }
1589         *domain = talloc_strdup(mem_ctx, fstr_domain);
1590         *user = talloc_strdup(mem_ctx, fstr_user);
1591         return ((*domain != NULL) && (*user != NULL));
1592 }
1593
1594 /* Ensure an incoming username from NSS is fully qualified. Replace the
1595    incoming fstring with DOMAIN <separator> user. Returns the same
1596    values as parse_domain_user() but also replaces the incoming username.
1597    Used to ensure all names are fully qualified within winbindd.
1598    Used by the NSS protocols of auth, chauthtok, logoff and ccache_ntlm_auth.
1599    The protocol definitions of auth_crap, chng_pswd_auth_crap
1600    really should be changed to use this instead of doing things
1601    by hand. JRA. */
1602
1603 bool canonicalize_username(fstring username_inout, fstring domain, fstring user)
1604 {
1605         if (!parse_domain_user(username_inout, domain, user)) {
1606                 return False;
1607         }
1608         slprintf(username_inout, sizeof(fstring) - 1, "%s%c%s",
1609                  domain, *lp_winbind_separator(),
1610                  user);
1611         return True;
1612 }
1613
1614 /*
1615     Fill DOMAIN\\USERNAME entry accounting 'winbind use default domain' and
1616     'winbind separator' options.
1617     This means:
1618         - omit DOMAIN when 'winbind use default domain = true' and DOMAIN is
1619         lp_workgroup()
1620
1621     If we are a PDC or BDC, and this is for our domain, do likewise.
1622
1623     On an AD DC we always fill DOMAIN\\USERNAME.
1624
1625     We always canonicalize as UPPERCASE DOMAIN, lowercase username.
1626 */
1627 void fill_domain_username(fstring name, const char *domain, const char *user, bool can_assume)
1628 {
1629         fstring tmp_user;
1630
1631         if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
1632                 can_assume = false;
1633         }
1634
1635         fstrcpy(tmp_user, user);
1636         (void)strlower_m(tmp_user);
1637
1638         if (can_assume && assume_domain(domain)) {
1639                 strlcpy(name, tmp_user, sizeof(fstring));
1640         } else {
1641                 slprintf(name, sizeof(fstring) - 1, "%s%c%s",
1642                          domain, *lp_winbind_separator(),
1643                          tmp_user);
1644         }
1645 }
1646
1647 /**
1648  * talloc version of fill_domain_username()
1649  * return NULL on talloc failure.
1650  */
1651 char *fill_domain_username_talloc(TALLOC_CTX *mem_ctx,
1652                                   const char *domain,
1653                                   const char *user,
1654                                   bool can_assume)
1655 {
1656         char *tmp_user, *name;
1657
1658         if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
1659                 can_assume = false;
1660         }
1661
1662         tmp_user = talloc_strdup(mem_ctx, user);
1663         if (!strlower_m(tmp_user)) {
1664                 TALLOC_FREE(tmp_user);
1665                 return NULL;
1666         }
1667
1668         if (can_assume && assume_domain(domain)) {
1669                 name = tmp_user;
1670         } else {
1671                 name = talloc_asprintf(mem_ctx, "%s%c%s",
1672                                        domain,
1673                                        *lp_winbind_separator(),
1674                                        tmp_user);
1675                 TALLOC_FREE(tmp_user);
1676         }
1677
1678         return name;
1679 }
1680
1681 /*
1682  * Client list accessor functions
1683  */
1684
1685 static struct winbindd_cli_state *_client_list;
1686 static int _num_clients;
1687
1688 /* Return list of all connected clients */
1689
1690 struct winbindd_cli_state *winbindd_client_list(void)
1691 {
1692         return _client_list;
1693 }
1694
1695 /* Return list-tail of all connected clients */
1696
1697 struct winbindd_cli_state *winbindd_client_list_tail(void)
1698 {
1699         return DLIST_TAIL(_client_list);
1700 }
1701
1702 /* Return previous (read:newer) client in list */
1703
1704 struct winbindd_cli_state *
1705 winbindd_client_list_prev(struct winbindd_cli_state *cli)
1706 {
1707         return DLIST_PREV(cli);
1708 }
1709
1710 /* Add a connection to the list */
1711
1712 void winbindd_add_client(struct winbindd_cli_state *cli)
1713 {
1714         cli->last_access = time(NULL);
1715         DLIST_ADD(_client_list, cli);
1716         _num_clients++;
1717 }
1718
1719 /* Remove a client from the list */
1720
1721 void winbindd_remove_client(struct winbindd_cli_state *cli)
1722 {
1723         DLIST_REMOVE(_client_list, cli);
1724         _num_clients--;
1725 }
1726
1727 /* Move a client to head or list */
1728
1729 void winbindd_promote_client(struct winbindd_cli_state *cli)
1730 {
1731         cli->last_access = time(NULL);
1732         DLIST_PROMOTE(_client_list, cli);
1733 }
1734
1735 /* Return number of open clients */
1736
1737 int winbindd_num_clients(void)
1738 {
1739         return _num_clients;
1740 }
1741
1742 NTSTATUS lookup_usergroups_cached(TALLOC_CTX *mem_ctx,
1743                                   const struct dom_sid *user_sid,
1744                                   uint32_t *p_num_groups, struct dom_sid **user_sids)
1745 {
1746         struct netr_SamInfo3 *info3 = NULL;
1747         NTSTATUS status = NT_STATUS_NO_MEMORY;
1748         uint32_t num_groups = 0;
1749
1750         DEBUG(3,(": lookup_usergroups_cached\n"));
1751
1752         *user_sids = NULL;
1753         *p_num_groups = 0;
1754
1755         info3 = netsamlogon_cache_get(mem_ctx, user_sid);
1756
1757         if (info3 == NULL) {
1758                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1759         }
1760
1761         /*
1762          * Before bug #7843 the "Domain Local" groups were added with a
1763          * lookupuseraliases call, but this isn't done anymore for our domain
1764          * so we need to resolve resource groups here.
1765          *
1766          * When to use Resource Groups:
1767          * http://technet.microsoft.com/en-us/library/cc753670%28v=WS.10%29.aspx
1768          */
1769         status = sid_array_from_info3(mem_ctx, info3,
1770                                       user_sids,
1771                                       &num_groups,
1772                                       false);
1773
1774         if (!NT_STATUS_IS_OK(status)) {
1775                 TALLOC_FREE(info3);
1776                 return status;
1777         }
1778
1779         TALLOC_FREE(info3);
1780         *p_num_groups = num_groups;
1781         status = (user_sids != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1782
1783         DEBUG(3,(": lookup_usergroups_cached succeeded\n"));
1784
1785         return status;
1786 }
1787
1788 /*********************************************************************
1789  We use this to remove spaces from user and group names
1790 ********************************************************************/
1791
1792 NTSTATUS normalize_name_map(TALLOC_CTX *mem_ctx,
1793                              const char *domain_name,
1794                              const char *name,
1795                              char **normalized)
1796 {
1797         struct winbindd_domain *domain = NULL;
1798         NTSTATUS nt_status;
1799
1800         if (!name || !normalized) {
1801                 return NT_STATUS_INVALID_PARAMETER;
1802         }
1803
1804         if (!lp_winbind_normalize_names()) {
1805                 return NT_STATUS_PROCEDURE_NOT_FOUND;
1806         }
1807
1808         domain = find_domain_from_name_noinit(domain_name);
1809         if (domain == NULL) {
1810                 DBG_ERR("Failed to find domain '%s'\n", domain_name);
1811                 return NT_STATUS_NO_SUCH_DOMAIN;
1812         }
1813
1814         /* Alias support and whitespace replacement are mutually
1815            exclusive */
1816
1817         nt_status = resolve_username_to_alias(mem_ctx, domain,
1818                                               name, normalized );
1819         if (NT_STATUS_IS_OK(nt_status)) {
1820                 /* special return code to let the caller know we
1821                    mapped to an alias */
1822                 return NT_STATUS_FILE_RENAMED;
1823         }
1824
1825         /* check for an unreachable domain */
1826
1827         if (NT_STATUS_EQUAL(nt_status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) {
1828                 DEBUG(5,("normalize_name_map: Setting domain %s offline\n",
1829                          domain->name));
1830                 set_domain_offline(domain);
1831                 return nt_status;
1832         }
1833
1834         /* deal with whitespace */
1835
1836         *normalized = talloc_strdup(mem_ctx, name);
1837         if (!(*normalized)) {
1838                 return NT_STATUS_NO_MEMORY;
1839         }
1840
1841         all_string_sub( *normalized, " ", "_", 0 );
1842
1843         return NT_STATUS_OK;
1844 }
1845
1846 /*********************************************************************
1847  We use this to do the inverse of normalize_name_map()
1848 ********************************************************************/
1849
1850 NTSTATUS normalize_name_unmap(TALLOC_CTX *mem_ctx,
1851                               char *name,
1852                               char **normalized)
1853 {
1854         NTSTATUS nt_status;
1855         struct winbindd_domain *domain = find_our_domain();
1856
1857         if (!name || !normalized) {
1858                 return NT_STATUS_INVALID_PARAMETER;
1859         }
1860
1861         if (!lp_winbind_normalize_names()) {
1862                 return NT_STATUS_PROCEDURE_NOT_FOUND;
1863         }
1864
1865         /* Alias support and whitespace replacement are mutally
1866            exclusive */
1867
1868         /* When mapping from an alias to a username, we don't know the
1869            domain.  But we only need a domain structure to cache
1870            a successful lookup , so just our own domain structure for
1871            the seqnum. */
1872
1873         nt_status = resolve_alias_to_username(mem_ctx, domain,
1874                                               name, normalized);
1875         if (NT_STATUS_IS_OK(nt_status)) {
1876                 /* Special return code to let the caller know we mapped
1877                    from an alias */
1878                 return NT_STATUS_FILE_RENAMED;
1879         }
1880
1881         /* check for an unreachable domain */
1882
1883         if (NT_STATUS_EQUAL(nt_status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) {
1884                 DEBUG(5,("normalize_name_unmap: Setting domain %s offline\n",
1885                          domain->name));
1886                 set_domain_offline(domain);
1887                 return nt_status;
1888         }
1889
1890         /* deal with whitespace */
1891
1892         *normalized = talloc_strdup(mem_ctx, name);
1893         if (!(*normalized)) {
1894                 return NT_STATUS_NO_MEMORY;
1895         }
1896
1897         all_string_sub(*normalized, "_", " ", 0);
1898
1899         return NT_STATUS_OK;
1900 }
1901
1902 /*********************************************************************
1903  ********************************************************************/
1904
1905 bool winbindd_can_contact_domain(struct winbindd_domain *domain)
1906 {
1907         struct winbindd_tdc_domain *tdc = NULL;
1908         TALLOC_CTX *frame = talloc_stackframe();
1909         bool ret = false;
1910
1911         /* We can contact the domain if it is our primary domain */
1912
1913         if (domain->primary) {
1914                 ret = true;
1915                 goto done;
1916         }
1917
1918         /* Trust the TDC cache and not the winbindd_domain flags */
1919
1920         if ((tdc = wcache_tdc_fetch_domain(frame, domain->name)) == NULL) {
1921                 DEBUG(10,("winbindd_can_contact_domain: %s not found in cache\n",
1922                           domain->name));
1923                 ret = false;
1924                 goto done;
1925         }
1926
1927         /* Can always contact a domain that is in out forest */
1928
1929         if (tdc->trust_flags & NETR_TRUST_FLAG_IN_FOREST) {
1930                 ret = true;
1931                 goto done;
1932         }
1933
1934         /*
1935          * On a _member_ server, we cannot contact the domain if it
1936          * is running AD and we have no inbound trust.
1937          */
1938
1939         if (!IS_DC &&
1940              domain->active_directory &&
1941             ((tdc->trust_flags & NETR_TRUST_FLAG_INBOUND) != NETR_TRUST_FLAG_INBOUND))
1942         {
1943                 DEBUG(10, ("winbindd_can_contact_domain: %s is an AD domain "
1944                            "and we have no inbound trust.\n", domain->name));
1945                 goto done;
1946         }
1947
1948         /* Assume everything else is ok (probably not true but what
1949            can you do?) */
1950
1951         ret = true;
1952
1953 done:
1954         talloc_destroy(frame);
1955
1956         return ret;
1957 }
1958
1959 /*********************************************************************
1960  ********************************************************************/
1961
1962 bool winbindd_internal_child(struct winbindd_child *child)
1963 {
1964         if ((child == idmap_child()) || (child == locator_child())) {
1965                 return True;
1966         }
1967
1968         return False;
1969 }
1970
1971 #ifdef HAVE_KRB5_LOCATE_PLUGIN_H
1972
1973 /*********************************************************************
1974  ********************************************************************/
1975
1976 static void winbindd_set_locator_kdc_env(const struct winbindd_domain *domain)
1977 {
1978         char *var = NULL;
1979         char addr[INET6_ADDRSTRLEN];
1980         const char *kdc = NULL;
1981         int lvl = 11;
1982
1983         if (!domain || !domain->alt_name || !*domain->alt_name) {
1984                 return;
1985         }
1986
1987         if (domain->initialized && !domain->active_directory) {
1988                 DEBUG(lvl,("winbindd_set_locator_kdc_env: %s not AD\n",
1989                         domain->alt_name));
1990                 return;
1991         }
1992
1993         print_sockaddr(addr, sizeof(addr), &domain->dcaddr);
1994         kdc = addr;
1995         if (!*kdc) {
1996                 DEBUG(lvl,("winbindd_set_locator_kdc_env: %s no DC IP\n",
1997                         domain->alt_name));
1998                 kdc = domain->dcname;
1999         }
2000
2001         if (!kdc || !*kdc) {
2002                 DEBUG(lvl,("winbindd_set_locator_kdc_env: %s no DC at all\n",
2003                         domain->alt_name));
2004                 return;
2005         }
2006
2007         if (asprintf_strupper_m(&var, "%s_%s", WINBINDD_LOCATOR_KDC_ADDRESS,
2008                                 domain->alt_name) == -1) {
2009                 return;
2010         }
2011
2012         DEBUG(lvl,("winbindd_set_locator_kdc_env: setting var: %s to: %s\n",
2013                 var, kdc));
2014
2015         setenv(var, kdc, 1);
2016         free(var);
2017 }
2018
2019 /*********************************************************************
2020  ********************************************************************/
2021
2022 void winbindd_set_locator_kdc_envs(const struct winbindd_domain *domain)
2023 {
2024         struct winbindd_domain *our_dom = find_our_domain();
2025
2026         winbindd_set_locator_kdc_env(domain);
2027
2028         if (domain != our_dom) {
2029                 winbindd_set_locator_kdc_env(our_dom);
2030         }
2031 }
2032
2033 /*********************************************************************
2034  ********************************************************************/
2035
2036 void winbindd_unset_locator_kdc_env(const struct winbindd_domain *domain)
2037 {
2038         char *var = NULL;
2039
2040         if (!domain || !domain->alt_name || !*domain->alt_name) {
2041                 return;
2042         }
2043
2044         if (asprintf_strupper_m(&var, "%s_%s", WINBINDD_LOCATOR_KDC_ADDRESS,
2045                                 domain->alt_name) == -1) {
2046                 return;
2047         }
2048
2049         unsetenv(var);
2050         free(var);
2051 }
2052 #else
2053
2054 void winbindd_set_locator_kdc_envs(const struct winbindd_domain *domain)
2055 {
2056         return;
2057 }
2058
2059 void winbindd_unset_locator_kdc_env(const struct winbindd_domain *domain)
2060 {
2061         return;
2062 }
2063
2064 #endif /* HAVE_KRB5_LOCATE_PLUGIN_H */
2065
2066 void set_auth_errors(struct winbindd_response *resp, NTSTATUS result)
2067 {
2068         resp->data.auth.nt_status = NT_STATUS_V(result);
2069         fstrcpy(resp->data.auth.nt_status_string, nt_errstr(result));
2070
2071         /* we might have given a more useful error above */
2072         if (*resp->data.auth.error_string == '\0')
2073                 fstrcpy(resp->data.auth.error_string,
2074                         get_friendly_nt_error_msg(result));
2075         resp->data.auth.pam_error = nt_status_to_pam(result);
2076 }
2077
2078 bool is_domain_offline(const struct winbindd_domain *domain)
2079 {
2080         if (get_global_winbindd_state_offline()) {
2081                 return true;
2082         }
2083         return !domain->online;
2084 }
2085
2086 bool is_domain_online(const struct winbindd_domain *domain)
2087 {
2088         return !is_domain_offline(domain);
2089 }
2090
2091 /**
2092  * Parse an char array into a list of sids.
2093  *
2094  * The input sidstr should consist of 0-terminated strings
2095  * representing sids, separated by newline characters '\n'.
2096  * The list is terminated by an empty string, i.e.
2097  * character '\0' directly following a character '\n'
2098  * (or '\0' right at the start of sidstr).
2099  */
2100 bool parse_sidlist(TALLOC_CTX *mem_ctx, const char *sidstr,
2101                    struct dom_sid **sids, uint32_t *num_sids)
2102 {
2103         const char *p;
2104
2105         p = sidstr;
2106         if (p == NULL)
2107                 return False;
2108
2109         while (p[0] != '\0') {
2110                 struct dom_sid sid;
2111                 const char *q = NULL;
2112
2113                 if (!dom_sid_parse_endp(p, &sid, &q)) {
2114                         DEBUG(1, ("Could not parse sid %s\n", p));
2115                         return false;
2116                 }
2117                 if (q[0] != '\n') {
2118                         DEBUG(1, ("Got invalid sidstr: %s\n", p));
2119                         return false;
2120                 }
2121                 if (!NT_STATUS_IS_OK(add_sid_to_array(mem_ctx, &sid, sids,
2122                                                       num_sids)))
2123                 {
2124                         return False;
2125                 }
2126                 p = q+1;
2127         }
2128         return True;
2129 }
2130
2131 bool parse_xidlist(TALLOC_CTX *mem_ctx, const char *xidstr,
2132                    struct unixid **pxids, uint32_t *pnum_xids)
2133 {
2134         const char *p;
2135         struct unixid *xids = NULL;
2136         uint32_t num_xids = 0;
2137
2138         p = xidstr;
2139         if (p == NULL) {
2140                 return false;
2141         }
2142
2143         while (p[0] != '\0') {
2144                 struct unixid *tmp;
2145                 struct unixid xid;
2146                 unsigned long long id;
2147                 char *endp;
2148
2149                 switch (p[0]) {
2150                 case 'U':
2151                         xid = (struct unixid) { .type = ID_TYPE_UID };
2152                         break;
2153                 case 'G':
2154                         xid = (struct unixid) { .type = ID_TYPE_GID };
2155                         break;
2156                 default:
2157                         return false;
2158                 }
2159
2160                 p += 1;
2161
2162                 id = strtoull(p, &endp, 10);
2163                 if ((id == ULLONG_MAX) && (errno == ERANGE)) {
2164                         goto fail;
2165                 }
2166                 if (*endp != '\n') {
2167                         goto fail;
2168                 }
2169                 p = endp+1;
2170
2171                 xid.id = id;
2172                 if ((unsigned long long)xid.id != id) {
2173                         goto fail;
2174                 }
2175
2176                 tmp = talloc_realloc(mem_ctx, xids, struct unixid, num_xids+1);
2177                 if (tmp == NULL) {
2178                         return 0;
2179                 }
2180                 xids = tmp;
2181
2182                 xids[num_xids] = xid;
2183                 num_xids += 1;
2184         }
2185
2186         *pxids = xids;
2187         *pnum_xids = num_xids;
2188         return true;
2189
2190 fail:
2191         TALLOC_FREE(xids);
2192         return false;
2193 }