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 "auth/auth_sam.h"
30 #include "dsdb/samdb/samdb.h"
31 #include "rpc_server/samr/proto.h"
33 #include "libcli/auth/libcli_auth.h"
34 #include "auth/gensec/schannel_state.h"
35 #include "libcli/security/security.h"
37 struct server_pipe_state {
38 struct netr_Credential client_challenge;
39 struct netr_Credential server_challenge;
43 static NTSTATUS netr_ServerReqChallenge(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
44 struct netr_ServerReqChallenge *r)
46 struct server_pipe_state *pipe_state = dce_call->context->private;
48 ZERO_STRUCTP(r->out.credentials);
50 /* destroyed on pipe shutdown */
53 talloc_free(pipe_state);
54 dce_call->context->private = NULL;
57 pipe_state = talloc(dce_call->context, struct server_pipe_state);
59 return NT_STATUS_NO_MEMORY;
62 pipe_state->client_challenge = *r->in.credentials;
64 generate_random_buffer(pipe_state->server_challenge.data,
65 sizeof(pipe_state->server_challenge.data));
67 *r->out.credentials = pipe_state->server_challenge;
69 dce_call->context->private = pipe_state;
74 static NTSTATUS netr_ServerAuthenticate3(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
75 struct netr_ServerAuthenticate3 *r)
77 struct server_pipe_state *pipe_state = dce_call->context->private;
78 struct creds_CredentialState *creds;
80 struct samr_Password *mach_pwd;
83 struct ldb_message **msgs;
85 const char *attrs[] = {"ntPwdHash", "userAccountControl",
88 ZERO_STRUCTP(r->out.credentials);
90 *r->out.negotiate_flags = *r->in.negotiate_flags;
93 DEBUG(1, ("No challenge requested by client, cannot authenticate\n"));
94 return NT_STATUS_ACCESS_DENIED;
97 sam_ctx = samdb_connect(mem_ctx, system_session(mem_ctx));
98 if (sam_ctx == NULL) {
99 return NT_STATUS_INVALID_SYSTEM_SERVICE;
101 /* pull the user attributes */
102 num_records = gendb_search(sam_ctx, mem_ctx, NULL, &msgs, attrs,
103 "(&(sAMAccountName=%s)(objectclass=user))",
106 if (num_records == 0) {
107 DEBUG(3,("Couldn't find user [%s] in samdb.\n",
108 r->in.account_name));
109 return NT_STATUS_ACCESS_DENIED;
112 if (num_records > 1) {
113 DEBUG(0,("Found %d records matching user [%s]\n", num_records, r->in.account_name));
114 return NT_STATUS_INTERNAL_DB_CORRUPTION;
117 acct_flags = samdb_result_acct_flags(msgs[0],
118 "userAccountControl");
120 if (acct_flags & ACB_DISABLED) {
121 DEBUG(1, ("Account [%s] is disabled\n", r->in.account_name));
122 return NT_STATUS_ACCESS_DENIED;
125 if (r->in.secure_channel_type == SEC_CHAN_WKSTA) {
126 if (!(acct_flags & ACB_WSTRUST)) {
127 DEBUG(1, ("Client asked for a workstation secure channel, but is not a workstation (member server) acb flags: 0x%x\n", acct_flags));
128 return NT_STATUS_ACCESS_DENIED;
130 } else if (r->in.secure_channel_type == SEC_CHAN_DOMAIN) {
131 if (!(acct_flags & ACB_DOMTRUST)) {
132 DEBUG(1, ("Client asked for a trusted domain secure channel, but is not a trusted domain: acb flags: 0x%x\n", acct_flags));
133 return NT_STATUS_ACCESS_DENIED;
135 } else if (r->in.secure_channel_type == SEC_CHAN_BDC) {
136 if (!(acct_flags & ACB_SVRTRUST)) {
137 DEBUG(1, ("Client asked for a server secure channel, but is not a server (domain controller): acb flags: 0x%x\n", acct_flags));
138 return NT_STATUS_ACCESS_DENIED;
141 DEBUG(1, ("Client asked for an invalid secure channel type: %d\n",
142 r->in.secure_channel_type));
143 return NT_STATUS_ACCESS_DENIED;
146 *r->out.rid = samdb_result_rid_from_sid(mem_ctx, msgs[0],
149 mach_pwd = samdb_result_hash(mem_ctx, msgs[0], "ntPwdHash");
150 if (mach_pwd == NULL) {
151 return NT_STATUS_ACCESS_DENIED;
154 creds = talloc(mem_ctx, struct creds_CredentialState);
156 return NT_STATUS_NO_MEMORY;
159 creds_server_init(creds, &pipe_state->client_challenge,
160 &pipe_state->server_challenge, mach_pwd,
162 *r->in.negotiate_flags);
164 if (!creds_server_check(creds, r->in.credentials)) {
166 return NT_STATUS_ACCESS_DENIED;
169 creds->account_name = talloc_steal(creds, r->in.account_name);
171 creds->computer_name = talloc_steal(creds, r->in.computer_name);
172 creds->domain = talloc_strdup(creds, lp_workgroup());
174 creds->secure_channel_type = r->in.secure_channel_type;
176 creds->sid = samdb_result_dom_sid(creds, msgs[0], "objectSid");
179 /* remember this session key state */
180 nt_status = schannel_store_session_key(mem_ctx, creds);
185 static NTSTATUS netr_ServerAuthenticate(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
186 struct netr_ServerAuthenticate *r)
188 struct netr_ServerAuthenticate3 r3;
191 * negotiate_flags is used as an [in] parameter
192 * so it need to be initialised.
194 * (I think ... = 0; seems wrong here --metze)
196 uint32_t negotiate_flags = 0;
198 r3.in.server_name = r->in.server_name;
199 r3.in.account_name = r->in.account_name;
200 r3.in.secure_channel_type = r->in.secure_channel_type;
201 r3.in.computer_name = r->in.computer_name;
202 r3.in.credentials = r->in.credentials;
203 r3.out.credentials = r->out.credentials;
204 r3.in.negotiate_flags = &negotiate_flags;
205 r3.out.negotiate_flags = &negotiate_flags;
208 return netr_ServerAuthenticate3(dce_call, mem_ctx, &r3);
211 static NTSTATUS netr_ServerAuthenticate2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
212 struct netr_ServerAuthenticate2 *r)
214 struct netr_ServerAuthenticate3 r3;
217 r3.in.server_name = r->in.server_name;
218 r3.in.account_name = r->in.account_name;
219 r3.in.secure_channel_type = r->in.secure_channel_type;
220 r3.in.computer_name = r->in.computer_name;
221 r3.in.credentials = r->in.credentials;
222 r3.out.credentials = r->out.credentials;
223 r3.in.negotiate_flags = r->in.negotiate_flags;
224 r3.out.negotiate_flags = r->out.negotiate_flags;
227 return netr_ServerAuthenticate3(dce_call, mem_ctx, &r3);
231 Validate an incoming authenticator against the credentials for the remote machine.
233 The credentials are (re)read and from the schannel database, and
234 written back after the caclulations are performed.
236 The creds_out parameter (if not NULL) returns the credentials, if
237 the caller needs some of that information.
240 static NTSTATUS netr_creds_server_step_check(const char *computer_name,
242 struct netr_Authenticator *received_authenticator,
243 struct netr_Authenticator *return_authenticator,
244 struct creds_CredentialState **creds_out)
246 struct creds_CredentialState *creds;
248 struct ldb_context *ldb;
251 ldb = schannel_db_connect(mem_ctx);
253 return NT_STATUS_ACCESS_DENIED;
256 ret = ldb_transaction_start(ldb);
259 return NT_STATUS_INTERNAL_DB_CORRUPTION;
262 /* Because this is a shared structure (even across
263 * disconnects) we must update the database every time we
264 * update the structure */
266 nt_status = schannel_fetch_session_key_ldb(ldb, ldb, computer_name, lp_workgroup(),
268 if (NT_STATUS_IS_OK(nt_status)) {
269 nt_status = creds_server_step_check(creds,
270 received_authenticator,
271 return_authenticator);
273 if (NT_STATUS_IS_OK(nt_status)) {
274 nt_status = schannel_store_session_key_ldb(ldb, ldb, creds);
277 if (NT_STATUS_IS_OK(nt_status)) {
278 ldb_transaction_commit(ldb);
281 talloc_steal(mem_ctx, creds);
284 ldb_transaction_cancel(ldb);
291 Change the machine account password for the currently connected
292 client. Supplies only the NT#.
295 static NTSTATUS netr_ServerPasswordSet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
296 struct netr_ServerPasswordSet *r)
298 struct creds_CredentialState *creds;
299 struct ldb_context *sam_ctx;
302 nt_status = netr_creds_server_step_check(r->in.computer_name, mem_ctx,
303 &r->in.credential, &r->out.return_authenticator,
305 NT_STATUS_NOT_OK_RETURN(nt_status);
307 sam_ctx = samdb_connect(mem_ctx, system_session(mem_ctx));
308 if (sam_ctx == NULL) {
309 return NT_STATUS_INVALID_SYSTEM_SERVICE;
312 creds_des_decrypt(creds, &r->in.new_password);
314 /* Using the sid for the account as the key, set the password */
315 nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
317 NULL, /* Don't have plaintext */
318 NULL, &r->in.new_password,
319 False, /* This is not considered a password change */
320 False, /* don't restrict this password change (match w2k3) */
326 Change the machine account password for the currently connected
327 client. Supplies new plaintext.
329 static NTSTATUS netr_ServerPasswordSet2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
330 struct netr_ServerPasswordSet2 *r)
332 struct creds_CredentialState *creds;
333 struct ldb_context *sam_ctx;
336 uint32_t new_pass_len;
339 struct samr_CryptPassword password_buf;
341 nt_status = netr_creds_server_step_check(r->in.computer_name, mem_ctx,
342 &r->in.credential, &r->out.return_authenticator,
344 NT_STATUS_NOT_OK_RETURN(nt_status);
346 sam_ctx = samdb_connect(mem_ctx, system_session(mem_ctx));
347 if (sam_ctx == NULL) {
348 return NT_STATUS_INVALID_SYSTEM_SERVICE;
351 memcpy(password_buf.data, r->in.new_password.data, 512);
352 SIVAL(password_buf.data,512,r->in.new_password.length);
353 creds_arcfour_crypt(creds, password_buf.data, 516);
355 ret = decode_pw_buffer(password_buf.data, new_pass, sizeof(new_pass),
356 &new_pass_len, STR_UNICODE);
358 DEBUG(3,("netr_ServerPasswordSet2: failed to decode password buffer\n"));
359 return NT_STATUS_ACCESS_DENIED;
362 /* Using the sid for the account as the key, set the password */
363 nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
365 new_pass, /* we have plaintext */
367 False, /* This is not considered a password change */
368 False, /* don't restrict this password change (match w2k3) */
377 static WERROR netr_LogonUasLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
378 struct netr_LogonUasLogon *r)
380 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
387 static WERROR netr_LogonUasLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
388 struct netr_LogonUasLogoff *r)
390 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
395 netr_LogonSamLogon_base
397 This version of the function allows other wrappers to say 'do not check the credentials'
399 We can't do the traditional 'wrapping' format completly, as this function must only run under schannel
401 static NTSTATUS netr_LogonSamLogon_base(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
402 struct netr_LogonSamLogonEx *r, struct creds_CredentialState *creds)
404 struct auth_context *auth_context;
405 struct auth_usersupplied_info *user_info;
406 struct auth_serversupplied_info *server_info;
408 static const char zeros[16];
409 struct netr_SamBaseInfo *sam;
410 struct netr_SamInfo2 *sam2;
411 struct netr_SamInfo3 *sam3;
412 struct netr_SamInfo6 *sam6;
414 user_info = talloc(mem_ctx, struct auth_usersupplied_info);
416 return NT_STATUS_NO_MEMORY;
419 user_info->flags = 0;
420 user_info->mapped_state = False;
421 user_info->remote_host = NULL;
423 switch (r->in.logon_level) {
427 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
428 creds_arcfour_crypt(creds,
429 r->in.logon.password->lmpassword.hash,
430 sizeof(r->in.logon.password->lmpassword.hash));
431 creds_arcfour_crypt(creds,
432 r->in.logon.password->ntpassword.hash,
433 sizeof(r->in.logon.password->ntpassword.hash));
435 creds_des_decrypt(creds, &r->in.logon.password->lmpassword);
436 creds_des_decrypt(creds, &r->in.logon.password->ntpassword);
439 /* TODO: we need to deny anonymous access here */
440 nt_status = auth_context_create(mem_ctx, lp_auth_methods(), &auth_context,
441 dce_call->event_ctx);
442 NT_STATUS_NOT_OK_RETURN(nt_status);
444 user_info->logon_parameters = r->in.logon.password->identity_info.parameter_control;
445 user_info->client.account_name = r->in.logon.password->identity_info.account_name.string;
446 user_info->client.domain_name = r->in.logon.password->identity_info.domain_name.string;
447 user_info->workstation_name = r->in.logon.password->identity_info.workstation.string;
449 user_info->password_state = AUTH_PASSWORD_HASH;
450 user_info->password.hash.lanman = talloc(user_info, struct samr_Password);
451 if (!user_info->password.hash.lanman) {
452 return NT_STATUS_NO_MEMORY;
454 *user_info->password.hash.lanman = r->in.logon.password->lmpassword;
456 user_info->password.hash.nt = talloc(user_info, struct samr_Password);
457 if (!user_info->password.hash.nt) {
458 return NT_STATUS_NO_MEMORY;
460 *user_info->password.hash.nt = r->in.logon.password->ntpassword;
462 user_info->flags |= USER_INFO_INTERACTIVE_LOGON;
468 /* TODO: we need to deny anonymous access here */
469 nt_status = auth_context_create(mem_ctx, lp_auth_methods(), &auth_context,
470 dce_call->event_ctx);
471 NT_STATUS_NOT_OK_RETURN(nt_status);
473 nt_status = auth_context_set_challenge(auth_context, r->in.logon.network->challenge, "netr_LogonSamLogonWithFlags");
474 NT_STATUS_NOT_OK_RETURN(nt_status);
476 user_info->logon_parameters = r->in.logon.network->identity_info.parameter_control;
477 user_info->client.account_name = r->in.logon.network->identity_info.account_name.string;
478 user_info->client.domain_name = r->in.logon.network->identity_info.domain_name.string;
479 user_info->workstation_name = r->in.logon.network->identity_info.workstation.string;
481 user_info->password_state = AUTH_PASSWORD_RESPONSE;
482 user_info->password.response.lanman = data_blob_talloc(mem_ctx, r->in.logon.network->lm.data, r->in.logon.network->lm.length);
483 user_info->password.response.nt = data_blob_talloc(mem_ctx, r->in.logon.network->nt.data, r->in.logon.network->nt.length);
487 return NT_STATUS_INVALID_PARAMETER;
490 nt_status = auth_check_password(auth_context, mem_ctx, user_info, &server_info);
491 NT_STATUS_NOT_OK_RETURN(nt_status);
493 nt_status = auth_convert_server_info_sambaseinfo(mem_ctx, server_info, &sam);
495 NT_STATUS_NOT_OK_RETURN(nt_status);
497 /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
498 /* It appears that level 6 is not individually encrypted */
499 if ((r->in.validation_level != 6)
500 && memcmp(sam->key.key, zeros,
501 sizeof(sam->key.key)) != 0) {
503 /* This key is sent unencrypted without the ARCFOUR flag set */
504 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
505 creds_arcfour_crypt(creds,
507 sizeof(sam->key.key));
511 /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
512 /* It appears that level 6 is not individually encrypted */
513 if ((r->in.validation_level != 6)
514 && memcmp(sam->LMSessKey.key, zeros,
515 sizeof(sam->LMSessKey.key)) != 0) {
516 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
517 creds_arcfour_crypt(creds,
519 sizeof(sam->LMSessKey.key));
521 creds_des_encrypt_LMKey(creds,
526 switch (r->in.validation_level) {
528 sam2 = talloc_zero(mem_ctx, struct netr_SamInfo2);
529 NT_STATUS_HAVE_NO_MEMORY(sam2);
531 r->out.validation.sam2 = sam2;
535 sam3 = talloc_zero(mem_ctx, struct netr_SamInfo3);
536 NT_STATUS_HAVE_NO_MEMORY(sam3);
538 r->out.validation.sam3 = sam3;
542 sam6 = talloc_zero(mem_ctx, struct netr_SamInfo6);
543 NT_STATUS_HAVE_NO_MEMORY(sam6);
545 sam6->forest.string = lp_realm();
546 sam6->principle.string = talloc_asprintf(mem_ctx, "%s@%s",
547 sam->account_name.string, sam6->forest.string);
548 NT_STATUS_HAVE_NO_MEMORY(sam6->principle.string);
549 r->out.validation.sam6 = sam6;
556 r->out.authoritative = 1;
558 /* TODO: Describe and deal with these flags */
564 static NTSTATUS netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
565 struct netr_LogonSamLogonEx *r)
568 struct creds_CredentialState *creds;
569 nt_status = schannel_fetch_session_key(mem_ctx, r->in.computer_name, lp_workgroup(), &creds);
570 if (!NT_STATUS_IS_OK(nt_status)) {
574 if (!dce_call->conn->auth_state.auth_info
575 || dce_call->conn->auth_state.auth_info->auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
576 return NT_STATUS_INTERNAL_ERROR;
578 return netr_LogonSamLogon_base(dce_call, mem_ctx, r, creds);
582 netr_LogonSamLogonWithFlags
585 static NTSTATUS netr_LogonSamLogonWithFlags(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
586 struct netr_LogonSamLogonWithFlags *r)
589 struct creds_CredentialState *creds;
590 struct netr_LogonSamLogonEx r2;
592 struct netr_Authenticator *return_authenticator;
594 return_authenticator = talloc(mem_ctx, struct netr_Authenticator);
595 NT_STATUS_HAVE_NO_MEMORY(return_authenticator);
597 nt_status = netr_creds_server_step_check(r->in.computer_name, mem_ctx,
598 r->in.credential, return_authenticator,
600 NT_STATUS_NOT_OK_RETURN(nt_status);
604 r2.in.server_name = r->in.server_name;
605 r2.in.computer_name = r->in.computer_name;
606 r2.in.logon_level = r->in.logon_level;
607 r2.in.logon = r->in.logon;
608 r2.in.validation_level = r->in.validation_level;
609 r2.in.flags = r->in.flags;
611 nt_status = netr_LogonSamLogon_base(dce_call, mem_ctx, &r2, creds);
613 r->out.return_authenticator = return_authenticator;
614 r->out.validation = r2.out.validation;
615 r->out.authoritative = r2.out.authoritative;
616 r->out.flags = r2.out.flags;
624 static NTSTATUS netr_LogonSamLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
625 struct netr_LogonSamLogon *r)
627 struct netr_LogonSamLogonWithFlags r2;
632 r2.in.server_name = r->in.server_name;
633 r2.in.computer_name = r->in.computer_name;
634 r2.in.credential = r->in.credential;
635 r2.in.return_authenticator = r->in.return_authenticator;
636 r2.in.logon_level = r->in.logon_level;
637 r2.in.logon = r->in.logon;
638 r2.in.validation_level = r->in.validation_level;
641 status = netr_LogonSamLogonWithFlags(dce_call, mem_ctx, &r2);
643 r->out.return_authenticator = r2.out.return_authenticator;
644 r->out.validation = r2.out.validation;
645 r->out.authoritative = r2.out.authoritative;
654 static NTSTATUS netr_LogonSamLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
655 struct netr_LogonSamLogoff *r)
657 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
665 static NTSTATUS netr_DatabaseDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
666 struct netr_DatabaseDeltas *r)
668 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
675 static NTSTATUS netr_DatabaseSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
676 struct netr_DatabaseSync *r)
678 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
685 static NTSTATUS netr_AccountDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
686 struct netr_AccountDeltas *r)
688 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
695 static NTSTATUS netr_AccountSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
696 struct netr_AccountSync *r)
698 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
705 static NTSTATUS netr_GetDcName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
706 struct netr_GetDcName *r)
708 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
715 static WERROR netr_LogonControl(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
716 struct netr_LogonControl *r)
718 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
725 static WERROR netr_GetAnyDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
726 struct netr_GetAnyDCName *r)
728 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
735 static WERROR netr_LogonControl2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
736 struct netr_LogonControl2 *r)
738 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
745 static NTSTATUS netr_DatabaseSync2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
746 struct netr_DatabaseSync2 *r)
748 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
755 static NTSTATUS netr_DatabaseRedo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
756 struct netr_DatabaseRedo *r)
758 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
765 static WERROR netr_LogonControl2Ex(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
766 struct netr_LogonControl2Ex *r)
768 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
773 netr_NETRENUMERATETRUSTEDDOMAINS
775 static WERROR netr_NETRENUMERATETRUSTEDDOMAINS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
776 struct netr_NETRENUMERATETRUSTEDDOMAINS *r)
778 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
783 netr_NETRLOGONDUMMYROUTINE1
785 static WERROR netr_NETRLOGONDUMMYROUTINE1(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
786 struct netr_NETRLOGONDUMMYROUTINE1 *r)
788 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
793 netr_NETRLOGONSETSERVICEBITS
795 static WERROR netr_NETRLOGONSETSERVICEBITS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
796 struct netr_NETRLOGONSETSERVICEBITS *r)
798 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
803 netr_NETRLOGONGETTRUSTRID
805 static WERROR netr_NETRLOGONGETTRUSTRID(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
806 struct netr_NETRLOGONGETTRUSTRID *r)
808 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
813 netr_NETRLOGONCOMPUTESERVERDIGEST
815 static WERROR netr_NETRLOGONCOMPUTESERVERDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
816 struct netr_NETRLOGONCOMPUTESERVERDIGEST *r)
818 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
823 netr_NETRLOGONCOMPUTECLIENTDIGEST
825 static WERROR netr_NETRLOGONCOMPUTECLIENTDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
826 struct netr_NETRLOGONCOMPUTECLIENTDIGEST *r)
828 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
836 static WERROR netr_DsRGetSiteName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
837 struct netr_DsRGetSiteName *r)
839 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
844 fill in a netr_DomainTrustInfo from a ldb search result
846 static NTSTATUS fill_domain_primary_info(TALLOC_CTX *mem_ctx, struct ldb_message *res,
847 struct netr_DomainTrustInfo *info,
848 const char *local_domain)
852 info->domainname.string = local_domain;
853 info->fulldomainname.string = talloc_asprintf(info, "%s.", samdb_result_string(res, "dnsDomain", NULL));
854 /* TODO: we need proper forest support */
855 info->forest.string = info->fulldomainname.string;
856 info->guid = samdb_result_guid(res, "objectGUID");
857 info->sid = samdb_result_dom_sid(mem_ctx, res, "objectSid");
863 fill in a netr_DomainTrustInfo from a ldb search result
865 static NTSTATUS fill_domain_trust_info(TALLOC_CTX *mem_ctx, struct ldb_message *res,
866 struct netr_DomainTrustInfo *info,
867 const char *local_domain, BOOL is_local)
872 info->domainname.string = local_domain;
873 info->fulldomainname.string = samdb_result_string(res, "dnsDomain", NULL);
874 info->forest.string = NULL;
875 info->guid = samdb_result_guid(res, "objectGUID");
876 info->sid = samdb_result_dom_sid(mem_ctx, res, "objectSid");
878 info->domainname.string = samdb_result_string(res, "flatName", NULL);
879 info->fulldomainname.string = samdb_result_string(res, "name", NULL);
880 info->forest.string = NULL;
881 info->guid = samdb_result_guid(res, "objectGUID");
882 info->sid = samdb_result_dom_sid(mem_ctx, res, "securityIdentifier");
889 netr_LogonGetDomainInfo
890 this is called as part of the ADS domain logon procedure.
892 static NTSTATUS netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
893 struct netr_LogonGetDomainInfo *r)
895 const char * const attrs[] = { "dnsDomain", "objectSid",
896 "objectGUID", "flatName", "securityIdentifier",
898 const char * const ref_attrs[] = { "nETBIOSName", NULL };
899 struct ldb_context *sam_ctx;
900 struct ldb_message **res1, **res2, **ref_res;
901 struct netr_DomainInfo1 *info1;
902 int ret, ret1, ret2, i;
905 const char *local_domain;
907 status = netr_creds_server_step_check(r->in.computer_name, mem_ctx,
909 r->out.return_authenticator,
911 if (!NT_STATUS_IS_OK(status)) {
915 sam_ctx = samdb_connect(mem_ctx, dce_call->conn->auth_state.session_info);
916 if (sam_ctx == NULL) {
917 return NT_STATUS_INVALID_SYSTEM_SERVICE;
920 /* we need to do two searches. The first will pull our primary
921 domain and the second will pull any trusted domains. Our
922 primary domain is also a "trusted" domain, so we need to
923 put the primary domain into the lists of returned trusts as
925 ret1 = gendb_search(sam_ctx, mem_ctx, NULL, &res1, attrs, "(objectClass=domainDNS)");
927 return NT_STATUS_INTERNAL_DB_CORRUPTION;
930 /* try and find the domain */
931 ret = gendb_search(sam_ctx, mem_ctx, NULL,
933 "(&(objectClass=crossRef)(ncName=%s))",
934 ldb_dn_linearize(mem_ctx, res1[0]->dn));
936 return NT_STATUS_INTERNAL_DB_CORRUPTION;
939 local_domain = samdb_result_string(ref_res[0], "nETBIOSName", NULL);
941 ret2 = gendb_search(sam_ctx, mem_ctx, NULL, &res2, attrs, "(objectClass=trustedDomain)");
943 return NT_STATUS_INTERNAL_DB_CORRUPTION;
946 info1 = talloc(mem_ctx, struct netr_DomainInfo1);
948 return NT_STATUS_NO_MEMORY;
953 info1->num_trusts = ret2 + 1;
954 info1->trusts = talloc_array(mem_ctx, struct netr_DomainTrustInfo,
956 if (info1->trusts == NULL) {
957 return NT_STATUS_NO_MEMORY;
960 status = fill_domain_primary_info(mem_ctx, res1[0], &info1->domaininfo, local_domain);
961 if (!NT_STATUS_IS_OK(status)) {
965 for (i=0;i<ret2;i++) {
966 status = fill_domain_trust_info(mem_ctx, res2[i], &info1->trusts[i], NULL, False);
967 if (!NT_STATUS_IS_OK(status)) {
972 status = fill_domain_trust_info(mem_ctx, res1[0], &info1->trusts[i], local_domain, True);
973 if (!NT_STATUS_IS_OK(status)) {
977 r->out.info.info1 = info1;
985 netr_NETRSERVERPASSWORDGET
987 static WERROR netr_NETRSERVERPASSWORDGET(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
988 struct netr_NETRSERVERPASSWORDGET *r)
990 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
995 netr_NETRLOGONSENDTOSAM
997 static WERROR netr_NETRLOGONSENDTOSAM(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
998 struct netr_NETRLOGONSENDTOSAM *r)
1000 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1005 netr_DSRADDRESSTOSITENAMESW
1007 static WERROR netr_DSRADDRESSTOSITENAMESW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1008 struct netr_DSRADDRESSTOSITENAMESW *r)
1010 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1015 netr_DsRGetDCNameEx2
1017 static WERROR netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1018 struct netr_DsRGetDCNameEx2 *r)
1020 const char * const attrs[] = { "dnsDomain", "objectGUID", NULL };
1022 struct ldb_message **res;
1025 ZERO_STRUCT(r->out);
1027 sam_ctx = samdb_connect(mem_ctx, dce_call->conn->auth_state.session_info);
1028 if (sam_ctx == NULL) {
1029 return WERR_DS_SERVICE_UNAVAILABLE;
1032 ret = gendb_search(sam_ctx, mem_ctx, NULL, &res, attrs,
1033 "(&(objectClass=domainDNS)(dnsDomain=%s))",
1036 return WERR_NO_SUCH_DOMAIN;
1039 r->out.info = talloc(mem_ctx, struct netr_DsRGetDCNameInfo);
1044 /* TODO: - return real IP address
1045 * - check all r->in.* parameters (server_unc is ignored by w2k3!)
1047 r->out.info->dc_unc = talloc_asprintf(mem_ctx, "\\\\%s.%s", lp_netbios_name(),lp_realm());
1048 r->out.info->dc_address = talloc_strdup(mem_ctx, "\\\\0.0.0.0");
1049 r->out.info->dc_address_type = 1;
1050 r->out.info->domain_guid = samdb_result_guid(res[0], "objectGUID");
1051 r->out.info->domain_name = samdb_result_string(res[0], "dnsDomain", NULL);
1052 r->out.info->forest_name = samdb_result_string(res[0], "dnsDomain", NULL);
1053 r->out.info->dc_flags = 0xE00001FD;
1054 r->out.info->dc_site_name = talloc_strdup(mem_ctx, "Default-First-Site-Name");
1055 r->out.info->client_site_name = talloc_strdup(mem_ctx, "Default-First-Site-Name");
1063 static WERROR netr_DsRGetDCNameEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1064 struct netr_DsRGetDCNameEx *r)
1066 struct netr_DsRGetDCNameEx2 r2;
1071 r2.in.server_unc = r->in.server_unc;
1072 r2.in.client_account = NULL;
1074 r2.in.domain_guid = r->in.domain_guid;
1075 r2.in.domain_name = r->in.domain_name;
1076 r2.in.site_name = r->in.site_name;
1077 r2.in.flags = r->in.flags;
1080 werr = netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1082 r->out.info = r2.out.info;
1090 static WERROR netr_DsRGetDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1091 struct netr_DsRGetDCName *r)
1093 struct netr_DsRGetDCNameEx2 r2;
1098 r2.in.server_unc = r->in.server_unc;
1099 r2.in.client_account = NULL;
1101 r2.in.domain_name = r->in.domain_name;
1102 r2.in.domain_guid = r->in.domain_guid;
1104 r2.in.site_name = NULL; /* should fill in from site GUID */
1105 r2.in.flags = r->in.flags;
1108 werr = netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1110 r->out.info = r2.out.info;
1116 netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN
1118 static WERROR netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1119 struct netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN *r)
1121 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1126 netr_NETRENUMERATETRUSTEDDOMAINSEX
1128 static WERROR netr_NETRENUMERATETRUSTEDDOMAINSEX(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1129 struct netr_NETRENUMERATETRUSTEDDOMAINSEX *r)
1131 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1136 netr_DSRADDRESSTOSITENAMESEXW
1138 static WERROR netr_DSRADDRESSTOSITENAMESEXW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1139 struct netr_DSRADDRESSTOSITENAMESEXW *r)
1141 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1146 netr_DSRGETDCSITECOVERAGEW
1148 static WERROR netr_DSRGETDCSITECOVERAGEW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1149 struct netr_DSRGETDCSITECOVERAGEW *r)
1151 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1156 netr_DsrEnumerateDomainTrusts
1158 static WERROR netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1159 struct netr_DsrEnumerateDomainTrusts *r)
1161 struct netr_DomainTrust *trusts;
1164 struct ldb_message **dom_res, **ref_res;
1165 const char * const dom_attrs[] = { "dnsDomain", "objectSid", "objectGUID", NULL };
1166 const char * const ref_attrs[] = { "nETBIOSName", NULL };
1168 ZERO_STRUCT(r->out);
1170 sam_ctx = samdb_connect(mem_ctx, dce_call->conn->auth_state.session_info);
1171 if (sam_ctx == NULL) {
1172 return WERR_GENERAL_FAILURE;
1175 ret = gendb_search_dn(sam_ctx, mem_ctx, samdb_base_dn(mem_ctx), &dom_res, dom_attrs);
1177 return WERR_GENERAL_FAILURE;
1181 return WERR_GENERAL_FAILURE;
1184 ret = gendb_search(sam_ctx, mem_ctx, NULL, &ref_res, ref_attrs,
1185 "(&(objectClass=crossRef)(ncName=%s))",
1186 ldb_dn_linearize(mem_ctx, dom_res[0]->dn));
1188 return WERR_GENERAL_FAILURE;
1192 return WERR_GENERAL_FAILURE;
1197 trusts = talloc_array(mem_ctx, struct netr_DomainTrust, ret);
1198 if (trusts == NULL) {
1203 r->out.trusts = trusts;
1205 /* TODO: add filtering by trust_flags, and correct trust_type
1207 trusts[0].netbios_name = samdb_result_string(ref_res[0], "nETBIOSName", NULL);
1208 trusts[0].dns_name = samdb_result_string(dom_res[0], "dnsDomain", NULL);
1209 trusts[0].trust_flags =
1210 NETR_TRUST_FLAG_TREEROOT |
1211 NETR_TRUST_FLAG_IN_FOREST |
1212 NETR_TRUST_FLAG_PRIMARY;
1213 trusts[0].parent_index = 0;
1214 trusts[0].trust_type = 2;
1215 trusts[0].trust_attributes = 0;
1216 trusts[0].sid = samdb_result_dom_sid(mem_ctx, dom_res[0], "objectSid");
1217 trusts[0].guid = samdb_result_guid(dom_res[0], "objectGUID");
1224 netr_DSRDEREGISTERDNSHOSTRECORDS
1226 static WERROR netr_DSRDEREGISTERDNSHOSTRECORDS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1227 struct netr_DSRDEREGISTERDNSHOSTRECORDS *r)
1229 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1234 netr_NETRSERVERTRUSTPASSWORDSGET
1236 static WERROR netr_NETRSERVERTRUSTPASSWORDSGET(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1237 struct netr_NETRSERVERTRUSTPASSWORDSGET *r)
1239 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1244 netr_DSRGETFORESTTRUSTINFORMATION
1246 static WERROR netr_DSRGETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1247 struct netr_DSRGETFORESTTRUSTINFORMATION *r)
1249 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1254 netr_NETRGETFORESTTRUSTINFORMATION
1256 static WERROR netr_NETRGETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1257 struct netr_NETRGETFORESTTRUSTINFORMATION *r)
1259 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1264 netr_NETRSERVERGETTRUSTINFO
1266 static WERROR netr_NETRSERVERGETTRUSTINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1267 struct netr_NETRSERVERGETTRUSTINFO *r)
1269 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1273 /* include the generated boilerplate */
1274 #include "librpc/gen_ndr/ndr_netlogon_s.c"