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