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"
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,
436 NT_STATUS_NOT_OK_RETURN(nt_status);
438 user_info->logon_parameters = r->in.logon.password->identity_info.parameter_control;
439 user_info->client.account_name = r->in.logon.password->identity_info.account_name.string;
440 user_info->client.domain_name = r->in.logon.password->identity_info.domain_name.string;
441 user_info->workstation_name = r->in.logon.password->identity_info.workstation.string;
443 user_info->flags |= USER_INFO_INTERACTIVE_LOGON;
444 user_info->password_state = AUTH_PASSWORD_HASH;
446 user_info->password.hash.lanman = talloc(user_info, struct samr_Password);
447 NT_STATUS_HAVE_NO_MEMORY(user_info->password.hash.lanman);
448 *user_info->password.hash.lanman = r->in.logon.password->lmpassword;
450 user_info->password.hash.nt = talloc(user_info, struct samr_Password);
451 NT_STATUS_HAVE_NO_MEMORY(user_info->password.hash.nt);
452 *user_info->password.hash.nt = r->in.logon.password->ntpassword;
458 /* TODO: we need to deny anonymous access here */
459 nt_status = auth_context_create(mem_ctx,
460 dce_call->event_ctx, dce_call->msg_ctx,
462 NT_STATUS_NOT_OK_RETURN(nt_status);
464 nt_status = auth_context_set_challenge(auth_context, r->in.logon.network->challenge, "netr_LogonSamLogonWithFlags");
465 NT_STATUS_NOT_OK_RETURN(nt_status);
467 user_info->logon_parameters = r->in.logon.network->identity_info.parameter_control;
468 user_info->client.account_name = r->in.logon.network->identity_info.account_name.string;
469 user_info->client.domain_name = r->in.logon.network->identity_info.domain_name.string;
470 user_info->workstation_name = r->in.logon.network->identity_info.workstation.string;
472 user_info->password_state = AUTH_PASSWORD_RESPONSE;
473 user_info->password.response.lanman = data_blob_talloc(mem_ctx, r->in.logon.network->lm.data, r->in.logon.network->lm.length);
474 user_info->password.response.nt = data_blob_talloc(mem_ctx, r->in.logon.network->nt.data, r->in.logon.network->nt.length);
478 return NT_STATUS_INVALID_PARAMETER;
481 nt_status = auth_check_password(auth_context, mem_ctx, user_info, &server_info);
482 NT_STATUS_NOT_OK_RETURN(nt_status);
484 nt_status = auth_convert_server_info_sambaseinfo(mem_ctx, server_info, &sam);
485 NT_STATUS_NOT_OK_RETURN(nt_status);
487 /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
488 /* It appears that level 6 is not individually encrypted */
489 if ((r->in.validation_level != 6) &&
490 memcmp(sam->key.key, zeros, sizeof(sam->key.key)) != 0) {
491 /* This key is sent unencrypted without the ARCFOUR flag set */
492 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
493 creds_arcfour_crypt(creds,
495 sizeof(sam->key.key));
499 /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
500 /* It appears that level 6 is not individually encrypted */
501 if ((r->in.validation_level != 6) &&
502 memcmp(sam->LMSessKey.key, zeros, sizeof(sam->LMSessKey.key)) != 0) {
503 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
504 creds_arcfour_crypt(creds,
506 sizeof(sam->LMSessKey.key));
508 creds_des_encrypt_LMKey(creds,
513 switch (r->in.validation_level) {
515 sam2 = talloc_zero(mem_ctx, struct netr_SamInfo2);
516 NT_STATUS_HAVE_NO_MEMORY(sam2);
518 r->out.validation.sam2 = sam2;
522 sam3 = talloc_zero(mem_ctx, struct netr_SamInfo3);
523 NT_STATUS_HAVE_NO_MEMORY(sam3);
525 r->out.validation.sam3 = sam3;
529 sam6 = talloc_zero(mem_ctx, struct netr_SamInfo6);
530 NT_STATUS_HAVE_NO_MEMORY(sam6);
532 sam6->forest.string = lp_realm(global_loadparm);
533 sam6->principle.string = talloc_asprintf(mem_ctx, "%s@%s",
534 sam->account_name.string, sam6->forest.string);
535 NT_STATUS_HAVE_NO_MEMORY(sam6->principle.string);
536 r->out.validation.sam6 = sam6;
543 r->out.authoritative = 1;
545 /* TODO: Describe and deal with these flags */
551 static NTSTATUS dcesrv_netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
552 struct netr_LogonSamLogonEx *r)
555 struct creds_CredentialState *creds;
556 nt_status = schannel_fetch_session_key(mem_ctx, r->in.computer_name, lp_workgroup(global_loadparm), &creds);
557 if (!NT_STATUS_IS_OK(nt_status)) {
561 if (!dce_call->conn->auth_state.auth_info ||
562 dce_call->conn->auth_state.auth_info->auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
563 return NT_STATUS_INTERNAL_ERROR;
565 return dcesrv_netr_LogonSamLogon_base(dce_call, mem_ctx, r, creds);
569 netr_LogonSamLogonWithFlags
572 static NTSTATUS dcesrv_netr_LogonSamLogonWithFlags(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
573 struct netr_LogonSamLogonWithFlags *r)
576 struct creds_CredentialState *creds;
577 struct netr_LogonSamLogonEx r2;
579 struct netr_Authenticator *return_authenticator;
581 return_authenticator = talloc(mem_ctx, struct netr_Authenticator);
582 NT_STATUS_HAVE_NO_MEMORY(return_authenticator);
584 nt_status = dcesrv_netr_creds_server_step_check(r->in.computer_name, mem_ctx,
585 r->in.credential, return_authenticator,
587 NT_STATUS_NOT_OK_RETURN(nt_status);
591 r2.in.server_name = r->in.server_name;
592 r2.in.computer_name = r->in.computer_name;
593 r2.in.logon_level = r->in.logon_level;
594 r2.in.logon = r->in.logon;
595 r2.in.validation_level = r->in.validation_level;
596 r2.in.flags = r->in.flags;
598 nt_status = dcesrv_netr_LogonSamLogon_base(dce_call, mem_ctx, &r2, creds);
600 r->out.return_authenticator = return_authenticator;
601 r->out.validation = r2.out.validation;
602 r->out.authoritative = r2.out.authoritative;
603 r->out.flags = r2.out.flags;
611 static NTSTATUS dcesrv_netr_LogonSamLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
612 struct netr_LogonSamLogon *r)
614 struct netr_LogonSamLogonWithFlags r2;
619 r2.in.server_name = r->in.server_name;
620 r2.in.computer_name = r->in.computer_name;
621 r2.in.credential = r->in.credential;
622 r2.in.return_authenticator = r->in.return_authenticator;
623 r2.in.logon_level = r->in.logon_level;
624 r2.in.logon = r->in.logon;
625 r2.in.validation_level = r->in.validation_level;
628 status = dcesrv_netr_LogonSamLogonWithFlags(dce_call, mem_ctx, &r2);
630 r->out.return_authenticator = r2.out.return_authenticator;
631 r->out.validation = r2.out.validation;
632 r->out.authoritative = r2.out.authoritative;
641 static NTSTATUS dcesrv_netr_LogonSamLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
642 struct netr_LogonSamLogoff *r)
644 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
652 static NTSTATUS dcesrv_netr_DatabaseDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
653 struct netr_DatabaseDeltas *r)
655 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
662 static NTSTATUS dcesrv_netr_DatabaseSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
663 struct netr_DatabaseSync *r)
665 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
672 static NTSTATUS dcesrv_netr_AccountDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
673 struct netr_AccountDeltas *r)
675 /* w2k3 returns "NOT IMPLEMENTED" for this call */
676 return NT_STATUS_NOT_IMPLEMENTED;
683 static NTSTATUS dcesrv_netr_AccountSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
684 struct netr_AccountSync *r)
686 /* w2k3 returns "NOT IMPLEMENTED" for this call */
687 return NT_STATUS_NOT_IMPLEMENTED;
694 static WERROR dcesrv_netr_GetDcName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
695 struct netr_GetDcName *r)
697 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
704 static WERROR dcesrv_netr_LogonControl(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
705 struct netr_LogonControl *r)
707 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
714 static WERROR dcesrv_netr_GetAnyDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
715 struct netr_GetAnyDCName *r)
717 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
724 static WERROR dcesrv_netr_LogonControl2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
725 struct netr_LogonControl2 *r)
727 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
734 static NTSTATUS dcesrv_netr_DatabaseSync2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
735 struct netr_DatabaseSync2 *r)
737 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
744 static NTSTATUS dcesrv_netr_DatabaseRedo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
745 struct netr_DatabaseRedo *r)
747 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
754 static WERROR dcesrv_netr_LogonControl2Ex(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
755 struct netr_LogonControl2Ex *r)
757 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
762 netr_NETRENUMERATETRUSTEDDOMAINS
764 static WERROR dcesrv_netr_NETRENUMERATETRUSTEDDOMAINS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
765 struct netr_NETRENUMERATETRUSTEDDOMAINS *r)
767 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
772 netr_NETRLOGONDUMMYROUTINE1
774 static WERROR dcesrv_netr_NETRLOGONDUMMYROUTINE1(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
775 struct netr_NETRLOGONDUMMYROUTINE1 *r)
777 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
782 netr_NETRLOGONSETSERVICEBITS
784 static WERROR dcesrv_netr_NETRLOGONSETSERVICEBITS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
785 struct netr_NETRLOGONSETSERVICEBITS *r)
787 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
792 netr_NETRLOGONGETTRUSTRID
794 static WERROR dcesrv_netr_NETRLOGONGETTRUSTRID(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
795 struct netr_NETRLOGONGETTRUSTRID *r)
797 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
802 netr_NETRLOGONCOMPUTESERVERDIGEST
804 static WERROR dcesrv_netr_NETRLOGONCOMPUTESERVERDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
805 struct netr_NETRLOGONCOMPUTESERVERDIGEST *r)
807 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
812 netr_NETRLOGONCOMPUTECLIENTDIGEST
814 static WERROR dcesrv_netr_NETRLOGONCOMPUTECLIENTDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
815 struct netr_NETRLOGONCOMPUTECLIENTDIGEST *r)
817 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
825 static WERROR dcesrv_netr_DsRGetSiteName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
826 struct netr_DsRGetSiteName *r)
828 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
833 fill in a netr_DomainTrustInfo from a ldb search result
835 static NTSTATUS fill_domain_trust_info(TALLOC_CTX *mem_ctx,
836 struct ldb_message *res,
837 struct ldb_message *ref_res,
838 struct netr_DomainTrustInfo *info,
844 info->domainname.string = samdb_result_string(ref_res, "nETBIOSName", NULL);
845 info->fulldomainname.string = samdb_result_string(ref_res, "dnsRoot", NULL);
846 info->forest.string = NULL;
847 info->guid = samdb_result_guid(res, "objectGUID");
848 info->sid = samdb_result_dom_sid(mem_ctx, res, "objectSid");
850 info->domainname.string = samdb_result_string(res, "flatName", NULL);
851 info->fulldomainname.string = samdb_result_string(res, "trustPartner", NULL);
852 info->forest.string = NULL;
853 info->guid = samdb_result_guid(res, "objectGUID");
854 info->sid = samdb_result_dom_sid(mem_ctx, res, "securityIdentifier");
861 netr_LogonGetDomainInfo
862 this is called as part of the ADS domain logon procedure.
864 static NTSTATUS dcesrv_netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
865 struct netr_LogonGetDomainInfo *r)
867 const char * const attrs[] = { "objectSid",
868 "objectGUID", "flatName", "securityIdentifier",
869 "trustPartner", NULL };
870 const char * const ref_attrs[] = { "nETBIOSName", "dnsRoot", NULL };
871 struct ldb_context *sam_ctx;
872 struct ldb_message **res1, **res2, **ref_res;
873 struct netr_DomainInfo1 *info1;
874 int ret, ret1, ret2, i;
876 struct ldb_dn *partitions_basedn;
878 const char *local_domain;
880 status = dcesrv_netr_creds_server_step_check(r->in.computer_name, mem_ctx,
882 r->out.return_authenticator,
884 NT_STATUS_NOT_OK_RETURN(status);
886 sam_ctx = samdb_connect(mem_ctx, dce_call->conn->auth_state.session_info);
887 if (sam_ctx == NULL) {
888 return NT_STATUS_INVALID_SYSTEM_SERVICE;
891 partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);
893 /* we need to do two searches. The first will pull our primary
894 domain and the second will pull any trusted domains. Our
895 primary domain is also a "trusted" domain, so we need to
896 put the primary domain into the lists of returned trusts as
898 ret1 = gendb_search_dn(sam_ctx, mem_ctx, samdb_base_dn(sam_ctx), &res1, attrs);
900 return NT_STATUS_INTERNAL_DB_CORRUPTION;
903 /* try and find the domain */
904 ret = gendb_search(sam_ctx, mem_ctx, partitions_basedn,
906 "(&(objectClass=crossRef)(ncName=%s))",
907 ldb_dn_get_linearized(res1[0]->dn));
909 return NT_STATUS_INTERNAL_DB_CORRUPTION;
912 local_domain = samdb_result_string(ref_res[0], "nETBIOSName", NULL);
914 ret2 = gendb_search(sam_ctx, mem_ctx, NULL, &res2, attrs, "(objectClass=trustedDomain)");
916 return NT_STATUS_INTERNAL_DB_CORRUPTION;
919 info1 = talloc(mem_ctx, struct netr_DomainInfo1);
920 NT_STATUS_HAVE_NO_MEMORY(info1);
924 info1->num_trusts = ret2 + 1;
925 info1->trusts = talloc_array(mem_ctx, struct netr_DomainTrustInfo,
927 NT_STATUS_HAVE_NO_MEMORY(info1->trusts);
929 status = fill_domain_trust_info(mem_ctx, res1[0], ref_res[0], &info1->domaininfo, true);
930 NT_STATUS_NOT_OK_RETURN(status);
932 for (i=0;i<ret2;i++) {
933 status = fill_domain_trust_info(mem_ctx, res2[i], NULL, &info1->trusts[i], false);
934 NT_STATUS_NOT_OK_RETURN(status);
937 status = fill_domain_trust_info(mem_ctx, res1[0], ref_res[0], &info1->trusts[i], true);
938 NT_STATUS_NOT_OK_RETURN(status);
940 r->out.info.info1 = info1;
948 netr_NETRSERVERPASSWORDGET
950 static WERROR dcesrv_netr_NETRSERVERPASSWORDGET(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
951 struct netr_NETRSERVERPASSWORDGET *r)
953 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
958 netr_NETRLOGONSENDTOSAM
960 static WERROR dcesrv_netr_NETRLOGONSENDTOSAM(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
961 struct netr_NETRLOGONSENDTOSAM *r)
963 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
968 netr_DSRADDRESSTOSITENAMESW
970 static WERROR dcesrv_netr_DSRADDRESSTOSITENAMESW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
971 struct netr_DSRADDRESSTOSITENAMESW *r)
973 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
980 static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
981 struct netr_DsRGetDCNameEx2 *r)
983 const char * const attrs[] = { "dnsDomain", "objectGUID", NULL };
985 struct ldb_message **res;
990 sam_ctx = samdb_connect(mem_ctx, dce_call->conn->auth_state.session_info);
991 if (sam_ctx == NULL) {
992 return WERR_DS_SERVICE_UNAVAILABLE;
995 ret = gendb_search(sam_ctx, mem_ctx, NULL, &res, attrs,
996 "(&(objectClass=domainDNS)(dnsDomain=%s))",
999 return WERR_NO_SUCH_DOMAIN;
1002 r->out.info = talloc(mem_ctx, struct netr_DsRGetDCNameInfo);
1003 W_ERROR_HAVE_NO_MEMORY(r->out.info);
1005 /* TODO: - return real IP address
1006 * - check all r->in.* parameters (server_unc is ignored by w2k3!)
1008 r->out.info->dc_unc = talloc_asprintf(mem_ctx, "\\\\%s.%s",
1009 lp_netbios_name(global_loadparm),
1010 lp_realm(global_loadparm));
1011 W_ERROR_HAVE_NO_MEMORY(r->out.info->dc_unc);
1012 r->out.info->dc_address = talloc_strdup(mem_ctx, "\\\\0.0.0.0");
1013 W_ERROR_HAVE_NO_MEMORY(r->out.info->dc_address);
1014 r->out.info->dc_address_type = DS_ADDRESS_TYPE_INET;
1015 r->out.info->domain_guid = samdb_result_guid(res[0], "objectGUID");
1016 r->out.info->domain_name = samdb_result_string(res[0], "dnsDomain", NULL);
1017 r->out.info->forest_name = samdb_result_string(res[0], "dnsDomain", NULL);
1018 r->out.info->dc_flags = DS_DNS_FOREST |
1021 DS_SERVER_WRITABLE |
1023 DS_SERVER_TIMESERV |
1029 r->out.info->dc_site_name = talloc_strdup(mem_ctx, "Default-First-Site-Name");
1030 W_ERROR_HAVE_NO_MEMORY(r->out.info->dc_site_name);
1031 r->out.info->client_site_name = talloc_strdup(mem_ctx, "Default-First-Site-Name");
1032 W_ERROR_HAVE_NO_MEMORY(r->out.info->client_site_name);
1040 static WERROR dcesrv_netr_DsRGetDCNameEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1041 struct netr_DsRGetDCNameEx *r)
1043 struct netr_DsRGetDCNameEx2 r2;
1048 r2.in.server_unc = r->in.server_unc;
1049 r2.in.client_account = NULL;
1051 r2.in.domain_guid = r->in.domain_guid;
1052 r2.in.domain_name = r->in.domain_name;
1053 r2.in.site_name = r->in.site_name;
1054 r2.in.flags = r->in.flags;
1057 werr = dcesrv_netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1059 r->out.info = r2.out.info;
1067 static WERROR dcesrv_netr_DsRGetDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1068 struct netr_DsRGetDCName *r)
1070 struct netr_DsRGetDCNameEx2 r2;
1075 r2.in.server_unc = r->in.server_unc;
1076 r2.in.client_account = NULL;
1078 r2.in.domain_name = r->in.domain_name;
1079 r2.in.domain_guid = r->in.domain_guid;
1081 r2.in.site_name = NULL; /* should fill in from site GUID */
1082 r2.in.flags = r->in.flags;
1085 werr = dcesrv_netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1087 r->out.info = r2.out.info;
1093 netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN
1095 static WERROR dcesrv_netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1096 struct netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN *r)
1098 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1103 netr_NETRENUMERATETRUSTEDDOMAINSEX
1105 static WERROR dcesrv_netr_NETRENUMERATETRUSTEDDOMAINSEX(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1106 struct netr_NETRENUMERATETRUSTEDDOMAINSEX *r)
1108 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1113 netr_DSRADDRESSTOSITENAMESEXW
1115 static WERROR dcesrv_netr_DSRADDRESSTOSITENAMESEXW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1116 struct netr_DSRADDRESSTOSITENAMESEXW *r)
1118 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1123 netr_DsrGetDcSiteCoverageW
1125 static WERROR dcesrv_netr_DsrGetDcSiteCoverageW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1126 struct netr_DsrGetDcSiteCoverageW *r)
1128 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1133 netr_DsrEnumerateDomainTrusts
1135 static WERROR dcesrv_netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1136 struct netr_DsrEnumerateDomainTrusts *r)
1138 struct netr_DomainTrust *trusts;
1141 struct ldb_message **dom_res, **ref_res;
1142 const char * const dom_attrs[] = { "objectSid", "objectGUID", NULL };
1143 const char * const ref_attrs[] = { "nETBIOSName", "dnsRoot", NULL };
1144 struct ldb_dn *partitions_basedn;
1146 ZERO_STRUCT(r->out);
1148 sam_ctx = samdb_connect(mem_ctx, dce_call->conn->auth_state.session_info);
1149 if (sam_ctx == NULL) {
1150 return WERR_GENERAL_FAILURE;
1153 partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);
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_get_linearized(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(ref_res[0], "dnsRoot", 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 dcesrv_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 dcesrv_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 dcesrv_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 dcesrv_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 dcesrv_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"