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"
40 struct server_pipe_state {
41 struct netr_Credential client_challenge;
42 struct netr_Credential server_challenge;
46 static NTSTATUS dcesrv_netr_ServerReqChallenge(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
47 struct netr_ServerReqChallenge *r)
49 struct server_pipe_state *pipe_state = dce_call->context->private;
51 ZERO_STRUCTP(r->out.credentials);
53 /* destroyed on pipe shutdown */
56 talloc_free(pipe_state);
57 dce_call->context->private = NULL;
60 pipe_state = talloc(dce_call->context, struct server_pipe_state);
61 NT_STATUS_HAVE_NO_MEMORY(pipe_state);
63 pipe_state->client_challenge = *r->in.credentials;
65 generate_random_buffer(pipe_state->server_challenge.data,
66 sizeof(pipe_state->server_challenge.data));
68 *r->out.credentials = pipe_state->server_challenge;
70 dce_call->context->private = pipe_state;
75 static NTSTATUS dcesrv_netr_ServerAuthenticate3(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
76 struct netr_ServerAuthenticate3 *r)
78 struct server_pipe_state *pipe_state = dce_call->context->private;
79 struct creds_CredentialState *creds;
81 struct samr_Password *mach_pwd;
82 uint32_t user_account_control;
84 struct ldb_message **msgs;
86 const char *attrs[] = {"unicodePwd", "userAccountControl",
89 ZERO_STRUCTP(r->out.credentials);
91 *r->out.negotiate_flags = *r->in.negotiate_flags;
94 DEBUG(1, ("No challenge requested by client, cannot authenticate\n"));
95 return NT_STATUS_ACCESS_DENIED;
98 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx,
99 system_session(mem_ctx, dce_call->conn->dce_ctx->lp_ctx));
100 if (sam_ctx == NULL) {
101 return NT_STATUS_INVALID_SYSTEM_SERVICE;
103 /* pull the user attributes */
104 num_records = gendb_search(sam_ctx, mem_ctx, NULL, &msgs, attrs,
105 "(&(sAMAccountName=%s)(objectclass=user))",
108 if (num_records == 0) {
109 DEBUG(3,("Couldn't find user [%s] in samdb.\n",
110 r->in.account_name));
111 return NT_STATUS_ACCESS_DENIED;
114 if (num_records > 1) {
115 DEBUG(0,("Found %d records matching user [%s]\n", num_records, r->in.account_name));
116 return NT_STATUS_INTERNAL_DB_CORRUPTION;
120 user_account_control = ldb_msg_find_attr_as_uint(msgs[0], "userAccountControl", 0);
122 if (user_account_control & UF_ACCOUNTDISABLE) {
123 DEBUG(1, ("Account [%s] is disabled\n", r->in.account_name));
124 return NT_STATUS_ACCESS_DENIED;
127 if (r->in.secure_channel_type == SEC_CHAN_WKSTA) {
128 if (!(user_account_control & UF_WORKSTATION_TRUST_ACCOUNT)) {
129 DEBUG(1, ("Client asked for a workstation secure channel, but is not a workstation (member server) acb flags: 0x%x\n", user_account_control));
130 return NT_STATUS_ACCESS_DENIED;
132 } else if (r->in.secure_channel_type == SEC_CHAN_DOMAIN) {
133 if (!(user_account_control & UF_INTERDOMAIN_TRUST_ACCOUNT)) {
134 DEBUG(1, ("Client asked for a trusted domain secure channel, but is not a trusted domain: acb flags: 0x%x\n", user_account_control));
136 return NT_STATUS_ACCESS_DENIED;
138 } else if (r->in.secure_channel_type == SEC_CHAN_BDC) {
139 if (!(user_account_control & UF_SERVER_TRUST_ACCOUNT)) {
140 DEBUG(1, ("Client asked for a server secure channel, but is not a server (domain controller): acb flags: 0x%x\n", user_account_control));
141 return NT_STATUS_ACCESS_DENIED;
144 DEBUG(1, ("Client asked for an invalid secure channel type: %d\n",
145 r->in.secure_channel_type));
146 return NT_STATUS_ACCESS_DENIED;
149 *r->out.rid = samdb_result_rid_from_sid(mem_ctx, msgs[0],
152 mach_pwd = samdb_result_hash(mem_ctx, msgs[0], "unicodePwd");
153 if (mach_pwd == NULL) {
154 return NT_STATUS_ACCESS_DENIED;
157 creds = talloc(mem_ctx, struct creds_CredentialState);
158 NT_STATUS_HAVE_NO_MEMORY(creds);
160 creds_server_init(creds, &pipe_state->client_challenge,
161 &pipe_state->server_challenge, mach_pwd,
163 *r->in.negotiate_flags);
165 if (!creds_server_check(creds, r->in.credentials)) {
167 return NT_STATUS_ACCESS_DENIED;
170 creds->account_name = talloc_steal(creds, r->in.account_name);
172 creds->computer_name = talloc_steal(creds, r->in.computer_name);
173 creds->domain = talloc_strdup(creds, lp_workgroup(dce_call->conn->dce_ctx->lp_ctx));
175 creds->secure_channel_type = r->in.secure_channel_type;
177 creds->sid = samdb_result_dom_sid(creds, msgs[0], "objectSid");
180 /* remember this session key state */
181 nt_status = schannel_store_session_key(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, creds);
186 static NTSTATUS dcesrv_netr_ServerAuthenticate(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
187 struct netr_ServerAuthenticate *r)
189 struct netr_ServerAuthenticate3 r3;
192 * negotiate_flags is used as an [in] parameter
193 * so it need to be initialised.
195 * (I think ... = 0; seems wrong here --metze)
197 uint32_t negotiate_flags = 0;
199 r3.in.server_name = r->in.server_name;
200 r3.in.account_name = r->in.account_name;
201 r3.in.secure_channel_type = r->in.secure_channel_type;
202 r3.in.computer_name = r->in.computer_name;
203 r3.in.credentials = r->in.credentials;
204 r3.out.credentials = r->out.credentials;
205 r3.in.negotiate_flags = &negotiate_flags;
206 r3.out.negotiate_flags = &negotiate_flags;
209 return dcesrv_netr_ServerAuthenticate3(dce_call, mem_ctx, &r3);
212 static NTSTATUS dcesrv_netr_ServerAuthenticate2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
213 struct netr_ServerAuthenticate2 *r)
215 struct netr_ServerAuthenticate3 r3;
218 r3.in.server_name = r->in.server_name;
219 r3.in.account_name = r->in.account_name;
220 r3.in.secure_channel_type = r->in.secure_channel_type;
221 r3.in.computer_name = r->in.computer_name;
222 r3.in.credentials = r->in.credentials;
223 r3.out.credentials = r->out.credentials;
224 r3.in.negotiate_flags = r->in.negotiate_flags;
225 r3.out.negotiate_flags = r->out.negotiate_flags;
228 return dcesrv_netr_ServerAuthenticate3(dce_call, mem_ctx, &r3);
232 Validate an incoming authenticator against the credentials for the remote machine.
234 The credentials are (re)read and from the schannel database, and
235 written back after the caclulations are performed.
237 The creds_out parameter (if not NULL) returns the credentials, if
238 the caller needs some of that information.
241 static NTSTATUS dcesrv_netr_creds_server_step_check(struct event_context *event_ctx,
242 struct loadparm_context *lp_ctx,
243 const char *computer_name,
245 struct netr_Authenticator *received_authenticator,
246 struct netr_Authenticator *return_authenticator,
247 struct creds_CredentialState **creds_out)
249 struct creds_CredentialState *creds;
251 struct ldb_context *ldb;
254 ldb = schannel_db_connect(mem_ctx, event_ctx, lp_ctx);
256 return NT_STATUS_ACCESS_DENIED;
259 ret = ldb_transaction_start(ldb);
262 return NT_STATUS_INTERNAL_DB_CORRUPTION;
265 /* Because this is a shared structure (even across
266 * disconnects) we must update the database every time we
267 * update the structure */
269 nt_status = schannel_fetch_session_key_ldb(ldb, ldb, computer_name,
270 lp_workgroup(lp_ctx),
272 if (NT_STATUS_IS_OK(nt_status)) {
273 nt_status = creds_server_step_check(creds,
274 received_authenticator,
275 return_authenticator);
277 if (NT_STATUS_IS_OK(nt_status)) {
278 nt_status = schannel_store_session_key_ldb(ldb, ldb, creds);
281 if (NT_STATUS_IS_OK(nt_status)) {
282 ldb_transaction_commit(ldb);
285 talloc_steal(mem_ctx, creds);
288 ldb_transaction_cancel(ldb);
295 Change the machine account password for the currently connected
296 client. Supplies only the NT#.
299 static NTSTATUS dcesrv_netr_ServerPasswordSet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
300 struct netr_ServerPasswordSet *r)
302 struct creds_CredentialState *creds;
303 struct ldb_context *sam_ctx;
306 nt_status = dcesrv_netr_creds_server_step_check(dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx,
307 r->in.computer_name, mem_ctx,
308 &r->in.credential, &r->out.return_authenticator,
310 NT_STATUS_NOT_OK_RETURN(nt_status);
312 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));
313 if (sam_ctx == NULL) {
314 return NT_STATUS_INVALID_SYSTEM_SERVICE;
317 creds_des_decrypt(creds, &r->in.new_password);
319 /* Using the sid for the account as the key, set the password */
320 nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
322 NULL, /* Don't have plaintext */
323 NULL, &r->in.new_password,
324 false, /* This is not considered a password change */
330 Change the machine account password for the currently connected
331 client. Supplies new plaintext.
333 static NTSTATUS dcesrv_netr_ServerPasswordSet2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
334 struct netr_ServerPasswordSet2 *r)
336 struct creds_CredentialState *creds;
337 struct ldb_context *sam_ctx;
340 uint32_t new_pass_len;
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),
361 &new_pass_len, STR_UNICODE);
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,
907 info->domainname.string = samdb_result_string(ref_res, "nETBIOSName", NULL);
908 info->fulldomainname.string = samdb_result_string(ref_res, "dnsRoot", NULL);
909 info->forest.string = NULL;
910 info->guid = samdb_result_guid(res, "objectGUID");
911 info->sid = samdb_result_dom_sid(mem_ctx, res, "objectSid");
913 info->domainname.string = samdb_result_string(res, "flatName", NULL);
914 info->fulldomainname.string = samdb_result_string(res, "trustPartner", NULL);
915 info->forest.string = NULL;
916 info->guid = samdb_result_guid(res, "objectGUID");
917 info->sid = samdb_result_dom_sid(mem_ctx, res, "securityIdentifier");
924 netr_LogonGetDomainInfo
925 this is called as part of the ADS domain logon procedure.
927 It has an important role in convaying details about the client, such
928 as Operating System, Version, Service Pack etc.
930 static NTSTATUS dcesrv_netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
931 struct netr_LogonGetDomainInfo *r)
933 const char * const attrs[] = { "objectSid",
934 "objectGUID", "flatName", "securityIdentifier",
935 "trustPartner", NULL };
936 const char * const ref_attrs[] = { "nETBIOSName", "dnsRoot", NULL };
937 struct ldb_context *sam_ctx;
938 struct ldb_message **res1, **res2, **ref_res;
939 struct netr_DomainInfo1 *info1;
940 int ret, ret1, ret2, i;
942 struct ldb_dn *partitions_basedn;
944 const char *local_domain;
946 status = dcesrv_netr_creds_server_step_check(dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx,
947 r->in.computer_name, mem_ctx,
949 r->out.return_authenticator,
951 NT_STATUS_NOT_OK_RETURN(status);
953 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
954 if (sam_ctx == NULL) {
955 return NT_STATUS_INVALID_SYSTEM_SERVICE;
958 partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);
960 /* we need to do two searches. The first will pull our primary
961 domain and the second will pull any trusted domains. Our
962 primary domain is also a "trusted" domain, so we need to
963 put the primary domain into the lists of returned trusts as
965 ret1 = gendb_search_dn(sam_ctx, mem_ctx, samdb_base_dn(sam_ctx), &res1, attrs);
967 return NT_STATUS_INTERNAL_DB_CORRUPTION;
970 /* try and find the domain */
971 ret = gendb_search(sam_ctx, mem_ctx, partitions_basedn,
973 "(&(objectClass=crossRef)(ncName=%s))",
974 ldb_dn_get_linearized(res1[0]->dn));
976 return NT_STATUS_INTERNAL_DB_CORRUPTION;
979 local_domain = samdb_result_string(ref_res[0], "nETBIOSName", NULL);
981 ret2 = gendb_search(sam_ctx, mem_ctx, NULL, &res2, attrs, "(objectClass=trustedDomain)");
983 return NT_STATUS_INTERNAL_DB_CORRUPTION;
986 info1 = talloc(mem_ctx, struct netr_DomainInfo1);
987 NT_STATUS_HAVE_NO_MEMORY(info1);
991 info1->num_trusts = ret2 + 1;
992 info1->trusts = talloc_array(mem_ctx, struct netr_DomainTrustInfo,
994 NT_STATUS_HAVE_NO_MEMORY(info1->trusts);
996 status = fill_domain_trust_info(mem_ctx, res1[0], ref_res[0], &info1->domaininfo, true);
997 NT_STATUS_NOT_OK_RETURN(status);
999 for (i=0;i<ret2;i++) {
1000 status = fill_domain_trust_info(mem_ctx, res2[i], NULL, &info1->trusts[i], false);
1001 NT_STATUS_NOT_OK_RETURN(status);
1004 status = fill_domain_trust_info(mem_ctx, res1[0], ref_res[0], &info1->trusts[i], true);
1005 NT_STATUS_NOT_OK_RETURN(status);
1007 r->out.info.info1 = info1;
1009 return NT_STATUS_OK;
1015 netr_ServerPasswordGet
1017 static WERROR dcesrv_netr_ServerPasswordGet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1018 struct netr_ServerPasswordGet *r)
1020 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1025 netr_NETRLOGONSENDTOSAM
1027 static WERROR dcesrv_netr_NETRLOGONSENDTOSAM(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1028 struct netr_NETRLOGONSENDTOSAM *r)
1030 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1035 netr_DsRAddressToSitenamesW
1037 static WERROR dcesrv_netr_DsRAddressToSitenamesW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1038 struct netr_DsRAddressToSitenamesW *r)
1040 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1045 netr_DsRGetDCNameEx2
1047 static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1048 struct netr_DsRGetDCNameEx2 *r)
1050 const char * const attrs[] = { "dnsDomain", "objectGUID", NULL };
1052 struct ldb_message **res;
1053 struct ldb_dn *domain_dn;
1056 ZERO_STRUCT(r->out);
1058 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
1059 if (sam_ctx == NULL) {
1060 return WERR_DS_SERVICE_UNAVAILABLE;
1063 domain_dn = samdb_dns_domain_to_dn(sam_ctx, mem_ctx,
1065 if (domain_dn == NULL) {
1066 return WERR_DS_SERVICE_UNAVAILABLE;
1069 ret = gendb_search_dn(sam_ctx, mem_ctx, domain_dn, &res, attrs);
1071 return WERR_NO_SUCH_DOMAIN;
1074 r->out.info = talloc(mem_ctx, struct netr_DsRGetDCNameInfo);
1075 W_ERROR_HAVE_NO_MEMORY(r->out.info);
1077 /* TODO: - return real IP address
1078 * - check all r->in.* parameters (server_unc is ignored by w2k3!)
1080 r->out.info->dc_unc = talloc_asprintf(mem_ctx, "\\\\%s.%s",
1081 lp_netbios_name(dce_call->conn->dce_ctx->lp_ctx),
1082 lp_realm(dce_call->conn->dce_ctx->lp_ctx));
1083 W_ERROR_HAVE_NO_MEMORY(r->out.info->dc_unc);
1084 r->out.info->dc_address = talloc_strdup(mem_ctx, "\\\\0.0.0.0");
1085 W_ERROR_HAVE_NO_MEMORY(r->out.info->dc_address);
1086 r->out.info->dc_address_type = DS_ADDRESS_TYPE_INET;
1087 r->out.info->domain_guid = samdb_result_guid(res[0], "objectGUID");
1088 r->out.info->domain_name = samdb_result_string(res[0], "dnsDomain", NULL);
1089 r->out.info->forest_name = samdb_result_string(res[0], "dnsDomain", NULL);
1090 r->out.info->dc_flags = DS_DNS_FOREST |
1093 DS_SERVER_WRITABLE |
1095 DS_SERVER_TIMESERV |
1101 r->out.info->dc_site_name = talloc_strdup(mem_ctx, "Default-First-Site-Name");
1102 W_ERROR_HAVE_NO_MEMORY(r->out.info->dc_site_name);
1103 r->out.info->client_site_name = talloc_strdup(mem_ctx, "Default-First-Site-Name");
1104 W_ERROR_HAVE_NO_MEMORY(r->out.info->client_site_name);
1112 static WERROR dcesrv_netr_DsRGetDCNameEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1113 struct netr_DsRGetDCNameEx *r)
1115 struct netr_DsRGetDCNameEx2 r2;
1120 r2.in.server_unc = r->in.server_unc;
1121 r2.in.client_account = NULL;
1123 r2.in.domain_guid = r->in.domain_guid;
1124 r2.in.domain_name = r->in.domain_name;
1125 r2.in.site_name = r->in.site_name;
1126 r2.in.flags = r->in.flags;
1129 werr = dcesrv_netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1131 r->out.info = r2.out.info;
1139 static WERROR dcesrv_netr_DsRGetDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1140 struct netr_DsRGetDCName *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_name = r->in.domain_name;
1151 r2.in.domain_guid = r->in.domain_guid;
1153 r2.in.site_name = NULL; /* should fill in from site GUID */
1154 r2.in.flags = r->in.flags;
1157 werr = dcesrv_netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1159 r->out.info = r2.out.info;
1165 netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN
1167 static WERROR dcesrv_netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1168 struct netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN *r)
1170 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1175 netr_NetrEnumerateTrustedDomainsEx
1177 static WERROR dcesrv_netr_NetrEnumerateTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1178 struct netr_NetrEnumerateTrustedDomainsEx *r)
1180 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1185 netr_DsRAddressToSitenamesExW
1187 static WERROR dcesrv_netr_DsRAddressToSitenamesExW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1188 struct netr_DsRAddressToSitenamesExW *r)
1190 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1195 netr_DsrGetDcSiteCoverageW
1197 static WERROR dcesrv_netr_DsrGetDcSiteCoverageW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1198 struct netr_DsrGetDcSiteCoverageW *r)
1200 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1205 netr_DsrEnumerateDomainTrusts
1207 static WERROR dcesrv_netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1208 struct netr_DsrEnumerateDomainTrusts *r)
1210 struct netr_DomainTrust *trusts;
1213 struct ldb_message **dom_res, **ref_res;
1214 const char * const dom_attrs[] = { "objectSid", "objectGUID", NULL };
1215 const char * const ref_attrs[] = { "nETBIOSName", "dnsRoot", NULL };
1216 struct ldb_dn *partitions_basedn;
1218 ZERO_STRUCT(r->out);
1220 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
1221 if (sam_ctx == NULL) {
1222 return WERR_GENERAL_FAILURE;
1225 partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);
1227 ret = gendb_search_dn(sam_ctx, mem_ctx, NULL, &dom_res, dom_attrs);
1229 return WERR_GENERAL_FAILURE;
1232 return WERR_GENERAL_FAILURE;
1235 ret = gendb_search(sam_ctx, mem_ctx, partitions_basedn, &ref_res, ref_attrs,
1236 "(&(objectClass=crossRef)(ncName=%s))",
1237 ldb_dn_get_linearized(dom_res[0]->dn));
1239 return WERR_GENERAL_FAILURE;
1242 return WERR_GENERAL_FAILURE;
1245 trusts = talloc_array(mem_ctx, struct netr_DomainTrust, ret);
1246 W_ERROR_HAVE_NO_MEMORY(trusts);
1249 r->out.trusts = trusts;
1251 /* TODO: add filtering by trust_flags, and correct trust_type
1253 trusts[0].netbios_name = samdb_result_string(ref_res[0], "nETBIOSName", NULL);
1254 trusts[0].dns_name = samdb_result_string(ref_res[0], "dnsRoot", NULL);
1255 trusts[0].trust_flags =
1256 NETR_TRUST_FLAG_TREEROOT |
1257 NETR_TRUST_FLAG_IN_FOREST |
1258 NETR_TRUST_FLAG_PRIMARY;
1259 trusts[0].parent_index = 0;
1260 trusts[0].trust_type = 2;
1261 trusts[0].trust_attributes = 0;
1262 trusts[0].sid = samdb_result_dom_sid(mem_ctx, dom_res[0], "objectSid");
1263 trusts[0].guid = samdb_result_guid(dom_res[0], "objectGUID");
1270 netr_DsrDeregisterDNSHostRecords
1272 static WERROR dcesrv_netr_DsrDeregisterDNSHostRecords(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1273 struct netr_DsrDeregisterDNSHostRecords *r)
1275 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1280 netr_ServerTrustPasswordsGet
1282 static NTSTATUS dcesrv_netr_ServerTrustPasswordsGet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1283 struct netr_ServerTrustPasswordsGet *r)
1285 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1290 netr_DsRGetForestTrustInformation
1292 static WERROR dcesrv_netr_DsRGetForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1293 struct netr_DsRGetForestTrustInformation *r)
1295 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1300 netr_GetForestTrustInformation
1302 static WERROR dcesrv_netr_GetForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1303 struct netr_GetForestTrustInformation *r)
1305 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1310 netr_NETRSERVERGETTRUSTINFO
1312 static WERROR dcesrv_netr_NETRSERVERGETTRUSTINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1313 struct netr_NETRSERVERGETTRUSTINFO *r)
1315 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1319 /* include the generated boilerplate */
1320 #include "librpc/gen_ndr/ndr_netlogon_s.c"