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 */
320 Change the machine account password for the currently connected
321 client. Supplies new plaintext.
323 static NTSTATUS dcesrv_netr_ServerPasswordSet2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
324 struct netr_ServerPasswordSet2 *r)
326 struct creds_CredentialState *creds;
327 struct ldb_context *sam_ctx;
330 uint32_t new_pass_len;
333 struct samr_CryptPassword password_buf;
335 nt_status = dcesrv_netr_creds_server_step_check(r->in.computer_name, mem_ctx,
336 &r->in.credential, &r->out.return_authenticator,
338 NT_STATUS_NOT_OK_RETURN(nt_status);
340 sam_ctx = samdb_connect(mem_ctx, system_session(mem_ctx));
341 if (sam_ctx == NULL) {
342 return NT_STATUS_INVALID_SYSTEM_SERVICE;
345 memcpy(password_buf.data, r->in.new_password.data, 512);
346 SIVAL(password_buf.data,512,r->in.new_password.length);
347 creds_arcfour_crypt(creds, password_buf.data, 516);
349 ret = decode_pw_buffer(password_buf.data, new_pass, sizeof(new_pass),
350 &new_pass_len, STR_UNICODE);
352 DEBUG(3,("netr_ServerPasswordSet2: failed to decode password buffer\n"));
353 return NT_STATUS_ACCESS_DENIED;
356 /* Using the sid for the account as the key, set the password */
357 nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
359 new_pass, /* we have plaintext */
361 False, /* This is not considered a password change */
370 static WERROR dcesrv_netr_LogonUasLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
371 struct netr_LogonUasLogon *r)
373 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
380 static WERROR dcesrv_netr_LogonUasLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
381 struct netr_LogonUasLogoff *r)
383 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
388 netr_LogonSamLogon_base
390 This version of the function allows other wrappers to say 'do not check the credentials'
392 We can't do the traditional 'wrapping' format completly, as this function must only run under schannel
394 static NTSTATUS dcesrv_netr_LogonSamLogon_base(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
395 struct netr_LogonSamLogonEx *r, struct creds_CredentialState *creds)
397 struct auth_context *auth_context;
398 struct auth_usersupplied_info *user_info;
399 struct auth_serversupplied_info *server_info;
401 static const char zeros[16];
402 struct netr_SamBaseInfo *sam;
403 struct netr_SamInfo2 *sam2;
404 struct netr_SamInfo3 *sam3;
405 struct netr_SamInfo6 *sam6;
407 user_info = talloc(mem_ctx, struct auth_usersupplied_info);
408 NT_STATUS_HAVE_NO_MEMORY(user_info);
410 user_info->flags = 0;
411 user_info->mapped_state = False;
412 user_info->remote_host = NULL;
414 switch (r->in.logon_level) {
418 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
419 creds_arcfour_crypt(creds,
420 r->in.logon.password->lmpassword.hash,
421 sizeof(r->in.logon.password->lmpassword.hash));
422 creds_arcfour_crypt(creds,
423 r->in.logon.password->ntpassword.hash,
424 sizeof(r->in.logon.password->ntpassword.hash));
426 creds_des_decrypt(creds, &r->in.logon.password->lmpassword);
427 creds_des_decrypt(creds, &r->in.logon.password->ntpassword);
430 /* TODO: we need to deny anonymous access here */
431 nt_status = auth_context_create(mem_ctx,
432 dce_call->event_ctx, dce_call->msg_ctx,
434 NT_STATUS_NOT_OK_RETURN(nt_status);
436 user_info->logon_parameters = r->in.logon.password->identity_info.parameter_control;
437 user_info->client.account_name = r->in.logon.password->identity_info.account_name.string;
438 user_info->client.domain_name = r->in.logon.password->identity_info.domain_name.string;
439 user_info->workstation_name = r->in.logon.password->identity_info.workstation.string;
441 user_info->flags |= USER_INFO_INTERACTIVE_LOGON;
442 user_info->password_state = AUTH_PASSWORD_HASH;
444 user_info->password.hash.lanman = talloc(user_info, struct samr_Password);
445 NT_STATUS_HAVE_NO_MEMORY(user_info->password.hash.lanman);
446 *user_info->password.hash.lanman = r->in.logon.password->lmpassword;
448 user_info->password.hash.nt = talloc(user_info, struct samr_Password);
449 NT_STATUS_HAVE_NO_MEMORY(user_info->password.hash.nt);
450 *user_info->password.hash.nt = r->in.logon.password->ntpassword;
456 /* TODO: we need to deny anonymous access here */
457 nt_status = auth_context_create(mem_ctx,
458 dce_call->event_ctx, dce_call->msg_ctx,
460 NT_STATUS_NOT_OK_RETURN(nt_status);
462 nt_status = auth_context_set_challenge(auth_context, r->in.logon.network->challenge, "netr_LogonSamLogonWithFlags");
463 NT_STATUS_NOT_OK_RETURN(nt_status);
465 user_info->logon_parameters = r->in.logon.network->identity_info.parameter_control;
466 user_info->client.account_name = r->in.logon.network->identity_info.account_name.string;
467 user_info->client.domain_name = r->in.logon.network->identity_info.domain_name.string;
468 user_info->workstation_name = r->in.logon.network->identity_info.workstation.string;
470 user_info->password_state = AUTH_PASSWORD_RESPONSE;
471 user_info->password.response.lanman = data_blob_talloc(mem_ctx, r->in.logon.network->lm.data, r->in.logon.network->lm.length);
472 user_info->password.response.nt = data_blob_talloc(mem_ctx, r->in.logon.network->nt.data, r->in.logon.network->nt.length);
476 return NT_STATUS_INVALID_PARAMETER;
479 nt_status = auth_check_password(auth_context, mem_ctx, user_info, &server_info);
480 NT_STATUS_NOT_OK_RETURN(nt_status);
482 nt_status = auth_convert_server_info_sambaseinfo(mem_ctx, server_info, &sam);
483 NT_STATUS_NOT_OK_RETURN(nt_status);
485 /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
486 /* It appears that level 6 is not individually encrypted */
487 if ((r->in.validation_level != 6) &&
488 memcmp(sam->key.key, zeros, sizeof(sam->key.key)) != 0) {
489 /* This key is sent unencrypted without the ARCFOUR flag set */
490 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
491 creds_arcfour_crypt(creds,
493 sizeof(sam->key.key));
497 /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
498 /* It appears that level 6 is not individually encrypted */
499 if ((r->in.validation_level != 6) &&
500 memcmp(sam->LMSessKey.key, zeros, sizeof(sam->LMSessKey.key)) != 0) {
501 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
502 creds_arcfour_crypt(creds,
504 sizeof(sam->LMSessKey.key));
506 creds_des_encrypt_LMKey(creds,
511 switch (r->in.validation_level) {
513 sam2 = talloc_zero(mem_ctx, struct netr_SamInfo2);
514 NT_STATUS_HAVE_NO_MEMORY(sam2);
516 r->out.validation.sam2 = sam2;
520 sam3 = talloc_zero(mem_ctx, struct netr_SamInfo3);
521 NT_STATUS_HAVE_NO_MEMORY(sam3);
523 r->out.validation.sam3 = sam3;
527 sam6 = talloc_zero(mem_ctx, struct netr_SamInfo6);
528 NT_STATUS_HAVE_NO_MEMORY(sam6);
530 sam6->forest.string = lp_realm();
531 sam6->principle.string = talloc_asprintf(mem_ctx, "%s@%s",
532 sam->account_name.string, sam6->forest.string);
533 NT_STATUS_HAVE_NO_MEMORY(sam6->principle.string);
534 r->out.validation.sam6 = sam6;
541 r->out.authoritative = 1;
543 /* TODO: Describe and deal with these flags */
549 static NTSTATUS dcesrv_netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
550 struct netr_LogonSamLogonEx *r)
553 struct creds_CredentialState *creds;
554 nt_status = schannel_fetch_session_key(mem_ctx, r->in.computer_name, lp_workgroup(), &creds);
555 if (!NT_STATUS_IS_OK(nt_status)) {
559 if (!dce_call->conn->auth_state.auth_info ||
560 dce_call->conn->auth_state.auth_info->auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
561 return NT_STATUS_INTERNAL_ERROR;
563 return dcesrv_netr_LogonSamLogon_base(dce_call, mem_ctx, r, creds);
567 netr_LogonSamLogonWithFlags
570 static NTSTATUS dcesrv_netr_LogonSamLogonWithFlags(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
571 struct netr_LogonSamLogonWithFlags *r)
574 struct creds_CredentialState *creds;
575 struct netr_LogonSamLogonEx r2;
577 struct netr_Authenticator *return_authenticator;
579 return_authenticator = talloc(mem_ctx, struct netr_Authenticator);
580 NT_STATUS_HAVE_NO_MEMORY(return_authenticator);
582 nt_status = dcesrv_netr_creds_server_step_check(r->in.computer_name, mem_ctx,
583 r->in.credential, return_authenticator,
585 NT_STATUS_NOT_OK_RETURN(nt_status);
589 r2.in.server_name = r->in.server_name;
590 r2.in.computer_name = r->in.computer_name;
591 r2.in.logon_level = r->in.logon_level;
592 r2.in.logon = r->in.logon;
593 r2.in.validation_level = r->in.validation_level;
594 r2.in.flags = r->in.flags;
596 nt_status = dcesrv_netr_LogonSamLogon_base(dce_call, mem_ctx, &r2, creds);
598 r->out.return_authenticator = return_authenticator;
599 r->out.validation = r2.out.validation;
600 r->out.authoritative = r2.out.authoritative;
601 r->out.flags = r2.out.flags;
609 static NTSTATUS dcesrv_netr_LogonSamLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
610 struct netr_LogonSamLogon *r)
612 struct netr_LogonSamLogonWithFlags r2;
617 r2.in.server_name = r->in.server_name;
618 r2.in.computer_name = r->in.computer_name;
619 r2.in.credential = r->in.credential;
620 r2.in.return_authenticator = r->in.return_authenticator;
621 r2.in.logon_level = r->in.logon_level;
622 r2.in.logon = r->in.logon;
623 r2.in.validation_level = r->in.validation_level;
626 status = dcesrv_netr_LogonSamLogonWithFlags(dce_call, mem_ctx, &r2);
628 r->out.return_authenticator = r2.out.return_authenticator;
629 r->out.validation = r2.out.validation;
630 r->out.authoritative = r2.out.authoritative;
639 static NTSTATUS dcesrv_netr_LogonSamLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
640 struct netr_LogonSamLogoff *r)
642 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
650 static NTSTATUS dcesrv_netr_DatabaseDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
651 struct netr_DatabaseDeltas *r)
653 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
660 static NTSTATUS dcesrv_netr_DatabaseSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
661 struct netr_DatabaseSync *r)
663 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
670 static NTSTATUS dcesrv_netr_AccountDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
671 struct netr_AccountDeltas *r)
673 /* w2k3 returns "NOT IMPLEMENTED" for this call */
674 return NT_STATUS_NOT_IMPLEMENTED;
681 static NTSTATUS dcesrv_netr_AccountSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
682 struct netr_AccountSync *r)
684 /* w2k3 returns "NOT IMPLEMENTED" for this call */
685 return NT_STATUS_NOT_IMPLEMENTED;
692 static WERROR dcesrv_netr_GetDcName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
693 struct netr_GetDcName *r)
695 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
702 static WERROR dcesrv_netr_LogonControl(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
703 struct netr_LogonControl *r)
705 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
712 static WERROR dcesrv_netr_GetAnyDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
713 struct netr_GetAnyDCName *r)
715 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
722 static WERROR dcesrv_netr_LogonControl2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
723 struct netr_LogonControl2 *r)
725 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
732 static NTSTATUS dcesrv_netr_DatabaseSync2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
733 struct netr_DatabaseSync2 *r)
735 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
742 static NTSTATUS dcesrv_netr_DatabaseRedo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
743 struct netr_DatabaseRedo *r)
745 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
752 static WERROR dcesrv_netr_LogonControl2Ex(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
753 struct netr_LogonControl2Ex *r)
755 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
760 netr_NETRENUMERATETRUSTEDDOMAINS
762 static WERROR dcesrv_netr_NETRENUMERATETRUSTEDDOMAINS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
763 struct netr_NETRENUMERATETRUSTEDDOMAINS *r)
765 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
770 netr_NETRLOGONDUMMYROUTINE1
772 static WERROR dcesrv_netr_NETRLOGONDUMMYROUTINE1(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
773 struct netr_NETRLOGONDUMMYROUTINE1 *r)
775 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
780 netr_NETRLOGONSETSERVICEBITS
782 static WERROR dcesrv_netr_NETRLOGONSETSERVICEBITS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
783 struct netr_NETRLOGONSETSERVICEBITS *r)
785 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
790 netr_NETRLOGONGETTRUSTRID
792 static WERROR dcesrv_netr_NETRLOGONGETTRUSTRID(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
793 struct netr_NETRLOGONGETTRUSTRID *r)
795 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
800 netr_NETRLOGONCOMPUTESERVERDIGEST
802 static WERROR dcesrv_netr_NETRLOGONCOMPUTESERVERDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
803 struct netr_NETRLOGONCOMPUTESERVERDIGEST *r)
805 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
810 netr_NETRLOGONCOMPUTECLIENTDIGEST
812 static WERROR dcesrv_netr_NETRLOGONCOMPUTECLIENTDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
813 struct netr_NETRLOGONCOMPUTECLIENTDIGEST *r)
815 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
823 static WERROR dcesrv_netr_DsRGetSiteName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
824 struct netr_DsRGetSiteName *r)
826 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
831 fill in a netr_DomainTrustInfo from a ldb search result
833 static NTSTATUS fill_domain_trust_info(TALLOC_CTX *mem_ctx,
834 struct ldb_message *res,
835 struct ldb_message *ref_res,
836 struct netr_DomainTrustInfo *info,
842 info->domainname.string = samdb_result_string(ref_res, "nETBIOSName", NULL);
843 info->fulldomainname.string = samdb_result_string(ref_res, "dnsRoot", NULL);
844 info->forest.string = NULL;
845 info->guid = samdb_result_guid(res, "objectGUID");
846 info->sid = samdb_result_dom_sid(mem_ctx, res, "objectSid");
848 info->domainname.string = samdb_result_string(res, "flatName", NULL);
849 info->fulldomainname.string = samdb_result_string(res, "trustPartner", NULL);
850 info->forest.string = NULL;
851 info->guid = samdb_result_guid(res, "objectGUID");
852 info->sid = samdb_result_dom_sid(mem_ctx, res, "securityIdentifier");
859 netr_LogonGetDomainInfo
860 this is called as part of the ADS domain logon procedure.
862 static NTSTATUS dcesrv_netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
863 struct netr_LogonGetDomainInfo *r)
865 const char * const attrs[] = { "objectSid",
866 "objectGUID", "flatName", "securityIdentifier",
867 "trustPartner", NULL };
868 const char * const ref_attrs[] = { "nETBIOSName", "dnsRoot", NULL };
869 struct ldb_context *sam_ctx;
870 struct ldb_message **res1, **res2, **ref_res;
871 struct netr_DomainInfo1 *info1;
872 int ret, ret1, ret2, i;
874 struct ldb_dn *partitions_basedn;
876 const char *local_domain;
878 status = dcesrv_netr_creds_server_step_check(r->in.computer_name, mem_ctx,
880 r->out.return_authenticator,
882 NT_STATUS_NOT_OK_RETURN(status);
884 sam_ctx = samdb_connect(mem_ctx, dce_call->conn->auth_state.session_info);
885 if (sam_ctx == NULL) {
886 return NT_STATUS_INVALID_SYSTEM_SERVICE;
889 partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);
891 /* we need to do two searches. The first will pull our primary
892 domain and the second will pull any trusted domains. Our
893 primary domain is also a "trusted" domain, so we need to
894 put the primary domain into the lists of returned trusts as
896 ret1 = gendb_search_dn(sam_ctx, mem_ctx, samdb_base_dn(sam_ctx), &res1, attrs);
898 return NT_STATUS_INTERNAL_DB_CORRUPTION;
901 /* try and find the domain */
902 ret = gendb_search(sam_ctx, mem_ctx, partitions_basedn,
904 "(&(objectClass=crossRef)(ncName=%s))",
905 ldb_dn_get_linearized(res1[0]->dn));
907 return NT_STATUS_INTERNAL_DB_CORRUPTION;
910 local_domain = samdb_result_string(ref_res[0], "nETBIOSName", NULL);
912 ret2 = gendb_search(sam_ctx, mem_ctx, NULL, &res2, attrs, "(objectClass=trustedDomain)");
914 return NT_STATUS_INTERNAL_DB_CORRUPTION;
917 info1 = talloc(mem_ctx, struct netr_DomainInfo1);
918 NT_STATUS_HAVE_NO_MEMORY(info1);
922 info1->num_trusts = ret2 + 1;
923 info1->trusts = talloc_array(mem_ctx, struct netr_DomainTrustInfo,
925 NT_STATUS_HAVE_NO_MEMORY(info1->trusts);
927 status = fill_domain_trust_info(mem_ctx, res1[0], ref_res[0], &info1->domaininfo, True);
928 NT_STATUS_NOT_OK_RETURN(status);
930 for (i=0;i<ret2;i++) {
931 status = fill_domain_trust_info(mem_ctx, res2[i], NULL, &info1->trusts[i], False);
932 NT_STATUS_NOT_OK_RETURN(status);
935 status = fill_domain_trust_info(mem_ctx, res1[0], ref_res[0], &info1->trusts[i], True);
936 NT_STATUS_NOT_OK_RETURN(status);
938 r->out.info.info1 = info1;
946 netr_NETRSERVERPASSWORDGET
948 static WERROR dcesrv_netr_NETRSERVERPASSWORDGET(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
949 struct netr_NETRSERVERPASSWORDGET *r)
951 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
956 netr_NETRLOGONSENDTOSAM
958 static WERROR dcesrv_netr_NETRLOGONSENDTOSAM(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
959 struct netr_NETRLOGONSENDTOSAM *r)
961 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
966 netr_DSRADDRESSTOSITENAMESW
968 static WERROR dcesrv_netr_DSRADDRESSTOSITENAMESW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
969 struct netr_DSRADDRESSTOSITENAMESW *r)
971 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
978 static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
979 struct netr_DsRGetDCNameEx2 *r)
981 const char * const attrs[] = { "dnsDomain", "objectGUID", NULL };
983 struct ldb_message **res;
988 sam_ctx = samdb_connect(mem_ctx, dce_call->conn->auth_state.session_info);
989 if (sam_ctx == NULL) {
990 return WERR_DS_SERVICE_UNAVAILABLE;
993 ret = gendb_search(sam_ctx, mem_ctx, NULL, &res, attrs,
994 "(&(objectClass=domainDNS)(dnsDomain=%s))",
997 return WERR_NO_SUCH_DOMAIN;
1000 r->out.info = talloc(mem_ctx, struct netr_DsRGetDCNameInfo);
1001 W_ERROR_HAVE_NO_MEMORY(r->out.info);
1003 /* TODO: - return real IP address
1004 * - check all r->in.* parameters (server_unc is ignored by w2k3!)
1006 r->out.info->dc_unc = talloc_asprintf(mem_ctx, "\\\\%s.%s", lp_netbios_name(),lp_realm());
1007 W_ERROR_HAVE_NO_MEMORY(r->out.info->dc_unc);
1008 r->out.info->dc_address = talloc_strdup(mem_ctx, "\\\\0.0.0.0");
1009 W_ERROR_HAVE_NO_MEMORY(r->out.info->dc_address);
1010 r->out.info->dc_address_type = DS_ADDRESS_TYPE_INET;
1011 r->out.info->domain_guid = samdb_result_guid(res[0], "objectGUID");
1012 r->out.info->domain_name = samdb_result_string(res[0], "dnsDomain", NULL);
1013 r->out.info->forest_name = samdb_result_string(res[0], "dnsDomain", NULL);
1014 r->out.info->dc_flags = DS_DNS_FOREST |
1017 DS_SERVER_WRITABLE |
1019 DS_SERVER_TIMESERV |
1025 r->out.info->dc_site_name = talloc_strdup(mem_ctx, "Default-First-Site-Name");
1026 W_ERROR_HAVE_NO_MEMORY(r->out.info->dc_site_name);
1027 r->out.info->client_site_name = talloc_strdup(mem_ctx, "Default-First-Site-Name");
1028 W_ERROR_HAVE_NO_MEMORY(r->out.info->client_site_name);
1036 static WERROR dcesrv_netr_DsRGetDCNameEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1037 struct netr_DsRGetDCNameEx *r)
1039 struct netr_DsRGetDCNameEx2 r2;
1044 r2.in.server_unc = r->in.server_unc;
1045 r2.in.client_account = NULL;
1047 r2.in.domain_guid = r->in.domain_guid;
1048 r2.in.domain_name = r->in.domain_name;
1049 r2.in.site_name = r->in.site_name;
1050 r2.in.flags = r->in.flags;
1053 werr = dcesrv_netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1055 r->out.info = r2.out.info;
1063 static WERROR dcesrv_netr_DsRGetDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1064 struct netr_DsRGetDCName *r)
1066 struct netr_DsRGetDCNameEx2 r2;
1071 r2.in.server_unc = r->in.server_unc;
1072 r2.in.client_account = NULL;
1074 r2.in.domain_name = r->in.domain_name;
1075 r2.in.domain_guid = r->in.domain_guid;
1077 r2.in.site_name = NULL; /* should fill in from site GUID */
1078 r2.in.flags = r->in.flags;
1081 werr = dcesrv_netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1083 r->out.info = r2.out.info;
1089 netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN
1091 static WERROR dcesrv_netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1092 struct netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN *r)
1094 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1099 netr_NETRENUMERATETRUSTEDDOMAINSEX
1101 static WERROR dcesrv_netr_NETRENUMERATETRUSTEDDOMAINSEX(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1102 struct netr_NETRENUMERATETRUSTEDDOMAINSEX *r)
1104 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1109 netr_DSRADDRESSTOSITENAMESEXW
1111 static WERROR dcesrv_netr_DSRADDRESSTOSITENAMESEXW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1112 struct netr_DSRADDRESSTOSITENAMESEXW *r)
1114 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1119 netr_DsrGetDcSiteCoverageW
1121 static WERROR dcesrv_netr_DsrGetDcSiteCoverageW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1122 struct netr_DsrGetDcSiteCoverageW *r)
1124 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1129 netr_DsrEnumerateDomainTrusts
1131 static WERROR dcesrv_netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1132 struct netr_DsrEnumerateDomainTrusts *r)
1134 struct netr_DomainTrust *trusts;
1137 struct ldb_message **dom_res, **ref_res;
1138 const char * const dom_attrs[] = { "objectSid", "objectGUID", NULL };
1139 const char * const ref_attrs[] = { "nETBIOSName", "dnsRoot", NULL };
1140 struct ldb_dn *partitions_basedn;
1142 ZERO_STRUCT(r->out);
1144 sam_ctx = samdb_connect(mem_ctx, dce_call->conn->auth_state.session_info);
1145 if (sam_ctx == NULL) {
1146 return WERR_GENERAL_FAILURE;
1149 partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);
1151 ret = gendb_search_dn(sam_ctx, mem_ctx, NULL, &dom_res, dom_attrs);
1153 return WERR_GENERAL_FAILURE;
1156 return WERR_GENERAL_FAILURE;
1159 ret = gendb_search(sam_ctx, mem_ctx, partitions_basedn, &ref_res, ref_attrs,
1160 "(&(objectClass=crossRef)(ncName=%s))",
1161 ldb_dn_get_linearized(dom_res[0]->dn));
1163 return WERR_GENERAL_FAILURE;
1166 return WERR_GENERAL_FAILURE;
1169 trusts = talloc_array(mem_ctx, struct netr_DomainTrust, ret);
1170 W_ERROR_HAVE_NO_MEMORY(trusts);
1173 r->out.trusts = trusts;
1175 /* TODO: add filtering by trust_flags, and correct trust_type
1177 trusts[0].netbios_name = samdb_result_string(ref_res[0], "nETBIOSName", NULL);
1178 trusts[0].dns_name = samdb_result_string(ref_res[0], "dnsRoot", NULL);
1179 trusts[0].trust_flags =
1180 NETR_TRUST_FLAG_TREEROOT |
1181 NETR_TRUST_FLAG_IN_FOREST |
1182 NETR_TRUST_FLAG_PRIMARY;
1183 trusts[0].parent_index = 0;
1184 trusts[0].trust_type = 2;
1185 trusts[0].trust_attributes = 0;
1186 trusts[0].sid = samdb_result_dom_sid(mem_ctx, dom_res[0], "objectSid");
1187 trusts[0].guid = samdb_result_guid(dom_res[0], "objectGUID");
1194 netr_DSRDEREGISTERDNSHOSTRECORDS
1196 static WERROR dcesrv_netr_DSRDEREGISTERDNSHOSTRECORDS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1197 struct netr_DSRDEREGISTERDNSHOSTRECORDS *r)
1199 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1204 netr_NETRSERVERTRUSTPASSWORDSGET
1206 static WERROR dcesrv_netr_NETRSERVERTRUSTPASSWORDSGET(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1207 struct netr_NETRSERVERTRUSTPASSWORDSGET *r)
1209 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1214 netr_DsRGetForestTrustInformation
1216 static WERROR dcesrv_netr_DsRGetForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1217 struct netr_DsRGetForestTrustInformation *r)
1219 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1224 netr_NETRGETFORESTTRUSTINFORMATION
1226 static WERROR dcesrv_netr_NETRGETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1227 struct netr_NETRGETFORESTTRUSTINFORMATION *r)
1229 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1234 netr_NETRSERVERGETTRUSTINFO
1236 static WERROR dcesrv_netr_NETRSERVERGETTRUSTINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1237 struct netr_NETRSERVERGETTRUSTINFO *r)
1239 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1243 /* include the generated boilerplate */
1244 #include "librpc/gen_ndr/ndr_netlogon_s.c"