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_sam.h"
29 #include "auth/auth.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"
36 struct server_pipe_state {
37 struct netr_Credential client_challenge;
38 struct netr_Credential server_challenge;
42 static NTSTATUS netr_ServerReqChallenge(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
43 struct netr_ServerReqChallenge *r)
45 struct server_pipe_state *pipe_state = dce_call->context->private;
47 ZERO_STRUCTP(r->out.credentials);
49 /* destroyed on pipe shutdown */
52 talloc_free(pipe_state);
53 dce_call->context->private = NULL;
56 pipe_state = talloc(dce_call->context, struct server_pipe_state);
58 return NT_STATUS_NO_MEMORY;
61 pipe_state->client_challenge = *r->in.credentials;
63 generate_random_buffer(pipe_state->server_challenge.data,
64 sizeof(pipe_state->server_challenge.data));
66 *r->out.credentials = pipe_state->server_challenge;
68 dce_call->context->private = pipe_state;
73 static NTSTATUS netr_ServerAuthenticate3(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
74 struct netr_ServerAuthenticate3 *r)
76 struct server_pipe_state *pipe_state = dce_call->context->private;
77 struct creds_CredentialState *creds;
79 struct samr_Password *mach_pwd;
82 struct ldb_message **msgs;
84 const char *attrs[] = {"ntPwdHash", "userAccountControl",
87 ZERO_STRUCTP(r->out.credentials);
89 *r->out.negotiate_flags = *r->in.negotiate_flags;
92 DEBUG(1, ("No challenge requested by client, cannot authenticate\n"));
93 return NT_STATUS_ACCESS_DENIED;
96 sam_ctx = samdb_connect(mem_ctx, system_session(mem_ctx));
97 if (sam_ctx == NULL) {
98 return NT_STATUS_INVALID_SYSTEM_SERVICE;
100 /* pull the user attributes */
101 num_records = gendb_search(sam_ctx, mem_ctx, NULL, &msgs, attrs,
102 "(&(sAMAccountName=%s)(objectclass=user))",
105 if (num_records == 0) {
106 DEBUG(3,("Couldn't find user [%s] in samdb.\n",
107 r->in.account_name));
108 return NT_STATUS_ACCESS_DENIED;
111 if (num_records > 1) {
112 DEBUG(0,("Found %d records matching user [%s]\n", num_records, r->in.account_name));
113 return NT_STATUS_INTERNAL_DB_CORRUPTION;
116 acct_flags = samdb_result_acct_flags(msgs[0],
117 "userAccountControl");
119 if (acct_flags & ACB_DISABLED) {
120 DEBUG(1, ("Account [%s] is disabled\n", r->in.account_name));
121 return NT_STATUS_ACCESS_DENIED;
124 if (r->in.secure_channel_type == SEC_CHAN_WKSTA) {
125 if (!(acct_flags & ACB_WSTRUST)) {
126 DEBUG(1, ("Client asked for a workstation secure channel, but is not a workstation (member server) acb flags: 0x%x\n", acct_flags));
127 return NT_STATUS_ACCESS_DENIED;
129 } else if (r->in.secure_channel_type == SEC_CHAN_DOMAIN) {
130 if (!(acct_flags & ACB_DOMTRUST)) {
131 DEBUG(1, ("Client asked for a trusted domain secure channel, but is not a trusted domain: acb flags: 0x%x\n", acct_flags));
132 return NT_STATUS_ACCESS_DENIED;
134 } else if (r->in.secure_channel_type == SEC_CHAN_BDC) {
135 if (!(acct_flags & ACB_SVRTRUST)) {
136 DEBUG(1, ("Client asked for a server secure channel, but is not a server (domain controller): acb flags: 0x%x\n", acct_flags));
137 return NT_STATUS_ACCESS_DENIED;
140 DEBUG(1, ("Client asked for an invalid secure channel type: %d\n",
141 r->in.secure_channel_type));
142 return NT_STATUS_ACCESS_DENIED;
145 *r->out.rid = samdb_result_rid_from_sid(mem_ctx, msgs[0],
148 mach_pwd = samdb_result_hash(mem_ctx, msgs[0], "ntPwdHash");
149 if (mach_pwd == NULL) {
150 return NT_STATUS_ACCESS_DENIED;
153 creds = talloc(mem_ctx, struct creds_CredentialState);
155 return NT_STATUS_NO_MEMORY;
158 creds_server_init(creds, &pipe_state->client_challenge,
159 &pipe_state->server_challenge, mach_pwd,
161 *r->in.negotiate_flags);
163 if (!creds_server_check(creds, r->in.credentials)) {
165 return NT_STATUS_ACCESS_DENIED;
168 creds->account_name = talloc_steal(creds, r->in.account_name);
170 creds->computer_name = talloc_steal(creds, r->in.computer_name);
171 creds->domain = talloc_strdup(creds, lp_workgroup());
173 creds->secure_channel_type = r->in.secure_channel_type;
175 creds->sid = samdb_result_dom_sid(creds, msgs[0], "objectSid");
178 /* remember this session key state */
179 nt_status = schannel_store_session_key(mem_ctx, creds);
184 static NTSTATUS netr_ServerAuthenticate(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
185 struct netr_ServerAuthenticate *r)
187 struct netr_ServerAuthenticate3 r3;
190 * negotiate_flags is used as an [in] parameter
191 * so it need to be initialised.
193 * (I think ... = 0; seems wrong here --metze)
195 uint32_t negotiate_flags = 0;
197 r3.in.server_name = r->in.server_name;
198 r3.in.account_name = r->in.account_name;
199 r3.in.secure_channel_type = r->in.secure_channel_type;
200 r3.in.computer_name = r->in.computer_name;
201 r3.in.credentials = r->in.credentials;
202 r3.out.credentials = r->out.credentials;
203 r3.in.negotiate_flags = &negotiate_flags;
204 r3.out.negotiate_flags = &negotiate_flags;
207 return netr_ServerAuthenticate3(dce_call, mem_ctx, &r3);
210 static NTSTATUS netr_ServerAuthenticate2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
211 struct netr_ServerAuthenticate2 *r)
213 struct netr_ServerAuthenticate3 r3;
216 r3.in.server_name = r->in.server_name;
217 r3.in.account_name = r->in.account_name;
218 r3.in.secure_channel_type = r->in.secure_channel_type;
219 r3.in.computer_name = r->in.computer_name;
220 r3.in.credentials = r->in.credentials;
221 r3.out.credentials = r->out.credentials;
222 r3.in.negotiate_flags = r->in.negotiate_flags;
223 r3.out.negotiate_flags = r->out.negotiate_flags;
226 return netr_ServerAuthenticate3(dce_call, mem_ctx, &r3);
230 Validate an incoming authenticator against the credentials for the remote machine.
232 The credentials are (re)read and from the schannel database, and
233 written back after the caclulations are performed.
235 The creds_out parameter (if not NULL) returns the credentials, if
236 the caller needs some of that information.
239 static NTSTATUS netr_creds_server_step_check(const char *computer_name,
241 struct netr_Authenticator *received_authenticator,
242 struct netr_Authenticator *return_authenticator,
243 struct creds_CredentialState **creds_out)
245 struct creds_CredentialState *creds;
247 struct ldb_context *ldb;
250 ldb = schannel_db_connect(mem_ctx);
252 return NT_STATUS_ACCESS_DENIED;
255 ret = ldb_transaction_start(ldb);
258 return NT_STATUS_INTERNAL_DB_CORRUPTION;
261 /* Because this is a shared structure (even across
262 * disconnects) we must update the database every time we
263 * update the structure */
265 nt_status = schannel_fetch_session_key_ldb(ldb, ldb, computer_name, lp_workgroup(),
267 if (NT_STATUS_IS_OK(nt_status)) {
268 nt_status = creds_server_step_check(creds,
269 received_authenticator,
270 return_authenticator);
272 if (NT_STATUS_IS_OK(nt_status)) {
273 nt_status = schannel_store_session_key_ldb(ldb, ldb, creds);
276 if (NT_STATUS_IS_OK(nt_status)) {
277 ldb_transaction_commit(ldb);
280 talloc_steal(mem_ctx, creds);
283 ldb_transaction_cancel(ldb);
290 Change the machine account password for the currently connected
291 client. Supplies only the NT#.
294 static NTSTATUS netr_ServerPasswordSet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
295 struct netr_ServerPasswordSet *r)
297 struct creds_CredentialState *creds;
298 struct ldb_context *sam_ctx;
301 nt_status = netr_creds_server_step_check(r->in.computer_name, mem_ctx,
302 &r->in.credential, &r->out.return_authenticator,
304 NT_STATUS_NOT_OK_RETURN(nt_status);
306 sam_ctx = samdb_connect(mem_ctx, system_session(mem_ctx));
307 if (sam_ctx == NULL) {
308 return NT_STATUS_INVALID_SYSTEM_SERVICE;
311 creds_des_decrypt(creds, &r->in.new_password);
313 /* Using the sid for the account as the key, set the password */
314 nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
316 NULL, /* Don't have plaintext */
317 NULL, &r->in.new_password,
318 False, /* This is not considered a password change */
319 False, /* don't restrict this password change (match w2k3) */
325 Change the machine account password for the currently connected
326 client. Supplies new plaintext.
328 static NTSTATUS netr_ServerPasswordSet2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
329 struct netr_ServerPasswordSet2 *r)
331 struct creds_CredentialState *creds;
332 struct ldb_context *sam_ctx;
335 uint32_t new_pass_len;
338 struct samr_CryptPassword password_buf;
340 nt_status = netr_creds_server_step_check(r->in.computer_name, mem_ctx,
341 &r->in.credential, &r->out.return_authenticator,
343 NT_STATUS_NOT_OK_RETURN(nt_status);
345 sam_ctx = samdb_connect(mem_ctx, system_session(mem_ctx));
346 if (sam_ctx == NULL) {
347 return NT_STATUS_INVALID_SYSTEM_SERVICE;
350 memcpy(password_buf.data, r->in.new_password.data, 512);
351 SIVAL(password_buf.data,512,r->in.new_password.length);
352 creds_arcfour_crypt(creds, password_buf.data, 516);
354 ret = decode_pw_buffer(password_buf.data, new_pass, sizeof(new_pass),
355 &new_pass_len, STR_UNICODE);
357 DEBUG(3,("netr_ServerPasswordSet2: failed to decode password buffer\n"));
358 return NT_STATUS_ACCESS_DENIED;
361 /* Using the sid for the account as the key, set the password */
362 nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
364 new_pass, /* we have plaintext */
366 False, /* This is not considered a password change */
367 False, /* don't restrict this password change (match w2k3) */
376 static WERROR netr_LogonUasLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
377 struct netr_LogonUasLogon *r)
379 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
386 static WERROR netr_LogonUasLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
387 struct netr_LogonUasLogoff *r)
389 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
394 netr_LogonSamLogon_base
396 This version of the function allows other wrappers to say 'do not check the credentials'
398 We can't do the traditional 'wrapping' format completly, as this function must only run under schannel
400 static NTSTATUS netr_LogonSamLogon_base(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
401 struct netr_LogonSamLogonEx *r, struct creds_CredentialState *creds)
403 struct auth_context *auth_context;
404 struct auth_usersupplied_info *user_info;
405 struct auth_serversupplied_info *server_info;
407 static const char zeros[16];
408 struct netr_SamBaseInfo *sam;
409 struct netr_SamInfo2 *sam2;
410 struct netr_SamInfo3 *sam3;
411 struct netr_SamInfo6 *sam6;
413 user_info = talloc(mem_ctx, struct auth_usersupplied_info);
415 return NT_STATUS_NO_MEMORY;
418 user_info->flags = 0;
419 user_info->mapped_state = False;
420 user_info->remote_host = NULL;
422 switch (r->in.logon_level) {
426 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
427 creds_arcfour_crypt(creds,
428 r->in.logon.password->lmpassword.hash,
429 sizeof(r->in.logon.password->lmpassword.hash));
430 creds_arcfour_crypt(creds,
431 r->in.logon.password->ntpassword.hash,
432 sizeof(r->in.logon.password->ntpassword.hash));
434 creds_des_decrypt(creds, &r->in.logon.password->lmpassword);
435 creds_des_decrypt(creds, &r->in.logon.password->ntpassword);
438 /* TODO: we need to deny anonymous access here */
439 nt_status = auth_context_create(mem_ctx, lp_auth_methods(), &auth_context,
440 dce_call->event_ctx);
441 NT_STATUS_NOT_OK_RETURN(nt_status);
443 user_info->logon_parameters = r->in.logon.password->identity_info.parameter_control;
444 user_info->client.account_name = r->in.logon.password->identity_info.account_name.string;
445 user_info->client.domain_name = r->in.logon.password->identity_info.domain_name.string;
446 user_info->workstation_name = r->in.logon.password->identity_info.workstation.string;
448 user_info->password_state = AUTH_PASSWORD_HASH;
449 user_info->password.hash.lanman = talloc(user_info, struct samr_Password);
450 if (!user_info->password.hash.lanman) {
451 return NT_STATUS_NO_MEMORY;
453 *user_info->password.hash.lanman = r->in.logon.password->lmpassword;
455 user_info->password.hash.nt = talloc(user_info, struct samr_Password);
456 if (!user_info->password.hash.nt) {
457 return NT_STATUS_NO_MEMORY;
459 *user_info->password.hash.nt = r->in.logon.password->ntpassword;
461 user_info->flags |= USER_INFO_INTERACTIVE_LOGON;
467 /* TODO: we need to deny anonymous access here */
468 nt_status = auth_context_create(mem_ctx, lp_auth_methods(), &auth_context,
469 dce_call->event_ctx);
470 NT_STATUS_NOT_OK_RETURN(nt_status);
472 nt_status = auth_context_set_challenge(auth_context, r->in.logon.network->challenge, "netr_LogonSamLogonWithFlags");
473 NT_STATUS_NOT_OK_RETURN(nt_status);
475 user_info->logon_parameters = r->in.logon.network->identity_info.parameter_control;
476 user_info->client.account_name = r->in.logon.network->identity_info.account_name.string;
477 user_info->client.domain_name = r->in.logon.network->identity_info.domain_name.string;
478 user_info->workstation_name = r->in.logon.network->identity_info.workstation.string;
480 user_info->password_state = AUTH_PASSWORD_RESPONSE;
481 user_info->password.response.lanman = data_blob(r->in.logon.network->lm.data, r->in.logon.network->lm.length);
482 user_info->password.response.nt = data_blob(r->in.logon.network->nt.data, r->in.logon.network->nt.length);
486 return NT_STATUS_INVALID_PARAMETER;
489 nt_status = auth_check_password(auth_context, mem_ctx, user_info, &server_info);
490 NT_STATUS_NOT_OK_RETURN(nt_status);
492 nt_status = auth_convert_server_info_sambaseinfo(mem_ctx, server_info, &sam);
494 NT_STATUS_NOT_OK_RETURN(nt_status);
496 /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
497 /* It appears that level 6 is not individually encrypted */
498 if ((r->in.validation_level != 6)
499 && memcmp(sam->key.key, zeros,
500 sizeof(sam->key.key)) != 0) {
502 /* This key is sent unencrypted without the ARCFOUR flag set */
503 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
504 creds_arcfour_crypt(creds,
506 sizeof(sam->key.key));
510 /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
511 /* It appears that level 6 is not individually encrypted */
512 if ((r->in.validation_level != 6)
513 && memcmp(sam->LMSessKey.key, zeros,
514 sizeof(sam->LMSessKey.key)) != 0) {
515 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
516 creds_arcfour_crypt(creds,
518 sizeof(sam->LMSessKey.key));
520 creds_des_encrypt_LMKey(creds,
525 switch (r->in.validation_level) {
527 sam2 = talloc_zero(mem_ctx, struct netr_SamInfo2);
528 NT_STATUS_HAVE_NO_MEMORY(sam2);
530 r->out.validation.sam2 = sam2;
534 sam3 = talloc_zero(mem_ctx, struct netr_SamInfo3);
535 NT_STATUS_HAVE_NO_MEMORY(sam3);
537 r->out.validation.sam3 = sam3;
541 sam6 = talloc_zero(mem_ctx, struct netr_SamInfo6);
542 NT_STATUS_HAVE_NO_MEMORY(sam6);
544 sam6->forest.string = lp_realm();
545 sam6->principle.string = talloc_asprintf(mem_ctx, "%s@%s",
546 sam->account_name.string, sam6->forest.string);
547 NT_STATUS_HAVE_NO_MEMORY(sam6->principle.string);
548 r->out.validation.sam6 = sam6;
555 r->out.authoritative = 1;
557 /* TODO: Describe and deal with these flags */
563 static NTSTATUS netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
564 struct netr_LogonSamLogonEx *r)
567 struct creds_CredentialState *creds;
568 nt_status = schannel_fetch_session_key(mem_ctx, r->in.computer_name, lp_workgroup(), &creds);
569 if (!NT_STATUS_IS_OK(nt_status)) {
573 if (!dce_call->conn->auth_state.auth_info
574 || dce_call->conn->auth_state.auth_info->auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
575 return NT_STATUS_INTERNAL_ERROR;
577 return netr_LogonSamLogon_base(dce_call, mem_ctx, r, creds);
581 netr_LogonSamLogonWithFlags
584 static NTSTATUS netr_LogonSamLogonWithFlags(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
585 struct netr_LogonSamLogonWithFlags *r)
588 struct creds_CredentialState *creds;
589 struct netr_LogonSamLogonEx r2;
591 struct netr_Authenticator *return_authenticator;
593 return_authenticator = talloc(mem_ctx, struct netr_Authenticator);
594 NT_STATUS_HAVE_NO_MEMORY(return_authenticator);
596 nt_status = netr_creds_server_step_check(r->in.computer_name, mem_ctx,
597 r->in.credential, return_authenticator,
599 NT_STATUS_NOT_OK_RETURN(nt_status);
603 r2.in.server_name = r->in.server_name;
604 r2.in.computer_name = r->in.computer_name;
605 r2.in.logon_level = r->in.logon_level;
606 r2.in.logon = r->in.logon;
607 r2.in.validation_level = r->in.validation_level;
608 r2.in.flags = r->in.flags;
610 nt_status = netr_LogonSamLogon_base(dce_call, mem_ctx, &r2, creds);
612 r->out.return_authenticator = return_authenticator;
613 r->out.validation = r2.out.validation;
614 r->out.authoritative = r2.out.authoritative;
615 r->out.flags = r2.out.flags;
623 static NTSTATUS netr_LogonSamLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
624 struct netr_LogonSamLogon *r)
626 struct netr_LogonSamLogonWithFlags r2;
631 r2.in.server_name = r->in.server_name;
632 r2.in.computer_name = r->in.computer_name;
633 r2.in.credential = r->in.credential;
634 r2.in.return_authenticator = r->in.return_authenticator;
635 r2.in.logon_level = r->in.logon_level;
636 r2.in.logon = r->in.logon;
637 r2.in.validation_level = r->in.validation_level;
640 status = netr_LogonSamLogonWithFlags(dce_call, mem_ctx, &r2);
642 r->out.return_authenticator = r2.out.return_authenticator;
643 r->out.validation = r2.out.validation;
644 r->out.authoritative = r2.out.authoritative;
653 static NTSTATUS netr_LogonSamLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
654 struct netr_LogonSamLogoff *r)
656 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
664 static NTSTATUS netr_DatabaseDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
665 struct netr_DatabaseDeltas *r)
667 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
674 static NTSTATUS netr_DatabaseSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
675 struct netr_DatabaseSync *r)
677 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
684 static NTSTATUS netr_AccountDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
685 struct netr_AccountDeltas *r)
687 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
694 static NTSTATUS netr_AccountSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
695 struct netr_AccountSync *r)
697 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
704 static NTSTATUS netr_GetDcName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
705 struct netr_GetDcName *r)
707 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
714 static WERROR netr_LogonControl(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
715 struct netr_LogonControl *r)
717 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
724 static WERROR netr_GetAnyDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
725 struct netr_GetAnyDCName *r)
727 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
734 static WERROR netr_LogonControl2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
735 struct netr_LogonControl2 *r)
737 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
744 static NTSTATUS netr_DatabaseSync2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
745 struct netr_DatabaseSync2 *r)
747 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
754 static NTSTATUS netr_DatabaseRedo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
755 struct netr_DatabaseRedo *r)
757 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
764 static WERROR netr_LogonControl2Ex(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
765 struct netr_LogonControl2Ex *r)
767 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
772 netr_NETRENUMERATETRUSTEDDOMAINS
774 static WERROR netr_NETRENUMERATETRUSTEDDOMAINS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
775 struct netr_NETRENUMERATETRUSTEDDOMAINS *r)
777 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
782 netr_NETRLOGONDUMMYROUTINE1
784 static WERROR netr_NETRLOGONDUMMYROUTINE1(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
785 struct netr_NETRLOGONDUMMYROUTINE1 *r)
787 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
792 netr_NETRLOGONSETSERVICEBITS
794 static WERROR netr_NETRLOGONSETSERVICEBITS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
795 struct netr_NETRLOGONSETSERVICEBITS *r)
797 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
802 netr_NETRLOGONGETTRUSTRID
804 static WERROR netr_NETRLOGONGETTRUSTRID(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
805 struct netr_NETRLOGONGETTRUSTRID *r)
807 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
812 netr_NETRLOGONCOMPUTESERVERDIGEST
814 static WERROR netr_NETRLOGONCOMPUTESERVERDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
815 struct netr_NETRLOGONCOMPUTESERVERDIGEST *r)
817 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
822 netr_NETRLOGONCOMPUTECLIENTDIGEST
824 static WERROR netr_NETRLOGONCOMPUTECLIENTDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
825 struct netr_NETRLOGONCOMPUTECLIENTDIGEST *r)
827 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
835 static WERROR netr_DsRGetSiteName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
836 struct netr_DsRGetSiteName *r)
838 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
843 fill in a netr_DomainTrustInfo from a ldb search result
845 static NTSTATUS fill_domain_primary_info(TALLOC_CTX *mem_ctx, struct ldb_message *res,
846 struct netr_DomainTrustInfo *info,
847 const char *local_domain)
851 info->domainname.string = local_domain;
852 info->fulldomainname.string = talloc_asprintf(info, "%s.", samdb_result_string(res, "dnsDomain", NULL));
853 /* TODO: we need proper forest support */
854 info->forest.string = info->fulldomainname.string;
855 info->guid = samdb_result_guid(res, "objectGUID");
856 info->sid = samdb_result_dom_sid(mem_ctx, res, "objectSid");
862 fill in a netr_DomainTrustInfo from a ldb search result
864 static NTSTATUS fill_domain_trust_info(TALLOC_CTX *mem_ctx, struct ldb_message *res,
865 struct netr_DomainTrustInfo *info,
866 const char *local_domain, BOOL is_local)
871 info->domainname.string = local_domain;
872 info->fulldomainname.string = samdb_result_string(res, "dnsDomain", NULL);
873 info->forest.string = NULL;
874 info->guid = samdb_result_guid(res, "objectGUID");
875 info->sid = samdb_result_dom_sid(mem_ctx, res, "objectSid");
877 info->domainname.string = samdb_result_string(res, "flatName", NULL);
878 info->fulldomainname.string = samdb_result_string(res, "name", NULL);
879 info->forest.string = NULL;
880 info->guid = samdb_result_guid(res, "objectGUID");
881 info->sid = samdb_result_dom_sid(mem_ctx, res, "securityIdentifier");
888 netr_LogonGetDomainInfo
889 this is called as part of the ADS domain logon procedure.
891 static NTSTATUS netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
892 struct netr_LogonGetDomainInfo *r)
894 const char * const attrs[] = { "dnsDomain", "objectSid",
895 "objectGUID", "flatName", "securityIdentifier",
897 const char * const ref_attrs[] = { "nETBIOSName", NULL };
898 struct ldb_context *sam_ctx;
899 struct ldb_message **res1, **res2, **ref_res;
900 struct netr_DomainInfo1 *info1;
901 int ret, ret1, ret2, i;
904 const char *local_domain;
906 status = netr_creds_server_step_check(r->in.computer_name, mem_ctx,
908 r->out.return_authenticator,
910 if (!NT_STATUS_IS_OK(status)) {
914 sam_ctx = samdb_connect(mem_ctx, dce_call->conn->auth_state.session_info);
915 if (sam_ctx == NULL) {
916 return NT_STATUS_INVALID_SYSTEM_SERVICE;
919 /* we need to do two searches. The first will pull our primary
920 domain and the second will pull any trusted domains. Our
921 primary domain is also a "trusted" domain, so we need to
922 put the primary domain into the lists of returned trusts as
924 ret1 = gendb_search(sam_ctx, mem_ctx, NULL, &res1, attrs, "(objectClass=domainDNS)");
926 return NT_STATUS_INTERNAL_DB_CORRUPTION;
929 /* try and find the domain */
930 ret = gendb_search(sam_ctx, mem_ctx, NULL,
932 "(&(objectClass=crossRef)(ncName=%s))",
933 ldb_dn_linearize(mem_ctx, res1[0]->dn));
935 return NT_STATUS_INTERNAL_DB_CORRUPTION;
938 local_domain = samdb_result_string(ref_res[0], "nETBIOSName", NULL);
940 ret2 = gendb_search(sam_ctx, mem_ctx, NULL, &res2, attrs, "(objectClass=trustedDomain)");
942 return NT_STATUS_INTERNAL_DB_CORRUPTION;
945 info1 = talloc(mem_ctx, struct netr_DomainInfo1);
947 return NT_STATUS_NO_MEMORY;
952 info1->num_trusts = ret2 + 1;
953 info1->trusts = talloc_array(mem_ctx, struct netr_DomainTrustInfo,
955 if (info1->trusts == NULL) {
956 return NT_STATUS_NO_MEMORY;
959 status = fill_domain_primary_info(mem_ctx, res1[0], &info1->domaininfo, local_domain);
960 if (!NT_STATUS_IS_OK(status)) {
964 for (i=0;i<ret2;i++) {
965 status = fill_domain_trust_info(mem_ctx, res2[i], &info1->trusts[i], NULL, False);
966 if (!NT_STATUS_IS_OK(status)) {
971 status = fill_domain_trust_info(mem_ctx, res1[0], &info1->trusts[i], local_domain, True);
972 if (!NT_STATUS_IS_OK(status)) {
976 r->out.info.info1 = info1;
984 netr_NETRSERVERPASSWORDGET
986 static WERROR netr_NETRSERVERPASSWORDGET(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
987 struct netr_NETRSERVERPASSWORDGET *r)
989 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
994 netr_NETRLOGONSENDTOSAM
996 static WERROR netr_NETRLOGONSENDTOSAM(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
997 struct netr_NETRLOGONSENDTOSAM *r)
999 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1004 netr_DSRADDRESSTOSITENAMESW
1006 static WERROR netr_DSRADDRESSTOSITENAMESW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1007 struct netr_DSRADDRESSTOSITENAMESW *r)
1009 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1014 netr_DsRGetDCNameEx2
1016 static WERROR netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1017 struct netr_DsRGetDCNameEx2 *r)
1019 const char * const attrs[] = { "dnsDomain", "objectGUID", NULL };
1021 struct ldb_message **res;
1024 ZERO_STRUCT(r->out);
1026 sam_ctx = samdb_connect(mem_ctx, dce_call->conn->auth_state.session_info);
1027 if (sam_ctx == NULL) {
1028 return WERR_DS_SERVICE_UNAVAILABLE;
1031 ret = gendb_search(sam_ctx, mem_ctx, NULL, &res, attrs,
1032 "(&(objectClass=domainDNS)(dnsDomain=%s))",
1035 return WERR_NO_SUCH_DOMAIN;
1038 r->out.info = talloc(mem_ctx, struct netr_DsRGetDCNameInfo);
1043 /* TODO: - return real IP address
1044 * - check all r->in.* parameters (server_unc is ignored by w2k3!)
1046 r->out.info->dc_unc = talloc_asprintf(mem_ctx, "\\\\%s.%s", lp_netbios_name(),lp_realm());
1047 r->out.info->dc_address = talloc_strdup(mem_ctx, "\\\\0.0.0.0");
1048 r->out.info->dc_address_type = 1;
1049 r->out.info->domain_guid = samdb_result_guid(res[0], "objectGUID");
1050 r->out.info->domain_name = samdb_result_string(res[0], "dnsDomain", NULL);
1051 r->out.info->forest_name = samdb_result_string(res[0], "dnsDomain", NULL);
1052 r->out.info->dc_flags = 0xE00001FD;
1053 r->out.info->dc_site_name = talloc_strdup(mem_ctx, "Default-First-Site-Name");
1054 r->out.info->client_site_name = talloc_strdup(mem_ctx, "Default-First-Site-Name");
1062 static WERROR netr_DsRGetDCNameEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1063 struct netr_DsRGetDCNameEx *r)
1065 struct netr_DsRGetDCNameEx2 r2;
1070 r2.in.server_unc = r->in.server_unc;
1071 r2.in.client_account = NULL;
1073 r2.in.domain_guid = r->in.domain_guid;
1074 r2.in.domain_name = r->in.domain_name;
1075 r2.in.site_name = r->in.site_name;
1076 r2.in.flags = r->in.flags;
1079 werr = netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1081 r->out.info = r2.out.info;
1089 static WERROR netr_DsRGetDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1090 struct netr_DsRGetDCName *r)
1092 struct netr_DsRGetDCNameEx2 r2;
1097 r2.in.server_unc = r->in.server_unc;
1098 r2.in.client_account = NULL;
1100 r2.in.domain_name = r->in.domain_name;
1101 r2.in.domain_guid = r->in.domain_guid;
1103 r2.in.site_name = NULL; /* should fill in from site GUID */
1104 r2.in.flags = r->in.flags;
1107 werr = netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1109 r->out.info = r2.out.info;
1115 netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN
1117 static WERROR netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1118 struct netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN *r)
1120 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1125 netr_NETRENUMERATETRUSTEDDOMAINSEX
1127 static WERROR netr_NETRENUMERATETRUSTEDDOMAINSEX(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1128 struct netr_NETRENUMERATETRUSTEDDOMAINSEX *r)
1130 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1135 netr_DSRADDRESSTOSITENAMESEXW
1137 static WERROR netr_DSRADDRESSTOSITENAMESEXW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1138 struct netr_DSRADDRESSTOSITENAMESEXW *r)
1140 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1145 netr_DSRGETDCSITECOVERAGEW
1147 static WERROR netr_DSRGETDCSITECOVERAGEW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1148 struct netr_DSRGETDCSITECOVERAGEW *r)
1150 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1155 netr_DsrEnumerateDomainTrusts
1157 static WERROR netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1158 struct netr_DsrEnumerateDomainTrusts *r)
1160 struct netr_DomainTrust *trusts;
1163 struct ldb_message **dom_res, **ref_res;
1164 const char * const dom_attrs[] = { "dnsDomain", "objectSid", "objectGUID", NULL };
1165 const char * const ref_attrs[] = { "nETBIOSName", NULL };
1167 ZERO_STRUCT(r->out);
1169 sam_ctx = samdb_connect(mem_ctx, dce_call->conn->auth_state.session_info);
1170 if (sam_ctx == NULL) {
1171 return WERR_GENERAL_FAILURE;
1174 ret = gendb_search_dn(sam_ctx, mem_ctx, samdb_base_dn(mem_ctx), &dom_res, dom_attrs);
1176 return WERR_GENERAL_FAILURE;
1180 return WERR_GENERAL_FAILURE;
1183 ret = gendb_search(sam_ctx, mem_ctx, NULL, &ref_res, ref_attrs,
1184 "(&(objectClass=crossRef)(ncName=%s))",
1185 ldb_dn_linearize(mem_ctx, dom_res[0]->dn));
1187 return WERR_GENERAL_FAILURE;
1191 return WERR_GENERAL_FAILURE;
1196 trusts = talloc_array(mem_ctx, struct netr_DomainTrust, ret);
1197 if (trusts == NULL) {
1202 r->out.trusts = trusts;
1204 /* TODO: add filtering by trust_flags, and correct trust_type
1206 trusts[0].netbios_name = samdb_result_string(ref_res[0], "nETBIOSName", NULL);
1207 trusts[0].dns_name = samdb_result_string(dom_res[0], "dnsDomain", NULL);
1208 trusts[0].trust_flags =
1209 NETR_TRUST_FLAG_TREEROOT |
1210 NETR_TRUST_FLAG_IN_FOREST |
1211 NETR_TRUST_FLAG_PRIMARY;
1212 trusts[0].parent_index = 0;
1213 trusts[0].trust_type = 2;
1214 trusts[0].trust_attributes = 0;
1215 trusts[0].sid = samdb_result_dom_sid(mem_ctx, dom_res[0], "objectSid");
1216 trusts[0].guid = samdb_result_guid(dom_res[0], "objectGUID");
1223 netr_DSRDEREGISTERDNSHOSTRECORDS
1225 static WERROR netr_DSRDEREGISTERDNSHOSTRECORDS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1226 struct netr_DSRDEREGISTERDNSHOSTRECORDS *r)
1228 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1233 netr_NETRSERVERTRUSTPASSWORDSGET
1235 static WERROR netr_NETRSERVERTRUSTPASSWORDSGET(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1236 struct netr_NETRSERVERTRUSTPASSWORDSGET *r)
1238 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1243 netr_DSRGETFORESTTRUSTINFORMATION
1245 static WERROR netr_DSRGETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1246 struct netr_DSRGETFORESTTRUSTINFORMATION *r)
1248 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1253 netr_NETRGETFORESTTRUSTINFORMATION
1255 static WERROR netr_NETRGETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1256 struct netr_NETRGETFORESTTRUSTINFORMATION *r)
1258 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1263 netr_NETRSERVERGETTRUSTINFO
1265 static WERROR netr_NETRSERVERGETTRUSTINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1266 struct netr_NETRSERVERGETTRUSTINFO *r)
1268 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1272 /* include the generated boilerplate */
1273 #include "librpc/gen_ndr/ndr_netlogon_s.c"