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->event_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->event_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 event_context *event_ctx,
240 struct loadparm_context *lp_ctx,
241 const char *computer_name,
243 struct netr_Authenticator *received_authenticator,
244 struct netr_Authenticator *return_authenticator,
245 struct creds_CredentialState **creds_out)
247 struct creds_CredentialState *creds;
249 struct ldb_context *ldb;
252 ldb = schannel_db_connect(mem_ctx, event_ctx, lp_ctx);
254 return NT_STATUS_ACCESS_DENIED;
257 ret = ldb_transaction_start(ldb);
260 return NT_STATUS_INTERNAL_DB_CORRUPTION;
263 /* Because this is a shared structure (even across
264 * disconnects) we must update the database every time we
265 * update the structure */
267 nt_status = schannel_fetch_session_key_ldb(ldb, ldb, computer_name,
268 lp_workgroup(lp_ctx),
270 if (NT_STATUS_IS_OK(nt_status)) {
271 nt_status = creds_server_step_check(creds,
272 received_authenticator,
273 return_authenticator);
275 if (NT_STATUS_IS_OK(nt_status)) {
276 nt_status = schannel_store_session_key_ldb(ldb, ldb, creds);
279 if (NT_STATUS_IS_OK(nt_status)) {
280 ldb_transaction_commit(ldb);
283 talloc_steal(mem_ctx, creds);
286 ldb_transaction_cancel(ldb);
293 Change the machine account password for the currently connected
294 client. Supplies only the NT#.
297 static NTSTATUS dcesrv_netr_ServerPasswordSet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
298 struct netr_ServerPasswordSet *r)
300 struct creds_CredentialState *creds;
301 struct ldb_context *sam_ctx;
304 nt_status = dcesrv_netr_creds_server_step_check(dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx,
305 r->in.computer_name, mem_ctx,
306 &r->in.credential, &r->out.return_authenticator,
308 NT_STATUS_NOT_OK_RETURN(nt_status);
310 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(mem_ctx, dce_call->conn->dce_ctx->lp_ctx));
311 if (sam_ctx == NULL) {
312 return NT_STATUS_INVALID_SYSTEM_SERVICE;
315 creds_des_decrypt(creds, &r->in.new_password);
317 /* Using the sid for the account as the key, set the password */
318 nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
320 NULL, /* Don't have plaintext */
321 NULL, &r->in.new_password,
322 false, /* This is not considered a password change */
328 Change the machine account password for the currently connected
329 client. Supplies new plaintext.
331 static NTSTATUS dcesrv_netr_ServerPasswordSet2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
332 struct netr_ServerPasswordSet2 *r)
334 struct creds_CredentialState *creds;
335 struct ldb_context *sam_ctx;
338 uint32_t new_pass_len;
341 struct samr_CryptPassword password_buf;
343 nt_status = dcesrv_netr_creds_server_step_check(dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx,
344 r->in.computer_name, mem_ctx,
345 &r->in.credential, &r->out.return_authenticator,
347 NT_STATUS_NOT_OK_RETURN(nt_status);
349 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(mem_ctx, dce_call->conn->dce_ctx->lp_ctx));
350 if (sam_ctx == NULL) {
351 return NT_STATUS_INVALID_SYSTEM_SERVICE;
354 memcpy(password_buf.data, r->in.new_password.data, 512);
355 SIVAL(password_buf.data,512,r->in.new_password.length);
356 creds_arcfour_crypt(creds, password_buf.data, 516);
358 ret = decode_pw_buffer(password_buf.data, new_pass, sizeof(new_pass),
359 &new_pass_len, STR_UNICODE);
361 DEBUG(3,("netr_ServerPasswordSet2: failed to decode password buffer\n"));
362 return NT_STATUS_ACCESS_DENIED;
365 /* Using the sid for the account as the key, set the password */
366 nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
368 new_pass, /* we have plaintext */
370 false, /* This is not considered a password change */
379 static WERROR dcesrv_netr_LogonUasLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
380 struct netr_LogonUasLogon *r)
382 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
389 static WERROR dcesrv_netr_LogonUasLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
390 struct netr_LogonUasLogoff *r)
392 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
397 netr_LogonSamLogon_base
399 This version of the function allows other wrappers to say 'do not check the credentials'
401 We can't do the traditional 'wrapping' format completly, as this function must only run under schannel
403 static NTSTATUS dcesrv_netr_LogonSamLogon_base(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
404 struct netr_LogonSamLogonEx *r, struct creds_CredentialState *creds)
406 struct auth_context *auth_context;
407 struct auth_usersupplied_info *user_info;
408 struct auth_serversupplied_info *server_info;
410 static const char zeros[16];
411 struct netr_SamBaseInfo *sam;
412 struct netr_SamInfo2 *sam2;
413 struct netr_SamInfo3 *sam3;
414 struct netr_SamInfo6 *sam6;
416 user_info = talloc(mem_ctx, struct auth_usersupplied_info);
417 NT_STATUS_HAVE_NO_MEMORY(user_info);
419 user_info->flags = 0;
420 user_info->mapped_state = false;
421 user_info->remote_host = NULL;
423 switch (r->in.logon_level) {
427 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
428 creds_arcfour_crypt(creds,
429 r->in.logon.password->lmpassword.hash,
430 sizeof(r->in.logon.password->lmpassword.hash));
431 creds_arcfour_crypt(creds,
432 r->in.logon.password->ntpassword.hash,
433 sizeof(r->in.logon.password->ntpassword.hash));
435 creds_des_decrypt(creds, &r->in.logon.password->lmpassword);
436 creds_des_decrypt(creds, &r->in.logon.password->ntpassword);
439 /* TODO: we need to deny anonymous access here */
440 nt_status = auth_context_create(mem_ctx,
441 dce_call->event_ctx, dce_call->msg_ctx,
442 dce_call->conn->dce_ctx->lp_ctx,
444 NT_STATUS_NOT_OK_RETURN(nt_status);
446 user_info->logon_parameters = r->in.logon.password->identity_info.parameter_control;
447 user_info->client.account_name = r->in.logon.password->identity_info.account_name.string;
448 user_info->client.domain_name = r->in.logon.password->identity_info.domain_name.string;
449 user_info->workstation_name = r->in.logon.password->identity_info.workstation.string;
451 user_info->flags |= USER_INFO_INTERACTIVE_LOGON;
452 user_info->password_state = AUTH_PASSWORD_HASH;
454 user_info->password.hash.lanman = talloc(user_info, struct samr_Password);
455 NT_STATUS_HAVE_NO_MEMORY(user_info->password.hash.lanman);
456 *user_info->password.hash.lanman = r->in.logon.password->lmpassword;
458 user_info->password.hash.nt = talloc(user_info, struct samr_Password);
459 NT_STATUS_HAVE_NO_MEMORY(user_info->password.hash.nt);
460 *user_info->password.hash.nt = r->in.logon.password->ntpassword;
466 /* TODO: we need to deny anonymous access here */
467 nt_status = auth_context_create(mem_ctx,
468 dce_call->event_ctx, dce_call->msg_ctx,
469 dce_call->conn->dce_ctx->lp_ctx,
471 NT_STATUS_NOT_OK_RETURN(nt_status);
473 nt_status = auth_context_set_challenge(auth_context, r->in.logon.network->challenge, "netr_LogonSamLogonWithFlags");
474 NT_STATUS_NOT_OK_RETURN(nt_status);
476 user_info->logon_parameters = r->in.logon.network->identity_info.parameter_control;
477 user_info->client.account_name = r->in.logon.network->identity_info.account_name.string;
478 user_info->client.domain_name = r->in.logon.network->identity_info.domain_name.string;
479 user_info->workstation_name = r->in.logon.network->identity_info.workstation.string;
481 user_info->password_state = AUTH_PASSWORD_RESPONSE;
482 user_info->password.response.lanman = data_blob_talloc(mem_ctx, r->in.logon.network->lm.data, r->in.logon.network->lm.length);
483 user_info->password.response.nt = data_blob_talloc(mem_ctx, r->in.logon.network->nt.data, r->in.logon.network->nt.length);
487 return NT_STATUS_INVALID_PARAMETER;
490 nt_status = auth_check_password(auth_context, mem_ctx, user_info, &server_info);
491 NT_STATUS_NOT_OK_RETURN(nt_status);
493 nt_status = auth_convert_server_info_sambaseinfo(mem_ctx, server_info, &sam);
494 NT_STATUS_NOT_OK_RETURN(nt_status);
496 /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
497 /* It appears that level 6 is not individually encrypted */
498 if ((r->in.validation_level != 6) &&
499 memcmp(sam->key.key, zeros, sizeof(sam->key.key)) != 0) {
500 /* This key is sent unencrypted without the ARCFOUR flag set */
501 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
502 creds_arcfour_crypt(creds,
504 sizeof(sam->key.key));
508 /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
509 /* It appears that level 6 is not individually encrypted */
510 if ((r->in.validation_level != 6) &&
511 memcmp(sam->LMSessKey.key, zeros, sizeof(sam->LMSessKey.key)) != 0) {
512 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
513 creds_arcfour_crypt(creds,
515 sizeof(sam->LMSessKey.key));
517 creds_des_encrypt_LMKey(creds,
522 switch (r->in.validation_level) {
524 sam2 = talloc_zero(mem_ctx, struct netr_SamInfo2);
525 NT_STATUS_HAVE_NO_MEMORY(sam2);
527 r->out.validation.sam2 = sam2;
531 sam3 = talloc_zero(mem_ctx, struct netr_SamInfo3);
532 NT_STATUS_HAVE_NO_MEMORY(sam3);
534 r->out.validation.sam3 = sam3;
538 sam6 = talloc_zero(mem_ctx, struct netr_SamInfo6);
539 NT_STATUS_HAVE_NO_MEMORY(sam6);
541 sam6->forest.string = lp_realm(dce_call->conn->dce_ctx->lp_ctx);
542 sam6->principle.string = talloc_asprintf(mem_ctx, "%s@%s",
543 sam->account_name.string, sam6->forest.string);
544 NT_STATUS_HAVE_NO_MEMORY(sam6->principle.string);
545 r->out.validation.sam6 = sam6;
552 r->out.authoritative = 1;
554 /* TODO: Describe and deal with these flags */
560 static NTSTATUS dcesrv_netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
561 struct netr_LogonSamLogonEx *r)
564 struct creds_CredentialState *creds;
565 nt_status = schannel_fetch_session_key(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, r->in.computer_name, lp_workgroup(dce_call->conn->dce_ctx->lp_ctx), &creds);
566 if (!NT_STATUS_IS_OK(nt_status)) {
570 if (!dce_call->conn->auth_state.auth_info ||
571 dce_call->conn->auth_state.auth_info->auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
572 return NT_STATUS_INTERNAL_ERROR;
574 return dcesrv_netr_LogonSamLogon_base(dce_call, mem_ctx, r, creds);
578 netr_LogonSamLogonWithFlags
581 static NTSTATUS dcesrv_netr_LogonSamLogonWithFlags(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
582 struct netr_LogonSamLogonWithFlags *r)
585 struct creds_CredentialState *creds;
586 struct netr_LogonSamLogonEx r2;
588 struct netr_Authenticator *return_authenticator;
590 return_authenticator = talloc(mem_ctx, struct netr_Authenticator);
591 NT_STATUS_HAVE_NO_MEMORY(return_authenticator);
593 nt_status = dcesrv_netr_creds_server_step_check(dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx,
594 r->in.computer_name, mem_ctx,
595 r->in.credential, return_authenticator,
597 NT_STATUS_NOT_OK_RETURN(nt_status);
601 r2.in.server_name = r->in.server_name;
602 r2.in.computer_name = r->in.computer_name;
603 r2.in.logon_level = r->in.logon_level;
604 r2.in.logon = r->in.logon;
605 r2.in.validation_level = r->in.validation_level;
606 r2.in.flags = r->in.flags;
608 nt_status = dcesrv_netr_LogonSamLogon_base(dce_call, mem_ctx, &r2, creds);
610 r->out.return_authenticator = return_authenticator;
611 r->out.validation = r2.out.validation;
612 r->out.authoritative = r2.out.authoritative;
613 r->out.flags = r2.out.flags;
621 static NTSTATUS dcesrv_netr_LogonSamLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
622 struct netr_LogonSamLogon *r)
624 struct netr_LogonSamLogonWithFlags r2;
629 r2.in.server_name = r->in.server_name;
630 r2.in.computer_name = r->in.computer_name;
631 r2.in.credential = r->in.credential;
632 r2.in.return_authenticator = r->in.return_authenticator;
633 r2.in.logon_level = r->in.logon_level;
634 r2.in.logon = r->in.logon;
635 r2.in.validation_level = r->in.validation_level;
638 status = dcesrv_netr_LogonSamLogonWithFlags(dce_call, mem_ctx, &r2);
640 r->out.return_authenticator = r2.out.return_authenticator;
641 r->out.validation = r2.out.validation;
642 r->out.authoritative = r2.out.authoritative;
651 static NTSTATUS dcesrv_netr_LogonSamLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
652 struct netr_LogonSamLogoff *r)
654 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
662 static NTSTATUS dcesrv_netr_DatabaseDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
663 struct netr_DatabaseDeltas *r)
665 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
672 static NTSTATUS dcesrv_netr_DatabaseSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
673 struct netr_DatabaseSync *r)
675 /* win2k3 native mode returns "NOT IMPLEMENTED" for this call */
676 return NT_STATUS_NOT_IMPLEMENTED;
683 static NTSTATUS dcesrv_netr_AccountDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
684 struct netr_AccountDeltas *r)
686 /* w2k3 returns "NOT IMPLEMENTED" for this call */
687 return NT_STATUS_NOT_IMPLEMENTED;
694 static NTSTATUS dcesrv_netr_AccountSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
695 struct netr_AccountSync *r)
697 /* w2k3 returns "NOT IMPLEMENTED" for this call */
698 return NT_STATUS_NOT_IMPLEMENTED;
705 static WERROR dcesrv_netr_GetDcName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
706 struct netr_GetDcName *r)
708 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
715 static WERROR dcesrv_netr_LogonControl(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
716 struct netr_LogonControl *r)
718 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
725 static WERROR dcesrv_netr_GetAnyDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
726 struct netr_GetAnyDCName *r)
728 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
735 static WERROR dcesrv_netr_LogonControl2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
736 struct netr_LogonControl2 *r)
738 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
745 static NTSTATUS dcesrv_netr_DatabaseSync2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
746 struct netr_DatabaseSync2 *r)
748 /* win2k3 native mode returns "NOT IMPLEMENTED" for this call */
749 return NT_STATUS_NOT_IMPLEMENTED;
756 static NTSTATUS dcesrv_netr_DatabaseRedo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
757 struct netr_DatabaseRedo *r)
759 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
766 static WERROR dcesrv_netr_LogonControl2Ex(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
767 struct netr_LogonControl2Ex *r)
769 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
774 netr_NetrEnumerateTurstedDomains
776 static WERROR dcesrv_netr_NetrEnumerateTrustedDomains(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
777 struct netr_NetrEnumerateTrustedDomains *r)
779 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
784 netr_NETRLOGONDUMMYROUTINE1
786 static WERROR dcesrv_netr_NETRLOGONDUMMYROUTINE1(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
787 struct netr_NETRLOGONDUMMYROUTINE1 *r)
789 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
794 netr_NETRLOGONSETSERVICEBITS
796 static WERROR dcesrv_netr_NETRLOGONSETSERVICEBITS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
797 struct netr_NETRLOGONSETSERVICEBITS *r)
799 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
804 netr_LogonGetTrustRid
806 static WERROR dcesrv_netr_LogonGetTrustRid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
807 struct netr_LogonGetTrustRid *r)
809 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
814 netr_NETRLOGONCOMPUTESERVERDIGEST
816 static WERROR dcesrv_netr_NETRLOGONCOMPUTESERVERDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
817 struct netr_NETRLOGONCOMPUTESERVERDIGEST *r)
819 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
824 netr_NETRLOGONCOMPUTECLIENTDIGEST
826 static WERROR dcesrv_netr_NETRLOGONCOMPUTECLIENTDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
827 struct netr_NETRLOGONCOMPUTECLIENTDIGEST *r)
829 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
837 static WERROR dcesrv_netr_DsRGetSiteName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
838 struct netr_DsRGetSiteName *r)
840 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
845 fill in a netr_DomainTrustInfo from a ldb search result
847 static NTSTATUS fill_domain_trust_info(TALLOC_CTX *mem_ctx,
848 struct ldb_message *res,
849 struct ldb_message *ref_res,
850 struct netr_DomainTrustInfo *info,
856 info->domainname.string = samdb_result_string(ref_res, "nETBIOSName", NULL);
857 info->fulldomainname.string = samdb_result_string(ref_res, "dnsRoot", NULL);
858 info->forest.string = NULL;
859 info->guid = samdb_result_guid(res, "objectGUID");
860 info->sid = samdb_result_dom_sid(mem_ctx, res, "objectSid");
862 info->domainname.string = samdb_result_string(res, "flatName", NULL);
863 info->fulldomainname.string = samdb_result_string(res, "trustPartner", NULL);
864 info->forest.string = NULL;
865 info->guid = samdb_result_guid(res, "objectGUID");
866 info->sid = samdb_result_dom_sid(mem_ctx, res, "securityIdentifier");
873 netr_LogonGetDomainInfo
874 this is called as part of the ADS domain logon procedure.
876 It has an important role in convaying details about the client, such
877 as Operating System, Version, Service Pack etc.
879 static NTSTATUS dcesrv_netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
880 struct netr_LogonGetDomainInfo *r)
882 const char * const attrs[] = { "objectSid",
883 "objectGUID", "flatName", "securityIdentifier",
884 "trustPartner", NULL };
885 const char * const ref_attrs[] = { "nETBIOSName", "dnsRoot", NULL };
886 struct ldb_context *sam_ctx;
887 struct ldb_message **res1, **res2, **ref_res;
888 struct netr_DomainInfo1 *info1;
889 int ret, ret1, ret2, i;
891 struct ldb_dn *partitions_basedn;
893 const char *local_domain;
895 status = dcesrv_netr_creds_server_step_check(dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx,
896 r->in.computer_name, mem_ctx,
898 r->out.return_authenticator,
900 NT_STATUS_NOT_OK_RETURN(status);
902 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
903 if (sam_ctx == NULL) {
904 return NT_STATUS_INVALID_SYSTEM_SERVICE;
907 partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);
909 /* we need to do two searches. The first will pull our primary
910 domain and the second will pull any trusted domains. Our
911 primary domain is also a "trusted" domain, so we need to
912 put the primary domain into the lists of returned trusts as
914 ret1 = gendb_search_dn(sam_ctx, mem_ctx, samdb_base_dn(sam_ctx), &res1, attrs);
916 return NT_STATUS_INTERNAL_DB_CORRUPTION;
919 /* try and find the domain */
920 ret = gendb_search(sam_ctx, mem_ctx, partitions_basedn,
922 "(&(objectClass=crossRef)(ncName=%s))",
923 ldb_dn_get_linearized(res1[0]->dn));
925 return NT_STATUS_INTERNAL_DB_CORRUPTION;
928 local_domain = samdb_result_string(ref_res[0], "nETBIOSName", NULL);
930 ret2 = gendb_search(sam_ctx, mem_ctx, NULL, &res2, attrs, "(objectClass=trustedDomain)");
932 return NT_STATUS_INTERNAL_DB_CORRUPTION;
935 info1 = talloc(mem_ctx, struct netr_DomainInfo1);
936 NT_STATUS_HAVE_NO_MEMORY(info1);
940 info1->num_trusts = ret2 + 1;
941 info1->trusts = talloc_array(mem_ctx, struct netr_DomainTrustInfo,
943 NT_STATUS_HAVE_NO_MEMORY(info1->trusts);
945 status = fill_domain_trust_info(mem_ctx, res1[0], ref_res[0], &info1->domaininfo, true);
946 NT_STATUS_NOT_OK_RETURN(status);
948 for (i=0;i<ret2;i++) {
949 status = fill_domain_trust_info(mem_ctx, res2[i], NULL, &info1->trusts[i], false);
950 NT_STATUS_NOT_OK_RETURN(status);
953 status = fill_domain_trust_info(mem_ctx, res1[0], ref_res[0], &info1->trusts[i], true);
954 NT_STATUS_NOT_OK_RETURN(status);
956 r->out.info.info1 = info1;
964 netr_ServerPasswordGet
966 static WERROR dcesrv_netr_ServerPasswordGet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
967 struct netr_ServerPasswordGet *r)
969 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
974 netr_NETRLOGONSENDTOSAM
976 static WERROR dcesrv_netr_NETRLOGONSENDTOSAM(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
977 struct netr_NETRLOGONSENDTOSAM *r)
979 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
984 netr_DsRAddressToSitenamesW
986 static WERROR dcesrv_netr_DsRAddressToSitenamesW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
987 struct netr_DsRAddressToSitenamesW *r)
989 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
996 static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
997 struct netr_DsRGetDCNameEx2 *r)
999 const char * const attrs[] = { "dnsDomain", "objectGUID", NULL };
1001 struct ldb_message **res;
1002 struct ldb_dn *domain_dn;
1005 ZERO_STRUCT(r->out);
1007 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
1008 if (sam_ctx == NULL) {
1009 return WERR_DS_SERVICE_UNAVAILABLE;
1012 domain_dn = samdb_dns_domain_to_dn(sam_ctx, mem_ctx,
1014 if (domain_dn == NULL) {
1015 return WERR_DS_SERVICE_UNAVAILABLE;
1018 ret = gendb_search_dn(sam_ctx, mem_ctx, domain_dn, &res, attrs);
1020 return WERR_NO_SUCH_DOMAIN;
1023 r->out.info = talloc(mem_ctx, struct netr_DsRGetDCNameInfo);
1024 W_ERROR_HAVE_NO_MEMORY(r->out.info);
1026 /* TODO: - return real IP address
1027 * - check all r->in.* parameters (server_unc is ignored by w2k3!)
1029 r->out.info->dc_unc = talloc_asprintf(mem_ctx, "\\\\%s.%s",
1030 lp_netbios_name(dce_call->conn->dce_ctx->lp_ctx),
1031 lp_realm(dce_call->conn->dce_ctx->lp_ctx));
1032 W_ERROR_HAVE_NO_MEMORY(r->out.info->dc_unc);
1033 r->out.info->dc_address = talloc_strdup(mem_ctx, "\\\\0.0.0.0");
1034 W_ERROR_HAVE_NO_MEMORY(r->out.info->dc_address);
1035 r->out.info->dc_address_type = DS_ADDRESS_TYPE_INET;
1036 r->out.info->domain_guid = samdb_result_guid(res[0], "objectGUID");
1037 r->out.info->domain_name = samdb_result_string(res[0], "dnsDomain", NULL);
1038 r->out.info->forest_name = samdb_result_string(res[0], "dnsDomain", NULL);
1039 r->out.info->dc_flags = DS_DNS_FOREST |
1042 DS_SERVER_WRITABLE |
1044 DS_SERVER_TIMESERV |
1050 r->out.info->dc_site_name = talloc_strdup(mem_ctx, "Default-First-Site-Name");
1051 W_ERROR_HAVE_NO_MEMORY(r->out.info->dc_site_name);
1052 r->out.info->client_site_name = talloc_strdup(mem_ctx, "Default-First-Site-Name");
1053 W_ERROR_HAVE_NO_MEMORY(r->out.info->client_site_name);
1061 static WERROR dcesrv_netr_DsRGetDCNameEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1062 struct netr_DsRGetDCNameEx *r)
1064 struct netr_DsRGetDCNameEx2 r2;
1069 r2.in.server_unc = r->in.server_unc;
1070 r2.in.client_account = NULL;
1072 r2.in.domain_guid = r->in.domain_guid;
1073 r2.in.domain_name = r->in.domain_name;
1074 r2.in.site_name = r->in.site_name;
1075 r2.in.flags = r->in.flags;
1078 werr = dcesrv_netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1080 r->out.info = r2.out.info;
1088 static WERROR dcesrv_netr_DsRGetDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1089 struct netr_DsRGetDCName *r)
1091 struct netr_DsRGetDCNameEx2 r2;
1096 r2.in.server_unc = r->in.server_unc;
1097 r2.in.client_account = NULL;
1099 r2.in.domain_name = r->in.domain_name;
1100 r2.in.domain_guid = r->in.domain_guid;
1102 r2.in.site_name = NULL; /* should fill in from site GUID */
1103 r2.in.flags = r->in.flags;
1106 werr = dcesrv_netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1108 r->out.info = r2.out.info;
1114 netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN
1116 static WERROR dcesrv_netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1117 struct netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN *r)
1119 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1124 netr_NetrEnumerateTrustedDomainsEx
1126 static WERROR dcesrv_netr_NetrEnumerateTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1127 struct netr_NetrEnumerateTrustedDomainsEx *r)
1129 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1134 netr_DsRAddressToSitenamesExW
1136 static WERROR dcesrv_netr_DsRAddressToSitenamesExW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1137 struct netr_DsRAddressToSitenamesExW *r)
1139 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1144 netr_DsrGetDcSiteCoverageW
1146 static WERROR dcesrv_netr_DsrGetDcSiteCoverageW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1147 struct netr_DsrGetDcSiteCoverageW *r)
1149 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1154 netr_DsrEnumerateDomainTrusts
1156 static WERROR dcesrv_netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1157 struct netr_DsrEnumerateDomainTrusts *r)
1159 struct netr_DomainTrust *trusts;
1162 struct ldb_message **dom_res, **ref_res;
1163 const char * const dom_attrs[] = { "objectSid", "objectGUID", NULL };
1164 const char * const ref_attrs[] = { "nETBIOSName", "dnsRoot", NULL };
1165 struct ldb_dn *partitions_basedn;
1167 ZERO_STRUCT(r->out);
1169 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
1170 if (sam_ctx == NULL) {
1171 return WERR_GENERAL_FAILURE;
1174 partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);
1176 ret = gendb_search_dn(sam_ctx, mem_ctx, NULL, &dom_res, dom_attrs);
1178 return WERR_GENERAL_FAILURE;
1181 return WERR_GENERAL_FAILURE;
1184 ret = gendb_search(sam_ctx, mem_ctx, partitions_basedn, &ref_res, ref_attrs,
1185 "(&(objectClass=crossRef)(ncName=%s))",
1186 ldb_dn_get_linearized(dom_res[0]->dn));
1188 return WERR_GENERAL_FAILURE;
1191 return WERR_GENERAL_FAILURE;
1194 trusts = talloc_array(mem_ctx, struct netr_DomainTrust, ret);
1195 W_ERROR_HAVE_NO_MEMORY(trusts);
1198 r->out.trusts = trusts;
1200 /* TODO: add filtering by trust_flags, and correct trust_type
1202 trusts[0].netbios_name = samdb_result_string(ref_res[0], "nETBIOSName", NULL);
1203 trusts[0].dns_name = samdb_result_string(ref_res[0], "dnsRoot", NULL);
1204 trusts[0].trust_flags =
1205 NETR_TRUST_FLAG_TREEROOT |
1206 NETR_TRUST_FLAG_IN_FOREST |
1207 NETR_TRUST_FLAG_PRIMARY;
1208 trusts[0].parent_index = 0;
1209 trusts[0].trust_type = 2;
1210 trusts[0].trust_attributes = 0;
1211 trusts[0].sid = samdb_result_dom_sid(mem_ctx, dom_res[0], "objectSid");
1212 trusts[0].guid = samdb_result_guid(dom_res[0], "objectGUID");
1219 netr_DsrDeregisterDNSHostRecords
1221 static WERROR dcesrv_netr_DsrDeregisterDNSHostRecords(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1222 struct netr_DsrDeregisterDNSHostRecords *r)
1224 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1229 netr_ServerTrustPasswordsGet
1231 static NTSTATUS dcesrv_netr_ServerTrustPasswordsGet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1232 struct netr_ServerTrustPasswordsGet *r)
1234 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1239 netr_DsRGetForestTrustInformation
1241 static WERROR dcesrv_netr_DsRGetForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1242 struct netr_DsRGetForestTrustInformation *r)
1244 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1249 netr_GetForestTrustInformation
1251 static WERROR dcesrv_netr_GetForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1252 struct netr_GetForestTrustInformation *r)
1254 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1259 netr_NETRSERVERGETTRUSTINFO
1261 static WERROR dcesrv_netr_NETRSERVERGETTRUSTINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1262 struct netr_NETRSERVERGETTRUSTINFO *r)
1264 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1268 /* include the generated boilerplate */
1269 #include "librpc/gen_ndr/ndr_netlogon_s.c"