bcf5c000b3a9a208b0b49e3eb94f1e8b75b2729a
[ira/wip.git] / source3 / rpc_server / 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 "../libcli/auth/libcli_auth.h"
29 #include "../libcli/auth/schannel_state.h"
30 #include "../libcli/auth/schannel.h"
31
32 extern userdom_struct current_user_info;
33
34 #undef DBGC_CLASS
35 #define DBGC_CLASS DBGC_RPC_SRV
36
37 struct netlogon_server_pipe_state {
38         struct netr_Credential client_challenge;
39         struct netr_Credential server_challenge;
40 };
41
42 /*************************************************************************
43  _netr_LogonControl
44  *************************************************************************/
45
46 WERROR _netr_LogonControl(pipes_struct *p,
47                           struct netr_LogonControl *r)
48 {
49         struct netr_LogonControl2Ex l;
50
51         switch (r->in.level) {
52         case 1:
53                 break;
54         case 2:
55                 return WERR_NOT_SUPPORTED;
56         default:
57                 return WERR_UNKNOWN_LEVEL;
58         }
59
60         l.in.logon_server       = r->in.logon_server;
61         l.in.function_code      = r->in.function_code;
62         l.in.level              = r->in.level;
63         l.in.data               = NULL;
64         l.out.query             = r->out.query;
65
66         return _netr_LogonControl2Ex(p, &l);
67 }
68
69 /****************************************************************************
70 Send a message to smbd to do a sam synchronisation
71 **************************************************************************/
72
73 static void send_sync_message(void)
74 {
75         DEBUG(3, ("sending sam synchronisation message\n"));
76         message_send_all(smbd_messaging_context(), MSG_SMB_SAM_SYNC, NULL, 0,
77                          NULL);
78 }
79
80 /*************************************************************************
81  _netr_LogonControl2
82  *************************************************************************/
83
84 WERROR _netr_LogonControl2(pipes_struct *p,
85                            struct netr_LogonControl2 *r)
86 {
87         struct netr_LogonControl2Ex l;
88
89         l.in.logon_server       = r->in.logon_server;
90         l.in.function_code      = r->in.function_code;
91         l.in.level              = r->in.level;
92         l.in.data               = r->in.data;
93         l.out.query             = r->out.query;
94
95         return _netr_LogonControl2Ex(p, &l);
96 }
97
98 /*************************************************************************
99  *************************************************************************/
100
101 static bool wb_change_trust_creds(const char *domain, WERROR *tc_status)
102 {
103         wbcErr result;
104         struct wbcAuthErrorInfo *error = NULL;
105
106         result = wbcChangeTrustCredentials(domain, &error);
107         switch (result) {
108         case WBC_ERR_WINBIND_NOT_AVAILABLE:
109                 return false;
110         case WBC_ERR_DOMAIN_NOT_FOUND:
111                 *tc_status = WERR_NO_SUCH_DOMAIN;
112                 return true;
113         case WBC_ERR_SUCCESS:
114                 *tc_status = WERR_OK;
115                 return true;
116         default:
117                 break;
118         }
119
120         if (error && error->nt_status != 0) {
121                 *tc_status = ntstatus_to_werror(NT_STATUS(error->nt_status));
122         } else {
123                 *tc_status = WERR_TRUST_FAILURE;
124         }
125         wbcFreeMemory(error);
126         return true;
127 }
128
129 /*************************************************************************
130  *************************************************************************/
131
132 static bool wb_check_trust_creds(const char *domain, WERROR *tc_status)
133 {
134         wbcErr result;
135         struct wbcAuthErrorInfo *error = NULL;
136
137         result = wbcCheckTrustCredentials(domain, &error);
138         switch (result) {
139         case WBC_ERR_WINBIND_NOT_AVAILABLE:
140                 return false;
141         case WBC_ERR_DOMAIN_NOT_FOUND:
142                 *tc_status = WERR_NO_SUCH_DOMAIN;
143                 return true;
144         case WBC_ERR_SUCCESS:
145                 *tc_status = WERR_OK;
146                 return true;
147         default:
148                 break;
149         }
150
151         if (error && error->nt_status != 0) {
152                 *tc_status = ntstatus_to_werror(NT_STATUS(error->nt_status));
153         } else {
154                 *tc_status = WERR_TRUST_FAILURE;
155         }
156         wbcFreeMemory(error);
157         return true;
158 }
159
160 /****************************************************************
161  _netr_LogonControl2Ex
162 ****************************************************************/
163
164 WERROR _netr_LogonControl2Ex(pipes_struct *p,
165                              struct netr_LogonControl2Ex *r)
166 {
167         uint32_t flags = 0x0;
168         WERROR pdc_connection_status = WERR_OK;
169         uint32_t logon_attempts = 0x0;
170         WERROR tc_status;
171         fstring dc_name2;
172         const char *dc_name = NULL;
173         struct sockaddr_storage dc_ss;
174         const char *domain = NULL;
175         struct netr_NETLOGON_INFO_1 *info1;
176         struct netr_NETLOGON_INFO_2 *info2;
177         struct netr_NETLOGON_INFO_3 *info3;
178         struct netr_NETLOGON_INFO_4 *info4;
179         const char *fn;
180
181         switch (p->hdr_req.opnum) {
182         case NDR_NETR_LOGONCONTROL:
183                 fn = "_netr_LogonControl";
184                 break;
185         case NDR_NETR_LOGONCONTROL2:
186                 fn = "_netr_LogonControl2";
187                 break;
188         case NDR_NETR_LOGONCONTROL2EX:
189                 fn = "_netr_LogonControl2Ex";
190                 break;
191         default:
192                 return WERR_INVALID_PARAM;
193         }
194
195         switch (r->in.function_code) {
196         case NETLOGON_CONTROL_TC_VERIFY:
197         case NETLOGON_CONTROL_CHANGE_PASSWORD:
198         case NETLOGON_CONTROL_REDISCOVER:
199                 if (!nt_token_check_domain_rid(p->server_info->ptok, DOMAIN_GROUP_RID_ADMINS) &&
200                     !nt_token_check_sid(&global_sid_Builtin_Administrators, p->server_info->ptok)) {
201                         return WERR_ACCESS_DENIED;
202                 }
203                 break;
204         default:
205                 break;
206         }
207
208         tc_status = WERR_NO_SUCH_DOMAIN;
209
210         switch (r->in.function_code) {
211         case NETLOGON_CONTROL_QUERY:
212                 tc_status = WERR_OK;
213                 break;
214         case NETLOGON_CONTROL_REPLICATE:
215         case NETLOGON_CONTROL_SYNCHRONIZE:
216         case NETLOGON_CONTROL_PDC_REPLICATE:
217         case NETLOGON_CONTROL_BACKUP_CHANGE_LOG:
218         case NETLOGON_CONTROL_TRUNCATE_LOG:
219         case NETLOGON_CONTROL_BREAKPOINT:
220                 return WERR_ACCESS_DENIED;
221         case NETLOGON_CONTROL_TRANSPORT_NOTIFY:
222         case NETLOGON_CONTROL_FORCE_DNS_REG:
223         case NETLOGON_CONTROL_QUERY_DNS_REG:
224                 return WERR_NOT_SUPPORTED;
225         case NETLOGON_CONTROL_FIND_USER:
226                 if (!r->in.data || !r->in.data->user) {
227                         return WERR_NOT_SUPPORTED;
228                 }
229                 break;
230         case NETLOGON_CONTROL_SET_DBFLAG:
231                 if (!r->in.data) {
232                         return WERR_NOT_SUPPORTED;
233                 }
234                 break;
235         case NETLOGON_CONTROL_TC_VERIFY:
236                 if (!r->in.data || !r->in.data->domain) {
237                         return WERR_NOT_SUPPORTED;
238                 }
239
240                 if (!wb_check_trust_creds(r->in.data->domain, &tc_status)) {
241                         return WERR_NOT_SUPPORTED;
242                 }
243                 break;
244         case NETLOGON_CONTROL_TC_QUERY:
245                 if (!r->in.data || !r->in.data->domain) {
246                         return WERR_NOT_SUPPORTED;
247                 }
248
249                 domain = r->in.data->domain;
250
251                 if (!is_trusted_domain(domain)) {
252                         break;
253                 }
254
255                 if (!get_dc_name(domain, NULL, dc_name2, &dc_ss)) {
256                         tc_status = WERR_NO_LOGON_SERVERS;
257                         break;
258                 }
259
260                 dc_name = talloc_asprintf(p->mem_ctx, "\\\\%s", dc_name2);
261                 if (!dc_name) {
262                         return WERR_NOMEM;
263                 }
264
265                 tc_status = WERR_OK;
266
267                 break;
268
269         case NETLOGON_CONTROL_REDISCOVER:
270                 if (!r->in.data || !r->in.data->domain) {
271                         return WERR_NOT_SUPPORTED;
272                 }
273
274                 domain = r->in.data->domain;
275
276                 if (!is_trusted_domain(domain)) {
277                         break;
278                 }
279
280                 if (!get_dc_name(domain, NULL, dc_name2, &dc_ss)) {
281                         tc_status = WERR_NO_LOGON_SERVERS;
282                         break;
283                 }
284
285                 dc_name = talloc_asprintf(p->mem_ctx, "\\\\%s", dc_name2);
286                 if (!dc_name) {
287                         return WERR_NOMEM;
288                 }
289
290                 tc_status = WERR_OK;
291
292                 break;
293
294         case NETLOGON_CONTROL_CHANGE_PASSWORD:
295                 if (!r->in.data || !r->in.data->domain) {
296                         return WERR_NOT_SUPPORTED;
297                 }
298
299                 if (!wb_change_trust_creds(r->in.data->domain, &tc_status)) {
300                         return WERR_NOT_SUPPORTED;
301                 }
302                 break;
303
304         default:
305                 /* no idea what this should be */
306                 DEBUG(0,("%s: unimplemented function level [%d]\n",
307                         fn, r->in.function_code));
308                 return WERR_UNKNOWN_LEVEL;
309         }
310
311         /* prepare the response */
312
313         switch (r->in.level) {
314         case 1:
315                 info1 = TALLOC_ZERO_P(p->mem_ctx, struct netr_NETLOGON_INFO_1);
316                 W_ERROR_HAVE_NO_MEMORY(info1);
317
318                 info1->flags                    = flags;
319                 info1->pdc_connection_status    = pdc_connection_status;
320
321                 r->out.query->info1 = info1;
322                 break;
323         case 2:
324                 info2 = TALLOC_ZERO_P(p->mem_ctx, struct netr_NETLOGON_INFO_2);
325                 W_ERROR_HAVE_NO_MEMORY(info2);
326
327                 info2->flags                    = flags;
328                 info2->pdc_connection_status    = pdc_connection_status;
329                 info2->trusted_dc_name          = dc_name;
330                 info2->tc_connection_status     = tc_status;
331
332                 r->out.query->info2 = info2;
333                 break;
334         case 3:
335                 info3 = TALLOC_ZERO_P(p->mem_ctx, struct netr_NETLOGON_INFO_3);
336                 W_ERROR_HAVE_NO_MEMORY(info3);
337
338                 info3->flags                    = flags;
339                 info3->logon_attempts           = logon_attempts;
340
341                 r->out.query->info3 = info3;
342                 break;
343         case 4:
344                 info4 = TALLOC_ZERO_P(p->mem_ctx, struct netr_NETLOGON_INFO_4);
345                 W_ERROR_HAVE_NO_MEMORY(info4);
346
347                 info4->trusted_dc_name          = dc_name;
348                 info4->trusted_domain_name      = r->in.data->domain;
349
350                 r->out.query->info4 = info4;
351                 break;
352         default:
353                 return WERR_UNKNOWN_LEVEL;
354         }
355
356         if (lp_server_role() == ROLE_DOMAIN_BDC) {
357                 send_sync_message();
358         }
359
360         return WERR_OK;
361 }
362
363 /*************************************************************************
364  _netr_NetrEnumerateTrustedDomains
365  *************************************************************************/
366
367 WERROR _netr_NetrEnumerateTrustedDomains(pipes_struct *p,
368                                          struct netr_NetrEnumerateTrustedDomains *r)
369 {
370         NTSTATUS status;
371         DATA_BLOB blob;
372         struct trustdom_info **domains;
373         uint32_t num_domains;
374         const char **trusted_domains;
375         int i;
376
377         DEBUG(6,("_netr_NetrEnumerateTrustedDomains: %d\n", __LINE__));
378
379         /* set up the Trusted Domain List response */
380
381         become_root();
382         status = pdb_enum_trusteddoms(p->mem_ctx, &num_domains, &domains);
383         unbecome_root();
384
385         if (!NT_STATUS_IS_OK(status)) {
386                 return ntstatus_to_werror(status);
387         }
388
389         trusted_domains = talloc_zero_array(p->mem_ctx, const char *, num_domains + 1);
390         if (!trusted_domains) {
391                 return WERR_NOMEM;
392         }
393
394         for (i = 0; i < num_domains; i++) {
395                 trusted_domains[i] = talloc_strdup(trusted_domains, domains[i]->name);
396                 if (!trusted_domains[i]) {
397                         TALLOC_FREE(trusted_domains);
398                         return WERR_NOMEM;
399                 }
400         }
401
402         if (!push_reg_multi_sz(trusted_domains, &blob, trusted_domains)) {
403                 TALLOC_FREE(trusted_domains);
404                 return WERR_NOMEM;
405         }
406
407         r->out.trusted_domains_blob->data = blob.data;
408         r->out.trusted_domains_blob->length = blob.length;
409
410         DEBUG(6,("_netr_NetrEnumerateTrustedDomains: %d\n", __LINE__));
411
412         return WERR_OK;
413 }
414
415 /******************************************************************
416  gets a machine password entry.  checks access rights of the host.
417  ******************************************************************/
418
419 static NTSTATUS get_md4pw(struct samr_Password *md4pw, const char *mach_acct,
420                           enum netr_SchannelType sec_chan_type, struct dom_sid *sid)
421 {
422         struct samu *sampass = NULL;
423         const uint8 *pass;
424         bool ret;
425         uint32 acct_ctrl;
426
427 #if 0
428         char addr[INET6_ADDRSTRLEN];
429
430     /*
431      * Currently this code is redundent as we already have a filter
432      * by hostname list. What this code really needs to do is to
433      * get a hosts allowed/hosts denied list from the SAM database
434      * on a per user basis, and make the access decision there.
435      * I will leave this code here for now as a reminder to implement
436      * this at a later date. JRA.
437      */
438
439         if (!allow_access(lp_domain_hostsdeny(), lp_domain_hostsallow(),
440                         client_name(get_client_fd()),
441                         client_addr(get_client_fd(),addr,sizeof(addr)))) {
442                 DEBUG(0,("get_md4pw: Workstation %s denied access to domain\n", mach_acct));
443                 return False;
444         }
445 #endif /* 0 */
446
447         if ( !(sampass = samu_new( NULL )) ) {
448                 return NT_STATUS_NO_MEMORY;
449         }
450
451         /* JRA. This is ok as it is only used for generating the challenge. */
452         become_root();
453         ret = pdb_getsampwnam(sampass, mach_acct);
454         unbecome_root();
455
456         if (!ret) {
457                 DEBUG(0,("get_md4pw: Workstation %s: no account in domain\n", mach_acct));
458                 TALLOC_FREE(sampass);
459                 return NT_STATUS_ACCESS_DENIED;
460         }
461
462         acct_ctrl = pdb_get_acct_ctrl(sampass);
463         if (acct_ctrl & ACB_DISABLED) {
464                 DEBUG(0,("get_md4pw: Workstation %s: account is disabled\n", mach_acct));
465                 TALLOC_FREE(sampass);
466                 return NT_STATUS_ACCOUNT_DISABLED;
467         }
468
469         if (!(acct_ctrl & ACB_SVRTRUST) &&
470             !(acct_ctrl & ACB_WSTRUST) &&
471             !(acct_ctrl & ACB_DOMTRUST))
472         {
473                 DEBUG(0,("get_md4pw: Workstation %s: account is not a trust account\n", mach_acct));
474                 TALLOC_FREE(sampass);
475                 return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
476         }
477
478         switch (sec_chan_type) {
479                 case SEC_CHAN_BDC:
480                         if (!(acct_ctrl & ACB_SVRTRUST)) {
481                                 DEBUG(0,("get_md4pw: Workstation %s: BDC secure channel requested "
482                                          "but not a server trust account\n", mach_acct));
483                                 TALLOC_FREE(sampass);
484                                 return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
485                         }
486                         break;
487                 case SEC_CHAN_WKSTA:
488                         if (!(acct_ctrl & ACB_WSTRUST)) {
489                                 DEBUG(0,("get_md4pw: Workstation %s: WORKSTATION secure channel requested "
490                                          "but not a workstation trust account\n", mach_acct));
491                                 TALLOC_FREE(sampass);
492                                 return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
493                         }
494                         break;
495                 case SEC_CHAN_DOMAIN:
496                         if (!(acct_ctrl & ACB_DOMTRUST)) {
497                                 DEBUG(0,("get_md4pw: Workstation %s: DOMAIN secure channel requested "
498                                          "but not a interdomain trust account\n", mach_acct));
499                                 TALLOC_FREE(sampass);
500                                 return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
501                         }
502                         break;
503                 default:
504                         break;
505         }
506
507         if ((pass = pdb_get_nt_passwd(sampass)) == NULL) {
508                 DEBUG(0,("get_md4pw: Workstation %s: account does not have a password\n", mach_acct));
509                 TALLOC_FREE(sampass);
510                 return NT_STATUS_LOGON_FAILURE;
511         }
512
513         memcpy(md4pw->hash, pass, 16);
514         dump_data(5, md4pw->hash, 16);
515
516         sid_copy(sid, pdb_get_user_sid(sampass));
517
518         TALLOC_FREE(sampass);
519
520         return NT_STATUS_OK;
521
522
523 }
524
525 /*************************************************************************
526  _netr_ServerReqChallenge
527  *************************************************************************/
528
529 NTSTATUS _netr_ServerReqChallenge(pipes_struct *p,
530                                   struct netr_ServerReqChallenge *r)
531 {
532         struct netlogon_server_pipe_state *pipe_state =
533                 talloc_get_type(p->private_data, struct netlogon_server_pipe_state);
534
535         if (pipe_state) {
536                 DEBUG(10,("_netr_ServerReqChallenge: new challenge requested. Clearing old state.\n"));
537                 talloc_free(pipe_state);
538                 p->private_data = NULL;
539         }
540
541         pipe_state = talloc(p, struct netlogon_server_pipe_state);
542         NT_STATUS_HAVE_NO_MEMORY(pipe_state);
543
544         pipe_state->client_challenge = *r->in.credentials;
545
546         generate_random_buffer(pipe_state->server_challenge.data,
547                                sizeof(pipe_state->server_challenge.data));
548
549         *r->out.return_credentials = pipe_state->server_challenge;
550
551         p->private_data = pipe_state;
552
553         return NT_STATUS_OK;
554 }
555
556 /*************************************************************************
557  _netr_ServerAuthenticate
558  Create the initial credentials.
559  *************************************************************************/
560
561 NTSTATUS _netr_ServerAuthenticate(pipes_struct *p,
562                                   struct netr_ServerAuthenticate *r)
563 {
564         struct netr_ServerAuthenticate3 a;
565         uint32_t negotiate_flags = 0;
566         uint32_t rid;
567
568         a.in.server_name                = r->in.server_name;
569         a.in.account_name               = r->in.account_name;
570         a.in.secure_channel_type        = r->in.secure_channel_type;
571         a.in.computer_name              = r->in.computer_name;
572         a.in.credentials                = r->in.credentials;
573         a.in.negotiate_flags            = &negotiate_flags;
574
575         a.out.return_credentials        = r->out.return_credentials;
576         a.out.rid                       = &rid;
577         a.out.negotiate_flags           = &negotiate_flags;
578
579         return _netr_ServerAuthenticate3(p, &a);
580
581 }
582
583 /*************************************************************************
584  _netr_ServerAuthenticate3
585  *************************************************************************/
586
587 NTSTATUS _netr_ServerAuthenticate3(pipes_struct *p,
588                                    struct netr_ServerAuthenticate3 *r)
589 {
590         NTSTATUS status;
591         uint32_t srv_flgs;
592         /* r->in.negotiate_flags is an aliased pointer to r->out.negotiate_flags,
593          * so use a copy to avoid destroying the client values. */
594         uint32_t in_neg_flags = *r->in.negotiate_flags;
595         const char *fn;
596         struct dom_sid sid;
597         struct samr_Password mach_pwd;
598         struct netlogon_creds_CredentialState *creds;
599         struct netlogon_server_pipe_state *pipe_state =
600                 talloc_get_type(p->private_data, struct netlogon_server_pipe_state);
601
602         /* According to Microsoft (see bugid #6099)
603          * Windows 7 looks at the negotiate_flags
604          * returned in this structure *even if the
605          * call fails with access denied* ! So in order
606          * to allow Win7 to connect to a Samba NT style
607          * PDC we set the flags before we know if it's
608          * an error or not.
609          */
610
611         /* 0x000001ff */
612         srv_flgs = NETLOGON_NEG_ACCOUNT_LOCKOUT |
613                    NETLOGON_NEG_PERSISTENT_SAMREPL |
614                    NETLOGON_NEG_ARCFOUR |
615                    NETLOGON_NEG_PROMOTION_COUNT |
616                    NETLOGON_NEG_CHANGELOG_BDC |
617                    NETLOGON_NEG_FULL_SYNC_REPL |
618                    NETLOGON_NEG_MULTIPLE_SIDS |
619                    NETLOGON_NEG_REDO |
620                    NETLOGON_NEG_PASSWORD_CHANGE_REFUSAL |
621                    NETLOGON_NEG_PASSWORD_SET2;
622
623         /* Ensure we support strong (128-bit) keys. */
624         if (in_neg_flags & NETLOGON_NEG_STRONG_KEYS) {
625                 srv_flgs |= NETLOGON_NEG_STRONG_KEYS;
626         }
627
628         if (lp_server_schannel() != false) {
629                 srv_flgs |= NETLOGON_NEG_SCHANNEL;
630         }
631
632         switch (p->hdr_req.opnum) {
633                 case NDR_NETR_SERVERAUTHENTICATE:
634                         fn = "_netr_ServerAuthenticate";
635                         break;
636                 case NDR_NETR_SERVERAUTHENTICATE2:
637                         fn = "_netr_ServerAuthenticate2";
638                         break;
639                 case NDR_NETR_SERVERAUTHENTICATE3:
640                         fn = "_netr_ServerAuthenticate3";
641                         break;
642                 default:
643                         return NT_STATUS_INTERNAL_ERROR;
644         }
645
646         /* We use this as the key to store the creds: */
647         /* r->in.computer_name */
648
649         if (!pipe_state) {
650                 DEBUG(0,("%s: no challenge sent to client %s\n", fn,
651                         r->in.computer_name));
652                 status = NT_STATUS_ACCESS_DENIED;
653                 goto out;
654         }
655
656         if ( (lp_server_schannel() == true) &&
657              ((in_neg_flags & NETLOGON_NEG_SCHANNEL) == 0) ) {
658
659                 /* schannel must be used, but client did not offer it. */
660                 DEBUG(0,("%s: schannel required but client failed "
661                         "to offer it. Client was %s\n",
662                         fn, r->in.account_name));
663                 status = NT_STATUS_ACCESS_DENIED;
664                 goto out;
665         }
666
667         status = get_md4pw(&mach_pwd,
668                            r->in.account_name,
669                            r->in.secure_channel_type,
670                            &sid);
671         if (!NT_STATUS_IS_OK(status)) {
672                 DEBUG(0,("%s: failed to get machine password for "
673                         "account %s: %s\n",
674                         fn, r->in.account_name, nt_errstr(status) ));
675                 /* always return NT_STATUS_ACCESS_DENIED */
676                 status = NT_STATUS_ACCESS_DENIED;
677                 goto out;
678         }
679
680         /* From the client / server challenges and md4 password, generate sess key */
681         /* Check client credentials are valid. */
682         creds = netlogon_creds_server_init(p->mem_ctx,
683                                            r->in.account_name,
684                                            r->in.computer_name,
685                                            r->in.secure_channel_type,
686                                            &pipe_state->client_challenge,
687                                            &pipe_state->server_challenge,
688                                            &mach_pwd,
689                                            r->in.credentials,
690                                            r->out.return_credentials,
691                                            *r->in.negotiate_flags);
692         if (!creds) {
693                 DEBUG(0,("%s: netlogon_creds_server_check failed. Rejecting auth "
694                         "request from client %s machine account %s\n",
695                         fn, r->in.computer_name,
696                         r->in.account_name));
697                 status = NT_STATUS_ACCESS_DENIED;
698                 goto out;
699         }
700
701         creds->sid = sid_dup_talloc(creds, &sid);
702         if (!creds->sid) {
703                 status = NT_STATUS_NO_MEMORY;
704                 goto out;
705         }
706
707         /* Store off the state so we can continue after client disconnect. */
708         become_root();
709         status = schannel_store_session_key(p->mem_ctx, creds);
710         unbecome_root();
711
712         if (!NT_STATUS_IS_OK(status)) {
713                 goto out;
714         }
715
716         sid_peek_rid(&sid, r->out.rid);
717
718         status = NT_STATUS_OK;
719
720   out:
721
722         *r->out.negotiate_flags = srv_flgs;
723         return status;
724 }
725
726 /*************************************************************************
727  _netr_ServerAuthenticate2
728  *************************************************************************/
729
730 NTSTATUS _netr_ServerAuthenticate2(pipes_struct *p,
731                                    struct netr_ServerAuthenticate2 *r)
732 {
733         struct netr_ServerAuthenticate3 a;
734         uint32_t rid;
735
736         a.in.server_name                = r->in.server_name;
737         a.in.account_name               = r->in.account_name;
738         a.in.secure_channel_type        = r->in.secure_channel_type;
739         a.in.computer_name              = r->in.computer_name;
740         a.in.credentials                = r->in.credentials;
741         a.in.negotiate_flags            = r->in.negotiate_flags;
742
743         a.out.return_credentials        = r->out.return_credentials;
744         a.out.rid                       = &rid;
745         a.out.negotiate_flags           = r->out.negotiate_flags;
746
747         return _netr_ServerAuthenticate3(p, &a);
748 }
749
750 /*************************************************************************
751  *************************************************************************/
752
753 static NTSTATUS netr_creds_server_step_check(pipes_struct *p,
754                                              TALLOC_CTX *mem_ctx,
755                                              const char *computer_name,
756                                              struct netr_Authenticator *received_authenticator,
757                                              struct netr_Authenticator *return_authenticator,
758                                              struct netlogon_creds_CredentialState **creds_out)
759 {
760         NTSTATUS status;
761         struct tdb_context *tdb;
762         bool schannel_global_required = (lp_server_schannel() == true) ? true:false;
763         bool schannel_in_use = (p->auth.auth_type == PIPE_AUTH_TYPE_SCHANNEL) ? true:false; /* &&
764                 (p->auth.auth_level == DCERPC_AUTH_LEVEL_INTEGRITY ||
765                  p->auth.auth_level == DCERPC_AUTH_LEVEL_PRIVACY); */
766
767         tdb = open_schannel_session_store(mem_ctx);
768         if (!tdb) {
769                 return NT_STATUS_ACCESS_DENIED;
770         }
771
772         status = schannel_creds_server_step_check_tdb(tdb, mem_ctx,
773                                                       computer_name,
774                                                       schannel_global_required,
775                                                       schannel_in_use,
776                                                       received_authenticator,
777                                                       return_authenticator,
778                                                       creds_out);
779         tdb_close(tdb);
780
781         return status;
782 }
783
784 /*************************************************************************
785  *************************************************************************/
786
787 static NTSTATUS netr_find_machine_account(TALLOC_CTX *mem_ctx,
788                                           const char *account_name,
789                                           struct samu **sampassp)
790 {
791         struct samu *sampass;
792         bool ret = false;
793         uint32_t acct_ctrl;
794
795         sampass = samu_new(mem_ctx);
796         if (!sampass) {
797                 return NT_STATUS_NO_MEMORY;
798         }
799
800         become_root();
801         ret = pdb_getsampwnam(sampass, account_name);
802         unbecome_root();
803
804         if (!ret) {
805                 TALLOC_FREE(sampass);
806                 return NT_STATUS_ACCESS_DENIED;
807         }
808
809         /* Ensure the account exists and is a machine account. */
810
811         acct_ctrl = pdb_get_acct_ctrl(sampass);
812
813         if (!(acct_ctrl & ACB_WSTRUST ||
814               acct_ctrl & ACB_SVRTRUST ||
815               acct_ctrl & ACB_DOMTRUST)) {
816                 TALLOC_FREE(sampass);
817                 return NT_STATUS_NO_SUCH_USER;
818         }
819
820         if (acct_ctrl & ACB_DISABLED) {
821                 TALLOC_FREE(sampass);
822                 return NT_STATUS_ACCOUNT_DISABLED;
823         }
824
825         *sampassp = sampass;
826
827         return NT_STATUS_OK;
828 }
829
830 /*************************************************************************
831  *************************************************************************/
832
833 static NTSTATUS netr_set_machine_account_password(TALLOC_CTX *mem_ctx,
834                                                   struct samu *sampass,
835                                                   DATA_BLOB *plaintext_blob,
836                                                   struct samr_Password *nt_hash,
837                                                   struct samr_Password *lm_hash)
838 {
839         NTSTATUS status;
840         const uchar *old_pw;
841         const char *plaintext = NULL;
842         size_t plaintext_len;
843         struct samr_Password nt_hash_local;
844
845         if (!sampass) {
846                 return NT_STATUS_INVALID_PARAMETER;
847         }
848
849         if (plaintext_blob) {
850                 if (!convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX,
851                                            plaintext_blob->data, plaintext_blob->length,
852                                            &plaintext, &plaintext_len, false))
853                 {
854                         plaintext = NULL;
855                         mdfour(nt_hash_local.hash, plaintext_blob->data, plaintext_blob->length);
856                         nt_hash = &nt_hash_local;
857                 }
858         }
859
860         if (plaintext) {
861                 if (!pdb_set_plaintext_passwd(sampass, plaintext)) {
862                         return NT_STATUS_ACCESS_DENIED;
863                 }
864
865                 goto done;
866         }
867
868         if (nt_hash) {
869                 old_pw = pdb_get_nt_passwd(sampass);
870
871                 if (old_pw && memcmp(nt_hash->hash, old_pw, 16) == 0) {
872                         /* Avoid backend modificiations and other fun if the
873                            client changed the password to the *same thing* */
874                 } else {
875                         /* LM password should be NULL for machines */
876                         if (!pdb_set_lanman_passwd(sampass, NULL, PDB_CHANGED)) {
877                                 return NT_STATUS_NO_MEMORY;
878                         }
879                         if (!pdb_set_nt_passwd(sampass, nt_hash->hash, PDB_CHANGED)) {
880                                 return NT_STATUS_NO_MEMORY;
881                         }
882
883                         if (!pdb_set_pass_last_set_time(sampass, time(NULL), PDB_CHANGED)) {
884                                 /* Not quite sure what this one qualifies as, but this will do */
885                                 return NT_STATUS_UNSUCCESSFUL;
886                         }
887                 }
888         }
889
890  done:
891         become_root();
892         status = pdb_update_sam_account(sampass);
893         unbecome_root();
894
895         return status;
896 }
897
898 /*************************************************************************
899  _netr_ServerPasswordSet
900  *************************************************************************/
901
902 NTSTATUS _netr_ServerPasswordSet(pipes_struct *p,
903                                  struct netr_ServerPasswordSet *r)
904 {
905         NTSTATUS status = NT_STATUS_OK;
906         struct samu *sampass=NULL;
907         int i;
908         struct netlogon_creds_CredentialState *creds;
909
910         DEBUG(5,("_netr_ServerPasswordSet: %d\n", __LINE__));
911
912         become_root();
913         status = netr_creds_server_step_check(p, p->mem_ctx,
914                                               r->in.computer_name,
915                                               r->in.credential,
916                                               r->out.return_authenticator,
917                                               &creds);
918         unbecome_root();
919
920         if (!NT_STATUS_IS_OK(status)) {
921                 DEBUG(2,("_netr_ServerPasswordSet: netlogon_creds_server_step failed. Rejecting auth "
922                         "request from client %s machine account %s\n",
923                         r->in.computer_name, creds->computer_name));
924                 TALLOC_FREE(creds);
925                 return status;
926         }
927
928         DEBUG(3,("_netr_ServerPasswordSet: Server Password Set by remote machine:[%s] on account [%s]\n",
929                         r->in.computer_name, creds->computer_name));
930
931         netlogon_creds_des_decrypt(creds, r->in.new_password);
932
933         DEBUG(100,("_netr_ServerPasswordSet: new given value was :\n"));
934         for(i = 0; i < sizeof(r->in.new_password->hash); i++)
935                 DEBUG(100,("%02X ", r->in.new_password->hash[i]));
936         DEBUG(100,("\n"));
937
938         status = netr_find_machine_account(p->mem_ctx,
939                                            creds->account_name,
940                                            &sampass);
941         if (!NT_STATUS_IS_OK(status)) {
942                 return status;
943         }
944
945         status = netr_set_machine_account_password(sampass,
946                                                    sampass,
947                                                    NULL,
948                                                    r->in.new_password,
949                                                    NULL);
950         TALLOC_FREE(sampass);
951         return status;
952 }
953
954 /****************************************************************
955  _netr_ServerPasswordSet2
956 ****************************************************************/
957
958 NTSTATUS _netr_ServerPasswordSet2(pipes_struct *p,
959                                   struct netr_ServerPasswordSet2 *r)
960 {
961         NTSTATUS status;
962         struct netlogon_creds_CredentialState *creds;
963         struct samu *sampass;
964         DATA_BLOB plaintext;
965         struct samr_CryptPassword password_buf;
966         struct samr_Password nt_hash;
967
968         become_root();
969         status = netr_creds_server_step_check(p, p->mem_ctx,
970                                               r->in.computer_name,
971                                               r->in.credential,
972                                               r->out.return_authenticator,
973                                               &creds);
974         unbecome_root();
975
976         if (!NT_STATUS_IS_OK(status)) {
977                 DEBUG(2,("_netr_ServerPasswordSet2: netlogon_creds_server_step "
978                         "failed. Rejecting auth request from client %s machine account %s\n",
979                         r->in.computer_name, creds->computer_name));
980                 TALLOC_FREE(creds);
981                 return status;
982         }
983
984         memcpy(password_buf.data, r->in.new_password->data, 512);
985         SIVAL(password_buf.data, 512, r->in.new_password->length);
986         netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
987
988         if (!extract_pw_from_buffer(p->mem_ctx, password_buf.data, &plaintext)) {
989                 return NT_STATUS_WRONG_PASSWORD;
990         }
991
992         mdfour(nt_hash.hash, plaintext.data, plaintext.length);
993
994         status = netr_find_machine_account(p->mem_ctx,
995                                            creds->account_name,
996                                            &sampass);
997         if (!NT_STATUS_IS_OK(status)) {
998                 return status;
999         }
1000
1001         status = netr_set_machine_account_password(sampass,
1002                                                    sampass,
1003                                                    NULL,
1004                                                    &nt_hash,
1005                                                    NULL);
1006         TALLOC_FREE(sampass);
1007         return status;
1008 }
1009
1010 /*************************************************************************
1011  _netr_LogonSamLogoff
1012  *************************************************************************/
1013
1014 NTSTATUS _netr_LogonSamLogoff(pipes_struct *p,
1015                               struct netr_LogonSamLogoff *r)
1016 {
1017         NTSTATUS status;
1018         struct netlogon_creds_CredentialState *creds;
1019
1020         become_root();
1021         status = netr_creds_server_step_check(p, p->mem_ctx,
1022                                               r->in.computer_name,
1023                                               r->in.credential,
1024                                               r->out.return_authenticator,
1025                                               &creds);
1026         unbecome_root();
1027
1028         return status;
1029 }
1030
1031 /*************************************************************************
1032  _netr_LogonSamLogon_base
1033  *************************************************************************/
1034
1035 static NTSTATUS _netr_LogonSamLogon_base(pipes_struct *p,
1036                                          struct netr_LogonSamLogonEx *r,
1037                                          struct netlogon_creds_CredentialState *creds)
1038 {
1039         NTSTATUS status = NT_STATUS_OK;
1040         union netr_LogonLevel *logon = r->in.logon;
1041         const char *nt_username, *nt_domain, *nt_workstation;
1042         auth_usersupplied_info *user_info = NULL;
1043         auth_serversupplied_info *server_info = NULL;
1044         struct auth_context *auth_context = NULL;
1045         uint8_t pipe_session_key[16];
1046         bool process_creds = true;
1047         const char *fn;
1048
1049         switch (p->hdr_req.opnum) {
1050                 case NDR_NETR_LOGONSAMLOGON:
1051                         process_creds = true;
1052                         fn = "_netr_LogonSamLogon";
1053                         break;
1054                 case NDR_NETR_LOGONSAMLOGONWITHFLAGS:
1055                         process_creds = true;
1056                         fn = "_netr_LogonSamLogonWithFlags";
1057                         break;
1058                 case NDR_NETR_LOGONSAMLOGONEX:
1059                         process_creds = false;
1060                         fn = "_netr_LogonSamLogonEx";
1061                         break;
1062                 default:
1063                         return NT_STATUS_INTERNAL_ERROR;
1064         }
1065
1066         *r->out.authoritative = true; /* authoritative response */
1067
1068         switch (r->in.validation_level) {
1069         case 2:
1070                 r->out.validation->sam2 = TALLOC_ZERO_P(p->mem_ctx, struct netr_SamInfo2);
1071                 if (!r->out.validation->sam2) {
1072                         return NT_STATUS_NO_MEMORY;
1073                 }
1074                 break;
1075         case 3:
1076                 r->out.validation->sam3 = TALLOC_ZERO_P(p->mem_ctx, struct netr_SamInfo3);
1077                 if (!r->out.validation->sam3) {
1078                         return NT_STATUS_NO_MEMORY;
1079                 }
1080                 break;
1081         case 6:
1082                 r->out.validation->sam6 = TALLOC_ZERO_P(p->mem_ctx, struct netr_SamInfo6);
1083                 if (!r->out.validation->sam6) {
1084                         return NT_STATUS_NO_MEMORY;
1085                 }
1086                 break;
1087         default:
1088                 DEBUG(0,("%s: bad validation_level value %d.\n",
1089                         fn, (int)r->in.validation_level));
1090                 return NT_STATUS_INVALID_INFO_CLASS;
1091         }
1092
1093         switch (r->in.logon_level) {
1094         case NetlogonInteractiveInformation:
1095         case NetlogonServiceInformation:
1096         case NetlogonInteractiveTransitiveInformation:
1097         case NetlogonServiceTransitiveInformation:
1098                 nt_username     = logon->password->identity_info.account_name.string;
1099                 nt_domain       = logon->password->identity_info.domain_name.string;
1100                 nt_workstation  = logon->password->identity_info.workstation.string;
1101
1102                 DEBUG(3,("SAM Logon (Interactive). Domain:[%s].  ", lp_workgroup()));
1103                 break;
1104         case NetlogonNetworkInformation:
1105         case NetlogonNetworkTransitiveInformation:
1106                 nt_username     = logon->network->identity_info.account_name.string;
1107                 nt_domain       = logon->network->identity_info.domain_name.string;
1108                 nt_workstation  = logon->network->identity_info.workstation.string;
1109
1110                 DEBUG(3,("SAM Logon (Network). Domain:[%s].  ", lp_workgroup()));
1111                 break;
1112         default:
1113                 DEBUG(2,("SAM Logon: unsupported switch value\n"));
1114                 return NT_STATUS_INVALID_INFO_CLASS;
1115         } /* end switch */
1116
1117         DEBUG(3,("User:[%s@%s] Requested Domain:[%s]\n", nt_username, nt_workstation, nt_domain));
1118         fstrcpy(current_user_info.smb_name, nt_username);
1119         sub_set_smb_name(nt_username);
1120
1121         DEBUG(5,("Attempting validation level %d for unmapped username %s.\n",
1122                 r->in.validation_level, nt_username));
1123
1124         status = NT_STATUS_OK;
1125
1126         switch (r->in.logon_level) {
1127         case NetlogonNetworkInformation:
1128         case NetlogonNetworkTransitiveInformation:
1129         {
1130                 const char *wksname = nt_workstation;
1131
1132                 status = make_auth_context_fixed(&auth_context,
1133                                                  logon->network->challenge);
1134                 if (!NT_STATUS_IS_OK(status)) {
1135                         return status;
1136                 }
1137
1138                 /* For a network logon, the workstation name comes in with two
1139                  * backslashes in the front. Strip them if they are there. */
1140
1141                 if (*wksname == '\\') wksname++;
1142                 if (*wksname == '\\') wksname++;
1143
1144                 /* Standard challenge/response authenticaion */
1145                 if (!make_user_info_netlogon_network(&user_info,
1146                                                      nt_username, nt_domain,
1147                                                      wksname,
1148                                                      logon->network->identity_info.parameter_control,
1149                                                      logon->network->lm.data,
1150                                                      logon->network->lm.length,
1151                                                      logon->network->nt.data,
1152                                                      logon->network->nt.length)) {
1153                         status = NT_STATUS_NO_MEMORY;
1154                 }
1155                 break;
1156         }
1157         case NetlogonInteractiveInformation:
1158         case NetlogonServiceInformation:
1159         case NetlogonInteractiveTransitiveInformation:
1160         case NetlogonServiceTransitiveInformation:
1161
1162                 /* 'Interactive' authentication, supplies the password in its
1163                    MD4 form, encrypted with the session key.  We will convert
1164                    this to challenge/response for the auth subsystem to chew
1165                    on */
1166         {
1167                 uint8_t chal[8];
1168
1169                 if (!NT_STATUS_IS_OK(status = make_auth_context_subsystem(&auth_context))) {
1170                         return status;
1171                 }
1172
1173                 auth_context->get_ntlm_challenge(auth_context, chal);
1174
1175                 if (!make_user_info_netlogon_interactive(&user_info,
1176                                                          nt_username, nt_domain,
1177                                                          nt_workstation,
1178                                                          logon->password->identity_info.parameter_control,
1179                                                          chal,
1180                                                          logon->password->lmpassword.hash,
1181                                                          logon->password->ntpassword.hash,
1182                                                          creds->session_key)) {
1183                         status = NT_STATUS_NO_MEMORY;
1184                 }
1185                 break;
1186         }
1187         default:
1188                 DEBUG(2,("SAM Logon: unsupported switch value\n"));
1189                 return NT_STATUS_INVALID_INFO_CLASS;
1190         } /* end switch */
1191
1192         if ( NT_STATUS_IS_OK(status) ) {
1193                 status = auth_context->check_ntlm_password(auth_context,
1194                         user_info, &server_info);
1195         }
1196
1197         (auth_context->free)(&auth_context);
1198         free_user_info(&user_info);
1199
1200         DEBUG(5,("%s: check_password returned status %s\n",
1201                   fn, nt_errstr(status)));
1202
1203         /* Check account and password */
1204
1205         if (!NT_STATUS_IS_OK(status)) {
1206                 /* If we don't know what this domain is, we need to
1207                    indicate that we are not authoritative.  This
1208                    allows the client to decide if it needs to try
1209                    a local user.  Fix by jpjanosi@us.ibm.com, #2976 */
1210                 if ( NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)
1211                      && !strequal(nt_domain, get_global_sam_name())
1212                      && !is_trusted_domain(nt_domain) )
1213                         *r->out.authoritative = false; /* We are not authoritative */
1214
1215                 TALLOC_FREE(server_info);
1216                 return status;
1217         }
1218
1219         if (server_info->guest) {
1220                 /* We don't like guest domain logons... */
1221                 DEBUG(5,("%s: Attempted domain logon as GUEST "
1222                          "denied.\n", fn));
1223                 TALLOC_FREE(server_info);
1224                 return NT_STATUS_LOGON_FAILURE;
1225         }
1226
1227         /* This is the point at which, if the login was successful, that
1228            the SAM Local Security Authority should record that the user is
1229            logged in to the domain.  */
1230
1231         if (process_creds) {
1232                 /* Get the pipe session key from the creds. */
1233                 memcpy(pipe_session_key, creds->session_key, 16);
1234         } else {
1235                 /* Get the pipe session key from the schannel. */
1236                 if ((p->auth.auth_type != PIPE_AUTH_TYPE_SCHANNEL)
1237                     || (p->auth.a_u.schannel_auth == NULL)) {
1238                         return NT_STATUS_INVALID_HANDLE;
1239                 }
1240                 memcpy(pipe_session_key, p->auth.a_u.schannel_auth->creds->session_key, 16);
1241         }
1242
1243         switch (r->in.validation_level) {
1244         case 2:
1245                 status = serverinfo_to_SamInfo2(server_info, pipe_session_key, 16,
1246                                                 r->out.validation->sam2);
1247                 break;
1248         case 3:
1249                 status = serverinfo_to_SamInfo3(server_info, pipe_session_key, 16,
1250                                                 r->out.validation->sam3);
1251                 break;
1252         case 6:
1253                 status = serverinfo_to_SamInfo6(server_info, pipe_session_key, 16,
1254                                                 r->out.validation->sam6);
1255                 break;
1256         }
1257
1258         TALLOC_FREE(server_info);
1259
1260         return status;
1261 }
1262
1263 /****************************************************************
1264  _netr_LogonSamLogonWithFlags
1265 ****************************************************************/
1266
1267 NTSTATUS _netr_LogonSamLogonWithFlags(pipes_struct *p,
1268                                       struct netr_LogonSamLogonWithFlags *r)
1269 {
1270         NTSTATUS status;
1271         struct netlogon_creds_CredentialState *creds;
1272         struct netr_LogonSamLogonEx r2;
1273         struct netr_Authenticator return_authenticator;
1274
1275         become_root();
1276         status = netr_creds_server_step_check(p, p->mem_ctx,
1277                                               r->in.computer_name,
1278                                               r->in.credential,
1279                                               &return_authenticator,
1280                                               &creds);
1281         unbecome_root();
1282         if (!NT_STATUS_IS_OK(status)) {
1283                 return status;
1284         }
1285
1286         r2.in.server_name       = r->in.server_name;
1287         r2.in.computer_name     = r->in.computer_name;
1288         r2.in.logon_level       = r->in.logon_level;
1289         r2.in.logon             = r->in.logon;
1290         r2.in.validation_level  = r->in.validation_level;
1291         r2.in.flags             = r->in.flags;
1292         r2.out.validation       = r->out.validation;
1293         r2.out.authoritative    = r->out.authoritative;
1294         r2.out.flags            = r->out.flags;
1295
1296         status = _netr_LogonSamLogon_base(p, &r2, creds);
1297
1298         *r->out.return_authenticator = return_authenticator;
1299
1300         return status;
1301 }
1302
1303 /*************************************************************************
1304  _netr_LogonSamLogon
1305  *************************************************************************/
1306
1307 NTSTATUS _netr_LogonSamLogon(pipes_struct *p,
1308                              struct netr_LogonSamLogon *r)
1309 {
1310         NTSTATUS status;
1311         struct netr_LogonSamLogonWithFlags r2;
1312         uint32_t flags = 0;
1313
1314         r2.in.server_name               = r->in.server_name;
1315         r2.in.computer_name             = r->in.computer_name;
1316         r2.in.credential                = r->in.credential;
1317         r2.in.logon_level               = r->in.logon_level;
1318         r2.in.logon                     = r->in.logon;
1319         r2.in.validation_level          = r->in.validation_level;
1320         r2.in.return_authenticator      = r->in.return_authenticator;
1321         r2.in.flags                     = &flags;
1322         r2.out.validation               = r->out.validation;
1323         r2.out.authoritative            = r->out.authoritative;
1324         r2.out.flags                    = &flags;
1325         r2.out.return_authenticator     = r->out.return_authenticator;
1326
1327         status = _netr_LogonSamLogonWithFlags(p, &r2);
1328
1329         return status;
1330 }
1331
1332 /*************************************************************************
1333  _netr_LogonSamLogonEx
1334  - no credential chaining. Map into net sam logon.
1335  *************************************************************************/
1336
1337 NTSTATUS _netr_LogonSamLogonEx(pipes_struct *p,
1338                                struct netr_LogonSamLogonEx *r)
1339 {
1340         NTSTATUS status;
1341         struct netlogon_creds_CredentialState *creds = NULL;
1342
1343         become_root();
1344         status = schannel_fetch_session_key(p->mem_ctx, r->in.computer_name, &creds);
1345         unbecome_root();
1346         if (!NT_STATUS_IS_OK(status)) {
1347                 return status;
1348         }
1349
1350         /* Only allow this if the pipe is protected. */
1351         if (p->auth.auth_type != PIPE_AUTH_TYPE_SCHANNEL) {
1352                 DEBUG(0,("_netr_LogonSamLogonEx: client %s not using schannel for netlogon\n",
1353                         get_remote_machine_name() ));
1354                 return NT_STATUS_INVALID_PARAMETER;
1355         }
1356
1357         status = _netr_LogonSamLogon_base(p, r, creds);
1358         TALLOC_FREE(creds);
1359
1360         return status;
1361 }
1362
1363 /*************************************************************************
1364  _ds_enum_dom_trusts
1365  *************************************************************************/
1366 #if 0   /* JERRY -- not correct */
1367  NTSTATUS _ds_enum_dom_trusts(pipes_struct *p, DS_Q_ENUM_DOM_TRUSTS *q_u,
1368                              DS_R_ENUM_DOM_TRUSTS *r_u)
1369 {
1370         NTSTATUS status = NT_STATUS_OK;
1371
1372         /* TODO: According to MSDN, the can only be executed against a
1373            DC or domain member running Windows 2000 or later.  Need
1374            to test against a standalone 2k server and see what it
1375            does.  A windows 2000 DC includes its own domain in the
1376            list.  --jerry */
1377
1378         return status;
1379 }
1380 #endif  /* JERRY */
1381
1382
1383 /****************************************************************
1384 ****************************************************************/
1385
1386 WERROR _netr_LogonUasLogon(pipes_struct *p,
1387                            struct netr_LogonUasLogon *r)
1388 {
1389         p->rng_fault_state = true;
1390         return WERR_NOT_SUPPORTED;
1391 }
1392
1393 /****************************************************************
1394 ****************************************************************/
1395
1396 WERROR _netr_LogonUasLogoff(pipes_struct *p,
1397                             struct netr_LogonUasLogoff *r)
1398 {
1399         p->rng_fault_state = true;
1400         return WERR_NOT_SUPPORTED;
1401 }
1402
1403 /****************************************************************
1404 ****************************************************************/
1405
1406 NTSTATUS _netr_DatabaseDeltas(pipes_struct *p,
1407                               struct netr_DatabaseDeltas *r)
1408 {
1409         p->rng_fault_state = true;
1410         return NT_STATUS_NOT_IMPLEMENTED;
1411 }
1412
1413 /****************************************************************
1414 ****************************************************************/
1415
1416 NTSTATUS _netr_DatabaseSync(pipes_struct *p,
1417                             struct netr_DatabaseSync *r)
1418 {
1419         p->rng_fault_state = true;
1420         return NT_STATUS_NOT_IMPLEMENTED;
1421 }
1422
1423 /****************************************************************
1424 ****************************************************************/
1425
1426 NTSTATUS _netr_AccountDeltas(pipes_struct *p,
1427                              struct netr_AccountDeltas *r)
1428 {
1429         p->rng_fault_state = true;
1430         return NT_STATUS_NOT_IMPLEMENTED;
1431 }
1432
1433 /****************************************************************
1434 ****************************************************************/
1435
1436 NTSTATUS _netr_AccountSync(pipes_struct *p,
1437                            struct netr_AccountSync *r)
1438 {
1439         p->rng_fault_state = true;
1440         return NT_STATUS_NOT_IMPLEMENTED;
1441 }
1442
1443 /****************************************************************
1444 ****************************************************************/
1445
1446 static bool wb_getdcname(TALLOC_CTX *mem_ctx,
1447                          const char *domain,
1448                          const char **dcname,
1449                          uint32_t flags,
1450                          WERROR *werr)
1451 {
1452         wbcErr result;
1453         struct wbcDomainControllerInfo *dc_info = NULL;
1454
1455         result = wbcLookupDomainController(domain,
1456                                            flags,
1457                                            &dc_info);
1458         switch (result) {
1459         case WBC_ERR_SUCCESS:
1460                 break;
1461         case WBC_ERR_WINBIND_NOT_AVAILABLE:
1462                 return false;
1463         case WBC_ERR_DOMAIN_NOT_FOUND:
1464                 *werr = WERR_NO_SUCH_DOMAIN;
1465                 return true;
1466         default:
1467                 *werr = WERR_DOMAIN_CONTROLLER_NOT_FOUND;
1468                 return true;
1469         }
1470
1471         *dcname = talloc_strdup(mem_ctx, dc_info->dc_name);
1472         wbcFreeMemory(dc_info);
1473         if (!*dcname) {
1474                 *werr = WERR_NOMEM;
1475                 return false;
1476         }
1477
1478         *werr = WERR_OK;
1479
1480         return true;
1481 }
1482
1483 /****************************************************************
1484  _netr_GetDcName
1485 ****************************************************************/
1486
1487 WERROR _netr_GetDcName(pipes_struct *p,
1488                        struct netr_GetDcName *r)
1489 {
1490         NTSTATUS status;
1491         WERROR werr;
1492         uint32_t flags;
1493         struct netr_DsRGetDCNameInfo *info;
1494         bool ret;
1495
1496         ret = wb_getdcname(p->mem_ctx,
1497                            r->in.domainname,
1498                            r->out.dcname,
1499                            WBC_LOOKUP_DC_IS_FLAT_NAME |
1500                            WBC_LOOKUP_DC_RETURN_FLAT_NAME |
1501                            WBC_LOOKUP_DC_PDC_REQUIRED,
1502                            &werr);
1503         if (ret == true) {
1504                 return werr;
1505         }
1506
1507         flags = DS_PDC_REQUIRED | DS_IS_FLAT_NAME | DS_RETURN_FLAT_NAME;
1508
1509         status = dsgetdcname(p->mem_ctx,
1510                              smbd_messaging_context(),
1511                              r->in.domainname,
1512                              NULL,
1513                              NULL,
1514                              flags,
1515                              &info);
1516         if (!NT_STATUS_IS_OK(status)) {
1517                 return ntstatus_to_werror(status);
1518         }
1519
1520         *r->out.dcname = talloc_strdup(p->mem_ctx, info->dc_unc);
1521         talloc_free(info);
1522         if (!*r->out.dcname) {
1523                 return WERR_NOMEM;
1524         }
1525
1526         return WERR_OK;
1527 }
1528
1529 /****************************************************************
1530  _netr_GetAnyDCName
1531 ****************************************************************/
1532
1533 WERROR _netr_GetAnyDCName(pipes_struct *p,
1534                           struct netr_GetAnyDCName *r)
1535 {
1536         NTSTATUS status;
1537         WERROR werr;
1538         uint32_t flags;
1539         struct netr_DsRGetDCNameInfo *info;
1540         bool ret;
1541
1542         ret = wb_getdcname(p->mem_ctx,
1543                            r->in.domainname,
1544                            r->out.dcname,
1545                            WBC_LOOKUP_DC_IS_FLAT_NAME |
1546                            WBC_LOOKUP_DC_RETURN_FLAT_NAME,
1547                            &werr);
1548         if (ret == true) {
1549                 return werr;
1550         }
1551
1552         flags = DS_IS_FLAT_NAME | DS_RETURN_FLAT_NAME;
1553
1554         status = dsgetdcname(p->mem_ctx,
1555                              smbd_messaging_context(),
1556                              r->in.domainname,
1557                              NULL,
1558                              NULL,
1559                              flags,
1560                              &info);
1561         if (!NT_STATUS_IS_OK(status)) {
1562                 return ntstatus_to_werror(status);
1563         }
1564
1565         *r->out.dcname = talloc_strdup(p->mem_ctx, info->dc_unc);
1566         talloc_free(info);
1567         if (!*r->out.dcname) {
1568                 return WERR_NOMEM;
1569         }
1570
1571         return WERR_OK;
1572 }
1573
1574 /****************************************************************
1575 ****************************************************************/
1576
1577 NTSTATUS _netr_DatabaseSync2(pipes_struct *p,
1578                              struct netr_DatabaseSync2 *r)
1579 {
1580         p->rng_fault_state = true;
1581         return NT_STATUS_NOT_IMPLEMENTED;
1582 }
1583
1584 /****************************************************************
1585 ****************************************************************/
1586
1587 NTSTATUS _netr_DatabaseRedo(pipes_struct *p,
1588                             struct netr_DatabaseRedo *r)
1589 {
1590         p->rng_fault_state = true;
1591         return NT_STATUS_NOT_IMPLEMENTED;
1592 }
1593
1594 /****************************************************************
1595 ****************************************************************/
1596
1597 WERROR _netr_DsRGetDCName(pipes_struct *p,
1598                           struct netr_DsRGetDCName *r)
1599 {
1600         p->rng_fault_state = true;
1601         return WERR_NOT_SUPPORTED;
1602 }
1603
1604 /****************************************************************
1605 ****************************************************************/
1606
1607 NTSTATUS _netr_LogonGetCapabilities(pipes_struct *p,
1608                                     struct netr_LogonGetCapabilities *r)
1609 {
1610         return NT_STATUS_NOT_IMPLEMENTED;
1611 }
1612
1613 /****************************************************************
1614 ****************************************************************/
1615
1616 WERROR _netr_NETRLOGONSETSERVICEBITS(pipes_struct *p,
1617                                      struct netr_NETRLOGONSETSERVICEBITS *r)
1618 {
1619         p->rng_fault_state = true;
1620         return WERR_NOT_SUPPORTED;
1621 }
1622
1623 /****************************************************************
1624 ****************************************************************/
1625
1626 WERROR _netr_LogonGetTrustRid(pipes_struct *p,
1627                               struct netr_LogonGetTrustRid *r)
1628 {
1629         p->rng_fault_state = true;
1630         return WERR_NOT_SUPPORTED;
1631 }
1632
1633 /****************************************************************
1634 ****************************************************************/
1635
1636 WERROR _netr_NETRLOGONCOMPUTESERVERDIGEST(pipes_struct *p,
1637                                           struct netr_NETRLOGONCOMPUTESERVERDIGEST *r)
1638 {
1639         p->rng_fault_state = true;
1640         return WERR_NOT_SUPPORTED;
1641 }
1642
1643 /****************************************************************
1644 ****************************************************************/
1645
1646 WERROR _netr_NETRLOGONCOMPUTECLIENTDIGEST(pipes_struct *p,
1647                                           struct netr_NETRLOGONCOMPUTECLIENTDIGEST *r)
1648 {
1649         p->rng_fault_state = true;
1650         return WERR_NOT_SUPPORTED;
1651 }
1652
1653 /****************************************************************
1654 ****************************************************************/
1655
1656 WERROR _netr_DsRGetDCNameEx(pipes_struct *p,
1657                             struct netr_DsRGetDCNameEx *r)
1658 {
1659         p->rng_fault_state = true;
1660         return WERR_NOT_SUPPORTED;
1661 }
1662
1663 /****************************************************************
1664 ****************************************************************/
1665
1666 WERROR _netr_DsRGetSiteName(pipes_struct *p,
1667                             struct netr_DsRGetSiteName *r)
1668 {
1669         p->rng_fault_state = true;
1670         return WERR_NOT_SUPPORTED;
1671 }
1672
1673 /****************************************************************
1674 ****************************************************************/
1675
1676 NTSTATUS _netr_LogonGetDomainInfo(pipes_struct *p,
1677                                   struct netr_LogonGetDomainInfo *r)
1678 {
1679         p->rng_fault_state = true;
1680         return NT_STATUS_NOT_IMPLEMENTED;
1681 }
1682
1683 /****************************************************************
1684 ****************************************************************/
1685
1686 WERROR _netr_ServerPasswordGet(pipes_struct *p,
1687                                struct netr_ServerPasswordGet *r)
1688 {
1689         p->rng_fault_state = true;
1690         return WERR_NOT_SUPPORTED;
1691 }
1692
1693 /****************************************************************
1694 ****************************************************************/
1695
1696 WERROR _netr_NETRLOGONSENDTOSAM(pipes_struct *p,
1697                                 struct netr_NETRLOGONSENDTOSAM *r)
1698 {
1699         p->rng_fault_state = true;
1700         return WERR_NOT_SUPPORTED;
1701 }
1702
1703 /****************************************************************
1704 ****************************************************************/
1705
1706 WERROR _netr_DsRAddressToSitenamesW(pipes_struct *p,
1707                                     struct netr_DsRAddressToSitenamesW *r)
1708 {
1709         p->rng_fault_state = true;
1710         return WERR_NOT_SUPPORTED;
1711 }
1712
1713 /****************************************************************
1714 ****************************************************************/
1715
1716 WERROR _netr_DsRGetDCNameEx2(pipes_struct *p,
1717                              struct netr_DsRGetDCNameEx2 *r)
1718 {
1719         p->rng_fault_state = true;
1720         return WERR_NOT_SUPPORTED;
1721 }
1722
1723 /****************************************************************
1724 ****************************************************************/
1725
1726 WERROR _netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN(pipes_struct *p,
1727                                                  struct netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN *r)
1728 {
1729         p->rng_fault_state = true;
1730         return WERR_NOT_SUPPORTED;
1731 }
1732
1733 /****************************************************************
1734 ****************************************************************/
1735
1736 WERROR _netr_NetrEnumerateTrustedDomainsEx(pipes_struct *p,
1737                                            struct netr_NetrEnumerateTrustedDomainsEx *r)
1738 {
1739         p->rng_fault_state = true;
1740         return WERR_NOT_SUPPORTED;
1741 }
1742
1743 /****************************************************************
1744 ****************************************************************/
1745
1746 WERROR _netr_DsRAddressToSitenamesExW(pipes_struct *p,
1747                                       struct netr_DsRAddressToSitenamesExW *r)
1748 {
1749         p->rng_fault_state = true;
1750         return WERR_NOT_SUPPORTED;
1751 }
1752
1753 /****************************************************************
1754 ****************************************************************/
1755
1756 WERROR _netr_DsrGetDcSiteCoverageW(pipes_struct *p,
1757                                    struct netr_DsrGetDcSiteCoverageW *r)
1758 {
1759         p->rng_fault_state = true;
1760         return WERR_NOT_SUPPORTED;
1761 }
1762
1763 /****************************************************************
1764 ****************************************************************/
1765
1766 WERROR _netr_DsrEnumerateDomainTrusts(pipes_struct *p,
1767                                       struct netr_DsrEnumerateDomainTrusts *r)
1768 {
1769         p->rng_fault_state = true;
1770         return WERR_NOT_SUPPORTED;
1771 }
1772
1773 /****************************************************************
1774 ****************************************************************/
1775
1776 WERROR _netr_DsrDeregisterDNSHostRecords(pipes_struct *p,
1777                                          struct netr_DsrDeregisterDNSHostRecords *r)
1778 {
1779         p->rng_fault_state = true;
1780         return WERR_NOT_SUPPORTED;
1781 }
1782
1783 /****************************************************************
1784 ****************************************************************/
1785
1786 NTSTATUS _netr_ServerTrustPasswordsGet(pipes_struct *p,
1787                                        struct netr_ServerTrustPasswordsGet *r)
1788 {
1789         p->rng_fault_state = true;
1790         return NT_STATUS_NOT_IMPLEMENTED;
1791 }
1792
1793 /****************************************************************
1794 ****************************************************************/
1795
1796 WERROR _netr_DsRGetForestTrustInformation(pipes_struct *p,
1797                                           struct netr_DsRGetForestTrustInformation *r)
1798 {
1799         p->rng_fault_state = true;
1800         return WERR_NOT_SUPPORTED;
1801 }
1802
1803 /****************************************************************
1804 ****************************************************************/
1805
1806 WERROR _netr_GetForestTrustInformation(pipes_struct *p,
1807                                        struct netr_GetForestTrustInformation *r)
1808 {
1809         p->rng_fault_state = true;
1810         return WERR_NOT_SUPPORTED;
1811 }
1812
1813 /****************************************************************
1814 ****************************************************************/
1815
1816 NTSTATUS _netr_ServerGetTrustInfo(pipes_struct *p,
1817                                   struct netr_ServerGetTrustInfo *r)
1818 {
1819         p->rng_fault_state = true;
1820         return NT_STATUS_NOT_IMPLEMENTED;
1821 }
1822