2 Unix SMB/CIFS implementation.
4 endpoint server for the netlogon pipe
6 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2008
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"
37 #include "lib/messaging/irpc.h"
38 #include "librpc/gen_ndr/ndr_irpc.h"
39 #include "librpc/gen_ndr/ndr_netlogon.h"
41 struct server_pipe_state {
42 struct netr_Credential client_challenge;
43 struct netr_Credential server_challenge;
47 static NTSTATUS dcesrv_netr_ServerReqChallenge(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
48 struct netr_ServerReqChallenge *r)
50 struct server_pipe_state *pipe_state = dce_call->context->private;
52 ZERO_STRUCTP(r->out.credentials);
54 /* destroyed on pipe shutdown */
57 talloc_free(pipe_state);
58 dce_call->context->private = NULL;
61 pipe_state = talloc(dce_call->context, struct server_pipe_state);
62 NT_STATUS_HAVE_NO_MEMORY(pipe_state);
64 pipe_state->client_challenge = *r->in.credentials;
66 generate_random_buffer(pipe_state->server_challenge.data,
67 sizeof(pipe_state->server_challenge.data));
69 *r->out.credentials = pipe_state->server_challenge;
71 dce_call->context->private = pipe_state;
76 static NTSTATUS dcesrv_netr_ServerAuthenticate3(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
77 struct netr_ServerAuthenticate3 *r)
79 struct server_pipe_state *pipe_state = dce_call->context->private;
80 struct creds_CredentialState *creds;
82 struct samr_Password *mach_pwd;
83 uint32_t user_account_control;
85 struct ldb_message **msgs;
87 const char *attrs[] = {"unicodePwd", "userAccountControl",
90 ZERO_STRUCTP(r->out.credentials);
92 *r->out.negotiate_flags = *r->in.negotiate_flags;
95 DEBUG(1, ("No challenge requested by client, cannot authenticate\n"));
96 return NT_STATUS_ACCESS_DENIED;
99 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx,
100 system_session(mem_ctx, dce_call->conn->dce_ctx->lp_ctx));
101 if (sam_ctx == NULL) {
102 return NT_STATUS_INVALID_SYSTEM_SERVICE;
104 /* pull the user attributes */
105 num_records = gendb_search(sam_ctx, mem_ctx, NULL, &msgs, attrs,
106 "(&(sAMAccountName=%s)(objectclass=user))",
109 if (num_records == 0) {
110 DEBUG(3,("Couldn't find user [%s] in samdb.\n",
111 r->in.account_name));
112 return NT_STATUS_ACCESS_DENIED;
115 if (num_records > 1) {
116 DEBUG(0,("Found %d records matching user [%s]\n", num_records, r->in.account_name));
117 return NT_STATUS_INTERNAL_DB_CORRUPTION;
121 user_account_control = ldb_msg_find_attr_as_uint(msgs[0], "userAccountControl", 0);
123 if (user_account_control & UF_ACCOUNTDISABLE) {
124 DEBUG(1, ("Account [%s] is disabled\n", r->in.account_name));
125 return NT_STATUS_ACCESS_DENIED;
128 if (r->in.secure_channel_type == SEC_CHAN_WKSTA) {
129 if (!(user_account_control & UF_WORKSTATION_TRUST_ACCOUNT)) {
130 DEBUG(1, ("Client asked for a workstation secure channel, but is not a workstation (member server) acb flags: 0x%x\n", user_account_control));
131 return NT_STATUS_ACCESS_DENIED;
133 } else if (r->in.secure_channel_type == SEC_CHAN_DOMAIN) {
134 if (!(user_account_control & UF_INTERDOMAIN_TRUST_ACCOUNT)) {
135 DEBUG(1, ("Client asked for a trusted domain secure channel, but is not a trusted domain: acb flags: 0x%x\n", user_account_control));
137 return NT_STATUS_ACCESS_DENIED;
139 } else if (r->in.secure_channel_type == SEC_CHAN_BDC) {
140 if (!(user_account_control & UF_SERVER_TRUST_ACCOUNT)) {
141 DEBUG(1, ("Client asked for a server secure channel, but is not a server (domain controller): acb flags: 0x%x\n", user_account_control));
142 return NT_STATUS_ACCESS_DENIED;
145 DEBUG(1, ("Client asked for an invalid secure channel type: %d\n",
146 r->in.secure_channel_type));
147 return NT_STATUS_ACCESS_DENIED;
150 *r->out.rid = samdb_result_rid_from_sid(mem_ctx, msgs[0],
153 mach_pwd = samdb_result_hash(mem_ctx, msgs[0], "unicodePwd");
154 if (mach_pwd == NULL) {
155 return NT_STATUS_ACCESS_DENIED;
158 creds = talloc(mem_ctx, struct creds_CredentialState);
159 NT_STATUS_HAVE_NO_MEMORY(creds);
161 creds_server_init(creds, &pipe_state->client_challenge,
162 &pipe_state->server_challenge, mach_pwd,
164 *r->in.negotiate_flags);
166 if (!creds_server_check(creds, r->in.credentials)) {
168 return NT_STATUS_ACCESS_DENIED;
171 creds->account_name = talloc_steal(creds, r->in.account_name);
173 creds->computer_name = talloc_steal(creds, r->in.computer_name);
174 creds->domain = talloc_strdup(creds, lp_workgroup(dce_call->conn->dce_ctx->lp_ctx));
176 creds->secure_channel_type = r->in.secure_channel_type;
178 creds->sid = samdb_result_dom_sid(creds, msgs[0], "objectSid");
181 /* remember this session key state */
182 nt_status = schannel_store_session_key(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, creds);
187 static NTSTATUS dcesrv_netr_ServerAuthenticate(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
188 struct netr_ServerAuthenticate *r)
190 struct netr_ServerAuthenticate3 r3;
193 * negotiate_flags is used as an [in] parameter
194 * so it need to be initialised.
196 * (I think ... = 0; seems wrong here --metze)
198 uint32_t negotiate_flags = 0;
200 r3.in.server_name = r->in.server_name;
201 r3.in.account_name = r->in.account_name;
202 r3.in.secure_channel_type = r->in.secure_channel_type;
203 r3.in.computer_name = r->in.computer_name;
204 r3.in.credentials = r->in.credentials;
205 r3.out.credentials = r->out.credentials;
206 r3.in.negotiate_flags = &negotiate_flags;
207 r3.out.negotiate_flags = &negotiate_flags;
210 return dcesrv_netr_ServerAuthenticate3(dce_call, mem_ctx, &r3);
213 static NTSTATUS dcesrv_netr_ServerAuthenticate2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
214 struct netr_ServerAuthenticate2 *r)
216 struct netr_ServerAuthenticate3 r3;
219 r3.in.server_name = r->in.server_name;
220 r3.in.account_name = r->in.account_name;
221 r3.in.secure_channel_type = r->in.secure_channel_type;
222 r3.in.computer_name = r->in.computer_name;
223 r3.in.credentials = r->in.credentials;
224 r3.out.credentials = r->out.credentials;
225 r3.in.negotiate_flags = r->in.negotiate_flags;
226 r3.out.negotiate_flags = r->out.negotiate_flags;
229 return dcesrv_netr_ServerAuthenticate3(dce_call, mem_ctx, &r3);
233 Validate an incoming authenticator against the credentials for the remote machine.
235 The credentials are (re)read and from the schannel database, and
236 written back after the caclulations are performed.
238 The creds_out parameter (if not NULL) returns the credentials, if
239 the caller needs some of that information.
242 static NTSTATUS dcesrv_netr_creds_server_step_check(struct event_context *event_ctx,
243 struct loadparm_context *lp_ctx,
244 const char *computer_name,
246 struct netr_Authenticator *received_authenticator,
247 struct netr_Authenticator *return_authenticator,
248 struct creds_CredentialState **creds_out)
250 struct creds_CredentialState *creds;
252 struct ldb_context *ldb;
255 ldb = schannel_db_connect(mem_ctx, event_ctx, lp_ctx);
257 return NT_STATUS_ACCESS_DENIED;
260 ret = ldb_transaction_start(ldb);
263 return NT_STATUS_INTERNAL_DB_CORRUPTION;
266 /* Because this is a shared structure (even across
267 * disconnects) we must update the database every time we
268 * update the structure */
270 nt_status = schannel_fetch_session_key_ldb(ldb, ldb, computer_name,
271 lp_workgroup(lp_ctx),
273 if (NT_STATUS_IS_OK(nt_status)) {
274 nt_status = creds_server_step_check(creds,
275 received_authenticator,
276 return_authenticator);
278 if (NT_STATUS_IS_OK(nt_status)) {
279 nt_status = schannel_store_session_key_ldb(ldb, ldb, creds);
282 if (NT_STATUS_IS_OK(nt_status)) {
283 ldb_transaction_commit(ldb);
286 talloc_steal(mem_ctx, creds);
289 ldb_transaction_cancel(ldb);
296 Change the machine account password for the currently connected
297 client. Supplies only the NT#.
300 static NTSTATUS dcesrv_netr_ServerPasswordSet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
301 struct netr_ServerPasswordSet *r)
303 struct creds_CredentialState *creds;
304 struct ldb_context *sam_ctx;
307 nt_status = dcesrv_netr_creds_server_step_check(dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx,
308 r->in.computer_name, mem_ctx,
309 &r->in.credential, &r->out.return_authenticator,
311 NT_STATUS_NOT_OK_RETURN(nt_status);
313 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));
314 if (sam_ctx == NULL) {
315 return NT_STATUS_INVALID_SYSTEM_SERVICE;
318 creds_des_decrypt(creds, &r->in.new_password);
320 /* Using the sid for the account as the key, set the password */
321 nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
323 NULL, /* Don't have plaintext */
324 NULL, &r->in.new_password,
325 false, /* This is not considered a password change */
331 Change the machine account password for the currently connected
332 client. Supplies new plaintext.
334 static NTSTATUS dcesrv_netr_ServerPasswordSet2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
335 struct netr_ServerPasswordSet2 *r)
337 struct creds_CredentialState *creds;
338 struct ldb_context *sam_ctx;
343 struct samr_CryptPassword password_buf;
345 nt_status = dcesrv_netr_creds_server_step_check(dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx,
346 r->in.computer_name, mem_ctx,
347 &r->in.credential, &r->out.return_authenticator,
349 NT_STATUS_NOT_OK_RETURN(nt_status);
351 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));
352 if (sam_ctx == NULL) {
353 return NT_STATUS_INVALID_SYSTEM_SERVICE;
356 memcpy(password_buf.data, r->in.new_password.data, 512);
357 SIVAL(password_buf.data,512,r->in.new_password.length);
358 creds_arcfour_crypt(creds, password_buf.data, 516);
360 ret = decode_pw_buffer(password_buf.data, new_pass, sizeof(new_pass),
363 DEBUG(3,("netr_ServerPasswordSet2: failed to decode password buffer\n"));
364 return NT_STATUS_ACCESS_DENIED;
367 /* Using the sid for the account as the key, set the password */
368 nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
370 new_pass, /* we have plaintext */
372 false, /* This is not considered a password change */
381 static WERROR dcesrv_netr_LogonUasLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
382 struct netr_LogonUasLogon *r)
384 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
391 static WERROR dcesrv_netr_LogonUasLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
392 struct netr_LogonUasLogoff *r)
394 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
399 netr_LogonSamLogon_base
401 This version of the function allows other wrappers to say 'do not check the credentials'
403 We can't do the traditional 'wrapping' format completly, as this function must only run under schannel
405 static NTSTATUS dcesrv_netr_LogonSamLogon_base(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
406 struct netr_LogonSamLogonEx *r, struct creds_CredentialState *creds)
408 struct auth_context *auth_context;
409 struct auth_usersupplied_info *user_info;
410 struct auth_serversupplied_info *server_info;
412 static const char zeros[16];
413 struct netr_SamBaseInfo *sam;
414 struct netr_SamInfo2 *sam2;
415 struct netr_SamInfo3 *sam3;
416 struct netr_SamInfo6 *sam6;
418 user_info = talloc(mem_ctx, struct auth_usersupplied_info);
419 NT_STATUS_HAVE_NO_MEMORY(user_info);
421 user_info->flags = 0;
422 user_info->mapped_state = false;
423 user_info->remote_host = NULL;
425 switch (r->in.logon_level) {
426 case NetlogonInteractiveInformation:
427 case NetlogonServiceInformation:
428 case NetlogonInteractiveTransitiveInformation:
429 case NetlogonServiceTransitiveInformation:
430 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
431 creds_arcfour_crypt(creds,
432 r->in.logon.password->lmpassword.hash,
433 sizeof(r->in.logon.password->lmpassword.hash));
434 creds_arcfour_crypt(creds,
435 r->in.logon.password->ntpassword.hash,
436 sizeof(r->in.logon.password->ntpassword.hash));
438 creds_des_decrypt(creds, &r->in.logon.password->lmpassword);
439 creds_des_decrypt(creds, &r->in.logon.password->ntpassword);
442 /* TODO: we need to deny anonymous access here */
443 nt_status = auth_context_create(mem_ctx,
444 dce_call->event_ctx, dce_call->msg_ctx,
445 dce_call->conn->dce_ctx->lp_ctx,
447 NT_STATUS_NOT_OK_RETURN(nt_status);
449 user_info->logon_parameters = r->in.logon.password->identity_info.parameter_control;
450 user_info->client.account_name = r->in.logon.password->identity_info.account_name.string;
451 user_info->client.domain_name = r->in.logon.password->identity_info.domain_name.string;
452 user_info->workstation_name = r->in.logon.password->identity_info.workstation.string;
454 user_info->flags |= USER_INFO_INTERACTIVE_LOGON;
455 user_info->password_state = AUTH_PASSWORD_HASH;
457 user_info->password.hash.lanman = talloc(user_info, struct samr_Password);
458 NT_STATUS_HAVE_NO_MEMORY(user_info->password.hash.lanman);
459 *user_info->password.hash.lanman = r->in.logon.password->lmpassword;
461 user_info->password.hash.nt = talloc(user_info, struct samr_Password);
462 NT_STATUS_HAVE_NO_MEMORY(user_info->password.hash.nt);
463 *user_info->password.hash.nt = r->in.logon.password->ntpassword;
466 case NetlogonNetworkInformation:
467 case NetlogonNetworkTransitiveInformation:
469 /* TODO: we need to deny anonymous access here */
470 nt_status = auth_context_create(mem_ctx,
471 dce_call->event_ctx, dce_call->msg_ctx,
472 dce_call->conn->dce_ctx->lp_ctx,
474 NT_STATUS_NOT_OK_RETURN(nt_status);
476 nt_status = auth_context_set_challenge(auth_context, r->in.logon.network->challenge, "netr_LogonSamLogonWithFlags");
477 NT_STATUS_NOT_OK_RETURN(nt_status);
479 user_info->logon_parameters = r->in.logon.network->identity_info.parameter_control;
480 user_info->client.account_name = r->in.logon.network->identity_info.account_name.string;
481 user_info->client.domain_name = r->in.logon.network->identity_info.domain_name.string;
482 user_info->workstation_name = r->in.logon.network->identity_info.workstation.string;
484 user_info->password_state = AUTH_PASSWORD_RESPONSE;
485 user_info->password.response.lanman = data_blob_talloc(mem_ctx, r->in.logon.network->lm.data, r->in.logon.network->lm.length);
486 user_info->password.response.nt = data_blob_talloc(mem_ctx, r->in.logon.network->nt.data, r->in.logon.network->nt.length);
491 case NetlogonGenericInformation:
493 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
494 creds_arcfour_crypt(creds,
495 r->in.logon.generic->data, r->in.logon.generic->length);
497 /* Using DES to verify kerberos tickets makes no sense */
498 return NT_STATUS_INVALID_PARAMETER;
501 if (strcmp(r->in.logon.generic->package_name.string, "Kerberos") == 0) {
503 struct server_id *kdc;
504 struct kdc_check_generic_kerberos check;
505 struct netr_GenericInfo2 *generic = talloc_zero(mem_ctx, struct netr_GenericInfo2);
506 NT_STATUS_HAVE_NO_MEMORY(generic);
507 r->out.authoritative = 1;
509 /* TODO: Describe and deal with these flags */
512 r->out.validation.generic = generic;
514 kdc = irpc_servers_byname(dce_call->msg_ctx, mem_ctx, "kdc_server");
515 if ((kdc == NULL) || (kdc[0].id == 0)) {
516 return NT_STATUS_NO_LOGON_SERVERS;
519 check.in.generic_request =
520 data_blob_const(r->in.logon.generic->data,
521 r->in.logon.generic->length);
523 status = irpc_call(dce_call->msg_ctx, kdc[0],
524 &ndr_table_irpc, NDR_KDC_CHECK_GENERIC_KERBEROS,
526 if (!NT_STATUS_IS_OK(status)) {
529 generic->length = check.out.generic_reply.length;
530 generic->data = check.out.generic_reply.data;
534 /* Until we get an implemetnation of these other packages */
535 return NT_STATUS_INVALID_PARAMETER;
538 return NT_STATUS_INVALID_PARAMETER;
541 nt_status = auth_check_password(auth_context, mem_ctx, user_info, &server_info);
542 NT_STATUS_NOT_OK_RETURN(nt_status);
544 nt_status = auth_convert_server_info_sambaseinfo(mem_ctx, server_info, &sam);
545 NT_STATUS_NOT_OK_RETURN(nt_status);
547 /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
548 /* It appears that level 6 is not individually encrypted */
549 if ((r->in.validation_level != 6) &&
550 memcmp(sam->key.key, zeros, sizeof(sam->key.key)) != 0) {
551 /* This key is sent unencrypted without the ARCFOUR flag set */
552 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
553 creds_arcfour_crypt(creds,
555 sizeof(sam->key.key));
559 /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
560 /* It appears that level 6 is not individually encrypted */
561 if ((r->in.validation_level != 6) &&
562 memcmp(sam->LMSessKey.key, zeros, sizeof(sam->LMSessKey.key)) != 0) {
563 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
564 creds_arcfour_crypt(creds,
566 sizeof(sam->LMSessKey.key));
568 creds_des_encrypt_LMKey(creds,
573 switch (r->in.validation_level) {
575 sam2 = talloc_zero(mem_ctx, struct netr_SamInfo2);
576 NT_STATUS_HAVE_NO_MEMORY(sam2);
578 r->out.validation.sam2 = sam2;
582 sam3 = talloc_zero(mem_ctx, struct netr_SamInfo3);
583 NT_STATUS_HAVE_NO_MEMORY(sam3);
585 r->out.validation.sam3 = sam3;
589 sam6 = talloc_zero(mem_ctx, struct netr_SamInfo6);
590 NT_STATUS_HAVE_NO_MEMORY(sam6);
592 sam6->forest.string = lp_realm(dce_call->conn->dce_ctx->lp_ctx);
593 sam6->principle.string = talloc_asprintf(mem_ctx, "%s@%s",
594 sam->account_name.string, sam6->forest.string);
595 NT_STATUS_HAVE_NO_MEMORY(sam6->principle.string);
596 r->out.validation.sam6 = sam6;
603 r->out.authoritative = 1;
605 /* TODO: Describe and deal with these flags */
611 static NTSTATUS dcesrv_netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
612 struct netr_LogonSamLogonEx *r)
615 struct creds_CredentialState *creds;
616 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);
617 if (!NT_STATUS_IS_OK(nt_status)) {
621 if (!dce_call->conn->auth_state.auth_info ||
622 dce_call->conn->auth_state.auth_info->auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
623 return NT_STATUS_INTERNAL_ERROR;
625 return dcesrv_netr_LogonSamLogon_base(dce_call, mem_ctx, r, creds);
629 netr_LogonSamLogonWithFlags
632 static NTSTATUS dcesrv_netr_LogonSamLogonWithFlags(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
633 struct netr_LogonSamLogonWithFlags *r)
636 struct creds_CredentialState *creds;
637 struct netr_LogonSamLogonEx r2;
639 struct netr_Authenticator *return_authenticator;
641 return_authenticator = talloc(mem_ctx, struct netr_Authenticator);
642 NT_STATUS_HAVE_NO_MEMORY(return_authenticator);
644 nt_status = dcesrv_netr_creds_server_step_check(dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx,
645 r->in.computer_name, mem_ctx,
646 r->in.credential, return_authenticator,
648 NT_STATUS_NOT_OK_RETURN(nt_status);
652 r2.in.server_name = r->in.server_name;
653 r2.in.computer_name = r->in.computer_name;
654 r2.in.logon_level = r->in.logon_level;
655 r2.in.logon = r->in.logon;
656 r2.in.validation_level = r->in.validation_level;
657 r2.in.flags = r->in.flags;
659 nt_status = dcesrv_netr_LogonSamLogon_base(dce_call, mem_ctx, &r2, creds);
661 r->out.return_authenticator = return_authenticator;
662 r->out.validation = r2.out.validation;
663 r->out.authoritative = r2.out.authoritative;
664 r->out.flags = r2.out.flags;
672 static NTSTATUS dcesrv_netr_LogonSamLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
673 struct netr_LogonSamLogon *r)
675 struct netr_LogonSamLogonWithFlags r2;
680 r2.in.server_name = r->in.server_name;
681 r2.in.computer_name = r->in.computer_name;
682 r2.in.credential = r->in.credential;
683 r2.in.return_authenticator = r->in.return_authenticator;
684 r2.in.logon_level = r->in.logon_level;
685 r2.in.logon = r->in.logon;
686 r2.in.validation_level = r->in.validation_level;
689 status = dcesrv_netr_LogonSamLogonWithFlags(dce_call, mem_ctx, &r2);
691 r->out.return_authenticator = r2.out.return_authenticator;
692 r->out.validation = r2.out.validation;
693 r->out.authoritative = r2.out.authoritative;
702 static NTSTATUS dcesrv_netr_LogonSamLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
703 struct netr_LogonSamLogoff *r)
705 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
713 static NTSTATUS dcesrv_netr_DatabaseDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
714 struct netr_DatabaseDeltas *r)
716 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
723 static NTSTATUS dcesrv_netr_DatabaseSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
724 struct netr_DatabaseSync *r)
726 /* win2k3 native mode returns "NOT IMPLEMENTED" for this call */
727 return NT_STATUS_NOT_IMPLEMENTED;
734 static NTSTATUS dcesrv_netr_AccountDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
735 struct netr_AccountDeltas *r)
737 /* w2k3 returns "NOT IMPLEMENTED" for this call */
738 return NT_STATUS_NOT_IMPLEMENTED;
745 static NTSTATUS dcesrv_netr_AccountSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
746 struct netr_AccountSync *r)
748 /* w2k3 returns "NOT IMPLEMENTED" for this call */
749 return NT_STATUS_NOT_IMPLEMENTED;
756 static WERROR dcesrv_netr_GetDcName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
757 struct netr_GetDcName *r)
759 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
766 static WERROR dcesrv_netr_LogonControl(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
767 struct netr_LogonControl *r)
769 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
776 static WERROR dcesrv_netr_GetAnyDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
777 struct netr_GetAnyDCName *r)
779 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
786 static WERROR dcesrv_netr_LogonControl2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
787 struct netr_LogonControl2 *r)
789 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
796 static NTSTATUS dcesrv_netr_DatabaseSync2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
797 struct netr_DatabaseSync2 *r)
799 /* win2k3 native mode returns "NOT IMPLEMENTED" for this call */
800 return NT_STATUS_NOT_IMPLEMENTED;
807 static NTSTATUS dcesrv_netr_DatabaseRedo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
808 struct netr_DatabaseRedo *r)
810 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
817 static WERROR dcesrv_netr_LogonControl2Ex(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
818 struct netr_LogonControl2Ex *r)
820 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
825 netr_NetrEnumerateTurstedDomains
827 static WERROR dcesrv_netr_NetrEnumerateTrustedDomains(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
828 struct netr_NetrEnumerateTrustedDomains *r)
830 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
835 netr_NETRLOGONDUMMYROUTINE1
837 static WERROR dcesrv_netr_NETRLOGONDUMMYROUTINE1(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
838 struct netr_NETRLOGONDUMMYROUTINE1 *r)
840 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
845 netr_NETRLOGONSETSERVICEBITS
847 static WERROR dcesrv_netr_NETRLOGONSETSERVICEBITS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
848 struct netr_NETRLOGONSETSERVICEBITS *r)
850 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
855 netr_LogonGetTrustRid
857 static WERROR dcesrv_netr_LogonGetTrustRid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
858 struct netr_LogonGetTrustRid *r)
860 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
865 netr_NETRLOGONCOMPUTESERVERDIGEST
867 static WERROR dcesrv_netr_NETRLOGONCOMPUTESERVERDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
868 struct netr_NETRLOGONCOMPUTESERVERDIGEST *r)
870 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
875 netr_NETRLOGONCOMPUTECLIENTDIGEST
877 static WERROR dcesrv_netr_NETRLOGONCOMPUTECLIENTDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
878 struct netr_NETRLOGONCOMPUTECLIENTDIGEST *r)
880 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
888 static WERROR dcesrv_netr_DsRGetSiteName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
889 struct netr_DsRGetSiteName *r)
891 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
896 fill in a netr_DomainTrustInfo from a ldb search result
898 static NTSTATUS fill_domain_trust_info(TALLOC_CTX *mem_ctx,
899 struct ldb_message *res,
900 struct ldb_message *ref_res,
901 struct netr_DomainTrustInfo *info,
902 bool is_local, bool is_trust_list)
906 info->trust_extension.info = talloc_zero(mem_ctx, struct netr_trust_extension);
907 info->trust_extension.length = 16;
908 info->trust_extension.info->flags =
909 NETR_TRUST_FLAG_TREEROOT |
910 NETR_TRUST_FLAG_IN_FOREST |
911 NETR_TRUST_FLAG_PRIMARY;
912 info->trust_extension.info->parent_index = 0; /* should be index into array
914 info->trust_extension.info->trust_type = LSA_TRUST_TYPE_UPLEVEL; /* should be based on ldb search for trusts */
915 info->trust_extension.info->trust_attributes = LSA_TRUST_ATTRIBUTE_NON_TRANSITIVE; /* needs to be based on ldb search */
918 /* MS-NRPC 3.5.4.3.9 - must be set to NULL for trust list */
919 info->forest.string = NULL;
921 info->forest.string = "bludom.tridgell.net"; /* need ldb search */
925 info->domainname.string = samdb_result_string(ref_res, "nETBIOSName", NULL);
926 info->fulldomainname.string = samdb_result_string(ref_res, "dnsRoot", NULL);
927 info->guid = samdb_result_guid(res, "objectGUID");
928 info->sid = samdb_result_dom_sid(mem_ctx, res, "objectSid");
930 info->domainname.string = samdb_result_string(res, "flatName", NULL);
931 info->fulldomainname.string = samdb_result_string(res, "trustPartner", NULL);
932 info->guid = samdb_result_guid(res, "objectGUID");
933 info->sid = samdb_result_dom_sid(mem_ctx, res, "securityIdentifier");
940 netr_LogonGetDomainInfo
941 this is called as part of the ADS domain logon procedure.
943 It has an important role in convaying details about the client, such
944 as Operating System, Version, Service Pack etc.
946 static NTSTATUS dcesrv_netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
947 struct netr_LogonGetDomainInfo *r)
949 const char * const attrs[] = { "objectSid",
950 "objectGUID", "flatName", "securityIdentifier",
951 "trustPartner", NULL };
952 const char * const ref_attrs[] = { "nETBIOSName", "dnsRoot", NULL };
953 struct ldb_context *sam_ctx;
954 struct ldb_message **res1, **res2, **ref_res;
955 struct netr_DomainInfo1 *info1;
956 int ret, ret1, ret2, i;
958 struct ldb_dn *partitions_basedn;
960 const char *local_domain;
962 status = dcesrv_netr_creds_server_step_check(dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx,
963 r->in.computer_name, mem_ctx,
965 r->out.return_authenticator,
967 if (!NT_STATUS_IS_OK(status)) {
968 DEBUG(0,(__location__ " Bad credentials - error\n"));
970 NT_STATUS_NOT_OK_RETURN(status);
972 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
973 if (sam_ctx == NULL) {
974 return NT_STATUS_INVALID_SYSTEM_SERVICE;
977 partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);
979 /* we need to do two searches. The first will pull our primary
980 domain and the second will pull any trusted domains. Our
981 primary domain is also a "trusted" domain, so we need to
982 put the primary domain into the lists of returned trusts as
984 ret1 = gendb_search_dn(sam_ctx, mem_ctx, samdb_base_dn(sam_ctx), &res1, attrs);
986 return NT_STATUS_INTERNAL_DB_CORRUPTION;
989 /* try and find the domain */
990 ret = gendb_search(sam_ctx, mem_ctx, partitions_basedn,
992 "(&(objectClass=crossRef)(ncName=%s))",
993 ldb_dn_get_linearized(res1[0]->dn));
995 return NT_STATUS_INTERNAL_DB_CORRUPTION;
998 local_domain = samdb_result_string(ref_res[0], "nETBIOSName", NULL);
1000 ret2 = gendb_search(sam_ctx, mem_ctx, NULL, &res2, attrs, "(objectClass=trustedDomain)");
1002 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1005 info1 = talloc(mem_ctx, struct netr_DomainInfo1);
1006 NT_STATUS_HAVE_NO_MEMORY(info1);
1008 ZERO_STRUCTP(info1);
1010 info1->num_trusts = ret2 + 1;
1011 info1->trusts = talloc_array(mem_ctx, struct netr_DomainTrustInfo,
1013 NT_STATUS_HAVE_NO_MEMORY(info1->trusts);
1015 status = fill_domain_trust_info(mem_ctx, res1[0], ref_res[0], &info1->domaininfo,
1017 NT_STATUS_NOT_OK_RETURN(status);
1019 for (i=0;i<ret2;i++) {
1020 status = fill_domain_trust_info(mem_ctx, res2[i], NULL, &info1->trusts[i],
1022 NT_STATUS_NOT_OK_RETURN(status);
1025 status = fill_domain_trust_info(mem_ctx, res1[0], ref_res[0], &info1->trusts[i],
1027 NT_STATUS_NOT_OK_RETURN(status);
1029 info1->dns_hostname.string = "blu.bludom.tridgell.net";
1030 info1->workstation_flags =
1031 NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS | NETR_WS_FLAG_HANDLES_SPN_UPDATE;
1032 info1->supported_enc_types = 0; /* w2008 gives this 0 */
1034 r->out.info.info1 = info1;
1036 return NT_STATUS_OK;
1042 netr_ServerPasswordGet
1044 static WERROR dcesrv_netr_ServerPasswordGet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1045 struct netr_ServerPasswordGet *r)
1047 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1052 netr_NETRLOGONSENDTOSAM
1054 static WERROR dcesrv_netr_NETRLOGONSENDTOSAM(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1055 struct netr_NETRLOGONSENDTOSAM *r)
1057 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1062 netr_DsRAddressToSitenamesW
1064 static WERROR dcesrv_netr_DsRAddressToSitenamesW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1065 struct netr_DsRAddressToSitenamesW *r)
1067 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1072 netr_DsRGetDCNameEx2
1074 static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1075 struct netr_DsRGetDCNameEx2 *r)
1077 const char * const attrs[] = { "dnsDomain", "objectGUID", NULL };
1079 struct ldb_message **res;
1080 struct ldb_dn *domain_dn;
1083 ZERO_STRUCT(r->out);
1085 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
1086 if (sam_ctx == NULL) {
1087 return WERR_DS_SERVICE_UNAVAILABLE;
1090 domain_dn = samdb_dns_domain_to_dn(sam_ctx, mem_ctx,
1092 if (domain_dn == NULL) {
1093 return WERR_DS_SERVICE_UNAVAILABLE;
1096 ret = gendb_search_dn(sam_ctx, mem_ctx, domain_dn, &res, attrs);
1098 return WERR_NO_SUCH_DOMAIN;
1101 r->out.info = talloc(mem_ctx, struct netr_DsRGetDCNameInfo);
1102 W_ERROR_HAVE_NO_MEMORY(r->out.info);
1104 /* TODO: - return real IP address
1105 * - check all r->in.* parameters (server_unc is ignored by w2k3!)
1107 r->out.info->dc_unc = talloc_asprintf(mem_ctx, "\\\\%s.%s",
1108 lp_netbios_name(dce_call->conn->dce_ctx->lp_ctx),
1109 lp_realm(dce_call->conn->dce_ctx->lp_ctx));
1110 W_ERROR_HAVE_NO_MEMORY(r->out.info->dc_unc);
1111 r->out.info->dc_address = talloc_strdup(mem_ctx, "\\\\0.0.0.0");
1112 W_ERROR_HAVE_NO_MEMORY(r->out.info->dc_address);
1113 r->out.info->dc_address_type = DS_ADDRESS_TYPE_INET;
1114 r->out.info->domain_guid = samdb_result_guid(res[0], "objectGUID");
1115 r->out.info->domain_name = samdb_result_string(res[0], "dnsDomain", NULL);
1116 r->out.info->forest_name = samdb_result_string(res[0], "dnsDomain", NULL);
1117 r->out.info->dc_flags = DS_DNS_FOREST |
1120 DS_SERVER_WRITABLE |
1122 DS_SERVER_TIMESERV |
1128 r->out.info->dc_site_name = talloc_strdup(mem_ctx, "Default-First-Site-Name");
1129 W_ERROR_HAVE_NO_MEMORY(r->out.info->dc_site_name);
1130 r->out.info->client_site_name = talloc_strdup(mem_ctx, "Default-First-Site-Name");
1131 W_ERROR_HAVE_NO_MEMORY(r->out.info->client_site_name);
1139 static WERROR dcesrv_netr_DsRGetDCNameEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1140 struct netr_DsRGetDCNameEx *r)
1142 struct netr_DsRGetDCNameEx2 r2;
1147 r2.in.server_unc = r->in.server_unc;
1148 r2.in.client_account = NULL;
1150 r2.in.domain_guid = r->in.domain_guid;
1151 r2.in.domain_name = r->in.domain_name;
1152 r2.in.site_name = r->in.site_name;
1153 r2.in.flags = r->in.flags;
1156 werr = dcesrv_netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1158 r->out.info = r2.out.info;
1166 static WERROR dcesrv_netr_DsRGetDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1167 struct netr_DsRGetDCName *r)
1169 struct netr_DsRGetDCNameEx2 r2;
1174 r2.in.server_unc = r->in.server_unc;
1175 r2.in.client_account = NULL;
1177 r2.in.domain_name = r->in.domain_name;
1178 r2.in.domain_guid = r->in.domain_guid;
1180 r2.in.site_name = NULL; /* should fill in from site GUID */
1181 r2.in.flags = r->in.flags;
1184 werr = dcesrv_netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1186 r->out.info = r2.out.info;
1192 netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN
1194 static WERROR dcesrv_netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1195 struct netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN *r)
1197 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1202 netr_NetrEnumerateTrustedDomainsEx
1204 static WERROR dcesrv_netr_NetrEnumerateTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1205 struct netr_NetrEnumerateTrustedDomainsEx *r)
1207 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1212 netr_DsRAddressToSitenamesExW
1214 static WERROR dcesrv_netr_DsRAddressToSitenamesExW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1215 struct netr_DsRAddressToSitenamesExW *r)
1217 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1222 netr_DsrGetDcSiteCoverageW
1224 static WERROR dcesrv_netr_DsrGetDcSiteCoverageW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1225 struct netr_DsrGetDcSiteCoverageW *r)
1227 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1232 netr_DsrEnumerateDomainTrusts
1234 static WERROR dcesrv_netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1235 struct netr_DsrEnumerateDomainTrusts *r)
1237 struct netr_DomainTrust *trusts;
1240 struct ldb_message **dom_res, **ref_res;
1241 const char * const dom_attrs[] = { "objectSid", "objectGUID", NULL };
1242 const char * const ref_attrs[] = { "nETBIOSName", "dnsRoot", NULL };
1243 struct ldb_dn *partitions_basedn;
1245 ZERO_STRUCT(r->out);
1247 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
1248 if (sam_ctx == NULL) {
1249 return WERR_GENERAL_FAILURE;
1252 partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);
1254 ret = gendb_search_dn(sam_ctx, mem_ctx, NULL, &dom_res, dom_attrs);
1256 return WERR_GENERAL_FAILURE;
1259 return WERR_GENERAL_FAILURE;
1262 ret = gendb_search(sam_ctx, mem_ctx, partitions_basedn, &ref_res, ref_attrs,
1263 "(&(objectClass=crossRef)(ncName=%s))",
1264 ldb_dn_get_linearized(dom_res[0]->dn));
1266 return WERR_GENERAL_FAILURE;
1269 return WERR_GENERAL_FAILURE;
1272 trusts = talloc_array(mem_ctx, struct netr_DomainTrust, ret);
1273 W_ERROR_HAVE_NO_MEMORY(trusts);
1276 r->out.trusts = trusts;
1278 /* TODO: add filtering by trust_flags, and correct trust_type
1280 trusts[0].netbios_name = samdb_result_string(ref_res[0], "nETBIOSName", NULL);
1281 trusts[0].dns_name = samdb_result_string(ref_res[0], "dnsRoot", NULL);
1282 trusts[0].trust_flags =
1283 NETR_TRUST_FLAG_TREEROOT |
1284 NETR_TRUST_FLAG_IN_FOREST |
1285 NETR_TRUST_FLAG_PRIMARY;
1286 trusts[0].parent_index = 0;
1287 trusts[0].trust_type = 2;
1288 trusts[0].trust_attributes = 0;
1289 trusts[0].sid = samdb_result_dom_sid(mem_ctx, dom_res[0], "objectSid");
1290 trusts[0].guid = samdb_result_guid(dom_res[0], "objectGUID");
1297 netr_DsrDeregisterDNSHostRecords
1299 static WERROR dcesrv_netr_DsrDeregisterDNSHostRecords(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1300 struct netr_DsrDeregisterDNSHostRecords *r)
1302 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1307 netr_ServerTrustPasswordsGet
1309 static NTSTATUS dcesrv_netr_ServerTrustPasswordsGet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1310 struct netr_ServerTrustPasswordsGet *r)
1312 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1317 netr_DsRGetForestTrustInformation
1319 static WERROR dcesrv_netr_DsRGetForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1320 struct netr_DsRGetForestTrustInformation *r)
1322 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1327 netr_GetForestTrustInformation
1329 static WERROR dcesrv_netr_GetForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1330 struct netr_GetForestTrustInformation *r)
1332 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1337 netr_NETRSERVERGETTRUSTINFO
1339 static WERROR dcesrv_netr_NETRSERVERGETTRUSTINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1340 struct netr_NETRSERVERGETTRUSTINFO *r)
1342 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1346 /* include the generated boilerplate */
1347 #include "librpc/gen_ndr/ndr_netlogon_s.c"