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 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
683 static NTSTATUS netr_AccountSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
684 struct netr_AccountSync *r)
686 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
693 static NTSTATUS netr_GetDcName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
694 struct netr_GetDcName *r)
696 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
703 static WERROR netr_LogonControl(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
704 struct netr_LogonControl *r)
706 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
713 static WERROR netr_GetAnyDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
714 struct netr_GetAnyDCName *r)
716 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
723 static WERROR netr_LogonControl2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
724 struct netr_LogonControl2 *r)
726 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
733 static NTSTATUS netr_DatabaseSync2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
734 struct netr_DatabaseSync2 *r)
736 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
743 static NTSTATUS netr_DatabaseRedo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
744 struct netr_DatabaseRedo *r)
746 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
753 static WERROR netr_LogonControl2Ex(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
754 struct netr_LogonControl2Ex *r)
756 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
761 netr_NETRENUMERATETRUSTEDDOMAINS
763 static WERROR netr_NETRENUMERATETRUSTEDDOMAINS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
764 struct netr_NETRENUMERATETRUSTEDDOMAINS *r)
766 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
771 netr_NETRLOGONDUMMYROUTINE1
773 static WERROR netr_NETRLOGONDUMMYROUTINE1(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
774 struct netr_NETRLOGONDUMMYROUTINE1 *r)
776 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
781 netr_NETRLOGONSETSERVICEBITS
783 static WERROR netr_NETRLOGONSETSERVICEBITS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
784 struct netr_NETRLOGONSETSERVICEBITS *r)
786 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
791 netr_NETRLOGONGETTRUSTRID
793 static WERROR netr_NETRLOGONGETTRUSTRID(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
794 struct netr_NETRLOGONGETTRUSTRID *r)
796 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
801 netr_NETRLOGONCOMPUTESERVERDIGEST
803 static WERROR netr_NETRLOGONCOMPUTESERVERDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
804 struct netr_NETRLOGONCOMPUTESERVERDIGEST *r)
806 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
811 netr_NETRLOGONCOMPUTECLIENTDIGEST
813 static WERROR netr_NETRLOGONCOMPUTECLIENTDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
814 struct netr_NETRLOGONCOMPUTECLIENTDIGEST *r)
816 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
824 static WERROR netr_DsRGetSiteName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
825 struct netr_DsRGetSiteName *r)
827 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
832 fill in a netr_DomainTrustInfo from a ldb search result
834 static NTSTATUS fill_domain_primary_info(TALLOC_CTX *mem_ctx, struct ldb_message *res,
835 struct netr_DomainTrustInfo *info,
836 const char *local_domain)
840 info->domainname.string = local_domain;
841 info->fulldomainname.string = talloc_asprintf(info, "%s.", samdb_result_string(res, "dnsDomain", NULL));
842 /* TODO: we need proper forest support */
843 info->forest.string = info->fulldomainname.string;
844 info->guid = samdb_result_guid(res, "objectGUID");
845 info->sid = samdb_result_dom_sid(mem_ctx, res, "objectSid");
851 fill in a netr_DomainTrustInfo from a ldb search result
853 static NTSTATUS fill_domain_trust_info(TALLOC_CTX *mem_ctx, struct ldb_message *res,
854 struct netr_DomainTrustInfo *info,
855 const char *local_domain, BOOL is_local)
860 info->domainname.string = local_domain;
861 info->fulldomainname.string = samdb_result_string(res, "dnsDomain", NULL);
862 info->forest.string = NULL;
863 info->guid = samdb_result_guid(res, "objectGUID");
864 info->sid = samdb_result_dom_sid(mem_ctx, res, "objectSid");
866 info->domainname.string = samdb_result_string(res, "flatName", NULL);
867 info->fulldomainname.string = samdb_result_string(res, "name", NULL);
868 info->forest.string = NULL;
869 info->guid = samdb_result_guid(res, "objectGUID");
870 info->sid = samdb_result_dom_sid(mem_ctx, res, "securityIdentifier");
877 netr_LogonGetDomainInfo
878 this is called as part of the ADS domain logon procedure.
880 static NTSTATUS netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
881 struct netr_LogonGetDomainInfo *r)
883 const char * const attrs[] = { "dnsDomain", "objectSid",
884 "objectGUID", "flatName", "securityIdentifier",
886 const char * const ref_attrs[] = { "nETBIOSName", NULL };
887 struct ldb_context *sam_ctx;
888 struct ldb_message **res1, **res2, **ref_res;
889 struct netr_DomainInfo1 *info1;
890 int ret, ret1, ret2, i;
892 const struct ldb_dn *partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);
894 const char *local_domain;
896 status = netr_creds_server_step_check(r->in.computer_name, mem_ctx,
898 r->out.return_authenticator,
900 NT_STATUS_NOT_OK_RETURN(status);
902 sam_ctx = samdb_connect(mem_ctx, dce_call->conn->auth_state.session_info);
903 if (sam_ctx == NULL) {
904 return NT_STATUS_INVALID_SYSTEM_SERVICE;
907 /* we need to do two searches. The first will pull our primary
908 domain and the second will pull any trusted domains. Our
909 primary domain is also a "trusted" domain, so we need to
910 put the primary domain into the lists of returned trusts as
912 ret1 = gendb_search(sam_ctx, mem_ctx, NULL, &res1, attrs, "(objectClass=domainDNS)");
914 return NT_STATUS_INTERNAL_DB_CORRUPTION;
917 /* try and find the domain */
918 ret = gendb_search(sam_ctx, mem_ctx, partitions_basedn,
920 "(&(objectClass=crossRef)(ncName=%s))",
921 ldb_dn_linearize(mem_ctx, res1[0]->dn));
923 return NT_STATUS_INTERNAL_DB_CORRUPTION;
926 local_domain = samdb_result_string(ref_res[0], "nETBIOSName", NULL);
928 ret2 = gendb_search(sam_ctx, mem_ctx, NULL, &res2, attrs, "(objectClass=trustedDomain)");
930 return NT_STATUS_INTERNAL_DB_CORRUPTION;
933 info1 = talloc(mem_ctx, struct netr_DomainInfo1);
934 NT_STATUS_HAVE_NO_MEMORY(info1);
938 info1->num_trusts = ret2 + 1;
939 info1->trusts = talloc_array(mem_ctx, struct netr_DomainTrustInfo,
941 NT_STATUS_HAVE_NO_MEMORY(info1->trusts);
943 status = fill_domain_primary_info(mem_ctx, res1[0], &info1->domaininfo, local_domain);
944 NT_STATUS_NOT_OK_RETURN(status);
946 for (i=0;i<ret2;i++) {
947 status = fill_domain_trust_info(mem_ctx, res2[i], &info1->trusts[i], NULL, False);
948 NT_STATUS_NOT_OK_RETURN(status);
951 status = fill_domain_trust_info(mem_ctx, res1[0], &info1->trusts[i], local_domain, True);
952 NT_STATUS_NOT_OK_RETURN(status);
954 r->out.info.info1 = info1;
962 netr_NETRSERVERPASSWORDGET
964 static WERROR netr_NETRSERVERPASSWORDGET(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
965 struct netr_NETRSERVERPASSWORDGET *r)
967 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
972 netr_NETRLOGONSENDTOSAM
974 static WERROR netr_NETRLOGONSENDTOSAM(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
975 struct netr_NETRLOGONSENDTOSAM *r)
977 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
982 netr_DSRADDRESSTOSITENAMESW
984 static WERROR netr_DSRADDRESSTOSITENAMESW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
985 struct netr_DSRADDRESSTOSITENAMESW *r)
987 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
994 static WERROR netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
995 struct netr_DsRGetDCNameEx2 *r)
997 const char * const attrs[] = { "dnsDomain", "objectGUID", NULL };
999 struct ldb_message **res;
1002 ZERO_STRUCT(r->out);
1004 sam_ctx = samdb_connect(mem_ctx, dce_call->conn->auth_state.session_info);
1005 if (sam_ctx == NULL) {
1006 return WERR_DS_SERVICE_UNAVAILABLE;
1009 ret = gendb_search(sam_ctx, mem_ctx, NULL, &res, attrs,
1010 "(&(objectClass=domainDNS)(dnsDomain=%s))",
1013 return WERR_NO_SUCH_DOMAIN;
1016 r->out.info = talloc(mem_ctx, struct netr_DsRGetDCNameInfo);
1017 W_ERROR_HAVE_NO_MEMORY(r->out.info);
1019 /* TODO: - return real IP address
1020 * - check all r->in.* parameters (server_unc is ignored by w2k3!)
1022 r->out.info->dc_unc = talloc_asprintf(mem_ctx, "\\\\%s.%s", lp_netbios_name(),lp_realm());
1023 W_ERROR_HAVE_NO_MEMORY(r->out.info->dc_unc);
1024 r->out.info->dc_address = talloc_strdup(mem_ctx, "\\\\0.0.0.0");
1025 W_ERROR_HAVE_NO_MEMORY(r->out.info->dc_address);
1026 r->out.info->dc_address_type = 1;
1027 r->out.info->domain_guid = samdb_result_guid(res[0], "objectGUID");
1028 r->out.info->domain_name = samdb_result_string(res[0], "dnsDomain", NULL);
1029 r->out.info->forest_name = samdb_result_string(res[0], "dnsDomain", NULL);
1030 r->out.info->dc_flags = 0xE00001FD;
1031 r->out.info->dc_site_name = talloc_strdup(mem_ctx, "Default-First-Site-Name");
1032 W_ERROR_HAVE_NO_MEMORY(r->out.info->dc_site_name);
1033 r->out.info->client_site_name = talloc_strdup(mem_ctx, "Default-First-Site-Name");
1034 W_ERROR_HAVE_NO_MEMORY(r->out.info->client_site_name);
1042 static WERROR netr_DsRGetDCNameEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1043 struct netr_DsRGetDCNameEx *r)
1045 struct netr_DsRGetDCNameEx2 r2;
1050 r2.in.server_unc = r->in.server_unc;
1051 r2.in.client_account = NULL;
1053 r2.in.domain_guid = r->in.domain_guid;
1054 r2.in.domain_name = r->in.domain_name;
1055 r2.in.site_name = r->in.site_name;
1056 r2.in.flags = r->in.flags;
1059 werr = netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1061 r->out.info = r2.out.info;
1069 static WERROR netr_DsRGetDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1070 struct netr_DsRGetDCName *r)
1072 struct netr_DsRGetDCNameEx2 r2;
1077 r2.in.server_unc = r->in.server_unc;
1078 r2.in.client_account = NULL;
1080 r2.in.domain_name = r->in.domain_name;
1081 r2.in.domain_guid = r->in.domain_guid;
1083 r2.in.site_name = NULL; /* should fill in from site GUID */
1084 r2.in.flags = r->in.flags;
1087 werr = netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1089 r->out.info = r2.out.info;
1095 netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN
1097 static WERROR netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1098 struct netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN *r)
1100 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1105 netr_NETRENUMERATETRUSTEDDOMAINSEX
1107 static WERROR netr_NETRENUMERATETRUSTEDDOMAINSEX(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1108 struct netr_NETRENUMERATETRUSTEDDOMAINSEX *r)
1110 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1115 netr_DSRADDRESSTOSITENAMESEXW
1117 static WERROR netr_DSRADDRESSTOSITENAMESEXW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1118 struct netr_DSRADDRESSTOSITENAMESEXW *r)
1120 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1125 netr_DSRGETDCSITECOVERAGEW
1127 static WERROR netr_DSRGETDCSITECOVERAGEW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1128 struct netr_DSRGETDCSITECOVERAGEW *r)
1130 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1135 netr_DsrEnumerateDomainTrusts
1137 static WERROR netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1138 struct netr_DsrEnumerateDomainTrusts *r)
1140 struct netr_DomainTrust *trusts;
1143 struct ldb_message **dom_res, **ref_res;
1144 const char * const dom_attrs[] = { "dnsDomain", "objectSid", "objectGUID", NULL };
1145 const char * const ref_attrs[] = { "nETBIOSName", NULL };
1146 const struct ldb_dn *partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);
1148 ZERO_STRUCT(r->out);
1150 sam_ctx = samdb_connect(mem_ctx, dce_call->conn->auth_state.session_info);
1151 if (sam_ctx == NULL) {
1152 return WERR_GENERAL_FAILURE;
1155 ret = gendb_search_dn(sam_ctx, mem_ctx, NULL, &dom_res, dom_attrs);
1157 return WERR_GENERAL_FAILURE;
1160 return WERR_GENERAL_FAILURE;
1163 ret = gendb_search(sam_ctx, mem_ctx, partitions_basedn, &ref_res, ref_attrs,
1164 "(&(objectClass=crossRef)(ncName=%s))",
1165 ldb_dn_linearize(mem_ctx, dom_res[0]->dn));
1167 return WERR_GENERAL_FAILURE;
1170 return WERR_GENERAL_FAILURE;
1173 trusts = talloc_array(mem_ctx, struct netr_DomainTrust, ret);
1174 W_ERROR_HAVE_NO_MEMORY(trusts);
1177 r->out.trusts = trusts;
1179 /* TODO: add filtering by trust_flags, and correct trust_type
1181 trusts[0].netbios_name = samdb_result_string(ref_res[0], "nETBIOSName", NULL);
1182 trusts[0].dns_name = samdb_result_string(dom_res[0], "dnsDomain", NULL);
1183 trusts[0].trust_flags =
1184 NETR_TRUST_FLAG_TREEROOT |
1185 NETR_TRUST_FLAG_IN_FOREST |
1186 NETR_TRUST_FLAG_PRIMARY;
1187 trusts[0].parent_index = 0;
1188 trusts[0].trust_type = 2;
1189 trusts[0].trust_attributes = 0;
1190 trusts[0].sid = samdb_result_dom_sid(mem_ctx, dom_res[0], "objectSid");
1191 trusts[0].guid = samdb_result_guid(dom_res[0], "objectGUID");
1198 netr_DSRDEREGISTERDNSHOSTRECORDS
1200 static WERROR netr_DSRDEREGISTERDNSHOSTRECORDS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1201 struct netr_DSRDEREGISTERDNSHOSTRECORDS *r)
1203 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1208 netr_NETRSERVERTRUSTPASSWORDSGET
1210 static WERROR netr_NETRSERVERTRUSTPASSWORDSGET(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1211 struct netr_NETRSERVERTRUSTPASSWORDSGET *r)
1213 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1218 netr_DSRGETFORESTTRUSTINFORMATION
1220 static WERROR netr_DSRGETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1221 struct netr_DSRGETFORESTTRUSTINFORMATION *r)
1223 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1228 netr_NETRGETFORESTTRUSTINFORMATION
1230 static WERROR netr_NETRGETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1231 struct netr_NETRGETFORESTTRUSTINFORMATION *r)
1233 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1238 netr_NETRSERVERGETTRUSTINFO
1240 static WERROR netr_NETRSERVERGETTRUSTINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1241 struct netr_NETRSERVERGETTRUSTINFO *r)
1243 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1247 /* include the generated boilerplate */
1248 #include "librpc/gen_ndr/ndr_netlogon_s.c"