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 3 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, see <http://www.gnu.org/licenses/>.
24 #include "rpc_server/dcerpc_server.h"
25 #include "rpc_server/common/common.h"
26 #include "lib/ldb/include/ldb.h"
27 #include "auth/auth.h"
28 #include "auth/auth_sam.h"
29 #include "dsdb/samdb/samdb.h"
30 #include "rpc_server/samr/proto.h"
31 #include "util/util_ldb.h"
32 #include "libcli/auth/libcli_auth.h"
33 #include "auth/gensec/schannel_state.h"
34 #include "libcli/security/security.h"
35 #include "param/param.h"
37 struct server_pipe_state {
38 struct netr_Credential client_challenge;
39 struct netr_Credential server_challenge;
43 static NTSTATUS dcesrv_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 dcesrv_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[] = {"unicodePwd", "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], "unicodePwd");
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(global_loadparm));
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 dcesrv_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 dcesrv_netr_ServerAuthenticate3(dce_call, mem_ctx, &r3);
207 static NTSTATUS dcesrv_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 dcesrv_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 dcesrv_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,
263 lp_workgroup(global_loadparm),
265 if (NT_STATUS_IS_OK(nt_status)) {
266 nt_status = creds_server_step_check(creds,
267 received_authenticator,
268 return_authenticator);
270 if (NT_STATUS_IS_OK(nt_status)) {
271 nt_status = schannel_store_session_key_ldb(ldb, ldb, creds);
274 if (NT_STATUS_IS_OK(nt_status)) {
275 ldb_transaction_commit(ldb);
278 talloc_steal(mem_ctx, creds);
281 ldb_transaction_cancel(ldb);
288 Change the machine account password for the currently connected
289 client. Supplies only the NT#.
292 static NTSTATUS dcesrv_netr_ServerPasswordSet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
293 struct netr_ServerPasswordSet *r)
295 struct creds_CredentialState *creds;
296 struct ldb_context *sam_ctx;
299 nt_status = dcesrv_netr_creds_server_step_check(r->in.computer_name, mem_ctx,
300 &r->in.credential, &r->out.return_authenticator,
302 NT_STATUS_NOT_OK_RETURN(nt_status);
304 sam_ctx = samdb_connect(mem_ctx, system_session(mem_ctx));
305 if (sam_ctx == NULL) {
306 return NT_STATUS_INVALID_SYSTEM_SERVICE;
309 creds_des_decrypt(creds, &r->in.new_password);
311 /* Using the sid for the account as the key, set the password */
312 nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
314 NULL, /* Don't have plaintext */
315 NULL, &r->in.new_password,
316 false, /* This is not considered a password change */
322 Change the machine account password for the currently connected
323 client. Supplies new plaintext.
325 static NTSTATUS dcesrv_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 = dcesrv_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 */
372 static WERROR dcesrv_netr_LogonUasLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
373 struct netr_LogonUasLogon *r)
375 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
382 static WERROR dcesrv_netr_LogonUasLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
383 struct netr_LogonUasLogoff *r)
385 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
390 netr_LogonSamLogon_base
392 This version of the function allows other wrappers to say 'do not check the credentials'
394 We can't do the traditional 'wrapping' format completly, as this function must only run under schannel
396 static NTSTATUS dcesrv_netr_LogonSamLogon_base(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
397 struct netr_LogonSamLogonEx *r, struct creds_CredentialState *creds)
399 struct auth_context *auth_context;
400 struct auth_usersupplied_info *user_info;
401 struct auth_serversupplied_info *server_info;
403 static const char zeros[16];
404 struct netr_SamBaseInfo *sam;
405 struct netr_SamInfo2 *sam2;
406 struct netr_SamInfo3 *sam3;
407 struct netr_SamInfo6 *sam6;
409 user_info = talloc(mem_ctx, struct auth_usersupplied_info);
410 NT_STATUS_HAVE_NO_MEMORY(user_info);
412 user_info->flags = 0;
413 user_info->mapped_state = false;
414 user_info->remote_host = NULL;
416 switch (r->in.logon_level) {
420 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
421 creds_arcfour_crypt(creds,
422 r->in.logon.password->lmpassword.hash,
423 sizeof(r->in.logon.password->lmpassword.hash));
424 creds_arcfour_crypt(creds,
425 r->in.logon.password->ntpassword.hash,
426 sizeof(r->in.logon.password->ntpassword.hash));
428 creds_des_decrypt(creds, &r->in.logon.password->lmpassword);
429 creds_des_decrypt(creds, &r->in.logon.password->ntpassword);
432 /* TODO: we need to deny anonymous access here */
433 nt_status = auth_context_create(mem_ctx,
434 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,
461 dce_call->event_ctx, dce_call->msg_ctx,
464 NT_STATUS_NOT_OK_RETURN(nt_status);
466 nt_status = auth_context_set_challenge(auth_context, r->in.logon.network->challenge, "netr_LogonSamLogonWithFlags");
467 NT_STATUS_NOT_OK_RETURN(nt_status);
469 user_info->logon_parameters = r->in.logon.network->identity_info.parameter_control;
470 user_info->client.account_name = r->in.logon.network->identity_info.account_name.string;
471 user_info->client.domain_name = r->in.logon.network->identity_info.domain_name.string;
472 user_info->workstation_name = r->in.logon.network->identity_info.workstation.string;
474 user_info->password_state = AUTH_PASSWORD_RESPONSE;
475 user_info->password.response.lanman = data_blob_talloc(mem_ctx, r->in.logon.network->lm.data, r->in.logon.network->lm.length);
476 user_info->password.response.nt = data_blob_talloc(mem_ctx, r->in.logon.network->nt.data, r->in.logon.network->nt.length);
480 return NT_STATUS_INVALID_PARAMETER;
483 nt_status = auth_check_password(auth_context, mem_ctx, user_info, &server_info);
484 NT_STATUS_NOT_OK_RETURN(nt_status);
486 nt_status = auth_convert_server_info_sambaseinfo(mem_ctx, server_info, &sam);
487 NT_STATUS_NOT_OK_RETURN(nt_status);
489 /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
490 /* It appears that level 6 is not individually encrypted */
491 if ((r->in.validation_level != 6) &&
492 memcmp(sam->key.key, zeros, sizeof(sam->key.key)) != 0) {
493 /* This key is sent unencrypted without the ARCFOUR flag set */
494 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
495 creds_arcfour_crypt(creds,
497 sizeof(sam->key.key));
501 /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
502 /* It appears that level 6 is not individually encrypted */
503 if ((r->in.validation_level != 6) &&
504 memcmp(sam->LMSessKey.key, zeros, sizeof(sam->LMSessKey.key)) != 0) {
505 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
506 creds_arcfour_crypt(creds,
508 sizeof(sam->LMSessKey.key));
510 creds_des_encrypt_LMKey(creds,
515 switch (r->in.validation_level) {
517 sam2 = talloc_zero(mem_ctx, struct netr_SamInfo2);
518 NT_STATUS_HAVE_NO_MEMORY(sam2);
520 r->out.validation.sam2 = sam2;
524 sam3 = talloc_zero(mem_ctx, struct netr_SamInfo3);
525 NT_STATUS_HAVE_NO_MEMORY(sam3);
527 r->out.validation.sam3 = sam3;
531 sam6 = talloc_zero(mem_ctx, struct netr_SamInfo6);
532 NT_STATUS_HAVE_NO_MEMORY(sam6);
534 sam6->forest.string = lp_realm(global_loadparm);
535 sam6->principle.string = talloc_asprintf(mem_ctx, "%s@%s",
536 sam->account_name.string, sam6->forest.string);
537 NT_STATUS_HAVE_NO_MEMORY(sam6->principle.string);
538 r->out.validation.sam6 = sam6;
545 r->out.authoritative = 1;
547 /* TODO: Describe and deal with these flags */
553 static NTSTATUS dcesrv_netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
554 struct netr_LogonSamLogonEx *r)
557 struct creds_CredentialState *creds;
558 nt_status = schannel_fetch_session_key(mem_ctx, r->in.computer_name, lp_workgroup(global_loadparm), &creds);
559 if (!NT_STATUS_IS_OK(nt_status)) {
563 if (!dce_call->conn->auth_state.auth_info ||
564 dce_call->conn->auth_state.auth_info->auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
565 return NT_STATUS_INTERNAL_ERROR;
567 return dcesrv_netr_LogonSamLogon_base(dce_call, mem_ctx, r, creds);
571 netr_LogonSamLogonWithFlags
574 static NTSTATUS dcesrv_netr_LogonSamLogonWithFlags(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
575 struct netr_LogonSamLogonWithFlags *r)
578 struct creds_CredentialState *creds;
579 struct netr_LogonSamLogonEx r2;
581 struct netr_Authenticator *return_authenticator;
583 return_authenticator = talloc(mem_ctx, struct netr_Authenticator);
584 NT_STATUS_HAVE_NO_MEMORY(return_authenticator);
586 nt_status = dcesrv_netr_creds_server_step_check(r->in.computer_name, mem_ctx,
587 r->in.credential, return_authenticator,
589 NT_STATUS_NOT_OK_RETURN(nt_status);
593 r2.in.server_name = r->in.server_name;
594 r2.in.computer_name = r->in.computer_name;
595 r2.in.logon_level = r->in.logon_level;
596 r2.in.logon = r->in.logon;
597 r2.in.validation_level = r->in.validation_level;
598 r2.in.flags = r->in.flags;
600 nt_status = dcesrv_netr_LogonSamLogon_base(dce_call, mem_ctx, &r2, creds);
602 r->out.return_authenticator = return_authenticator;
603 r->out.validation = r2.out.validation;
604 r->out.authoritative = r2.out.authoritative;
605 r->out.flags = r2.out.flags;
613 static NTSTATUS dcesrv_netr_LogonSamLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
614 struct netr_LogonSamLogon *r)
616 struct netr_LogonSamLogonWithFlags r2;
621 r2.in.server_name = r->in.server_name;
622 r2.in.computer_name = r->in.computer_name;
623 r2.in.credential = r->in.credential;
624 r2.in.return_authenticator = r->in.return_authenticator;
625 r2.in.logon_level = r->in.logon_level;
626 r2.in.logon = r->in.logon;
627 r2.in.validation_level = r->in.validation_level;
630 status = dcesrv_netr_LogonSamLogonWithFlags(dce_call, mem_ctx, &r2);
632 r->out.return_authenticator = r2.out.return_authenticator;
633 r->out.validation = r2.out.validation;
634 r->out.authoritative = r2.out.authoritative;
643 static NTSTATUS dcesrv_netr_LogonSamLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
644 struct netr_LogonSamLogoff *r)
646 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
654 static NTSTATUS dcesrv_netr_DatabaseDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
655 struct netr_DatabaseDeltas *r)
657 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
664 static NTSTATUS dcesrv_netr_DatabaseSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
665 struct netr_DatabaseSync *r)
667 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
674 static NTSTATUS dcesrv_netr_AccountDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
675 struct netr_AccountDeltas *r)
677 /* w2k3 returns "NOT IMPLEMENTED" for this call */
678 return NT_STATUS_NOT_IMPLEMENTED;
685 static NTSTATUS dcesrv_netr_AccountSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
686 struct netr_AccountSync *r)
688 /* w2k3 returns "NOT IMPLEMENTED" for this call */
689 return NT_STATUS_NOT_IMPLEMENTED;
696 static WERROR dcesrv_netr_GetDcName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
697 struct netr_GetDcName *r)
699 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
706 static WERROR dcesrv_netr_LogonControl(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
707 struct netr_LogonControl *r)
709 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
716 static WERROR dcesrv_netr_GetAnyDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
717 struct netr_GetAnyDCName *r)
719 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
726 static WERROR dcesrv_netr_LogonControl2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
727 struct netr_LogonControl2 *r)
729 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
736 static NTSTATUS dcesrv_netr_DatabaseSync2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
737 struct netr_DatabaseSync2 *r)
739 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
746 static NTSTATUS dcesrv_netr_DatabaseRedo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
747 struct netr_DatabaseRedo *r)
749 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
756 static WERROR dcesrv_netr_LogonControl2Ex(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
757 struct netr_LogonControl2Ex *r)
759 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
764 netr_NETRENUMERATETRUSTEDDOMAINS
766 static WERROR dcesrv_netr_NETRENUMERATETRUSTEDDOMAINS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
767 struct netr_NETRENUMERATETRUSTEDDOMAINS *r)
769 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
774 netr_NETRLOGONDUMMYROUTINE1
776 static WERROR dcesrv_netr_NETRLOGONDUMMYROUTINE1(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
777 struct netr_NETRLOGONDUMMYROUTINE1 *r)
779 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
784 netr_NETRLOGONSETSERVICEBITS
786 static WERROR dcesrv_netr_NETRLOGONSETSERVICEBITS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
787 struct netr_NETRLOGONSETSERVICEBITS *r)
789 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
794 netr_NETRLOGONGETTRUSTRID
796 static WERROR dcesrv_netr_NETRLOGONGETTRUSTRID(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
797 struct netr_NETRLOGONGETTRUSTRID *r)
799 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
804 netr_NETRLOGONCOMPUTESERVERDIGEST
806 static WERROR dcesrv_netr_NETRLOGONCOMPUTESERVERDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
807 struct netr_NETRLOGONCOMPUTESERVERDIGEST *r)
809 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
814 netr_NETRLOGONCOMPUTECLIENTDIGEST
816 static WERROR dcesrv_netr_NETRLOGONCOMPUTECLIENTDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
817 struct netr_NETRLOGONCOMPUTECLIENTDIGEST *r)
819 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
827 static WERROR dcesrv_netr_DsRGetSiteName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
828 struct netr_DsRGetSiteName *r)
830 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
835 fill in a netr_DomainTrustInfo from a ldb search result
837 static NTSTATUS fill_domain_trust_info(TALLOC_CTX *mem_ctx,
838 struct ldb_message *res,
839 struct ldb_message *ref_res,
840 struct netr_DomainTrustInfo *info,
846 info->domainname.string = samdb_result_string(ref_res, "nETBIOSName", NULL);
847 info->fulldomainname.string = samdb_result_string(ref_res, "dnsRoot", NULL);
848 info->forest.string = NULL;
849 info->guid = samdb_result_guid(res, "objectGUID");
850 info->sid = samdb_result_dom_sid(mem_ctx, res, "objectSid");
852 info->domainname.string = samdb_result_string(res, "flatName", NULL);
853 info->fulldomainname.string = samdb_result_string(res, "trustPartner", NULL);
854 info->forest.string = NULL;
855 info->guid = samdb_result_guid(res, "objectGUID");
856 info->sid = samdb_result_dom_sid(mem_ctx, res, "securityIdentifier");
863 netr_LogonGetDomainInfo
864 this is called as part of the ADS domain logon procedure.
866 static NTSTATUS dcesrv_netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
867 struct netr_LogonGetDomainInfo *r)
869 const char * const attrs[] = { "objectSid",
870 "objectGUID", "flatName", "securityIdentifier",
871 "trustPartner", NULL };
872 const char * const ref_attrs[] = { "nETBIOSName", "dnsRoot", NULL };
873 struct ldb_context *sam_ctx;
874 struct ldb_message **res1, **res2, **ref_res;
875 struct netr_DomainInfo1 *info1;
876 int ret, ret1, ret2, i;
878 struct ldb_dn *partitions_basedn;
880 const char *local_domain;
882 status = dcesrv_netr_creds_server_step_check(r->in.computer_name, mem_ctx,
884 r->out.return_authenticator,
886 NT_STATUS_NOT_OK_RETURN(status);
888 sam_ctx = samdb_connect(mem_ctx, dce_call->conn->auth_state.session_info);
889 if (sam_ctx == NULL) {
890 return NT_STATUS_INVALID_SYSTEM_SERVICE;
893 partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);
895 /* we need to do two searches. The first will pull our primary
896 domain and the second will pull any trusted domains. Our
897 primary domain is also a "trusted" domain, so we need to
898 put the primary domain into the lists of returned trusts as
900 ret1 = gendb_search_dn(sam_ctx, mem_ctx, samdb_base_dn(sam_ctx), &res1, attrs);
902 return NT_STATUS_INTERNAL_DB_CORRUPTION;
905 /* try and find the domain */
906 ret = gendb_search(sam_ctx, mem_ctx, partitions_basedn,
908 "(&(objectClass=crossRef)(ncName=%s))",
909 ldb_dn_get_linearized(res1[0]->dn));
911 return NT_STATUS_INTERNAL_DB_CORRUPTION;
914 local_domain = samdb_result_string(ref_res[0], "nETBIOSName", NULL);
916 ret2 = gendb_search(sam_ctx, mem_ctx, NULL, &res2, attrs, "(objectClass=trustedDomain)");
918 return NT_STATUS_INTERNAL_DB_CORRUPTION;
921 info1 = talloc(mem_ctx, struct netr_DomainInfo1);
922 NT_STATUS_HAVE_NO_MEMORY(info1);
926 info1->num_trusts = ret2 + 1;
927 info1->trusts = talloc_array(mem_ctx, struct netr_DomainTrustInfo,
929 NT_STATUS_HAVE_NO_MEMORY(info1->trusts);
931 status = fill_domain_trust_info(mem_ctx, res1[0], ref_res[0], &info1->domaininfo, true);
932 NT_STATUS_NOT_OK_RETURN(status);
934 for (i=0;i<ret2;i++) {
935 status = fill_domain_trust_info(mem_ctx, res2[i], NULL, &info1->trusts[i], false);
936 NT_STATUS_NOT_OK_RETURN(status);
939 status = fill_domain_trust_info(mem_ctx, res1[0], ref_res[0], &info1->trusts[i], true);
940 NT_STATUS_NOT_OK_RETURN(status);
942 r->out.info.info1 = info1;
950 netr_NETRSERVERPASSWORDGET
952 static WERROR dcesrv_netr_NETRSERVERPASSWORDGET(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
953 struct netr_NETRSERVERPASSWORDGET *r)
955 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
960 netr_NETRLOGONSENDTOSAM
962 static WERROR dcesrv_netr_NETRLOGONSENDTOSAM(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
963 struct netr_NETRLOGONSENDTOSAM *r)
965 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
970 netr_DsRAddressToSitenamesW
972 static WERROR dcesrv_netr_DsRAddressToSitenamesW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
973 struct netr_DsRAddressToSitenamesW *r)
975 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
982 static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
983 struct netr_DsRGetDCNameEx2 *r)
985 const char * const attrs[] = { "dnsDomain", "objectGUID", NULL };
987 struct ldb_message **res;
992 sam_ctx = samdb_connect(mem_ctx, dce_call->conn->auth_state.session_info);
993 if (sam_ctx == NULL) {
994 return WERR_DS_SERVICE_UNAVAILABLE;
997 ret = gendb_search(sam_ctx, mem_ctx, NULL, &res, attrs,
998 "(&(objectClass=domainDNS)(dnsDomain=%s))",
1001 return WERR_NO_SUCH_DOMAIN;
1004 r->out.info = talloc(mem_ctx, struct netr_DsRGetDCNameInfo);
1005 W_ERROR_HAVE_NO_MEMORY(r->out.info);
1007 /* TODO: - return real IP address
1008 * - check all r->in.* parameters (server_unc is ignored by w2k3!)
1010 r->out.info->dc_unc = talloc_asprintf(mem_ctx, "\\\\%s.%s",
1011 lp_netbios_name(global_loadparm),
1012 lp_realm(global_loadparm));
1013 W_ERROR_HAVE_NO_MEMORY(r->out.info->dc_unc);
1014 r->out.info->dc_address = talloc_strdup(mem_ctx, "\\\\0.0.0.0");
1015 W_ERROR_HAVE_NO_MEMORY(r->out.info->dc_address);
1016 r->out.info->dc_address_type = DS_ADDRESS_TYPE_INET;
1017 r->out.info->domain_guid = samdb_result_guid(res[0], "objectGUID");
1018 r->out.info->domain_name = samdb_result_string(res[0], "dnsDomain", NULL);
1019 r->out.info->forest_name = samdb_result_string(res[0], "dnsDomain", NULL);
1020 r->out.info->dc_flags = DS_DNS_FOREST |
1023 DS_SERVER_WRITABLE |
1025 DS_SERVER_TIMESERV |
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 dcesrv_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 = dcesrv_netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1061 r->out.info = r2.out.info;
1069 static WERROR dcesrv_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 = dcesrv_netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1089 r->out.info = r2.out.info;
1095 netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN
1097 static WERROR dcesrv_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 dcesrv_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 dcesrv_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 dcesrv_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 dcesrv_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[] = { "objectSid", "objectGUID", NULL };
1145 const char * const ref_attrs[] = { "nETBIOSName", "dnsRoot", NULL };
1146 struct ldb_dn *partitions_basedn;
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 partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);
1157 ret = gendb_search_dn(sam_ctx, mem_ctx, NULL, &dom_res, dom_attrs);
1159 return WERR_GENERAL_FAILURE;
1162 return WERR_GENERAL_FAILURE;
1165 ret = gendb_search(sam_ctx, mem_ctx, partitions_basedn, &ref_res, ref_attrs,
1166 "(&(objectClass=crossRef)(ncName=%s))",
1167 ldb_dn_get_linearized(dom_res[0]->dn));
1169 return WERR_GENERAL_FAILURE;
1172 return WERR_GENERAL_FAILURE;
1175 trusts = talloc_array(mem_ctx, struct netr_DomainTrust, ret);
1176 W_ERROR_HAVE_NO_MEMORY(trusts);
1179 r->out.trusts = trusts;
1181 /* TODO: add filtering by trust_flags, and correct trust_type
1183 trusts[0].netbios_name = samdb_result_string(ref_res[0], "nETBIOSName", NULL);
1184 trusts[0].dns_name = samdb_result_string(ref_res[0], "dnsRoot", NULL);
1185 trusts[0].trust_flags =
1186 NETR_TRUST_FLAG_TREEROOT |
1187 NETR_TRUST_FLAG_IN_FOREST |
1188 NETR_TRUST_FLAG_PRIMARY;
1189 trusts[0].parent_index = 0;
1190 trusts[0].trust_type = 2;
1191 trusts[0].trust_attributes = 0;
1192 trusts[0].sid = samdb_result_dom_sid(mem_ctx, dom_res[0], "objectSid");
1193 trusts[0].guid = samdb_result_guid(dom_res[0], "objectGUID");
1200 netr_DSRDEREGISTERDNSHOSTRECORDS
1202 static WERROR dcesrv_netr_DSRDEREGISTERDNSHOSTRECORDS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1203 struct netr_DSRDEREGISTERDNSHOSTRECORDS *r)
1205 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1210 netr_NETRSERVERTRUSTPASSWORDSGET
1212 static WERROR dcesrv_netr_NETRSERVERTRUSTPASSWORDSGET(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1213 struct netr_NETRSERVERTRUSTPASSWORDSGET *r)
1215 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1220 netr_DsRGetForestTrustInformation
1222 static WERROR dcesrv_netr_DsRGetForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1223 struct netr_DsRGetForestTrustInformation *r)
1225 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1230 netr_NETRGETFORESTTRUSTINFORMATION
1232 static WERROR dcesrv_netr_NETRGETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1233 struct netr_NETRGETFORESTTRUSTINFORMATION *r)
1235 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1240 netr_NETRSERVERGETTRUSTINFO
1242 static WERROR dcesrv_netr_NETRSERVERGETTRUSTINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1243 struct netr_NETRSERVERGETTRUSTINFO *r)
1245 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1249 /* include the generated boilerplate */
1250 #include "librpc/gen_ndr/ndr_netlogon_s.c"