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) {
424 case NetlogonInteractiveInformation:
425 case NetlogonServiceInformation:
426 case NetlogonInteractiveTransitiveInformation:
427 case NetlogonServiceTransitiveInformation:
428 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
429 creds_arcfour_crypt(creds,
430 r->in.logon.password->lmpassword.hash,
431 sizeof(r->in.logon.password->lmpassword.hash));
432 creds_arcfour_crypt(creds,
433 r->in.logon.password->ntpassword.hash,
434 sizeof(r->in.logon.password->ntpassword.hash));
436 creds_des_decrypt(creds, &r->in.logon.password->lmpassword);
437 creds_des_decrypt(creds, &r->in.logon.password->ntpassword);
440 /* TODO: we need to deny anonymous access here */
441 nt_status = auth_context_create(mem_ctx,
442 dce_call->event_ctx, dce_call->msg_ctx,
443 dce_call->conn->dce_ctx->lp_ctx,
445 NT_STATUS_NOT_OK_RETURN(nt_status);
447 user_info->logon_parameters = r->in.logon.password->identity_info.parameter_control;
448 user_info->client.account_name = r->in.logon.password->identity_info.account_name.string;
449 user_info->client.domain_name = r->in.logon.password->identity_info.domain_name.string;
450 user_info->workstation_name = r->in.logon.password->identity_info.workstation.string;
452 user_info->flags |= USER_INFO_INTERACTIVE_LOGON;
453 user_info->password_state = AUTH_PASSWORD_HASH;
455 user_info->password.hash.lanman = talloc(user_info, struct samr_Password);
456 NT_STATUS_HAVE_NO_MEMORY(user_info->password.hash.lanman);
457 *user_info->password.hash.lanman = r->in.logon.password->lmpassword;
459 user_info->password.hash.nt = talloc(user_info, struct samr_Password);
460 NT_STATUS_HAVE_NO_MEMORY(user_info->password.hash.nt);
461 *user_info->password.hash.nt = r->in.logon.password->ntpassword;
464 case NetlogonNetworkInformation:
465 case NetlogonNetworkTransitiveInformation:
467 /* TODO: we need to deny anonymous access here */
468 nt_status = auth_context_create(mem_ctx,
469 dce_call->event_ctx, dce_call->msg_ctx,
470 dce_call->conn->dce_ctx->lp_ctx,
472 NT_STATUS_NOT_OK_RETURN(nt_status);
474 nt_status = auth_context_set_challenge(auth_context, r->in.logon.network->challenge, "netr_LogonSamLogonWithFlags");
475 NT_STATUS_NOT_OK_RETURN(nt_status);
477 user_info->logon_parameters = r->in.logon.network->identity_info.parameter_control;
478 user_info->client.account_name = r->in.logon.network->identity_info.account_name.string;
479 user_info->client.domain_name = r->in.logon.network->identity_info.domain_name.string;
480 user_info->workstation_name = r->in.logon.network->identity_info.workstation.string;
482 user_info->password_state = AUTH_PASSWORD_RESPONSE;
483 user_info->password.response.lanman = data_blob_talloc(mem_ctx, r->in.logon.network->lm.data, r->in.logon.network->lm.length);
484 user_info->password.response.nt = data_blob_talloc(mem_ctx, r->in.logon.network->nt.data, r->in.logon.network->nt.length);
489 case NetlogonGenericInformation:
491 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
492 creds_arcfour_crypt(creds,
493 r->in.logon.generic->data, r->in.logon.generic->length);
495 /* Using DES to verify kerberos tickets makes no sense */
496 return NT_STATUS_INVALID_PARAMETER;
499 if (strcmp(r->in.logon.generic->package_name.string, "Kerberos")) {
500 struct PAC_Validate pac_validate;
502 struct PAC_SIGNATURE_DATA kdc_sig;
503 DATA_BLOB pac_validate_blob = data_blob_const(r->in.logon.generic->data,
504 r->in.logon.generic->length);
505 ndr_err = ndr_pull_struct_blob(&pac_validate_blob, mem_ctx,
506 lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx),
508 (ndr_pull_flags_fn_t)ndr_pull_PAC_Validate);
509 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
510 return NT_STATUS_INVALID_PARAMETER;
513 if (pac_validate->MessageType != 3) {
514 /* We don't implement any other message types - such as certificate validation - yet */
515 return NT_STATUS_INVALID_PARAMETER;
518 if (pac_validate->ChecksumAndSignature.length != (pac_validate->ChecksumLength + pac_validate->SignatureLength)
519 || pac_validate->ChecksumAndSignature.length < pac_validate->ChecksumLength
520 || pac_validate->ChecksumAndSignature.length < pac_validate->SignatureLength ) {
521 return NT_STATUS_INVALID_PARAMETER;
524 srv_sig = data_blob_const(pac_validate->ChecksumAndSignature.data,
525 pac_validate->ChecksumLength);
527 kdc_sig.type = pac_validate->SignatureType;
528 kdc_sig.signature = data_blob_const(&pac_validate->ChecksumAndSignature.data[pac_validate->ChecksumLength],
529 pac_validate->SignatureLength);
530 check_pac_checksum(mem_ctx, srv_sig, &kdc_sig,
536 /* Until we get an implemetnation of these other packages */
537 return NT_STATUS_INVALID_PARAMETER;
540 return NT_STATUS_INVALID_PARAMETER;
543 nt_status = auth_check_password(auth_context, mem_ctx, user_info, &server_info);
544 NT_STATUS_NOT_OK_RETURN(nt_status);
546 nt_status = auth_convert_server_info_sambaseinfo(mem_ctx, server_info, &sam);
547 NT_STATUS_NOT_OK_RETURN(nt_status);
549 /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
550 /* It appears that level 6 is not individually encrypted */
551 if ((r->in.validation_level != 6) &&
552 memcmp(sam->key.key, zeros, sizeof(sam->key.key)) != 0) {
553 /* This key is sent unencrypted without the ARCFOUR flag set */
554 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
555 creds_arcfour_crypt(creds,
557 sizeof(sam->key.key));
561 /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
562 /* It appears that level 6 is not individually encrypted */
563 if ((r->in.validation_level != 6) &&
564 memcmp(sam->LMSessKey.key, zeros, sizeof(sam->LMSessKey.key)) != 0) {
565 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
566 creds_arcfour_crypt(creds,
568 sizeof(sam->LMSessKey.key));
570 creds_des_encrypt_LMKey(creds,
575 switch (r->in.validation_level) {
577 sam2 = talloc_zero(mem_ctx, struct netr_SamInfo2);
578 NT_STATUS_HAVE_NO_MEMORY(sam2);
580 r->out.validation.sam2 = sam2;
584 sam3 = talloc_zero(mem_ctx, struct netr_SamInfo3);
585 NT_STATUS_HAVE_NO_MEMORY(sam3);
587 r->out.validation.sam3 = sam3;
591 sam6 = talloc_zero(mem_ctx, struct netr_SamInfo6);
592 NT_STATUS_HAVE_NO_MEMORY(sam6);
594 sam6->forest.string = lp_realm(dce_call->conn->dce_ctx->lp_ctx);
595 sam6->principle.string = talloc_asprintf(mem_ctx, "%s@%s",
596 sam->account_name.string, sam6->forest.string);
597 NT_STATUS_HAVE_NO_MEMORY(sam6->principle.string);
598 r->out.validation.sam6 = sam6;
605 r->out.authoritative = 1;
607 /* TODO: Describe and deal with these flags */
613 static NTSTATUS dcesrv_netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
614 struct netr_LogonSamLogonEx *r)
617 struct creds_CredentialState *creds;
618 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);
619 if (!NT_STATUS_IS_OK(nt_status)) {
623 if (!dce_call->conn->auth_state.auth_info ||
624 dce_call->conn->auth_state.auth_info->auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
625 return NT_STATUS_INTERNAL_ERROR;
627 return dcesrv_netr_LogonSamLogon_base(dce_call, mem_ctx, r, creds);
631 netr_LogonSamLogonWithFlags
634 static NTSTATUS dcesrv_netr_LogonSamLogonWithFlags(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
635 struct netr_LogonSamLogonWithFlags *r)
638 struct creds_CredentialState *creds;
639 struct netr_LogonSamLogonEx r2;
641 struct netr_Authenticator *return_authenticator;
643 return_authenticator = talloc(mem_ctx, struct netr_Authenticator);
644 NT_STATUS_HAVE_NO_MEMORY(return_authenticator);
646 nt_status = dcesrv_netr_creds_server_step_check(dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx,
647 r->in.computer_name, mem_ctx,
648 r->in.credential, return_authenticator,
650 NT_STATUS_NOT_OK_RETURN(nt_status);
654 r2.in.server_name = r->in.server_name;
655 r2.in.computer_name = r->in.computer_name;
656 r2.in.logon_level = r->in.logon_level;
657 r2.in.logon = r->in.logon;
658 r2.in.validation_level = r->in.validation_level;
659 r2.in.flags = r->in.flags;
661 nt_status = dcesrv_netr_LogonSamLogon_base(dce_call, mem_ctx, &r2, creds);
663 r->out.return_authenticator = return_authenticator;
664 r->out.validation = r2.out.validation;
665 r->out.authoritative = r2.out.authoritative;
666 r->out.flags = r2.out.flags;
674 static NTSTATUS dcesrv_netr_LogonSamLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
675 struct netr_LogonSamLogon *r)
677 struct netr_LogonSamLogonWithFlags r2;
682 r2.in.server_name = r->in.server_name;
683 r2.in.computer_name = r->in.computer_name;
684 r2.in.credential = r->in.credential;
685 r2.in.return_authenticator = r->in.return_authenticator;
686 r2.in.logon_level = r->in.logon_level;
687 r2.in.logon = r->in.logon;
688 r2.in.validation_level = r->in.validation_level;
691 status = dcesrv_netr_LogonSamLogonWithFlags(dce_call, mem_ctx, &r2);
693 r->out.return_authenticator = r2.out.return_authenticator;
694 r->out.validation = r2.out.validation;
695 r->out.authoritative = r2.out.authoritative;
704 static NTSTATUS dcesrv_netr_LogonSamLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
705 struct netr_LogonSamLogoff *r)
707 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
715 static NTSTATUS dcesrv_netr_DatabaseDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
716 struct netr_DatabaseDeltas *r)
718 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
725 static NTSTATUS dcesrv_netr_DatabaseSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
726 struct netr_DatabaseSync *r)
728 /* win2k3 native mode returns "NOT IMPLEMENTED" for this call */
729 return NT_STATUS_NOT_IMPLEMENTED;
736 static NTSTATUS dcesrv_netr_AccountDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
737 struct netr_AccountDeltas *r)
739 /* w2k3 returns "NOT IMPLEMENTED" for this call */
740 return NT_STATUS_NOT_IMPLEMENTED;
747 static NTSTATUS dcesrv_netr_AccountSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
748 struct netr_AccountSync *r)
750 /* w2k3 returns "NOT IMPLEMENTED" for this call */
751 return NT_STATUS_NOT_IMPLEMENTED;
758 static WERROR dcesrv_netr_GetDcName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
759 struct netr_GetDcName *r)
761 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
768 static WERROR dcesrv_netr_LogonControl(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
769 struct netr_LogonControl *r)
771 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
778 static WERROR dcesrv_netr_GetAnyDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
779 struct netr_GetAnyDCName *r)
781 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
788 static WERROR dcesrv_netr_LogonControl2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
789 struct netr_LogonControl2 *r)
791 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
798 static NTSTATUS dcesrv_netr_DatabaseSync2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
799 struct netr_DatabaseSync2 *r)
801 /* win2k3 native mode returns "NOT IMPLEMENTED" for this call */
802 return NT_STATUS_NOT_IMPLEMENTED;
809 static NTSTATUS dcesrv_netr_DatabaseRedo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
810 struct netr_DatabaseRedo *r)
812 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
819 static WERROR dcesrv_netr_LogonControl2Ex(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
820 struct netr_LogonControl2Ex *r)
822 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
827 netr_NetrEnumerateTurstedDomains
829 static WERROR dcesrv_netr_NetrEnumerateTrustedDomains(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
830 struct netr_NetrEnumerateTrustedDomains *r)
832 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
837 netr_NETRLOGONDUMMYROUTINE1
839 static WERROR dcesrv_netr_NETRLOGONDUMMYROUTINE1(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
840 struct netr_NETRLOGONDUMMYROUTINE1 *r)
842 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
847 netr_NETRLOGONSETSERVICEBITS
849 static WERROR dcesrv_netr_NETRLOGONSETSERVICEBITS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
850 struct netr_NETRLOGONSETSERVICEBITS *r)
852 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
857 netr_LogonGetTrustRid
859 static WERROR dcesrv_netr_LogonGetTrustRid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
860 struct netr_LogonGetTrustRid *r)
862 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
867 netr_NETRLOGONCOMPUTESERVERDIGEST
869 static WERROR dcesrv_netr_NETRLOGONCOMPUTESERVERDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
870 struct netr_NETRLOGONCOMPUTESERVERDIGEST *r)
872 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
877 netr_NETRLOGONCOMPUTECLIENTDIGEST
879 static WERROR dcesrv_netr_NETRLOGONCOMPUTECLIENTDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
880 struct netr_NETRLOGONCOMPUTECLIENTDIGEST *r)
882 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
890 static WERROR dcesrv_netr_DsRGetSiteName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
891 struct netr_DsRGetSiteName *r)
893 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
898 fill in a netr_DomainTrustInfo from a ldb search result
900 static NTSTATUS fill_domain_trust_info(TALLOC_CTX *mem_ctx,
901 struct ldb_message *res,
902 struct ldb_message *ref_res,
903 struct netr_DomainTrustInfo *info,
909 info->domainname.string = samdb_result_string(ref_res, "nETBIOSName", NULL);
910 info->fulldomainname.string = samdb_result_string(ref_res, "dnsRoot", NULL);
911 info->forest.string = NULL;
912 info->guid = samdb_result_guid(res, "objectGUID");
913 info->sid = samdb_result_dom_sid(mem_ctx, res, "objectSid");
915 info->domainname.string = samdb_result_string(res, "flatName", NULL);
916 info->fulldomainname.string = samdb_result_string(res, "trustPartner", NULL);
917 info->forest.string = NULL;
918 info->guid = samdb_result_guid(res, "objectGUID");
919 info->sid = samdb_result_dom_sid(mem_ctx, res, "securityIdentifier");
926 netr_LogonGetDomainInfo
927 this is called as part of the ADS domain logon procedure.
929 It has an important role in convaying details about the client, such
930 as Operating System, Version, Service Pack etc.
932 static NTSTATUS dcesrv_netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
933 struct netr_LogonGetDomainInfo *r)
935 const char * const attrs[] = { "objectSid",
936 "objectGUID", "flatName", "securityIdentifier",
937 "trustPartner", NULL };
938 const char * const ref_attrs[] = { "nETBIOSName", "dnsRoot", NULL };
939 struct ldb_context *sam_ctx;
940 struct ldb_message **res1, **res2, **ref_res;
941 struct netr_DomainInfo1 *info1;
942 int ret, ret1, ret2, i;
944 struct ldb_dn *partitions_basedn;
946 const char *local_domain;
948 status = dcesrv_netr_creds_server_step_check(dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx,
949 r->in.computer_name, mem_ctx,
951 r->out.return_authenticator,
953 NT_STATUS_NOT_OK_RETURN(status);
955 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
956 if (sam_ctx == NULL) {
957 return NT_STATUS_INVALID_SYSTEM_SERVICE;
960 partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);
962 /* we need to do two searches. The first will pull our primary
963 domain and the second will pull any trusted domains. Our
964 primary domain is also a "trusted" domain, so we need to
965 put the primary domain into the lists of returned trusts as
967 ret1 = gendb_search_dn(sam_ctx, mem_ctx, samdb_base_dn(sam_ctx), &res1, attrs);
969 return NT_STATUS_INTERNAL_DB_CORRUPTION;
972 /* try and find the domain */
973 ret = gendb_search(sam_ctx, mem_ctx, partitions_basedn,
975 "(&(objectClass=crossRef)(ncName=%s))",
976 ldb_dn_get_linearized(res1[0]->dn));
978 return NT_STATUS_INTERNAL_DB_CORRUPTION;
981 local_domain = samdb_result_string(ref_res[0], "nETBIOSName", NULL);
983 ret2 = gendb_search(sam_ctx, mem_ctx, NULL, &res2, attrs, "(objectClass=trustedDomain)");
985 return NT_STATUS_INTERNAL_DB_CORRUPTION;
988 info1 = talloc(mem_ctx, struct netr_DomainInfo1);
989 NT_STATUS_HAVE_NO_MEMORY(info1);
993 info1->num_trusts = ret2 + 1;
994 info1->trusts = talloc_array(mem_ctx, struct netr_DomainTrustInfo,
996 NT_STATUS_HAVE_NO_MEMORY(info1->trusts);
998 status = fill_domain_trust_info(mem_ctx, res1[0], ref_res[0], &info1->domaininfo, true);
999 NT_STATUS_NOT_OK_RETURN(status);
1001 for (i=0;i<ret2;i++) {
1002 status = fill_domain_trust_info(mem_ctx, res2[i], NULL, &info1->trusts[i], false);
1003 NT_STATUS_NOT_OK_RETURN(status);
1006 status = fill_domain_trust_info(mem_ctx, res1[0], ref_res[0], &info1->trusts[i], true);
1007 NT_STATUS_NOT_OK_RETURN(status);
1009 r->out.info.info1 = info1;
1011 return NT_STATUS_OK;
1017 netr_ServerPasswordGet
1019 static WERROR dcesrv_netr_ServerPasswordGet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1020 struct netr_ServerPasswordGet *r)
1022 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1027 netr_NETRLOGONSENDTOSAM
1029 static WERROR dcesrv_netr_NETRLOGONSENDTOSAM(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1030 struct netr_NETRLOGONSENDTOSAM *r)
1032 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1037 netr_DsRAddressToSitenamesW
1039 static WERROR dcesrv_netr_DsRAddressToSitenamesW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1040 struct netr_DsRAddressToSitenamesW *r)
1042 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1047 netr_DsRGetDCNameEx2
1049 static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1050 struct netr_DsRGetDCNameEx2 *r)
1052 const char * const attrs[] = { "dnsDomain", "objectGUID", NULL };
1054 struct ldb_message **res;
1055 struct ldb_dn *domain_dn;
1058 ZERO_STRUCT(r->out);
1060 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
1061 if (sam_ctx == NULL) {
1062 return WERR_DS_SERVICE_UNAVAILABLE;
1065 domain_dn = samdb_dns_domain_to_dn(sam_ctx, mem_ctx,
1067 if (domain_dn == NULL) {
1068 return WERR_DS_SERVICE_UNAVAILABLE;
1071 ret = gendb_search_dn(sam_ctx, mem_ctx, domain_dn, &res, attrs);
1073 return WERR_NO_SUCH_DOMAIN;
1076 r->out.info = talloc(mem_ctx, struct netr_DsRGetDCNameInfo);
1077 W_ERROR_HAVE_NO_MEMORY(r->out.info);
1079 /* TODO: - return real IP address
1080 * - check all r->in.* parameters (server_unc is ignored by w2k3!)
1082 r->out.info->dc_unc = talloc_asprintf(mem_ctx, "\\\\%s.%s",
1083 lp_netbios_name(dce_call->conn->dce_ctx->lp_ctx),
1084 lp_realm(dce_call->conn->dce_ctx->lp_ctx));
1085 W_ERROR_HAVE_NO_MEMORY(r->out.info->dc_unc);
1086 r->out.info->dc_address = talloc_strdup(mem_ctx, "\\\\0.0.0.0");
1087 W_ERROR_HAVE_NO_MEMORY(r->out.info->dc_address);
1088 r->out.info->dc_address_type = DS_ADDRESS_TYPE_INET;
1089 r->out.info->domain_guid = samdb_result_guid(res[0], "objectGUID");
1090 r->out.info->domain_name = samdb_result_string(res[0], "dnsDomain", NULL);
1091 r->out.info->forest_name = samdb_result_string(res[0], "dnsDomain", NULL);
1092 r->out.info->dc_flags = DS_DNS_FOREST |
1095 DS_SERVER_WRITABLE |
1097 DS_SERVER_TIMESERV |
1103 r->out.info->dc_site_name = talloc_strdup(mem_ctx, "Default-First-Site-Name");
1104 W_ERROR_HAVE_NO_MEMORY(r->out.info->dc_site_name);
1105 r->out.info->client_site_name = talloc_strdup(mem_ctx, "Default-First-Site-Name");
1106 W_ERROR_HAVE_NO_MEMORY(r->out.info->client_site_name);
1114 static WERROR dcesrv_netr_DsRGetDCNameEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1115 struct netr_DsRGetDCNameEx *r)
1117 struct netr_DsRGetDCNameEx2 r2;
1122 r2.in.server_unc = r->in.server_unc;
1123 r2.in.client_account = NULL;
1125 r2.in.domain_guid = r->in.domain_guid;
1126 r2.in.domain_name = r->in.domain_name;
1127 r2.in.site_name = r->in.site_name;
1128 r2.in.flags = r->in.flags;
1131 werr = dcesrv_netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1133 r->out.info = r2.out.info;
1141 static WERROR dcesrv_netr_DsRGetDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1142 struct netr_DsRGetDCName *r)
1144 struct netr_DsRGetDCNameEx2 r2;
1149 r2.in.server_unc = r->in.server_unc;
1150 r2.in.client_account = NULL;
1152 r2.in.domain_name = r->in.domain_name;
1153 r2.in.domain_guid = r->in.domain_guid;
1155 r2.in.site_name = NULL; /* should fill in from site GUID */
1156 r2.in.flags = r->in.flags;
1159 werr = dcesrv_netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1161 r->out.info = r2.out.info;
1167 netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN
1169 static WERROR dcesrv_netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1170 struct netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN *r)
1172 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1177 netr_NetrEnumerateTrustedDomainsEx
1179 static WERROR dcesrv_netr_NetrEnumerateTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1180 struct netr_NetrEnumerateTrustedDomainsEx *r)
1182 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1187 netr_DsRAddressToSitenamesExW
1189 static WERROR dcesrv_netr_DsRAddressToSitenamesExW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1190 struct netr_DsRAddressToSitenamesExW *r)
1192 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1197 netr_DsrGetDcSiteCoverageW
1199 static WERROR dcesrv_netr_DsrGetDcSiteCoverageW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1200 struct netr_DsrGetDcSiteCoverageW *r)
1202 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1207 netr_DsrEnumerateDomainTrusts
1209 static WERROR dcesrv_netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1210 struct netr_DsrEnumerateDomainTrusts *r)
1212 struct netr_DomainTrust *trusts;
1215 struct ldb_message **dom_res, **ref_res;
1216 const char * const dom_attrs[] = { "objectSid", "objectGUID", NULL };
1217 const char * const ref_attrs[] = { "nETBIOSName", "dnsRoot", NULL };
1218 struct ldb_dn *partitions_basedn;
1220 ZERO_STRUCT(r->out);
1222 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
1223 if (sam_ctx == NULL) {
1224 return WERR_GENERAL_FAILURE;
1227 partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);
1229 ret = gendb_search_dn(sam_ctx, mem_ctx, NULL, &dom_res, dom_attrs);
1231 return WERR_GENERAL_FAILURE;
1234 return WERR_GENERAL_FAILURE;
1237 ret = gendb_search(sam_ctx, mem_ctx, partitions_basedn, &ref_res, ref_attrs,
1238 "(&(objectClass=crossRef)(ncName=%s))",
1239 ldb_dn_get_linearized(dom_res[0]->dn));
1241 return WERR_GENERAL_FAILURE;
1244 return WERR_GENERAL_FAILURE;
1247 trusts = talloc_array(mem_ctx, struct netr_DomainTrust, ret);
1248 W_ERROR_HAVE_NO_MEMORY(trusts);
1251 r->out.trusts = trusts;
1253 /* TODO: add filtering by trust_flags, and correct trust_type
1255 trusts[0].netbios_name = samdb_result_string(ref_res[0], "nETBIOSName", NULL);
1256 trusts[0].dns_name = samdb_result_string(ref_res[0], "dnsRoot", NULL);
1257 trusts[0].trust_flags =
1258 NETR_TRUST_FLAG_TREEROOT |
1259 NETR_TRUST_FLAG_IN_FOREST |
1260 NETR_TRUST_FLAG_PRIMARY;
1261 trusts[0].parent_index = 0;
1262 trusts[0].trust_type = 2;
1263 trusts[0].trust_attributes = 0;
1264 trusts[0].sid = samdb_result_dom_sid(mem_ctx, dom_res[0], "objectSid");
1265 trusts[0].guid = samdb_result_guid(dom_res[0], "objectGUID");
1272 netr_DsrDeregisterDNSHostRecords
1274 static WERROR dcesrv_netr_DsrDeregisterDNSHostRecords(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1275 struct netr_DsrDeregisterDNSHostRecords *r)
1277 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1282 netr_ServerTrustPasswordsGet
1284 static NTSTATUS dcesrv_netr_ServerTrustPasswordsGet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1285 struct netr_ServerTrustPasswordsGet *r)
1287 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1292 netr_DsRGetForestTrustInformation
1294 static WERROR dcesrv_netr_DsRGetForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1295 struct netr_DsRGetForestTrustInformation *r)
1297 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1302 netr_GetForestTrustInformation
1304 static WERROR dcesrv_netr_GetForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1305 struct netr_GetForestTrustInformation *r)
1307 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1312 netr_NETRSERVERGETTRUSTINFO
1314 static WERROR dcesrv_netr_NETRSERVERGETTRUSTINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1315 struct netr_NETRSERVERGETTRUSTINFO *r)
1317 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1321 /* include the generated boilerplate */
1322 #include "librpc/gen_ndr/ndr_netlogon_s.c"