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_reply.h"
29 #include "dsdb/samdb/samdb.h"
30 #include "rpc_server/samr/proto.h"
31 #include "util/util_ldb.h"
32 #include "libcli/auth/libcli_auth.h"
33 #include "auth/gensec/schannel_state.h"
34 #include "libcli/security/security.h"
35 #include "param/param.h"
37 struct server_pipe_state {
38 struct netr_Credential client_challenge;
39 struct netr_Credential server_challenge;
43 static NTSTATUS dcesrv_netr_ServerReqChallenge(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
44 struct netr_ServerReqChallenge *r)
46 struct server_pipe_state *pipe_state = dce_call->context->private;
48 ZERO_STRUCTP(r->out.credentials);
50 /* destroyed on pipe shutdown */
53 talloc_free(pipe_state);
54 dce_call->context->private = NULL;
57 pipe_state = talloc(dce_call->context, struct server_pipe_state);
58 NT_STATUS_HAVE_NO_MEMORY(pipe_state);
60 pipe_state->client_challenge = *r->in.credentials;
62 generate_random_buffer(pipe_state->server_challenge.data,
63 sizeof(pipe_state->server_challenge.data));
65 *r->out.credentials = pipe_state->server_challenge;
67 dce_call->context->private = pipe_state;
72 static NTSTATUS dcesrv_netr_ServerAuthenticate3(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
73 struct netr_ServerAuthenticate3 *r)
75 struct server_pipe_state *pipe_state = dce_call->context->private;
76 struct creds_CredentialState *creds;
78 struct samr_Password *mach_pwd;
81 struct ldb_message **msgs;
83 const char *attrs[] = {"unicodePwd", "userAccountControl",
86 ZERO_STRUCTP(r->out.credentials);
88 *r->out.negotiate_flags = *r->in.negotiate_flags;
91 DEBUG(1, ("No challenge requested by client, cannot authenticate\n"));
92 return NT_STATUS_ACCESS_DENIED;
95 sam_ctx = samdb_connect(mem_ctx, dce_call->conn->dce_ctx->lp_ctx,
96 system_session(mem_ctx, dce_call->conn->dce_ctx->lp_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], "unicodePwd");
149 if (mach_pwd == NULL) {
150 return NT_STATUS_ACCESS_DENIED;
153 creds = talloc(mem_ctx, struct creds_CredentialState);
154 NT_STATUS_HAVE_NO_MEMORY(creds);
156 creds_server_init(creds, &pipe_state->client_challenge,
157 &pipe_state->server_challenge, mach_pwd,
159 *r->in.negotiate_flags);
161 if (!creds_server_check(creds, r->in.credentials)) {
163 return NT_STATUS_ACCESS_DENIED;
166 creds->account_name = talloc_steal(creds, r->in.account_name);
168 creds->computer_name = talloc_steal(creds, r->in.computer_name);
169 creds->domain = talloc_strdup(creds, lp_workgroup(dce_call->conn->dce_ctx->lp_ctx));
171 creds->secure_channel_type = r->in.secure_channel_type;
173 creds->sid = samdb_result_dom_sid(creds, msgs[0], "objectSid");
176 /* remember this session key state */
177 nt_status = schannel_store_session_key(mem_ctx, dce_call->conn->dce_ctx->lp_ctx, creds);
182 static NTSTATUS dcesrv_netr_ServerAuthenticate(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
183 struct netr_ServerAuthenticate *r)
185 struct netr_ServerAuthenticate3 r3;
188 * negotiate_flags is used as an [in] parameter
189 * so it need to be initialised.
191 * (I think ... = 0; seems wrong here --metze)
193 uint32_t negotiate_flags = 0;
195 r3.in.server_name = r->in.server_name;
196 r3.in.account_name = r->in.account_name;
197 r3.in.secure_channel_type = r->in.secure_channel_type;
198 r3.in.computer_name = r->in.computer_name;
199 r3.in.credentials = r->in.credentials;
200 r3.out.credentials = r->out.credentials;
201 r3.in.negotiate_flags = &negotiate_flags;
202 r3.out.negotiate_flags = &negotiate_flags;
205 return dcesrv_netr_ServerAuthenticate3(dce_call, mem_ctx, &r3);
208 static NTSTATUS dcesrv_netr_ServerAuthenticate2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
209 struct netr_ServerAuthenticate2 *r)
211 struct netr_ServerAuthenticate3 r3;
214 r3.in.server_name = r->in.server_name;
215 r3.in.account_name = r->in.account_name;
216 r3.in.secure_channel_type = r->in.secure_channel_type;
217 r3.in.computer_name = r->in.computer_name;
218 r3.in.credentials = r->in.credentials;
219 r3.out.credentials = r->out.credentials;
220 r3.in.negotiate_flags = r->in.negotiate_flags;
221 r3.out.negotiate_flags = r->out.negotiate_flags;
224 return dcesrv_netr_ServerAuthenticate3(dce_call, mem_ctx, &r3);
228 Validate an incoming authenticator against the credentials for the remote machine.
230 The credentials are (re)read and from the schannel database, and
231 written back after the caclulations are performed.
233 The creds_out parameter (if not NULL) returns the credentials, if
234 the caller needs some of that information.
237 static NTSTATUS dcesrv_netr_creds_server_step_check(struct loadparm_context *lp_ctx,
238 const char *computer_name,
240 struct netr_Authenticator *received_authenticator,
241 struct netr_Authenticator *return_authenticator,
242 struct creds_CredentialState **creds_out)
244 struct creds_CredentialState *creds;
246 struct ldb_context *ldb;
249 ldb = schannel_db_connect(mem_ctx, lp_ctx);
251 return NT_STATUS_ACCESS_DENIED;
254 ret = ldb_transaction_start(ldb);
257 return NT_STATUS_INTERNAL_DB_CORRUPTION;
260 /* Because this is a shared structure (even across
261 * disconnects) we must update the database every time we
262 * update the structure */
264 nt_status = schannel_fetch_session_key_ldb(ldb, ldb, computer_name,
265 lp_workgroup(lp_ctx),
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 dcesrv_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 = dcesrv_netr_creds_server_step_check(dce_call->conn->dce_ctx->lp_ctx,
302 r->in.computer_name, mem_ctx,
303 &r->in.credential, &r->out.return_authenticator,
305 NT_STATUS_NOT_OK_RETURN(nt_status);
307 sam_ctx = samdb_connect(mem_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(mem_ctx, dce_call->conn->dce_ctx->lp_ctx));
308 if (sam_ctx == NULL) {
309 return NT_STATUS_INVALID_SYSTEM_SERVICE;
312 creds_des_decrypt(creds, &r->in.new_password);
314 /* Using the sid for the account as the key, set the password */
315 nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
317 NULL, /* Don't have plaintext */
318 NULL, &r->in.new_password,
319 false, /* This is not considered a password change */
325 Change the machine account password for the currently connected
326 client. Supplies new plaintext.
328 static NTSTATUS dcesrv_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 = dcesrv_netr_creds_server_step_check(dce_call->conn->dce_ctx->lp_ctx,
341 r->in.computer_name, mem_ctx,
342 &r->in.credential, &r->out.return_authenticator,
344 NT_STATUS_NOT_OK_RETURN(nt_status);
346 sam_ctx = samdb_connect(mem_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(mem_ctx, dce_call->conn->dce_ctx->lp_ctx));
347 if (sam_ctx == NULL) {
348 return NT_STATUS_INVALID_SYSTEM_SERVICE;
351 memcpy(password_buf.data, r->in.new_password.data, 512);
352 SIVAL(password_buf.data,512,r->in.new_password.length);
353 creds_arcfour_crypt(creds, password_buf.data, 516);
355 ret = decode_pw_buffer(password_buf.data, new_pass, sizeof(new_pass),
356 &new_pass_len, STR_UNICODE);
358 DEBUG(3,("netr_ServerPasswordSet2: failed to decode password buffer\n"));
359 return NT_STATUS_ACCESS_DENIED;
362 /* Using the sid for the account as the key, set the password */
363 nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
365 new_pass, /* we have plaintext */
367 false, /* This is not considered a password change */
376 static WERROR dcesrv_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 dcesrv_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 dcesrv_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);
414 NT_STATUS_HAVE_NO_MEMORY(user_info);
416 user_info->flags = 0;
417 user_info->mapped_state = false;
418 user_info->remote_host = NULL;
420 switch (r->in.logon_level) {
424 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
425 creds_arcfour_crypt(creds,
426 r->in.logon.password->lmpassword.hash,
427 sizeof(r->in.logon.password->lmpassword.hash));
428 creds_arcfour_crypt(creds,
429 r->in.logon.password->ntpassword.hash,
430 sizeof(r->in.logon.password->ntpassword.hash));
432 creds_des_decrypt(creds, &r->in.logon.password->lmpassword);
433 creds_des_decrypt(creds, &r->in.logon.password->ntpassword);
436 /* TODO: we need to deny anonymous access here */
437 nt_status = auth_context_create(mem_ctx,
438 dce_call->event_ctx, dce_call->msg_ctx,
439 dce_call->conn->dce_ctx->lp_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->flags |= USER_INFO_INTERACTIVE_LOGON;
449 user_info->password_state = AUTH_PASSWORD_HASH;
451 user_info->password.hash.lanman = talloc(user_info, struct samr_Password);
452 NT_STATUS_HAVE_NO_MEMORY(user_info->password.hash.lanman);
453 *user_info->password.hash.lanman = r->in.logon.password->lmpassword;
455 user_info->password.hash.nt = talloc(user_info, struct samr_Password);
456 NT_STATUS_HAVE_NO_MEMORY(user_info->password.hash.nt);
457 *user_info->password.hash.nt = r->in.logon.password->ntpassword;
463 /* TODO: we need to deny anonymous access here */
464 nt_status = auth_context_create(mem_ctx,
465 dce_call->event_ctx, dce_call->msg_ctx,
466 dce_call->conn->dce_ctx->lp_ctx,
468 NT_STATUS_NOT_OK_RETURN(nt_status);
470 nt_status = auth_context_set_challenge(auth_context, r->in.logon.network->challenge, "netr_LogonSamLogonWithFlags");
471 NT_STATUS_NOT_OK_RETURN(nt_status);
473 user_info->logon_parameters = r->in.logon.network->identity_info.parameter_control;
474 user_info->client.account_name = r->in.logon.network->identity_info.account_name.string;
475 user_info->client.domain_name = r->in.logon.network->identity_info.domain_name.string;
476 user_info->workstation_name = r->in.logon.network->identity_info.workstation.string;
478 user_info->password_state = AUTH_PASSWORD_RESPONSE;
479 user_info->password.response.lanman = data_blob_talloc(mem_ctx, r->in.logon.network->lm.data, r->in.logon.network->lm.length);
480 user_info->password.response.nt = data_blob_talloc(mem_ctx, r->in.logon.network->nt.data, r->in.logon.network->nt.length);
484 return NT_STATUS_INVALID_PARAMETER;
487 nt_status = auth_check_password(auth_context, mem_ctx, user_info, &server_info);
488 NT_STATUS_NOT_OK_RETURN(nt_status);
490 nt_status = auth_convert_server_info_sambaseinfo(mem_ctx, server_info, &sam);
491 NT_STATUS_NOT_OK_RETURN(nt_status);
493 /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
494 /* It appears that level 6 is not individually encrypted */
495 if ((r->in.validation_level != 6) &&
496 memcmp(sam->key.key, zeros, sizeof(sam->key.key)) != 0) {
497 /* This key is sent unencrypted without the ARCFOUR flag set */
498 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
499 creds_arcfour_crypt(creds,
501 sizeof(sam->key.key));
505 /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
506 /* It appears that level 6 is not individually encrypted */
507 if ((r->in.validation_level != 6) &&
508 memcmp(sam->LMSessKey.key, zeros, sizeof(sam->LMSessKey.key)) != 0) {
509 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
510 creds_arcfour_crypt(creds,
512 sizeof(sam->LMSessKey.key));
514 creds_des_encrypt_LMKey(creds,
519 switch (r->in.validation_level) {
521 sam2 = talloc_zero(mem_ctx, struct netr_SamInfo2);
522 NT_STATUS_HAVE_NO_MEMORY(sam2);
524 r->out.validation.sam2 = sam2;
528 sam3 = talloc_zero(mem_ctx, struct netr_SamInfo3);
529 NT_STATUS_HAVE_NO_MEMORY(sam3);
531 r->out.validation.sam3 = sam3;
535 sam6 = talloc_zero(mem_ctx, struct netr_SamInfo6);
536 NT_STATUS_HAVE_NO_MEMORY(sam6);
538 sam6->forest.string = lp_realm(dce_call->conn->dce_ctx->lp_ctx);
539 sam6->principle.string = talloc_asprintf(mem_ctx, "%s@%s",
540 sam->account_name.string, sam6->forest.string);
541 NT_STATUS_HAVE_NO_MEMORY(sam6->principle.string);
542 r->out.validation.sam6 = sam6;
549 r->out.authoritative = 1;
551 /* TODO: Describe and deal with these flags */
557 static NTSTATUS dcesrv_netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
558 struct netr_LogonSamLogonEx *r)
561 struct creds_CredentialState *creds;
562 nt_status = schannel_fetch_session_key(mem_ctx, dce_call->conn->dce_ctx->lp_ctx, r->in.computer_name, lp_workgroup(dce_call->conn->dce_ctx->lp_ctx), &creds);
563 if (!NT_STATUS_IS_OK(nt_status)) {
567 if (!dce_call->conn->auth_state.auth_info ||
568 dce_call->conn->auth_state.auth_info->auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
569 return NT_STATUS_INTERNAL_ERROR;
571 return dcesrv_netr_LogonSamLogon_base(dce_call, mem_ctx, r, creds);
575 netr_LogonSamLogonWithFlags
578 static NTSTATUS dcesrv_netr_LogonSamLogonWithFlags(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
579 struct netr_LogonSamLogonWithFlags *r)
582 struct creds_CredentialState *creds;
583 struct netr_LogonSamLogonEx r2;
585 struct netr_Authenticator *return_authenticator;
587 return_authenticator = talloc(mem_ctx, struct netr_Authenticator);
588 NT_STATUS_HAVE_NO_MEMORY(return_authenticator);
590 nt_status = dcesrv_netr_creds_server_step_check(dce_call->conn->dce_ctx->lp_ctx,
591 r->in.computer_name, mem_ctx,
592 r->in.credential, return_authenticator,
594 NT_STATUS_NOT_OK_RETURN(nt_status);
598 r2.in.server_name = r->in.server_name;
599 r2.in.computer_name = r->in.computer_name;
600 r2.in.logon_level = r->in.logon_level;
601 r2.in.logon = r->in.logon;
602 r2.in.validation_level = r->in.validation_level;
603 r2.in.flags = r->in.flags;
605 nt_status = dcesrv_netr_LogonSamLogon_base(dce_call, mem_ctx, &r2, creds);
607 r->out.return_authenticator = return_authenticator;
608 r->out.validation = r2.out.validation;
609 r->out.authoritative = r2.out.authoritative;
610 r->out.flags = r2.out.flags;
618 static NTSTATUS dcesrv_netr_LogonSamLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
619 struct netr_LogonSamLogon *r)
621 struct netr_LogonSamLogonWithFlags r2;
626 r2.in.server_name = r->in.server_name;
627 r2.in.computer_name = r->in.computer_name;
628 r2.in.credential = r->in.credential;
629 r2.in.return_authenticator = r->in.return_authenticator;
630 r2.in.logon_level = r->in.logon_level;
631 r2.in.logon = r->in.logon;
632 r2.in.validation_level = r->in.validation_level;
635 status = dcesrv_netr_LogonSamLogonWithFlags(dce_call, mem_ctx, &r2);
637 r->out.return_authenticator = r2.out.return_authenticator;
638 r->out.validation = r2.out.validation;
639 r->out.authoritative = r2.out.authoritative;
648 static NTSTATUS dcesrv_netr_LogonSamLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
649 struct netr_LogonSamLogoff *r)
651 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
659 static NTSTATUS dcesrv_netr_DatabaseDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
660 struct netr_DatabaseDeltas *r)
662 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
669 static NTSTATUS dcesrv_netr_DatabaseSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
670 struct netr_DatabaseSync *r)
672 /* win2k3 native mode returns "NOT IMPLEMENTED" for this call */
673 return NT_STATUS_NOT_IMPLEMENTED;
680 static NTSTATUS dcesrv_netr_AccountDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
681 struct netr_AccountDeltas *r)
683 /* w2k3 returns "NOT IMPLEMENTED" for this call */
684 return NT_STATUS_NOT_IMPLEMENTED;
691 static NTSTATUS dcesrv_netr_AccountSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
692 struct netr_AccountSync *r)
694 /* w2k3 returns "NOT IMPLEMENTED" for this call */
695 return NT_STATUS_NOT_IMPLEMENTED;
702 static WERROR dcesrv_netr_GetDcName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
703 struct netr_GetDcName *r)
705 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
712 static WERROR dcesrv_netr_LogonControl(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
713 struct netr_LogonControl *r)
715 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
722 static WERROR dcesrv_netr_GetAnyDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
723 struct netr_GetAnyDCName *r)
725 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
732 static WERROR dcesrv_netr_LogonControl2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
733 struct netr_LogonControl2 *r)
735 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
742 static NTSTATUS dcesrv_netr_DatabaseSync2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
743 struct netr_DatabaseSync2 *r)
745 /* win2k3 native mode returns "NOT IMPLEMENTED" for this call */
746 return NT_STATUS_NOT_IMPLEMENTED;
753 static NTSTATUS dcesrv_netr_DatabaseRedo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
754 struct netr_DatabaseRedo *r)
756 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
763 static WERROR dcesrv_netr_LogonControl2Ex(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
764 struct netr_LogonControl2Ex *r)
766 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
771 netr_NetrEnumerateTurstedDomains
773 static WERROR dcesrv_netr_NetrEnumerateTrustedDomains(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
774 struct netr_NetrEnumerateTrustedDomains *r)
776 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
781 netr_NETRLOGONDUMMYROUTINE1
783 static WERROR dcesrv_netr_NETRLOGONDUMMYROUTINE1(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
784 struct netr_NETRLOGONDUMMYROUTINE1 *r)
786 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
791 netr_NETRLOGONSETSERVICEBITS
793 static WERROR dcesrv_netr_NETRLOGONSETSERVICEBITS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
794 struct netr_NETRLOGONSETSERVICEBITS *r)
796 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
801 netr_NETRLOGONGETTRUSTRID
803 static WERROR dcesrv_netr_NETRLOGONGETTRUSTRID(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
804 struct netr_NETRLOGONGETTRUSTRID *r)
806 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
811 netr_NETRLOGONCOMPUTESERVERDIGEST
813 static WERROR dcesrv_netr_NETRLOGONCOMPUTESERVERDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
814 struct netr_NETRLOGONCOMPUTESERVERDIGEST *r)
816 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
821 netr_NETRLOGONCOMPUTECLIENTDIGEST
823 static WERROR dcesrv_netr_NETRLOGONCOMPUTECLIENTDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
824 struct netr_NETRLOGONCOMPUTECLIENTDIGEST *r)
826 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
834 static WERROR dcesrv_netr_DsRGetSiteName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
835 struct netr_DsRGetSiteName *r)
837 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
842 fill in a netr_DomainTrustInfo from a ldb search result
844 static NTSTATUS fill_domain_trust_info(TALLOC_CTX *mem_ctx,
845 struct ldb_message *res,
846 struct ldb_message *ref_res,
847 struct netr_DomainTrustInfo *info,
853 info->domainname.string = samdb_result_string(ref_res, "nETBIOSName", NULL);
854 info->fulldomainname.string = samdb_result_string(ref_res, "dnsRoot", NULL);
855 info->forest.string = NULL;
856 info->guid = samdb_result_guid(res, "objectGUID");
857 info->sid = samdb_result_dom_sid(mem_ctx, res, "objectSid");
859 info->domainname.string = samdb_result_string(res, "flatName", NULL);
860 info->fulldomainname.string = samdb_result_string(res, "trustPartner", NULL);
861 info->forest.string = NULL;
862 info->guid = samdb_result_guid(res, "objectGUID");
863 info->sid = samdb_result_dom_sid(mem_ctx, res, "securityIdentifier");
870 netr_LogonGetDomainInfo
871 this is called as part of the ADS domain logon procedure.
873 It has an important role in convaying details about the client, such
874 as Operating System, Version, Service Pack etc.
876 static NTSTATUS dcesrv_netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
877 struct netr_LogonGetDomainInfo *r)
879 const char * const attrs[] = { "objectSid",
880 "objectGUID", "flatName", "securityIdentifier",
881 "trustPartner", NULL };
882 const char * const ref_attrs[] = { "nETBIOSName", "dnsRoot", NULL };
883 struct ldb_context *sam_ctx;
884 struct ldb_message **res1, **res2, **ref_res;
885 struct netr_DomainInfo1 *info1;
886 int ret, ret1, ret2, i;
888 struct ldb_dn *partitions_basedn;
890 const char *local_domain;
892 status = dcesrv_netr_creds_server_step_check(dce_call->conn->dce_ctx->lp_ctx,
893 r->in.computer_name, mem_ctx,
895 r->out.return_authenticator,
897 NT_STATUS_NOT_OK_RETURN(status);
899 sam_ctx = samdb_connect(mem_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
900 if (sam_ctx == NULL) {
901 return NT_STATUS_INVALID_SYSTEM_SERVICE;
904 partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);
906 /* we need to do two searches. The first will pull our primary
907 domain and the second will pull any trusted domains. Our
908 primary domain is also a "trusted" domain, so we need to
909 put the primary domain into the lists of returned trusts as
911 ret1 = gendb_search_dn(sam_ctx, mem_ctx, samdb_base_dn(sam_ctx), &res1, attrs);
913 return NT_STATUS_INTERNAL_DB_CORRUPTION;
916 /* try and find the domain */
917 ret = gendb_search(sam_ctx, mem_ctx, partitions_basedn,
919 "(&(objectClass=crossRef)(ncName=%s))",
920 ldb_dn_get_linearized(res1[0]->dn));
922 return NT_STATUS_INTERNAL_DB_CORRUPTION;
925 local_domain = samdb_result_string(ref_res[0], "nETBIOSName", NULL);
927 ret2 = gendb_search(sam_ctx, mem_ctx, NULL, &res2, attrs, "(objectClass=trustedDomain)");
929 return NT_STATUS_INTERNAL_DB_CORRUPTION;
932 info1 = talloc(mem_ctx, struct netr_DomainInfo1);
933 NT_STATUS_HAVE_NO_MEMORY(info1);
937 info1->num_trusts = ret2 + 1;
938 info1->trusts = talloc_array(mem_ctx, struct netr_DomainTrustInfo,
940 NT_STATUS_HAVE_NO_MEMORY(info1->trusts);
942 status = fill_domain_trust_info(mem_ctx, res1[0], ref_res[0], &info1->domaininfo, true);
943 NT_STATUS_NOT_OK_RETURN(status);
945 for (i=0;i<ret2;i++) {
946 status = fill_domain_trust_info(mem_ctx, res2[i], NULL, &info1->trusts[i], false);
947 NT_STATUS_NOT_OK_RETURN(status);
950 status = fill_domain_trust_info(mem_ctx, res1[0], ref_res[0], &info1->trusts[i], true);
951 NT_STATUS_NOT_OK_RETURN(status);
953 r->out.info.info1 = info1;
961 netr_ServerPasswordGet
963 static WERROR dcesrv_netr_ServerPasswordGet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
964 struct netr_ServerPasswordGet *r)
966 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
971 netr_NETRLOGONSENDTOSAM
973 static WERROR dcesrv_netr_NETRLOGONSENDTOSAM(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
974 struct netr_NETRLOGONSENDTOSAM *r)
976 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
981 netr_DsRAddressToSitenamesW
983 static WERROR dcesrv_netr_DsRAddressToSitenamesW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
984 struct netr_DsRAddressToSitenamesW *r)
986 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
993 static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
994 struct netr_DsRGetDCNameEx2 *r)
996 const char * const attrs[] = { "dnsDomain", "objectGUID", NULL };
998 struct ldb_message **res;
999 struct ldb_dn *domain_dn;
1002 ZERO_STRUCT(r->out);
1004 sam_ctx = samdb_connect(mem_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
1005 if (sam_ctx == NULL) {
1006 return WERR_DS_SERVICE_UNAVAILABLE;
1009 domain_dn = samdb_dns_domain_to_dn(sam_ctx, mem_ctx,
1011 if (domain_dn == NULL) {
1012 return WERR_DS_SERVICE_UNAVAILABLE;
1015 ret = gendb_search_dn(sam_ctx, mem_ctx, domain_dn, &res, attrs);
1017 return WERR_NO_SUCH_DOMAIN;
1020 r->out.info = talloc(mem_ctx, struct netr_DsRGetDCNameInfo);
1021 W_ERROR_HAVE_NO_MEMORY(r->out.info);
1023 /* TODO: - return real IP address
1024 * - check all r->in.* parameters (server_unc is ignored by w2k3!)
1026 r->out.info->dc_unc = talloc_asprintf(mem_ctx, "\\\\%s.%s",
1027 lp_netbios_name(dce_call->conn->dce_ctx->lp_ctx),
1028 lp_realm(dce_call->conn->dce_ctx->lp_ctx));
1029 W_ERROR_HAVE_NO_MEMORY(r->out.info->dc_unc);
1030 r->out.info->dc_address = talloc_strdup(mem_ctx, "\\\\0.0.0.0");
1031 W_ERROR_HAVE_NO_MEMORY(r->out.info->dc_address);
1032 r->out.info->dc_address_type = DS_ADDRESS_TYPE_INET;
1033 r->out.info->domain_guid = samdb_result_guid(res[0], "objectGUID");
1034 r->out.info->domain_name = samdb_result_string(res[0], "dnsDomain", NULL);
1035 r->out.info->forest_name = samdb_result_string(res[0], "dnsDomain", NULL);
1036 r->out.info->dc_flags = DS_DNS_FOREST |
1039 DS_SERVER_WRITABLE |
1041 DS_SERVER_TIMESERV |
1047 r->out.info->dc_site_name = talloc_strdup(mem_ctx, "Default-First-Site-Name");
1048 W_ERROR_HAVE_NO_MEMORY(r->out.info->dc_site_name);
1049 r->out.info->client_site_name = talloc_strdup(mem_ctx, "Default-First-Site-Name");
1050 W_ERROR_HAVE_NO_MEMORY(r->out.info->client_site_name);
1058 static WERROR dcesrv_netr_DsRGetDCNameEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1059 struct netr_DsRGetDCNameEx *r)
1061 struct netr_DsRGetDCNameEx2 r2;
1066 r2.in.server_unc = r->in.server_unc;
1067 r2.in.client_account = NULL;
1069 r2.in.domain_guid = r->in.domain_guid;
1070 r2.in.domain_name = r->in.domain_name;
1071 r2.in.site_name = r->in.site_name;
1072 r2.in.flags = r->in.flags;
1075 werr = dcesrv_netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1077 r->out.info = r2.out.info;
1085 static WERROR dcesrv_netr_DsRGetDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1086 struct netr_DsRGetDCName *r)
1088 struct netr_DsRGetDCNameEx2 r2;
1093 r2.in.server_unc = r->in.server_unc;
1094 r2.in.client_account = NULL;
1096 r2.in.domain_name = r->in.domain_name;
1097 r2.in.domain_guid = r->in.domain_guid;
1099 r2.in.site_name = NULL; /* should fill in from site GUID */
1100 r2.in.flags = r->in.flags;
1103 werr = dcesrv_netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1105 r->out.info = r2.out.info;
1111 netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN
1113 static WERROR dcesrv_netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1114 struct netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN *r)
1116 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1121 netr_NetrEnumerateTrustedDomainsEx
1123 static WERROR dcesrv_netr_NetrEnumerateTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1124 struct netr_NetrEnumerateTrustedDomainsEx *r)
1126 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1131 netr_DsRAddressToSitenamesExW
1133 static WERROR dcesrv_netr_DsRAddressToSitenamesExW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1134 struct netr_DsRAddressToSitenamesExW *r)
1136 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1141 netr_DsrGetDcSiteCoverageW
1143 static WERROR dcesrv_netr_DsrGetDcSiteCoverageW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1144 struct netr_DsrGetDcSiteCoverageW *r)
1146 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1151 netr_DsrEnumerateDomainTrusts
1153 static WERROR dcesrv_netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1154 struct netr_DsrEnumerateDomainTrusts *r)
1156 struct netr_DomainTrust *trusts;
1159 struct ldb_message **dom_res, **ref_res;
1160 const char * const dom_attrs[] = { "objectSid", "objectGUID", NULL };
1161 const char * const ref_attrs[] = { "nETBIOSName", "dnsRoot", NULL };
1162 struct ldb_dn *partitions_basedn;
1164 ZERO_STRUCT(r->out);
1166 sam_ctx = samdb_connect(mem_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
1167 if (sam_ctx == NULL) {
1168 return WERR_GENERAL_FAILURE;
1171 partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);
1173 ret = gendb_search_dn(sam_ctx, mem_ctx, NULL, &dom_res, dom_attrs);
1175 return WERR_GENERAL_FAILURE;
1178 return WERR_GENERAL_FAILURE;
1181 ret = gendb_search(sam_ctx, mem_ctx, partitions_basedn, &ref_res, ref_attrs,
1182 "(&(objectClass=crossRef)(ncName=%s))",
1183 ldb_dn_get_linearized(dom_res[0]->dn));
1185 return WERR_GENERAL_FAILURE;
1188 return WERR_GENERAL_FAILURE;
1191 trusts = talloc_array(mem_ctx, struct netr_DomainTrust, ret);
1192 W_ERROR_HAVE_NO_MEMORY(trusts);
1195 r->out.trusts = trusts;
1197 /* TODO: add filtering by trust_flags, and correct trust_type
1199 trusts[0].netbios_name = samdb_result_string(ref_res[0], "nETBIOSName", NULL);
1200 trusts[0].dns_name = samdb_result_string(ref_res[0], "dnsRoot", NULL);
1201 trusts[0].trust_flags =
1202 NETR_TRUST_FLAG_TREEROOT |
1203 NETR_TRUST_FLAG_IN_FOREST |
1204 NETR_TRUST_FLAG_PRIMARY;
1205 trusts[0].parent_index = 0;
1206 trusts[0].trust_type = 2;
1207 trusts[0].trust_attributes = 0;
1208 trusts[0].sid = samdb_result_dom_sid(mem_ctx, dom_res[0], "objectSid");
1209 trusts[0].guid = samdb_result_guid(dom_res[0], "objectGUID");
1216 netr_DSRDEREGISTERDNSHOSTRECORDS
1218 static WERROR dcesrv_netr_DSRDEREGISTERDNSHOSTRECORDS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1219 struct netr_DSRDEREGISTERDNSHOSTRECORDS *r)
1221 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1226 netr_ServerTrustPasswordsGet
1228 static NTSTATUS dcesrv_netr_ServerTrustPasswordsGet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1229 struct netr_ServerTrustPasswordsGet *r)
1231 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1236 netr_DsRGetForestTrustInformation
1238 static WERROR dcesrv_netr_DsRGetForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1239 struct netr_DsRGetForestTrustInformation *r)
1241 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1246 netr_GetForestTrustInformation
1248 static WERROR dcesrv_netr_GetForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1249 struct netr_GetForestTrustInformation *r)
1251 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1256 netr_NETRSERVERGETTRUSTINFO
1258 static WERROR dcesrv_netr_NETRSERVERGETTRUSTINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1259 struct netr_NETRSERVERGETTRUSTINFO *r)
1261 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1265 /* include the generated boilerplate */
1266 #include "librpc/gen_ndr/ndr_netlogon_s.c"