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);
58 NT_STATUS_HAVE_NO_MEMORY(pipe_state);
60 pipe_state->client_challenge = *r->in.credentials;
62 generate_random_buffer(pipe_state->server_challenge.data,
63 sizeof(pipe_state->server_challenge.data));
65 *r->out.credentials = pipe_state->server_challenge;
67 dce_call->context->private = pipe_state;
72 static NTSTATUS netr_ServerAuthenticate3(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
73 struct netr_ServerAuthenticate3 *r)
75 struct server_pipe_state *pipe_state = dce_call->context->private;
76 struct creds_CredentialState *creds;
78 struct samr_Password *mach_pwd;
81 struct ldb_message **msgs;
83 const char *attrs[] = {"ntPwdHash", "userAccountControl",
86 ZERO_STRUCTP(r->out.credentials);
88 *r->out.negotiate_flags = *r->in.negotiate_flags;
91 DEBUG(1, ("No challenge requested by client, cannot authenticate\n"));
92 return NT_STATUS_ACCESS_DENIED;
95 sam_ctx = samdb_connect(mem_ctx, system_session(mem_ctx));
96 if (sam_ctx == NULL) {
97 return NT_STATUS_INVALID_SYSTEM_SERVICE;
99 /* pull the user attributes */
100 num_records = gendb_search(sam_ctx, mem_ctx, NULL, &msgs, attrs,
101 "(&(sAMAccountName=%s)(objectclass=user))",
104 if (num_records == 0) {
105 DEBUG(3,("Couldn't find user [%s] in samdb.\n",
106 r->in.account_name));
107 return NT_STATUS_ACCESS_DENIED;
110 if (num_records > 1) {
111 DEBUG(0,("Found %d records matching user [%s]\n", num_records, r->in.account_name));
112 return NT_STATUS_INTERNAL_DB_CORRUPTION;
115 acct_flags = samdb_result_acct_flags(msgs[0],
116 "userAccountControl");
118 if (acct_flags & ACB_DISABLED) {
119 DEBUG(1, ("Account [%s] is disabled\n", r->in.account_name));
120 return NT_STATUS_ACCESS_DENIED;
123 if (r->in.secure_channel_type == SEC_CHAN_WKSTA) {
124 if (!(acct_flags & ACB_WSTRUST)) {
125 DEBUG(1, ("Client asked for a workstation secure channel, but is not a workstation (member server) acb flags: 0x%x\n", acct_flags));
126 return NT_STATUS_ACCESS_DENIED;
128 } else if (r->in.secure_channel_type == SEC_CHAN_DOMAIN) {
129 if (!(acct_flags & ACB_DOMTRUST)) {
130 DEBUG(1, ("Client asked for a trusted domain secure channel, but is not a trusted domain: acb flags: 0x%x\n", acct_flags));
131 return NT_STATUS_ACCESS_DENIED;
133 } else if (r->in.secure_channel_type == SEC_CHAN_BDC) {
134 if (!(acct_flags & ACB_SVRTRUST)) {
135 DEBUG(1, ("Client asked for a server secure channel, but is not a server (domain controller): acb flags: 0x%x\n", acct_flags));
136 return NT_STATUS_ACCESS_DENIED;
139 DEBUG(1, ("Client asked for an invalid secure channel type: %d\n",
140 r->in.secure_channel_type));
141 return NT_STATUS_ACCESS_DENIED;
144 *r->out.rid = samdb_result_rid_from_sid(mem_ctx, msgs[0],
147 mach_pwd = samdb_result_hash(mem_ctx, msgs[0], "ntPwdHash");
148 if (mach_pwd == NULL) {
149 return NT_STATUS_ACCESS_DENIED;
152 creds = talloc(mem_ctx, struct creds_CredentialState);
153 NT_STATUS_HAVE_NO_MEMORY(creds);
155 creds_server_init(creds, &pipe_state->client_challenge,
156 &pipe_state->server_challenge, mach_pwd,
158 *r->in.negotiate_flags);
160 if (!creds_server_check(creds, r->in.credentials)) {
162 return NT_STATUS_ACCESS_DENIED;
165 creds->account_name = talloc_steal(creds, r->in.account_name);
167 creds->computer_name = talloc_steal(creds, r->in.computer_name);
168 creds->domain = talloc_strdup(creds, lp_workgroup());
170 creds->secure_channel_type = r->in.secure_channel_type;
172 creds->sid = samdb_result_dom_sid(creds, msgs[0], "objectSid");
175 /* remember this session key state */
176 nt_status = schannel_store_session_key(mem_ctx, creds);
181 static NTSTATUS netr_ServerAuthenticate(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
182 struct netr_ServerAuthenticate *r)
184 struct netr_ServerAuthenticate3 r3;
187 * negotiate_flags is used as an [in] parameter
188 * so it need to be initialised.
190 * (I think ... = 0; seems wrong here --metze)
192 uint32_t negotiate_flags = 0;
194 r3.in.server_name = r->in.server_name;
195 r3.in.account_name = r->in.account_name;
196 r3.in.secure_channel_type = r->in.secure_channel_type;
197 r3.in.computer_name = r->in.computer_name;
198 r3.in.credentials = r->in.credentials;
199 r3.out.credentials = r->out.credentials;
200 r3.in.negotiate_flags = &negotiate_flags;
201 r3.out.negotiate_flags = &negotiate_flags;
204 return netr_ServerAuthenticate3(dce_call, mem_ctx, &r3);
207 static NTSTATUS netr_ServerAuthenticate2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
208 struct netr_ServerAuthenticate2 *r)
210 struct netr_ServerAuthenticate3 r3;
213 r3.in.server_name = r->in.server_name;
214 r3.in.account_name = r->in.account_name;
215 r3.in.secure_channel_type = r->in.secure_channel_type;
216 r3.in.computer_name = r->in.computer_name;
217 r3.in.credentials = r->in.credentials;
218 r3.out.credentials = r->out.credentials;
219 r3.in.negotiate_flags = r->in.negotiate_flags;
220 r3.out.negotiate_flags = r->out.negotiate_flags;
223 return netr_ServerAuthenticate3(dce_call, mem_ctx, &r3);
227 Validate an incoming authenticator against the credentials for the remote machine.
229 The credentials are (re)read and from the schannel database, and
230 written back after the caclulations are performed.
232 The creds_out parameter (if not NULL) returns the credentials, if
233 the caller needs some of that information.
236 static NTSTATUS netr_creds_server_step_check(const char *computer_name,
238 struct netr_Authenticator *received_authenticator,
239 struct netr_Authenticator *return_authenticator,
240 struct creds_CredentialState **creds_out)
242 struct creds_CredentialState *creds;
244 struct ldb_context *ldb;
247 ldb = schannel_db_connect(mem_ctx);
249 return NT_STATUS_ACCESS_DENIED;
252 ret = ldb_transaction_start(ldb);
255 return NT_STATUS_INTERNAL_DB_CORRUPTION;
258 /* Because this is a shared structure (even across
259 * disconnects) we must update the database every time we
260 * update the structure */
262 nt_status = schannel_fetch_session_key_ldb(ldb, ldb, computer_name, lp_workgroup(),
264 if (NT_STATUS_IS_OK(nt_status)) {
265 nt_status = creds_server_step_check(creds,
266 received_authenticator,
267 return_authenticator);
269 if (NT_STATUS_IS_OK(nt_status)) {
270 nt_status = schannel_store_session_key_ldb(ldb, ldb, creds);
273 if (NT_STATUS_IS_OK(nt_status)) {
274 ldb_transaction_commit(ldb);
277 talloc_steal(mem_ctx, creds);
280 ldb_transaction_cancel(ldb);
287 Change the machine account password for the currently connected
288 client. Supplies only the NT#.
291 static NTSTATUS netr_ServerPasswordSet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
292 struct netr_ServerPasswordSet *r)
294 struct creds_CredentialState *creds;
295 struct ldb_context *sam_ctx;
298 nt_status = netr_creds_server_step_check(r->in.computer_name, mem_ctx,
299 &r->in.credential, &r->out.return_authenticator,
301 NT_STATUS_NOT_OK_RETURN(nt_status);
303 sam_ctx = samdb_connect(mem_ctx, system_session(mem_ctx));
304 if (sam_ctx == NULL) {
305 return NT_STATUS_INVALID_SYSTEM_SERVICE;
308 creds_des_decrypt(creds, &r->in.new_password);
310 /* Using the sid for the account as the key, set the password */
311 nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
313 NULL, /* Don't have plaintext */
314 NULL, &r->in.new_password,
315 False, /* This is not considered a password change */
316 False, /* don't restrict this password change (match w2k3) */
322 Change the machine account password for the currently connected
323 client. Supplies new plaintext.
325 static NTSTATUS netr_ServerPasswordSet2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
326 struct netr_ServerPasswordSet2 *r)
328 struct creds_CredentialState *creds;
329 struct ldb_context *sam_ctx;
332 uint32_t new_pass_len;
335 struct samr_CryptPassword password_buf;
337 nt_status = netr_creds_server_step_check(r->in.computer_name, mem_ctx,
338 &r->in.credential, &r->out.return_authenticator,
340 NT_STATUS_NOT_OK_RETURN(nt_status);
342 sam_ctx = samdb_connect(mem_ctx, system_session(mem_ctx));
343 if (sam_ctx == NULL) {
344 return NT_STATUS_INVALID_SYSTEM_SERVICE;
347 memcpy(password_buf.data, r->in.new_password.data, 512);
348 SIVAL(password_buf.data,512,r->in.new_password.length);
349 creds_arcfour_crypt(creds, password_buf.data, 516);
351 ret = decode_pw_buffer(password_buf.data, new_pass, sizeof(new_pass),
352 &new_pass_len, STR_UNICODE);
354 DEBUG(3,("netr_ServerPasswordSet2: failed to decode password buffer\n"));
355 return NT_STATUS_ACCESS_DENIED;
358 /* Using the sid for the account as the key, set the password */
359 nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
361 new_pass, /* we have plaintext */
363 False, /* This is not considered a password change */
364 False, /* don't restrict this password change (match w2k3) */
373 static WERROR netr_LogonUasLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
374 struct netr_LogonUasLogon *r)
376 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
383 static WERROR netr_LogonUasLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
384 struct netr_LogonUasLogoff *r)
386 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
391 netr_LogonSamLogon_base
393 This version of the function allows other wrappers to say 'do not check the credentials'
395 We can't do the traditional 'wrapping' format completly, as this function must only run under schannel
397 static NTSTATUS netr_LogonSamLogon_base(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
398 struct netr_LogonSamLogonEx *r, struct creds_CredentialState *creds)
400 struct auth_context *auth_context;
401 struct auth_usersupplied_info *user_info;
402 struct auth_serversupplied_info *server_info;
404 static const char zeros[16];
405 struct netr_SamBaseInfo *sam;
406 struct netr_SamInfo2 *sam2;
407 struct netr_SamInfo3 *sam3;
408 struct netr_SamInfo6 *sam6;
410 user_info = talloc(mem_ctx, struct auth_usersupplied_info);
411 NT_STATUS_HAVE_NO_MEMORY(user_info);
413 user_info->flags = 0;
414 user_info->mapped_state = False;
415 user_info->remote_host = NULL;
417 switch (r->in.logon_level) {
421 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
422 creds_arcfour_crypt(creds,
423 r->in.logon.password->lmpassword.hash,
424 sizeof(r->in.logon.password->lmpassword.hash));
425 creds_arcfour_crypt(creds,
426 r->in.logon.password->ntpassword.hash,
427 sizeof(r->in.logon.password->ntpassword.hash));
429 creds_des_decrypt(creds, &r->in.logon.password->lmpassword);
430 creds_des_decrypt(creds, &r->in.logon.password->ntpassword);
433 /* TODO: we need to deny anonymous access here */
434 nt_status = auth_context_create(mem_ctx, lp_auth_methods(),
435 dce_call->event_ctx, dce_call->msg_ctx,
437 NT_STATUS_NOT_OK_RETURN(nt_status);
439 user_info->logon_parameters = r->in.logon.password->identity_info.parameter_control;
440 user_info->client.account_name = r->in.logon.password->identity_info.account_name.string;
441 user_info->client.domain_name = r->in.logon.password->identity_info.domain_name.string;
442 user_info->workstation_name = r->in.logon.password->identity_info.workstation.string;
444 user_info->flags |= USER_INFO_INTERACTIVE_LOGON;
445 user_info->password_state = AUTH_PASSWORD_HASH;
447 user_info->password.hash.lanman = talloc(user_info, struct samr_Password);
448 NT_STATUS_HAVE_NO_MEMORY(user_info->password.hash.lanman);
449 *user_info->password.hash.lanman = r->in.logon.password->lmpassword;
451 user_info->password.hash.nt = talloc(user_info, struct samr_Password);
452 NT_STATUS_HAVE_NO_MEMORY(user_info->password.hash.nt);
453 *user_info->password.hash.nt = r->in.logon.password->ntpassword;
459 /* TODO: we need to deny anonymous access here */
460 nt_status = auth_context_create(mem_ctx, lp_auth_methods(),
461 dce_call->event_ctx, dce_call->msg_ctx,
463 NT_STATUS_NOT_OK_RETURN(nt_status);
465 nt_status = auth_context_set_challenge(auth_context, r->in.logon.network->challenge, "netr_LogonSamLogonWithFlags");
466 NT_STATUS_NOT_OK_RETURN(nt_status);
468 user_info->logon_parameters = r->in.logon.network->identity_info.parameter_control;
469 user_info->client.account_name = r->in.logon.network->identity_info.account_name.string;
470 user_info->client.domain_name = r->in.logon.network->identity_info.domain_name.string;
471 user_info->workstation_name = r->in.logon.network->identity_info.workstation.string;
473 user_info->password_state = AUTH_PASSWORD_RESPONSE;
474 user_info->password.response.lanman = data_blob_talloc(mem_ctx, r->in.logon.network->lm.data, r->in.logon.network->lm.length);
475 user_info->password.response.nt = data_blob_talloc(mem_ctx, r->in.logon.network->nt.data, r->in.logon.network->nt.length);
479 return NT_STATUS_INVALID_PARAMETER;
482 nt_status = auth_check_password(auth_context, mem_ctx, user_info, &server_info);
483 NT_STATUS_NOT_OK_RETURN(nt_status);
485 nt_status = auth_convert_server_info_sambaseinfo(mem_ctx, server_info, &sam);
486 NT_STATUS_NOT_OK_RETURN(nt_status);
488 /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
489 /* It appears that level 6 is not individually encrypted */
490 if ((r->in.validation_level != 6) &&
491 memcmp(sam->key.key, zeros, sizeof(sam->key.key)) != 0) {
492 /* This key is sent unencrypted without the ARCFOUR flag set */
493 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
494 creds_arcfour_crypt(creds,
496 sizeof(sam->key.key));
500 /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
501 /* It appears that level 6 is not individually encrypted */
502 if ((r->in.validation_level != 6) &&
503 memcmp(sam->LMSessKey.key, zeros, sizeof(sam->LMSessKey.key)) != 0) {
504 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
505 creds_arcfour_crypt(creds,
507 sizeof(sam->LMSessKey.key));
509 creds_des_encrypt_LMKey(creds,
514 switch (r->in.validation_level) {
516 sam2 = talloc_zero(mem_ctx, struct netr_SamInfo2);
517 NT_STATUS_HAVE_NO_MEMORY(sam2);
519 r->out.validation.sam2 = sam2;
523 sam3 = talloc_zero(mem_ctx, struct netr_SamInfo3);
524 NT_STATUS_HAVE_NO_MEMORY(sam3);
526 r->out.validation.sam3 = sam3;
530 sam6 = talloc_zero(mem_ctx, struct netr_SamInfo6);
531 NT_STATUS_HAVE_NO_MEMORY(sam6);
533 sam6->forest.string = lp_realm();
534 sam6->principle.string = talloc_asprintf(mem_ctx, "%s@%s",
535 sam->account_name.string, sam6->forest.string);
536 NT_STATUS_HAVE_NO_MEMORY(sam6->principle.string);
537 r->out.validation.sam6 = sam6;
544 r->out.authoritative = 1;
546 /* TODO: Describe and deal with these flags */
552 static NTSTATUS netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
553 struct netr_LogonSamLogonEx *r)
556 struct creds_CredentialState *creds;
557 nt_status = schannel_fetch_session_key(mem_ctx, r->in.computer_name, lp_workgroup(), &creds);
558 if (!NT_STATUS_IS_OK(nt_status)) {
562 if (!dce_call->conn->auth_state.auth_info ||
563 dce_call->conn->auth_state.auth_info->auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
564 return NT_STATUS_INTERNAL_ERROR;
566 return netr_LogonSamLogon_base(dce_call, mem_ctx, r, creds);
570 netr_LogonSamLogonWithFlags
573 static NTSTATUS netr_LogonSamLogonWithFlags(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
574 struct netr_LogonSamLogonWithFlags *r)
577 struct creds_CredentialState *creds;
578 struct netr_LogonSamLogonEx r2;
580 struct netr_Authenticator *return_authenticator;
582 return_authenticator = talloc(mem_ctx, struct netr_Authenticator);
583 NT_STATUS_HAVE_NO_MEMORY(return_authenticator);
585 nt_status = netr_creds_server_step_check(r->in.computer_name, mem_ctx,
586 r->in.credential, return_authenticator,
588 NT_STATUS_NOT_OK_RETURN(nt_status);
592 r2.in.server_name = r->in.server_name;
593 r2.in.computer_name = r->in.computer_name;
594 r2.in.logon_level = r->in.logon_level;
595 r2.in.logon = r->in.logon;
596 r2.in.validation_level = r->in.validation_level;
597 r2.in.flags = r->in.flags;
599 nt_status = netr_LogonSamLogon_base(dce_call, mem_ctx, &r2, creds);
601 r->out.return_authenticator = return_authenticator;
602 r->out.validation = r2.out.validation;
603 r->out.authoritative = r2.out.authoritative;
604 r->out.flags = r2.out.flags;
612 static NTSTATUS netr_LogonSamLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
613 struct netr_LogonSamLogon *r)
615 struct netr_LogonSamLogonWithFlags r2;
620 r2.in.server_name = r->in.server_name;
621 r2.in.computer_name = r->in.computer_name;
622 r2.in.credential = r->in.credential;
623 r2.in.return_authenticator = r->in.return_authenticator;
624 r2.in.logon_level = r->in.logon_level;
625 r2.in.logon = r->in.logon;
626 r2.in.validation_level = r->in.validation_level;
629 status = netr_LogonSamLogonWithFlags(dce_call, mem_ctx, &r2);
631 r->out.return_authenticator = r2.out.return_authenticator;
632 r->out.validation = r2.out.validation;
633 r->out.authoritative = r2.out.authoritative;
642 static NTSTATUS netr_LogonSamLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
643 struct netr_LogonSamLogoff *r)
645 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
653 static NTSTATUS netr_DatabaseDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
654 struct netr_DatabaseDeltas *r)
656 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
663 static NTSTATUS netr_DatabaseSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
664 struct netr_DatabaseSync *r)
666 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
673 static NTSTATUS netr_AccountDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
674 struct netr_AccountDeltas *r)
676 /* w2k3 returns "NOT IMPLEMENTED" for this call */
677 return NT_STATUS_NOT_IMPLEMENTED;
684 static NTSTATUS netr_AccountSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
685 struct netr_AccountSync *r)
687 /* w2k3 returns "NOT IMPLEMENTED" for this call */
688 return NT_STATUS_NOT_IMPLEMENTED;
695 static NTSTATUS netr_GetDcName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
696 struct netr_GetDcName *r)
698 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
705 static WERROR netr_LogonControl(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
706 struct netr_LogonControl *r)
708 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
715 static WERROR netr_GetAnyDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
716 struct netr_GetAnyDCName *r)
718 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
725 static WERROR netr_LogonControl2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
726 struct netr_LogonControl2 *r)
728 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
735 static NTSTATUS netr_DatabaseSync2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
736 struct netr_DatabaseSync2 *r)
738 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
745 static NTSTATUS netr_DatabaseRedo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
746 struct netr_DatabaseRedo *r)
748 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
755 static WERROR netr_LogonControl2Ex(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
756 struct netr_LogonControl2Ex *r)
758 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
763 netr_NETRENUMERATETRUSTEDDOMAINS
765 static WERROR netr_NETRENUMERATETRUSTEDDOMAINS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
766 struct netr_NETRENUMERATETRUSTEDDOMAINS *r)
768 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
773 netr_NETRLOGONDUMMYROUTINE1
775 static WERROR netr_NETRLOGONDUMMYROUTINE1(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
776 struct netr_NETRLOGONDUMMYROUTINE1 *r)
778 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
783 netr_NETRLOGONSETSERVICEBITS
785 static WERROR netr_NETRLOGONSETSERVICEBITS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
786 struct netr_NETRLOGONSETSERVICEBITS *r)
788 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
793 netr_NETRLOGONGETTRUSTRID
795 static WERROR netr_NETRLOGONGETTRUSTRID(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
796 struct netr_NETRLOGONGETTRUSTRID *r)
798 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
803 netr_NETRLOGONCOMPUTESERVERDIGEST
805 static WERROR netr_NETRLOGONCOMPUTESERVERDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
806 struct netr_NETRLOGONCOMPUTESERVERDIGEST *r)
808 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
813 netr_NETRLOGONCOMPUTECLIENTDIGEST
815 static WERROR netr_NETRLOGONCOMPUTECLIENTDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
816 struct netr_NETRLOGONCOMPUTECLIENTDIGEST *r)
818 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
826 static WERROR netr_DsRGetSiteName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
827 struct netr_DsRGetSiteName *r)
829 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
834 fill in a netr_DomainTrustInfo from a ldb search result
836 static NTSTATUS fill_domain_trust_info(TALLOC_CTX *mem_ctx,
837 struct ldb_message *res,
838 struct ldb_message *ref_res,
839 struct netr_DomainTrustInfo *info,
845 info->domainname.string = samdb_result_string(ref_res, "nETBIOSName", NULL);
846 info->fulldomainname.string = samdb_result_string(ref_res, "dnsRoot", NULL);
847 info->forest.string = NULL;
848 info->guid = samdb_result_guid(res, "objectGUID");
849 info->sid = samdb_result_dom_sid(mem_ctx, res, "objectSid");
851 info->domainname.string = samdb_result_string(res, "flatName", NULL);
852 info->fulldomainname.string = samdb_result_string(res, "trustPartner", NULL);
853 info->forest.string = NULL;
854 info->guid = samdb_result_guid(res, "objectGUID");
855 info->sid = samdb_result_dom_sid(mem_ctx, res, "securityIdentifier");
862 netr_LogonGetDomainInfo
863 this is called as part of the ADS domain logon procedure.
865 static NTSTATUS netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
866 struct netr_LogonGetDomainInfo *r)
868 const char * const attrs[] = { "objectSid",
869 "objectGUID", "flatName", "securityIdentifier",
870 "trustPartner", NULL };
871 const char * const ref_attrs[] = { "nETBIOSName", "dnsRoot", NULL };
872 struct ldb_context *sam_ctx;
873 struct ldb_message **res1, **res2, **ref_res;
874 struct netr_DomainInfo1 *info1;
875 int ret, ret1, ret2, i;
877 const struct ldb_dn *partitions_basedn;
879 const char *local_domain;
881 status = netr_creds_server_step_check(r->in.computer_name, mem_ctx,
883 r->out.return_authenticator,
885 NT_STATUS_NOT_OK_RETURN(status);
887 sam_ctx = samdb_connect(mem_ctx, dce_call->conn->auth_state.session_info);
888 if (sam_ctx == NULL) {
889 return NT_STATUS_INVALID_SYSTEM_SERVICE;
892 partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);
894 /* we need to do two searches. The first will pull our primary
895 domain and the second will pull any trusted domains. Our
896 primary domain is also a "trusted" domain, so we need to
897 put the primary domain into the lists of returned trusts as
899 ret1 = gendb_search_dn(sam_ctx, mem_ctx, samdb_base_dn(sam_ctx), &res1, attrs);
901 return NT_STATUS_INTERNAL_DB_CORRUPTION;
904 /* try and find the domain */
905 ret = gendb_search(sam_ctx, mem_ctx, partitions_basedn,
907 "(&(objectClass=crossRef)(ncName=%s))",
908 ldb_dn_linearize(mem_ctx, res1[0]->dn));
910 return NT_STATUS_INTERNAL_DB_CORRUPTION;
913 local_domain = samdb_result_string(ref_res[0], "nETBIOSName", NULL);
915 ret2 = gendb_search(sam_ctx, mem_ctx, NULL, &res2, attrs, "(objectClass=trustedDomain)");
917 return NT_STATUS_INTERNAL_DB_CORRUPTION;
920 info1 = talloc(mem_ctx, struct netr_DomainInfo1);
921 NT_STATUS_HAVE_NO_MEMORY(info1);
925 info1->num_trusts = ret2 + 1;
926 info1->trusts = talloc_array(mem_ctx, struct netr_DomainTrustInfo,
928 NT_STATUS_HAVE_NO_MEMORY(info1->trusts);
930 status = fill_domain_trust_info(mem_ctx, res1[0], ref_res[0], &info1->domaininfo, True);
931 NT_STATUS_NOT_OK_RETURN(status);
933 for (i=0;i<ret2;i++) {
934 status = fill_domain_trust_info(mem_ctx, res2[i], NULL, &info1->trusts[i], False);
935 NT_STATUS_NOT_OK_RETURN(status);
938 status = fill_domain_trust_info(mem_ctx, res1[0], ref_res[0], &info1->trusts[i], True);
939 NT_STATUS_NOT_OK_RETURN(status);
941 r->out.info.info1 = info1;
949 netr_NETRSERVERPASSWORDGET
951 static WERROR netr_NETRSERVERPASSWORDGET(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
952 struct netr_NETRSERVERPASSWORDGET *r)
954 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
959 netr_NETRLOGONSENDTOSAM
961 static WERROR netr_NETRLOGONSENDTOSAM(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
962 struct netr_NETRLOGONSENDTOSAM *r)
964 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
969 netr_DSRADDRESSTOSITENAMESW
971 static WERROR netr_DSRADDRESSTOSITENAMESW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
972 struct netr_DSRADDRESSTOSITENAMESW *r)
974 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
981 static WERROR netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
982 struct netr_DsRGetDCNameEx2 *r)
984 const char * const attrs[] = { "dnsDomain", "objectGUID", NULL };
986 struct ldb_message **res;
991 sam_ctx = samdb_connect(mem_ctx, dce_call->conn->auth_state.session_info);
992 if (sam_ctx == NULL) {
993 return WERR_DS_SERVICE_UNAVAILABLE;
996 ret = gendb_search(sam_ctx, mem_ctx, NULL, &res, attrs,
997 "(&(objectClass=domainDNS)(dnsDomain=%s))",
1000 return WERR_NO_SUCH_DOMAIN;
1003 r->out.info = talloc(mem_ctx, struct netr_DsRGetDCNameInfo);
1004 W_ERROR_HAVE_NO_MEMORY(r->out.info);
1006 /* TODO: - return real IP address
1007 * - check all r->in.* parameters (server_unc is ignored by w2k3!)
1009 r->out.info->dc_unc = talloc_asprintf(mem_ctx, "\\\\%s.%s", lp_netbios_name(),lp_realm());
1010 W_ERROR_HAVE_NO_MEMORY(r->out.info->dc_unc);
1011 r->out.info->dc_address = talloc_strdup(mem_ctx, "\\\\0.0.0.0");
1012 W_ERROR_HAVE_NO_MEMORY(r->out.info->dc_address);
1013 r->out.info->dc_address_type = 1;
1014 r->out.info->domain_guid = samdb_result_guid(res[0], "objectGUID");
1015 r->out.info->domain_name = samdb_result_string(res[0], "dnsDomain", NULL);
1016 r->out.info->forest_name = samdb_result_string(res[0], "dnsDomain", NULL);
1017 r->out.info->dc_flags = 0xE00001FD;
1018 r->out.info->dc_site_name = talloc_strdup(mem_ctx, "Default-First-Site-Name");
1019 W_ERROR_HAVE_NO_MEMORY(r->out.info->dc_site_name);
1020 r->out.info->client_site_name = talloc_strdup(mem_ctx, "Default-First-Site-Name");
1021 W_ERROR_HAVE_NO_MEMORY(r->out.info->client_site_name);
1029 static WERROR netr_DsRGetDCNameEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1030 struct netr_DsRGetDCNameEx *r)
1032 struct netr_DsRGetDCNameEx2 r2;
1037 r2.in.server_unc = r->in.server_unc;
1038 r2.in.client_account = NULL;
1040 r2.in.domain_guid = r->in.domain_guid;
1041 r2.in.domain_name = r->in.domain_name;
1042 r2.in.site_name = r->in.site_name;
1043 r2.in.flags = r->in.flags;
1046 werr = netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1048 r->out.info = r2.out.info;
1056 static WERROR netr_DsRGetDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1057 struct netr_DsRGetDCName *r)
1059 struct netr_DsRGetDCNameEx2 r2;
1064 r2.in.server_unc = r->in.server_unc;
1065 r2.in.client_account = NULL;
1067 r2.in.domain_name = r->in.domain_name;
1068 r2.in.domain_guid = r->in.domain_guid;
1070 r2.in.site_name = NULL; /* should fill in from site GUID */
1071 r2.in.flags = r->in.flags;
1074 werr = netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1076 r->out.info = r2.out.info;
1082 netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN
1084 static WERROR netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1085 struct netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN *r)
1087 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1092 netr_NETRENUMERATETRUSTEDDOMAINSEX
1094 static WERROR netr_NETRENUMERATETRUSTEDDOMAINSEX(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1095 struct netr_NETRENUMERATETRUSTEDDOMAINSEX *r)
1097 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1102 netr_DSRADDRESSTOSITENAMESEXW
1104 static WERROR netr_DSRADDRESSTOSITENAMESEXW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1105 struct netr_DSRADDRESSTOSITENAMESEXW *r)
1107 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1112 netr_DSRGETDCSITECOVERAGEW
1114 static WERROR netr_DSRGETDCSITECOVERAGEW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1115 struct netr_DSRGETDCSITECOVERAGEW *r)
1117 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1122 netr_DsrEnumerateDomainTrusts
1124 static WERROR netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1125 struct netr_DsrEnumerateDomainTrusts *r)
1127 struct netr_DomainTrust *trusts;
1130 struct ldb_message **dom_res, **ref_res;
1131 const char * const dom_attrs[] = { "objectSid", "objectGUID", NULL };
1132 const char * const ref_attrs[] = { "nETBIOSName", "dnsRoot", NULL };
1133 const struct ldb_dn *partitions_basedn;
1135 ZERO_STRUCT(r->out);
1137 sam_ctx = samdb_connect(mem_ctx, dce_call->conn->auth_state.session_info);
1138 if (sam_ctx == NULL) {
1139 return WERR_GENERAL_FAILURE;
1142 partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);
1144 ret = gendb_search_dn(sam_ctx, mem_ctx, NULL, &dom_res, dom_attrs);
1146 return WERR_GENERAL_FAILURE;
1149 return WERR_GENERAL_FAILURE;
1152 ret = gendb_search(sam_ctx, mem_ctx, partitions_basedn, &ref_res, ref_attrs,
1153 "(&(objectClass=crossRef)(ncName=%s))",
1154 ldb_dn_linearize(mem_ctx, dom_res[0]->dn));
1156 return WERR_GENERAL_FAILURE;
1159 return WERR_GENERAL_FAILURE;
1162 trusts = talloc_array(mem_ctx, struct netr_DomainTrust, ret);
1163 W_ERROR_HAVE_NO_MEMORY(trusts);
1166 r->out.trusts = trusts;
1168 /* TODO: add filtering by trust_flags, and correct trust_type
1170 trusts[0].netbios_name = samdb_result_string(ref_res[0], "nETBIOSName", NULL);
1171 trusts[0].dns_name = samdb_result_string(ref_res[0], "dnsRoot", NULL);
1172 trusts[0].trust_flags =
1173 NETR_TRUST_FLAG_TREEROOT |
1174 NETR_TRUST_FLAG_IN_FOREST |
1175 NETR_TRUST_FLAG_PRIMARY;
1176 trusts[0].parent_index = 0;
1177 trusts[0].trust_type = 2;
1178 trusts[0].trust_attributes = 0;
1179 trusts[0].sid = samdb_result_dom_sid(mem_ctx, dom_res[0], "objectSid");
1180 trusts[0].guid = samdb_result_guid(dom_res[0], "objectGUID");
1187 netr_DSRDEREGISTERDNSHOSTRECORDS
1189 static WERROR netr_DSRDEREGISTERDNSHOSTRECORDS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1190 struct netr_DSRDEREGISTERDNSHOSTRECORDS *r)
1192 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1197 netr_NETRSERVERTRUSTPASSWORDSGET
1199 static WERROR netr_NETRSERVERTRUSTPASSWORDSGET(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1200 struct netr_NETRSERVERTRUSTPASSWORDSGET *r)
1202 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1207 netr_DSRGETFORESTTRUSTINFORMATION
1209 static WERROR netr_DSRGETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1210 struct netr_DSRGETFORESTTRUSTINFORMATION *r)
1212 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1217 netr_NETRGETFORESTTRUSTINFORMATION
1219 static WERROR netr_NETRGETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1220 struct netr_NETRGETFORESTTRUSTINFORMATION *r)
1222 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1227 netr_NETRSERVERGETTRUSTINFO
1229 static WERROR netr_NETRSERVERGETTRUSTINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1230 struct netr_NETRSERVERGETTRUSTINFO *r)
1232 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1236 /* include the generated boilerplate */
1237 #include "librpc/gen_ndr/ndr_netlogon_s.c"