s4/torture: Fix misplaced positional arguments for u64 comparison
[gd/samba-autobuild/.git] / source3 / winbindd / winbindd_cm.c
1 /*
2    Unix SMB/CIFS implementation.
3
4    Winbind daemon connection manager
5
6    Copyright (C) Tim Potter                2001
7    Copyright (C) Andrew Bartlett           2002
8    Copyright (C) Gerald (Jerry) Carter     2003-2005.
9    Copyright (C) Volker Lendecke           2004-2005
10    Copyright (C) Jeremy Allison            2006
11
12    This program is free software; you can redistribute it and/or modify
13    it under the terms of the GNU General Public License as published by
14    the Free Software Foundation; either version 3 of the License, or
15    (at your option) any later version.
16
17    This program is distributed in the hope that it will be useful,
18    but WITHOUT ANY WARRANTY; without even the implied warranty of
19    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20    GNU General Public License for more details.
21
22    You should have received a copy of the GNU General Public License
23    along with this program.  If not, see <http://www.gnu.org/licenses/>.
24 */
25
26 /*
27    We need to manage connections to domain controllers without having to
28    mess up the main winbindd code with other issues.  The aim of the
29    connection manager is to:
30
31        - make connections to domain controllers and cache them
32        - re-establish connections when networks or servers go down
33        - centralise the policy on connection timeouts, domain controller
34          selection etc
35        - manage re-entrancy for when winbindd becomes able to handle
36          multiple outstanding rpc requests
37
38    Why not have connection management as part of the rpc layer like tng?
39    Good question.  This code may morph into libsmb/rpc_cache.c or something
40    like that but at the moment it's simply staying as part of winbind.  I
41    think the TNG architecture of forcing every user of the rpc layer to use
42    the connection caching system is a bad idea.  It should be an optional
43    method of using the routines.
44
45    The TNG design is quite good but I disagree with some aspects of the
46    implementation. -tpot
47
48  */
49
50 /*
51    TODO:
52
53      - I'm pretty annoyed by all the make_nmb_name() stuff.  It should be
54        moved down into another function.
55
56      - Take care when destroying cli_structs as they can be shared between
57        various sam handles.
58
59  */
60
61 #include "includes.h"
62 #include "winbindd.h"
63 #include "libsmb/namequery.h"
64 #include "../libcli/auth/libcli_auth.h"
65 #include "../librpc/gen_ndr/ndr_netlogon_c.h"
66 #include "rpc_client/cli_pipe.h"
67 #include "rpc_client/cli_netlogon.h"
68 #include "../librpc/gen_ndr/ndr_samr_c.h"
69 #include "../librpc/gen_ndr/ndr_lsa_c.h"
70 #include "rpc_client/cli_lsarpc.h"
71 #include "../librpc/gen_ndr/ndr_dssetup_c.h"
72 #include "libads/sitename_cache.h"
73 #include "libsmb/libsmb.h"
74 #include "libsmb/clidgram.h"
75 #include "ads.h"
76 #include "secrets.h"
77 #include "../libcli/security/security.h"
78 #include "passdb.h"
79 #include "messages.h"
80 #include "auth/gensec/gensec.h"
81 #include "../libcli/smb/smbXcli_base.h"
82 #include "libcli/auth/netlogon_creds_cli.h"
83 #include "auth.h"
84 #include "rpc_server/rpc_ncacn_np.h"
85 #include "auth/credentials/credentials.h"
86 #include "lib/param/param.h"
87 #include "lib/gencache.h"
88 #include "lib/util/string_wrappers.h"
89 #include "lib/global_contexts.h"
90 #include "librpc/gen_ndr/ndr_winbind_c.h"
91
92 #undef DBGC_CLASS
93 #define DBGC_CLASS DBGC_WINBIND
94
95 struct dc_name_ip {
96         fstring name;
97         struct sockaddr_storage ss;
98 };
99
100 extern struct winbindd_methods reconnect_methods;
101
102 static NTSTATUS init_dc_connection_network(struct winbindd_domain *domain, bool need_rw_dc);
103 static void set_dc_type_and_flags( struct winbindd_domain *domain );
104 static bool set_dc_type_and_flags_trustinfo( struct winbindd_domain *domain );
105 static bool get_dcs(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain,
106                     struct dc_name_ip **dcs, int *num_dcs,
107                     uint32_t request_flags);
108
109 void winbind_msg_domain_offline(struct messaging_context *msg_ctx,
110                                 void *private_data,
111                                 uint32_t msg_type,
112                                 struct server_id server_id,
113                                 DATA_BLOB *data)
114 {
115         const char *domain_name = (const char *)data->data;
116         struct winbindd_domain *domain;
117
118         domain = find_domain_from_name_noinit(domain_name);
119         if (domain == NULL) {
120                 DBG_DEBUG("Domain %s not found!\n", domain_name);
121                 return;
122         }
123
124         DBG_DEBUG("Domain %s was %s, change to offline now.\n",
125                   domain_name,
126                   domain->online ? "online" : "offline");
127
128         domain->online = false;
129 }
130
131 void winbind_msg_domain_online(struct messaging_context *msg_ctx,
132                                 void *private_data,
133                                 uint32_t msg_type,
134                                 struct server_id server_id,
135                                 DATA_BLOB *data)
136 {
137         const char *domain_name = (const char *)data->data;
138         struct winbindd_domain *domain;
139
140         domain = find_domain_from_name_noinit(domain_name);
141         if (domain == NULL) {
142                 return;
143         }
144
145         SMB_ASSERT(wb_child_domain() == NULL);
146
147         DBG_DEBUG("Domain %s was %s, marking as online now!\n",
148                   domain_name,
149                   domain->online ? "online" : "offline");
150
151         domain->online = true;
152 }
153
154 /****************************************************************
155  Set domain offline and also add handler to put us back online
156  if we detect a DC.
157 ****************************************************************/
158
159 void set_domain_offline(struct winbindd_domain *domain)
160 {
161         pid_t parent_pid = getppid();
162
163         DEBUG(10,("set_domain_offline: called for domain %s\n",
164                 domain->name ));
165
166         if (domain->internal) {
167                 DEBUG(3,("set_domain_offline: domain %s is internal - logic error.\n",
168                         domain->name ));
169                 return;
170         }
171
172         domain->online = False;
173
174         /* Offline domains are always initialized. They're
175            re-initialized when they go back online. */
176
177         domain->initialized = True;
178
179         /* Send a message to the parent that the domain is offline. */
180         if (parent_pid > 1 && !domain->internal) {
181                 messaging_send_buf(global_messaging_context(),
182                                    pid_to_procid(parent_pid),
183                                    MSG_WINBIND_DOMAIN_OFFLINE,
184                                    (uint8_t *)domain->name,
185                                    strlen(domain->name) + 1);
186         }
187
188         /* Send an offline message to the idmap child when our
189            primary domain goes offline */
190         if ( domain->primary ) {
191                 pid_t idmap_pid = idmap_child_pid();
192
193                 if (idmap_pid != 0) {
194                         messaging_send_buf(global_messaging_context(),
195                                            pid_to_procid(idmap_pid),
196                                            MSG_WINBIND_OFFLINE,
197                                            (const uint8_t *)domain->name,
198                                            strlen(domain->name)+1);
199                 }
200         }
201
202         return;
203 }
204
205 /****************************************************************
206  Set domain online - if allowed.
207 ****************************************************************/
208
209 static void set_domain_online(struct winbindd_domain *domain)
210 {
211         pid_t parent_pid = getppid();
212
213         DEBUG(10,("set_domain_online: called for domain %s\n",
214                 domain->name ));
215
216         if (domain->internal) {
217                 DEBUG(3,("set_domain_online: domain %s is internal - logic error.\n",
218                         domain->name ));
219                 return;
220         }
221
222         if (get_global_winbindd_state_offline()) {
223                 DEBUG(10,("set_domain_online: domain %s remaining globally offline\n",
224                         domain->name ));
225                 return;
226         }
227
228         winbindd_set_locator_kdc_envs(domain);
229
230         /* If we are waiting to get a krb5 ticket, trigger immediately. */
231         ccache_regain_all_now();
232
233         /* Ok, we're out of any startup mode now... */
234         domain->startup = False;
235
236         if (domain->online == False) {
237                 /* We were offline - now we're online. We default to
238                    using the MS-RPC backend if we started offline,
239                    and if we're going online for the first time we
240                    should really re-initialize the backends and the
241                    checks to see if we're talking to an AD or NT domain.
242                 */
243
244                 domain->initialized = False;
245
246                 /* 'reconnect_methods' is the MS-RPC backend. */
247                 if (domain->backend == &reconnect_methods) {
248                         domain->backend = NULL;
249                 }
250         }
251
252         domain->online = True;
253
254         /* Send a message to the parent that the domain is online. */
255         if (parent_pid > 1 && !domain->internal) {
256                 messaging_send_buf(global_messaging_context(),
257                                    pid_to_procid(parent_pid),
258                                    MSG_WINBIND_DOMAIN_ONLINE,
259                                    (uint8_t *)domain->name,
260                                    strlen(domain->name) + 1);
261         }
262
263         /* Send an online message to the idmap child when our
264            primary domain comes online */
265
266         if ( domain->primary ) {
267                 pid_t idmap_pid = idmap_child_pid();
268
269                 if (idmap_pid != 0) {
270                         messaging_send_buf(global_messaging_context(),
271                                            pid_to_procid(idmap_pid),
272                                            MSG_WINBIND_ONLINE,
273                                            (const uint8_t *)domain->name,
274                                            strlen(domain->name)+1);
275                 }
276         }
277
278         return;
279 }
280
281 /****************************************************************
282  Requested to set a domain online.
283 ****************************************************************/
284
285 void set_domain_online_request(struct winbindd_domain *domain)
286 {
287         NTSTATUS status;
288
289         SMB_ASSERT(wb_child_domain() || idmap_child());
290
291         DEBUG(10,("set_domain_online_request: called for domain %s\n",
292                 domain->name ));
293
294         if (get_global_winbindd_state_offline()) {
295                 DEBUG(10,("set_domain_online_request: domain %s remaining globally offline\n",
296                         domain->name ));
297                 return;
298         }
299
300         if (domain->internal) {
301                 DEBUG(10, ("set_domain_online_request: Internal domains are "
302                            "always online\n"));
303                 return;
304         }
305
306         /*
307          * This call takes care of setting the online flag to true if we
308          * connected, or tell the parent to ping us back if false. Bypasses
309          * online check so always does network calls.
310          */
311         status = init_dc_connection_network(domain, true);
312         DBG_DEBUG("init_dc_connection_network(), returned %s, called for "
313                   "domain %s (online = %s)\n",
314                   nt_errstr(status),
315                   domain->name,
316                   domain->online ? "true" : "false");
317 }
318
319 /****************************************************************
320  Add -ve connection cache entries for domain and realm.
321 ****************************************************************/
322
323 static void winbind_add_failed_connection_entry(
324         const struct winbindd_domain *domain,
325         const char *server,
326         NTSTATUS result)
327 {
328         add_failed_connection_entry(domain->name, server, result);
329         /* If this was the saf name for the last thing we talked to,
330            remove it. */
331         saf_delete(domain->name);
332         if (domain->alt_name != NULL) {
333                 add_failed_connection_entry(domain->alt_name, server, result);
334                 saf_delete(domain->alt_name);
335         }
336         winbindd_unset_locator_kdc_env(domain);
337 }
338
339 /* Choose between anonymous or authenticated connections.  We need to use
340    an authenticated connection if DCs have the RestrictAnonymous registry
341    entry set > 0, or the "Additional restrictions for anonymous
342    connections" set in the win2k Local Security Policy.
343
344    Caller to free() result in domain, username, password
345 */
346
347 static void cm_get_ipc_userpass(char **username, char **domain, char **password)
348 {
349         *username = (char *)secrets_fetch(SECRETS_AUTH_USER, NULL);
350         *domain = (char *)secrets_fetch(SECRETS_AUTH_DOMAIN, NULL);
351         *password = (char *)secrets_fetch(SECRETS_AUTH_PASSWORD, NULL);
352
353         if (*username && **username) {
354
355                 if (!*domain || !**domain)
356                         *domain = smb_xstrdup(lp_workgroup());
357
358                 if (!*password || !**password)
359                         *password = smb_xstrdup("");
360
361                 DEBUG(3, ("cm_get_ipc_userpass: Retrieved auth-user from secrets.tdb [%s\\%s]\n",
362                           *domain, *username));
363
364         } else {
365                 DEBUG(3, ("cm_get_ipc_userpass: No auth-user defined\n"));
366                 *username = smb_xstrdup("");
367                 *domain = smb_xstrdup("");
368                 *password = smb_xstrdup("");
369         }
370 }
371
372 static NTSTATUS cm_get_ipc_credentials(TALLOC_CTX *mem_ctx,
373                                        struct cli_credentials **_creds)
374 {
375
376         TALLOC_CTX *frame = talloc_stackframe();
377         NTSTATUS status = NT_STATUS_INTERNAL_ERROR;
378         struct loadparm_context *lp_ctx;
379         char *username = NULL;
380         char *netbios_domain = NULL;
381         char *password = NULL;
382         struct cli_credentials *creds = NULL;
383         bool ok;
384
385         cm_get_ipc_userpass(&username, &netbios_domain, &password);
386
387         lp_ctx = loadparm_init_s3(frame, loadparm_s3_helpers());
388         if (lp_ctx == NULL) {
389                 DEBUG(1, ("loadparm_init_s3 failed\n"));
390                 status = NT_STATUS_INTERNAL_ERROR;
391                 goto fail;
392         }
393
394         creds = cli_credentials_init(mem_ctx);
395         if (creds == NULL) {
396                 status = NT_STATUS_NO_MEMORY;
397                 goto fail;
398         }
399
400         ok = cli_credentials_set_conf(creds, lp_ctx);
401         if (!ok) {
402                 status = NT_STATUS_INTERNAL_ERROR;
403                 goto fail;
404         }
405
406         cli_credentials_set_kerberos_state(creds,
407                                            CRED_USE_KERBEROS_DISABLED,
408                                            CRED_SPECIFIED);
409
410         ok = cli_credentials_set_domain(creds, netbios_domain, CRED_SPECIFIED);
411         if (!ok) {
412                 status = NT_STATUS_NO_MEMORY;
413                 goto fail;
414         }
415
416         ok = cli_credentials_set_username(creds, username, CRED_SPECIFIED);
417         if (!ok) {
418                 status = NT_STATUS_NO_MEMORY;
419                 goto fail;
420         }
421
422         ok = cli_credentials_set_password(creds, password, CRED_SPECIFIED);
423         if (!ok) {
424                 status = NT_STATUS_NO_MEMORY;
425                 goto fail;
426         }
427
428         *_creds = creds;
429         creds = NULL;
430         status = NT_STATUS_OK;
431  fail:
432         TALLOC_FREE(creds);
433         SAFE_FREE(username);
434         SAFE_FREE(netbios_domain);
435         SAFE_FREE(password);
436         TALLOC_FREE(frame);
437         return status;
438 }
439
440 static bool cm_is_ipc_credentials(struct cli_credentials *creds)
441 {
442         TALLOC_CTX *frame = talloc_stackframe();
443         char *ipc_account = NULL;
444         char *ipc_domain = NULL;
445         char *ipc_password = NULL;
446         const char *creds_account = NULL;
447         const char *creds_domain = NULL;
448         const char *creds_password = NULL;
449         bool ret = false;
450
451         cm_get_ipc_userpass(&ipc_account, &ipc_domain, &ipc_password);
452
453         creds_account = cli_credentials_get_username(creds);
454         creds_domain = cli_credentials_get_domain(creds);
455         creds_password = cli_credentials_get_password(creds);
456
457         if (!strequal(ipc_domain, creds_domain)) {
458                 goto done;
459         }
460
461         if (!strequal(ipc_account, creds_account)) {
462                 goto done;
463         }
464
465         if (!strcsequal(ipc_password, creds_password)) {
466                 goto done;
467         }
468
469         ret = true;
470  done:
471         SAFE_FREE(ipc_account);
472         SAFE_FREE(ipc_domain);
473         SAFE_FREE(ipc_password);
474         TALLOC_FREE(frame);
475         return ret;
476 }
477
478 static bool get_dc_name_via_netlogon(struct winbindd_domain *domain,
479                                      fstring dcname,
480                                      struct sockaddr_storage *dc_ss,
481                                      uint32_t request_flags)
482 {
483         struct winbindd_domain *our_domain = NULL;
484         struct rpc_pipe_client *netlogon_pipe = NULL;
485         NTSTATUS result;
486         WERROR werr;
487         TALLOC_CTX *mem_ctx;
488         unsigned int orig_timeout;
489         const char *tmp = NULL;
490         const char *p;
491         struct dcerpc_binding_handle *b;
492
493         /* Hmmmm. We can only open one connection to the NETLOGON pipe at the
494          * moment.... */
495
496         if (IS_DC) {
497                 return False;
498         }
499
500         if (domain->primary) {
501                 return False;
502         }
503
504         our_domain = find_our_domain();
505
506         if ((mem_ctx = talloc_init("get_dc_name_via_netlogon")) == NULL) {
507                 return False;
508         }
509
510         result = cm_connect_netlogon(our_domain, &netlogon_pipe);
511         if (!NT_STATUS_IS_OK(result)) {
512                 talloc_destroy(mem_ctx);
513                 return False;
514         }
515
516         b = netlogon_pipe->binding_handle;
517
518         /* This call can take a long time - allow the server to time out.
519            35 seconds should do it. */
520
521         orig_timeout = rpccli_set_timeout(netlogon_pipe, 35000);
522
523         if (our_domain->active_directory) {
524                 struct netr_DsRGetDCNameInfo *domain_info = NULL;
525
526                 /*
527                  * TODO request flags are not respected in the server
528                  * (and in some cases, like REQUIRE_PDC, causes an error)
529                  */
530                 result = dcerpc_netr_DsRGetDCName(b,
531                                                   mem_ctx,
532                                                   our_domain->dcname,
533                                                   domain->name,
534                                                   NULL,
535                                                   NULL,
536                                                   request_flags|DS_RETURN_DNS_NAME,
537                                                   &domain_info,
538                                                   &werr);
539                 if (NT_STATUS_IS_OK(result) && W_ERROR_IS_OK(werr)) {
540                         tmp = talloc_strdup(
541                                 mem_ctx, domain_info->dc_unc);
542                         if (tmp == NULL) {
543                                 DEBUG(0, ("talloc_strdup failed\n"));
544                                 talloc_destroy(mem_ctx);
545                                 return false;
546                         }
547                         if (domain->alt_name == NULL) {
548                                 domain->alt_name = talloc_strdup(domain,
549                                                                  domain_info->domain_name);
550                                 if (domain->alt_name == NULL) {
551                                         DEBUG(0, ("talloc_strdup failed\n"));
552                                         talloc_destroy(mem_ctx);
553                                         return false;
554                                 }
555                         }
556                         if (domain->forest_name == NULL) {
557                                 domain->forest_name = talloc_strdup(domain,
558                                                                     domain_info->forest_name);
559                                 if (domain->forest_name == NULL) {
560                                         DEBUG(0, ("talloc_strdup failed\n"));
561                                         talloc_destroy(mem_ctx);
562                                         return false;
563                                 }
564                         }
565                 }
566         } else {
567                 result = dcerpc_netr_GetAnyDCName(b, mem_ctx,
568                                                   our_domain->dcname,
569                                                   domain->name,
570                                                   &tmp,
571                                                   &werr);
572         }
573
574         /* And restore our original timeout. */
575         rpccli_set_timeout(netlogon_pipe, orig_timeout);
576
577         if (!NT_STATUS_IS_OK(result)) {
578                 DEBUG(10,("dcerpc_netr_GetAnyDCName failed: %s\n",
579                         nt_errstr(result)));
580                 talloc_destroy(mem_ctx);
581                 return false;
582         }
583
584         if (!W_ERROR_IS_OK(werr)) {
585                 DEBUG(10,("dcerpc_netr_GetAnyDCName failed: %s\n",
586                            win_errstr(werr)));
587                 talloc_destroy(mem_ctx);
588                 return false;
589         }
590
591         /* dcerpc_netr_GetAnyDCName gives us a name with \\ */
592         p = strip_hostname(tmp);
593
594         fstrcpy(dcname, p);
595
596         talloc_destroy(mem_ctx);
597
598         DEBUG(10,("dcerpc_netr_GetAnyDCName returned %s\n", dcname));
599
600         if (!resolve_name(dcname, dc_ss, 0x20, true)) {
601                 return False;
602         }
603
604         return True;
605 }
606
607 /**
608  * Helper function to assemble trust password and account name
609  */
610 static NTSTATUS get_trust_credentials(struct winbindd_domain *domain,
611                                       TALLOC_CTX *mem_ctx,
612                                       bool netlogon,
613                                       struct cli_credentials **_creds)
614 {
615         const struct winbindd_domain *creds_domain = NULL;
616         struct cli_credentials *creds;
617         NTSTATUS status;
618         bool force_machine_account = false;
619
620         /* If we are a DC and this is not our own domain */
621
622         if (!domain->active_directory) {
623                 if (!netlogon) {
624                         /*
625                          * For non active directory domains
626                          * we can only use NTLMSSP for SMB.
627                          *
628                          * But the trust account is not allowed
629                          * to use SMB with NTLMSSP.
630                          */
631                         force_machine_account = true;
632                 }
633         }
634
635         if (IS_DC && !force_machine_account) {
636                 creds_domain = domain;
637         } else {
638                 creds_domain = find_our_domain();
639                 if (creds_domain == NULL) {
640                         return NT_STATUS_INVALID_SERVER_STATE;
641                 }
642         }
643
644         status = pdb_get_trust_credentials(creds_domain->name,
645                                            creds_domain->alt_name,
646                                            mem_ctx,
647                                            &creds);
648         if (!NT_STATUS_IS_OK(status)) {
649                 goto ipc_fallback;
650         }
651
652         if (creds_domain != domain) {
653                 /*
654                  * We can only use schannel against a direct trust
655                  */
656                 cli_credentials_set_secure_channel_type(creds,
657                                                         SEC_CHAN_NULL);
658         }
659
660         *_creds = creds;
661         return NT_STATUS_OK;
662
663  ipc_fallback:
664         if (netlogon) {
665                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
666         }
667
668         status = cm_get_ipc_credentials(mem_ctx, &creds);
669         if (!NT_STATUS_IS_OK(status)) {
670                 return status;
671         }
672
673         *_creds = creds;
674         return NT_STATUS_OK;
675 }
676
677 /************************************************************************
678  Given a fd with a just-connected TCP connection to a DC, open a connection
679  to the pipe.
680 ************************************************************************/
681
682 static NTSTATUS cm_prepare_connection(struct winbindd_domain *domain,
683                                       const int sockfd,
684                                       const char *controller,
685                                       struct cli_state **cli,
686                                       bool *retry)
687 {
688         bool try_ipc_auth = false;
689         const char *machine_principal = NULL;
690         const char *machine_realm = NULL;
691         const char *machine_account = NULL;
692         const char *machine_domain = NULL;
693         int flags = 0;
694         struct cli_credentials *creds = NULL;
695
696         struct named_mutex *mutex;
697
698         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
699         NTSTATUS tmp_status;
700         NTSTATUS tcon_status = NT_STATUS_NETWORK_NAME_DELETED;
701
702         enum smb_signing_setting smb_sign_client_connections = lp_client_ipc_signing();
703
704         if (IS_DC) {
705                 if (domain->secure_channel_type == SEC_CHAN_NULL) {
706                         /*
707                          * Make sure we don't even try to
708                          * connect to a foreign domain
709                          * without a direct outbound trust.
710                          */
711                         close(sockfd);
712                         return NT_STATUS_NO_TRUST_LSA_SECRET;
713                 }
714
715                 /*
716                  * As AD DC we only use netlogon and lsa
717                  * using schannel over an anonymous transport
718                  * (ncacn_ip_tcp or ncacn_np).
719                  *
720                  * Currently we always establish the SMB connection,
721                  * even if we don't use it, because we later use ncacn_ip_tcp.
722                  *
723                  * As we won't use the SMB connection there's no
724                  * need to try kerberos. And NT4 domains expect
725                  * an anonymous IPC$ connection anyway.
726                  */
727                 smb_sign_client_connections = SMB_SIGNING_OFF;
728         }
729
730         if (smb_sign_client_connections == SMB_SIGNING_DEFAULT) {
731                 /*
732                  * If we are connecting to our own AD domain, require
733                  * smb signing to disrupt MITM attacks
734                  */
735                 if (domain->primary && lp_security() == SEC_ADS) {
736                         smb_sign_client_connections = SMB_SIGNING_REQUIRED;
737                 /*
738                  * If we are in or are an AD domain and connecting to another
739                  * AD domain in our forest
740                  * then require smb signing to disrupt MITM attacks
741                  */
742                 } else if ((lp_security() == SEC_ADS)
743                            && domain->active_directory
744                            && (domain->domain_trust_attribs
745                                & LSA_TRUST_ATTRIBUTE_WITHIN_FOREST)) {
746                         smb_sign_client_connections = SMB_SIGNING_REQUIRED;
747                 }
748         }
749
750         DEBUG(10,("cm_prepare_connection: connecting to DC %s for domain %s\n",
751                 controller, domain->name ));
752
753         *retry = True;
754
755         mutex = grab_named_mutex(talloc_tos(), controller,
756                                  WINBIND_SERVER_MUTEX_WAIT_TIME);
757         if (mutex == NULL) {
758                 close(sockfd);
759                 DEBUG(0,("cm_prepare_connection: mutex grab failed for %s\n",
760                          controller));
761                 result = NT_STATUS_POSSIBLE_DEADLOCK;
762                 goto done;
763         }
764
765         /*
766          * cm_prepare_connection() is responsible that sockfd does not leak.
767          * Once cli_state_create() returns with success, the
768          * smbXcli_conn_destructor() makes sure that close(sockfd) is finally
769          * called. Till that, close(sockfd) must be called on every unsuccessful
770          * return.
771          */
772         *cli = cli_state_create(NULL, sockfd, controller,
773                                 smb_sign_client_connections, flags);
774         if (*cli == NULL) {
775                 close(sockfd);
776                 DEBUG(1, ("Could not cli_initialize\n"));
777                 result = NT_STATUS_NO_MEMORY;
778                 goto done;
779         }
780
781         cli_set_timeout(*cli, 10000); /* 10 seconds */
782
783         set_socket_options(sockfd, lp_socket_options());
784
785         result = smbXcli_negprot((*cli)->conn,
786                                  (*cli)->timeout,
787                                  lp_client_ipc_min_protocol(),
788                                  lp_client_ipc_max_protocol(),
789                                  NULL,
790                                  NULL,
791                                  NULL);
792
793         if (!NT_STATUS_IS_OK(result)) {
794                 DEBUG(1, ("cli_negprot failed: %s\n", nt_errstr(result)));
795                 goto done;
796         }
797
798         if (smbXcli_conn_protocol((*cli)->conn) >= PROTOCOL_NT1 &&
799             smb1cli_conn_capabilities((*cli)->conn) & CAP_EXTENDED_SECURITY) {
800                 try_ipc_auth = true;
801         } else if (smbXcli_conn_protocol((*cli)->conn) >= PROTOCOL_SMB2_02) {
802                 try_ipc_auth = true;
803         } else if (smb_sign_client_connections == SMB_SIGNING_REQUIRED) {
804                 /*
805                  * If we are forcing on SMB signing, then we must
806                  * require authentication unless this is a one-way
807                  * trust, and we have no stored user/password
808                  */
809                 try_ipc_auth = true;
810         }
811
812         if (IS_DC) {
813                 /*
814                  * As AD DC we only use netlogon and lsa
815                  * using schannel over an anonymous transport
816                  * (ncacn_ip_tcp or ncacn_np).
817                  *
818                  * Currently we always establish the SMB connection,
819                  * even if we don't use it, because we later use ncacn_ip_tcp.
820                  *
821                  * As we won't use the SMB connection there's no
822                  * need to try kerberos. And NT4 domains expect
823                  * an anonymous IPC$ connection anyway.
824                  */
825                 try_ipc_auth = false;
826         }
827
828         if (try_ipc_auth) {
829                 result = get_trust_credentials(domain, talloc_tos(), false, &creds);
830                 if (!NT_STATUS_IS_OK(result)) {
831                         DEBUG(1, ("get_trust_credentials(%s) failed: %s\n",
832                                   domain->name, nt_errstr(result)));
833                         goto done;
834                 }
835         } else {
836                 /*
837                  * Without SPNEGO or NTLMSSP (perhaps via SMB2) we
838                  * would try and authentication with our machine
839                  * account password and fail.  This is very rare in
840                  * the modern world however
841                  */
842                 creds = cli_credentials_init_anon(talloc_tos());
843                 if (creds == NULL) {
844                         result = NT_STATUS_NO_MEMORY;
845                         DEBUG(1, ("cli_credentials_init_anon(%s) failed: %s\n",
846                                   domain->name, nt_errstr(result)));
847                         goto done;
848                 }
849         }
850
851         machine_principal = cli_credentials_get_principal(creds,
852                                                         talloc_tos());
853         machine_realm = cli_credentials_get_realm(creds);
854         machine_account = cli_credentials_get_username(creds);
855         machine_domain = cli_credentials_get_domain(creds);
856
857         DEBUG(5, ("connecting to %s (%s, %s) with account [%s\\%s] principal "
858                   "[%s] and realm [%s]\n",
859                   controller, domain->name, domain->alt_name,
860                   machine_domain, machine_account,
861                   machine_principal, machine_realm));
862
863         if (cli_credentials_is_anonymous(creds)) {
864                 goto anon_fallback;
865         }
866
867         winbindd_set_locator_kdc_envs(domain);
868
869         result = cli_session_setup_creds(*cli, creds);
870         if (NT_STATUS_IS_OK(result)) {
871                 goto session_setup_done;
872         }
873
874         DEBUG(1, ("authenticated session setup to %s using %s failed with %s\n",
875                   controller,
876                   cli_credentials_get_unparsed_name(creds, talloc_tos()),
877                   nt_errstr(result)));
878
879         /*
880          * If we are not going to validate the connection
881          * with SMB signing, then allow us to fall back to
882          * anonymous
883          */
884         if (NT_STATUS_EQUAL(result, NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT)
885             || NT_STATUS_EQUAL(result, NT_STATUS_TRUSTED_DOMAIN_FAILURE)
886             || NT_STATUS_EQUAL(result, NT_STATUS_INVALID_ACCOUNT_NAME)
887             || NT_STATUS_EQUAL(result, NT_STATUS_INVALID_COMPUTER_NAME)
888             || NT_STATUS_EQUAL(result, NT_STATUS_NO_SUCH_DOMAIN)
889             || NT_STATUS_EQUAL(result, NT_STATUS_NO_LOGON_SERVERS)
890             || NT_STATUS_EQUAL(result, NT_STATUS_LOGON_FAILURE))
891         {
892                 if (!cm_is_ipc_credentials(creds)) {
893                         goto ipc_fallback;
894                 }
895
896                 if (smb_sign_client_connections == SMB_SIGNING_REQUIRED) {
897                         goto done;
898                 }
899
900                 goto anon_fallback;
901         }
902
903         goto done;
904
905  ipc_fallback:
906         TALLOC_FREE(creds);
907         tmp_status = cm_get_ipc_credentials(talloc_tos(), &creds);
908         if (!NT_STATUS_IS_OK(tmp_status)) {
909                 result = tmp_status;
910                 goto done;
911         }
912
913         if (cli_credentials_is_anonymous(creds)) {
914                 goto anon_fallback;
915         }
916
917         machine_account = cli_credentials_get_username(creds);
918         machine_domain = cli_credentials_get_domain(creds);
919
920         DEBUG(5, ("connecting to %s from %s using NTLMSSP with username "
921                   "[%s]\\[%s]\n",  controller, lp_netbios_name(),
922                   machine_domain, machine_account));
923
924         result = cli_session_setup_creds(*cli, creds);
925         if (NT_STATUS_IS_OK(result)) {
926                 goto session_setup_done;
927         }
928
929         DEBUG(1, ("authenticated session setup to %s using %s failed with %s\n",
930                   controller,
931                   cli_credentials_get_unparsed_name(creds, talloc_tos()),
932                   nt_errstr(result)));
933
934         /*
935          * If we are not going to validate the connection
936          * with SMB signing, then allow us to fall back to
937          * anonymous
938          */
939         if (NT_STATUS_EQUAL(result, NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT)
940             || NT_STATUS_EQUAL(result, NT_STATUS_TRUSTED_DOMAIN_FAILURE)
941             || NT_STATUS_EQUAL(result, NT_STATUS_INVALID_ACCOUNT_NAME)
942             || NT_STATUS_EQUAL(result, NT_STATUS_INVALID_COMPUTER_NAME)
943             || NT_STATUS_EQUAL(result, NT_STATUS_NO_SUCH_DOMAIN)
944             || NT_STATUS_EQUAL(result, NT_STATUS_NO_LOGON_SERVERS)
945             || NT_STATUS_EQUAL(result, NT_STATUS_LOGON_FAILURE))
946         {
947                 goto anon_fallback;
948         }
949
950         goto done;
951
952  anon_fallback:
953         TALLOC_FREE(creds);
954
955         if (smb_sign_client_connections == SMB_SIGNING_REQUIRED) {
956                 goto done;
957         }
958
959         /* Fall back to anonymous connection, this might fail later */
960         DEBUG(5,("cm_prepare_connection: falling back to anonymous "
961                 "connection for DC %s\n",
962                 controller ));
963
964         result = cli_session_setup_anon(*cli);
965         if (NT_STATUS_IS_OK(result)) {
966                 DEBUG(5, ("Connected anonymously\n"));
967                 goto session_setup_done;
968         }
969
970         DEBUG(1, ("anonymous session setup to %s failed with %s\n",
971                   controller, nt_errstr(result)));
972
973         /* We can't session setup */
974         goto done;
975
976  session_setup_done:
977         TALLOC_FREE(creds);
978
979         /*
980          * This should be a short term hack until
981          * dynamic re-authentication is implemented.
982          *
983          * See Bug 9175 - winbindd doesn't recover from
984          * NT_STATUS_NETWORK_SESSION_EXPIRED
985          */
986         if (smbXcli_conn_protocol((*cli)->conn) >= PROTOCOL_SMB2_02) {
987                 smbXcli_session_set_disconnect_expired((*cli)->smb2.session);
988         }
989
990         result = cli_tree_connect(*cli, "IPC$", "IPC", NULL);
991         if (!NT_STATUS_IS_OK(result)) {
992                 DEBUG(1,("failed tcon_X with %s\n", nt_errstr(result)));
993                 goto done;
994         }
995         tcon_status = result;
996
997         /* cache the server name for later connections */
998
999         saf_store(domain->name, controller);
1000         if (domain->alt_name) {
1001                 saf_store(domain->alt_name, controller);
1002         }
1003
1004         winbindd_set_locator_kdc_envs(domain);
1005
1006         TALLOC_FREE(mutex);
1007         *retry = False;
1008
1009         result = NT_STATUS_OK;
1010
1011  done:
1012         TALLOC_FREE(mutex);
1013         TALLOC_FREE(creds);
1014
1015         if (NT_STATUS_IS_OK(result)) {
1016                 result = tcon_status;
1017         }
1018
1019         if (!NT_STATUS_IS_OK(result)) {
1020                 DEBUG(1, ("Failed to prepare SMB connection to %s: %s\n",
1021                           controller, nt_errstr(result)));
1022                 winbind_add_failed_connection_entry(domain, controller, result);
1023                 if ((*cli) != NULL) {
1024                         cli_shutdown(*cli);
1025                         *cli = NULL;
1026                 }
1027         }
1028
1029         return result;
1030 }
1031
1032 /*******************************************************************
1033  Add a dcname and sockaddr_storage pair to the end of a dc_name_ip
1034  array.
1035
1036  Keeps the list unique by not adding duplicate entries.
1037
1038  @param[in] mem_ctx talloc memory context to allocate from
1039  @param[in] domain_name domain of the DC
1040  @param[in] dcname name of the DC to add to the list
1041  @param[in] pss Internet address and port pair to add to the list
1042  @param[in,out] dcs array of dc_name_ip structures to add to
1043  @param[in,out] num_dcs number of dcs returned in the dcs array
1044  @return true if the list was added to, false otherwise
1045 *******************************************************************/
1046
1047 static bool add_one_dc_unique(TALLOC_CTX *mem_ctx, const char *domain_name,
1048                               const char *dcname, struct sockaddr_storage *pss,
1049                               struct dc_name_ip **dcs, int *num)
1050 {
1051         int i = 0;
1052
1053         if (!NT_STATUS_IS_OK(check_negative_conn_cache(domain_name, dcname))) {
1054                 DEBUG(10, ("DC %s was in the negative conn cache\n", dcname));
1055                 return False;
1056         }
1057
1058         /* Make sure there's no duplicates in the list */
1059         for (i=0; i<*num; i++)
1060                 if (sockaddr_equal(
1061                             (struct sockaddr *)(void *)&(*dcs)[i].ss,
1062                             (struct sockaddr *)(void *)pss))
1063                         return False;
1064
1065         *dcs = talloc_realloc(mem_ctx, *dcs, struct dc_name_ip, (*num)+1);
1066
1067         if (*dcs == NULL)
1068                 return False;
1069
1070         fstrcpy((*dcs)[*num].name, dcname);
1071         (*dcs)[*num].ss = *pss;
1072         *num += 1;
1073         return True;
1074 }
1075
1076 static bool add_sockaddr_to_array(TALLOC_CTX *mem_ctx,
1077                                   struct sockaddr_storage *pss, uint16_t port,
1078                                   struct sockaddr_storage **addrs, int *num)
1079 {
1080         *addrs = talloc_realloc(mem_ctx, *addrs, struct sockaddr_storage, (*num)+1);
1081
1082         if (*addrs == NULL) {
1083                 *num = 0;
1084                 return False;
1085         }
1086
1087         (*addrs)[*num] = *pss;
1088         set_sockaddr_port((struct sockaddr *)&(*addrs)[*num], port);
1089
1090         *num += 1;
1091         return True;
1092 }
1093
1094 #ifdef HAVE_ADS
1095 static bool dcip_check_name_ads(const struct winbindd_domain *domain,
1096                                 struct samba_sockaddr *sa,
1097                                 uint32_t request_flags,
1098                                 TALLOC_CTX *mem_ctx,
1099                                 char **namep)
1100 {
1101         TALLOC_CTX *tmp_ctx = talloc_stackframe();
1102         char *name = NULL;
1103         ADS_STRUCT *ads = NULL;
1104         ADS_STATUS ads_status;
1105         char addr[INET6_ADDRSTRLEN];
1106
1107         print_sockaddr(addr, sizeof(addr), &sa->u.ss);
1108         D_DEBUG("Trying to figure out the DC name for domain '%s' at IP '%s'.\n",
1109                 domain->name,
1110                 addr);
1111
1112         ads = ads_init(tmp_ctx,
1113                        domain->alt_name,
1114                        domain->name,
1115                        addr,
1116                        ADS_SASL_PLAIN);
1117         if (ads == NULL) {
1118                 ads_status = ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
1119                 goto out;
1120         }
1121         ads->auth.flags |= ADS_AUTH_NO_BIND;
1122         ads->config.flags |= request_flags;
1123         ads->server.no_fallback = true;
1124
1125         ads_status = ads_connect(ads);
1126         if (!ADS_ERR_OK(ads_status)) {
1127                 goto out;
1128         }
1129
1130         /* We got a cldap packet. */
1131         name = talloc_strdup(tmp_ctx, ads->config.ldap_server_name);
1132         if (name == NULL) {
1133                 ads_status = ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
1134                 goto out;
1135         }
1136         namecache_store(name, 0x20, 1, sa);
1137
1138         DBG_DEBUG("CLDAP flags = 0x%"PRIx32"\n", ads->config.flags);
1139
1140         if (domain->primary && (ads->config.flags & NBT_SERVER_KDC)) {
1141                 if (ads_closest_dc(ads)) {
1142                         char *sitename = sitename_fetch(tmp_ctx,
1143                                                         ads->config.realm);
1144
1145                         /* We're going to use this KDC for this realm/domain.
1146                            If we are using sites, then force the krb5 libs
1147                            to use this KDC. */
1148
1149                         create_local_private_krb5_conf_for_domain(domain->alt_name,
1150                                                         domain->name,
1151                                                         sitename,
1152                                                         &sa->u.ss);
1153
1154                         TALLOC_FREE(sitename);
1155                 } else {
1156                         /* use an off site KDC */
1157                         create_local_private_krb5_conf_for_domain(domain->alt_name,
1158                                                         domain->name,
1159                                                         NULL,
1160                                                         &sa->u.ss);
1161                 }
1162                 winbindd_set_locator_kdc_envs(domain);
1163
1164                 /* Ensure we contact this DC also. */
1165                 saf_store(domain->name, name);
1166                 saf_store(domain->alt_name, name);
1167         }
1168
1169         D_DEBUG("DC name for domain '%s' at IP '%s' is '%s'\n",
1170                 domain->name,
1171                 addr,
1172                 name);
1173         *namep = talloc_move(mem_ctx, &name);
1174
1175 out:
1176         TALLOC_FREE(tmp_ctx);
1177
1178         return ADS_ERR_OK(ads_status) ? true : false;
1179 }
1180 #endif
1181
1182 /*******************************************************************
1183  convert an ip to a name
1184  For an AD Domain, it checks the requirements of the request flags.
1185 *******************************************************************/
1186
1187 static bool dcip_check_name(TALLOC_CTX *mem_ctx,
1188                             const struct winbindd_domain *domain,
1189                             struct sockaddr_storage *pss,
1190                             char **name, uint32_t request_flags)
1191 {
1192         struct samba_sockaddr sa = {0};
1193         uint32_t nt_version = NETLOGON_NT_VERSION_1;
1194         NTSTATUS status;
1195         const char *dc_name;
1196         fstring nbtname;
1197 #ifdef HAVE_ADS
1198         bool is_ad_domain = false;
1199 #endif
1200         bool ok = sockaddr_storage_to_samba_sockaddr(&sa, pss);
1201         if (!ok) {
1202                 return false;
1203         }
1204
1205 #ifdef HAVE_ADS
1206         /* For active directory servers, try to get the ldap server name.
1207            None of these failures should be considered critical for now */
1208
1209         if ((lp_security() == SEC_ADS) && (domain->alt_name != NULL)) {
1210                 is_ad_domain = true;
1211         } else if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
1212                 is_ad_domain = domain->active_directory;
1213         }
1214
1215         if (is_ad_domain) {
1216                 return dcip_check_name_ads(domain,
1217                                            &sa,
1218                                            request_flags,
1219                                            mem_ctx,
1220                                            name);
1221         }
1222 #endif
1223
1224         {
1225                 size_t len = strlen(lp_netbios_name());
1226                 char my_acct_name[len+2];
1227
1228                 snprintf(my_acct_name,
1229                          sizeof(my_acct_name),
1230                          "%s$",
1231                          lp_netbios_name());
1232
1233                 status = nbt_getdc(global_messaging_context(), 10, &sa.u.ss,
1234                                    domain->name, &domain->sid,
1235                                    my_acct_name, ACB_WSTRUST,
1236                                    nt_version, mem_ctx, &nt_version,
1237                                    &dc_name, NULL);
1238         }
1239         if (NT_STATUS_IS_OK(status)) {
1240                 *name = talloc_strdup(mem_ctx, dc_name);
1241                 if (*name == NULL) {
1242                         return false;
1243                 }
1244                 namecache_store(*name, 0x20, 1, &sa);
1245                 return True;
1246         }
1247
1248         /* try node status request */
1249
1250         if (name_status_find(domain->name, 0x1c, 0x20, &sa.u.ss, nbtname) ) {
1251                 namecache_store(nbtname, 0x20, 1, &sa);
1252
1253                 if (name != NULL) {
1254                         *name = talloc_strdup(mem_ctx, nbtname);
1255                         if (*name == NULL) {
1256                                 return false;
1257                         }
1258                 }
1259
1260                 return true;
1261         }
1262         return False;
1263 }
1264
1265 /*******************************************************************
1266  Retrieve a list of IP addresses for domain controllers.
1267
1268  The array is sorted in the preferred connection order.
1269
1270  @param[in] mem_ctx talloc memory context to allocate from
1271  @param[in] domain domain to retrieve DCs for
1272  @param[out] dcs array of dcs that will be returned
1273  @param[out] num_dcs number of dcs returned in the dcs array
1274  @return always true
1275 *******************************************************************/
1276
1277 static bool get_dcs(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain,
1278                     struct dc_name_ip **dcs, int *num_dcs,
1279                     uint32_t request_flags)
1280 {
1281         fstring dcname;
1282         struct  sockaddr_storage ss;
1283         struct  samba_sockaddr *sa_list = NULL;
1284         size_t     salist_size = 0;
1285         size_t     i;
1286         bool    is_our_domain;
1287         enum security_types sec = (enum security_types)lp_security();
1288
1289         is_our_domain = strequal(domain->name, lp_workgroup());
1290
1291         /* If not our domain, get the preferred DC, by asking our primary DC */
1292         if ( !is_our_domain
1293                 && get_dc_name_via_netlogon(domain, dcname, &ss, request_flags)
1294                 && add_one_dc_unique(mem_ctx, domain->name, dcname, &ss, dcs,
1295                        num_dcs) )
1296         {
1297                 char addr[INET6_ADDRSTRLEN];
1298                 print_sockaddr(addr, sizeof(addr), &ss);
1299                 DEBUG(10, ("Retrieved DC %s at %s via netlogon\n",
1300                            dcname, addr));
1301                 return True;
1302         }
1303
1304         if ((sec == SEC_ADS) && (domain->alt_name != NULL)) {
1305                 char *sitename = NULL;
1306
1307                 /* We need to make sure we know the local site before
1308                    doing any DNS queries, as this will restrict the
1309                    get_sorted_dc_list() call below to only fetching
1310                    DNS records for the correct site. */
1311
1312                 /* Find any DC to get the site record.
1313                    We deliberately don't care about the
1314                    return here. */
1315
1316                 get_dc_name(domain->name, domain->alt_name, dcname, &ss);
1317
1318                 sitename = sitename_fetch(mem_ctx, domain->alt_name);
1319                 if (sitename) {
1320
1321                         /* Do the site-specific AD dns lookup first. */
1322                         (void)get_sorted_dc_list(mem_ctx,
1323                                         domain->alt_name,
1324                                         sitename,
1325                                         &sa_list,
1326                                         &salist_size,
1327                                         true);
1328
1329                         /* Add ips to the DC array.  We don't look up the name
1330                            of the DC in this function, but we fill in the char*
1331                            of the ip now to make the failed connection cache
1332                            work */
1333                         for ( i=0; i<salist_size; i++ ) {
1334                                 char addr[INET6_ADDRSTRLEN];
1335                                 print_sockaddr(addr, sizeof(addr),
1336                                                 &sa_list[i].u.ss);
1337                                 add_one_dc_unique(mem_ctx,
1338                                                 domain->name,
1339                                                 addr,
1340                                                 &sa_list[i].u.ss,
1341                                                 dcs,
1342                                                 num_dcs);
1343                         }
1344
1345                         TALLOC_FREE(sa_list);
1346                         TALLOC_FREE(sitename);
1347                         salist_size = 0;
1348                 }
1349
1350                 /* Now we add DCs from the main AD DNS lookup. */
1351                 (void)get_sorted_dc_list(mem_ctx,
1352                                 domain->alt_name,
1353                                 NULL,
1354                                 &sa_list,
1355                                 &salist_size,
1356                                 true);
1357
1358                 for ( i=0; i<salist_size; i++ ) {
1359                         char addr[INET6_ADDRSTRLEN];
1360                         print_sockaddr(addr, sizeof(addr),
1361                                         &sa_list[i].u.ss);
1362                         add_one_dc_unique(mem_ctx,
1363                                         domain->name,
1364                                         addr,
1365                                         &sa_list[i].u.ss,
1366                                         dcs,
1367                                         num_dcs);
1368                 }
1369
1370                 TALLOC_FREE(sa_list);
1371                 salist_size = 0;
1372         }
1373
1374         /* Try standard netbios queries if no ADS and fall back to DNS queries
1375          * if alt_name is available */
1376         if (*num_dcs == 0) {
1377                 (void)get_sorted_dc_list(mem_ctx,
1378                                         domain->name,
1379                                         NULL,
1380                                         &sa_list,
1381                                         &salist_size,
1382                                         false);
1383                 if (salist_size == 0) {
1384                         if (domain->alt_name != NULL) {
1385                                 (void)get_sorted_dc_list(mem_ctx,
1386                                                 domain->alt_name,
1387                                                 NULL,
1388                                                 &sa_list,
1389                                                 &salist_size,
1390                                                 true);
1391                         }
1392                 }
1393
1394                 for ( i=0; i<salist_size; i++ ) {
1395                         char addr[INET6_ADDRSTRLEN];
1396                         print_sockaddr(addr, sizeof(addr),
1397                                         &sa_list[i].u.ss);
1398                         add_one_dc_unique(mem_ctx,
1399                                         domain->name,
1400                                         addr,
1401                                         &sa_list[i].u.ss,
1402                                         dcs,
1403                                         num_dcs);
1404                 }
1405
1406                 TALLOC_FREE(sa_list);
1407                 salist_size = 0;
1408         }
1409
1410         return True;
1411 }
1412
1413 static bool connect_preferred_dc(TALLOC_CTX *mem_ctx,
1414                                  struct winbindd_domain *domain,
1415                                  uint32_t request_flags,
1416                                  int *fd)
1417 {
1418         char *saf_servername = NULL;
1419         NTSTATUS status;
1420         bool ok;
1421
1422         /*
1423          * We have to check the server affinity cache here since later we select
1424          * a DC based on response time and not preference.
1425          */
1426         if (domain->force_dc) {
1427                 saf_servername = domain->dcname;
1428         } else {
1429                 saf_servername = saf_fetch(mem_ctx, domain->name);
1430         }
1431
1432         /*
1433          * Check the negative connection cache before talking to it. It going
1434          * down may have triggered the reconnection.
1435          */
1436         if (saf_servername != NULL) {
1437                 status = check_negative_conn_cache(domain->name,
1438                                                    saf_servername);
1439                 if (!NT_STATUS_IS_OK(status)) {
1440                         saf_servername = NULL;
1441                 }
1442         }
1443
1444         if (saf_servername != NULL) {
1445                 DBG_DEBUG("saf_servername is '%s' for domain %s\n",
1446                           saf_servername, domain->name);
1447
1448                 /* convert an ip address to a name */
1449                 if (is_ipaddress(saf_servername)) {
1450                         ok = interpret_string_addr(&domain->dcaddr,
1451                                                    saf_servername,
1452                                                    AI_NUMERICHOST);
1453                         if (!ok) {
1454                                 return false;
1455                         }
1456                 } else {
1457                         ok = resolve_name(saf_servername,
1458                                           &domain->dcaddr,
1459                                           0x20,
1460                                           true);
1461                         if (!ok) {
1462                                 goto fail;
1463                         }
1464                 }
1465
1466                 TALLOC_FREE(domain->dcname);
1467                 ok = dcip_check_name(domain,
1468                                      domain,
1469                                      &domain->dcaddr,
1470                                      &domain->dcname,
1471                                      request_flags);
1472                 if (!ok) {
1473                         goto fail;
1474                 }
1475         }
1476
1477         if (domain->dcname == NULL) {
1478                 return false;
1479         }
1480
1481         status = check_negative_conn_cache(domain->name, domain->dcname);
1482         if (!NT_STATUS_IS_OK(status)) {
1483                 return false;
1484         }
1485
1486         status = smbsock_connect(&domain->dcaddr, 0,
1487                                  NULL, -1, NULL, -1,
1488                                  fd, NULL, 10);
1489         if (!NT_STATUS_IS_OK(status)) {
1490                 winbind_add_failed_connection_entry(domain,
1491                                                     domain->dcname,
1492                                                     NT_STATUS_UNSUCCESSFUL);
1493                 return false;
1494         }
1495         return true;
1496
1497 fail:
1498         winbind_add_failed_connection_entry(domain,
1499                                             saf_servername,
1500                                             NT_STATUS_UNSUCCESSFUL);
1501         return false;
1502
1503 }
1504
1505 /*******************************************************************
1506  Find and make a connection to a DC in the given domain.
1507
1508  @param[in] mem_ctx talloc memory context to allocate from
1509  @param[in] domain domain to find a dc in
1510  @param[out] fd fd of the open socket connected to the newly found dc
1511  @return true when a DC connection is made, false otherwise
1512 *******************************************************************/
1513
1514 static bool find_dc(TALLOC_CTX *mem_ctx,
1515                     struct winbindd_domain *domain,
1516                     uint32_t request_flags,
1517                     int *fd)
1518 {
1519         struct dc_name_ip *dcs = NULL;
1520         int num_dcs = 0;
1521
1522         const char **dcnames = NULL;
1523         size_t num_dcnames = 0;
1524
1525         struct sockaddr_storage *addrs = NULL;
1526         int num_addrs = 0;
1527
1528         int i;
1529         size_t fd_index;
1530
1531         NTSTATUS status;
1532         bool ok;
1533
1534         *fd = -1;
1535
1536         D_NOTICE("First try to connect to the closest DC (using server "
1537                  "affinity cache). If this fails, try to lookup the DC using "
1538                  "DNS afterwards.\n");
1539         ok = connect_preferred_dc(mem_ctx, domain, request_flags, fd);
1540         if (ok) {
1541                 return true;
1542         }
1543
1544         if (domain->force_dc) {
1545                 return false;
1546         }
1547
1548  again:
1549         D_DEBUG("Retrieving a list of IP addresses for DCs.\n");
1550         if (!get_dcs(mem_ctx, domain, &dcs, &num_dcs, request_flags) || (num_dcs == 0))
1551                 return False;
1552
1553         D_DEBUG("Retrieved IP addresses for %d DCs.\n", num_dcs);
1554         for (i=0; i<num_dcs; i++) {
1555
1556                 if (!add_string_to_array(mem_ctx, dcs[i].name,
1557                                     &dcnames, &num_dcnames)) {
1558                         return False;
1559                 }
1560                 if (!add_sockaddr_to_array(mem_ctx, &dcs[i].ss, TCP_SMB_PORT,
1561                                       &addrs, &num_addrs)) {
1562                         return False;
1563                 }
1564         }
1565
1566         if ((num_dcnames == 0) || (num_dcnames != num_addrs))
1567                 return False;
1568
1569         if ((addrs == NULL) || (dcnames == NULL))
1570                 return False;
1571
1572         D_DEBUG("Trying to establish a connection to one of the %d DCs "
1573                 "(timeout of 10 sec for each DC).\n",
1574                 num_dcs);
1575         status = smbsock_any_connect(addrs, dcnames, NULL, NULL, NULL,
1576                                      num_addrs, 0, 10, fd, &fd_index, NULL);
1577         if (!NT_STATUS_IS_OK(status)) {
1578                 for (i=0; i<num_dcs; i++) {
1579                         char ab[INET6_ADDRSTRLEN];
1580                         print_sockaddr(ab, sizeof(ab), &dcs[i].ss);
1581                         DBG_DEBUG("smbsock_any_connect failed for "
1582                                 "domain %s address %s. Error was %s\n",
1583                                    domain->name, ab, nt_errstr(status));
1584                         winbind_add_failed_connection_entry(domain,
1585                                 dcs[i].name, NT_STATUS_UNSUCCESSFUL);
1586                 }
1587                 return False;
1588         }
1589         D_NOTICE("Successfully connected to DC '%s'.\n", dcs[fd_index].name);
1590
1591         domain->dcaddr = addrs[fd_index];
1592
1593         if (*dcnames[fd_index] != '\0' && !is_ipaddress(dcnames[fd_index])) {
1594                 /* Ok, we've got a name for the DC */
1595                 TALLOC_FREE(domain->dcname);
1596                 domain->dcname = talloc_strdup(domain, dcnames[fd_index]);
1597                 if (domain->dcname == NULL) {
1598                         return false;
1599                 }
1600                 return true;
1601         }
1602
1603         /* Try to figure out the name */
1604         TALLOC_FREE(domain->dcname);
1605         ok = dcip_check_name(domain,
1606                              domain,
1607                              &domain->dcaddr,
1608                              &domain->dcname,
1609                              request_flags);
1610         if (ok) {
1611                 return true;
1612         }
1613
1614         /* We can not continue without the DC's name */
1615         winbind_add_failed_connection_entry(domain, dcs[fd_index].name,
1616                                     NT_STATUS_UNSUCCESSFUL);
1617
1618         /* Throw away all arrays as we're doing this again. */
1619         TALLOC_FREE(dcs);
1620         num_dcs = 0;
1621
1622         TALLOC_FREE(dcnames);
1623         num_dcnames = 0;
1624
1625         TALLOC_FREE(addrs);
1626         num_addrs = 0;
1627
1628         if (*fd != -1) {
1629                 close(*fd);
1630                 *fd = -1;
1631         }
1632
1633         /*
1634          * This should not be an infinite loop, since get_dcs() will not return
1635          * the DC added to the negative connection cache in the above
1636          * winbind_add_failed_connection_entry() call.
1637          */
1638         goto again;
1639 }
1640
1641 static char *current_dc_key(TALLOC_CTX *mem_ctx, const char *domain_name)
1642 {
1643         return talloc_asprintf_strupper_m(mem_ctx, "CURRENT_DCNAME/%s",
1644                                           domain_name);
1645 }
1646
1647 static void store_current_dc_in_gencache(const char *domain_name,
1648                                          const char *dc_name,
1649                                          struct cli_state *cli)
1650 {
1651         char addr[INET6_ADDRSTRLEN];
1652         char *key = NULL;
1653         char *value = NULL;
1654
1655         if (!cli_state_is_connected(cli)) {
1656                 return;
1657         }
1658
1659         print_sockaddr(addr, sizeof(addr),
1660                        smbXcli_conn_remote_sockaddr(cli->conn));
1661
1662         key = current_dc_key(talloc_tos(), domain_name);
1663         if (key == NULL) {
1664                 goto done;
1665         }
1666
1667         value = talloc_asprintf(talloc_tos(), "%s %s", addr, dc_name);
1668         if (value == NULL) {
1669                 goto done;
1670         }
1671
1672         gencache_set(key, value, 0x7fffffff);
1673 done:
1674         TALLOC_FREE(value);
1675         TALLOC_FREE(key);
1676 }
1677
1678 bool fetch_current_dc_from_gencache(TALLOC_CTX *mem_ctx,
1679                                     const char *domain_name,
1680                                     char **p_dc_name, char **p_dc_ip)
1681 {
1682         char *key, *p;
1683         char *value = NULL;
1684         bool ret = false;
1685         char *dc_name = NULL;
1686         char *dc_ip = NULL;
1687
1688         key = current_dc_key(talloc_tos(), domain_name);
1689         if (key == NULL) {
1690                 goto done;
1691         }
1692         if (!gencache_get(key, mem_ctx, &value, NULL)) {
1693                 goto done;
1694         }
1695         p = strchr(value, ' ');
1696         if (p == NULL) {
1697                 goto done;
1698         }
1699         dc_ip = talloc_strndup(mem_ctx, value, p - value);
1700         if (dc_ip == NULL) {
1701                 goto done;
1702         }
1703         dc_name = talloc_strdup(mem_ctx, p+1);
1704         if (dc_name == NULL) {
1705                 goto done;
1706         }
1707
1708         if (p_dc_ip != NULL) {
1709                 *p_dc_ip = dc_ip;
1710                 dc_ip = NULL;
1711         }
1712         if (p_dc_name != NULL) {
1713                 *p_dc_name = dc_name;
1714                 dc_name = NULL;
1715         }
1716         ret = true;
1717 done:
1718         TALLOC_FREE(dc_name);
1719         TALLOC_FREE(dc_ip);
1720         TALLOC_FREE(key);
1721         TALLOC_FREE(value);
1722         return ret;
1723 }
1724
1725 NTSTATUS wb_open_internal_pipe(TALLOC_CTX *mem_ctx,
1726                                const struct ndr_interface_table *table,
1727                                struct rpc_pipe_client **ret_pipe)
1728 {
1729         struct rpc_pipe_client *cli = NULL;
1730         const struct auth_session_info *session_info = NULL;
1731         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
1732
1733
1734         session_info = get_session_info_system();
1735         SMB_ASSERT(session_info != NULL);
1736
1737         status = rpc_pipe_open_local_np(
1738                 mem_ctx, table, NULL, NULL, NULL, NULL, session_info, &cli);
1739         if (!NT_STATUS_IS_OK(status)) {
1740                 return status;
1741         }
1742
1743         if (ret_pipe) {
1744                 *ret_pipe = cli;
1745         }
1746
1747         return NT_STATUS_OK;
1748 }
1749
1750 static NTSTATUS cm_open_connection(struct winbindd_domain *domain,
1751                                    struct winbindd_cm_conn *new_conn,
1752                                    bool need_rw_dc)
1753 {
1754         TALLOC_CTX *mem_ctx;
1755         NTSTATUS result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
1756         int retries;
1757         uint32_t request_flags = need_rw_dc ? DS_WRITABLE_REQUIRED : 0;
1758         int fd = -1;
1759         bool retry = false;
1760         bool seal_pipes = true;
1761
1762         if ((mem_ctx = talloc_init("cm_open_connection")) == NULL) {
1763                 set_domain_offline(domain);
1764                 return NT_STATUS_NO_MEMORY;
1765         }
1766
1767         D_NOTICE("Creating connection to domain controller. This is a start of "
1768                  "a new connection or a DC failover. The failover only happens "
1769                  "if the domain has more than one DC. We will try to connect 3 "
1770                  "times at most.\n");
1771         for (retries = 0; retries < 3; retries++) {
1772                 bool found_dc;
1773
1774                 D_DEBUG("Attempt %d/3: DC '%s' of domain '%s'.\n",
1775                         retries,
1776                         domain->dcname ? domain->dcname : "",
1777                         domain->name);
1778
1779                 found_dc = find_dc(mem_ctx, domain, request_flags, &fd);
1780                 if (!found_dc) {
1781                         /* This is the one place where we will
1782                            set the global winbindd offline state
1783                            to true, if a "WINBINDD_OFFLINE" entry
1784                            is found in the winbindd cache. */
1785                         set_global_winbindd_state_offline();
1786                         result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
1787                         break;
1788                 }
1789
1790                 new_conn->cli = NULL;
1791
1792                 result = cm_prepare_connection(domain, fd, domain->dcname,
1793                         &new_conn->cli, &retry);
1794                 if (NT_STATUS_IS_OK(result)) {
1795                         break;
1796                 }
1797                 if (!retry) {
1798                         break;
1799                 }
1800         }
1801
1802         if (!NT_STATUS_IS_OK(result)) {
1803                 /* Ensure we setup the retry handler. */
1804                 set_domain_offline(domain);
1805                 goto out;
1806         }
1807
1808         winbindd_set_locator_kdc_envs(domain);
1809
1810         if (domain->online == False) {
1811                 /* We're changing state from offline to online. */
1812                 set_global_winbindd_state_online();
1813         }
1814         set_domain_online(domain);
1815
1816         /*
1817          * Much as I hate global state, this seems to be the point
1818          * where we can be certain that we have a proper connection to
1819          * a DC. wbinfo --dc-info needs that information, store it in
1820          * gencache with a looong timeout. This will need revisiting
1821          * once we start to connect to multiple DCs, wbcDcInfo is
1822          * already prepared for that.
1823          */
1824         store_current_dc_in_gencache(domain->name, domain->dcname,
1825                                      new_conn->cli);
1826
1827         seal_pipes = lp_winbind_sealed_pipes();
1828         seal_pipes = lp_parm_bool(-1, "winbind sealed pipes",
1829                                   domain->name,
1830                                   seal_pipes);
1831
1832         if (seal_pipes) {
1833                 new_conn->auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
1834         } else {
1835                 new_conn->auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
1836         }
1837
1838 out:
1839         talloc_destroy(mem_ctx);
1840         return result;
1841 }
1842
1843 /* Close down all open pipes on a connection. */
1844
1845 void invalidate_cm_connection(struct winbindd_domain *domain)
1846 {
1847         NTSTATUS result;
1848         struct winbindd_cm_conn *conn = &domain->conn;
1849
1850         domain->sequence_number = DOM_SEQUENCE_NONE;
1851         domain->last_seq_check = 0;
1852         domain->last_status = NT_STATUS_SERVER_DISABLED;
1853
1854         /* We're closing down a possibly dead
1855            connection. Don't have impossibly long (10s) timeouts. */
1856
1857         if (conn->cli) {
1858                 cli_set_timeout(conn->cli, 1000); /* 1 second. */
1859         }
1860
1861         if (conn->samr_pipe != NULL) {
1862                 if (is_valid_policy_hnd(&conn->sam_connect_handle)) {
1863                         dcerpc_samr_Close(conn->samr_pipe->binding_handle,
1864                                           talloc_tos(),
1865                                           &conn->sam_connect_handle,
1866                                           &result);
1867                 }
1868                 TALLOC_FREE(conn->samr_pipe);
1869                 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1870                 if (conn->cli) {
1871                         cli_set_timeout(conn->cli, 500);
1872                 }
1873         }
1874
1875         if (conn->lsa_pipe != NULL) {
1876                 if (is_valid_policy_hnd(&conn->lsa_policy)) {
1877                         dcerpc_lsa_Close(conn->lsa_pipe->binding_handle,
1878                                          talloc_tos(),
1879                                          &conn->lsa_policy,
1880                                          &result);
1881                 }
1882                 TALLOC_FREE(conn->lsa_pipe);
1883                 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1884                 if (conn->cli) {
1885                         cli_set_timeout(conn->cli, 500);
1886                 }
1887         }
1888
1889         if (conn->lsa_pipe_tcp != NULL) {
1890                 if (is_valid_policy_hnd(&conn->lsa_policy)) {
1891                         dcerpc_lsa_Close(conn->lsa_pipe_tcp->binding_handle,
1892                                          talloc_tos(),
1893                                          &conn->lsa_policy,
1894                                          &result);
1895                 }
1896                 TALLOC_FREE(conn->lsa_pipe_tcp);
1897                 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1898                 if (conn->cli) {
1899                         cli_set_timeout(conn->cli, 500);
1900                 }
1901         }
1902
1903         if (conn->netlogon_pipe != NULL) {
1904                 TALLOC_FREE(conn->netlogon_pipe);
1905                 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1906                 if (conn->cli) {
1907                         cli_set_timeout(conn->cli, 500);
1908                 }
1909         }
1910
1911         conn->auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
1912         TALLOC_FREE(conn->netlogon_creds_ctx);
1913
1914         if (conn->cli) {
1915                 cli_shutdown(conn->cli);
1916         }
1917
1918         conn->cli = NULL;
1919 }
1920
1921 void close_conns_after_fork(void)
1922 {
1923         struct winbindd_domain *domain;
1924         struct winbindd_cli_state *cli_state;
1925
1926         for (domain = domain_list(); domain; domain = domain->next) {
1927                 /*
1928                  * first close the low level SMB TCP connection
1929                  * so that we don't generate any SMBclose
1930                  * requests in invalidate_cm_connection()
1931                  */
1932                 if (cli_state_is_connected(domain->conn.cli)) {
1933                         smbXcli_conn_disconnect(domain->conn.cli->conn, NT_STATUS_OK);
1934                 }
1935
1936                 invalidate_cm_connection(domain);
1937         }
1938
1939         for (cli_state = winbindd_client_list();
1940              cli_state != NULL;
1941              cli_state = cli_state->next) {
1942                 if (cli_state->sock >= 0) {
1943                         close(cli_state->sock);
1944                         cli_state->sock = -1;
1945                 }
1946         }
1947 }
1948
1949 static bool connection_ok(struct winbindd_domain *domain)
1950 {
1951         bool ok;
1952
1953         ok = cli_state_is_connected(domain->conn.cli);
1954         if (!ok) {
1955                 DEBUG(3, ("connection_ok: Connection to %s for domain %s is not connected\n",
1956                           domain->dcname, domain->name));
1957                 return False;
1958         }
1959
1960         if (!domain->online) {
1961                 DEBUG(3, ("connection_ok: Domain %s is offline\n", domain->name));
1962                 return False;
1963         }
1964
1965         return True;
1966 }
1967
1968 /* Initialize a new connection up to the RPC BIND.
1969    Bypass online status check so always does network calls. */
1970
1971 static NTSTATUS init_dc_connection_network(struct winbindd_domain *domain, bool need_rw_dc)
1972 {
1973         NTSTATUS result;
1974         bool skip_connection = domain->internal;
1975         if (need_rw_dc && domain->rodc) {
1976                 skip_connection = false;
1977         }
1978
1979         /* Internal connections never use the network. */
1980         if (dom_sid_equal(&domain->sid, &global_sid_Builtin)) {
1981                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1982         }
1983
1984         /* Still ask the internal LSA and SAMR server about the local domain */
1985         if (skip_connection || connection_ok(domain)) {
1986                 if (!domain->initialized) {
1987                         set_dc_type_and_flags(domain);
1988                 }
1989                 return NT_STATUS_OK;
1990         }
1991
1992         invalidate_cm_connection(domain);
1993
1994         if (!domain->primary && !domain->initialized) {
1995                 /*
1996                  * Before we connect to a trust, work out if it is an
1997                  * AD domain by asking our own domain.
1998                  */
1999                 set_dc_type_and_flags_trustinfo(domain);
2000         }
2001
2002         result = cm_open_connection(domain, &domain->conn, need_rw_dc);
2003
2004         if (NT_STATUS_IS_OK(result) && !domain->initialized) {
2005                 set_dc_type_and_flags(domain);
2006         }
2007
2008         return result;
2009 }
2010
2011 NTSTATUS init_dc_connection(struct winbindd_domain *domain, bool need_rw_dc)
2012 {
2013         if (dom_sid_equal(&domain->sid, &global_sid_Builtin)) {
2014                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2015         }
2016
2017         SMB_ASSERT(wb_child_domain() || idmap_child());
2018
2019         return init_dc_connection_network(domain, need_rw_dc);
2020 }
2021
2022 static NTSTATUS init_dc_connection_rpc(struct winbindd_domain *domain, bool need_rw_dc)
2023 {
2024         NTSTATUS status;
2025
2026         status = init_dc_connection(domain, need_rw_dc);
2027         if (!NT_STATUS_IS_OK(status)) {
2028                 return status;
2029         }
2030
2031         if (!domain->internal && domain->conn.cli == NULL) {
2032                 /* happens for trusted domains without inbound trust */
2033                 return NT_STATUS_TRUSTED_DOMAIN_FAILURE;
2034         }
2035
2036         return NT_STATUS_OK;
2037 }
2038
2039 /******************************************************************************
2040  Set the trust flags (direction and forest location) for a domain
2041 ******************************************************************************/
2042
2043 static bool set_dc_type_and_flags_trustinfo( struct winbindd_domain *domain )
2044 {
2045         struct winbindd_domain *our_domain;
2046         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2047         WERROR werr;
2048         struct netr_DomainTrustList trusts;
2049         int i;
2050         uint32_t flags = (NETR_TRUST_FLAG_IN_FOREST |
2051                         NETR_TRUST_FLAG_OUTBOUND |
2052                         NETR_TRUST_FLAG_INBOUND);
2053         struct rpc_pipe_client *cli;
2054         TALLOC_CTX *mem_ctx = NULL;
2055         struct dcerpc_binding_handle *b;
2056
2057         if (IS_DC) {
2058                 /*
2059                  * On a DC we loaded all trusts
2060                  * from configuration and never learn
2061                  * new domains.
2062                  */
2063                 return true;
2064         }
2065
2066         DEBUG(5, ("set_dc_type_and_flags_trustinfo: domain %s\n", domain->name ));
2067
2068         /* Our primary domain doesn't need to worry about trust flags.
2069            Force it to go through the network setup */
2070         if ( domain->primary ) {
2071                 return False;
2072         }
2073
2074         mem_ctx = talloc_stackframe();
2075         our_domain = find_our_domain();
2076         if (our_domain->internal) {
2077                 result = init_dc_connection(our_domain, false);
2078                 if (!NT_STATUS_IS_OK(result)) {
2079                         DEBUG(3,("set_dc_type_and_flags_trustinfo: "
2080                                  "Not able to make a connection to our domain: %s\n",
2081                                   nt_errstr(result)));
2082                         TALLOC_FREE(mem_ctx);
2083                         return false;
2084                 }
2085         }
2086
2087         /* This won't work unless our domain is AD */
2088         if ( !our_domain->active_directory ) {
2089                 TALLOC_FREE(mem_ctx);
2090                 return False;
2091         }
2092
2093         if (our_domain->internal) {
2094                 result = wb_open_internal_pipe(mem_ctx, &ndr_table_netlogon, &cli);
2095         } else if (!connection_ok(our_domain)) {
2096                 DEBUG(3,("set_dc_type_and_flags_trustinfo: "
2097                          "No connection to our domain!\n"));
2098                 TALLOC_FREE(mem_ctx);
2099                 return False;
2100         } else {
2101                 result = cm_connect_netlogon(our_domain, &cli);
2102         }
2103
2104         if (!NT_STATUS_IS_OK(result)) {
2105                 DEBUG(5, ("set_dc_type_and_flags_trustinfo: Could not open "
2106                           "a connection to %s for PIPE_NETLOGON (%s)\n",
2107                           domain->name, nt_errstr(result)));
2108                 TALLOC_FREE(mem_ctx);
2109                 return False;
2110         }
2111         b = cli->binding_handle;
2112
2113         /* Use DsEnumerateDomainTrusts to get us the trust direction and type. */
2114         result = dcerpc_netr_DsrEnumerateDomainTrusts(b, mem_ctx,
2115                                                       cli->desthost,
2116                                                       flags,
2117                                                       &trusts,
2118                                                       &werr);
2119         if (!NT_STATUS_IS_OK(result)) {
2120                 DEBUG(0,("set_dc_type_and_flags_trustinfo: "
2121                         "failed to query trusted domain list: %s\n",
2122                         nt_errstr(result)));
2123                 TALLOC_FREE(mem_ctx);
2124                 return false;
2125         }
2126         if (!W_ERROR_IS_OK(werr)) {
2127                 DEBUG(0,("set_dc_type_and_flags_trustinfo: "
2128                         "failed to query trusted domain list: %s\n",
2129                         win_errstr(werr)));
2130                 TALLOC_FREE(mem_ctx);
2131                 return false;
2132         }
2133
2134         /* Now find the domain name and get the flags */
2135
2136         for ( i=0; i<trusts.count; i++ ) {
2137                 if ( strequal( domain->name, trusts.array[i].netbios_name) ) {
2138                         domain->domain_flags          = trusts.array[i].trust_flags;
2139                         domain->domain_type           = trusts.array[i].trust_type;
2140                         domain->domain_trust_attribs  = trusts.array[i].trust_attributes;
2141
2142                         if ( domain->domain_type == LSA_TRUST_TYPE_UPLEVEL )
2143                                 domain->active_directory = True;
2144
2145                         /* This flag is only set if the domain is *our*
2146                            primary domain and the primary domain is in
2147                            native mode */
2148
2149                         domain->native_mode = (domain->domain_flags & NETR_TRUST_FLAG_NATIVE);
2150
2151                         DEBUG(5, ("set_dc_type_and_flags_trustinfo: domain %s is %sin "
2152                                   "native mode.\n", domain->name,
2153                                   domain->native_mode ? "" : "NOT "));
2154
2155                         DEBUG(5,("set_dc_type_and_flags_trustinfo: domain %s is %s"
2156                                  "running active directory.\n", domain->name,
2157                                  domain->active_directory ? "" : "NOT "));
2158
2159                         domain->can_do_ncacn_ip_tcp = domain->active_directory;
2160
2161                         domain->initialized = True;
2162
2163                         break;
2164                 }
2165         }
2166
2167         TALLOC_FREE(mem_ctx);
2168
2169         return domain->initialized;
2170 }
2171
2172 /******************************************************************************
2173  We can 'sense' certain things about the DC by it's replies to certain
2174  questions.
2175
2176  This tells us if this particular remote server is Active Directory, and if it
2177  is native mode.
2178 ******************************************************************************/
2179
2180 static void set_dc_type_and_flags_connect( struct winbindd_domain *domain )
2181 {
2182         NTSTATUS status, result;
2183         NTSTATUS close_status = NT_STATUS_UNSUCCESSFUL;
2184         WERROR werr;
2185         TALLOC_CTX              *mem_ctx = NULL;
2186         struct rpc_pipe_client  *cli = NULL;
2187         struct policy_handle pol = { .handle_type = 0 };
2188         union dssetup_DsRoleInfo info;
2189         union lsa_PolicyInformation *lsa_info = NULL;
2190         union lsa_revision_info out_revision_info = {
2191                 .info1 = {
2192                         .revision = 0,
2193                 },
2194         };
2195         uint32_t out_version = 0;
2196
2197         if (!domain->internal && !connection_ok(domain)) {
2198                 return;
2199         }
2200
2201         mem_ctx = talloc_init("set_dc_type_and_flags on domain %s\n",
2202                               domain->name);
2203         if (!mem_ctx) {
2204                 DEBUG(1, ("set_dc_type_and_flags_connect: talloc_init() failed\n"));
2205                 return;
2206         }
2207
2208         DEBUG(5, ("set_dc_type_and_flags_connect: domain %s\n", domain->name ));
2209
2210         if (domain->internal) {
2211                 status = wb_open_internal_pipe(mem_ctx,
2212                                                &ndr_table_dssetup,
2213                                                &cli);
2214         } else {
2215                 status = cli_rpc_pipe_open_noauth(domain->conn.cli,
2216                                                   &ndr_table_dssetup,
2217                                                   &cli);
2218         }
2219
2220         if (!NT_STATUS_IS_OK(status)) {
2221                 DEBUG(5, ("set_dc_type_and_flags_connect: Could not bind to "
2222                           "PI_DSSETUP on domain %s: (%s)\n",
2223                           domain->name, nt_errstr(status)));
2224
2225                 /* if this is just a non-AD domain we need to continue
2226                  * identifying so that we can in the end return with
2227                  * domain->initialized = True - gd */
2228
2229                 goto no_dssetup;
2230         }
2231
2232         status = dcerpc_dssetup_DsRoleGetPrimaryDomainInformation(cli->binding_handle, mem_ctx,
2233                                                                   DS_ROLE_BASIC_INFORMATION,
2234                                                                   &info,
2235                                                                   &werr);
2236         TALLOC_FREE(cli);
2237
2238         if (NT_STATUS_IS_OK(status)) {
2239                 result = werror_to_ntstatus(werr);
2240         }
2241         if (!NT_STATUS_IS_OK(status)) {
2242                 DEBUG(5, ("set_dc_type_and_flags_connect: rpccli_ds_getprimarydominfo "
2243                           "on domain %s failed: (%s)\n",
2244                           domain->name, nt_errstr(status)));
2245
2246                 /* older samba3 DCs will return DCERPC_FAULT_OP_RNG_ERROR for
2247                  * every opcode on the DSSETUP pipe, continue with
2248                  * no_dssetup mode here as well to get domain->initialized
2249                  * set - gd */
2250
2251                 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) {
2252                         goto no_dssetup;
2253                 }
2254
2255                 TALLOC_FREE(mem_ctx);
2256                 return;
2257         }
2258
2259         if ((info.basic.flags & DS_ROLE_PRIMARY_DS_RUNNING) &&
2260             !(info.basic.flags & DS_ROLE_PRIMARY_DS_MIXED_MODE)) {
2261                 domain->native_mode = True;
2262         } else {
2263                 domain->native_mode = False;
2264         }
2265
2266 no_dssetup:
2267         if (domain->internal) {
2268                 status = wb_open_internal_pipe(mem_ctx,
2269                                                &ndr_table_lsarpc,
2270                                                &cli);
2271         } else {
2272                 status = cli_rpc_pipe_open_noauth(domain->conn.cli,
2273                                                   &ndr_table_lsarpc, &cli);
2274         }
2275         if (!NT_STATUS_IS_OK(status)) {
2276                 DEBUG(5, ("set_dc_type_and_flags_connect: Could not bind to "
2277                           "PI_LSARPC on domain %s: (%s)\n",
2278                           domain->name, nt_errstr(status)));
2279                 TALLOC_FREE(cli);
2280                 TALLOC_FREE(mem_ctx);
2281                 return;
2282         }
2283
2284         status = dcerpc_lsa_open_policy_fallback(cli->binding_handle,
2285                                                  mem_ctx,
2286                                                  cli->srv_name_slash,
2287                                                  true,
2288                                                  SEC_FLAG_MAXIMUM_ALLOWED,
2289                                                  &out_version,
2290                                                  &out_revision_info,
2291                                                  &pol,
2292                                                  &result);
2293
2294         if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) {
2295                 /* This particular query is exactly what Win2k clients use
2296                    to determine that the DC is active directory */
2297                 status = dcerpc_lsa_QueryInfoPolicy2(cli->binding_handle, mem_ctx,
2298                                                      &pol,
2299                                                      LSA_POLICY_INFO_DNS,
2300                                                      &lsa_info,
2301                                                      &result);
2302         }
2303
2304         /*
2305          * If the status and result will not be OK we will fallback to
2306          * OpenPolicy.
2307          */
2308         if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) {
2309                 domain->active_directory = True;
2310
2311                 if (lsa_info->dns.name.string) {
2312                         if (!strequal(domain->name, lsa_info->dns.name.string))
2313                         {
2314                                 DEBUG(1, ("set_dc_type_and_flags_connect: DC "
2315                                           "for domain %s claimed it was a DC "
2316                                           "for domain %s, refusing to "
2317                                           "initialize\n",
2318                                           domain->name,
2319                                           lsa_info->dns.name.string));
2320                                 TALLOC_FREE(cli);
2321                                 TALLOC_FREE(mem_ctx);
2322                                 return;
2323                         }
2324                         talloc_free(domain->name);
2325                         domain->name = talloc_strdup(domain,
2326                                                      lsa_info->dns.name.string);
2327                         if (domain->name == NULL) {
2328                                 goto done;
2329                         }
2330                 }
2331
2332                 if (lsa_info->dns.dns_domain.string) {
2333                         if (domain->alt_name != NULL &&
2334                             !strequal(domain->alt_name,
2335                                       lsa_info->dns.dns_domain.string))
2336                         {
2337                                 DEBUG(1, ("set_dc_type_and_flags_connect: DC "
2338                                           "for domain %s (%s) claimed it was "
2339                                           "a DC for domain %s, refusing to "
2340                                           "initialize\n",
2341                                           domain->alt_name, domain->name,
2342                                           lsa_info->dns.dns_domain.string));
2343                                 TALLOC_FREE(cli);
2344                                 TALLOC_FREE(mem_ctx);
2345                                 return;
2346                         }
2347                         talloc_free(domain->alt_name);
2348                         domain->alt_name =
2349                                 talloc_strdup(domain,
2350                                               lsa_info->dns.dns_domain.string);
2351                         if (domain->alt_name == NULL) {
2352                                 goto done;
2353                         }
2354                 }
2355
2356                 /* See if we can set some domain trust flags about
2357                    ourself */
2358
2359                 if (lsa_info->dns.dns_forest.string) {
2360                         talloc_free(domain->forest_name);
2361                         domain->forest_name =
2362                                 talloc_strdup(domain,
2363                                               lsa_info->dns.dns_forest.string);
2364                         if (domain->forest_name == NULL) {
2365                                 goto done;
2366                         }
2367
2368                         if (strequal(domain->forest_name, domain->alt_name)) {
2369                                 domain->domain_flags |= NETR_TRUST_FLAG_TREEROOT;
2370                         }
2371                 }
2372
2373                 if (lsa_info->dns.sid) {
2374                         if (!is_null_sid(&domain->sid) &&
2375                             !dom_sid_equal(&domain->sid,
2376                                            lsa_info->dns.sid))
2377                         {
2378                                 struct dom_sid_buf buf1, buf2;
2379                                 DEBUG(1, ("set_dc_type_and_flags_connect: DC "
2380                                           "for domain %s (%s) claimed it was "
2381                                           "a DC for domain %s, refusing to "
2382                                           "initialize\n",
2383                                           dom_sid_str_buf(&domain->sid, &buf1),
2384                                           domain->name,
2385                                           dom_sid_str_buf(lsa_info->dns.sid,
2386                                                           &buf2)));
2387                                 TALLOC_FREE(cli);
2388                                 TALLOC_FREE(mem_ctx);
2389                                 return;
2390                         }
2391                         sid_copy(&domain->sid, lsa_info->dns.sid);
2392                 }
2393         } else {
2394                 domain->active_directory = False;
2395
2396                 status = rpccli_lsa_open_policy(cli, mem_ctx, True,
2397                                                 SEC_FLAG_MAXIMUM_ALLOWED,
2398                                                 &pol);
2399
2400                 if (!NT_STATUS_IS_OK(status)) {
2401                         goto done;
2402                 }
2403
2404                 status = dcerpc_lsa_QueryInfoPolicy(cli->binding_handle, mem_ctx,
2405                                                     &pol,
2406                                                     LSA_POLICY_INFO_ACCOUNT_DOMAIN,
2407                                                     &lsa_info,
2408                                                     &result);
2409                 if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) {
2410
2411                         if (lsa_info->account_domain.name.string) {
2412                                 if (!strequal(domain->name,
2413                                         lsa_info->account_domain.name.string))
2414                                 {
2415                                         DEBUG(1,
2416                                               ("set_dc_type_and_flags_connect: "
2417                                                "DC for domain %s claimed it was"
2418                                                " a DC for domain %s, refusing "
2419                                                "to initialize\n", domain->name,
2420                                                lsa_info->
2421                                                 account_domain.name.string));
2422                                         TALLOC_FREE(cli);
2423                                         TALLOC_FREE(mem_ctx);
2424                                         return;
2425                                 }
2426                                 talloc_free(domain->name);
2427                                 domain->name =
2428                                         talloc_strdup(domain,
2429                                                       lsa_info->account_domain.name.string);
2430                         }
2431
2432                         if (lsa_info->account_domain.sid) {
2433                                 if (!is_null_sid(&domain->sid) &&
2434                                     !dom_sid_equal(&domain->sid,
2435                                                 lsa_info->account_domain.sid))
2436                                 {
2437                                         struct dom_sid_buf buf1, buf2;
2438                                         DEBUG(1,
2439                                               ("set_dc_type_and_flags_connect: "
2440                                                "DC for domain %s (%s) claimed "
2441                                                "it was a DC for domain %s, "
2442                                                "refusing to initialize\n",
2443                                                dom_sid_str_buf(
2444                                                        &domain->sid, &buf1),
2445                                                domain->name,
2446                                                dom_sid_str_buf(
2447                                                 lsa_info->account_domain.sid,
2448                                                 &buf2)));
2449                                         TALLOC_FREE(cli);
2450                                         TALLOC_FREE(mem_ctx);
2451                                         return;
2452                                 }
2453                                 sid_copy(&domain->sid, lsa_info->account_domain.sid);
2454                         }
2455                 }
2456         }
2457 done:
2458         if (is_valid_policy_hnd(&pol)) {
2459                 dcerpc_lsa_Close(cli->binding_handle,
2460                                  mem_ctx,
2461                                  &pol,
2462                                  &close_status);
2463         }
2464
2465         DEBUG(5, ("set_dc_type_and_flags_connect: domain %s is %sin native mode.\n",
2466                   domain->name, domain->native_mode ? "" : "NOT "));
2467
2468         DEBUG(5,("set_dc_type_and_flags_connect: domain %s is %srunning active directory.\n",
2469                   domain->name, domain->active_directory ? "" : "NOT "));
2470
2471         domain->can_do_ncacn_ip_tcp = domain->active_directory;
2472
2473         TALLOC_FREE(cli);
2474
2475         TALLOC_FREE(mem_ctx);
2476
2477         domain->initialized = True;
2478 }
2479
2480 /**********************************************************************
2481  Set the domain_flags (trust attributes, domain operating modes, etc...
2482 ***********************************************************************/
2483
2484 static void set_dc_type_and_flags( struct winbindd_domain *domain )
2485 {
2486         if (IS_DC) {
2487                 /*
2488                  * On a DC we loaded all trusts
2489                  * from configuration and never learn
2490                  * new domains.
2491                  */
2492                 return;
2493         }
2494
2495         /* we always have to contact our primary domain */
2496
2497         if ( domain->primary || domain->internal) {
2498                 DEBUG(10,("set_dc_type_and_flags: setting up flags for "
2499                           "primary or internal domain\n"));
2500                 set_dc_type_and_flags_connect( domain );
2501                 return;
2502         }
2503
2504         /* Use our DC to get the information if possible */
2505
2506         if ( !set_dc_type_and_flags_trustinfo( domain ) ) {
2507                 /* Otherwise, fallback to contacting the
2508                    domain directly */
2509                 set_dc_type_and_flags_connect( domain );
2510         }
2511
2512         return;
2513 }
2514
2515
2516
2517 /**********************************************************************
2518 ***********************************************************************/
2519
2520 static NTSTATUS cm_get_schannel_creds(struct winbindd_domain *domain,
2521                                    struct netlogon_creds_cli_context **ppdc)
2522 {
2523         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2524         struct rpc_pipe_client *netlogon_pipe;
2525
2526         *ppdc = NULL;
2527
2528         if ((!IS_DC) && (!domain->primary)) {
2529                 return NT_STATUS_TRUSTED_DOMAIN_FAILURE;
2530         }
2531
2532         if (domain->conn.netlogon_creds_ctx != NULL) {
2533                 *ppdc = domain->conn.netlogon_creds_ctx;
2534                 return NT_STATUS_OK;
2535         }
2536
2537         result = cm_connect_netlogon_secure(domain, &netlogon_pipe, ppdc);
2538         if (!NT_STATUS_IS_OK(result)) {
2539                 return result;
2540         }
2541
2542         return NT_STATUS_OK;
2543 }
2544
2545 NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
2546                         bool need_rw_dc,
2547                         struct rpc_pipe_client **cli, struct policy_handle *sam_handle)
2548 {
2549         struct winbindd_cm_conn *conn;
2550         NTSTATUS status, result;
2551         struct netlogon_creds_cli_context *p_creds;
2552         struct cli_credentials *creds = NULL;
2553         bool retry = false; /* allow one retry attempt for expired session */
2554         const char *remote_name = NULL;
2555         const struct sockaddr_storage *remote_sockaddr = NULL;
2556         bool sealed_pipes = true;
2557         bool strong_key = true;
2558
2559         if (sid_check_is_our_sam(&domain->sid)) {
2560                 if (domain->rodc == false || need_rw_dc == false) {
2561                         return open_internal_samr_conn(mem_ctx, domain, cli, sam_handle);
2562                 }
2563         }
2564
2565         if (IS_AD_DC) {
2566                 /*
2567                  * In theory we should not use SAMR within
2568                  * winbindd at all, but that's a larger task to
2569                  * remove this and avoid breaking existing
2570                  * setups.
2571                  *
2572                  * At least as AD DC we have the restriction
2573                  * to avoid SAMR against trusted domains,
2574                  * as there're no existing setups.
2575                  */
2576                 return NT_STATUS_REQUEST_NOT_ACCEPTED;
2577         }
2578
2579 retry:
2580         status = init_dc_connection_rpc(domain, need_rw_dc);
2581         if (!NT_STATUS_IS_OK(status)) {
2582                 return status;
2583         }
2584
2585         conn = &domain->conn;
2586
2587         if (rpccli_is_connected(conn->samr_pipe)) {
2588                 goto done;
2589         }
2590
2591         TALLOC_FREE(conn->samr_pipe);
2592
2593         /*
2594          * No SAMR pipe yet. Attempt to get an NTLMSSP SPNEGO authenticated
2595          * sign and sealed pipe using the machine account password by
2596          * preference. If we can't - try schannel, if that fails, try
2597          * anonymous.
2598          */
2599
2600         result = get_trust_credentials(domain, talloc_tos(), false, &creds);
2601         if (!NT_STATUS_IS_OK(result)) {
2602                 DEBUG(10, ("cm_connect_sam: No user available for "
2603                            "domain %s, trying schannel\n", domain->name));
2604                 goto schannel;
2605         }
2606
2607         if (cli_credentials_is_anonymous(creds)) {
2608                 goto anonymous;
2609         }
2610
2611         remote_name = smbXcli_conn_remote_name(conn->cli->conn);
2612         remote_sockaddr = smbXcli_conn_remote_sockaddr(conn->cli->conn);
2613
2614         /*
2615          * We have an authenticated connection. Use a SPNEGO
2616          * authenticated SAMR pipe with sign & seal.
2617          */
2618         status = cli_rpc_pipe_open_with_creds(conn->cli,
2619                                               &ndr_table_samr,
2620                                               NCACN_NP,
2621                                               DCERPC_AUTH_TYPE_SPNEGO,
2622                                               conn->auth_level,
2623                                               remote_name,
2624                                               remote_sockaddr,
2625                                               creds,
2626                                               &conn->samr_pipe);
2627
2628         if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)
2629             && !retry) {
2630                 invalidate_cm_connection(domain);
2631                 retry = true;
2632                 goto retry;
2633         }
2634
2635         if (!NT_STATUS_IS_OK(status)) {
2636                 DEBUG(10,("cm_connect_sam: failed to connect to SAMR "
2637                           "pipe for domain %s using NTLMSSP "
2638                           "authenticated pipe: user %s. Error was "
2639                           "%s\n", domain->name,
2640                           cli_credentials_get_unparsed_name(creds, talloc_tos()),
2641                           nt_errstr(status)));
2642                 goto schannel;
2643         }
2644
2645         DEBUG(10,("cm_connect_sam: connected to SAMR pipe for "
2646                   "domain %s using NTLMSSP authenticated "
2647                   "pipe: user %s\n", domain->name,
2648                   cli_credentials_get_unparsed_name(creds, talloc_tos())));
2649
2650         status = dcerpc_samr_Connect2(conn->samr_pipe->binding_handle, mem_ctx,
2651                                       conn->samr_pipe->desthost,
2652                                       SEC_FLAG_MAXIMUM_ALLOWED,
2653                                       &conn->sam_connect_handle,
2654                                       &result);
2655
2656         if (NT_STATUS_EQUAL(status, NT_STATUS_IO_DEVICE_ERROR) && !retry) {
2657                 invalidate_cm_connection(domain);
2658                 TALLOC_FREE(conn->samr_pipe);
2659                 retry = true;
2660                 goto retry;
2661         }
2662
2663         if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) {
2664                 goto open_domain;
2665         }
2666         if (NT_STATUS_IS_OK(status)) {
2667                 status = result;
2668         }
2669
2670         DEBUG(10,("cm_connect_sam: ntlmssp-sealed dcerpc_samr_Connect2 "
2671                   "failed for domain %s, error was %s. Trying schannel\n",
2672                   domain->name, nt_errstr(status) ));
2673         TALLOC_FREE(conn->samr_pipe);
2674
2675  schannel:
2676
2677         /* Fall back to schannel if it's a W2K pre-SP1 box. */
2678
2679         status = cm_get_schannel_creds(domain, &p_creds);
2680         if (!NT_STATUS_IS_OK(status)) {
2681                 /* If this call fails - conn->cli can now be NULL ! */
2682                 DEBUG(10, ("cm_connect_sam: Could not get schannel auth info "
2683                            "for domain %s (error %s), trying anon\n",
2684                         domain->name,
2685                         nt_errstr(status) ));
2686                 goto anonymous;
2687         }
2688         TALLOC_FREE(creds);
2689         status = cli_rpc_pipe_open_schannel_with_creds(
2690                 conn->cli, &ndr_table_samr, NCACN_NP, p_creds,
2691                 remote_name,
2692                 remote_sockaddr,
2693                 &conn->samr_pipe);
2694
2695         if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)
2696             && !retry) {
2697                 invalidate_cm_connection(domain);
2698                 retry = true;
2699                 goto retry;
2700         }
2701
2702         if (!NT_STATUS_IS_OK(status)) {
2703                 DEBUG(10,("cm_connect_sam: failed to connect to SAMR pipe for "
2704                           "domain %s using schannel. Error was %s\n",
2705                           domain->name, nt_errstr(status) ));
2706                 goto anonymous;
2707         }
2708         DEBUG(10,("cm_connect_sam: connected to SAMR pipe for domain %s using "
2709                   "schannel.\n", domain->name ));
2710
2711         status = dcerpc_samr_Connect2(conn->samr_pipe->binding_handle, mem_ctx,
2712                                       conn->samr_pipe->desthost,
2713                                       SEC_FLAG_MAXIMUM_ALLOWED,
2714                                       &conn->sam_connect_handle,
2715                                       &result);
2716
2717         if (NT_STATUS_EQUAL(status, NT_STATUS_IO_DEVICE_ERROR) && !retry) {
2718                 invalidate_cm_connection(domain);
2719                 TALLOC_FREE(conn->samr_pipe);
2720                 retry = true;
2721                 goto retry;
2722         }
2723
2724         if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) {
2725                 goto open_domain;
2726         }
2727         if (NT_STATUS_IS_OK(status)) {
2728                 status = result;
2729         }
2730         DEBUG(10,("cm_connect_sam: schannel-sealed dcerpc_samr_Connect2 failed "
2731                   "for domain %s, error was %s. Trying anonymous\n",
2732                   domain->name, nt_errstr(status) ));
2733         TALLOC_FREE(conn->samr_pipe);
2734
2735  anonymous:
2736
2737         sealed_pipes = lp_winbind_sealed_pipes();
2738         sealed_pipes = lp_parm_bool(-1, "winbind sealed pipes",
2739                                     domain->name,
2740                                     sealed_pipes);
2741         strong_key = lp_require_strong_key();
2742         strong_key = lp_parm_bool(-1, "require strong key",
2743                                   domain->name,
2744                                   strong_key);
2745
2746         /* Finally fall back to anonymous. */
2747         if (sealed_pipes || strong_key) {
2748                 status = NT_STATUS_DOWNGRADE_DETECTED;
2749                 DEBUG(1, ("Unwilling to make SAMR connection to domain %s "
2750                           "without connection level security, "
2751                           "must set 'winbind sealed pipes:%s = false' and "
2752                           "'require strong key:%s = false' to proceed: %s\n",
2753                           domain->name, domain->name, domain->name,
2754                           nt_errstr(status)));
2755                 goto done;
2756         }
2757         status = cli_rpc_pipe_open_noauth(conn->cli, &ndr_table_samr,
2758                                           &conn->samr_pipe);
2759
2760         if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)
2761             && !retry) {
2762                 invalidate_cm_connection(domain);
2763                 retry = true;
2764                 goto retry;
2765         }
2766
2767         if (!NT_STATUS_IS_OK(status)) {
2768                 goto done;
2769         }
2770
2771         status = dcerpc_samr_Connect2(conn->samr_pipe->binding_handle, mem_ctx,
2772                                       conn->samr_pipe->desthost,
2773                                       SEC_FLAG_MAXIMUM_ALLOWED,
2774                                       &conn->sam_connect_handle,
2775                                       &result);
2776
2777         if (NT_STATUS_EQUAL(status, NT_STATUS_IO_DEVICE_ERROR) && !retry) {
2778                 invalidate_cm_connection(domain);
2779                 TALLOC_FREE(conn->samr_pipe);
2780                 retry = true;
2781                 goto retry;
2782         }
2783
2784         if (!NT_STATUS_IS_OK(status)) {
2785                 DEBUG(10,("cm_connect_sam: rpccli_samr_Connect2 failed "
2786                           "for domain %s Error was %s\n",
2787                           domain->name, nt_errstr(status) ));
2788                 goto done;
2789         }
2790         if (!NT_STATUS_IS_OK(result)) {
2791                 status = result;
2792                 DEBUG(10,("cm_connect_sam: dcerpc_samr_Connect2 failed "
2793                           "for domain %s Error was %s\n",
2794                           domain->name, nt_errstr(result)));
2795                 goto done;
2796         }
2797
2798  open_domain:
2799         status = dcerpc_samr_OpenDomain(conn->samr_pipe->binding_handle,
2800                                         mem_ctx,
2801                                         &conn->sam_connect_handle,
2802                                         SEC_FLAG_MAXIMUM_ALLOWED,
2803                                         &domain->sid,
2804                                         &conn->sam_domain_handle,
2805                                         &result);
2806         if (!NT_STATUS_IS_OK(status)) {
2807                 goto done;
2808         }
2809
2810         status = result;
2811  done:
2812
2813         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2814                 /*
2815                  * if we got access denied, we might just have no access rights
2816                  * to talk to the remote samr server server (e.g. when we are a
2817                  * PDC and we are connecting a w2k8 pdc via an interdomain
2818                  * trust). In that case do not invalidate the whole connection
2819                  * stack
2820                  */
2821                 TALLOC_FREE(conn->samr_pipe);
2822                 ZERO_STRUCT(conn->sam_domain_handle);
2823                 return status;
2824         } else if (!NT_STATUS_IS_OK(status)) {
2825                 invalidate_cm_connection(domain);
2826                 return status;
2827         }
2828
2829         *cli = conn->samr_pipe;
2830         *sam_handle = conn->sam_domain_handle;
2831         return status;
2832 }
2833
2834 /**********************************************************************
2835  open an schanneld ncacn_ip_tcp connection to LSA
2836 ***********************************************************************/
2837
2838 static NTSTATUS cm_connect_lsa_tcp(struct winbindd_domain *domain,
2839                                    TALLOC_CTX *mem_ctx,
2840                                    struct rpc_pipe_client **cli)
2841 {
2842         struct winbindd_cm_conn *conn;
2843         struct netlogon_creds_cli_context *p_creds = NULL;
2844         NTSTATUS status;
2845         const char *remote_name = NULL;
2846         const struct sockaddr_storage *remote_sockaddr = NULL;
2847
2848         DEBUG(10,("cm_connect_lsa_tcp\n"));
2849
2850         status = init_dc_connection_rpc(domain, false);
2851         if (!NT_STATUS_IS_OK(status)) {
2852                 return status;
2853         }
2854
2855         conn = &domain->conn;
2856
2857         /*
2858          * rpccli_is_connected handles more error cases
2859          */
2860         if (rpccli_is_connected(conn->lsa_pipe_tcp) &&
2861             conn->lsa_pipe_tcp->transport->transport == NCACN_IP_TCP &&
2862             conn->lsa_pipe_tcp->auth->auth_level >= DCERPC_AUTH_LEVEL_INTEGRITY) {
2863                 goto done;
2864         }
2865
2866         TALLOC_FREE(conn->lsa_pipe_tcp);
2867
2868         status = cm_get_schannel_creds(domain, &p_creds);
2869         if (!NT_STATUS_IS_OK(status)) {
2870                 goto done;
2871         }
2872
2873         remote_name = smbXcli_conn_remote_name(conn->cli->conn);
2874         remote_sockaddr = smbXcli_conn_remote_sockaddr(conn->cli->conn);
2875
2876         status = cli_rpc_pipe_open_schannel_with_creds(
2877                         conn->cli,
2878                         &ndr_table_lsarpc,
2879                         NCACN_IP_TCP,
2880                         p_creds,
2881                         remote_name,
2882                         remote_sockaddr,
2883                         &conn->lsa_pipe_tcp);
2884         if (!NT_STATUS_IS_OK(status)) {
2885                 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key failed: %s\n",
2886                         nt_errstr(status)));
2887                 goto done;
2888         }
2889
2890  done:
2891         if (!NT_STATUS_IS_OK(status)) {
2892                 TALLOC_FREE(conn->lsa_pipe_tcp);
2893                 return status;
2894         }
2895
2896         *cli = conn->lsa_pipe_tcp;
2897
2898         return status;
2899 }
2900
2901 NTSTATUS cm_connect_lsa(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
2902                         struct rpc_pipe_client **cli, struct policy_handle *lsa_policy)
2903 {
2904         struct winbindd_cm_conn *conn;
2905         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2906         struct netlogon_creds_cli_context *p_creds;
2907         struct cli_credentials *creds = NULL;
2908         bool retry = false; /* allow one retry attempt for expired session */
2909         const char *remote_name = NULL;
2910         const struct sockaddr_storage *remote_sockaddr = NULL;
2911         bool sealed_pipes = true;
2912         bool strong_key = true;
2913
2914 retry:
2915         result = init_dc_connection_rpc(domain, false);
2916         if (!NT_STATUS_IS_OK(result))
2917                 return result;
2918
2919         conn = &domain->conn;
2920
2921         if (rpccli_is_connected(conn->lsa_pipe)) {
2922                 goto done;
2923         }
2924
2925         TALLOC_FREE(conn->lsa_pipe);
2926
2927         if (IS_DC) {
2928                 /*
2929                  * Make sure we only use schannel as AD DC.
2930                  */
2931                 goto schannel;
2932         }
2933
2934         result = get_trust_credentials(domain, talloc_tos(), false, &creds);
2935         if (!NT_STATUS_IS_OK(result)) {
2936                 DEBUG(10, ("cm_connect_lsa: No user available for "
2937                            "domain %s, trying schannel\n", domain->name));
2938                 goto schannel;
2939         }
2940
2941         if (cli_credentials_is_anonymous(creds)) {
2942                 goto anonymous;
2943         }
2944
2945         remote_name = smbXcli_conn_remote_name(conn->cli->conn);
2946         remote_sockaddr = smbXcli_conn_remote_sockaddr(conn->cli->conn);
2947
2948         /*
2949          * We have an authenticated connection. Use a SPNEGO
2950          * authenticated LSA pipe with sign & seal.
2951          */
2952         result = cli_rpc_pipe_open_with_creds
2953                 (conn->cli, &ndr_table_lsarpc, NCACN_NP,
2954                  DCERPC_AUTH_TYPE_SPNEGO,
2955                  conn->auth_level,
2956                  remote_name,
2957                  remote_sockaddr,
2958                  creds,
2959                  &conn->lsa_pipe);
2960
2961         if (NT_STATUS_EQUAL(result, NT_STATUS_NETWORK_SESSION_EXPIRED)
2962             && !retry) {
2963                 invalidate_cm_connection(domain);
2964                 retry = true;
2965                 goto retry;
2966         }
2967
2968         if (!NT_STATUS_IS_OK(result)) {
2969                 DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
2970                           "domain %s using NTLMSSP authenticated pipe: user "
2971                           "%s. Error was %s. Trying schannel.\n",
2972                           domain->name,
2973                           cli_credentials_get_unparsed_name(creds, talloc_tos()),
2974                           nt_errstr(result)));
2975                 goto schannel;
2976         }
2977
2978         DEBUG(10,("cm_connect_lsa: connected to LSA pipe for domain %s using "
2979                   "NTLMSSP authenticated pipe: user %s\n",
2980                   domain->name, cli_credentials_get_unparsed_name(creds, talloc_tos())));
2981
2982         result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
2983                                         SEC_FLAG_MAXIMUM_ALLOWED,
2984                                         &conn->lsa_policy);
2985         if (NT_STATUS_EQUAL(result, NT_STATUS_IO_DEVICE_ERROR) && !retry) {
2986                 invalidate_cm_connection(domain);
2987                 TALLOC_FREE(conn->lsa_pipe);
2988                 retry = true;
2989                 goto retry;
2990         }
2991
2992         if (NT_STATUS_IS_OK(result)) {
2993                 goto done;
2994         }
2995
2996         DEBUG(10,("cm_connect_lsa: rpccli_lsa_open_policy failed, trying "
2997                   "schannel\n"));
2998
2999         TALLOC_FREE(conn->lsa_pipe);
3000
3001  schannel:
3002
3003         /* Fall back to schannel if it's a W2K pre-SP1 box. */
3004
3005         result = cm_get_schannel_creds(domain, &p_creds);
3006         if (!NT_STATUS_IS_OK(result)) {
3007                 /* If this call fails - conn->cli can now be NULL ! */
3008                 DEBUG(10, ("cm_connect_lsa: Could not get schannel auth info "
3009                            "for domain %s (error %s), trying anon\n",
3010                         domain->name,
3011                         nt_errstr(result) ));
3012                 goto anonymous;
3013         }
3014
3015         TALLOC_FREE(creds);
3016         result = cli_rpc_pipe_open_schannel_with_creds(
3017                 conn->cli, &ndr_table_lsarpc, NCACN_NP, p_creds,
3018                 remote_name,
3019                 remote_sockaddr,
3020                 &conn->lsa_pipe);
3021
3022         if (NT_STATUS_EQUAL(result, NT_STATUS_NETWORK_SESSION_EXPIRED)
3023             && !retry) {
3024                 invalidate_cm_connection(domain);
3025                 retry = true;
3026                 goto retry;
3027         }
3028
3029         if (!NT_STATUS_IS_OK(result)) {
3030                 DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
3031                           "domain %s using schannel. Error was %s\n",
3032                           domain->name, nt_errstr(result) ));
3033                 goto anonymous;
3034         }
3035         DEBUG(10,("cm_connect_lsa: connected to LSA pipe for domain %s using "
3036                   "schannel.\n", domain->name ));
3037
3038         result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
3039                                         SEC_FLAG_MAXIMUM_ALLOWED,
3040                                         &conn->lsa_policy);
3041
3042         if (NT_STATUS_EQUAL(result, NT_STATUS_IO_DEVICE_ERROR) && !retry) {
3043                 invalidate_cm_connection(domain);
3044                 TALLOC_FREE(conn->lsa_pipe);
3045                 retry = true;
3046                 goto retry;
3047         }
3048
3049         if (NT_STATUS_IS_OK(result)) {
3050                 goto done;
3051         }
3052
3053         if (IS_DC) {
3054                 /*
3055                  * Make sure we only use schannel as AD DC.
3056                  */
3057                 goto done;
3058         }
3059
3060         DEBUG(10,("cm_connect_lsa: rpccli_lsa_open_policy failed, trying "
3061                   "anonymous\n"));
3062
3063         TALLOC_FREE(conn->lsa_pipe);
3064
3065  anonymous:
3066
3067         if (IS_DC) {
3068                 /*
3069                  * Make sure we only use schannel as AD DC.
3070                  */
3071                 goto done;
3072         }
3073
3074         sealed_pipes = lp_winbind_sealed_pipes();
3075         sealed_pipes = lp_parm_bool(-1, "winbind sealed pipes",
3076                                     domain->name,
3077                                     sealed_pipes);
3078         strong_key = lp_require_strong_key();
3079         strong_key = lp_parm_bool(-1, "require strong key",
3080                                   domain->name,
3081                                   strong_key);
3082
3083         /* Finally fall back to anonymous. */
3084         if (sealed_pipes || strong_key) {
3085                 result = NT_STATUS_DOWNGRADE_DETECTED;
3086                 DEBUG(1, ("Unwilling to make LSA connection to domain %s "
3087                           "without connection level security, "
3088                           "must set 'winbind sealed pipes:%s = false' and "
3089                           "'require strong key:%s = false' to proceed: %s\n",
3090                           domain->name, domain->name, domain->name,
3091                           nt_errstr(result)));
3092                 goto done;
3093         }
3094
3095         result = cli_rpc_pipe_open_noauth(conn->cli,
3096                                           &ndr_table_lsarpc,
3097                                           &conn->lsa_pipe);
3098
3099         if (NT_STATUS_EQUAL(result, NT_STATUS_NETWORK_SESSION_EXPIRED)
3100             && !retry) {
3101                 invalidate_cm_connection(domain);
3102                 retry = true;
3103                 goto retry;
3104         }
3105
3106         if (!NT_STATUS_IS_OK(result)) {
3107                 goto done;
3108         }
3109
3110         result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
3111                                         SEC_FLAG_MAXIMUM_ALLOWED,
3112                                         &conn->lsa_policy);
3113
3114         if (NT_STATUS_EQUAL(result, NT_STATUS_IO_DEVICE_ERROR) && !retry) {
3115                 invalidate_cm_connection(domain);
3116                 TALLOC_FREE(conn->lsa_pipe);
3117                 retry = true;
3118                 goto retry;
3119         }
3120
3121  done:
3122         if (!NT_STATUS_IS_OK(result)) {
3123                 invalidate_cm_connection(domain);
3124                 return result;
3125         }
3126
3127         *cli = conn->lsa_pipe;
3128         *lsa_policy = conn->lsa_policy;
3129         return result;
3130 }
3131
3132 /****************************************************************************
3133 Open a LSA connection to a DC, suitable for LSA lookup calls.
3134 ****************************************************************************/
3135
3136 NTSTATUS cm_connect_lsat(struct winbindd_domain *domain,
3137                          TALLOC_CTX *mem_ctx,
3138                          struct rpc_pipe_client **cli,
3139                          struct policy_handle *lsa_policy)
3140 {
3141         NTSTATUS status;
3142
3143         if (domain->can_do_ncacn_ip_tcp) {
3144                 status = cm_connect_lsa_tcp(domain, mem_ctx, cli);
3145                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) ||
3146                     NT_STATUS_EQUAL(status, NT_STATUS_RPC_SEC_PKG_ERROR) ||
3147                     NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_ACCESS_DENIED)) {
3148                         invalidate_cm_connection(domain);
3149                         status = cm_connect_lsa_tcp(domain, mem_ctx, cli);
3150                 }
3151                 if (NT_STATUS_IS_OK(status)) {
3152                         return status;
3153                 }
3154
3155                 /*
3156                  * we tried twice to connect via ncan_ip_tcp and schannel and
3157                  * failed - maybe it is a trusted domain we can't connect to ?
3158                  * do not try tcp next time - gd
3159                  *
3160                  * This also prevents NETLOGON over TCP
3161                  */
3162                 domain->can_do_ncacn_ip_tcp = false;
3163         }
3164
3165         status = cm_connect_lsa(domain, mem_ctx, cli, lsa_policy);
3166
3167         return status;
3168 }
3169
3170 /****************************************************************************
3171  Open the netlogon pipe to this DC.
3172 ****************************************************************************/
3173
3174 static NTSTATUS cm_connect_netlogon_transport(struct winbindd_domain *domain,
3175                                               enum dcerpc_transport_t transport,
3176                                               struct rpc_pipe_client **cli)
3177 {
3178         struct messaging_context *msg_ctx = global_messaging_context();
3179         struct winbindd_cm_conn *conn;
3180         NTSTATUS result;
3181         enum netr_SchannelType sec_chan_type;
3182         struct cli_credentials *creds = NULL;
3183
3184         *cli = NULL;
3185
3186         if (IS_DC) {
3187                 if (domain->secure_channel_type == SEC_CHAN_NULL) {
3188                         /*
3189                          * Make sure we don't even try to
3190                          * connect to a foreign domain
3191                          * without a direct outbound trust.
3192                          */
3193                         return NT_STATUS_NO_TRUST_LSA_SECRET;
3194                 }
3195         }
3196
3197         result = init_dc_connection_rpc(domain, domain->rodc);
3198         if (!NT_STATUS_IS_OK(result)) {
3199                 return result;
3200         }
3201
3202         conn = &domain->conn;
3203
3204         if (rpccli_is_connected(conn->netlogon_pipe)) {
3205                 *cli = conn->netlogon_pipe;
3206                 return NT_STATUS_OK;
3207         }
3208
3209         TALLOC_FREE(conn->netlogon_pipe);
3210         TALLOC_FREE(conn->netlogon_creds_ctx);
3211
3212         result = get_trust_credentials(domain, talloc_tos(), true, &creds);
3213         if (!NT_STATUS_IS_OK(result)) {
3214                 DBG_DEBUG("No user available for domain %s when trying "
3215                           "schannel\n", domain->name);
3216                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
3217         }
3218
3219         if (cli_credentials_is_anonymous(creds)) {
3220                 DBG_WARNING("get_trust_credential only gave anonymous for %s, "
3221                             "unable to make get NETLOGON credentials\n",
3222                             domain->name);
3223                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
3224         }
3225
3226         sec_chan_type = cli_credentials_get_secure_channel_type(creds);
3227         if (sec_chan_type == SEC_CHAN_NULL) {
3228                 const char *remote_name =
3229                         smbXcli_conn_remote_name(conn->cli->conn);
3230                 const struct sockaddr_storage *remote_sockaddr =
3231                         smbXcli_conn_remote_sockaddr(conn->cli->conn);
3232
3233                 if (transport == NCACN_IP_TCP) {
3234                         DBG_NOTICE("get_secure_channel_type gave SEC_CHAN_NULL "
3235                                    "for %s, deny NCACN_IP_TCP and let the "
3236                                    "caller fallback to NCACN_NP.\n",
3237                                    domain->name);
3238                         return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
3239                 }
3240
3241                 DBG_NOTICE("get_secure_channel_type gave SEC_CHAN_NULL for %s, "
3242                            "fallback to noauth on NCACN_NP.\n",
3243                            domain->name);
3244
3245                 result = cli_rpc_pipe_open_noauth_transport(
3246                         conn->cli,
3247                         transport,
3248                         &ndr_table_netlogon,
3249                         remote_name,
3250                         remote_sockaddr,
3251                         &conn->netlogon_pipe);
3252                 if (!NT_STATUS_IS_OK(result)) {
3253                         invalidate_cm_connection(domain);
3254                         return result;
3255                 }
3256
3257                 *cli = conn->netlogon_pipe;
3258                 return NT_STATUS_OK;
3259         }
3260
3261         result = rpccli_create_netlogon_creds_ctx(creds,
3262                                                   domain->dcname,
3263                                                   msg_ctx,
3264                                                   domain,
3265                                                   &conn->netlogon_creds_ctx);
3266         if (!NT_STATUS_IS_OK(result)) {
3267                 DEBUG(1, ("rpccli_create_netlogon_creds failed for %s, "
3268                           "unable to create NETLOGON credentials: %s\n",
3269                           domain->name, nt_errstr(result)));
3270                 return result;
3271         }
3272
3273         result = rpccli_connect_netlogon(
3274                 conn->cli, transport,
3275                 conn->netlogon_creds_ctx, conn->netlogon_force_reauth, creds,
3276                 &conn->netlogon_pipe);
3277         conn->netlogon_force_reauth = false;
3278         if (!NT_STATUS_IS_OK(result)) {
3279                 DBG_DEBUG("rpccli_connect_netlogon failed: %s\n",
3280                           nt_errstr(result));
3281                 return result;
3282         }
3283
3284         *cli = conn->netlogon_pipe;
3285         return NT_STATUS_OK;
3286 }
3287
3288 /****************************************************************************
3289 Open a NETLOGON connection to a DC, suitable for SamLogon calls.
3290 ****************************************************************************/
3291
3292 NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain,
3293                              struct rpc_pipe_client **cli)
3294 {
3295         NTSTATUS status;
3296
3297         status = init_dc_connection_rpc(domain, domain->rodc);
3298         if (!NT_STATUS_IS_OK(status)) {
3299                 return status;
3300         }
3301
3302         if (domain->active_directory && domain->can_do_ncacn_ip_tcp) {
3303                 status = cm_connect_netlogon_transport(domain, NCACN_IP_TCP, cli);
3304                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) ||
3305                     NT_STATUS_EQUAL(status, NT_STATUS_RPC_SEC_PKG_ERROR) ||
3306                     NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_ACCESS_DENIED)) {
3307                         invalidate_cm_connection(domain);
3308                         status = cm_connect_netlogon_transport(domain, NCACN_IP_TCP, cli);
3309                 }
3310                 if (NT_STATUS_IS_OK(status)) {
3311                         return status;
3312                 }
3313
3314                 /*
3315                  * we tried twice to connect via ncan_ip_tcp and schannel and
3316                  * failed - maybe it is a trusted domain we can't connect to ?
3317                  * do not try tcp next time - gd
3318                  *
3319                  * This also prevents LSA over TCP
3320                  */
3321                 domain->can_do_ncacn_ip_tcp = false;
3322         }
3323
3324         status = cm_connect_netlogon_transport(domain, NCACN_NP, cli);
3325         if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
3326                 /*
3327                  * SMB2 session expired, needs reauthentication. Drop
3328                  * connection and retry.
3329                  */
3330                 invalidate_cm_connection(domain);
3331                 status = cm_connect_netlogon_transport(domain, NCACN_NP, cli);
3332         }
3333
3334         return status;
3335 }
3336
3337 NTSTATUS cm_connect_netlogon_secure(struct winbindd_domain *domain,
3338                                     struct rpc_pipe_client **cli,
3339                                     struct netlogon_creds_cli_context **ppdc)
3340 {
3341         NTSTATUS status;
3342
3343         if (domain->secure_channel_type == SEC_CHAN_NULL) {
3344                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
3345         }
3346
3347         status = cm_connect_netlogon(domain, cli);
3348         if (!NT_STATUS_IS_OK(status)) {
3349                 return status;
3350         }
3351
3352         if (domain->conn.netlogon_creds_ctx == NULL) {
3353                 return NT_STATUS_TRUSTED_DOMAIN_FAILURE;
3354         }
3355
3356         *ppdc = domain->conn.netlogon_creds_ctx;
3357         return NT_STATUS_OK;
3358 }
3359
3360 void winbind_msg_ip_dropped(struct messaging_context *msg_ctx,
3361                             void *private_data,
3362                             uint32_t msg_type,
3363                             struct server_id server_id,
3364                             DATA_BLOB *data)
3365 {
3366         struct winbindd_domain *domain;
3367         char *freeit = NULL;
3368         char *addr;
3369
3370         if ((data == NULL)
3371             || (data->data == NULL)
3372             || (data->length == 0)
3373             || (data->data[data->length-1] != '\0')) {
3374                 DEBUG(1, ("invalid msg_ip_dropped message: not a valid "
3375                           "string\n"));
3376                 return;
3377         }
3378
3379         addr = (char *)data->data;
3380         DEBUG(10, ("IP %s dropped\n", addr));
3381
3382         if (!is_ipaddress(addr)) {
3383                 char *slash;
3384                 /*
3385                  * Some code sends us ip addresses with the /netmask
3386                  * suffix
3387                  */
3388                 slash = strchr(addr, '/');
3389                 if (slash == NULL) {
3390                         DEBUG(1, ("invalid msg_ip_dropped message: %s\n",
3391                                   addr));
3392                         return;
3393                 }
3394                 freeit = talloc_strndup(talloc_tos(), addr, slash-addr);
3395                 if (freeit == NULL) {
3396                         DEBUG(1, ("talloc failed\n"));
3397                         return;
3398                 }
3399                 addr = freeit;
3400                 DEBUG(10, ("Stripped /netmask to IP %s\n", addr));
3401         }
3402
3403         for (domain = domain_list(); domain != NULL; domain = domain->next) {
3404                 char sockaddr[INET6_ADDRSTRLEN];
3405
3406                 if (!cli_state_is_connected(domain->conn.cli)) {
3407                         continue;
3408                 }
3409
3410                 print_sockaddr(sockaddr, sizeof(sockaddr),
3411                                smbXcli_conn_local_sockaddr(domain->conn.cli->conn));
3412
3413                 if (strequal(sockaddr, addr)) {
3414                         smbXcli_conn_disconnect(domain->conn.cli->conn, NT_STATUS_OK);
3415                 }
3416         }
3417         TALLOC_FREE(freeit);
3418 }
3419
3420 void winbind_msg_disconnect_dc(struct messaging_context *msg_ctx,
3421                                void *private_data,
3422                                uint32_t msg_type,
3423                                struct server_id server_id,
3424                                DATA_BLOB *data)
3425 {
3426         struct winbindd_domain *domain;
3427
3428         for (domain = domain_list(); domain; domain = domain->next) {
3429                 if (domain->internal) {
3430                         continue;
3431                 }
3432                 invalidate_cm_connection(domain);
3433         }
3434 }