2 Unix SMB/CIFS implementation.
4 endpoint server for the netlogon pipe
6 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004
7 Copyright (C) Stefan Metzmacher <metze@samba.org> 2005
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include "rpc_server/dcerpc_server.h"
26 #include "rpc_server/common/common.h"
27 #include "lib/ldb/include/ldb.h"
28 #include "auth/auth.h"
29 #include "dsdb/samdb/samdb.h"
30 #include "rpc_server/samr/proto.h"
32 #include "libcli/auth/proto.h"
34 struct server_pipe_state {
35 struct netr_Credential client_challenge;
36 struct netr_Credential server_challenge;
40 static NTSTATUS netr_ServerReqChallenge(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
41 struct netr_ServerReqChallenge *r)
43 struct server_pipe_state *pipe_state = dce_call->context->private;
45 ZERO_STRUCTP(r->out.credentials);
47 /* destroyed on pipe shutdown */
50 talloc_free(pipe_state);
51 dce_call->context->private = NULL;
54 pipe_state = talloc(dce_call->context, struct server_pipe_state);
56 return NT_STATUS_NO_MEMORY;
59 pipe_state->client_challenge = *r->in.credentials;
61 generate_random_buffer(pipe_state->server_challenge.data,
62 sizeof(pipe_state->server_challenge.data));
64 *r->out.credentials = pipe_state->server_challenge;
66 dce_call->context->private = pipe_state;
71 static NTSTATUS netr_ServerAuthenticate3(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
72 struct netr_ServerAuthenticate3 *r)
74 struct server_pipe_state *pipe_state = dce_call->context->private;
75 struct creds_CredentialState *creds;
77 struct samr_Password *mach_pwd;
80 struct ldb_message **msgs;
82 const char *attrs[] = {"ntPwdHash", "userAccountControl",
85 ZERO_STRUCTP(r->out.credentials);
87 *r->out.negotiate_flags = *r->in.negotiate_flags;
90 DEBUG(1, ("No challenge requested by client, cannot authenticate\n"));
91 return NT_STATUS_ACCESS_DENIED;
94 sam_ctx = samdb_connect(mem_ctx, system_session(mem_ctx));
95 if (sam_ctx == NULL) {
96 return NT_STATUS_INVALID_SYSTEM_SERVICE;
98 /* pull the user attributes */
99 num_records = gendb_search(sam_ctx, mem_ctx, NULL, &msgs, attrs,
100 "(&(sAMAccountName=%s)(objectclass=user))",
103 if (num_records == 0) {
104 DEBUG(3,("Couldn't find user [%s] in samdb.\n",
105 r->in.account_name));
106 return NT_STATUS_ACCESS_DENIED;
109 if (num_records > 1) {
110 DEBUG(0,("Found %d records matching user [%s]\n", num_records, r->in.account_name));
111 return NT_STATUS_INTERNAL_DB_CORRUPTION;
114 acct_flags = samdb_result_acct_flags(msgs[0],
115 "userAccountControl");
117 if (acct_flags & ACB_DISABLED) {
118 DEBUG(1, ("Account [%s] is disabled\n", r->in.account_name));
119 return NT_STATUS_ACCESS_DENIED;
122 if (r->in.secure_channel_type == SEC_CHAN_WKSTA) {
123 if (!(acct_flags & ACB_WSTRUST)) {
124 DEBUG(1, ("Client asked for a workstation secure channel, but is not a workstation (member server) acb flags: 0x%x\n", acct_flags));
125 return NT_STATUS_ACCESS_DENIED;
127 } else if (r->in.secure_channel_type == SEC_CHAN_DOMAIN) {
128 if (!(acct_flags & ACB_DOMTRUST)) {
129 DEBUG(1, ("Client asked for a trusted domain secure channel, but is not a trusted domain: acb flags: 0x%x\n", acct_flags));
130 return NT_STATUS_ACCESS_DENIED;
132 } else if (r->in.secure_channel_type == SEC_CHAN_BDC) {
133 if (!(acct_flags & ACB_SVRTRUST)) {
134 DEBUG(1, ("Client asked for a server secure channel, but is not a server (domain controller): acb flags: 0x%x\n", acct_flags));
135 return NT_STATUS_ACCESS_DENIED;
138 DEBUG(1, ("Client asked for an invalid secure channel type: %d\n",
139 r->in.secure_channel_type));
140 return NT_STATUS_ACCESS_DENIED;
143 *r->out.rid = samdb_result_rid_from_sid(mem_ctx, msgs[0],
146 mach_pwd = samdb_result_hash(mem_ctx, msgs[0], "ntPwdHash");
147 if (mach_pwd == NULL) {
148 return NT_STATUS_ACCESS_DENIED;
151 creds = talloc(mem_ctx, struct creds_CredentialState);
153 return NT_STATUS_NO_MEMORY;
156 creds_server_init(creds, &pipe_state->client_challenge,
157 &pipe_state->server_challenge, mach_pwd,
159 *r->in.negotiate_flags);
161 if (!creds_server_check(creds, r->in.credentials)) {
163 return NT_STATUS_ACCESS_DENIED;
166 creds->account_name = talloc_steal(creds, r->in.account_name);
168 creds->computer_name = talloc_steal(creds, r->in.computer_name);
169 creds->domain = talloc_strdup(creds, lp_workgroup());
171 creds->secure_channel_type = r->in.secure_channel_type;
173 creds->sid = samdb_result_dom_sid(creds, msgs[0], "objectSid");
176 /* remember this session key state */
177 nt_status = schannel_store_session_key(mem_ctx, creds);
182 static NTSTATUS netr_ServerAuthenticate(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
183 struct netr_ServerAuthenticate *r)
185 struct netr_ServerAuthenticate3 r3;
188 * negotiate_flags is used as an [in] parameter
189 * so it need to be initialised.
191 * (I think ... = 0; seems wrong here --metze)
193 uint32_t negotiate_flags = 0;
195 r3.in.server_name = r->in.server_name;
196 r3.in.account_name = r->in.account_name;
197 r3.in.secure_channel_type = r->in.secure_channel_type;
198 r3.in.computer_name = r->in.computer_name;
199 r3.in.credentials = r->in.credentials;
200 r3.out.credentials = r->out.credentials;
201 r3.in.negotiate_flags = &negotiate_flags;
202 r3.out.negotiate_flags = &negotiate_flags;
205 return netr_ServerAuthenticate3(dce_call, mem_ctx, &r3);
208 static NTSTATUS netr_ServerAuthenticate2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
209 struct netr_ServerAuthenticate2 *r)
211 struct netr_ServerAuthenticate3 r3;
214 r3.in.server_name = r->in.server_name;
215 r3.in.account_name = r->in.account_name;
216 r3.in.secure_channel_type = r->in.secure_channel_type;
217 r3.in.computer_name = r->in.computer_name;
218 r3.in.credentials = r->in.credentials;
219 r3.out.credentials = r->out.credentials;
220 r3.in.negotiate_flags = r->in.negotiate_flags;
221 r3.out.negotiate_flags = r->out.negotiate_flags;
224 return netr_ServerAuthenticate3(dce_call, mem_ctx, &r3);
228 Validate an incoming authenticator against the credentials for the remote machine.
230 The credentials are (re)read and from the schannel database, and
231 written back after the caclulations are performed.
233 The creds_out parameter (if not NULL) returns the credentials, if
234 the caller needs some of that information.
237 static NTSTATUS netr_creds_server_step_check(const char *computer_name,
239 struct netr_Authenticator *received_authenticator,
240 struct netr_Authenticator *return_authenticator,
241 struct creds_CredentialState **creds_out)
243 struct creds_CredentialState *creds;
245 struct ldb_context *ldb;
248 ldb = schannel_db_connect(mem_ctx);
250 return NT_STATUS_ACCESS_DENIED;
253 ret = ldb_transaction_start(ldb);
256 return NT_STATUS_INTERNAL_DB_CORRUPTION;
259 /* Because this is a shared structure (even across
260 * disconnects) we must update the database every time we
261 * update the structure */
263 nt_status = schannel_fetch_session_key_ldb(ldb, ldb, computer_name, lp_workgroup(),
265 if (NT_STATUS_IS_OK(nt_status)) {
266 nt_status = creds_server_step_check(creds,
267 received_authenticator,
268 return_authenticator);
270 if (NT_STATUS_IS_OK(nt_status)) {
271 nt_status = schannel_store_session_key_ldb(ldb, ldb, creds);
274 if (NT_STATUS_IS_OK(nt_status)) {
275 ldb_transaction_commit(ldb);
278 talloc_steal(mem_ctx, creds);
281 ldb_transaction_cancel(ldb);
288 Change the machine account password for the currently connected
289 client. Supplies only the NT#.
292 static NTSTATUS netr_ServerPasswordSet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
293 struct netr_ServerPasswordSet *r)
295 struct creds_CredentialState *creds;
296 struct ldb_context *sam_ctx;
299 nt_status = netr_creds_server_step_check(r->in.computer_name, mem_ctx,
300 &r->in.credential, &r->out.return_authenticator,
302 NT_STATUS_NOT_OK_RETURN(nt_status);
304 sam_ctx = samdb_connect(mem_ctx, system_session(mem_ctx));
305 if (sam_ctx == NULL) {
306 return NT_STATUS_INVALID_SYSTEM_SERVICE;
309 creds_des_decrypt(creds, &r->in.new_password);
311 /* Using the sid for the account as the key, set the password */
312 nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
314 NULL, /* Don't have plaintext */
315 NULL, &r->in.new_password,
316 False, /* This is not considered a password change */
317 False, /* don't restrict this password change (match w2k3) */
323 Change the machine account password for the currently connected
324 client. Supplies new plaintext.
326 static NTSTATUS netr_ServerPasswordSet2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
327 struct netr_ServerPasswordSet2 *r)
329 struct creds_CredentialState *creds;
330 struct ldb_context *sam_ctx;
333 uint32_t new_pass_len;
336 struct samr_CryptPassword password_buf;
338 nt_status = netr_creds_server_step_check(r->in.computer_name, mem_ctx,
339 &r->in.credential, &r->out.return_authenticator,
341 NT_STATUS_NOT_OK_RETURN(nt_status);
343 sam_ctx = samdb_connect(mem_ctx, system_session(mem_ctx));
344 if (sam_ctx == NULL) {
345 return NT_STATUS_INVALID_SYSTEM_SERVICE;
348 memcpy(password_buf.data, r->in.new_password.data, 512);
349 SIVAL(password_buf.data,512,r->in.new_password.length);
350 creds_arcfour_crypt(creds, password_buf.data, 516);
352 ret = decode_pw_buffer(password_buf.data, new_pass, sizeof(new_pass),
353 &new_pass_len, STR_UNICODE);
355 DEBUG(3,("netr_ServerPasswordSet2: failed to decode password buffer\n"));
356 return NT_STATUS_ACCESS_DENIED;
359 /* Using the sid for the account as the key, set the password */
360 nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
362 new_pass, /* we have plaintext */
364 False, /* This is not considered a password change */
365 False, /* don't restrict this password change (match w2k3) */
374 static WERROR netr_LogonUasLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
375 struct netr_LogonUasLogon *r)
377 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
384 static WERROR netr_LogonUasLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
385 struct netr_LogonUasLogoff *r)
387 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
392 netr_LogonSamLogon_base
394 This version of the function allows other wrappers to say 'do not check the credentials'
396 We can't do the traditional 'wrapping' format completly, as this function must only run under schannel
398 static NTSTATUS netr_LogonSamLogon_base(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
399 struct netr_LogonSamLogonEx *r, struct creds_CredentialState *creds)
401 struct auth_context *auth_context;
402 struct auth_usersupplied_info *user_info;
403 struct auth_serversupplied_info *server_info;
405 static const char zeros[16];
406 struct netr_SamBaseInfo *sam;
407 struct netr_SamInfo2 *sam2;
408 struct netr_SamInfo3 *sam3;
409 struct netr_SamInfo6 *sam6;
411 user_info = talloc(mem_ctx, struct auth_usersupplied_info);
413 return NT_STATUS_NO_MEMORY;
416 user_info->flags = 0;
417 user_info->mapped_state = False;
418 user_info->remote_host = NULL;
420 switch (r->in.logon_level) {
424 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
425 creds_arcfour_crypt(creds,
426 r->in.logon.password->lmpassword.hash,
427 sizeof(r->in.logon.password->lmpassword.hash));
428 creds_arcfour_crypt(creds,
429 r->in.logon.password->ntpassword.hash,
430 sizeof(r->in.logon.password->ntpassword.hash));
432 creds_des_decrypt(creds, &r->in.logon.password->lmpassword);
433 creds_des_decrypt(creds, &r->in.logon.password->ntpassword);
436 /* TODO: we need to deny anonymous access here */
437 nt_status = auth_context_create(mem_ctx, lp_auth_methods(), &auth_context,
438 dce_call->event_ctx);
439 NT_STATUS_NOT_OK_RETURN(nt_status);
441 user_info->logon_parameters = r->in.logon.password->identity_info.parameter_control;
442 user_info->client.account_name = r->in.logon.password->identity_info.account_name.string;
443 user_info->client.domain_name = r->in.logon.password->identity_info.domain_name.string;
444 user_info->workstation_name = r->in.logon.password->identity_info.workstation.string;
446 user_info->password_state = AUTH_PASSWORD_HASH;
447 user_info->password.hash.lanman = talloc(user_info, struct samr_Password);
448 if (!user_info->password.hash.lanman) {
449 return NT_STATUS_NO_MEMORY;
451 *user_info->password.hash.lanman = r->in.logon.password->lmpassword;
453 user_info->password.hash.nt = talloc(user_info, struct samr_Password);
454 if (!user_info->password.hash.nt) {
455 return NT_STATUS_NO_MEMORY;
457 *user_info->password.hash.nt = r->in.logon.password->ntpassword;
459 user_info->flags |= USER_INFO_INTERACTIVE_LOGON;
465 /* TODO: we need to deny anonymous access here */
466 nt_status = auth_context_create(mem_ctx, lp_auth_methods(), &auth_context,
467 dce_call->event_ctx);
468 NT_STATUS_NOT_OK_RETURN(nt_status);
470 nt_status = auth_context_set_challenge(auth_context, r->in.logon.network->challenge, "netr_LogonSamLogonWithFlags");
471 NT_STATUS_NOT_OK_RETURN(nt_status);
473 user_info->logon_parameters = r->in.logon.network->identity_info.parameter_control;
474 user_info->client.account_name = r->in.logon.network->identity_info.account_name.string;
475 user_info->client.domain_name = r->in.logon.network->identity_info.domain_name.string;
476 user_info->workstation_name = r->in.logon.network->identity_info.workstation.string;
478 user_info->password_state = AUTH_PASSWORD_RESPONSE;
479 user_info->password.response.lanman = data_blob(r->in.logon.network->lm.data, r->in.logon.network->lm.length);
480 user_info->password.response.nt = data_blob(r->in.logon.network->nt.data, r->in.logon.network->nt.length);
484 return NT_STATUS_INVALID_PARAMETER;
487 nt_status = auth_check_password(auth_context, mem_ctx, user_info, &server_info);
488 NT_STATUS_NOT_OK_RETURN(nt_status);
490 nt_status = auth_convert_server_info_sambaseinfo(mem_ctx, server_info, &sam);
492 NT_STATUS_NOT_OK_RETURN(nt_status);
494 /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
495 /* It appears that level 6 is not individually encrypted */
496 if ((r->in.validation_level != 6)
497 && memcmp(sam->key.key, zeros,
498 sizeof(sam->key.key)) != 0) {
500 /* This key is sent unencrypted without the ARCFOUR flag set */
501 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
502 creds_arcfour_crypt(creds,
504 sizeof(sam->key.key));
508 /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
509 /* It appears that level 6 is not individually encrypted */
510 if ((r->in.validation_level != 6)
511 && memcmp(sam->LMSessKey.key, zeros,
512 sizeof(sam->LMSessKey.key)) != 0) {
513 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
514 creds_arcfour_crypt(creds,
516 sizeof(sam->LMSessKey.key));
518 creds_des_encrypt_LMKey(creds,
523 switch (r->in.validation_level) {
525 sam2 = talloc_zero(mem_ctx, struct netr_SamInfo2);
526 NT_STATUS_HAVE_NO_MEMORY(sam2);
528 r->out.validation.sam2 = sam2;
532 sam3 = talloc_zero(mem_ctx, struct netr_SamInfo3);
533 NT_STATUS_HAVE_NO_MEMORY(sam3);
535 r->out.validation.sam3 = sam3;
539 sam6 = talloc_zero(mem_ctx, struct netr_SamInfo6);
540 NT_STATUS_HAVE_NO_MEMORY(sam6);
542 sam6->forest.string = lp_realm();
543 sam6->principle.string = talloc_asprintf(mem_ctx, "%s@%s",
544 sam->account_name.string, sam6->forest.string);
545 NT_STATUS_HAVE_NO_MEMORY(sam6->principle.string);
546 r->out.validation.sam6 = sam6;
553 r->out.authoritative = 1;
555 /* TODO: Describe and deal with these flags */
561 static NTSTATUS netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
562 struct netr_LogonSamLogonEx *r)
565 struct creds_CredentialState *creds;
566 nt_status = schannel_fetch_session_key(mem_ctx, r->in.computer_name, lp_workgroup(), &creds);
567 if (!NT_STATUS_IS_OK(nt_status)) {
571 if (!dce_call->conn->auth_state.auth_info
572 || dce_call->conn->auth_state.auth_info->auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
573 return NT_STATUS_INTERNAL_ERROR;
575 return netr_LogonSamLogon_base(dce_call, mem_ctx, r, creds);
579 netr_LogonSamLogonWithFlags
582 static NTSTATUS netr_LogonSamLogonWithFlags(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
583 struct netr_LogonSamLogonWithFlags *r)
586 struct creds_CredentialState *creds;
587 struct netr_LogonSamLogonEx r2;
589 struct netr_Authenticator *return_authenticator;
591 return_authenticator = talloc(mem_ctx, struct netr_Authenticator);
592 NT_STATUS_HAVE_NO_MEMORY(return_authenticator);
594 nt_status = netr_creds_server_step_check(r->in.computer_name, mem_ctx,
595 r->in.credential, return_authenticator,
597 NT_STATUS_NOT_OK_RETURN(nt_status);
601 r2.in.server_name = r->in.server_name;
602 r2.in.computer_name = r->in.computer_name;
603 r2.in.logon_level = r->in.logon_level;
604 r2.in.logon = r->in.logon;
605 r2.in.validation_level = r->in.validation_level;
606 r2.in.flags = r->in.flags;
608 nt_status = netr_LogonSamLogon_base(dce_call, mem_ctx, &r2, creds);
610 r->out.return_authenticator = return_authenticator;
611 r->out.validation = r2.out.validation;
612 r->out.authoritative = r2.out.authoritative;
613 r->out.flags = r2.out.flags;
621 static NTSTATUS netr_LogonSamLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
622 struct netr_LogonSamLogon *r)
624 struct netr_LogonSamLogonWithFlags r2;
629 r2.in.server_name = r->in.server_name;
630 r2.in.computer_name = r->in.computer_name;
631 r2.in.credential = r->in.credential;
632 r2.in.return_authenticator = r->in.return_authenticator;
633 r2.in.logon_level = r->in.logon_level;
634 r2.in.logon = r->in.logon;
635 r2.in.validation_level = r->in.validation_level;
638 status = netr_LogonSamLogonWithFlags(dce_call, mem_ctx, &r2);
640 r->out.return_authenticator = r2.out.return_authenticator;
641 r->out.validation = r2.out.validation;
642 r->out.authoritative = r2.out.authoritative;
651 static NTSTATUS netr_LogonSamLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
652 struct netr_LogonSamLogoff *r)
654 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
662 static NTSTATUS netr_DatabaseDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
663 struct netr_DatabaseDeltas *r)
665 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
672 static NTSTATUS netr_DatabaseSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
673 struct netr_DatabaseSync *r)
675 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
682 static NTSTATUS netr_AccountDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
683 struct netr_AccountDeltas *r)
685 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
692 static NTSTATUS netr_AccountSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
693 struct netr_AccountSync *r)
695 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
702 static NTSTATUS netr_GetDcName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
703 struct netr_GetDcName *r)
705 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
712 static WERROR netr_LogonControl(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
713 struct netr_LogonControl *r)
715 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
722 static WERROR netr_GetAnyDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
723 struct netr_GetAnyDCName *r)
725 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
732 static WERROR netr_LogonControl2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
733 struct netr_LogonControl2 *r)
735 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
742 static NTSTATUS netr_DatabaseSync2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
743 struct netr_DatabaseSync2 *r)
745 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
752 static NTSTATUS netr_DatabaseRedo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
753 struct netr_DatabaseRedo *r)
755 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
762 static WERROR netr_LogonControl2Ex(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
763 struct netr_LogonControl2Ex *r)
765 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
770 netr_NETRENUMERATETRUSTEDDOMAINS
772 static WERROR netr_NETRENUMERATETRUSTEDDOMAINS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
773 struct netr_NETRENUMERATETRUSTEDDOMAINS *r)
775 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
780 netr_NETRLOGONDUMMYROUTINE1
782 static WERROR netr_NETRLOGONDUMMYROUTINE1(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
783 struct netr_NETRLOGONDUMMYROUTINE1 *r)
785 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
790 netr_NETRLOGONSETSERVICEBITS
792 static WERROR netr_NETRLOGONSETSERVICEBITS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
793 struct netr_NETRLOGONSETSERVICEBITS *r)
795 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
800 netr_NETRLOGONGETTRUSTRID
802 static WERROR netr_NETRLOGONGETTRUSTRID(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
803 struct netr_NETRLOGONGETTRUSTRID *r)
805 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
810 netr_NETRLOGONCOMPUTESERVERDIGEST
812 static WERROR netr_NETRLOGONCOMPUTESERVERDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
813 struct netr_NETRLOGONCOMPUTESERVERDIGEST *r)
815 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
820 netr_NETRLOGONCOMPUTECLIENTDIGEST
822 static WERROR netr_NETRLOGONCOMPUTECLIENTDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
823 struct netr_NETRLOGONCOMPUTECLIENTDIGEST *r)
825 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
833 static WERROR netr_DsRGetSiteName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
834 struct netr_DsRGetSiteName *r)
836 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
841 fill in a netr_DomainTrustInfo from a ldb search result
843 static NTSTATUS fill_domain_primary_info(TALLOC_CTX *mem_ctx, struct ldb_message *res,
844 struct netr_DomainTrustInfo *info,
845 const char *local_domain)
849 info->domainname.string = local_domain;
850 info->fulldomainname.string = talloc_asprintf(info, "%s.", samdb_result_string(res, "dnsDomain", NULL));
851 /* TODO: we need proper forest support */
852 info->forest.string = info->fulldomainname.string;
853 info->guid = samdb_result_guid(res, "objectGUID");
854 info->sid = samdb_result_dom_sid(mem_ctx, res, "objectSid");
860 fill in a netr_DomainTrustInfo from a ldb search result
862 static NTSTATUS fill_domain_trust_info(TALLOC_CTX *mem_ctx, struct ldb_message *res,
863 struct netr_DomainTrustInfo *info,
864 const char *local_domain, BOOL is_local)
869 info->domainname.string = local_domain;
870 info->fulldomainname.string = samdb_result_string(res, "dnsDomain", NULL);
871 info->forest.string = NULL;
872 info->guid = samdb_result_guid(res, "objectGUID");
873 info->sid = samdb_result_dom_sid(mem_ctx, res, "objectSid");
875 info->domainname.string = samdb_result_string(res, "flatName", NULL);
876 info->fulldomainname.string = samdb_result_string(res, "name", NULL);
877 info->forest.string = NULL;
878 info->guid = samdb_result_guid(res, "objectGUID");
879 info->sid = samdb_result_dom_sid(mem_ctx, res, "securityIdentifier");
886 netr_LogonGetDomainInfo
887 this is called as part of the ADS domain logon procedure.
889 static NTSTATUS netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
890 struct netr_LogonGetDomainInfo *r)
892 const char * const attrs[] = { "dnsDomain", "objectSid",
893 "objectGUID", "flatName", "securityIdentifier",
895 const char * const ref_attrs[] = { "nETBIOSName", NULL };
896 struct ldb_context *sam_ctx;
897 struct ldb_message **res1, **res2, **ref_res;
898 struct netr_DomainInfo1 *info1;
899 int ret, ret1, ret2, i;
902 const char *local_domain;
904 status = netr_creds_server_step_check(r->in.computer_name, mem_ctx,
906 r->out.return_authenticator,
908 if (!NT_STATUS_IS_OK(status)) {
912 sam_ctx = samdb_connect(mem_ctx, dce_call->conn->auth_state.session_info);
913 if (sam_ctx == NULL) {
914 return NT_STATUS_INVALID_SYSTEM_SERVICE;
917 /* we need to do two searches. The first will pull our primary
918 domain and the second will pull any trusted domains. Our
919 primary domain is also a "trusted" domain, so we need to
920 put the primary domain into the lists of returned trusts as
922 ret1 = gendb_search(sam_ctx, mem_ctx, NULL, &res1, attrs, "(objectClass=domainDNS)");
924 return NT_STATUS_INTERNAL_DB_CORRUPTION;
927 /* try and find the domain */
928 ret = gendb_search(sam_ctx, mem_ctx, NULL,
930 "(&(objectClass=crossRef)(ncName=%s))",
931 ldb_dn_linearize(mem_ctx, res1[0]->dn));
933 return NT_STATUS_INTERNAL_DB_CORRUPTION;
936 local_domain = samdb_result_string(ref_res[0], "nETBIOSName", NULL);
938 ret2 = gendb_search(sam_ctx, mem_ctx, NULL, &res2, attrs, "(objectClass=trustedDomain)");
940 return NT_STATUS_INTERNAL_DB_CORRUPTION;
943 info1 = talloc(mem_ctx, struct netr_DomainInfo1);
945 return NT_STATUS_NO_MEMORY;
950 info1->num_trusts = ret2 + 1;
951 info1->trusts = talloc_array(mem_ctx, struct netr_DomainTrustInfo,
953 if (info1->trusts == NULL) {
954 return NT_STATUS_NO_MEMORY;
957 status = fill_domain_primary_info(mem_ctx, res1[0], &info1->domaininfo, local_domain);
958 if (!NT_STATUS_IS_OK(status)) {
962 for (i=0;i<ret2;i++) {
963 status = fill_domain_trust_info(mem_ctx, res2[i], &info1->trusts[i], NULL, False);
964 if (!NT_STATUS_IS_OK(status)) {
969 status = fill_domain_trust_info(mem_ctx, res1[0], &info1->trusts[i], local_domain, True);
970 if (!NT_STATUS_IS_OK(status)) {
974 r->out.info.info1 = info1;
982 netr_NETRSERVERPASSWORDGET
984 static WERROR netr_NETRSERVERPASSWORDGET(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
985 struct netr_NETRSERVERPASSWORDGET *r)
987 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
992 netr_NETRLOGONSENDTOSAM
994 static WERROR netr_NETRLOGONSENDTOSAM(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
995 struct netr_NETRLOGONSENDTOSAM *r)
997 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1002 netr_DSRADDRESSTOSITENAMESW
1004 static WERROR netr_DSRADDRESSTOSITENAMESW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1005 struct netr_DSRADDRESSTOSITENAMESW *r)
1007 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1012 netr_DsRGetDCNameEx2
1014 static WERROR netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1015 struct netr_DsRGetDCNameEx2 *r)
1017 const char * const attrs[] = { "dnsDomain", "objectGUID", NULL };
1019 struct ldb_message **res;
1022 ZERO_STRUCT(r->out);
1024 sam_ctx = samdb_connect(mem_ctx, dce_call->conn->auth_state.session_info);
1025 if (sam_ctx == NULL) {
1026 return WERR_DS_SERVICE_UNAVAILABLE;
1029 ret = gendb_search(sam_ctx, mem_ctx, NULL, &res, attrs,
1030 "(&(objectClass=domainDNS)(dnsDomain=%s))",
1033 return WERR_NO_SUCH_DOMAIN;
1036 r->out.info = talloc(mem_ctx, struct netr_DsRGetDCNameInfo);
1041 /* TODO: - return real IP address
1042 * - check all r->in.* parameters (server_unc is ignored by w2k3!)
1044 r->out.info->dc_unc = talloc_asprintf(mem_ctx, "\\\\%s.%s", lp_netbios_name(),lp_realm());
1045 r->out.info->dc_address = talloc_strdup(mem_ctx, "\\\\0.0.0.0");
1046 r->out.info->dc_address_type = 1;
1047 r->out.info->domain_guid = samdb_result_guid(res[0], "objectGUID");
1048 r->out.info->domain_name = samdb_result_string(res[0], "dnsDomain", NULL);
1049 r->out.info->forest_name = samdb_result_string(res[0], "dnsDomain", NULL);
1050 r->out.info->dc_flags = 0xE00001FD;
1051 r->out.info->dc_site_name = talloc_strdup(mem_ctx, "Default-First-Site-Name");
1052 r->out.info->client_site_name = talloc_strdup(mem_ctx, "Default-First-Site-Name");
1060 static WERROR netr_DsRGetDCNameEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1061 struct netr_DsRGetDCNameEx *r)
1063 struct netr_DsRGetDCNameEx2 r2;
1068 r2.in.server_unc = r->in.server_unc;
1069 r2.in.client_account = NULL;
1071 r2.in.domain_guid = r->in.domain_guid;
1072 r2.in.domain_name = r->in.domain_name;
1073 r2.in.site_name = r->in.site_name;
1074 r2.in.flags = r->in.flags;
1077 werr = netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1079 r->out.info = r2.out.info;
1087 static WERROR netr_DsRGetDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1088 struct netr_DsRGetDCName *r)
1090 struct netr_DsRGetDCNameEx2 r2;
1095 r2.in.server_unc = r->in.server_unc;
1096 r2.in.client_account = NULL;
1098 r2.in.domain_name = r->in.domain_name;
1099 r2.in.domain_guid = r->in.domain_guid;
1101 r2.in.site_name = NULL; /* should fill in from site GUID */
1102 r2.in.flags = r->in.flags;
1105 werr = netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1107 r->out.info = r2.out.info;
1113 netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN
1115 static WERROR netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1116 struct netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN *r)
1118 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1123 netr_NETRENUMERATETRUSTEDDOMAINSEX
1125 static WERROR netr_NETRENUMERATETRUSTEDDOMAINSEX(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1126 struct netr_NETRENUMERATETRUSTEDDOMAINSEX *r)
1128 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1133 netr_DSRADDRESSTOSITENAMESEXW
1135 static WERROR netr_DSRADDRESSTOSITENAMESEXW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1136 struct netr_DSRADDRESSTOSITENAMESEXW *r)
1138 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1143 netr_DSRGETDCSITECOVERAGEW
1145 static WERROR netr_DSRGETDCSITECOVERAGEW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1146 struct netr_DSRGETDCSITECOVERAGEW *r)
1148 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1153 netr_DsrEnumerateDomainTrusts
1155 static WERROR netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1156 struct netr_DsrEnumerateDomainTrusts *r)
1158 struct netr_DomainTrust *trusts;
1161 struct ldb_message **dom_res, **ref_res;
1162 const char * const dom_attrs[] = { "dnsDomain", "objectSid", "objectGUID", NULL };
1163 const char * const ref_attrs[] = { "nETBIOSName", NULL };
1165 ZERO_STRUCT(r->out);
1167 sam_ctx = samdb_connect(mem_ctx, dce_call->conn->auth_state.session_info);
1168 if (sam_ctx == NULL) {
1169 return WERR_GENERAL_FAILURE;
1172 ret = gendb_search_dn(sam_ctx, mem_ctx, samdb_base_dn(mem_ctx), &dom_res, dom_attrs);
1174 return WERR_GENERAL_FAILURE;
1178 return WERR_GENERAL_FAILURE;
1181 ret = gendb_search(sam_ctx, mem_ctx, NULL, &ref_res, ref_attrs,
1182 "(&(objectClass=crossRef)(ncName=%s))",
1183 ldb_dn_linearize(mem_ctx, dom_res[0]->dn));
1185 return WERR_GENERAL_FAILURE;
1189 return WERR_GENERAL_FAILURE;
1194 trusts = talloc_array(mem_ctx, struct netr_DomainTrust, ret);
1195 if (trusts == NULL) {
1200 r->out.trusts = trusts;
1202 /* TODO: add filtering by trust_flags, and correct trust_type
1204 trusts[0].netbios_name = samdb_result_string(ref_res[0], "nETBIOSName", NULL);
1205 trusts[0].dns_name = samdb_result_string(dom_res[0], "dnsDomain", NULL);
1206 trusts[0].trust_flags =
1207 NETR_TRUST_FLAG_TREEROOT |
1208 NETR_TRUST_FLAG_IN_FOREST |
1209 NETR_TRUST_FLAG_PRIMARY;
1210 trusts[0].parent_index = 0;
1211 trusts[0].trust_type = 2;
1212 trusts[0].trust_attributes = 0;
1213 trusts[0].sid = samdb_result_dom_sid(mem_ctx, dom_res[0], "objectSid");
1214 trusts[0].guid = samdb_result_guid(dom_res[0], "objectGUID");
1221 netr_DSRDEREGISTERDNSHOSTRECORDS
1223 static WERROR netr_DSRDEREGISTERDNSHOSTRECORDS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1224 struct netr_DSRDEREGISTERDNSHOSTRECORDS *r)
1226 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1231 netr_NETRSERVERTRUSTPASSWORDSGET
1233 static WERROR netr_NETRSERVERTRUSTPASSWORDSGET(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1234 struct netr_NETRSERVERTRUSTPASSWORDSGET *r)
1236 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1241 netr_DSRGETFORESTTRUSTINFORMATION
1243 static WERROR netr_DSRGETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1244 struct netr_DSRGETFORESTTRUSTINFORMATION *r)
1246 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1251 netr_NETRGETFORESTTRUSTINFORMATION
1253 static WERROR netr_NETRGETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1254 struct netr_NETRGETFORESTTRUSTINFORMATION *r)
1256 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1261 netr_NETRSERVERGETTRUSTINFO
1263 static WERROR netr_NETRSERVERGETTRUSTINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1264 struct netr_NETRSERVERGETTRUSTINFO *r)
1266 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1270 /* include the generated boilerplate */
1271 #include "librpc/gen_ndr/ndr_netlogon_s.c"