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"
36 struct server_pipe_state {
37 struct netr_Credential client_challenge;
38 struct netr_Credential server_challenge;
42 static NTSTATUS dcesrv_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);
57 NT_STATUS_HAVE_NO_MEMORY(pipe_state);
59 pipe_state->client_challenge = *r->in.credentials;
61 generate_random_buffer(pipe_state->server_challenge.data,
62 sizeof(pipe_state->server_challenge.data));
64 *r->out.credentials = pipe_state->server_challenge;
66 dce_call->context->private = pipe_state;
71 static NTSTATUS dcesrv_netr_ServerAuthenticate3(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
72 struct netr_ServerAuthenticate3 *r)
74 struct server_pipe_state *pipe_state = dce_call->context->private;
75 struct creds_CredentialState *creds;
77 struct samr_Password *mach_pwd;
80 struct ldb_message **msgs;
82 const char *attrs[] = {"unicodePwd", "userAccountControl",
85 ZERO_STRUCTP(r->out.credentials);
87 *r->out.negotiate_flags = *r->in.negotiate_flags;
90 DEBUG(1, ("No challenge requested by client, cannot authenticate\n"));
91 return NT_STATUS_ACCESS_DENIED;
94 sam_ctx = samdb_connect(mem_ctx, system_session(mem_ctx));
95 if (sam_ctx == NULL) {
96 return NT_STATUS_INVALID_SYSTEM_SERVICE;
98 /* pull the user attributes */
99 num_records = gendb_search(sam_ctx, mem_ctx, NULL, &msgs, attrs,
100 "(&(sAMAccountName=%s)(objectclass=user))",
103 if (num_records == 0) {
104 DEBUG(3,("Couldn't find user [%s] in samdb.\n",
105 r->in.account_name));
106 return NT_STATUS_ACCESS_DENIED;
109 if (num_records > 1) {
110 DEBUG(0,("Found %d records matching user [%s]\n", num_records, r->in.account_name));
111 return NT_STATUS_INTERNAL_DB_CORRUPTION;
114 acct_flags = samdb_result_acct_flags(msgs[0],
115 "userAccountControl");
117 if (acct_flags & ACB_DISABLED) {
118 DEBUG(1, ("Account [%s] is disabled\n", r->in.account_name));
119 return NT_STATUS_ACCESS_DENIED;
122 if (r->in.secure_channel_type == SEC_CHAN_WKSTA) {
123 if (!(acct_flags & ACB_WSTRUST)) {
124 DEBUG(1, ("Client asked for a workstation secure channel, but is not a workstation (member server) acb flags: 0x%x\n", acct_flags));
125 return NT_STATUS_ACCESS_DENIED;
127 } else if (r->in.secure_channel_type == SEC_CHAN_DOMAIN) {
128 if (!(acct_flags & ACB_DOMTRUST)) {
129 DEBUG(1, ("Client asked for a trusted domain secure channel, but is not a trusted domain: acb flags: 0x%x\n", acct_flags));
130 return NT_STATUS_ACCESS_DENIED;
132 } else if (r->in.secure_channel_type == SEC_CHAN_BDC) {
133 if (!(acct_flags & ACB_SVRTRUST)) {
134 DEBUG(1, ("Client asked for a server secure channel, but is not a server (domain controller): acb flags: 0x%x\n", acct_flags));
135 return NT_STATUS_ACCESS_DENIED;
138 DEBUG(1, ("Client asked for an invalid secure channel type: %d\n",
139 r->in.secure_channel_type));
140 return NT_STATUS_ACCESS_DENIED;
143 *r->out.rid = samdb_result_rid_from_sid(mem_ctx, msgs[0],
146 mach_pwd = samdb_result_hash(mem_ctx, msgs[0], "unicodePwd");
147 if (mach_pwd == NULL) {
148 return NT_STATUS_ACCESS_DENIED;
151 creds = talloc(mem_ctx, struct creds_CredentialState);
152 NT_STATUS_HAVE_NO_MEMORY(creds);
154 creds_server_init(creds, &pipe_state->client_challenge,
155 &pipe_state->server_challenge, mach_pwd,
157 *r->in.negotiate_flags);
159 if (!creds_server_check(creds, r->in.credentials)) {
161 return NT_STATUS_ACCESS_DENIED;
164 creds->account_name = talloc_steal(creds, r->in.account_name);
166 creds->computer_name = talloc_steal(creds, r->in.computer_name);
167 creds->domain = talloc_strdup(creds, lp_workgroup());
169 creds->secure_channel_type = r->in.secure_channel_type;
171 creds->sid = samdb_result_dom_sid(creds, msgs[0], "objectSid");
174 /* remember this session key state */
175 nt_status = schannel_store_session_key(mem_ctx, creds);
180 static NTSTATUS dcesrv_netr_ServerAuthenticate(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
181 struct netr_ServerAuthenticate *r)
183 struct netr_ServerAuthenticate3 r3;
186 * negotiate_flags is used as an [in] parameter
187 * so it need to be initialised.
189 * (I think ... = 0; seems wrong here --metze)
191 uint32_t negotiate_flags = 0;
193 r3.in.server_name = r->in.server_name;
194 r3.in.account_name = r->in.account_name;
195 r3.in.secure_channel_type = r->in.secure_channel_type;
196 r3.in.computer_name = r->in.computer_name;
197 r3.in.credentials = r->in.credentials;
198 r3.out.credentials = r->out.credentials;
199 r3.in.negotiate_flags = &negotiate_flags;
200 r3.out.negotiate_flags = &negotiate_flags;
203 return dcesrv_netr_ServerAuthenticate3(dce_call, mem_ctx, &r3);
206 static NTSTATUS dcesrv_netr_ServerAuthenticate2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
207 struct netr_ServerAuthenticate2 *r)
209 struct netr_ServerAuthenticate3 r3;
212 r3.in.server_name = r->in.server_name;
213 r3.in.account_name = r->in.account_name;
214 r3.in.secure_channel_type = r->in.secure_channel_type;
215 r3.in.computer_name = r->in.computer_name;
216 r3.in.credentials = r->in.credentials;
217 r3.out.credentials = r->out.credentials;
218 r3.in.negotiate_flags = r->in.negotiate_flags;
219 r3.out.negotiate_flags = r->out.negotiate_flags;
222 return dcesrv_netr_ServerAuthenticate3(dce_call, mem_ctx, &r3);
226 Validate an incoming authenticator against the credentials for the remote machine.
228 The credentials are (re)read and from the schannel database, and
229 written back after the caclulations are performed.
231 The creds_out parameter (if not NULL) returns the credentials, if
232 the caller needs some of that information.
235 static NTSTATUS dcesrv_netr_creds_server_step_check(const char *computer_name,
237 struct netr_Authenticator *received_authenticator,
238 struct netr_Authenticator *return_authenticator,
239 struct creds_CredentialState **creds_out)
241 struct creds_CredentialState *creds;
243 struct ldb_context *ldb;
246 ldb = schannel_db_connect(mem_ctx);
248 return NT_STATUS_ACCESS_DENIED;
251 ret = ldb_transaction_start(ldb);
254 return NT_STATUS_INTERNAL_DB_CORRUPTION;
257 /* Because this is a shared structure (even across
258 * disconnects) we must update the database every time we
259 * update the structure */
261 nt_status = schannel_fetch_session_key_ldb(ldb, ldb, computer_name, lp_workgroup(),
263 if (NT_STATUS_IS_OK(nt_status)) {
264 nt_status = creds_server_step_check(creds,
265 received_authenticator,
266 return_authenticator);
268 if (NT_STATUS_IS_OK(nt_status)) {
269 nt_status = schannel_store_session_key_ldb(ldb, ldb, creds);
272 if (NT_STATUS_IS_OK(nt_status)) {
273 ldb_transaction_commit(ldb);
276 talloc_steal(mem_ctx, creds);
279 ldb_transaction_cancel(ldb);
286 Change the machine account password for the currently connected
287 client. Supplies only the NT#.
290 static NTSTATUS dcesrv_netr_ServerPasswordSet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
291 struct netr_ServerPasswordSet *r)
293 struct creds_CredentialState *creds;
294 struct ldb_context *sam_ctx;
297 nt_status = dcesrv_netr_creds_server_step_check(r->in.computer_name, mem_ctx,
298 &r->in.credential, &r->out.return_authenticator,
300 NT_STATUS_NOT_OK_RETURN(nt_status);
302 sam_ctx = samdb_connect(mem_ctx, system_session(mem_ctx));
303 if (sam_ctx == NULL) {
304 return NT_STATUS_INVALID_SYSTEM_SERVICE;
307 creds_des_decrypt(creds, &r->in.new_password);
309 /* Using the sid for the account as the key, set the password */
310 nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
312 NULL, /* Don't have plaintext */
313 NULL, &r->in.new_password,
314 False, /* This is not considered a password change */
315 False, /* don't restrict this password change (match w2k3) */
321 Change the machine account password for the currently connected
322 client. Supplies new plaintext.
324 static NTSTATUS dcesrv_netr_ServerPasswordSet2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
325 struct netr_ServerPasswordSet2 *r)
327 struct creds_CredentialState *creds;
328 struct ldb_context *sam_ctx;
331 uint32_t new_pass_len;
334 struct samr_CryptPassword password_buf;
336 nt_status = dcesrv_netr_creds_server_step_check(r->in.computer_name, mem_ctx,
337 &r->in.credential, &r->out.return_authenticator,
339 NT_STATUS_NOT_OK_RETURN(nt_status);
341 sam_ctx = samdb_connect(mem_ctx, system_session(mem_ctx));
342 if (sam_ctx == NULL) {
343 return NT_STATUS_INVALID_SYSTEM_SERVICE;
346 memcpy(password_buf.data, r->in.new_password.data, 512);
347 SIVAL(password_buf.data,512,r->in.new_password.length);
348 creds_arcfour_crypt(creds, password_buf.data, 516);
350 ret = decode_pw_buffer(password_buf.data, new_pass, sizeof(new_pass),
351 &new_pass_len, STR_UNICODE);
353 DEBUG(3,("netr_ServerPasswordSet2: failed to decode password buffer\n"));
354 return NT_STATUS_ACCESS_DENIED;
357 /* Using the sid for the account as the key, set the password */
358 nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
360 new_pass, /* we have plaintext */
362 False, /* This is not considered a password change */
363 False, /* don't restrict this password change (match w2k3) */
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();
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(), &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", lp_netbios_name(),lp_realm());
1009 W_ERROR_HAVE_NO_MEMORY(r->out.info->dc_unc);
1010 r->out.info->dc_address = talloc_strdup(mem_ctx, "\\\\0.0.0.0");
1011 W_ERROR_HAVE_NO_MEMORY(r->out.info->dc_address);
1012 r->out.info->dc_address_type = DS_ADDRESS_TYPE_INET;
1013 r->out.info->domain_guid = samdb_result_guid(res[0], "objectGUID");
1014 r->out.info->domain_name = samdb_result_string(res[0], "dnsDomain", NULL);
1015 r->out.info->forest_name = samdb_result_string(res[0], "dnsDomain", NULL);
1016 r->out.info->dc_flags = DS_DNS_FOREST |
1019 DS_SERVER_WRITABLE |
1021 DS_SERVER_TIMESERV |
1027 r->out.info->dc_site_name = talloc_strdup(mem_ctx, "Default-First-Site-Name");
1028 W_ERROR_HAVE_NO_MEMORY(r->out.info->dc_site_name);
1029 r->out.info->client_site_name = talloc_strdup(mem_ctx, "Default-First-Site-Name");
1030 W_ERROR_HAVE_NO_MEMORY(r->out.info->client_site_name);
1038 static WERROR dcesrv_netr_DsRGetDCNameEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1039 struct netr_DsRGetDCNameEx *r)
1041 struct netr_DsRGetDCNameEx2 r2;
1046 r2.in.server_unc = r->in.server_unc;
1047 r2.in.client_account = NULL;
1049 r2.in.domain_guid = r->in.domain_guid;
1050 r2.in.domain_name = r->in.domain_name;
1051 r2.in.site_name = r->in.site_name;
1052 r2.in.flags = r->in.flags;
1055 werr = dcesrv_netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1057 r->out.info = r2.out.info;
1065 static WERROR dcesrv_netr_DsRGetDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1066 struct netr_DsRGetDCName *r)
1068 struct netr_DsRGetDCNameEx2 r2;
1073 r2.in.server_unc = r->in.server_unc;
1074 r2.in.client_account = NULL;
1076 r2.in.domain_name = r->in.domain_name;
1077 r2.in.domain_guid = r->in.domain_guid;
1079 r2.in.site_name = NULL; /* should fill in from site GUID */
1080 r2.in.flags = r->in.flags;
1083 werr = dcesrv_netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1085 r->out.info = r2.out.info;
1091 netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN
1093 static WERROR dcesrv_netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1094 struct netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN *r)
1096 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1101 netr_NETRENUMERATETRUSTEDDOMAINSEX
1103 static WERROR dcesrv_netr_NETRENUMERATETRUSTEDDOMAINSEX(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1104 struct netr_NETRENUMERATETRUSTEDDOMAINSEX *r)
1106 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1111 netr_DSRADDRESSTOSITENAMESEXW
1113 static WERROR dcesrv_netr_DSRADDRESSTOSITENAMESEXW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1114 struct netr_DSRADDRESSTOSITENAMESEXW *r)
1116 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1121 netr_DsrGetDcSiteCoverageW
1123 static WERROR dcesrv_netr_DsrGetDcSiteCoverageW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1124 struct netr_DsrGetDcSiteCoverageW *r)
1126 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1131 netr_DsrEnumerateDomainTrusts
1133 static WERROR dcesrv_netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1134 struct netr_DsrEnumerateDomainTrusts *r)
1136 struct netr_DomainTrust *trusts;
1139 struct ldb_message **dom_res, **ref_res;
1140 const char * const dom_attrs[] = { "objectSid", "objectGUID", NULL };
1141 const char * const ref_attrs[] = { "nETBIOSName", "dnsRoot", NULL };
1142 struct ldb_dn *partitions_basedn;
1144 ZERO_STRUCT(r->out);
1146 sam_ctx = samdb_connect(mem_ctx, dce_call->conn->auth_state.session_info);
1147 if (sam_ctx == NULL) {
1148 return WERR_GENERAL_FAILURE;
1151 partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);
1153 ret = gendb_search_dn(sam_ctx, mem_ctx, NULL, &dom_res, dom_attrs);
1155 return WERR_GENERAL_FAILURE;
1158 return WERR_GENERAL_FAILURE;
1161 ret = gendb_search(sam_ctx, mem_ctx, partitions_basedn, &ref_res, ref_attrs,
1162 "(&(objectClass=crossRef)(ncName=%s))",
1163 ldb_dn_get_linearized(dom_res[0]->dn));
1165 return WERR_GENERAL_FAILURE;
1168 return WERR_GENERAL_FAILURE;
1171 trusts = talloc_array(mem_ctx, struct netr_DomainTrust, ret);
1172 W_ERROR_HAVE_NO_MEMORY(trusts);
1175 r->out.trusts = trusts;
1177 /* TODO: add filtering by trust_flags, and correct trust_type
1179 trusts[0].netbios_name = samdb_result_string(ref_res[0], "nETBIOSName", NULL);
1180 trusts[0].dns_name = samdb_result_string(ref_res[0], "dnsRoot", NULL);
1181 trusts[0].trust_flags =
1182 NETR_TRUST_FLAG_TREEROOT |
1183 NETR_TRUST_FLAG_IN_FOREST |
1184 NETR_TRUST_FLAG_PRIMARY;
1185 trusts[0].parent_index = 0;
1186 trusts[0].trust_type = 2;
1187 trusts[0].trust_attributes = 0;
1188 trusts[0].sid = samdb_result_dom_sid(mem_ctx, dom_res[0], "objectSid");
1189 trusts[0].guid = samdb_result_guid(dom_res[0], "objectGUID");
1196 netr_DSRDEREGISTERDNSHOSTRECORDS
1198 static WERROR dcesrv_netr_DSRDEREGISTERDNSHOSTRECORDS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1199 struct netr_DSRDEREGISTERDNSHOSTRECORDS *r)
1201 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1206 netr_NETRSERVERTRUSTPASSWORDSGET
1208 static WERROR dcesrv_netr_NETRSERVERTRUSTPASSWORDSGET(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1209 struct netr_NETRSERVERTRUSTPASSWORDSGET *r)
1211 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1216 netr_DsRGetForestTrustInformation
1218 static WERROR dcesrv_netr_DsRGetForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1219 struct netr_DsRGetForestTrustInformation *r)
1221 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1226 netr_NETRGETFORESTTRUSTINFORMATION
1228 static WERROR dcesrv_netr_NETRGETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1229 struct netr_NETRGETFORESTTRUSTINFORMATION *r)
1231 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1236 netr_NETRSERVERGETTRUSTINFO
1238 static WERROR dcesrv_netr_NETRSERVERGETTRUSTINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1239 struct netr_NETRSERVERGETTRUSTINFO *r)
1241 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1245 /* include the generated boilerplate */
1246 #include "librpc/gen_ndr/ndr_netlogon_s.c"