cc92c84cc0795d15dd1b3c1c581bd295b5d7173c
[samba.git] / source3 / rpc_server / netlogon / srv_netlog_nt.c
1 /*
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Copyright (C) Andrew Tridgell              1992-1997,
5  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6  *  Copyright (C) Paul Ashton                       1997.
7  *  Copyright (C) Jeremy Allison               1998-2001.
8  *  Copyright (C) Andrew Bartlett                   2001.
9  *  Copyright (C) Guenther Deschner                 2008-2009.
10  *
11  *  This program is free software; you can redistribute it and/or modify
12  *  it under the terms of the GNU General Public License as published by
13  *  the Free Software Foundation; either version 3 of the License, or
14  *  (at your option) any later version.
15  *
16  *  This program is distributed in the hope that it will be useful,
17  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  *  GNU General Public License for more details.
20  *
21  *  You should have received a copy of the GNU General Public License
22  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
23  */
24
25 /* This is the implementation of the netlogon pipe. */
26
27 #include "includes.h"
28 #include "system/passwd.h" /* uid_wrapper */
29 #include "ntdomain.h"
30 #include "../libcli/auth/schannel.h"
31 #include "librpc/rpc/dcesrv_core.h"
32 #include "librpc/gen_ndr/ndr_netlogon.h"
33 #include "librpc/gen_ndr/ndr_netlogon_scompat.h"
34 #include "librpc/gen_ndr/ndr_samr_c.h"
35 #include "librpc/gen_ndr/ndr_lsa_c.h"
36 #include "rpc_client/cli_lsarpc.h"
37 #include "rpc_client/init_lsa.h"
38 #include "rpc_client/init_samr.h"
39 #include "rpc_server/rpc_ncacn_np.h"
40 #include "../libcli/security/security.h"
41 #include "../libcli/security/dom_sid.h"
42 #include "librpc/gen_ndr/ndr_drsblobs.h"
43 #include "lib/crypto/md4.h"
44 #include "nsswitch/libwbclient/wbclient.h"
45 #include "../libcli/registry/util_reg.h"
46 #include "passdb.h"
47 #include "auth.h"
48 #include "messages.h"
49 #include "../lib/tsocket/tsocket.h"
50 #include "lib/param/param.h"
51 #include "libsmb/dsgetdcname.h"
52 #include "lib/util/util_str_escape.h"
53 #include "source3/lib/substitute.h"
54
55 extern userdom_struct current_user_info;
56
57 #undef DBGC_CLASS
58 #define DBGC_CLASS DBGC_RPC_SRV
59
60 /*************************************************************************
61  _netr_LogonControl
62  *************************************************************************/
63
64 WERROR _netr_LogonControl(struct pipes_struct *p,
65                           struct netr_LogonControl *r)
66 {
67         struct netr_LogonControl2Ex l;
68
69         switch (r->in.level) {
70         case 1:
71                 break;
72         case 2:
73                 return WERR_NOT_SUPPORTED;
74         default:
75                 return WERR_INVALID_LEVEL;
76         }
77
78         switch (r->in.function_code) {
79         case NETLOGON_CONTROL_QUERY:
80         case NETLOGON_CONTROL_REPLICATE:
81         case NETLOGON_CONTROL_SYNCHRONIZE:
82         case NETLOGON_CONTROL_PDC_REPLICATE:
83         case NETLOGON_CONTROL_BREAKPOINT:
84         case NETLOGON_CONTROL_BACKUP_CHANGE_LOG:
85         case NETLOGON_CONTROL_TRUNCATE_LOG:
86                 break;
87         default:
88                 return WERR_NOT_SUPPORTED;
89         }
90
91         l.in.logon_server       = r->in.logon_server;
92         l.in.function_code      = r->in.function_code;
93         l.in.level              = r->in.level;
94         l.in.data               = NULL;
95         l.out.query             = r->out.query;
96
97         return _netr_LogonControl2Ex(p, &l);
98 }
99
100 /*************************************************************************
101  _netr_LogonControl2
102  *************************************************************************/
103
104 WERROR _netr_LogonControl2(struct pipes_struct *p,
105                            struct netr_LogonControl2 *r)
106 {
107         struct netr_LogonControl2Ex l;
108
109         l.in.logon_server       = r->in.logon_server;
110         l.in.function_code      = r->in.function_code;
111         l.in.level              = r->in.level;
112         l.in.data               = r->in.data;
113         l.out.query             = r->out.query;
114
115         return _netr_LogonControl2Ex(p, &l);
116 }
117
118 /*************************************************************************
119  *************************************************************************/
120
121 static bool wb_change_trust_creds(const char *domain, WERROR *tc_status)
122 {
123         wbcErr result;
124         struct wbcAuthErrorInfo *error = NULL;
125
126         result = wbcChangeTrustCredentials(domain, &error);
127         switch (result) {
128         case WBC_ERR_WINBIND_NOT_AVAILABLE:
129                 return false;
130         case WBC_ERR_DOMAIN_NOT_FOUND:
131                 *tc_status = WERR_NO_SUCH_DOMAIN;
132                 return true;
133         case WBC_ERR_SUCCESS:
134                 *tc_status = WERR_OK;
135                 return true;
136         default:
137                 break;
138         }
139
140         if (error && error->nt_status != 0) {
141                 *tc_status = ntstatus_to_werror(NT_STATUS(error->nt_status));
142         } else {
143                 *tc_status = WERR_TRUST_FAILURE;
144         }
145         wbcFreeMemory(error);
146         return true;
147 }
148
149 /*************************************************************************
150  *************************************************************************/
151
152 static bool wb_check_trust_creds(const char *domain, WERROR *tc_status)
153 {
154         wbcErr result;
155         struct wbcAuthErrorInfo *error = NULL;
156
157         result = wbcCheckTrustCredentials(domain, &error);
158         switch (result) {
159         case WBC_ERR_WINBIND_NOT_AVAILABLE:
160                 return false;
161         case WBC_ERR_DOMAIN_NOT_FOUND:
162                 *tc_status = WERR_NO_SUCH_DOMAIN;
163                 return true;
164         case WBC_ERR_SUCCESS:
165                 *tc_status = WERR_OK;
166                 return true;
167         default:
168                 break;
169         }
170
171         if (error && error->nt_status != 0) {
172                 *tc_status = ntstatus_to_werror(NT_STATUS(error->nt_status));
173         } else {
174                 *tc_status = WERR_TRUST_FAILURE;
175         }
176         wbcFreeMemory(error);
177         return true;
178 }
179
180 /****************************************************************
181  _netr_LogonControl2Ex
182 ****************************************************************/
183
184 WERROR _netr_LogonControl2Ex(struct pipes_struct *p,
185                              struct netr_LogonControl2Ex *r)
186 {
187         struct dcesrv_call_state *dce_call = p->dce_call;
188         struct auth_session_info *session_info =
189                 dcesrv_call_session_info(dce_call);
190         uint32_t flags = 0x0;
191         WERROR pdc_connection_status = WERR_OK;
192         uint32_t logon_attempts = 0x0;
193         WERROR tc_status;
194         fstring dc_name2;
195         const char *dc_name = NULL;
196         struct sockaddr_storage dc_ss;
197         const char *domain = NULL;
198         struct netr_NETLOGON_INFO_1 *info1;
199         struct netr_NETLOGON_INFO_2 *info2;
200         struct netr_NETLOGON_INFO_3 *info3;
201         struct netr_NETLOGON_INFO_4 *info4;
202         const char *fn;
203         NTSTATUS status;
204         struct netr_DsRGetDCNameInfo *dc_info;
205
206         switch (dce_call->pkt.u.request.opnum) {
207         case NDR_NETR_LOGONCONTROL:
208                 fn = "_netr_LogonControl";
209                 break;
210         case NDR_NETR_LOGONCONTROL2:
211                 fn = "_netr_LogonControl2";
212                 break;
213         case NDR_NETR_LOGONCONTROL2EX:
214                 fn = "_netr_LogonControl2Ex";
215                 break;
216         default:
217                 return WERR_INVALID_PARAMETER;
218         }
219
220         switch (r->in.level) {
221         case 1:
222         case 2:
223         case 3:
224         case 4:
225                 break;
226         default:
227                 return WERR_INVALID_LEVEL;
228         }
229
230         switch (r->in.function_code) {
231         case NETLOGON_CONTROL_QUERY:
232                 break;
233         default:
234                 if ((geteuid() != sec_initial_uid()) &&
235                     !nt_token_check_domain_rid(
236                             session_info->security_token, DOMAIN_RID_ADMINS) &&
237                     !nt_token_check_sid(
238                             &global_sid_Builtin_Administrators,
239                             session_info->security_token))
240                 {
241                         return WERR_ACCESS_DENIED;
242                 }
243                 break;
244         }
245
246         tc_status = WERR_NO_SUCH_DOMAIN;
247
248         switch (r->in.function_code) {
249         case NETLOGON_CONTROL_QUERY:
250                 switch (r->in.level) {
251                 case 1:
252                 case 3:
253                         break;
254                 default:
255                         return WERR_INVALID_PARAMETER;
256                 }
257
258                 tc_status = WERR_OK;
259                 break;
260         case NETLOGON_CONTROL_REPLICATE:
261         case NETLOGON_CONTROL_SYNCHRONIZE:
262         case NETLOGON_CONTROL_PDC_REPLICATE:
263         case NETLOGON_CONTROL_BACKUP_CHANGE_LOG:
264         case NETLOGON_CONTROL_BREAKPOINT:
265         case NETLOGON_CONTROL_TRUNCATE_LOG:
266         case NETLOGON_CONTROL_TRANSPORT_NOTIFY:
267         case NETLOGON_CONTROL_FORCE_DNS_REG:
268         case NETLOGON_CONTROL_QUERY_DNS_REG:
269                 return WERR_NOT_SUPPORTED;
270
271         case NETLOGON_CONTROL_FIND_USER:
272                 if (!r->in.data || !r->in.data->user) {
273                         return WERR_NOT_SUPPORTED;
274                 }
275                 break;
276         case NETLOGON_CONTROL_SET_DBFLAG:
277                 if (!r->in.data) {
278                         return WERR_NOT_SUPPORTED;
279                 }
280                 break;
281         case NETLOGON_CONTROL_TC_VERIFY:
282                 if (!r->in.data || !r->in.data->domain) {
283                         return WERR_NOT_SUPPORTED;
284                 }
285
286                 if (!wb_check_trust_creds(r->in.data->domain, &tc_status)) {
287                         return WERR_NOT_SUPPORTED;
288                 }
289                 break;
290         case NETLOGON_CONTROL_TC_QUERY:
291                 if (!r->in.data || !r->in.data->domain) {
292                         return WERR_NOT_SUPPORTED;
293                 }
294
295                 domain = r->in.data->domain;
296
297                 if (!is_trusted_domain(domain)) {
298                         break;
299                 }
300
301                 if (!get_dc_name(domain, NULL, dc_name2, &dc_ss)) {
302                         tc_status = WERR_NO_LOGON_SERVERS;
303                         break;
304                 }
305
306                 dc_name = talloc_asprintf(p->mem_ctx, "\\\\%s", dc_name2);
307                 if (!dc_name) {
308                         return WERR_NOT_ENOUGH_MEMORY;
309                 }
310
311                 tc_status = WERR_OK;
312
313                 break;
314
315         case NETLOGON_CONTROL_REDISCOVER:
316                 if (!r->in.data || !r->in.data->domain) {
317                         return WERR_NOT_SUPPORTED;
318                 }
319
320                 domain = r->in.data->domain;
321
322                 if (!is_trusted_domain(domain)) {
323                         break;
324                 }
325
326                 status = dsgetdcname(p->mem_ctx, p->msg_ctx, domain, NULL, NULL,
327                                      DS_FORCE_REDISCOVERY | DS_RETURN_FLAT_NAME,
328                                      &dc_info);
329                 if (!NT_STATUS_IS_OK(status)) {
330                         tc_status = WERR_NO_LOGON_SERVERS;
331                         break;
332                 }
333
334                 dc_name = talloc_asprintf(p->mem_ctx, "\\\\%s", dc_info->dc_unc);
335                 if (!dc_name) {
336                         return WERR_NOT_ENOUGH_MEMORY;
337                 }
338
339                 tc_status = WERR_OK;
340
341                 break;
342
343         case NETLOGON_CONTROL_CHANGE_PASSWORD:
344                 if (!r->in.data || !r->in.data->domain) {
345                         return WERR_NOT_SUPPORTED;
346                 }
347
348                 if (!wb_change_trust_creds(r->in.data->domain, &tc_status)) {
349                         return WERR_NOT_SUPPORTED;
350                 }
351                 break;
352
353         default:
354                 /* no idea what this should be */
355                 DEBUG(0,("%s: unimplemented function level [%d]\n",
356                         fn, r->in.function_code));
357                 return WERR_NOT_SUPPORTED;
358         }
359
360         /* prepare the response */
361
362         switch (r->in.level) {
363         case 1:
364                 info1 = talloc_zero(p->mem_ctx, struct netr_NETLOGON_INFO_1);
365                 W_ERROR_HAVE_NO_MEMORY(info1);
366
367                 info1->flags                    = flags;
368                 info1->pdc_connection_status    = pdc_connection_status;
369
370                 r->out.query->info1 = info1;
371                 break;
372         case 2:
373                 info2 = talloc_zero(p->mem_ctx, struct netr_NETLOGON_INFO_2);
374                 W_ERROR_HAVE_NO_MEMORY(info2);
375
376                 info2->flags                    = flags;
377                 info2->pdc_connection_status    = pdc_connection_status;
378                 info2->trusted_dc_name          = dc_name;
379                 info2->tc_connection_status     = tc_status;
380
381                 r->out.query->info2 = info2;
382                 break;
383         case 3:
384                 info3 = talloc_zero(p->mem_ctx, struct netr_NETLOGON_INFO_3);
385                 W_ERROR_HAVE_NO_MEMORY(info3);
386
387                 info3->flags                    = flags;
388                 info3->logon_attempts           = logon_attempts;
389
390                 r->out.query->info3 = info3;
391                 break;
392         case 4:
393                 info4 = talloc_zero(p->mem_ctx, struct netr_NETLOGON_INFO_4);
394                 W_ERROR_HAVE_NO_MEMORY(info4);
395
396                 info4->trusted_dc_name          = dc_name;
397                 info4->trusted_domain_name      = r->in.data->domain;
398
399                 r->out.query->info4 = info4;
400                 break;
401         default:
402                 return WERR_INVALID_LEVEL;
403         }
404
405         return WERR_OK;
406 }
407
408 /*************************************************************************
409  _netr_NetrEnumerateTrustedDomains
410  *************************************************************************/
411
412 NTSTATUS _netr_NetrEnumerateTrustedDomains(struct pipes_struct *p,
413                                            struct netr_NetrEnumerateTrustedDomains *r)
414 {
415         struct dcesrv_call_state *dce_call = p->dce_call;
416         struct dcesrv_connection *dcesrv_conn = dce_call->conn;
417         const struct tsocket_address *local_address =
418                 dcesrv_connection_get_local_address(dcesrv_conn);
419         const struct tsocket_address *remote_address =
420                 dcesrv_connection_get_remote_address(dcesrv_conn);
421         struct auth_session_info *session_info =
422                 dcesrv_call_session_info(dce_call);
423         NTSTATUS status;
424         NTSTATUS result = NT_STATUS_OK;
425         DATA_BLOB blob;
426         size_t num_domains = 0;
427         const char **trusted_domains = NULL;
428         struct lsa_DomainList domain_list;
429         struct dcerpc_binding_handle *h = NULL;
430         struct policy_handle pol;
431         uint32_t enum_ctx = 0;
432         uint32_t max_size = (uint32_t)-1;
433
434         ZERO_STRUCT(pol);
435         DEBUG(6,("_netr_NetrEnumerateTrustedDomains: %d\n", __LINE__));
436
437         status = rpcint_binding_handle(p->mem_ctx,
438                                        &ndr_table_lsarpc,
439                                        remote_address,
440                                        local_address,
441                                        session_info,
442                                        p->msg_ctx,
443                                        &h);
444         if (!NT_STATUS_IS_OK(status)) {
445                 return status;
446         }
447
448         status = dcerpc_lsa_open_policy2(h,
449                                          p->mem_ctx,
450                                          NULL,
451                                          true,
452                                          LSA_POLICY_VIEW_LOCAL_INFORMATION,
453                                          &pol,
454                                          &result);
455         if (any_nt_status_not_ok(status, result, &status)) {
456                 goto out;
457         }
458
459         do {
460                 uint32_t i;
461
462                 /* Lookup list of trusted domains */
463                 status = dcerpc_lsa_EnumTrustDom(h,
464                                                  p->mem_ctx,
465                                                  &pol,
466                                                  &enum_ctx,
467                                                  &domain_list,
468                                                  max_size,
469                                                  &result);
470                 if (!NT_STATUS_IS_OK(status)) {
471                         goto out;
472                 }
473                 if (!NT_STATUS_IS_OK(result) &&
474                     !NT_STATUS_EQUAL(result, NT_STATUS_NO_MORE_ENTRIES) &&
475                     !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
476                         status = result;
477                         goto out;
478                 }
479
480                 for (i = 0; i < domain_list.count; i++) {
481                         if (!add_string_to_array(p->mem_ctx, domain_list.domains[i].name.string,
482                                                  &trusted_domains, &num_domains)) {
483                                 status = NT_STATUS_NO_MEMORY;
484                                 goto out;
485                         }
486                 }
487         } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
488
489         if (num_domains > 0) {
490                 /* multi sz terminate */
491                 trusted_domains = talloc_realloc(p->mem_ctx, trusted_domains, const char *, num_domains + 1);
492                 if (trusted_domains == NULL) {
493                         status = NT_STATUS_NO_MEMORY;
494                         goto out;
495                 }
496
497                 trusted_domains[num_domains] = NULL;
498         }
499
500         if (!push_reg_multi_sz(trusted_domains, &blob, trusted_domains)) {
501                 TALLOC_FREE(trusted_domains);
502                 status = NT_STATUS_NO_MEMORY;
503                 goto out;
504         }
505
506         r->out.trusted_domains_blob->data = blob.data;
507         r->out.trusted_domains_blob->length = blob.length;
508
509         DEBUG(6,("_netr_NetrEnumerateTrustedDomains: %d\n", __LINE__));
510
511         status = NT_STATUS_OK;
512
513  out:
514         if (is_valid_policy_hnd(&pol)) {
515                 dcerpc_lsa_Close(h, p->mem_ctx, &pol, &result);
516         }
517
518         return status;
519 }
520
521 /*************************************************************************
522  *************************************************************************/
523
524 static NTSTATUS samr_find_machine_account(TALLOC_CTX *mem_ctx,
525                                           struct dcerpc_binding_handle *b,
526                                           const char *account_name,
527                                           uint32_t access_mask,
528                                           struct dom_sid2 **domain_sid_p,
529                                           uint32_t *user_rid_p,
530                                           struct policy_handle *user_handle)
531 {
532         NTSTATUS status;
533         NTSTATUS result = NT_STATUS_OK;
534         struct policy_handle connect_handle;
535         struct policy_handle domain_handle = { 0, };
536         struct lsa_String domain_name;
537         struct dom_sid2 *domain_sid;
538         struct lsa_String names;
539         struct samr_Ids rids;
540         struct samr_Ids types;
541         uint32_t rid;
542
543         status = dcerpc_samr_Connect2(b, mem_ctx,
544                                       lp_netbios_name(),
545                                       SAMR_ACCESS_CONNECT_TO_SERVER |
546                                       SAMR_ACCESS_ENUM_DOMAINS |
547                                       SAMR_ACCESS_LOOKUP_DOMAIN,
548                                       &connect_handle,
549                                       &result);
550         if (any_nt_status_not_ok(status, result, &status)) {
551                 goto out;
552         }
553
554         init_lsa_String(&domain_name, get_global_sam_name());
555
556         status = dcerpc_samr_LookupDomain(b, mem_ctx,
557                                           &connect_handle,
558                                           &domain_name,
559                                           &domain_sid,
560                                           &result);
561         if (any_nt_status_not_ok(status, result, &status)) {
562                 goto out;
563         }
564
565         status = dcerpc_samr_OpenDomain(b, mem_ctx,
566                                         &connect_handle,
567                                         SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
568                                         domain_sid,
569                                         &domain_handle,
570                                         &result);
571         if (any_nt_status_not_ok(status, result, &status)) {
572                 goto out;
573         }
574
575         init_lsa_String(&names, account_name);
576
577         status = dcerpc_samr_LookupNames(b, mem_ctx,
578                                          &domain_handle,
579                                          1,
580                                          &names,
581                                          &rids,
582                                          &types,
583                                          &result);
584         if (any_nt_status_not_ok(status, result, &status)) {
585                 goto out;
586         }
587
588         if (rids.count != 1) {
589                 status = NT_STATUS_NO_SUCH_USER;
590                 goto out;
591         }
592         if (types.count != 1) {
593                 status = NT_STATUS_INVALID_PARAMETER;
594                 goto out;
595         }
596         if (types.ids[0] != SID_NAME_USER) {
597                 status = NT_STATUS_NO_SUCH_USER;
598                 goto out;
599         }
600
601         rid = rids.ids[0];
602
603         status = dcerpc_samr_OpenUser(b, mem_ctx,
604                                       &domain_handle,
605                                       access_mask,
606                                       rid,
607                                       user_handle,
608                                       &result);
609         if (any_nt_status_not_ok(status, result, &status)) {
610                 goto out;
611         }
612
613         if (user_rid_p) {
614                 *user_rid_p = rid;
615         }
616
617         if (domain_sid_p) {
618                 *domain_sid_p = domain_sid;
619         }
620
621  out:
622         if (is_valid_policy_hnd(&domain_handle)) {
623                 dcerpc_samr_Close(b, mem_ctx, &domain_handle, &result);
624         }
625         if (is_valid_policy_hnd(&connect_handle)) {
626                 dcerpc_samr_Close(b, mem_ctx, &connect_handle, &result);
627         }
628
629         return status;
630 }
631
632 /******************************************************************
633  gets a machine password entry.  checks access rights of the host.
634  ******************************************************************/
635
636 static NTSTATUS get_md4pw(struct samr_Password *md4pw, const char *mach_acct,
637                           enum netr_SchannelType sec_chan_type,
638                           struct dom_sid *sid,
639                           struct messaging_context *msg_ctx)
640 {
641         NTSTATUS status;
642         NTSTATUS result = NT_STATUS_OK;
643         TALLOC_CTX *mem_ctx = NULL;
644         struct dcerpc_binding_handle *h = NULL;
645         struct tsocket_address *local = NULL;
646         struct policy_handle user_handle = { .handle_type = 0 };
647         uint32_t user_rid = UINT32_MAX;
648         struct dom_sid *domain_sid = NULL;
649         uint32_t acct_ctrl = 0;
650         union samr_UserInfo *info = NULL;
651         struct auth_session_info *session_info = NULL;
652         int rc;
653
654 #if 0
655
656     /*
657      * Currently this code is redundant as we already have a filter
658      * by hostname list. What this code really needs to do is to
659      * get a hosts allowed/hosts denied list from the SAM database
660      * on a per user basis, and make the access decision there.
661      * I will leave this code here for now as a reminder to implement
662      * this at a later date. JRA.
663      */
664
665         if (!allow_access(lp_domain_hostsdeny(), lp_domain_hostsallow(),
666                           p->client_id.name,
667                           p->client_id.addr)) {
668                 DEBUG(0,("get_md4pw: Workstation %s denied access to domain\n", mach_acct));
669                 return False;
670         }
671 #endif /* 0 */
672
673         mem_ctx = talloc_stackframe();
674
675         status = make_session_info_system(mem_ctx, &session_info);
676         if (!NT_STATUS_IS_OK(status)) {
677                 goto out;
678         }
679
680         ZERO_STRUCT(user_handle);
681
682         rc = tsocket_address_inet_from_strings(mem_ctx,
683                                                "ip",
684                                                "127.0.0.1",
685                                                0,
686                                                &local);
687         if (rc < 0) {
688                 status = NT_STATUS_NO_MEMORY;
689                 goto out;
690         }
691
692         status = rpcint_binding_handle(mem_ctx,
693                                        &ndr_table_samr,
694                                        local,
695                                        NULL,
696                                        session_info,
697                                        msg_ctx,
698                                        &h);
699         if (!NT_STATUS_IS_OK(status)) {
700                 goto out;
701         }
702
703         status = samr_find_machine_account(mem_ctx, h, mach_acct,
704                                            SEC_FLAG_MAXIMUM_ALLOWED,
705                                            &domain_sid, &user_rid,
706                                            &user_handle);
707         if (!NT_STATUS_IS_OK(status)) {
708                 goto out;
709         }
710
711         status = dcerpc_samr_QueryUserInfo2(h,
712                                             mem_ctx,
713                                             &user_handle,
714                                             UserControlInformation,
715                                             &info,
716                                             &result);
717         if (any_nt_status_not_ok(status, result, &status)) {
718                 goto out;
719         }
720
721         acct_ctrl = info->info16.acct_flags;
722
723         if (acct_ctrl & ACB_DISABLED) {
724                 DEBUG(0,("get_md4pw: Workstation %s: account is disabled\n", mach_acct));
725                 status = NT_STATUS_ACCOUNT_DISABLED;
726                 goto out;
727         }
728
729         if (!(acct_ctrl & ACB_SVRTRUST) &&
730             !(acct_ctrl & ACB_WSTRUST) &&
731             !(acct_ctrl & ACB_DOMTRUST))
732         {
733                 DEBUG(0,("get_md4pw: Workstation %s: account is not a trust account\n", mach_acct));
734                 status = NT_STATUS_NO_TRUST_SAM_ACCOUNT;
735                 goto out;
736         }
737
738         switch (sec_chan_type) {
739                 case SEC_CHAN_BDC:
740                         if (!(acct_ctrl & ACB_SVRTRUST)) {
741                                 DEBUG(0,("get_md4pw: Workstation %s: BDC secure channel requested "
742                                          "but not a server trust account\n", mach_acct));
743                                 status = NT_STATUS_NO_TRUST_SAM_ACCOUNT;
744                                 goto out;
745                         }
746                         break;
747                 case SEC_CHAN_WKSTA:
748                         if (!(acct_ctrl & ACB_WSTRUST)) {
749                                 DEBUG(0,("get_md4pw: Workstation %s: WORKSTATION secure channel requested "
750                                          "but not a workstation trust account\n", mach_acct));
751                                 status = NT_STATUS_NO_TRUST_SAM_ACCOUNT;
752                                 goto out;
753                         }
754                         break;
755                 case SEC_CHAN_DOMAIN:
756                         if (!(acct_ctrl & ACB_DOMTRUST)) {
757                                 DEBUG(0,("get_md4pw: Workstation %s: DOMAIN secure channel requested "
758                                          "but not a interdomain trust account\n", mach_acct));
759                                 status = NT_STATUS_NO_TRUST_SAM_ACCOUNT;
760                                 goto out;
761                         }
762                         break;
763                 default:
764                         break;
765         }
766
767         become_root();
768         status = dcerpc_samr_QueryUserInfo2(h,
769                                             mem_ctx,
770                                             &user_handle,
771                                             UserInternal1Information,
772                                             &info,
773                                             &result);
774         unbecome_root();
775         if (any_nt_status_not_ok(status, result, &status)) {
776                 goto out;
777         }
778
779         if (info->info18.nt_pwd_active == 0) {
780                 DEBUG(0,("get_md4pw: Workstation %s: account does not have a password\n", mach_acct));
781                 status = NT_STATUS_LOGON_FAILURE;
782                 goto out;
783         }
784
785         /* samr gives out nthash unencrypted (!) */
786         memcpy(md4pw->hash, info->info18.nt_pwd.hash, 16);
787
788         sid_compose(sid, domain_sid, user_rid);
789
790  out:
791         if (h && is_valid_policy_hnd(&user_handle)) {
792                 dcerpc_samr_Close(h, mem_ctx, &user_handle, &result);
793         }
794
795         talloc_free(mem_ctx);
796
797         return status;
798 }
799
800 /*************************************************************************
801  _netr_ServerReqChallenge
802  *************************************************************************/
803
804 NTSTATUS _netr_ServerReqChallenge(struct pipes_struct *p,
805                                   struct netr_ServerReqChallenge *r)
806 {
807         struct dcesrv_call_state *dce_call = p->dce_call;
808         struct netlogon_server_pipe_state *pipe_state = NULL;
809         NTSTATUS status;
810
811         pipe_state = dcesrv_iface_state_find_conn(
812                 dce_call,
813                 NETLOGON_SERVER_PIPE_STATE_MAGIC,
814                 struct netlogon_server_pipe_state);
815
816         if (pipe_state) {
817                 DEBUG(10,("_netr_ServerReqChallenge: new challenge requested. Clearing old state.\n"));
818                 talloc_free(pipe_state);
819         }
820
821         pipe_state = talloc(p->mem_ctx, struct netlogon_server_pipe_state);
822         NT_STATUS_HAVE_NO_MEMORY(pipe_state);
823
824         pipe_state->client_challenge = *r->in.credentials;
825
826         netlogon_creds_random_challenge(&pipe_state->server_challenge);
827
828         *r->out.return_credentials = pipe_state->server_challenge;
829
830         status = dcesrv_iface_state_store_conn(
831                 dce_call,
832                 NETLOGON_SERVER_PIPE_STATE_MAGIC,
833                 pipe_state);
834         if (!NT_STATUS_IS_OK(status)) {
835                 return status;
836         }
837
838         return NT_STATUS_OK;
839 }
840
841 /*************************************************************************
842  _netr_ServerAuthenticate
843  Create the initial credentials.
844  *************************************************************************/
845
846 NTSTATUS _netr_ServerAuthenticate(struct pipes_struct *p,
847                                   struct netr_ServerAuthenticate *r)
848 {
849         struct netr_ServerAuthenticate3 a;
850         uint32_t negotiate_flags = 0;
851         uint32_t rid;
852
853         a.in.server_name                = r->in.server_name;
854         a.in.account_name               = r->in.account_name;
855         a.in.secure_channel_type        = r->in.secure_channel_type;
856         a.in.computer_name              = r->in.computer_name;
857         a.in.credentials                = r->in.credentials;
858         a.in.negotiate_flags            = &negotiate_flags;
859
860         a.out.return_credentials        = r->out.return_credentials;
861         a.out.rid                       = &rid;
862         a.out.negotiate_flags           = &negotiate_flags;
863
864         return _netr_ServerAuthenticate3(p, &a);
865
866 }
867
868 /*************************************************************************
869  _netr_ServerAuthenticate3
870  *************************************************************************/
871
872 NTSTATUS _netr_ServerAuthenticate3(struct pipes_struct *p,
873                                    struct netr_ServerAuthenticate3 *r)
874 {
875         struct dcesrv_call_state *dce_call = p->dce_call;
876         NTSTATUS status;
877         uint32_t srv_flgs;
878         /* r->in.negotiate_flags is an aliased pointer to r->out.negotiate_flags,
879          * so use a copy to avoid destroying the client values. */
880         uint32_t in_neg_flags = *r->in.negotiate_flags;
881         const char *fn;
882         struct loadparm_context *lp_ctx;
883         struct dom_sid sid;
884         struct samr_Password mach_pwd;
885         struct netlogon_creds_CredentialState *creds;
886         struct netlogon_server_pipe_state *pipe_state = NULL;
887
888         /* According to Microsoft (see bugid #6099)
889          * Windows 7 looks at the negotiate_flags
890          * returned in this structure *even if the
891          * call fails with access denied* ! So in order
892          * to allow Win7 to connect to a Samba NT style
893          * PDC we set the flags before we know if it's
894          * an error or not.
895          */
896
897         /* 0x000001ff */
898         srv_flgs = NETLOGON_NEG_ACCOUNT_LOCKOUT |
899                    NETLOGON_NEG_PERSISTENT_SAMREPL |
900                    NETLOGON_NEG_ARCFOUR |
901                    NETLOGON_NEG_PROMOTION_COUNT |
902                    NETLOGON_NEG_CHANGELOG_BDC |
903                    NETLOGON_NEG_FULL_SYNC_REPL |
904                    NETLOGON_NEG_MULTIPLE_SIDS |
905                    NETLOGON_NEG_REDO |
906                    NETLOGON_NEG_PASSWORD_CHANGE_REFUSAL |
907                    NETLOGON_NEG_PASSWORD_SET2;
908
909         /* Ensure we support strong (128-bit) keys. */
910         if (in_neg_flags & NETLOGON_NEG_STRONG_KEYS) {
911                 srv_flgs |= NETLOGON_NEG_STRONG_KEYS;
912         }
913
914         if (in_neg_flags & NETLOGON_NEG_SUPPORTS_AES) {
915                 srv_flgs |= NETLOGON_NEG_SUPPORTS_AES;
916         }
917
918         if (in_neg_flags & NETLOGON_NEG_SCHANNEL) {
919                 srv_flgs |= NETLOGON_NEG_SCHANNEL;
920         }
921
922         /*
923          * Support authenticaten of trusted domains.
924          *
925          * These flags are the minimum required set which works with win2k3
926          * and win2k8.
927          */
928         if (pdb_capabilities() & PDB_CAP_TRUSTED_DOMAINS_EX) {
929                 srv_flgs |= NETLOGON_NEG_TRANSITIVE_TRUSTS |
930                             NETLOGON_NEG_DNS_DOMAIN_TRUSTS |
931                             NETLOGON_NEG_CROSS_FOREST_TRUSTS |
932                             NETLOGON_NEG_NEUTRALIZE_NT4_EMULATION;
933         }
934
935         /*
936          * If weak cryto is disabled, do not announce that we support RC4.
937          */
938         if (lp_weak_crypto() == SAMBA_WEAK_CRYPTO_DISALLOWED) {
939                 srv_flgs &= ~NETLOGON_NEG_ARCFOUR;
940         }
941
942         switch (dce_call->pkt.u.request.opnum) {
943                 case NDR_NETR_SERVERAUTHENTICATE:
944                         fn = "_netr_ServerAuthenticate";
945                         break;
946                 case NDR_NETR_SERVERAUTHENTICATE2:
947                         fn = "_netr_ServerAuthenticate2";
948                         break;
949                 case NDR_NETR_SERVERAUTHENTICATE3:
950                         fn = "_netr_ServerAuthenticate3";
951                         break;
952                 default:
953                         return NT_STATUS_INTERNAL_ERROR;
954         }
955
956         /* We use this as the key to store the creds: */
957         /* r->in.computer_name */
958
959         pipe_state = dcesrv_iface_state_find_conn(
960                 dce_call,
961                 NETLOGON_SERVER_PIPE_STATE_MAGIC,
962                 struct netlogon_server_pipe_state);
963
964         if (!pipe_state) {
965                 DEBUG(0,("%s: no challenge sent to client %s\n", fn,
966                         r->in.computer_name));
967                 status = NT_STATUS_ACCESS_DENIED;
968                 goto out;
969         }
970
971         status = get_md4pw(&mach_pwd,
972                            r->in.account_name,
973                            r->in.secure_channel_type,
974                            &sid, p->msg_ctx);
975         if (!NT_STATUS_IS_OK(status)) {
976                 DEBUG(0,("%s: failed to get machine password for "
977                         "account %s: %s\n",
978                         fn, r->in.account_name, nt_errstr(status) ));
979                 /* always return NT_STATUS_ACCESS_DENIED */
980                 status = NT_STATUS_ACCESS_DENIED;
981                 goto out;
982         }
983
984         /* From the client / server challenges and md4 password, generate sess key */
985         /* Check client credentials are valid. */
986         creds = netlogon_creds_server_init(p->mem_ctx,
987                                            r->in.account_name,
988                                            r->in.computer_name,
989                                            r->in.secure_channel_type,
990                                            &pipe_state->client_challenge,
991                                            &pipe_state->server_challenge,
992                                            &mach_pwd,
993                                            r->in.credentials,
994                                            r->out.return_credentials,
995                                            srv_flgs);
996         if (!creds) {
997                 DEBUG(0,("%s: netlogon_creds_server_check failed. Rejecting auth "
998                         "request from client %s machine account %s\n",
999                         fn, r->in.computer_name,
1000                         r->in.account_name));
1001                 status = NT_STATUS_ACCESS_DENIED;
1002                 goto out;
1003         }
1004
1005         creds->sid = dom_sid_dup(creds, &sid);
1006         if (!creds->sid) {
1007                 status = NT_STATUS_NO_MEMORY;
1008                 goto out;
1009         }
1010
1011         lp_ctx = loadparm_init_s3(p->mem_ctx, loadparm_s3_helpers());
1012         if (lp_ctx == NULL) {
1013                 DEBUG(10, ("loadparm_init_s3 failed\n"));
1014                 status = NT_STATUS_INTERNAL_ERROR;
1015                 goto out;
1016         }
1017
1018         /* Store off the state so we can continue after client disconnect. */
1019         become_root();
1020         status = schannel_save_creds_state(p->mem_ctx, lp_ctx, creds);
1021         unbecome_root();
1022
1023         talloc_unlink(p->mem_ctx, lp_ctx);
1024
1025         if (!NT_STATUS_IS_OK(status)) {
1026                 ZERO_STRUCTP(r->out.return_credentials);
1027                 goto out;
1028         }
1029
1030         sid_peek_rid(&sid, r->out.rid);
1031
1032         status = NT_STATUS_OK;
1033
1034   out:
1035
1036         *r->out.negotiate_flags = srv_flgs;
1037         return status;
1038 }
1039
1040 /*************************************************************************
1041  _netr_ServerAuthenticate2
1042  *************************************************************************/
1043
1044 NTSTATUS _netr_ServerAuthenticate2(struct pipes_struct *p,
1045                                    struct netr_ServerAuthenticate2 *r)
1046 {
1047         struct netr_ServerAuthenticate3 a;
1048         uint32_t rid;
1049
1050         a.in.server_name                = r->in.server_name;
1051         a.in.account_name               = r->in.account_name;
1052         a.in.secure_channel_type        = r->in.secure_channel_type;
1053         a.in.computer_name              = r->in.computer_name;
1054         a.in.credentials                = r->in.credentials;
1055         a.in.negotiate_flags            = r->in.negotiate_flags;
1056
1057         a.out.return_credentials        = r->out.return_credentials;
1058         a.out.rid                       = &rid;
1059         a.out.negotiate_flags           = r->out.negotiate_flags;
1060
1061         return _netr_ServerAuthenticate3(p, &a);
1062 }
1063
1064 /*************************************************************************
1065  *************************************************************************/
1066
1067 static NTSTATUS netr_creds_server_step_check(struct pipes_struct *p,
1068                                              TALLOC_CTX *mem_ctx,
1069                                              const char *computer_name,
1070                                              struct netr_Authenticator *received_authenticator,
1071                                              struct netr_Authenticator *return_authenticator,
1072                                              struct netlogon_creds_CredentialState **creds_out)
1073 {
1074         struct dcesrv_call_state *dce_call = p->dce_call;
1075         NTSTATUS status;
1076         bool schannel_global_required = (lp_server_schannel() == true) ? true:false;
1077         bool schannel_required = schannel_global_required;
1078         const char *explicit_opt = NULL;
1079         struct loadparm_context *lp_ctx;
1080         struct netlogon_creds_CredentialState *creds = NULL;
1081         enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
1082         uint16_t opnum = dce_call->pkt.u.request.opnum;
1083         const char *opname = "<unknown>";
1084         static bool warned_global_once = false;
1085
1086         if (creds_out != NULL) {
1087                 *creds_out = NULL;
1088         }
1089
1090         if (opnum < ndr_table_netlogon.num_calls) {
1091                 opname = ndr_table_netlogon.calls[opnum].name;
1092         }
1093
1094         dcesrv_call_auth_info(dce_call, &auth_type, NULL);
1095
1096         lp_ctx = loadparm_init_s3(mem_ctx, loadparm_s3_helpers());
1097         if (lp_ctx == NULL) {
1098                 DEBUG(0, ("loadparm_init_s3 failed\n"));
1099                 return NT_STATUS_INTERNAL_ERROR;
1100         }
1101
1102         status = schannel_check_creds_state(mem_ctx, lp_ctx,
1103                                             computer_name, received_authenticator,
1104                                             return_authenticator, &creds);
1105         talloc_unlink(mem_ctx, lp_ctx);
1106
1107         if (!NT_STATUS_IS_OK(status)) {
1108                 ZERO_STRUCTP(return_authenticator);
1109                 return status;
1110         }
1111
1112         /*
1113          * We don't use lp_parm_bool(), as we
1114          * need the explicit_opt pointer in order to
1115          * adjust the debug messages.
1116          */
1117
1118         explicit_opt = lp_parm_const_string(GLOBAL_SECTION_SNUM,
1119                                             "server require schannel",
1120                                             creds->account_name,
1121                                             NULL);
1122         if (explicit_opt != NULL) {
1123                 schannel_required = lp_bool(explicit_opt);
1124         }
1125
1126         if (schannel_required) {
1127                 if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
1128                         *creds_out = creds;
1129                         return NT_STATUS_OK;
1130                 }
1131
1132                 DBG_ERR("CVE-2020-1472(ZeroLogon): "
1133                         "%s request (opnum[%u]) without schannel from "
1134                         "client_account[%s] client_computer_name[%s]\n",
1135                         opname, opnum,
1136                         log_escape(mem_ctx, creds->account_name),
1137                         log_escape(mem_ctx, creds->computer_name));
1138                 DBG_ERR("CVE-2020-1472(ZeroLogon): Check if option "
1139                         "'server require schannel:%s = no' is needed! \n",
1140                         log_escape(mem_ctx, creds->account_name));
1141                 TALLOC_FREE(creds);
1142                 ZERO_STRUCTP(return_authenticator);
1143                 return NT_STATUS_ACCESS_DENIED;
1144         }
1145
1146         if (!schannel_global_required && !warned_global_once) {
1147                 /*
1148                  * We want admins to notice their misconfiguration!
1149                  */
1150                 DBG_ERR("CVE-2020-1472(ZeroLogon): "
1151                         "Please configure 'server schannel = yes', "
1152                         "See https://bugzilla.samba.org/show_bug.cgi?id=14497\n");
1153                 warned_global_once = true;
1154         }
1155
1156         if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
1157                 DBG_ERR("CVE-2020-1472(ZeroLogon): "
1158                         "%s request (opnum[%u]) WITH schannel from "
1159                         "client_account[%s] client_computer_name[%s]\n",
1160                         opname, opnum,
1161                         log_escape(mem_ctx, creds->account_name),
1162                         log_escape(mem_ctx, creds->computer_name));
1163                 DBG_ERR("CVE-2020-1472(ZeroLogon): "
1164                         "Option 'server require schannel:%s = no' not needed!?\n",
1165                         log_escape(mem_ctx, creds->account_name));
1166
1167                 *creds_out = creds;
1168                 return NT_STATUS_OK;
1169         }
1170
1171         if (explicit_opt != NULL) {
1172                 DBG_INFO("CVE-2020-1472(ZeroLogon): "
1173                          "%s request (opnum[%u]) without schannel from "
1174                          "client_account[%s] client_computer_name[%s]\n",
1175                          opname, opnum,
1176                          log_escape(mem_ctx, creds->account_name),
1177                          log_escape(mem_ctx, creds->computer_name));
1178                 DBG_INFO("CVE-2020-1472(ZeroLogon): "
1179                          "Option 'server require schannel:%s = no' still needed!\n",
1180                          log_escape(mem_ctx, creds->account_name));
1181         } else {
1182                 DBG_ERR("CVE-2020-1472(ZeroLogon): "
1183                         "%s request (opnum[%u]) without schannel from "
1184                         "client_account[%s] client_computer_name[%s]\n",
1185                         opname, opnum,
1186                         log_escape(mem_ctx, creds->account_name),
1187                         log_escape(mem_ctx, creds->computer_name));
1188                 DBG_ERR("CVE-2020-1472(ZeroLogon): Check if option "
1189                         "'server require schannel:%s = no' might be needed!\n",
1190                         log_escape(mem_ctx, creds->account_name));
1191         }
1192
1193         *creds_out = creds;
1194         return NT_STATUS_OK;
1195 }
1196
1197
1198 /*************************************************************************
1199  *************************************************************************/
1200
1201 static NTSTATUS samr_open_machine_account(
1202         struct dcerpc_binding_handle *b,
1203         const struct dom_sid *machine_sid,
1204         uint32_t access_mask,
1205         struct policy_handle *machine_handle)
1206 {
1207         TALLOC_CTX *frame = talloc_stackframe();
1208         struct policy_handle connect_handle = { .handle_type = 0 };
1209         struct policy_handle domain_handle = { .handle_type = 0 };
1210         struct dom_sid domain_sid = *machine_sid;
1211         uint32_t machine_rid;
1212         NTSTATUS result = NT_STATUS_OK;
1213         NTSTATUS status = NT_STATUS_INVALID_PARAMETER;
1214         bool ok;
1215
1216         ok = sid_split_rid(&domain_sid, &machine_rid);
1217         if (!ok) {
1218                 goto out;
1219         }
1220
1221         status = dcerpc_samr_Connect2(
1222                 b,
1223                 frame,
1224                 lp_netbios_name(),
1225                 SAMR_ACCESS_CONNECT_TO_SERVER |
1226                 SAMR_ACCESS_ENUM_DOMAINS |
1227                 SAMR_ACCESS_LOOKUP_DOMAIN,
1228                 &connect_handle,
1229                 &result);
1230         if (any_nt_status_not_ok(status, result, &status)) {
1231                 goto out;
1232         }
1233
1234         status = dcerpc_samr_OpenDomain(
1235                 b,
1236                 frame,
1237                 &connect_handle,
1238                 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1239                 &domain_sid,
1240                 &domain_handle,
1241                 &result);
1242         if (any_nt_status_not_ok(status, result, &status)) {
1243                 goto out;
1244         }
1245
1246         status = dcerpc_samr_OpenUser(
1247                 b,
1248                 frame,
1249                 &domain_handle,
1250                 SEC_FLAG_MAXIMUM_ALLOWED,
1251                 machine_rid,
1252                 machine_handle,
1253                 &result);
1254         if (any_nt_status_not_ok(status, result, &status)) {
1255                 goto out;
1256         }
1257
1258 out:
1259         if ((b != NULL) && is_valid_policy_hnd(&domain_handle)) {
1260                 dcerpc_samr_Close(b, frame, &domain_handle, &result);
1261         }
1262         if ((b != NULL) && is_valid_policy_hnd(&connect_handle)) {
1263                 dcerpc_samr_Close(b, frame, &connect_handle, &result);
1264         }
1265         TALLOC_FREE(frame);
1266         return status;
1267 }
1268
1269 struct _samr_Credentials_t {
1270         enum {
1271                 CRED_TYPE_NT_HASH,
1272                 CRED_TYPE_PLAIN_TEXT,
1273         } cred_type;
1274         union {
1275                 struct samr_Password *nt_hash;
1276                 const char *password;
1277         } creds;
1278 };
1279
1280
1281 static NTSTATUS netr_set_machine_account_password(
1282         TALLOC_CTX *mem_ctx,
1283         struct auth_session_info *session_info,
1284         struct messaging_context *msg_ctx,
1285         const struct dom_sid *machine_sid,
1286         struct _samr_Credentials_t *cr)
1287 {
1288         NTSTATUS status;
1289         NTSTATUS result = NT_STATUS_OK;
1290         struct dcerpc_binding_handle *h = NULL;
1291         struct tsocket_address *local;
1292         struct policy_handle user_handle = { .handle_type = 0 };
1293         uint32_t acct_ctrl;
1294         union samr_UserInfo *info;
1295         struct samr_UserInfo18 info18;
1296         struct samr_UserInfo26 info26;
1297         DATA_BLOB in,out;
1298         int rc;
1299         DATA_BLOB session_key;
1300         enum samr_UserInfoLevel infolevel;
1301         TALLOC_CTX *frame = talloc_stackframe();
1302
1303         status = session_extract_session_key(session_info,
1304                                              &session_key,
1305                                              KEY_USE_16BYTES);
1306         if (!NT_STATUS_IS_OK(status)) {
1307                 goto out;
1308         }
1309
1310         rc = tsocket_address_inet_from_strings(frame,
1311                                                "ip",
1312                                                "127.0.0.1",
1313                                                0,
1314                                                &local);
1315         if (rc < 0) {
1316                 status = NT_STATUS_NO_MEMORY;
1317                 goto out;
1318         }
1319
1320         status = rpcint_binding_handle(frame,
1321                                        &ndr_table_samr,
1322                                        local,
1323                                        NULL,
1324                                        get_session_info_system(),
1325                                        msg_ctx,
1326                                        &h);
1327         if (!NT_STATUS_IS_OK(status)) {
1328                 goto out;
1329         }
1330
1331         status = samr_open_machine_account(
1332                 h, machine_sid, SEC_FLAG_MAXIMUM_ALLOWED, &user_handle);
1333         if (!NT_STATUS_IS_OK(status)) {
1334                 goto out;
1335         }
1336
1337         status = dcerpc_samr_QueryUserInfo2(h,
1338                                             frame,
1339                                             &user_handle,
1340                                             UserControlInformation,
1341                                             &info,
1342                                             &result);
1343         if (any_nt_status_not_ok(status, result, &status)) {
1344                 goto out;
1345         }
1346
1347         acct_ctrl = info->info16.acct_flags;
1348
1349         if (!(acct_ctrl & ACB_WSTRUST ||
1350               acct_ctrl & ACB_SVRTRUST ||
1351               acct_ctrl & ACB_DOMTRUST)) {
1352                 status = NT_STATUS_NO_SUCH_USER;
1353                 goto out;
1354         }
1355
1356         if (acct_ctrl & ACB_DISABLED) {
1357                 status = NT_STATUS_ACCOUNT_DISABLED;
1358                 goto out;
1359         }
1360
1361         switch(cr->cred_type) {
1362                 case CRED_TYPE_NT_HASH:
1363                         ZERO_STRUCT(info18);
1364
1365                         infolevel = UserInternal1Information;
1366
1367                         in = data_blob_const(cr->creds.nt_hash, 16);
1368                         out = data_blob_talloc_zero(frame, 16);
1369                         if (out.data == NULL) {
1370                                 status = NT_STATUS_NO_MEMORY;
1371                                 goto out;
1372                         }
1373                         rc = sess_crypt_blob(&out, &in, &session_key, SAMBA_GNUTLS_ENCRYPT);
1374                         if (rc != 0) {
1375                                 status = gnutls_error_to_ntstatus(rc,
1376                                                                   NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER);
1377                                 goto out;
1378                         }
1379                         memcpy(info18.nt_pwd.hash, out.data, out.length);
1380
1381                         info18.nt_pwd_active = true;
1382
1383                         info->info18 = info18;
1384                 break;
1385                 case CRED_TYPE_PLAIN_TEXT:
1386                         ZERO_STRUCT(info26);
1387
1388                         infolevel = UserInternal5InformationNew;
1389
1390                         status = init_samr_CryptPasswordEx(cr->creds.password,
1391                                                            &session_key,
1392                                                            &info26.password);
1393                         if (!NT_STATUS_IS_OK(status)) {
1394                                 goto out;
1395                         }
1396
1397                         info26.password_expired = PASS_DONT_CHANGE_AT_NEXT_LOGON;
1398                         info->info26 = info26;
1399                 break;
1400                 default:
1401                         status = NT_STATUS_INTERNAL_ERROR;
1402                         goto out;
1403                 break;
1404         }
1405
1406         status = dcerpc_samr_SetUserInfo2(h,
1407                                           frame,
1408                                           &user_handle,
1409                                           infolevel,
1410                                           info,
1411                                           &result);
1412         if (any_nt_status_not_ok(status, result, &status)) {
1413                 goto out;
1414         }
1415
1416  out:
1417         if (h && is_valid_policy_hnd(&user_handle)) {
1418                 dcerpc_samr_Close(h, frame, &user_handle, &result);
1419         }
1420         TALLOC_FREE(frame);
1421
1422         return status;
1423 }
1424
1425 /*************************************************************************
1426  _netr_ServerPasswordSet
1427  *************************************************************************/
1428
1429 NTSTATUS _netr_ServerPasswordSet(struct pipes_struct *p,
1430                                  struct netr_ServerPasswordSet *r)
1431 {
1432         struct dcesrv_call_state *dce_call = p->dce_call;
1433         struct auth_session_info *session_info =
1434                 dcesrv_call_session_info(dce_call);
1435         NTSTATUS status = NT_STATUS_OK;
1436         size_t i;
1437         struct netlogon_creds_CredentialState *creds = NULL;
1438         struct _samr_Credentials_t cr = { CRED_TYPE_NT_HASH, {0}};
1439
1440         DEBUG(5,("_netr_ServerPasswordSet: %d\n", __LINE__));
1441
1442         become_root();
1443         status = netr_creds_server_step_check(p, p->mem_ctx,
1444                                               r->in.computer_name,
1445                                               r->in.credential,
1446                                               r->out.return_authenticator,
1447                                               &creds);
1448         unbecome_root();
1449
1450         if (!NT_STATUS_IS_OK(status)) {
1451                 const char *computer_name = "<unknown>";
1452
1453                 if (creds != NULL && creds->computer_name != NULL) {
1454                         computer_name = creds->computer_name;
1455                 }
1456                 DEBUG(2,("_netr_ServerPasswordSet: netlogon_creds_server_step failed. Rejecting auth "
1457                         "request from client %s machine account %s\n",
1458                         r->in.computer_name, computer_name));
1459                 TALLOC_FREE(creds);
1460                 return status;
1461         }
1462
1463         DEBUG(3,("_netr_ServerPasswordSet: Server Password Set by remote machine:[%s] on account [%s]\n",
1464                         r->in.computer_name, creds->computer_name));
1465
1466         status = netlogon_creds_des_decrypt(creds, r->in.new_password);
1467         if (!NT_STATUS_IS_OK(status)) {
1468                 return status;
1469         }
1470
1471         DEBUG(100,("_netr_ServerPasswordSet: new given value was :\n"));
1472         for(i = 0; i < sizeof(r->in.new_password->hash); i++)
1473                 DEBUG(100,("%02X ", r->in.new_password->hash[i]));
1474         DEBUG(100,("\n"));
1475
1476         cr.creds.nt_hash = r->in.new_password;
1477         status = netr_set_machine_account_password(p->mem_ctx,
1478                                                    session_info,
1479                                                    p->msg_ctx,
1480                                                    creds->sid,
1481                                                    &cr);
1482         return status;
1483 }
1484
1485 /****************************************************************
1486  _netr_ServerPasswordSet2
1487 ****************************************************************/
1488
1489 NTSTATUS _netr_ServerPasswordSet2(struct pipes_struct *p,
1490                                   struct netr_ServerPasswordSet2 *r)
1491 {
1492         struct dcesrv_call_state *dce_call = p->dce_call;
1493         struct auth_session_info *session_info =
1494                 dcesrv_call_session_info(dce_call);
1495         NTSTATUS status;
1496         struct netlogon_creds_CredentialState *creds = NULL;
1497         DATA_BLOB plaintext = data_blob_null;
1498         DATA_BLOB new_password = data_blob_null;
1499         size_t confounder_len;
1500         DATA_BLOB dec_blob = data_blob_null;
1501         DATA_BLOB enc_blob = data_blob_null;
1502         struct samr_CryptPassword password_buf;
1503         struct _samr_Credentials_t cr = { CRED_TYPE_PLAIN_TEXT, {0}};
1504         bool ok;
1505
1506         become_root();
1507         status = netr_creds_server_step_check(p, p->mem_ctx,
1508                                               r->in.computer_name,
1509                                               r->in.credential,
1510                                               r->out.return_authenticator,
1511                                               &creds);
1512         unbecome_root();
1513
1514         if (!NT_STATUS_IS_OK(status)) {
1515                 DBG_NOTICE("netlogon_creds_server_step failed. "
1516                            "Rejecting auth request from client %s\n",
1517                            r->in.computer_name);
1518                 TALLOC_FREE(creds);
1519                 return status;
1520         }
1521
1522         DBG_NOTICE("Server Password Set2 by remote "
1523                    "machine:[%s] on account [%s]\n",
1524                    r->in.computer_name,
1525                    creds->computer_name != NULL ?
1526                         creds->computer_name : "<unknown>");
1527
1528         memcpy(password_buf.data, r->in.new_password->data, 512);
1529         SIVAL(password_buf.data, 512, r->in.new_password->length);
1530
1531         if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
1532                 status = netlogon_creds_aes_decrypt(creds,
1533                                                     password_buf.data,
1534                                                     516);
1535         } else {
1536                 status = netlogon_creds_arcfour_crypt(creds,
1537                                                       password_buf.data,
1538                                                       516);
1539         }
1540         if (!NT_STATUS_IS_OK(status)) {
1541                 TALLOC_FREE(creds);
1542                 return status;
1543         }
1544
1545         if (!extract_pw_from_buffer(p->mem_ctx, password_buf.data, &new_password)) {
1546                 DEBUG(2,("_netr_ServerPasswordSet2: unable to extract password "
1547                          "from a buffer. Rejecting auth request as a wrong password\n"));
1548                 TALLOC_FREE(creds);
1549                 return NT_STATUS_WRONG_PASSWORD;
1550         }
1551
1552         /*
1553          * Make sure the length field was encrypted,
1554          * otherwise we are under attack.
1555          */
1556         if (new_password.length == r->in.new_password->length) {
1557                 DBG_WARNING("Length[%zu] field not encrypted\n",
1558                         new_password.length);
1559                 TALLOC_FREE(creds);
1560                 return NT_STATUS_WRONG_PASSWORD;
1561         }
1562
1563         /*
1564          * We don't allow empty passwords for machine accounts.
1565          */
1566         if (new_password.length < 2) {
1567                 DBG_WARNING("Empty password Length[%zu]\n",
1568                         new_password.length);
1569                 TALLOC_FREE(creds);
1570                 return NT_STATUS_WRONG_PASSWORD;
1571         }
1572
1573         /*
1574          * Make sure the confounder part of CryptPassword
1575          * buffer was encrypted, otherwise we are under attack.
1576          */
1577         confounder_len = 512 - new_password.length;
1578         enc_blob = data_blob_const(r->in.new_password->data, confounder_len);
1579         dec_blob = data_blob_const(password_buf.data, confounder_len);
1580         if (confounder_len > 0 && data_blob_equal_const_time(&dec_blob, &enc_blob)) {
1581                 DBG_WARNING("Confounder buffer not encrypted Length[%zu]\n",
1582                             confounder_len);
1583                 TALLOC_FREE(creds);
1584                 return NT_STATUS_WRONG_PASSWORD;
1585         }
1586
1587         /*
1588          * Check that the password part was actually encrypted,
1589          * otherwise we are under attack.
1590          */
1591         enc_blob = data_blob_const(r->in.new_password->data + confounder_len,
1592                                    new_password.length);
1593         dec_blob = data_blob_const(password_buf.data + confounder_len,
1594                                    new_password.length);
1595         if (data_blob_equal_const_time(&dec_blob, &enc_blob)) {
1596                 DBG_WARNING("Password buffer not encrypted Length[%zu]\n",
1597                             new_password.length);
1598                 TALLOC_FREE(creds);
1599                 return NT_STATUS_WRONG_PASSWORD;
1600         }
1601
1602         /*
1603          * don't allow zero buffers
1604          */
1605         if (all_zero(new_password.data, new_password.length)) {
1606                 DBG_WARNING("Password zero buffer Length[%zu]\n",
1607                             new_password.length);
1608                 TALLOC_FREE(creds);
1609                 return NT_STATUS_WRONG_PASSWORD;
1610         }
1611
1612         /* Convert from UTF16 -> plaintext. */
1613         ok = convert_string_talloc(p->mem_ctx,
1614                                 CH_UTF16,
1615                                 CH_UNIX,
1616                                 new_password.data,
1617                                 new_password.length,
1618                                 (void *)&plaintext.data,
1619                                 &plaintext.length);
1620         if (!ok) {
1621                 DBG_WARNING("unable to extract password from a buffer. "
1622                             "Rejecting auth request as a wrong password\n");
1623                 TALLOC_FREE(creds);
1624                 return NT_STATUS_WRONG_PASSWORD;
1625         }
1626
1627         /*
1628          * We don't allow empty passwords for machine accounts.
1629          */
1630
1631         cr.creds.password = (const char*) plaintext.data;
1632         if (strlen(cr.creds.password) == 0) {
1633                 DBG_WARNING("Empty plaintext password\n");
1634                 TALLOC_FREE(creds);
1635                 return NT_STATUS_WRONG_PASSWORD;
1636         }
1637
1638         status = netr_set_machine_account_password(p->mem_ctx,
1639                                                    session_info,
1640                                                    p->msg_ctx,
1641                                                    creds->sid,
1642                                                    &cr);
1643         TALLOC_FREE(creds);
1644         return status;
1645 }
1646
1647 /*************************************************************************
1648  _netr_LogonSamLogoff
1649  *************************************************************************/
1650
1651 NTSTATUS _netr_LogonSamLogoff(struct pipes_struct *p,
1652                               struct netr_LogonSamLogoff *r)
1653 {
1654         NTSTATUS status;
1655         struct netlogon_creds_CredentialState *creds;
1656
1657         become_root();
1658         status = netr_creds_server_step_check(p, p->mem_ctx,
1659                                               r->in.computer_name,
1660                                               r->in.credential,
1661                                               r->out.return_authenticator,
1662                                               &creds);
1663         unbecome_root();
1664
1665         return status;
1666 }
1667
1668 static NTSTATUS _netr_LogonSamLogon_check(const struct netr_LogonSamLogonEx *r)
1669 {
1670         switch (r->in.logon_level) {
1671         case NetlogonInteractiveInformation:
1672         case NetlogonServiceInformation:
1673         case NetlogonInteractiveTransitiveInformation:
1674         case NetlogonServiceTransitiveInformation:
1675                 if (r->in.logon->password == NULL) {
1676                         return NT_STATUS_INVALID_PARAMETER;
1677                 }
1678
1679                 switch (r->in.validation_level) {
1680                 case NetlogonValidationSamInfo:  /* 2 */
1681                 case NetlogonValidationSamInfo2: /* 3 */
1682                         break;
1683                 case NetlogonValidationSamInfo4: /* 6 */
1684                         if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
1685                                 DEBUG(10,("Not adding validation info level 6 "
1686                                    "without ADS passdb backend\n"));
1687                                 return NT_STATUS_INVALID_INFO_CLASS;
1688                         }
1689                         break;
1690                 default:
1691                         return NT_STATUS_INVALID_INFO_CLASS;
1692                 }
1693
1694                 break;
1695         case NetlogonNetworkInformation:
1696         case NetlogonNetworkTransitiveInformation:
1697                 if (r->in.logon->network == NULL) {
1698                         return NT_STATUS_INVALID_PARAMETER;
1699                 }
1700
1701                 switch (r->in.validation_level) {
1702                 case NetlogonValidationSamInfo:  /* 2 */
1703                 case NetlogonValidationSamInfo2: /* 3 */
1704                         break;
1705                 case NetlogonValidationSamInfo4: /* 6 */
1706                         if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
1707                                 DEBUG(10,("Not adding validation info level 6 "
1708                                    "without ADS passdb backend\n"));
1709                                 return NT_STATUS_INVALID_INFO_CLASS;
1710                         }
1711                         break;
1712                 default:
1713                         return NT_STATUS_INVALID_INFO_CLASS;
1714                 }
1715
1716                 break;
1717
1718         case NetlogonGenericInformation:
1719                 if (r->in.logon->generic == NULL) {
1720                         return NT_STATUS_INVALID_PARAMETER;
1721                 }
1722
1723                 /* we don't support this here */
1724                 return NT_STATUS_INVALID_PARAMETER;
1725 #if 0
1726                 switch (r->in.validation_level) {
1727                 /* TODO: case NetlogonValidationGenericInfo: 4 */
1728                 case NetlogonValidationGenericInfo2: /* 5 */
1729                         break;
1730                 default:
1731                         return NT_STATUS_INVALID_INFO_CLASS;
1732                 }
1733
1734                 break;
1735 #endif
1736         default:
1737                 return NT_STATUS_INVALID_PARAMETER;
1738         }
1739
1740         return NT_STATUS_OK;
1741 }
1742
1743 /*************************************************************************
1744  _netr_LogonSamLogon_base
1745  *************************************************************************/
1746
1747 static NTSTATUS _netr_LogonSamLogon_base(struct pipes_struct *p,
1748                                          struct netr_LogonSamLogonEx *r,
1749                                          struct netlogon_creds_CredentialState *creds)
1750 {
1751         struct dcesrv_call_state *dce_call = p->dce_call;
1752         struct dcesrv_connection *dcesrv_conn = dce_call->conn;
1753         const struct tsocket_address *local_address =
1754                 dcesrv_connection_get_local_address(dcesrv_conn);
1755         const struct tsocket_address *remote_address =
1756                 dcesrv_connection_get_remote_address(dcesrv_conn);
1757         NTSTATUS status = NT_STATUS_OK;
1758         union netr_LogonLevel *logon = r->in.logon;
1759         const char *nt_username, *nt_domain, *nt_workstation;
1760         char *sanitized_username = NULL;
1761         struct auth_usersupplied_info *user_info = NULL;
1762         struct auth_serversupplied_info *server_info = NULL;
1763         struct auth_context *auth_context = NULL;
1764         const char *fn;
1765
1766 #ifdef DEBUG_PASSWORD
1767         logon = netlogon_creds_shallow_copy_logon(p->mem_ctx,
1768                                                   r->in.logon_level,
1769                                                   r->in.logon);
1770         if (logon == NULL) {
1771                 logon = r->in.logon;
1772         }
1773 #endif
1774
1775         switch (dce_call->pkt.u.request.opnum) {
1776                 case NDR_NETR_LOGONSAMLOGON:
1777                         fn = "_netr_LogonSamLogon";
1778                         break;
1779                 case NDR_NETR_LOGONSAMLOGONWITHFLAGS:
1780                         fn = "_netr_LogonSamLogonWithFlags";
1781                         break;
1782                 case NDR_NETR_LOGONSAMLOGONEX:
1783                         fn = "_netr_LogonSamLogonEx";
1784                         break;
1785                 default:
1786                         return NT_STATUS_INTERNAL_ERROR;
1787         }
1788
1789         *r->out.authoritative = 1; /* authoritative response */
1790
1791         switch (r->in.validation_level) {
1792         case 2:
1793                 r->out.validation->sam2 = talloc_zero(p->mem_ctx, struct netr_SamInfo2);
1794                 if (!r->out.validation->sam2) {
1795                         return NT_STATUS_NO_MEMORY;
1796                 }
1797                 break;
1798         case 3:
1799                 r->out.validation->sam3 = talloc_zero(p->mem_ctx, struct netr_SamInfo3);
1800                 if (!r->out.validation->sam3) {
1801                         return NT_STATUS_NO_MEMORY;
1802                 }
1803                 break;
1804         case 6:
1805                 r->out.validation->sam6 = talloc_zero(p->mem_ctx, struct netr_SamInfo6);
1806                 if (!r->out.validation->sam6) {
1807                         return NT_STATUS_NO_MEMORY;
1808                 }
1809                 break;
1810         default:
1811                 DEBUG(0,("%s: bad validation_level value %d.\n",
1812                         fn, (int)r->in.validation_level));
1813                 return NT_STATUS_INVALID_INFO_CLASS;
1814         }
1815
1816         switch (r->in.logon_level) {
1817         case NetlogonInteractiveInformation:
1818         case NetlogonServiceInformation:
1819         case NetlogonInteractiveTransitiveInformation:
1820         case NetlogonServiceTransitiveInformation:
1821                 nt_username     = logon->password->identity_info.account_name.string ?
1822                                   logon->password->identity_info.account_name.string : "";
1823                 nt_domain       = logon->password->identity_info.domain_name.string ?
1824                                   logon->password->identity_info.domain_name.string : "";
1825                 nt_workstation  = logon->password->identity_info.workstation.string ?
1826                                   logon->password->identity_info.workstation.string : "";
1827
1828                 DEBUG(3,("SAM Logon (Interactive). Domain:[%s].  ", lp_workgroup()));
1829                 break;
1830         case NetlogonNetworkInformation:
1831         case NetlogonNetworkTransitiveInformation:
1832                 nt_username     = logon->network->identity_info.account_name.string ?
1833                                   logon->network->identity_info.account_name.string : "";
1834                 nt_domain       = logon->network->identity_info.domain_name.string ?
1835                                   logon->network->identity_info.domain_name.string : "";
1836                 nt_workstation  = logon->network->identity_info.workstation.string ?
1837                                   logon->network->identity_info.workstation.string : "";
1838
1839                 DEBUG(3,("SAM Logon (Network). Domain:[%s].  ", lp_workgroup()));
1840                 break;
1841         default:
1842                 DEBUG(2,("SAM Logon: unsupported switch value\n"));
1843                 return NT_STATUS_INVALID_INFO_CLASS;
1844         } /* end switch */
1845
1846         DEBUG(3,("User:[%s@%s] Requested Domain:[%s]\n", nt_username, nt_workstation, nt_domain));
1847
1848         DEBUG(5,("Attempting validation level %d for unmapped username %s.\n",
1849                 r->in.validation_level, nt_username));
1850
1851         status = netlogon_creds_decrypt_samlogon_logon(creds,
1852                                                        r->in.logon_level,
1853                                                        logon);
1854         if (!NT_STATUS_IS_OK(status)) {
1855                 return status;
1856         }
1857
1858         status = make_auth3_context_for_netlogon(talloc_tos(), &auth_context);
1859         if (!NT_STATUS_IS_OK(status)) {
1860                 return status;
1861         }
1862
1863         switch (r->in.logon_level) {
1864         case NetlogonNetworkInformation:
1865         case NetlogonNetworkTransitiveInformation:
1866         {
1867                 const char *wksname = nt_workstation;
1868                 const char *workgroup = lp_workgroup();
1869                 bool ok;
1870
1871                 ok = auth3_context_set_challenge(
1872                         auth_context, logon->network->challenge, "fixed");
1873                 if (!ok) {
1874                         return NT_STATUS_NO_MEMORY;
1875                 }
1876
1877                 /* For a network logon, the workstation name comes in with two
1878                  * backslashes in the front. Strip them if they are there. */
1879
1880                 if (*wksname == '\\') wksname++;
1881                 if (*wksname == '\\') wksname++;
1882
1883                 /* Standard challenge/response authentication */
1884                 if (!make_user_info_netlogon_network(talloc_tos(),
1885                                                      &user_info,
1886                                                      nt_username, nt_domain,
1887                                                      wksname,
1888                                                      remote_address,
1889                                                      local_address,
1890                                                      logon->network->identity_info.parameter_control,
1891                                                      logon->network->lm.data,
1892                                                      logon->network->lm.length,
1893                                                      logon->network->nt.data,
1894                                                      logon->network->nt.length)) {
1895                         status = NT_STATUS_NO_MEMORY;
1896                 }
1897
1898                 if (NT_STATUS_IS_OK(status)) {
1899                         status = NTLMv2_RESPONSE_verify_netlogon_creds(
1900                                                 user_info->client.account_name,
1901                                                 user_info->client.domain_name,
1902                                                 user_info->password.response.nt,
1903                                                 creds, workgroup);
1904                 }
1905                 break;
1906         }
1907         case NetlogonInteractiveInformation:
1908         case NetlogonServiceInformation:
1909         case NetlogonInteractiveTransitiveInformation:
1910         case NetlogonServiceTransitiveInformation:
1911
1912                 /* 'Interactive' authentication, supplies the password in its
1913                    MD4 form, encrypted with the session key.  We will convert
1914                    this to challenge/response for the auth subsystem to chew
1915                    on */
1916         {
1917                 uint8_t chal[8];
1918
1919 #ifdef DEBUG_PASSWORD
1920                 if (logon != r->in.logon) {
1921                         DEBUG(100,("lm owf password:"));
1922                         dump_data(100,
1923                                   r->in.logon->password->lmpassword.hash, 16);
1924
1925                         DEBUG(100,("nt owf password:"));
1926                         dump_data(100,
1927                                   r->in.logon->password->ntpassword.hash, 16);
1928                 }
1929
1930                 DEBUG(100,("decrypt of lm owf password:"));
1931                 dump_data(100, logon->password->lmpassword.hash, 16);
1932
1933                 DEBUG(100,("decrypt of nt owf password:"));
1934                 dump_data(100, logon->password->ntpassword.hash, 16);
1935 #endif
1936
1937                 auth_get_ntlm_challenge(auth_context, chal);
1938
1939                 if (!make_user_info_netlogon_interactive(talloc_tos(),
1940                                                          &user_info,
1941                                                          nt_username, nt_domain,
1942                                                          nt_workstation,
1943                                                          remote_address,
1944                                                          local_address,
1945                                                          logon->password->identity_info.parameter_control,
1946                                                          chal,
1947                                                          logon->password->lmpassword.hash,
1948                                                          logon->password->ntpassword.hash)) {
1949                         status = NT_STATUS_NO_MEMORY;
1950                 }
1951                 break;
1952         }
1953         default:
1954                 DEBUG(2,("SAM Logon: unsupported switch value\n"));
1955                 return NT_STATUS_INVALID_INFO_CLASS;
1956         } /* end switch */
1957
1958         if ( NT_STATUS_IS_OK(status) ) {
1959                 status = auth_check_ntlm_password(p->mem_ctx,
1960                                                   auth_context,
1961                                                   user_info,
1962                                                   &server_info,
1963                                                   r->out.authoritative);
1964         }
1965
1966         TALLOC_FREE(auth_context);
1967         TALLOC_FREE(user_info);
1968
1969         DEBUG(5,("%s: check_password returned status %s\n",
1970                   fn, nt_errstr(status)));
1971
1972         /* Check account and password */
1973
1974         if (!NT_STATUS_IS_OK(status)) {
1975                 TALLOC_FREE(server_info);
1976                 return status;
1977         }
1978
1979         if (server_info->guest) {
1980                 /* We don't like guest domain logons... */
1981                 DEBUG(5,("%s: Attempted domain logon as GUEST "
1982                          "denied.\n", fn));
1983                 TALLOC_FREE(server_info);
1984                 return NT_STATUS_LOGON_FAILURE;
1985         }
1986
1987         sanitized_username = talloc_alpha_strcpy(talloc_tos(),
1988                                                  nt_username,
1989                                                  SAFE_NETBIOS_CHARS "$");
1990         if (sanitized_username == NULL) {
1991                 TALLOC_FREE(server_info);
1992                 return NT_STATUS_NO_MEMORY;
1993         }
1994
1995         set_current_user_info(sanitized_username,
1996                               server_info->unix_name,
1997                               server_info->info3->base.logon_domain.string);
1998         TALLOC_FREE(sanitized_username);
1999
2000         /* This is the point at which, if the login was successful, that
2001            the SAM Local Security Authority should record that the user is
2002            logged in to the domain.  */
2003
2004         switch (r->in.validation_level) {
2005         case 2:
2006                 status = serverinfo_to_SamInfo2(server_info,
2007                                                 r->out.validation->sam2);
2008                 break;
2009         case 3:
2010                 status = serverinfo_to_SamInfo3(server_info,
2011                                                 r->out.validation->sam3);
2012                 break;
2013         case 6: {
2014                 enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
2015
2016                 dcesrv_call_auth_info(dce_call, NULL, &auth_level);
2017
2018                 /* Only allow this if the pipe is protected. */
2019                 if (auth_level < DCERPC_AUTH_LEVEL_PRIVACY) {
2020                         DEBUG(0,("netr_Validation6: client %s not using privacy for netlogon\n",
2021                                 get_remote_machine_name()));
2022                         status = NT_STATUS_INVALID_PARAMETER;
2023                         break;
2024                 }
2025
2026                 status = serverinfo_to_SamInfo6(server_info,
2027                                                 r->out.validation->sam6);
2028                 break;
2029         }
2030         }
2031
2032         TALLOC_FREE(server_info);
2033
2034         if (!NT_STATUS_IS_OK(status)) {
2035                 return status;
2036         }
2037
2038         status = netlogon_creds_encrypt_samlogon_validation(creds,
2039                                                             r->in.validation_level,
2040                                                             r->out.validation);
2041
2042         return status;
2043 }
2044
2045 /****************************************************************
2046  _netr_LogonSamLogonWithFlags
2047 ****************************************************************/
2048
2049 NTSTATUS _netr_LogonSamLogonWithFlags(struct pipes_struct *p,
2050                                       struct netr_LogonSamLogonWithFlags *r)
2051 {
2052         NTSTATUS status;
2053         struct netlogon_creds_CredentialState *creds;
2054         struct netr_LogonSamLogonEx r2;
2055         struct netr_Authenticator return_authenticator;
2056
2057         *r->out.authoritative = true;
2058
2059         r2.in.server_name       = r->in.server_name;
2060         r2.in.computer_name     = r->in.computer_name;
2061         r2.in.logon_level       = r->in.logon_level;
2062         r2.in.logon             = r->in.logon;
2063         r2.in.validation_level  = r->in.validation_level;
2064         r2.in.flags             = r->in.flags;
2065         r2.out.validation       = r->out.validation;
2066         r2.out.authoritative    = r->out.authoritative;
2067         r2.out.flags            = r->out.flags;
2068
2069         status = _netr_LogonSamLogon_check(&r2);
2070         if (!NT_STATUS_IS_OK(status)) {
2071                 return status;
2072         }
2073
2074         become_root();
2075         status = netr_creds_server_step_check(p, p->mem_ctx,
2076                                               r->in.computer_name,
2077                                               r->in.credential,
2078                                               &return_authenticator,
2079                                               &creds);
2080         unbecome_root();
2081         if (!NT_STATUS_IS_OK(status)) {
2082                 return status;
2083         }
2084
2085         status = _netr_LogonSamLogon_base(p, &r2, creds);
2086
2087         *r->out.return_authenticator = return_authenticator;
2088
2089         return status;
2090 }
2091
2092 /*************************************************************************
2093  _netr_LogonSamLogon
2094  *************************************************************************/
2095
2096 NTSTATUS _netr_LogonSamLogon(struct pipes_struct *p,
2097                              struct netr_LogonSamLogon *r)
2098 {
2099         NTSTATUS status;
2100         struct netr_LogonSamLogonWithFlags r2;
2101         uint32_t flags = 0;
2102
2103         r2.in.server_name               = r->in.server_name;
2104         r2.in.computer_name             = r->in.computer_name;
2105         r2.in.credential                = r->in.credential;
2106         r2.in.logon_level               = r->in.logon_level;
2107         r2.in.logon                     = r->in.logon;
2108         r2.in.validation_level          = r->in.validation_level;
2109         r2.in.return_authenticator      = r->in.return_authenticator;
2110         r2.in.flags                     = &flags;
2111         r2.out.validation               = r->out.validation;
2112         r2.out.authoritative            = r->out.authoritative;
2113         r2.out.flags                    = &flags;
2114         r2.out.return_authenticator     = r->out.return_authenticator;
2115
2116         status = _netr_LogonSamLogonWithFlags(p, &r2);
2117
2118         return status;
2119 }
2120
2121 /*************************************************************************
2122  _netr_LogonSamLogonEx
2123  - no credential chaining. Map into net sam logon.
2124  *************************************************************************/
2125
2126 NTSTATUS _netr_LogonSamLogonEx(struct pipes_struct *p,
2127                                struct netr_LogonSamLogonEx *r)
2128 {
2129         struct dcesrv_call_state *dce_call = p->dce_call;
2130         enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
2131         NTSTATUS status;
2132         struct netlogon_creds_CredentialState *creds = NULL;
2133         struct loadparm_context *lp_ctx;
2134
2135         *r->out.authoritative = true;
2136
2137         status = _netr_LogonSamLogon_check(r);
2138         if (!NT_STATUS_IS_OK(status)) {
2139                 return status;
2140         }
2141
2142         /* Only allow this if the pipe is protected. */
2143
2144         dcesrv_call_auth_info(dce_call, &auth_type, NULL);
2145
2146         if (auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
2147                 DEBUG(0,("_netr_LogonSamLogonEx: client %s not using schannel for netlogon\n",
2148                         get_remote_machine_name() ));
2149                 return NT_STATUS_INVALID_PARAMETER;
2150         }
2151
2152         lp_ctx = loadparm_init_s3(p->mem_ctx, loadparm_s3_helpers());
2153         if (lp_ctx == NULL) {
2154                 DEBUG(0, ("loadparm_init_s3 failed\n"));
2155                 return NT_STATUS_INTERNAL_ERROR;
2156         }
2157
2158         become_root();
2159         status = schannel_get_creds_state(p->mem_ctx, lp_ctx,
2160                                           r->in.computer_name, &creds);
2161         unbecome_root();
2162         talloc_unlink(p->mem_ctx, lp_ctx);
2163
2164         if (!NT_STATUS_IS_OK(status)) {
2165                 return status;
2166         }
2167
2168         status = _netr_LogonSamLogon_base(p, r, creds);
2169         TALLOC_FREE(creds);
2170
2171         return status;
2172 }
2173
2174 /*************************************************************************
2175  _ds_enum_dom_trusts
2176  *************************************************************************/
2177 #if 0   /* JERRY -- not correct */
2178  NTSTATUS _ds_enum_dom_trusts(struct pipes_struct *p, DS_Q_ENUM_DOM_TRUSTS *q_u,
2179                              DS_R_ENUM_DOM_TRUSTS *r_u)
2180 {
2181         NTSTATUS status = NT_STATUS_OK;
2182
2183         /* TODO: According to MSDN, the can only be executed against a
2184            DC or domain member running Windows 2000 or later.  Need
2185            to test against a standalone 2k server and see what it
2186            does.  A windows 2000 DC includes its own domain in the
2187            list.  --jerry */
2188
2189         return status;
2190 }
2191 #endif  /* JERRY */
2192
2193
2194 /****************************************************************
2195 ****************************************************************/
2196
2197 WERROR _netr_LogonUasLogon(struct pipes_struct *p,
2198                            struct netr_LogonUasLogon *r)
2199 {
2200         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2201         return WERR_NOT_SUPPORTED;
2202 }
2203
2204 /****************************************************************
2205 ****************************************************************/
2206
2207 WERROR _netr_LogonUasLogoff(struct pipes_struct *p,
2208                             struct netr_LogonUasLogoff *r)
2209 {
2210         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2211         return WERR_NOT_SUPPORTED;
2212 }
2213
2214 /****************************************************************
2215 ****************************************************************/
2216
2217 NTSTATUS _netr_DatabaseDeltas(struct pipes_struct *p,
2218                               struct netr_DatabaseDeltas *r)
2219 {
2220         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2221         return NT_STATUS_NOT_IMPLEMENTED;
2222 }
2223
2224 /****************************************************************
2225 ****************************************************************/
2226
2227 NTSTATUS _netr_DatabaseSync(struct pipes_struct *p,
2228                             struct netr_DatabaseSync *r)
2229 {
2230         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2231         return NT_STATUS_NOT_IMPLEMENTED;
2232 }
2233
2234 /****************************************************************
2235 ****************************************************************/
2236
2237 NTSTATUS _netr_AccountDeltas(struct pipes_struct *p,
2238                              struct netr_AccountDeltas *r)
2239 {
2240         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2241         return NT_STATUS_NOT_IMPLEMENTED;
2242 }
2243
2244 /****************************************************************
2245 ****************************************************************/
2246
2247 NTSTATUS _netr_AccountSync(struct pipes_struct *p,
2248                            struct netr_AccountSync *r)
2249 {
2250         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2251         return NT_STATUS_NOT_IMPLEMENTED;
2252 }
2253
2254 /****************************************************************
2255 ****************************************************************/
2256
2257 static bool wb_getdcname(TALLOC_CTX *mem_ctx,
2258                          const char *domain,
2259                          const char **dcname,
2260                          uint32_t flags,
2261                          WERROR *werr)
2262 {
2263         wbcErr result;
2264         struct wbcDomainControllerInfo *dc_info = NULL;
2265
2266         result = wbcLookupDomainController(domain,
2267                                            flags,
2268                                            &dc_info);
2269         switch (result) {
2270         case WBC_ERR_SUCCESS:
2271                 break;
2272         case WBC_ERR_WINBIND_NOT_AVAILABLE:
2273                 return false;
2274         case WBC_ERR_DOMAIN_NOT_FOUND:
2275                 *werr = WERR_NO_SUCH_DOMAIN;
2276                 return true;
2277         default:
2278                 *werr = WERR_DOMAIN_CONTROLLER_NOT_FOUND;
2279                 return true;
2280         }
2281
2282         *dcname = talloc_strdup(mem_ctx, dc_info->dc_name);
2283         wbcFreeMemory(dc_info);
2284         if (!*dcname) {
2285                 *werr = WERR_NOT_ENOUGH_MEMORY;
2286                 return false;
2287         }
2288
2289         *werr = WERR_OK;
2290
2291         return true;
2292 }
2293
2294 /****************************************************************
2295  _netr_GetDcName
2296 ****************************************************************/
2297
2298 WERROR _netr_GetDcName(struct pipes_struct *p,
2299                        struct netr_GetDcName *r)
2300 {
2301         NTSTATUS status;
2302         WERROR werr;
2303         uint32_t flags;
2304         struct netr_DsRGetDCNameInfo *info;
2305         bool ret;
2306
2307         ret = wb_getdcname(p->mem_ctx,
2308                            r->in.domainname,
2309                            r->out.dcname,
2310                            WBC_LOOKUP_DC_IS_FLAT_NAME |
2311                            WBC_LOOKUP_DC_RETURN_FLAT_NAME |
2312                            WBC_LOOKUP_DC_PDC_REQUIRED,
2313                            &werr);
2314         if (ret == true) {
2315                 return werr;
2316         }
2317
2318         flags = DS_PDC_REQUIRED | DS_IS_FLAT_NAME | DS_RETURN_FLAT_NAME;
2319
2320         status = dsgetdcname(p->mem_ctx,
2321                              p->msg_ctx,
2322                              r->in.domainname,
2323                              NULL,
2324                              NULL,
2325                              flags,
2326                              &info);
2327         if (!NT_STATUS_IS_OK(status)) {
2328                 return ntstatus_to_werror(status);
2329         }
2330
2331         *r->out.dcname = talloc_strdup(p->mem_ctx, info->dc_unc);
2332         talloc_free(info);
2333         if (!*r->out.dcname) {
2334                 return WERR_NOT_ENOUGH_MEMORY;
2335         }
2336
2337         return WERR_OK;
2338 }
2339
2340 /****************************************************************
2341  _netr_GetAnyDCName
2342 ****************************************************************/
2343
2344 WERROR _netr_GetAnyDCName(struct pipes_struct *p,
2345                           struct netr_GetAnyDCName *r)
2346 {
2347         NTSTATUS status;
2348         WERROR werr;
2349         uint32_t flags;
2350         struct netr_DsRGetDCNameInfo *info;
2351         bool ret;
2352
2353         ret = wb_getdcname(p->mem_ctx,
2354                            r->in.domainname,
2355                            r->out.dcname,
2356                            WBC_LOOKUP_DC_IS_FLAT_NAME |
2357                            WBC_LOOKUP_DC_RETURN_FLAT_NAME,
2358                            &werr);
2359         if (ret == true) {
2360                 return werr;
2361         }
2362
2363         flags = DS_IS_FLAT_NAME | DS_RETURN_FLAT_NAME;
2364
2365         status = dsgetdcname(p->mem_ctx,
2366                              p->msg_ctx,
2367                              r->in.domainname,
2368                              NULL,
2369                              NULL,
2370                              flags,
2371                              &info);
2372         if (!NT_STATUS_IS_OK(status)) {
2373                 return ntstatus_to_werror(status);
2374         }
2375
2376         *r->out.dcname = talloc_strdup(p->mem_ctx, info->dc_unc);
2377         talloc_free(info);
2378         if (!*r->out.dcname) {
2379                 return WERR_NOT_ENOUGH_MEMORY;
2380         }
2381
2382         return WERR_OK;
2383 }
2384
2385 /****************************************************************
2386 ****************************************************************/
2387
2388 NTSTATUS _netr_DatabaseSync2(struct pipes_struct *p,
2389                              struct netr_DatabaseSync2 *r)
2390 {
2391         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2392         return NT_STATUS_NOT_IMPLEMENTED;
2393 }
2394
2395 /****************************************************************
2396 ****************************************************************/
2397
2398 NTSTATUS _netr_DatabaseRedo(struct pipes_struct *p,
2399                             struct netr_DatabaseRedo *r)
2400 {
2401         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2402         return NT_STATUS_NOT_IMPLEMENTED;
2403 }
2404
2405 /****************************************************************
2406 ****************************************************************/
2407
2408 WERROR _netr_DsRGetDCName(struct pipes_struct *p,
2409                           struct netr_DsRGetDCName *r)
2410 {
2411         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2412         return WERR_NOT_SUPPORTED;
2413 }
2414
2415 /****************************************************************
2416 ****************************************************************/
2417
2418 NTSTATUS _netr_LogonGetCapabilities(struct pipes_struct *p,
2419                                     struct netr_LogonGetCapabilities *r)
2420 {
2421         struct netlogon_creds_CredentialState *creds;
2422         NTSTATUS status;
2423
2424         become_root();
2425         status = netr_creds_server_step_check(p, p->mem_ctx,
2426                                               r->in.computer_name,
2427                                               r->in.credential,
2428                                               r->out.return_authenticator,
2429                                               &creds);
2430         unbecome_root();
2431         if (!NT_STATUS_IS_OK(status)) {
2432                 return status;
2433         }
2434
2435         if (r->in.query_level != 1) {
2436                 return NT_STATUS_NOT_SUPPORTED;
2437         }
2438
2439         r->out.capabilities->server_capabilities = creds->negotiate_flags;
2440
2441         return NT_STATUS_OK;
2442 }
2443
2444 /****************************************************************
2445 ****************************************************************/
2446
2447 WERROR _netr_NETRLOGONSETSERVICEBITS(struct pipes_struct *p,
2448                                      struct netr_NETRLOGONSETSERVICEBITS *r)
2449 {
2450         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2451         return WERR_NOT_SUPPORTED;
2452 }
2453
2454 /****************************************************************
2455 ****************************************************************/
2456
2457 WERROR _netr_LogonGetTrustRid(struct pipes_struct *p,
2458                               struct netr_LogonGetTrustRid *r)
2459 {
2460         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2461         return WERR_NOT_SUPPORTED;
2462 }
2463
2464 /****************************************************************
2465 ****************************************************************/
2466
2467 WERROR _netr_NETRLOGONCOMPUTESERVERDIGEST(struct pipes_struct *p,
2468                                           struct netr_NETRLOGONCOMPUTESERVERDIGEST *r)
2469 {
2470         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2471         return WERR_NOT_SUPPORTED;
2472 }
2473
2474 /****************************************************************
2475 ****************************************************************/
2476
2477 WERROR _netr_NETRLOGONCOMPUTECLIENTDIGEST(struct pipes_struct *p,
2478                                           struct netr_NETRLOGONCOMPUTECLIENTDIGEST *r)
2479 {
2480         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2481         return WERR_NOT_SUPPORTED;
2482 }
2483
2484 /****************************************************************
2485 ****************************************************************/
2486
2487 WERROR _netr_DsRGetDCNameEx(struct pipes_struct *p,
2488                             struct netr_DsRGetDCNameEx *r)
2489 {
2490         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2491         return WERR_NOT_SUPPORTED;
2492 }
2493
2494 /****************************************************************
2495 ****************************************************************/
2496
2497 WERROR _netr_DsRGetSiteName(struct pipes_struct *p,
2498                             struct netr_DsRGetSiteName *r)
2499 {
2500         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2501         return WERR_NOT_SUPPORTED;
2502 }
2503
2504 /****************************************************************
2505 ****************************************************************/
2506
2507 NTSTATUS _netr_LogonGetDomainInfo(struct pipes_struct *p,
2508                                   struct netr_LogonGetDomainInfo *r)
2509 {
2510         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2511         return NT_STATUS_NOT_IMPLEMENTED;
2512 }
2513
2514 /****************************************************************
2515 ****************************************************************/
2516
2517 NTSTATUS _netr_ServerPasswordGet(struct pipes_struct *p,
2518                                  struct netr_ServerPasswordGet *r)
2519 {
2520         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2521         return NT_STATUS_NOT_SUPPORTED;
2522 }
2523
2524 /****************************************************************
2525 ****************************************************************/
2526
2527 NTSTATUS _netr_NetrLogonSendToSam(struct pipes_struct *p,
2528                                 struct netr_NetrLogonSendToSam *r)
2529 {
2530         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2531         return NT_STATUS_NOT_IMPLEMENTED;
2532 }
2533
2534 /****************************************************************
2535 ****************************************************************/
2536
2537 WERROR _netr_DsRAddressToSitenamesW(struct pipes_struct *p,
2538                                     struct netr_DsRAddressToSitenamesW *r)
2539 {
2540         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2541         return WERR_NOT_SUPPORTED;
2542 }
2543
2544 /****************************************************************
2545 ****************************************************************/
2546
2547 WERROR _netr_DsRGetDCNameEx2(struct pipes_struct *p,
2548                              struct netr_DsRGetDCNameEx2 *r)
2549 {
2550         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2551         return WERR_NOT_SUPPORTED;
2552 }
2553
2554 /****************************************************************
2555 ****************************************************************/
2556
2557 WERROR _netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN(struct pipes_struct *p,
2558                                                  struct netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN *r)
2559 {
2560         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2561         return WERR_NOT_SUPPORTED;
2562 }
2563
2564 /****************************************************************
2565 ****************************************************************/
2566
2567 WERROR _netr_NetrEnumerateTrustedDomainsEx(struct pipes_struct *p,
2568                                            struct netr_NetrEnumerateTrustedDomainsEx *r)
2569 {
2570         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2571         return WERR_NOT_SUPPORTED;
2572 }
2573
2574 /****************************************************************
2575 ****************************************************************/
2576
2577 WERROR _netr_DsRAddressToSitenamesExW(struct pipes_struct *p,
2578                                       struct netr_DsRAddressToSitenamesExW *r)
2579 {
2580         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2581         return WERR_NOT_SUPPORTED;
2582 }
2583
2584 /****************************************************************
2585 ****************************************************************/
2586
2587 WERROR _netr_DsrGetDcSiteCoverageW(struct pipes_struct *p,
2588                                    struct netr_DsrGetDcSiteCoverageW *r)
2589 {
2590         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2591         return WERR_NOT_SUPPORTED;
2592 }
2593
2594 /****************************************************************
2595 ****************************************************************/
2596
2597 WERROR _netr_DsrEnumerateDomainTrusts(struct pipes_struct *p,
2598                                       struct netr_DsrEnumerateDomainTrusts *r)
2599 {
2600         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2601         return WERR_NOT_SUPPORTED;
2602 }
2603
2604 /****************************************************************
2605 ****************************************************************/
2606
2607 WERROR _netr_DsrDeregisterDNSHostRecords(struct pipes_struct *p,
2608                                          struct netr_DsrDeregisterDNSHostRecords *r)
2609 {
2610         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2611         return WERR_NOT_SUPPORTED;
2612 }
2613
2614 /****************************************************************
2615 ****************************************************************/
2616
2617 NTSTATUS _netr_ServerTrustPasswordsGet(struct pipes_struct *p,
2618                                        struct netr_ServerTrustPasswordsGet *r)
2619 {
2620         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2621         return NT_STATUS_NOT_IMPLEMENTED;
2622 }
2623
2624 /****************************************************************
2625 ****************************************************************/
2626
2627 static NTSTATUS fill_forest_trust_array(TALLOC_CTX *mem_ctx,
2628                                         struct lsa_ForestTrustInformation *info)
2629 {
2630         struct lsa_ForestTrustRecord *e;
2631         struct pdb_domain_info *dom_info;
2632         struct lsa_ForestTrustDomainInfo *domain_info;
2633         char **upn_suffixes = NULL;
2634         uint32_t num_suffixes = 0;
2635         uint32_t i = 0;
2636         NTSTATUS status;
2637
2638         dom_info = pdb_get_domain_info(mem_ctx);
2639         if (dom_info == NULL) {
2640                 return NT_STATUS_NO_MEMORY;
2641         }
2642
2643         info->count = 2;
2644
2645         become_root();
2646         status = pdb_enum_upn_suffixes(info, &num_suffixes, &upn_suffixes);
2647         unbecome_root();
2648         if (NT_STATUS_IS_OK(status) && (num_suffixes > 0)) {
2649                 info->count += num_suffixes;
2650         }
2651
2652         info->entries = talloc_array(info, struct lsa_ForestTrustRecord *, info->count);
2653         if (info->entries == NULL) {
2654                 return NT_STATUS_NO_MEMORY;
2655         }
2656
2657         e = talloc(info, struct lsa_ForestTrustRecord);
2658         if (e == NULL) {
2659                 return NT_STATUS_NO_MEMORY;
2660         }
2661
2662         e->flags = 0;
2663         e->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME;
2664         e->time = 0; /* so far always 0 in trces. */
2665         e->forest_trust_data.top_level_name.string = talloc_steal(info,
2666                                                                   dom_info->dns_forest);
2667
2668         info->entries[0] = e;
2669
2670         if (num_suffixes > 0) {
2671                 for (i = 0; i < num_suffixes ; i++) {
2672                         e = talloc(info, struct lsa_ForestTrustRecord);
2673                         if (e == NULL) {
2674                                 return NT_STATUS_NO_MEMORY;
2675                         }
2676
2677                         e->flags = 0;
2678                         e->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME;
2679                         e->time = 0; /* so far always 0 in traces. */
2680                         e->forest_trust_data.top_level_name.string = upn_suffixes[i];
2681                         info->entries[1 + i] = e;
2682                 }
2683         }
2684
2685         e = talloc(info, struct lsa_ForestTrustRecord);
2686         if (e == NULL) {
2687                 return NT_STATUS_NO_MEMORY;
2688         }
2689
2690         /* TODO: check if disabled and set flags accordingly */
2691         e->flags = 0;
2692         e->type = LSA_FOREST_TRUST_DOMAIN_INFO;
2693         e->time = 0; /* so far always 0 in traces. */
2694
2695         domain_info = &e->forest_trust_data.domain_info;
2696         domain_info->domain_sid = dom_sid_dup(info, &dom_info->sid);
2697
2698         domain_info->dns_domain_name.string = talloc_steal(info,
2699                                                            dom_info->dns_domain);
2700         domain_info->netbios_domain_name.string = talloc_steal(info,
2701                                                                dom_info->name);
2702
2703         info->entries[info->count - 1] = e;
2704
2705         return NT_STATUS_OK;
2706 }
2707
2708 /****************************************************************
2709 ****************************************************************/
2710
2711 WERROR _netr_DsRGetForestTrustInformation(struct pipes_struct *p,
2712                                           struct netr_DsRGetForestTrustInformation *r)
2713 {
2714         struct dcesrv_call_state *dce_call = p->dce_call;
2715         struct auth_session_info *session_info =
2716                 dcesrv_call_session_info(dce_call);
2717         NTSTATUS status;
2718         struct lsa_ForestTrustInformation *info, **info_ptr;
2719         enum security_user_level security_level;
2720
2721         security_level = security_session_user_level(session_info, NULL);
2722         if (security_level < SECURITY_USER) {
2723                 return WERR_ACCESS_DENIED;
2724         }
2725
2726         if (r->in.flags & (~DS_GFTI_UPDATE_TDO)) {
2727                 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2728                 return WERR_INVALID_FLAGS;
2729         }
2730
2731         if ((r->in.flags & DS_GFTI_UPDATE_TDO) && (lp_server_role() != ROLE_DOMAIN_PDC)) {
2732                 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2733                 return WERR_NERR_NOTPRIMARY;
2734         }
2735
2736         if ((r->in.trusted_domain_name == NULL) && (r->in.flags & DS_GFTI_UPDATE_TDO)) {
2737                 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2738                 return WERR_INVALID_PARAMETER;
2739         }
2740
2741         /* retrieve forest trust information and stop further processing */
2742         if (r->in.trusted_domain_name == NULL) {
2743                 info_ptr = talloc(p->mem_ctx, struct lsa_ForestTrustInformation *);
2744                 if (info_ptr == NULL) {
2745                         p->fault_state = DCERPC_FAULT_CANT_PERFORM;
2746                         return WERR_NOT_ENOUGH_MEMORY;
2747                 }
2748                 info = talloc_zero(info_ptr, struct lsa_ForestTrustInformation);
2749                 if (info == NULL) {
2750                         p->fault_state = DCERPC_FAULT_CANT_PERFORM;
2751                         return WERR_NOT_ENOUGH_MEMORY;
2752                 }
2753
2754                 /* Fill forest trust information and expand UPN suffixes list */
2755                 status = fill_forest_trust_array(p->mem_ctx, info);
2756                 if (!NT_STATUS_IS_OK(status)) {
2757                         p->fault_state = DCERPC_FAULT_CANT_PERFORM;
2758                         return WERR_NOT_ENOUGH_MEMORY;
2759                 }
2760
2761                 *info_ptr = info;
2762                 r->out.forest_trust_info = info_ptr;
2763
2764                 return WERR_OK;
2765
2766         }
2767
2768         /* TODO: implement remaining parts of DsrGetForestTrustInformation (opnum 43)
2769          *       when trusted_domain_name is not NULL */
2770
2771         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2772         return WERR_NOT_SUPPORTED;
2773 }
2774
2775 /****************************************************************
2776  _netr_GetForestTrustInformation
2777 ****************************************************************/
2778
2779 NTSTATUS _netr_GetForestTrustInformation(struct pipes_struct *p,
2780                                          struct netr_GetForestTrustInformation *r)
2781 {
2782         NTSTATUS status;
2783         struct netlogon_creds_CredentialState *creds;
2784         struct lsa_ForestTrustInformation *info, **info_ptr;
2785
2786         /* TODO: check server name */
2787
2788         become_root();
2789         status = netr_creds_server_step_check(p, p->mem_ctx,
2790                                               r->in.computer_name,
2791                                               r->in.credential,
2792                                               r->out.return_authenticator,
2793                                               &creds);
2794         unbecome_root();
2795         if (!NT_STATUS_IS_OK(status)) {
2796                 return status;
2797         }
2798
2799         if ((creds->secure_channel_type != SEC_CHAN_DNS_DOMAIN) &&
2800             (creds->secure_channel_type != SEC_CHAN_DOMAIN)) {
2801                 return NT_STATUS_NOT_IMPLEMENTED;
2802         }
2803
2804         info_ptr = talloc(p->mem_ctx, struct lsa_ForestTrustInformation *);
2805         if (!info_ptr) {
2806                 return NT_STATUS_NO_MEMORY;
2807         }
2808         info = talloc_zero(info_ptr, struct lsa_ForestTrustInformation);
2809         if (!info) {
2810                 return NT_STATUS_NO_MEMORY;
2811         }
2812
2813         /* Fill forest trust information, do expand UPN suffixes list */
2814         status = fill_forest_trust_array(p->mem_ctx, info);
2815         if (!NT_STATUS_IS_OK(status)) {
2816                 return status;
2817         }
2818
2819         *info_ptr = info;
2820         r->out.forest_trust_info = info_ptr;
2821
2822         return NT_STATUS_OK;
2823 }
2824
2825 /****************************************************************
2826 ****************************************************************/
2827
2828 static NTSTATUS get_password_from_trustAuth(TALLOC_CTX *mem_ctx,
2829                                             const DATA_BLOB *trustAuth_blob,
2830                                             struct netlogon_creds_CredentialState *creds,
2831                                             struct samr_Password *current_pw_enc,
2832                                             struct samr_Password *previous_pw_enc)
2833 {
2834         enum ndr_err_code ndr_err;
2835         struct trustAuthInOutBlob trustAuth;
2836         NTSTATUS status;
2837
2838         ndr_err = ndr_pull_struct_blob_all(trustAuth_blob, mem_ctx, &trustAuth,
2839                                            (ndr_pull_flags_fn_t)ndr_pull_trustAuthInOutBlob);
2840         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2841                 return NT_STATUS_UNSUCCESSFUL;
2842         }
2843
2844         if (trustAuth.count != 0 && trustAuth.current.count != 0 &&
2845             trustAuth.current.array[0].AuthType == TRUST_AUTH_TYPE_CLEAR) {
2846                 mdfour(current_pw_enc->hash,
2847                        trustAuth.current.array[0].AuthInfo.clear.password,
2848                        trustAuth.current.array[0].AuthInfo.clear.size);
2849                 status = netlogon_creds_des_encrypt(creds, current_pw_enc);
2850                 if (!NT_STATUS_IS_OK(status)) {
2851                         return status;
2852                 }
2853         } else {
2854                 return NT_STATUS_UNSUCCESSFUL;
2855         }
2856
2857
2858         if (trustAuth.previous.count != 0 &&
2859             trustAuth.previous.array[0].AuthType == TRUST_AUTH_TYPE_CLEAR) {
2860                 mdfour(previous_pw_enc->hash,
2861                        trustAuth.previous.array[0].AuthInfo.clear.password,
2862                        trustAuth.previous.array[0].AuthInfo.clear.size);
2863                 status = netlogon_creds_des_encrypt(creds, previous_pw_enc);
2864                 if (!NT_STATUS_IS_OK(status)) {
2865                         return status;
2866                 }
2867         } else {
2868                 ZERO_STRUCTP(previous_pw_enc);
2869         }
2870
2871         return NT_STATUS_OK;
2872 }
2873
2874 /****************************************************************
2875  _netr_ServerGetTrustInfo
2876 ****************************************************************/
2877
2878 NTSTATUS _netr_ServerGetTrustInfo(struct pipes_struct *p,
2879                                   struct netr_ServerGetTrustInfo *r)
2880 {
2881         NTSTATUS status;
2882         struct netlogon_creds_CredentialState *creds;
2883         char *account_name;
2884         size_t account_name_last;
2885         bool trusted;
2886         struct netr_TrustInfo *trust_info;
2887         struct pdb_trusted_domain *td;
2888
2889         /* TODO: check server name */
2890
2891         become_root();
2892         status = netr_creds_server_step_check(p, p->mem_ctx,
2893                                               r->in.computer_name,
2894                                               r->in.credential,
2895                                               r->out.return_authenticator,
2896                                               &creds);
2897         unbecome_root();
2898         if (!NT_STATUS_IS_OK(status)) {
2899                 return status;
2900         }
2901
2902         account_name = talloc_strdup(p->mem_ctx, r->in.account_name);
2903         if (account_name == NULL) {
2904                 return NT_STATUS_NO_MEMORY;
2905         }
2906
2907         account_name_last = strlen(account_name);
2908         if (account_name_last == 0) {
2909                 return NT_STATUS_INVALID_PARAMETER;
2910         }
2911         account_name_last--;
2912         if (account_name[account_name_last] == '.') {
2913                 account_name[account_name_last] = '\0';
2914         }
2915
2916         if ((creds->secure_channel_type != SEC_CHAN_DNS_DOMAIN) &&
2917             (creds->secure_channel_type != SEC_CHAN_DOMAIN)) {
2918                 trusted = false;
2919         } else {
2920                 trusted = true;
2921         }
2922
2923
2924         if (trusted) {
2925                 account_name_last = strlen(account_name);
2926                 if (account_name_last == 0) {
2927                         return NT_STATUS_INVALID_PARAMETER;
2928                 }
2929                 account_name_last--;
2930                 if (account_name[account_name_last] == '$') {
2931                         account_name[account_name_last] = '\0';
2932                 }
2933
2934                 status = pdb_get_trusted_domain(p->mem_ctx, account_name, &td);
2935                 if (!NT_STATUS_IS_OK(status)) {
2936                         return status;
2937                 }
2938
2939                 if (r->out.trust_info != NULL) {
2940                         trust_info = talloc_zero(p->mem_ctx, struct netr_TrustInfo);
2941                         if (trust_info == NULL) {
2942                                 return NT_STATUS_NO_MEMORY;
2943                         }
2944                         trust_info->count = 1;
2945
2946                         trust_info->data = talloc_array(trust_info, uint32_t, 1);
2947                         if (trust_info->data == NULL) {
2948                                 return NT_STATUS_NO_MEMORY;
2949                         }
2950                         trust_info->data[0] = td->trust_attributes;
2951
2952                         *r->out.trust_info = trust_info;
2953                 }
2954
2955                 if (td->trust_auth_incoming.data == NULL) {
2956                         return NT_STATUS_INVALID_PARAMETER;
2957                 }
2958
2959                 status = get_password_from_trustAuth(p->mem_ctx,
2960                                                      &td->trust_auth_incoming,
2961                                                      creds,
2962                                                      r->out.new_owf_password,
2963                                                      r->out.old_owf_password);
2964
2965                 if (!NT_STATUS_IS_OK(status)) {
2966                         return status;
2967                 }
2968
2969         } else {
2970 /* TODO: look for machine password */
2971                 ZERO_STRUCTP(r->out.new_owf_password);
2972                 ZERO_STRUCTP(r->out.old_owf_password);
2973
2974                 return NT_STATUS_NOT_IMPLEMENTED;
2975         }
2976
2977         return NT_STATUS_OK;
2978 }
2979
2980 /****************************************************************
2981 ****************************************************************/
2982
2983 NTSTATUS _netr_Unused47(struct pipes_struct *p,
2984                         struct netr_Unused47 *r)
2985 {
2986         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2987         return NT_STATUS_NOT_IMPLEMENTED;
2988 }
2989
2990 /****************************************************************
2991 ****************************************************************/
2992
2993 NTSTATUS _netr_DsrUpdateReadOnlyServerDnsRecords(struct pipes_struct *p,
2994                                                  struct netr_DsrUpdateReadOnlyServerDnsRecords *r)
2995 {
2996         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
2997         return NT_STATUS_NOT_IMPLEMENTED;
2998 }
2999
3000 /* include the generated boilerplate */
3001 #include "librpc/gen_ndr/ndr_netlogon_scompat.c"