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 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
679 static NTSTATUS dcesrv_netr_AccountDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
680 struct netr_AccountDeltas *r)
682 /* w2k3 returns "NOT IMPLEMENTED" for this call */
683 return NT_STATUS_NOT_IMPLEMENTED;
690 static NTSTATUS dcesrv_netr_AccountSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
691 struct netr_AccountSync *r)
693 /* w2k3 returns "NOT IMPLEMENTED" for this call */
694 return NT_STATUS_NOT_IMPLEMENTED;
701 static WERROR dcesrv_netr_GetDcName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
702 struct netr_GetDcName *r)
704 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
711 static WERROR dcesrv_netr_LogonControl(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
712 struct netr_LogonControl *r)
714 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
721 static WERROR dcesrv_netr_GetAnyDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
722 struct netr_GetAnyDCName *r)
724 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
731 static WERROR dcesrv_netr_LogonControl2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
732 struct netr_LogonControl2 *r)
734 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
741 static NTSTATUS dcesrv_netr_DatabaseSync2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
742 struct netr_DatabaseSync2 *r)
744 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
751 static NTSTATUS dcesrv_netr_DatabaseRedo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
752 struct netr_DatabaseRedo *r)
754 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
761 static WERROR dcesrv_netr_LogonControl2Ex(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
762 struct netr_LogonControl2Ex *r)
764 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
769 netr_NetrEnumerateTurstedDomains
771 static WERROR dcesrv_netr_NetrEnumerateTrustedDomains(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
772 struct netr_NetrEnumerateTrustedDomains *r)
774 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
779 netr_NETRLOGONDUMMYROUTINE1
781 static WERROR dcesrv_netr_NETRLOGONDUMMYROUTINE1(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
782 struct netr_NETRLOGONDUMMYROUTINE1 *r)
784 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
789 netr_NETRLOGONSETSERVICEBITS
791 static WERROR dcesrv_netr_NETRLOGONSETSERVICEBITS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
792 struct netr_NETRLOGONSETSERVICEBITS *r)
794 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
799 netr_NETRLOGONGETTRUSTRID
801 static WERROR dcesrv_netr_NETRLOGONGETTRUSTRID(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
802 struct netr_NETRLOGONGETTRUSTRID *r)
804 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
809 netr_NETRLOGONCOMPUTESERVERDIGEST
811 static WERROR dcesrv_netr_NETRLOGONCOMPUTESERVERDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
812 struct netr_NETRLOGONCOMPUTESERVERDIGEST *r)
814 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
819 netr_NETRLOGONCOMPUTECLIENTDIGEST
821 static WERROR dcesrv_netr_NETRLOGONCOMPUTECLIENTDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
822 struct netr_NETRLOGONCOMPUTECLIENTDIGEST *r)
824 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
832 static WERROR dcesrv_netr_DsRGetSiteName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
833 struct netr_DsRGetSiteName *r)
835 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
840 fill in a netr_DomainTrustInfo from a ldb search result
842 static NTSTATUS fill_domain_trust_info(TALLOC_CTX *mem_ctx,
843 struct ldb_message *res,
844 struct ldb_message *ref_res,
845 struct netr_DomainTrustInfo *info,
851 info->domainname.string = samdb_result_string(ref_res, "nETBIOSName", NULL);
852 info->fulldomainname.string = samdb_result_string(ref_res, "dnsRoot", NULL);
853 info->forest.string = NULL;
854 info->guid = samdb_result_guid(res, "objectGUID");
855 info->sid = samdb_result_dom_sid(mem_ctx, res, "objectSid");
857 info->domainname.string = samdb_result_string(res, "flatName", NULL);
858 info->fulldomainname.string = samdb_result_string(res, "trustPartner", NULL);
859 info->forest.string = NULL;
860 info->guid = samdb_result_guid(res, "objectGUID");
861 info->sid = samdb_result_dom_sid(mem_ctx, res, "securityIdentifier");
868 netr_LogonGetDomainInfo
869 this is called as part of the ADS domain logon procedure.
871 static NTSTATUS dcesrv_netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
872 struct netr_LogonGetDomainInfo *r)
874 const char * const attrs[] = { "objectSid",
875 "objectGUID", "flatName", "securityIdentifier",
876 "trustPartner", NULL };
877 const char * const ref_attrs[] = { "nETBIOSName", "dnsRoot", NULL };
878 struct ldb_context *sam_ctx;
879 struct ldb_message **res1, **res2, **ref_res;
880 struct netr_DomainInfo1 *info1;
881 int ret, ret1, ret2, i;
883 struct ldb_dn *partitions_basedn;
885 const char *local_domain;
887 status = dcesrv_netr_creds_server_step_check(dce_call->conn->dce_ctx->lp_ctx,
888 r->in.computer_name, mem_ctx,
890 r->out.return_authenticator,
892 NT_STATUS_NOT_OK_RETURN(status);
894 sam_ctx = samdb_connect(mem_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
895 if (sam_ctx == NULL) {
896 return NT_STATUS_INVALID_SYSTEM_SERVICE;
899 partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);
901 /* we need to do two searches. The first will pull our primary
902 domain and the second will pull any trusted domains. Our
903 primary domain is also a "trusted" domain, so we need to
904 put the primary domain into the lists of returned trusts as
906 ret1 = gendb_search_dn(sam_ctx, mem_ctx, samdb_base_dn(sam_ctx), &res1, attrs);
908 return NT_STATUS_INTERNAL_DB_CORRUPTION;
911 /* try and find the domain */
912 ret = gendb_search(sam_ctx, mem_ctx, partitions_basedn,
914 "(&(objectClass=crossRef)(ncName=%s))",
915 ldb_dn_get_linearized(res1[0]->dn));
917 return NT_STATUS_INTERNAL_DB_CORRUPTION;
920 local_domain = samdb_result_string(ref_res[0], "nETBIOSName", NULL);
922 ret2 = gendb_search(sam_ctx, mem_ctx, NULL, &res2, attrs, "(objectClass=trustedDomain)");
924 return NT_STATUS_INTERNAL_DB_CORRUPTION;
927 info1 = talloc(mem_ctx, struct netr_DomainInfo1);
928 NT_STATUS_HAVE_NO_MEMORY(info1);
932 info1->num_trusts = ret2 + 1;
933 info1->trusts = talloc_array(mem_ctx, struct netr_DomainTrustInfo,
935 NT_STATUS_HAVE_NO_MEMORY(info1->trusts);
937 status = fill_domain_trust_info(mem_ctx, res1[0], ref_res[0], &info1->domaininfo, true);
938 NT_STATUS_NOT_OK_RETURN(status);
940 for (i=0;i<ret2;i++) {
941 status = fill_domain_trust_info(mem_ctx, res2[i], NULL, &info1->trusts[i], false);
942 NT_STATUS_NOT_OK_RETURN(status);
945 status = fill_domain_trust_info(mem_ctx, res1[0], ref_res[0], &info1->trusts[i], true);
946 NT_STATUS_NOT_OK_RETURN(status);
948 r->out.info.info1 = info1;
956 netr_ServerPasswordGet
958 static WERROR dcesrv_netr_ServerPasswordGet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
959 struct netr_ServerPasswordGet *r)
961 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
966 netr_NETRLOGONSENDTOSAM
968 static WERROR dcesrv_netr_NETRLOGONSENDTOSAM(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
969 struct netr_NETRLOGONSENDTOSAM *r)
971 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
976 netr_DsRAddressToSitenamesW
978 static WERROR dcesrv_netr_DsRAddressToSitenamesW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
979 struct netr_DsRAddressToSitenamesW *r)
981 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
988 static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
989 struct netr_DsRGetDCNameEx2 *r)
991 const char * const attrs[] = { "dnsDomain", "objectGUID", NULL };
993 struct ldb_message **res;
994 struct ldb_dn *domain_dn;
999 sam_ctx = samdb_connect(mem_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
1000 if (sam_ctx == NULL) {
1001 return WERR_DS_SERVICE_UNAVAILABLE;
1004 domain_dn = samdb_dns_domain_to_dn(sam_ctx, mem_ctx,
1006 if (domain_dn == NULL) {
1007 return WERR_DS_SERVICE_UNAVAILABLE;
1010 ret = gendb_search_dn(sam_ctx, mem_ctx, domain_dn, &res, attrs);
1012 return WERR_NO_SUCH_DOMAIN;
1015 r->out.info = talloc(mem_ctx, struct netr_DsRGetDCNameInfo);
1016 W_ERROR_HAVE_NO_MEMORY(r->out.info);
1018 /* TODO: - return real IP address
1019 * - check all r->in.* parameters (server_unc is ignored by w2k3!)
1021 r->out.info->dc_unc = talloc_asprintf(mem_ctx, "\\\\%s.%s",
1022 lp_netbios_name(dce_call->conn->dce_ctx->lp_ctx),
1023 lp_realm(dce_call->conn->dce_ctx->lp_ctx));
1024 W_ERROR_HAVE_NO_MEMORY(r->out.info->dc_unc);
1025 r->out.info->dc_address = talloc_strdup(mem_ctx, "\\\\0.0.0.0");
1026 W_ERROR_HAVE_NO_MEMORY(r->out.info->dc_address);
1027 r->out.info->dc_address_type = DS_ADDRESS_TYPE_INET;
1028 r->out.info->domain_guid = samdb_result_guid(res[0], "objectGUID");
1029 r->out.info->domain_name = samdb_result_string(res[0], "dnsDomain", NULL);
1030 r->out.info->forest_name = samdb_result_string(res[0], "dnsDomain", NULL);
1031 r->out.info->dc_flags = DS_DNS_FOREST |
1034 DS_SERVER_WRITABLE |
1036 DS_SERVER_TIMESERV |
1042 r->out.info->dc_site_name = talloc_strdup(mem_ctx, "Default-First-Site-Name");
1043 W_ERROR_HAVE_NO_MEMORY(r->out.info->dc_site_name);
1044 r->out.info->client_site_name = talloc_strdup(mem_ctx, "Default-First-Site-Name");
1045 W_ERROR_HAVE_NO_MEMORY(r->out.info->client_site_name);
1053 static WERROR dcesrv_netr_DsRGetDCNameEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1054 struct netr_DsRGetDCNameEx *r)
1056 struct netr_DsRGetDCNameEx2 r2;
1061 r2.in.server_unc = r->in.server_unc;
1062 r2.in.client_account = NULL;
1064 r2.in.domain_guid = r->in.domain_guid;
1065 r2.in.domain_name = r->in.domain_name;
1066 r2.in.site_name = r->in.site_name;
1067 r2.in.flags = r->in.flags;
1070 werr = dcesrv_netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1072 r->out.info = r2.out.info;
1080 static WERROR dcesrv_netr_DsRGetDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1081 struct netr_DsRGetDCName *r)
1083 struct netr_DsRGetDCNameEx2 r2;
1088 r2.in.server_unc = r->in.server_unc;
1089 r2.in.client_account = NULL;
1091 r2.in.domain_name = r->in.domain_name;
1092 r2.in.domain_guid = r->in.domain_guid;
1094 r2.in.site_name = NULL; /* should fill in from site GUID */
1095 r2.in.flags = r->in.flags;
1098 werr = dcesrv_netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1100 r->out.info = r2.out.info;
1106 netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN
1108 static WERROR dcesrv_netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1109 struct netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN *r)
1111 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1116 netr_NetrEnumerateTrustedDomainsEx
1118 static WERROR dcesrv_netr_NetrEnumerateTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1119 struct netr_NetrEnumerateTrustedDomainsEx *r)
1121 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1126 netr_DsRAddressToSitenamesExW
1128 static WERROR dcesrv_netr_DsRAddressToSitenamesExW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1129 struct netr_DsRAddressToSitenamesExW *r)
1131 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1136 netr_DsrGetDcSiteCoverageW
1138 static WERROR dcesrv_netr_DsrGetDcSiteCoverageW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1139 struct netr_DsrGetDcSiteCoverageW *r)
1141 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1146 netr_DsrEnumerateDomainTrusts
1148 static WERROR dcesrv_netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1149 struct netr_DsrEnumerateDomainTrusts *r)
1151 struct netr_DomainTrust *trusts;
1154 struct ldb_message **dom_res, **ref_res;
1155 const char * const dom_attrs[] = { "objectSid", "objectGUID", NULL };
1156 const char * const ref_attrs[] = { "nETBIOSName", "dnsRoot", NULL };
1157 struct ldb_dn *partitions_basedn;
1159 ZERO_STRUCT(r->out);
1161 sam_ctx = samdb_connect(mem_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
1162 if (sam_ctx == NULL) {
1163 return WERR_GENERAL_FAILURE;
1166 partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);
1168 ret = gendb_search_dn(sam_ctx, mem_ctx, NULL, &dom_res, dom_attrs);
1170 return WERR_GENERAL_FAILURE;
1173 return WERR_GENERAL_FAILURE;
1176 ret = gendb_search(sam_ctx, mem_ctx, partitions_basedn, &ref_res, ref_attrs,
1177 "(&(objectClass=crossRef)(ncName=%s))",
1178 ldb_dn_get_linearized(dom_res[0]->dn));
1180 return WERR_GENERAL_FAILURE;
1183 return WERR_GENERAL_FAILURE;
1186 trusts = talloc_array(mem_ctx, struct netr_DomainTrust, ret);
1187 W_ERROR_HAVE_NO_MEMORY(trusts);
1190 r->out.trusts = trusts;
1192 /* TODO: add filtering by trust_flags, and correct trust_type
1194 trusts[0].netbios_name = samdb_result_string(ref_res[0], "nETBIOSName", NULL);
1195 trusts[0].dns_name = samdb_result_string(ref_res[0], "dnsRoot", NULL);
1196 trusts[0].trust_flags =
1197 NETR_TRUST_FLAG_TREEROOT |
1198 NETR_TRUST_FLAG_IN_FOREST |
1199 NETR_TRUST_FLAG_PRIMARY;
1200 trusts[0].parent_index = 0;
1201 trusts[0].trust_type = 2;
1202 trusts[0].trust_attributes = 0;
1203 trusts[0].sid = samdb_result_dom_sid(mem_ctx, dom_res[0], "objectSid");
1204 trusts[0].guid = samdb_result_guid(dom_res[0], "objectGUID");
1211 netr_DSRDEREGISTERDNSHOSTRECORDS
1213 static WERROR dcesrv_netr_DSRDEREGISTERDNSHOSTRECORDS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1214 struct netr_DSRDEREGISTERDNSHOSTRECORDS *r)
1216 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1221 netr_ServerTrustPasswordsGet
1223 static NTSTATUS dcesrv_netr_ServerTrustPasswordsGet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1224 struct netr_ServerTrustPasswordsGet *r)
1226 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1231 netr_DsRGetForestTrustInformation
1233 static WERROR dcesrv_netr_DsRGetForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1234 struct netr_DsRGetForestTrustInformation *r)
1236 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1241 netr_GetForestTrustInformation
1243 static WERROR dcesrv_netr_GetForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1244 struct netr_GetForestTrustInformation *r)
1246 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1251 netr_NETRSERVERGETTRUSTINFO
1253 static WERROR dcesrv_netr_NETRSERVERGETTRUSTINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1254 struct netr_NETRSERVERGETTRUSTINFO *r)
1256 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1260 /* include the generated boilerplate */
1261 #include "librpc/gen_ndr/ndr_netlogon_s.c"