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