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