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 "dsdb/common/flags.h"
31 #include "rpc_server/samr/proto.h"
32 #include "util/util_ldb.h"
33 #include "libcli/auth/libcli_auth.h"
34 #include "auth/gensec/schannel_state.h"
35 #include "libcli/security/security.h"
36 #include "param/param.h"
38 struct server_pipe_state {
39 struct netr_Credential client_challenge;
40 struct netr_Credential server_challenge;
44 static NTSTATUS dcesrv_netr_ServerReqChallenge(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
45 struct netr_ServerReqChallenge *r)
47 struct server_pipe_state *pipe_state = dce_call->context->private;
49 ZERO_STRUCTP(r->out.credentials);
51 /* destroyed on pipe shutdown */
54 talloc_free(pipe_state);
55 dce_call->context->private = NULL;
58 pipe_state = talloc(dce_call->context, struct server_pipe_state);
59 NT_STATUS_HAVE_NO_MEMORY(pipe_state);
61 pipe_state->client_challenge = *r->in.credentials;
63 generate_random_buffer(pipe_state->server_challenge.data,
64 sizeof(pipe_state->server_challenge.data));
66 *r->out.credentials = pipe_state->server_challenge;
68 dce_call->context->private = pipe_state;
73 static NTSTATUS dcesrv_netr_ServerAuthenticate3(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
74 struct netr_ServerAuthenticate3 *r)
76 struct server_pipe_state *pipe_state = dce_call->context->private;
77 struct creds_CredentialState *creds;
79 struct samr_Password *mach_pwd;
80 uint32_t user_account_control;
82 struct ldb_message **msgs;
84 const char *attrs[] = {"unicodePwd", "userAccountControl",
87 ZERO_STRUCTP(r->out.credentials);
89 *r->out.negotiate_flags = *r->in.negotiate_flags;
92 DEBUG(1, ("No challenge requested by client, cannot authenticate\n"));
93 return NT_STATUS_ACCESS_DENIED;
96 sam_ctx = samdb_connect(mem_ctx, dce_call->conn->dce_ctx->lp_ctx,
97 system_session(mem_ctx, dce_call->conn->dce_ctx->lp_ctx));
98 if (sam_ctx == NULL) {
99 return NT_STATUS_INVALID_SYSTEM_SERVICE;
101 /* pull the user attributes */
102 num_records = gendb_search(sam_ctx, mem_ctx, NULL, &msgs, attrs,
103 "(&(sAMAccountName=%s)(objectclass=user))",
106 if (num_records == 0) {
107 DEBUG(3,("Couldn't find user [%s] in samdb.\n",
108 r->in.account_name));
109 return NT_STATUS_ACCESS_DENIED;
112 if (num_records > 1) {
113 DEBUG(0,("Found %d records matching user [%s]\n", num_records, r->in.account_name));
114 return NT_STATUS_INTERNAL_DB_CORRUPTION;
118 user_account_control = ldb_msg_find_attr_as_uint(msgs[0], "userAccountControl", 0);
120 if (user_account_control & UF_ACCOUNTDISABLE) {
121 DEBUG(1, ("Account [%s] is disabled\n", r->in.account_name));
122 return NT_STATUS_ACCESS_DENIED;
125 if (r->in.secure_channel_type == SEC_CHAN_WKSTA) {
126 if (!(user_account_control & UF_WORKSTATION_TRUST_ACCOUNT)) {
127 DEBUG(1, ("Client asked for a workstation secure channel, but is not a workstation (member server) acb flags: 0x%x\n", user_account_control));
128 return NT_STATUS_ACCESS_DENIED;
130 } else if (r->in.secure_channel_type == SEC_CHAN_DOMAIN) {
131 if (!(user_account_control & UF_INTERDOMAIN_TRUST_ACCOUNT)) {
132 DEBUG(1, ("Client asked for a trusted domain secure channel, but is not a trusted domain: acb flags: 0x%x\n", user_account_control));
134 return NT_STATUS_ACCESS_DENIED;
136 } else if (r->in.secure_channel_type == SEC_CHAN_BDC) {
137 if (!(user_account_control & UF_SERVER_TRUST_ACCOUNT)) {
138 DEBUG(1, ("Client asked for a server secure channel, but is not a server (domain controller): acb flags: 0x%x\n", user_account_control));
139 return NT_STATUS_ACCESS_DENIED;
142 DEBUG(1, ("Client asked for an invalid secure channel type: %d\n",
143 r->in.secure_channel_type));
144 return NT_STATUS_ACCESS_DENIED;
147 *r->out.rid = samdb_result_rid_from_sid(mem_ctx, msgs[0],
150 mach_pwd = samdb_result_hash(mem_ctx, msgs[0], "unicodePwd");
151 if (mach_pwd == NULL) {
152 return NT_STATUS_ACCESS_DENIED;
155 creds = talloc(mem_ctx, struct creds_CredentialState);
156 NT_STATUS_HAVE_NO_MEMORY(creds);
158 creds_server_init(creds, &pipe_state->client_challenge,
159 &pipe_state->server_challenge, mach_pwd,
161 *r->in.negotiate_flags);
163 if (!creds_server_check(creds, r->in.credentials)) {
165 return NT_STATUS_ACCESS_DENIED;
168 creds->account_name = talloc_steal(creds, r->in.account_name);
170 creds->computer_name = talloc_steal(creds, r->in.computer_name);
171 creds->domain = talloc_strdup(creds, lp_workgroup(dce_call->conn->dce_ctx->lp_ctx));
173 creds->secure_channel_type = r->in.secure_channel_type;
175 creds->sid = samdb_result_dom_sid(creds, msgs[0], "objectSid");
178 /* remember this session key state */
179 nt_status = schannel_store_session_key(mem_ctx, dce_call->conn->dce_ctx->lp_ctx, creds);
184 static NTSTATUS dcesrv_netr_ServerAuthenticate(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
185 struct netr_ServerAuthenticate *r)
187 struct netr_ServerAuthenticate3 r3;
190 * negotiate_flags is used as an [in] parameter
191 * so it need to be initialised.
193 * (I think ... = 0; seems wrong here --metze)
195 uint32_t negotiate_flags = 0;
197 r3.in.server_name = r->in.server_name;
198 r3.in.account_name = r->in.account_name;
199 r3.in.secure_channel_type = r->in.secure_channel_type;
200 r3.in.computer_name = r->in.computer_name;
201 r3.in.credentials = r->in.credentials;
202 r3.out.credentials = r->out.credentials;
203 r3.in.negotiate_flags = &negotiate_flags;
204 r3.out.negotiate_flags = &negotiate_flags;
207 return dcesrv_netr_ServerAuthenticate3(dce_call, mem_ctx, &r3);
210 static NTSTATUS dcesrv_netr_ServerAuthenticate2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
211 struct netr_ServerAuthenticate2 *r)
213 struct netr_ServerAuthenticate3 r3;
216 r3.in.server_name = r->in.server_name;
217 r3.in.account_name = r->in.account_name;
218 r3.in.secure_channel_type = r->in.secure_channel_type;
219 r3.in.computer_name = r->in.computer_name;
220 r3.in.credentials = r->in.credentials;
221 r3.out.credentials = r->out.credentials;
222 r3.in.negotiate_flags = r->in.negotiate_flags;
223 r3.out.negotiate_flags = r->out.negotiate_flags;
226 return dcesrv_netr_ServerAuthenticate3(dce_call, mem_ctx, &r3);
230 Validate an incoming authenticator against the credentials for the remote machine.
232 The credentials are (re)read and from the schannel database, and
233 written back after the caclulations are performed.
235 The creds_out parameter (if not NULL) returns the credentials, if
236 the caller needs some of that information.
239 static NTSTATUS dcesrv_netr_creds_server_step_check(struct loadparm_context *lp_ctx,
240 const char *computer_name,
242 struct netr_Authenticator *received_authenticator,
243 struct netr_Authenticator *return_authenticator,
244 struct creds_CredentialState **creds_out)
246 struct creds_CredentialState *creds;
248 struct ldb_context *ldb;
251 ldb = schannel_db_connect(mem_ctx, lp_ctx);
253 return NT_STATUS_ACCESS_DENIED;
256 ret = ldb_transaction_start(ldb);
259 return NT_STATUS_INTERNAL_DB_CORRUPTION;
262 /* Because this is a shared structure (even across
263 * disconnects) we must update the database every time we
264 * update the structure */
266 nt_status = schannel_fetch_session_key_ldb(ldb, ldb, computer_name,
267 lp_workgroup(lp_ctx),
269 if (NT_STATUS_IS_OK(nt_status)) {
270 nt_status = creds_server_step_check(creds,
271 received_authenticator,
272 return_authenticator);
274 if (NT_STATUS_IS_OK(nt_status)) {
275 nt_status = schannel_store_session_key_ldb(ldb, ldb, creds);
278 if (NT_STATUS_IS_OK(nt_status)) {
279 ldb_transaction_commit(ldb);
282 talloc_steal(mem_ctx, creds);
285 ldb_transaction_cancel(ldb);
292 Change the machine account password for the currently connected
293 client. Supplies only the NT#.
296 static NTSTATUS dcesrv_netr_ServerPasswordSet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
297 struct netr_ServerPasswordSet *r)
299 struct creds_CredentialState *creds;
300 struct ldb_context *sam_ctx;
303 nt_status = dcesrv_netr_creds_server_step_check(dce_call->conn->dce_ctx->lp_ctx,
304 r->in.computer_name, mem_ctx,
305 &r->in.credential, &r->out.return_authenticator,
307 NT_STATUS_NOT_OK_RETURN(nt_status);
309 sam_ctx = samdb_connect(mem_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(mem_ctx, dce_call->conn->dce_ctx->lp_ctx));
310 if (sam_ctx == NULL) {
311 return NT_STATUS_INVALID_SYSTEM_SERVICE;
314 creds_des_decrypt(creds, &r->in.new_password);
316 /* Using the sid for the account as the key, set the password */
317 nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
319 NULL, /* Don't have plaintext */
320 NULL, &r->in.new_password,
321 false, /* This is not considered a password change */
327 Change the machine account password for the currently connected
328 client. Supplies new plaintext.
330 static NTSTATUS dcesrv_netr_ServerPasswordSet2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
331 struct netr_ServerPasswordSet2 *r)
333 struct creds_CredentialState *creds;
334 struct ldb_context *sam_ctx;
337 uint32_t new_pass_len;
340 struct samr_CryptPassword password_buf;
342 nt_status = dcesrv_netr_creds_server_step_check(dce_call->conn->dce_ctx->lp_ctx,
343 r->in.computer_name, mem_ctx,
344 &r->in.credential, &r->out.return_authenticator,
346 NT_STATUS_NOT_OK_RETURN(nt_status);
348 sam_ctx = samdb_connect(mem_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(mem_ctx, dce_call->conn->dce_ctx->lp_ctx));
349 if (sam_ctx == NULL) {
350 return NT_STATUS_INVALID_SYSTEM_SERVICE;
353 memcpy(password_buf.data, r->in.new_password.data, 512);
354 SIVAL(password_buf.data,512,r->in.new_password.length);
355 creds_arcfour_crypt(creds, password_buf.data, 516);
357 ret = decode_pw_buffer(password_buf.data, new_pass, sizeof(new_pass),
358 &new_pass_len, STR_UNICODE);
360 DEBUG(3,("netr_ServerPasswordSet2: failed to decode password buffer\n"));
361 return NT_STATUS_ACCESS_DENIED;
364 /* Using the sid for the account as the key, set the password */
365 nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
367 new_pass, /* we have plaintext */
369 false, /* This is not considered a password change */
378 static WERROR dcesrv_netr_LogonUasLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
379 struct netr_LogonUasLogon *r)
381 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
388 static WERROR dcesrv_netr_LogonUasLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
389 struct netr_LogonUasLogoff *r)
391 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
396 netr_LogonSamLogon_base
398 This version of the function allows other wrappers to say 'do not check the credentials'
400 We can't do the traditional 'wrapping' format completly, as this function must only run under schannel
402 static NTSTATUS dcesrv_netr_LogonSamLogon_base(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
403 struct netr_LogonSamLogonEx *r, struct creds_CredentialState *creds)
405 struct auth_context *auth_context;
406 struct auth_usersupplied_info *user_info;
407 struct auth_serversupplied_info *server_info;
409 static const char zeros[16];
410 struct netr_SamBaseInfo *sam;
411 struct netr_SamInfo2 *sam2;
412 struct netr_SamInfo3 *sam3;
413 struct netr_SamInfo6 *sam6;
415 user_info = talloc(mem_ctx, struct auth_usersupplied_info);
416 NT_STATUS_HAVE_NO_MEMORY(user_info);
418 user_info->flags = 0;
419 user_info->mapped_state = false;
420 user_info->remote_host = NULL;
422 switch (r->in.logon_level) {
426 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
427 creds_arcfour_crypt(creds,
428 r->in.logon.password->lmpassword.hash,
429 sizeof(r->in.logon.password->lmpassword.hash));
430 creds_arcfour_crypt(creds,
431 r->in.logon.password->ntpassword.hash,
432 sizeof(r->in.logon.password->ntpassword.hash));
434 creds_des_decrypt(creds, &r->in.logon.password->lmpassword);
435 creds_des_decrypt(creds, &r->in.logon.password->ntpassword);
438 /* TODO: we need to deny anonymous access here */
439 nt_status = auth_context_create(mem_ctx,
440 dce_call->event_ctx, dce_call->msg_ctx,
441 dce_call->conn->dce_ctx->lp_ctx,
443 NT_STATUS_NOT_OK_RETURN(nt_status);
445 user_info->logon_parameters = r->in.logon.password->identity_info.parameter_control;
446 user_info->client.account_name = r->in.logon.password->identity_info.account_name.string;
447 user_info->client.domain_name = r->in.logon.password->identity_info.domain_name.string;
448 user_info->workstation_name = r->in.logon.password->identity_info.workstation.string;
450 user_info->flags |= USER_INFO_INTERACTIVE_LOGON;
451 user_info->password_state = AUTH_PASSWORD_HASH;
453 user_info->password.hash.lanman = talloc(user_info, struct samr_Password);
454 NT_STATUS_HAVE_NO_MEMORY(user_info->password.hash.lanman);
455 *user_info->password.hash.lanman = r->in.logon.password->lmpassword;
457 user_info->password.hash.nt = talloc(user_info, struct samr_Password);
458 NT_STATUS_HAVE_NO_MEMORY(user_info->password.hash.nt);
459 *user_info->password.hash.nt = r->in.logon.password->ntpassword;
465 /* TODO: we need to deny anonymous access here */
466 nt_status = auth_context_create(mem_ctx,
467 dce_call->event_ctx, dce_call->msg_ctx,
468 dce_call->conn->dce_ctx->lp_ctx,
470 NT_STATUS_NOT_OK_RETURN(nt_status);
472 nt_status = auth_context_set_challenge(auth_context, r->in.logon.network->challenge, "netr_LogonSamLogonWithFlags");
473 NT_STATUS_NOT_OK_RETURN(nt_status);
475 user_info->logon_parameters = r->in.logon.network->identity_info.parameter_control;
476 user_info->client.account_name = r->in.logon.network->identity_info.account_name.string;
477 user_info->client.domain_name = r->in.logon.network->identity_info.domain_name.string;
478 user_info->workstation_name = r->in.logon.network->identity_info.workstation.string;
480 user_info->password_state = AUTH_PASSWORD_RESPONSE;
481 user_info->password.response.lanman = data_blob_talloc(mem_ctx, r->in.logon.network->lm.data, r->in.logon.network->lm.length);
482 user_info->password.response.nt = data_blob_talloc(mem_ctx, r->in.logon.network->nt.data, r->in.logon.network->nt.length);
486 return NT_STATUS_INVALID_PARAMETER;
489 nt_status = auth_check_password(auth_context, mem_ctx, user_info, &server_info);
490 NT_STATUS_NOT_OK_RETURN(nt_status);
492 nt_status = auth_convert_server_info_sambaseinfo(mem_ctx, server_info, &sam);
493 NT_STATUS_NOT_OK_RETURN(nt_status);
495 /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
496 /* It appears that level 6 is not individually encrypted */
497 if ((r->in.validation_level != 6) &&
498 memcmp(sam->key.key, zeros, sizeof(sam->key.key)) != 0) {
499 /* This key is sent unencrypted without the ARCFOUR flag set */
500 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
501 creds_arcfour_crypt(creds,
503 sizeof(sam->key.key));
507 /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
508 /* It appears that level 6 is not individually encrypted */
509 if ((r->in.validation_level != 6) &&
510 memcmp(sam->LMSessKey.key, zeros, sizeof(sam->LMSessKey.key)) != 0) {
511 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
512 creds_arcfour_crypt(creds,
514 sizeof(sam->LMSessKey.key));
516 creds_des_encrypt_LMKey(creds,
521 switch (r->in.validation_level) {
523 sam2 = talloc_zero(mem_ctx, struct netr_SamInfo2);
524 NT_STATUS_HAVE_NO_MEMORY(sam2);
526 r->out.validation.sam2 = sam2;
530 sam3 = talloc_zero(mem_ctx, struct netr_SamInfo3);
531 NT_STATUS_HAVE_NO_MEMORY(sam3);
533 r->out.validation.sam3 = sam3;
537 sam6 = talloc_zero(mem_ctx, struct netr_SamInfo6);
538 NT_STATUS_HAVE_NO_MEMORY(sam6);
540 sam6->forest.string = lp_realm(dce_call->conn->dce_ctx->lp_ctx);
541 sam6->principle.string = talloc_asprintf(mem_ctx, "%s@%s",
542 sam->account_name.string, sam6->forest.string);
543 NT_STATUS_HAVE_NO_MEMORY(sam6->principle.string);
544 r->out.validation.sam6 = sam6;
551 r->out.authoritative = 1;
553 /* TODO: Describe and deal with these flags */
559 static NTSTATUS dcesrv_netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
560 struct netr_LogonSamLogonEx *r)
563 struct creds_CredentialState *creds;
564 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);
565 if (!NT_STATUS_IS_OK(nt_status)) {
569 if (!dce_call->conn->auth_state.auth_info ||
570 dce_call->conn->auth_state.auth_info->auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
571 return NT_STATUS_INTERNAL_ERROR;
573 return dcesrv_netr_LogonSamLogon_base(dce_call, mem_ctx, r, creds);
577 netr_LogonSamLogonWithFlags
580 static NTSTATUS dcesrv_netr_LogonSamLogonWithFlags(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
581 struct netr_LogonSamLogonWithFlags *r)
584 struct creds_CredentialState *creds;
585 struct netr_LogonSamLogonEx r2;
587 struct netr_Authenticator *return_authenticator;
589 return_authenticator = talloc(mem_ctx, struct netr_Authenticator);
590 NT_STATUS_HAVE_NO_MEMORY(return_authenticator);
592 nt_status = dcesrv_netr_creds_server_step_check(dce_call->conn->dce_ctx->lp_ctx,
593 r->in.computer_name, mem_ctx,
594 r->in.credential, return_authenticator,
596 NT_STATUS_NOT_OK_RETURN(nt_status);
600 r2.in.server_name = r->in.server_name;
601 r2.in.computer_name = r->in.computer_name;
602 r2.in.logon_level = r->in.logon_level;
603 r2.in.logon = r->in.logon;
604 r2.in.validation_level = r->in.validation_level;
605 r2.in.flags = r->in.flags;
607 nt_status = dcesrv_netr_LogonSamLogon_base(dce_call, mem_ctx, &r2, creds);
609 r->out.return_authenticator = return_authenticator;
610 r->out.validation = r2.out.validation;
611 r->out.authoritative = r2.out.authoritative;
612 r->out.flags = r2.out.flags;
620 static NTSTATUS dcesrv_netr_LogonSamLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
621 struct netr_LogonSamLogon *r)
623 struct netr_LogonSamLogonWithFlags r2;
628 r2.in.server_name = r->in.server_name;
629 r2.in.computer_name = r->in.computer_name;
630 r2.in.credential = r->in.credential;
631 r2.in.return_authenticator = r->in.return_authenticator;
632 r2.in.logon_level = r->in.logon_level;
633 r2.in.logon = r->in.logon;
634 r2.in.validation_level = r->in.validation_level;
637 status = dcesrv_netr_LogonSamLogonWithFlags(dce_call, mem_ctx, &r2);
639 r->out.return_authenticator = r2.out.return_authenticator;
640 r->out.validation = r2.out.validation;
641 r->out.authoritative = r2.out.authoritative;
650 static NTSTATUS dcesrv_netr_LogonSamLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
651 struct netr_LogonSamLogoff *r)
653 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
661 static NTSTATUS dcesrv_netr_DatabaseDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
662 struct netr_DatabaseDeltas *r)
664 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
671 static NTSTATUS dcesrv_netr_DatabaseSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
672 struct netr_DatabaseSync *r)
674 /* win2k3 native mode returns "NOT IMPLEMENTED" for this call */
675 return NT_STATUS_NOT_IMPLEMENTED;
682 static NTSTATUS dcesrv_netr_AccountDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
683 struct netr_AccountDeltas *r)
685 /* w2k3 returns "NOT IMPLEMENTED" for this call */
686 return NT_STATUS_NOT_IMPLEMENTED;
693 static NTSTATUS dcesrv_netr_AccountSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
694 struct netr_AccountSync *r)
696 /* w2k3 returns "NOT IMPLEMENTED" for this call */
697 return NT_STATUS_NOT_IMPLEMENTED;
704 static WERROR dcesrv_netr_GetDcName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
705 struct netr_GetDcName *r)
707 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
714 static WERROR dcesrv_netr_LogonControl(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
715 struct netr_LogonControl *r)
717 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
724 static WERROR dcesrv_netr_GetAnyDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
725 struct netr_GetAnyDCName *r)
727 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
734 static WERROR dcesrv_netr_LogonControl2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
735 struct netr_LogonControl2 *r)
737 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
744 static NTSTATUS dcesrv_netr_DatabaseSync2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
745 struct netr_DatabaseSync2 *r)
747 /* win2k3 native mode returns "NOT IMPLEMENTED" for this call */
748 return NT_STATUS_NOT_IMPLEMENTED;
755 static NTSTATUS dcesrv_netr_DatabaseRedo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
756 struct netr_DatabaseRedo *r)
758 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
765 static WERROR dcesrv_netr_LogonControl2Ex(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
766 struct netr_LogonControl2Ex *r)
768 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
773 netr_NetrEnumerateTurstedDomains
775 static WERROR dcesrv_netr_NetrEnumerateTrustedDomains(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
776 struct netr_NetrEnumerateTrustedDomains *r)
778 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
783 netr_NETRLOGONDUMMYROUTINE1
785 static WERROR dcesrv_netr_NETRLOGONDUMMYROUTINE1(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
786 struct netr_NETRLOGONDUMMYROUTINE1 *r)
788 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
793 netr_NETRLOGONSETSERVICEBITS
795 static WERROR dcesrv_netr_NETRLOGONSETSERVICEBITS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
796 struct netr_NETRLOGONSETSERVICEBITS *r)
798 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
803 netr_LogonGetTrustRid
805 static WERROR dcesrv_netr_LogonGetTrustRid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
806 struct netr_LogonGetTrustRid *r)
808 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
813 netr_NETRLOGONCOMPUTESERVERDIGEST
815 static WERROR dcesrv_netr_NETRLOGONCOMPUTESERVERDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
816 struct netr_NETRLOGONCOMPUTESERVERDIGEST *r)
818 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
823 netr_NETRLOGONCOMPUTECLIENTDIGEST
825 static WERROR dcesrv_netr_NETRLOGONCOMPUTECLIENTDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
826 struct netr_NETRLOGONCOMPUTECLIENTDIGEST *r)
828 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
836 static WERROR dcesrv_netr_DsRGetSiteName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
837 struct netr_DsRGetSiteName *r)
839 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
844 fill in a netr_DomainTrustInfo from a ldb search result
846 static NTSTATUS fill_domain_trust_info(TALLOC_CTX *mem_ctx,
847 struct ldb_message *res,
848 struct ldb_message *ref_res,
849 struct netr_DomainTrustInfo *info,
855 info->domainname.string = samdb_result_string(ref_res, "nETBIOSName", NULL);
856 info->fulldomainname.string = samdb_result_string(ref_res, "dnsRoot", NULL);
857 info->forest.string = NULL;
858 info->guid = samdb_result_guid(res, "objectGUID");
859 info->sid = samdb_result_dom_sid(mem_ctx, res, "objectSid");
861 info->domainname.string = samdb_result_string(res, "flatName", NULL);
862 info->fulldomainname.string = samdb_result_string(res, "trustPartner", NULL);
863 info->forest.string = NULL;
864 info->guid = samdb_result_guid(res, "objectGUID");
865 info->sid = samdb_result_dom_sid(mem_ctx, res, "securityIdentifier");
872 netr_LogonGetDomainInfo
873 this is called as part of the ADS domain logon procedure.
875 It has an important role in convaying details about the client, such
876 as Operating System, Version, Service Pack etc.
878 static NTSTATUS dcesrv_netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
879 struct netr_LogonGetDomainInfo *r)
881 const char * const attrs[] = { "objectSid",
882 "objectGUID", "flatName", "securityIdentifier",
883 "trustPartner", NULL };
884 const char * const ref_attrs[] = { "nETBIOSName", "dnsRoot", NULL };
885 struct ldb_context *sam_ctx;
886 struct ldb_message **res1, **res2, **ref_res;
887 struct netr_DomainInfo1 *info1;
888 int ret, ret1, ret2, i;
890 struct ldb_dn *partitions_basedn;
892 const char *local_domain;
894 status = dcesrv_netr_creds_server_step_check(dce_call->conn->dce_ctx->lp_ctx,
895 r->in.computer_name, mem_ctx,
897 r->out.return_authenticator,
899 NT_STATUS_NOT_OK_RETURN(status);
901 sam_ctx = samdb_connect(mem_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
902 if (sam_ctx == NULL) {
903 return NT_STATUS_INVALID_SYSTEM_SERVICE;
906 partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);
908 /* we need to do two searches. The first will pull our primary
909 domain and the second will pull any trusted domains. Our
910 primary domain is also a "trusted" domain, so we need to
911 put the primary domain into the lists of returned trusts as
913 ret1 = gendb_search_dn(sam_ctx, mem_ctx, samdb_base_dn(sam_ctx), &res1, attrs);
915 return NT_STATUS_INTERNAL_DB_CORRUPTION;
918 /* try and find the domain */
919 ret = gendb_search(sam_ctx, mem_ctx, partitions_basedn,
921 "(&(objectClass=crossRef)(ncName=%s))",
922 ldb_dn_get_linearized(res1[0]->dn));
924 return NT_STATUS_INTERNAL_DB_CORRUPTION;
927 local_domain = samdb_result_string(ref_res[0], "nETBIOSName", NULL);
929 ret2 = gendb_search(sam_ctx, mem_ctx, NULL, &res2, attrs, "(objectClass=trustedDomain)");
931 return NT_STATUS_INTERNAL_DB_CORRUPTION;
934 info1 = talloc(mem_ctx, struct netr_DomainInfo1);
935 NT_STATUS_HAVE_NO_MEMORY(info1);
939 info1->num_trusts = ret2 + 1;
940 info1->trusts = talloc_array(mem_ctx, struct netr_DomainTrustInfo,
942 NT_STATUS_HAVE_NO_MEMORY(info1->trusts);
944 status = fill_domain_trust_info(mem_ctx, res1[0], ref_res[0], &info1->domaininfo, true);
945 NT_STATUS_NOT_OK_RETURN(status);
947 for (i=0;i<ret2;i++) {
948 status = fill_domain_trust_info(mem_ctx, res2[i], NULL, &info1->trusts[i], false);
949 NT_STATUS_NOT_OK_RETURN(status);
952 status = fill_domain_trust_info(mem_ctx, res1[0], ref_res[0], &info1->trusts[i], true);
953 NT_STATUS_NOT_OK_RETURN(status);
955 r->out.info.info1 = info1;
963 netr_ServerPasswordGet
965 static WERROR dcesrv_netr_ServerPasswordGet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
966 struct netr_ServerPasswordGet *r)
968 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
973 netr_NETRLOGONSENDTOSAM
975 static WERROR dcesrv_netr_NETRLOGONSENDTOSAM(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
976 struct netr_NETRLOGONSENDTOSAM *r)
978 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
983 netr_DsRAddressToSitenamesW
985 static WERROR dcesrv_netr_DsRAddressToSitenamesW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
986 struct netr_DsRAddressToSitenamesW *r)
988 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
995 static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
996 struct netr_DsRGetDCNameEx2 *r)
998 const char * const attrs[] = { "dnsDomain", "objectGUID", NULL };
1000 struct ldb_message **res;
1001 struct ldb_dn *domain_dn;
1004 ZERO_STRUCT(r->out);
1006 sam_ctx = samdb_connect(mem_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
1007 if (sam_ctx == NULL) {
1008 return WERR_DS_SERVICE_UNAVAILABLE;
1011 domain_dn = samdb_dns_domain_to_dn(sam_ctx, mem_ctx,
1013 if (domain_dn == NULL) {
1014 return WERR_DS_SERVICE_UNAVAILABLE;
1017 ret = gendb_search_dn(sam_ctx, mem_ctx, domain_dn, &res, attrs);
1019 return WERR_NO_SUCH_DOMAIN;
1022 r->out.info = talloc(mem_ctx, struct netr_DsRGetDCNameInfo);
1023 W_ERROR_HAVE_NO_MEMORY(r->out.info);
1025 /* TODO: - return real IP address
1026 * - check all r->in.* parameters (server_unc is ignored by w2k3!)
1028 r->out.info->dc_unc = talloc_asprintf(mem_ctx, "\\\\%s.%s",
1029 lp_netbios_name(dce_call->conn->dce_ctx->lp_ctx),
1030 lp_realm(dce_call->conn->dce_ctx->lp_ctx));
1031 W_ERROR_HAVE_NO_MEMORY(r->out.info->dc_unc);
1032 r->out.info->dc_address = talloc_strdup(mem_ctx, "\\\\0.0.0.0");
1033 W_ERROR_HAVE_NO_MEMORY(r->out.info->dc_address);
1034 r->out.info->dc_address_type = DS_ADDRESS_TYPE_INET;
1035 r->out.info->domain_guid = samdb_result_guid(res[0], "objectGUID");
1036 r->out.info->domain_name = samdb_result_string(res[0], "dnsDomain", NULL);
1037 r->out.info->forest_name = samdb_result_string(res[0], "dnsDomain", NULL);
1038 r->out.info->dc_flags = DS_DNS_FOREST |
1041 DS_SERVER_WRITABLE |
1043 DS_SERVER_TIMESERV |
1049 r->out.info->dc_site_name = talloc_strdup(mem_ctx, "Default-First-Site-Name");
1050 W_ERROR_HAVE_NO_MEMORY(r->out.info->dc_site_name);
1051 r->out.info->client_site_name = talloc_strdup(mem_ctx, "Default-First-Site-Name");
1052 W_ERROR_HAVE_NO_MEMORY(r->out.info->client_site_name);
1060 static WERROR dcesrv_netr_DsRGetDCNameEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1061 struct netr_DsRGetDCNameEx *r)
1063 struct netr_DsRGetDCNameEx2 r2;
1068 r2.in.server_unc = r->in.server_unc;
1069 r2.in.client_account = NULL;
1071 r2.in.domain_guid = r->in.domain_guid;
1072 r2.in.domain_name = r->in.domain_name;
1073 r2.in.site_name = r->in.site_name;
1074 r2.in.flags = r->in.flags;
1077 werr = dcesrv_netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1079 r->out.info = r2.out.info;
1087 static WERROR dcesrv_netr_DsRGetDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1088 struct netr_DsRGetDCName *r)
1090 struct netr_DsRGetDCNameEx2 r2;
1095 r2.in.server_unc = r->in.server_unc;
1096 r2.in.client_account = NULL;
1098 r2.in.domain_name = r->in.domain_name;
1099 r2.in.domain_guid = r->in.domain_guid;
1101 r2.in.site_name = NULL; /* should fill in from site GUID */
1102 r2.in.flags = r->in.flags;
1105 werr = dcesrv_netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1107 r->out.info = r2.out.info;
1113 netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN
1115 static WERROR dcesrv_netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1116 struct netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN *r)
1118 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1123 netr_NetrEnumerateTrustedDomainsEx
1125 static WERROR dcesrv_netr_NetrEnumerateTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1126 struct netr_NetrEnumerateTrustedDomainsEx *r)
1128 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1133 netr_DsRAddressToSitenamesExW
1135 static WERROR dcesrv_netr_DsRAddressToSitenamesExW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1136 struct netr_DsRAddressToSitenamesExW *r)
1138 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1143 netr_DsrGetDcSiteCoverageW
1145 static WERROR dcesrv_netr_DsrGetDcSiteCoverageW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1146 struct netr_DsrGetDcSiteCoverageW *r)
1148 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1153 netr_DsrEnumerateDomainTrusts
1155 static WERROR dcesrv_netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1156 struct netr_DsrEnumerateDomainTrusts *r)
1158 struct netr_DomainTrust *trusts;
1161 struct ldb_message **dom_res, **ref_res;
1162 const char * const dom_attrs[] = { "objectSid", "objectGUID", NULL };
1163 const char * const ref_attrs[] = { "nETBIOSName", "dnsRoot", NULL };
1164 struct ldb_dn *partitions_basedn;
1166 ZERO_STRUCT(r->out);
1168 sam_ctx = samdb_connect(mem_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
1169 if (sam_ctx == NULL) {
1170 return WERR_GENERAL_FAILURE;
1173 partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);
1175 ret = gendb_search_dn(sam_ctx, mem_ctx, NULL, &dom_res, dom_attrs);
1177 return WERR_GENERAL_FAILURE;
1180 return WERR_GENERAL_FAILURE;
1183 ret = gendb_search(sam_ctx, mem_ctx, partitions_basedn, &ref_res, ref_attrs,
1184 "(&(objectClass=crossRef)(ncName=%s))",
1185 ldb_dn_get_linearized(dom_res[0]->dn));
1187 return WERR_GENERAL_FAILURE;
1190 return WERR_GENERAL_FAILURE;
1193 trusts = talloc_array(mem_ctx, struct netr_DomainTrust, ret);
1194 W_ERROR_HAVE_NO_MEMORY(trusts);
1197 r->out.trusts = trusts;
1199 /* TODO: add filtering by trust_flags, and correct trust_type
1201 trusts[0].netbios_name = samdb_result_string(ref_res[0], "nETBIOSName", NULL);
1202 trusts[0].dns_name = samdb_result_string(ref_res[0], "dnsRoot", NULL);
1203 trusts[0].trust_flags =
1204 NETR_TRUST_FLAG_TREEROOT |
1205 NETR_TRUST_FLAG_IN_FOREST |
1206 NETR_TRUST_FLAG_PRIMARY;
1207 trusts[0].parent_index = 0;
1208 trusts[0].trust_type = 2;
1209 trusts[0].trust_attributes = 0;
1210 trusts[0].sid = samdb_result_dom_sid(mem_ctx, dom_res[0], "objectSid");
1211 trusts[0].guid = samdb_result_guid(dom_res[0], "objectGUID");
1218 netr_DsrDeregisterDNSHostRecords
1220 static WERROR dcesrv_netr_DsrDeregisterDNSHostRecords(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1221 struct netr_DsrDeregisterDNSHostRecords *r)
1223 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1228 netr_ServerTrustPasswordsGet
1230 static NTSTATUS dcesrv_netr_ServerTrustPasswordsGet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1231 struct netr_ServerTrustPasswordsGet *r)
1233 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1238 netr_DsRGetForestTrustInformation
1240 static WERROR dcesrv_netr_DsRGetForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1241 struct netr_DsRGetForestTrustInformation *r)
1243 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1248 netr_GetForestTrustInformation
1250 static WERROR dcesrv_netr_GetForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1251 struct netr_GetForestTrustInformation *r)
1253 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1258 netr_NETRSERVERGETTRUSTINFO
1260 static WERROR dcesrv_netr_NETRSERVERGETTRUSTINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1261 struct netr_NETRSERVERGETTRUSTINFO *r)
1263 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1267 /* include the generated boilerplate */
1268 #include "librpc/gen_ndr/ndr_netlogon_s.c"