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
8 Copyright (C) Matthias Dieter Wallnöfer 2009-2010
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #include "rpc_server/dcerpc_server.h"
26 #include "auth/auth.h"
27 #include "auth/auth_sam_reply.h"
28 #include "dsdb/samdb/samdb.h"
29 #include "../lib/util/util_ldb.h"
30 #include "../libcli/auth/schannel.h"
31 #include "libcli/security/security.h"
32 #include "param/param.h"
33 #include "lib/messaging/irpc.h"
34 #include "librpc/gen_ndr/ndr_irpc_c.h"
35 #include "../libcli/ldap/ldap_ndr.h"
36 #include "dsdb/samdb/ldb_modules/util.h"
37 #include "lib/tsocket/tsocket.h"
38 #include "librpc/gen_ndr/ndr_netlogon.h"
39 #include "librpc/gen_ndr/ndr_lsa.h"
40 #include "librpc/gen_ndr/ndr_samr.h"
41 #include "librpc/gen_ndr/ndr_irpc.h"
42 #include "librpc/gen_ndr/ndr_winbind.h"
43 #include "librpc/gen_ndr/ndr_winbind_c.h"
44 #include "lib/socket/netif.h"
45 #include "rpc_server/common/sid_helper.h"
46 #include "lib/util/util_str_escape.h"
48 #define DCESRV_INTERFACE_NETLOGON_BIND(context, iface) \
49 dcesrv_interface_netlogon_bind(context, iface)
52 * This #define allows the netlogon interface to accept invalid
53 * association groups, because association groups are to coordinate
54 * handles, and handles are not used in NETLOGON. This in turn avoids
55 * the need to coordinate these across multiple possible NETLOGON
58 #define DCESRV_INTERFACE_NETLOGON_FLAGS DCESRV_INTERFACE_FLAGS_HANDLES_NOT_USED
60 static NTSTATUS dcesrv_interface_netlogon_bind(struct dcesrv_connection_context *context,
61 const struct dcesrv_interface *iface)
63 return dcesrv_interface_bind_reject_connect(context, iface);
66 #define NETLOGON_SERVER_PIPE_STATE_MAGIC 0x4f555358
67 struct netlogon_server_pipe_state {
68 struct netr_Credential client_challenge;
69 struct netr_Credential server_challenge;
72 static NTSTATUS dcesrv_netr_ServerReqChallenge(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
73 struct netr_ServerReqChallenge *r)
75 struct netlogon_server_pipe_state *pipe_state = NULL;
78 ZERO_STRUCTP(r->out.return_credentials);
80 pipe_state = dcesrv_iface_state_find_conn(dce_call,
81 NETLOGON_SERVER_PIPE_STATE_MAGIC,
82 struct netlogon_server_pipe_state);
83 TALLOC_FREE(pipe_state);
85 pipe_state = talloc_zero(dce_call,
86 struct netlogon_server_pipe_state);
87 if (pipe_state == NULL) {
88 return NT_STATUS_NO_MEMORY;
91 pipe_state->client_challenge = *r->in.credentials;
93 generate_random_buffer(pipe_state->server_challenge.data,
94 sizeof(pipe_state->server_challenge.data));
96 *r->out.return_credentials = pipe_state->server_challenge;
98 ntstatus = dcesrv_iface_state_store_conn(dce_call,
99 NETLOGON_SERVER_PIPE_STATE_MAGIC,
101 if (!NT_STATUS_IS_OK(ntstatus)) {
105 ntstatus = schannel_save_challenge(dce_call->conn->dce_ctx->lp_ctx,
106 &pipe_state->client_challenge,
107 &pipe_state->server_challenge,
108 r->in.computer_name);
109 if (!NT_STATUS_IS_OK(ntstatus)) {
110 TALLOC_FREE(pipe_state);
118 * Do the actual processing of a netr_ServerAuthenticate3 message.
119 * called from dcesrv_netr_ServerAuthenticate3, which handles the logging.
121 static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper(
122 struct dcesrv_call_state *dce_call,
124 struct netr_ServerAuthenticate3 *r,
125 const char **trust_account_for_search,
126 const char **trust_account_in_db,
127 struct dom_sid **sid)
129 struct netlogon_server_pipe_state *pipe_state = NULL;
130 bool challenge_valid = false;
131 struct netlogon_server_pipe_state challenge;
132 struct netlogon_creds_CredentialState *creds;
133 struct ldb_context *sam_ctx;
134 struct samr_Password *curNtHash = NULL;
135 struct samr_Password *prevNtHash = NULL;
136 uint32_t user_account_control;
138 struct ldb_message **msgs;
140 const char *attrs[] = {"unicodePwd", "userAccountControl",
141 "objectSid", "samAccountName", NULL};
142 uint32_t server_flags = 0;
143 uint32_t negotiate_flags = 0;
144 bool allow_nt4_crypto = lpcfg_allow_nt4_crypto(dce_call->conn->dce_ctx->lp_ctx);
145 bool reject_des_client = !allow_nt4_crypto;
146 bool reject_md5_client = lpcfg_reject_md5_clients(dce_call->conn->dce_ctx->lp_ctx);
148 ZERO_STRUCTP(r->out.return_credentials);
151 pipe_state = dcesrv_iface_state_find_conn(dce_call,
152 NETLOGON_SERVER_PIPE_STATE_MAGIC,
153 struct netlogon_server_pipe_state);
154 if (pipe_state != NULL) {
156 * If we had a challenge remembered on the connection
157 * consider this for usage. This can't be cleanup
160 * This is the default code path for typical clients
161 * which call netr_ServerReqChallenge() and
162 * netr_ServerAuthenticate3() on the same dcerpc connection.
164 challenge = *pipe_state;
166 challenge_valid = true;
172 * Fallback and try to get the challenge from
175 * If too many clients are using this code path,
176 * they may destroy their cache entries as the
177 * TDB has a fixed size limited via a lossy hash
179 * The TDB used is the schannel store, which is
180 * initialised at startup.
182 * NOTE: The challenge is deleted from the DB as soon as it is
183 * fetched, to prevent reuse.
187 ntstatus = schannel_get_challenge(dce_call->conn->dce_ctx->lp_ctx,
188 &challenge.client_challenge,
189 &challenge.server_challenge,
190 r->in.computer_name);
192 if (!NT_STATUS_IS_OK(ntstatus)) {
193 ZERO_STRUCT(challenge);
195 challenge_valid = true;
199 server_flags = NETLOGON_NEG_ACCOUNT_LOCKOUT |
200 NETLOGON_NEG_PERSISTENT_SAMREPL |
201 NETLOGON_NEG_ARCFOUR |
202 NETLOGON_NEG_PROMOTION_COUNT |
203 NETLOGON_NEG_CHANGELOG_BDC |
204 NETLOGON_NEG_FULL_SYNC_REPL |
205 NETLOGON_NEG_MULTIPLE_SIDS |
207 NETLOGON_NEG_PASSWORD_CHANGE_REFUSAL |
208 NETLOGON_NEG_SEND_PASSWORD_INFO_PDC |
209 NETLOGON_NEG_GENERIC_PASSTHROUGH |
210 NETLOGON_NEG_CONCURRENT_RPC |
211 NETLOGON_NEG_AVOID_ACCOUNT_DB_REPL |
212 NETLOGON_NEG_AVOID_SECURITYAUTH_DB_REPL |
213 NETLOGON_NEG_STRONG_KEYS |
214 NETLOGON_NEG_TRANSITIVE_TRUSTS |
215 NETLOGON_NEG_DNS_DOMAIN_TRUSTS |
216 NETLOGON_NEG_PASSWORD_SET2 |
217 NETLOGON_NEG_GETDOMAININFO |
218 NETLOGON_NEG_CROSS_FOREST_TRUSTS |
219 NETLOGON_NEG_NEUTRALIZE_NT4_EMULATION |
220 NETLOGON_NEG_RODC_PASSTHROUGH |
221 NETLOGON_NEG_SUPPORTS_AES |
222 NETLOGON_NEG_AUTHENTICATED_RPC_LSASS |
223 NETLOGON_NEG_AUTHENTICATED_RPC;
225 negotiate_flags = *r->in.negotiate_flags & server_flags;
227 if (negotiate_flags & NETLOGON_NEG_STRONG_KEYS) {
228 reject_des_client = false;
231 if (negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
232 reject_des_client = false;
233 reject_md5_client = false;
236 if (reject_des_client || reject_md5_client) {
238 * Here we match Windows 2012 and return no flags.
240 *r->out.negotiate_flags = 0;
241 return NT_STATUS_DOWNGRADE_DETECTED;
245 * This talloc_free is important to prevent re-use of the
246 * challenge. We have to delay it this far due to NETApp
248 * https://bugzilla.samba.org/show_bug.cgi?id=11291
250 TALLOC_FREE(pipe_state);
253 * At this point we must also cleanup the TDB cache
254 * entry, if we fail the client needs to call
255 * netr_ServerReqChallenge again.
257 * Note: this handles a non existing record just fine,
258 * the r->in.computer_name might not be the one used
259 * in netr_ServerReqChallenge(), but we are trying to
260 * just tidy up the normal case to prevent re-use.
262 schannel_delete_challenge(dce_call->conn->dce_ctx->lp_ctx,
263 r->in.computer_name);
266 * According to Microsoft (see bugid #6099)
267 * Windows 7 looks at the negotiate_flags
268 * returned in this structure *even if the
269 * call fails with access denied!
271 *r->out.negotiate_flags = negotiate_flags;
273 switch (r->in.secure_channel_type) {
275 case SEC_CHAN_DNS_DOMAIN:
276 case SEC_CHAN_DOMAIN:
281 return NT_STATUS_INVALID_PARAMETER;
283 DEBUG(1, ("Client asked for an invalid secure channel type: %d\n",
284 r->in.secure_channel_type));
285 return NT_STATUS_INVALID_PARAMETER;
288 sam_ctx = samdb_connect(mem_ctx,
290 dce_call->conn->dce_ctx->lp_ctx,
291 system_session(dce_call->conn->dce_ctx->lp_ctx),
292 dce_call->conn->remote_address,
294 if (sam_ctx == NULL) {
295 return NT_STATUS_INVALID_SYSTEM_SERVICE;
298 if (r->in.secure_channel_type == SEC_CHAN_DOMAIN ||
299 r->in.secure_channel_type == SEC_CHAN_DNS_DOMAIN)
301 struct ldb_message *tdo_msg = NULL;
302 const char * const tdo_attrs[] = {
308 char *encoded_name = NULL;
310 const char *flatname = NULL;
312 bool require_trailer = true;
313 const char *netbios = NULL;
314 const char *dns = NULL;
316 if (r->in.secure_channel_type == SEC_CHAN_DNS_DOMAIN) {
318 require_trailer = false;
321 encoded_name = ldb_binary_encode_string(mem_ctx,
323 if (encoded_name == NULL) {
324 return NT_STATUS_NO_MEMORY;
327 len = strlen(encoded_name);
329 return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
332 if (require_trailer && encoded_name[len - 1] != trailer) {
333 return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
335 encoded_name[len - 1] = '\0';
337 if (r->in.secure_channel_type == SEC_CHAN_DNS_DOMAIN) {
340 netbios = encoded_name;
343 nt_status = dsdb_trust_search_tdo(sam_ctx,
345 tdo_attrs, mem_ctx, &tdo_msg);
346 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
347 DEBUG(2, ("Client asked for a trusted domain secure channel, "
348 "but there's no tdo for [%s] => [%s] \n",
349 log_escape(mem_ctx, r->in.account_name),
351 return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
353 if (!NT_STATUS_IS_OK(nt_status)) {
357 nt_status = dsdb_trust_get_incoming_passwords(tdo_msg, mem_ctx,
360 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_ACCOUNT_DISABLED)) {
361 return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
363 if (!NT_STATUS_IS_OK(nt_status)) {
367 flatname = ldb_msg_find_attr_as_string(tdo_msg, "flatName", NULL);
368 if (flatname == NULL) {
369 return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
372 *trust_account_for_search = talloc_asprintf(mem_ctx, "%s$", flatname);
373 if (*trust_account_for_search == NULL) {
374 return NT_STATUS_NO_MEMORY;
377 *trust_account_for_search = r->in.account_name;
380 /* pull the user attributes */
381 num_records = gendb_search(sam_ctx, mem_ctx, NULL, &msgs, attrs,
382 "(&(sAMAccountName=%s)(objectclass=user))",
383 ldb_binary_encode_string(mem_ctx,
384 *trust_account_for_search));
386 if (num_records == 0) {
387 DEBUG(3,("Couldn't find user [%s] in samdb.\n",
388 log_escape(mem_ctx, r->in.account_name)));
389 return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
392 if (num_records > 1) {
393 DEBUG(0,("Found %d records matching user [%s]\n",
395 log_escape(mem_ctx, r->in.account_name)));
396 return NT_STATUS_INTERNAL_DB_CORRUPTION;
399 *trust_account_in_db = ldb_msg_find_attr_as_string(msgs[0],
402 if (*trust_account_in_db == NULL) {
403 DEBUG(0,("No samAccountName returned in record matching user [%s]\n",
404 r->in.account_name));
405 return NT_STATUS_INTERNAL_DB_CORRUPTION;
408 user_account_control = ldb_msg_find_attr_as_uint(msgs[0], "userAccountControl", 0);
410 if (user_account_control & UF_ACCOUNTDISABLE) {
411 DEBUG(1, ("Account [%s] is disabled\n",
412 log_escape(mem_ctx, r->in.account_name)));
413 return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
416 if (r->in.secure_channel_type == SEC_CHAN_WKSTA) {
417 if (!(user_account_control & UF_WORKSTATION_TRUST_ACCOUNT)) {
418 DEBUG(1, ("Client asked for a workstation secure channel, but is not a workstation (member server) acb flags: 0x%x\n", user_account_control));
419 return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
421 } else if (r->in.secure_channel_type == SEC_CHAN_DOMAIN ||
422 r->in.secure_channel_type == SEC_CHAN_DNS_DOMAIN) {
423 if (!(user_account_control & UF_INTERDOMAIN_TRUST_ACCOUNT)) {
424 DEBUG(1, ("Client asked for a trusted domain secure channel, but is not a trusted domain: acb flags: 0x%x\n", user_account_control));
426 return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
428 } else if (r->in.secure_channel_type == SEC_CHAN_BDC) {
429 if (!(user_account_control & UF_SERVER_TRUST_ACCOUNT)) {
430 DEBUG(1, ("Client asked for a server secure channel, but is not a server (domain controller): acb flags: 0x%x\n", user_account_control));
431 return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
433 } else if (r->in.secure_channel_type == SEC_CHAN_RODC) {
434 if (!(user_account_control & UF_PARTIAL_SECRETS_ACCOUNT)) {
435 DEBUG(1, ("Client asked for a RODC secure channel, but is not a RODC: acb flags: 0x%x\n", user_account_control));
436 return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
439 /* we should never reach this */
440 return NT_STATUS_INTERNAL_ERROR;
443 if (!(user_account_control & UF_INTERDOMAIN_TRUST_ACCOUNT)) {
444 nt_status = samdb_result_passwords_no_lockout(mem_ctx,
445 dce_call->conn->dce_ctx->lp_ctx,
446 msgs[0], NULL, &curNtHash);
447 if (!NT_STATUS_IS_OK(nt_status)) {
448 return NT_STATUS_ACCESS_DENIED;
452 if (curNtHash == NULL) {
453 return NT_STATUS_ACCESS_DENIED;
456 if (!challenge_valid) {
457 DEBUG(1, ("No challenge requested by client [%s/%s], "
458 "cannot authenticate\n",
459 log_escape(mem_ctx, r->in.computer_name),
460 log_escape(mem_ctx, r->in.account_name)));
461 return NT_STATUS_ACCESS_DENIED;
464 creds = netlogon_creds_server_init(mem_ctx,
467 r->in.secure_channel_type,
468 &challenge.client_challenge,
469 &challenge.server_challenge,
472 r->out.return_credentials,
474 if (creds == NULL && prevNtHash != NULL) {
476 * We fallback to the previous password for domain trusts.
478 * Note that lpcfg_old_password_allowed_period() doesn't
481 creds = netlogon_creds_server_init(mem_ctx,
484 r->in.secure_channel_type,
485 &challenge.client_challenge,
486 &challenge.server_challenge,
489 r->out.return_credentials,
494 return NT_STATUS_ACCESS_DENIED;
496 creds->sid = samdb_result_dom_sid(creds, msgs[0], "objectSid");
497 *sid = talloc_memdup(mem_ctx, creds->sid, sizeof(struct dom_sid));
499 nt_status = schannel_save_creds_state(mem_ctx,
500 dce_call->conn->dce_ctx->lp_ctx,
502 if (!NT_STATUS_IS_OK(nt_status)) {
503 ZERO_STRUCTP(r->out.return_credentials);
507 *r->out.rid = samdb_result_rid_from_sid(mem_ctx, msgs[0],
514 * Log a netr_ServerAuthenticate3 request, and then invoke
515 * dcesrv_netr_ServerAuthenticate3_helper to perform the actual processing
517 static NTSTATUS dcesrv_netr_ServerAuthenticate3(
518 struct dcesrv_call_state *dce_call,
520 struct netr_ServerAuthenticate3 *r)
523 struct dom_sid *sid = NULL;
524 const char *trust_account_for_search = NULL;
525 const char *trust_account_in_db = NULL;
526 struct auth_usersupplied_info ui = {
527 .local_host = dce_call->conn->local_address,
528 .remote_host = dce_call->conn->remote_address,
530 .account_name = r->in.account_name,
531 .domain_name = lpcfg_workgroup(dce_call->conn->dce_ctx->lp_ctx),
533 .service_description = "NETLOGON",
534 .auth_description = "ServerAuthenticate",
535 .netlogon_trust_account = {
536 .computer_name = r->in.computer_name,
537 .negotiate_flags = *r->in.negotiate_flags,
538 .secure_channel_type = r->in.secure_channel_type,
542 status = dcesrv_netr_ServerAuthenticate3_helper(dce_call,
545 &trust_account_for_search,
546 &trust_account_in_db,
548 ui.netlogon_trust_account.sid = sid;
549 ui.netlogon_trust_account.account_name = trust_account_in_db;
550 ui.mapped.account_name = trust_account_for_search;
551 log_authentication_event(
552 dce_call->conn->msg_ctx,
553 dce_call->conn->dce_ctx->lp_ctx,
557 lpcfg_workgroup(dce_call->conn->dce_ctx->lp_ctx),
563 static NTSTATUS dcesrv_netr_ServerAuthenticate(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
564 struct netr_ServerAuthenticate *r)
566 struct netr_ServerAuthenticate3 a;
569 * negotiate_flags is used as an [in] parameter
570 * so it need to be initialised.
572 * (I think ... = 0; seems wrong here --metze)
574 uint32_t negotiate_flags_in = 0;
575 uint32_t negotiate_flags_out = 0;
577 a.in.server_name = r->in.server_name;
578 a.in.account_name = r->in.account_name;
579 a.in.secure_channel_type = r->in.secure_channel_type;
580 a.in.computer_name = r->in.computer_name;
581 a.in.credentials = r->in.credentials;
582 a.in.negotiate_flags = &negotiate_flags_in;
584 a.out.return_credentials = r->out.return_credentials;
586 a.out.negotiate_flags = &negotiate_flags_out;
588 return dcesrv_netr_ServerAuthenticate3(dce_call, mem_ctx, &a);
591 static NTSTATUS dcesrv_netr_ServerAuthenticate2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
592 struct netr_ServerAuthenticate2 *r)
594 struct netr_ServerAuthenticate3 r3;
597 r3.in.server_name = r->in.server_name;
598 r3.in.account_name = r->in.account_name;
599 r3.in.secure_channel_type = r->in.secure_channel_type;
600 r3.in.computer_name = r->in.computer_name;
601 r3.in.credentials = r->in.credentials;
602 r3.out.return_credentials = r->out.return_credentials;
603 r3.in.negotiate_flags = r->in.negotiate_flags;
604 r3.out.negotiate_flags = r->out.negotiate_flags;
607 return dcesrv_netr_ServerAuthenticate3(dce_call, mem_ctx, &r3);
611 * NOTE: The following functions are nearly identical to the ones available in
612 * source3/rpc_server/srv_nelog_nt.c
613 * The reason we keep 2 copies is that they use different structures to
614 * represent the auth_info and the decrpc pipes.
616 static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dce_call,
618 const char *computer_name,
619 struct netr_Authenticator *received_authenticator,
620 struct netr_Authenticator *return_authenticator,
621 struct netlogon_creds_CredentialState **creds_out)
624 int schannel = lpcfg_server_schannel(dce_call->conn->dce_ctx->lp_ctx);
625 bool schannel_global_required = (schannel == true);
627 if (schannel_global_required) {
628 enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
630 dcesrv_call_auth_info(dce_call, &auth_type, NULL);
632 if (auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
633 DBG_ERR("[%s] is not using schannel\n",
635 return NT_STATUS_ACCESS_DENIED;
639 nt_status = schannel_check_creds_state(mem_ctx,
640 dce_call->conn->dce_ctx->lp_ctx,
642 received_authenticator,
643 return_authenticator,
649 Change the machine account password for the currently connected
650 client. Supplies only the NT#.
653 static NTSTATUS dcesrv_netr_ServerPasswordSet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
654 struct netr_ServerPasswordSet *r)
656 struct netlogon_creds_CredentialState *creds;
657 struct ldb_context *sam_ctx;
658 const char * const attrs[] = { "unicodePwd", NULL };
659 struct ldb_message **res;
660 struct samr_Password *oldNtHash;
664 nt_status = dcesrv_netr_creds_server_step_check(dce_call,
667 r->in.credential, r->out.return_authenticator,
669 NT_STATUS_NOT_OK_RETURN(nt_status);
671 sam_ctx = samdb_connect(mem_ctx,
673 dce_call->conn->dce_ctx->lp_ctx,
674 system_session(dce_call->conn->dce_ctx->lp_ctx),
675 dce_call->conn->remote_address,
677 if (sam_ctx == NULL) {
678 return NT_STATUS_INVALID_SYSTEM_SERVICE;
681 netlogon_creds_des_decrypt(creds, r->in.new_password);
683 /* fetch the old password hashes (the NT hash has to exist) */
685 ret = gendb_search(sam_ctx, mem_ctx, NULL, &res, attrs,
686 "(&(objectClass=user)(objectSid=%s))",
687 ldap_encode_ndr_dom_sid(mem_ctx, creds->sid));
689 return NT_STATUS_WRONG_PASSWORD;
692 nt_status = samdb_result_passwords_no_lockout(mem_ctx,
693 dce_call->conn->dce_ctx->lp_ctx,
694 res[0], NULL, &oldNtHash);
695 if (!NT_STATUS_IS_OK(nt_status) || !oldNtHash) {
696 return NT_STATUS_WRONG_PASSWORD;
699 /* Using the sid for the account as the key, set the password */
700 nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
702 NULL, /* Don't have version */
703 NULL, /* Don't have plaintext */
704 NULL, r->in.new_password,
705 NULL, oldNtHash, /* Password change */
711 Change the machine account password for the currently connected
712 client. Supplies new plaintext.
714 static NTSTATUS dcesrv_netr_ServerPasswordSet2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
715 struct netr_ServerPasswordSet2 *r)
717 struct netlogon_creds_CredentialState *creds;
718 struct ldb_context *sam_ctx;
719 const char * const attrs[] = { "dBCSPwd", "unicodePwd", NULL };
720 struct ldb_message **res;
721 struct samr_Password *oldLmHash, *oldNtHash;
722 struct NL_PASSWORD_VERSION version = {};
723 const uint32_t *new_version = NULL;
725 DATA_BLOB new_password;
727 struct samr_CryptPassword password_buf;
729 nt_status = dcesrv_netr_creds_server_step_check(dce_call,
732 r->in.credential, r->out.return_authenticator,
734 NT_STATUS_NOT_OK_RETURN(nt_status);
736 sam_ctx = samdb_connect(mem_ctx,
738 dce_call->conn->dce_ctx->lp_ctx,
739 system_session(dce_call->conn->dce_ctx->lp_ctx),
740 dce_call->conn->remote_address,
742 if (sam_ctx == NULL) {
743 return NT_STATUS_INVALID_SYSTEM_SERVICE;
746 memcpy(password_buf.data, r->in.new_password->data, 512);
747 SIVAL(password_buf.data, 512, r->in.new_password->length);
749 if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
750 netlogon_creds_aes_decrypt(creds, password_buf.data, 516);
752 nt_status = netlogon_creds_arcfour_crypt(creds,
755 if (!NT_STATUS_IS_OK(nt_status)) {
760 switch (creds->secure_channel_type) {
761 case SEC_CHAN_DOMAIN:
762 case SEC_CHAN_DNS_DOMAIN: {
763 uint32_t len = IVAL(password_buf.data, 512);
765 uint32_t ofs = 500 - len;
768 p = password_buf.data + ofs;
770 version.ReservedField = IVAL(p, 0);
771 version.PasswordVersionNumber = IVAL(p, 4);
772 version.PasswordVersionPresent = IVAL(p, 8);
774 if (version.PasswordVersionPresent == NETLOGON_PASSWORD_VERSION_NUMBER_PRESENT) {
775 new_version = &version.PasswordVersionNumber;
783 if (!extract_pw_from_buffer(mem_ctx, password_buf.data, &new_password)) {
784 DEBUG(3,("samr: failed to decode password buffer\n"));
785 return NT_STATUS_WRONG_PASSWORD;
788 /* fetch the old password hashes (at least one of both has to exist) */
790 ret = gendb_search(sam_ctx, mem_ctx, NULL, &res, attrs,
791 "(&(objectClass=user)(objectSid=%s))",
792 ldap_encode_ndr_dom_sid(mem_ctx, creds->sid));
794 return NT_STATUS_WRONG_PASSWORD;
797 nt_status = samdb_result_passwords_no_lockout(mem_ctx,
798 dce_call->conn->dce_ctx->lp_ctx,
799 res[0], &oldLmHash, &oldNtHash);
800 if (!NT_STATUS_IS_OK(nt_status) || (!oldLmHash && !oldNtHash)) {
801 return NT_STATUS_WRONG_PASSWORD;
804 /* Using the sid for the account as the key, set the password */
805 nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
808 &new_password, /* we have plaintext */
810 oldLmHash, oldNtHash, /* Password change */
819 static WERROR dcesrv_netr_LogonUasLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
820 struct netr_LogonUasLogon *r)
822 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
829 static WERROR dcesrv_netr_LogonUasLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
830 struct netr_LogonUasLogoff *r)
832 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
836 static NTSTATUS dcesrv_netr_LogonSamLogon_check(struct dcesrv_call_state *dce_call,
837 const struct netr_LogonSamLogonEx *r)
839 enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
841 switch (r->in.logon_level) {
842 case NetlogonInteractiveInformation:
843 case NetlogonServiceInformation:
844 case NetlogonInteractiveTransitiveInformation:
845 case NetlogonServiceTransitiveInformation:
846 if (r->in.logon->password == NULL) {
847 return NT_STATUS_INVALID_PARAMETER;
850 switch (r->in.validation_level) {
851 case NetlogonValidationSamInfo: /* 2 */
852 case NetlogonValidationSamInfo2: /* 3 */
853 case NetlogonValidationSamInfo4: /* 6 */
856 return NT_STATUS_INVALID_INFO_CLASS;
860 case NetlogonNetworkInformation:
861 case NetlogonNetworkTransitiveInformation:
862 if (r->in.logon->network == NULL) {
863 return NT_STATUS_INVALID_PARAMETER;
866 switch (r->in.validation_level) {
867 case NetlogonValidationSamInfo: /* 2 */
868 case NetlogonValidationSamInfo2: /* 3 */
869 case NetlogonValidationSamInfo4: /* 6 */
872 return NT_STATUS_INVALID_INFO_CLASS;
877 case NetlogonGenericInformation:
878 if (r->in.logon->generic == NULL) {
879 return NT_STATUS_INVALID_PARAMETER;
882 switch (r->in.validation_level) {
883 /* TODO: case NetlogonValidationGenericInfo: 4 */
884 case NetlogonValidationGenericInfo2: /* 5 */
887 return NT_STATUS_INVALID_INFO_CLASS;
892 return NT_STATUS_INVALID_PARAMETER;
895 dcesrv_call_auth_info(dce_call, NULL, &auth_level);
897 switch (r->in.validation_level) {
898 case NetlogonValidationSamInfo4: /* 6 */
899 if (auth_level < DCERPC_AUTH_LEVEL_PRIVACY) {
900 return NT_STATUS_INVALID_PARAMETER;
911 struct dcesrv_netr_LogonSamLogon_base_state {
912 struct dcesrv_call_state *dce_call;
916 struct netlogon_creds_CredentialState *creds;
918 struct netr_LogonSamLogonEx r;
920 uint32_t _ignored_flags;
923 struct netr_LogonSamLogon *lsl;
924 struct netr_LogonSamLogonWithFlags *lslwf;
925 struct netr_LogonSamLogonEx *lslex;
928 struct kdc_check_generic_kerberos kr;
931 static void dcesrv_netr_LogonSamLogon_base_auth_done(struct tevent_req *subreq);
932 static void dcesrv_netr_LogonSamLogon_base_krb5_done(struct tevent_req *subreq);
933 static void dcesrv_netr_LogonSamLogon_base_reply(
934 struct dcesrv_netr_LogonSamLogon_base_state *state);
937 netr_LogonSamLogon_base
939 This version of the function allows other wrappers to say 'do not check the credentials'
941 We can't do the traditional 'wrapping' format completely, as this
942 function must only run under schannel
944 static NTSTATUS dcesrv_netr_LogonSamLogon_base_call(struct dcesrv_netr_LogonSamLogon_base_state *state)
946 struct dcesrv_call_state *dce_call = state->dce_call;
947 TALLOC_CTX *mem_ctx = state->mem_ctx;
948 struct netr_LogonSamLogonEx *r = &state->r;
949 struct netlogon_creds_CredentialState *creds = state->creds;
950 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
951 const char *workgroup = lpcfg_workgroup(lp_ctx);
952 struct auth4_context *auth_context = NULL;
953 struct auth_usersupplied_info *user_info = NULL;
955 struct tevent_req *subreq = NULL;
957 *r->out.authoritative = 1;
959 if (*r->in.flags & NETLOGON_SAMLOGON_FLAG_PASS_TO_FOREST_ROOT) {
961 * Currently we're always the forest root ourself.
963 return NT_STATUS_NO_SUCH_USER;
966 if (*r->in.flags & NETLOGON_SAMLOGON_FLAG_PASS_CROSS_FOREST_HOP) {
968 * Currently we don't support trusts correctly yet.
970 return NT_STATUS_NO_SUCH_USER;
973 user_info = talloc_zero(mem_ctx, struct auth_usersupplied_info);
974 NT_STATUS_HAVE_NO_MEMORY(user_info);
976 user_info->service_description = "SamLogon";
978 nt_status = netlogon_creds_decrypt_samlogon_logon(creds,
981 NT_STATUS_NOT_OK_RETURN(nt_status);
983 switch (r->in.logon_level) {
984 case NetlogonInteractiveInformation:
985 case NetlogonServiceInformation:
986 case NetlogonInteractiveTransitiveInformation:
987 case NetlogonServiceTransitiveInformation:
988 case NetlogonNetworkInformation:
989 case NetlogonNetworkTransitiveInformation:
991 nt_status = auth_context_create_for_netlogon(mem_ctx,
992 dce_call->event_ctx, dce_call->msg_ctx,
993 dce_call->conn->dce_ctx->lp_ctx,
995 NT_STATUS_NOT_OK_RETURN(nt_status);
997 user_info->remote_host = dce_call->conn->remote_address;
998 user_info->local_host = dce_call->conn->local_address;
1000 user_info->netlogon_trust_account.secure_channel_type
1001 = creds->secure_channel_type;
1002 user_info->netlogon_trust_account.negotiate_flags
1003 = creds->negotiate_flags;
1006 * These two can be unrelated when the account is
1007 * actually that of a trusted domain, so we want to
1008 * know which DC in that trusted domain contacted
1011 user_info->netlogon_trust_account.computer_name
1012 = creds->computer_name;
1013 user_info->netlogon_trust_account.account_name
1014 = creds->account_name;
1015 user_info->netlogon_trust_account.sid
1019 /* We do not need to set up the user_info in this case */
1023 switch (r->in.logon_level) {
1024 case NetlogonInteractiveInformation:
1025 case NetlogonServiceInformation:
1026 case NetlogonInteractiveTransitiveInformation:
1027 case NetlogonServiceTransitiveInformation:
1028 user_info->auth_description = "interactive";
1030 user_info->logon_parameters
1031 = r->in.logon->password->identity_info.parameter_control;
1032 user_info->client.account_name
1033 = r->in.logon->password->identity_info.account_name.string;
1034 user_info->client.domain_name
1035 = r->in.logon->password->identity_info.domain_name.string;
1036 user_info->workstation_name
1037 = r->in.logon->password->identity_info.workstation.string;
1038 user_info->flags |= USER_INFO_INTERACTIVE_LOGON;
1039 user_info->password_state = AUTH_PASSWORD_HASH;
1041 user_info->password.hash.lanman = talloc(user_info, struct samr_Password);
1042 NT_STATUS_HAVE_NO_MEMORY(user_info->password.hash.lanman);
1043 *user_info->password.hash.lanman = r->in.logon->password->lmpassword;
1045 user_info->password.hash.nt = talloc(user_info, struct samr_Password);
1046 NT_STATUS_HAVE_NO_MEMORY(user_info->password.hash.nt);
1047 *user_info->password.hash.nt = r->in.logon->password->ntpassword;
1050 = r->in.logon->password->identity_info.logon_id;
1053 case NetlogonNetworkInformation:
1054 case NetlogonNetworkTransitiveInformation:
1055 user_info->auth_description = "network";
1057 nt_status = auth_context_set_challenge(
1059 r->in.logon->network->challenge,
1060 "netr_LogonSamLogonWithFlags");
1061 NT_STATUS_NOT_OK_RETURN(nt_status);
1063 user_info->logon_parameters
1064 = r->in.logon->network->identity_info.parameter_control;
1065 user_info->client.account_name
1066 = r->in.logon->network->identity_info.account_name.string;
1067 user_info->client.domain_name
1068 = r->in.logon->network->identity_info.domain_name.string;
1069 user_info->workstation_name
1070 = r->in.logon->network->identity_info.workstation.string;
1072 user_info->password_state = AUTH_PASSWORD_RESPONSE;
1073 user_info->password.response.lanman = data_blob_talloc(mem_ctx, r->in.logon->network->lm.data, r->in.logon->network->lm.length);
1074 user_info->password.response.nt = data_blob_talloc(mem_ctx, r->in.logon->network->nt.data, r->in.logon->network->nt.length);
1077 = r->in.logon->network->identity_info.logon_id;
1079 nt_status = NTLMv2_RESPONSE_verify_netlogon_creds(
1080 user_info->client.account_name,
1081 user_info->client.domain_name,
1082 user_info->password.response.nt,
1084 NT_STATUS_NOT_OK_RETURN(nt_status);
1089 case NetlogonGenericInformation:
1091 if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
1093 } else if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
1096 /* Using DES to verify kerberos tickets makes no sense */
1097 return NT_STATUS_INVALID_PARAMETER;
1100 if (strcmp(r->in.logon->generic->package_name.string, "Kerberos") == 0) {
1101 struct dcerpc_binding_handle *irpc_handle;
1102 struct netr_GenericInfo2 *generic = talloc_zero(mem_ctx, struct netr_GenericInfo2);
1103 NT_STATUS_HAVE_NO_MEMORY(generic);
1105 r->out.validation->generic = generic;
1108 = r->in.logon->generic->identity_info.logon_id;
1110 irpc_handle = irpc_binding_handle_by_name(mem_ctx,
1114 if (irpc_handle == NULL) {
1115 return NT_STATUS_NO_LOGON_SERVERS;
1118 state->kr.in.generic_request =
1119 data_blob_const(r->in.logon->generic->data,
1120 r->in.logon->generic->length);
1123 * 60 seconds should be enough
1125 dcerpc_binding_handle_set_timeout(irpc_handle, 60);
1126 subreq = dcerpc_kdc_check_generic_kerberos_r_send(state,
1127 state->dce_call->event_ctx,
1128 irpc_handle, &state->kr);
1129 if (subreq == NULL) {
1130 return NT_STATUS_NO_MEMORY;
1132 state->dce_call->state_flags |= DCESRV_CALL_STATE_FLAG_ASYNC;
1133 tevent_req_set_callback(subreq,
1134 dcesrv_netr_LogonSamLogon_base_krb5_done,
1136 return NT_STATUS_OK;
1139 /* Until we get an implemetnation of these other packages */
1140 return NT_STATUS_INVALID_PARAMETER;
1143 return NT_STATUS_INVALID_PARAMETER;
1146 subreq = auth_check_password_send(state, state->dce_call->event_ctx,
1147 auth_context, user_info);
1148 state->dce_call->state_flags |= DCESRV_CALL_STATE_FLAG_ASYNC;
1149 tevent_req_set_callback(subreq,
1150 dcesrv_netr_LogonSamLogon_base_auth_done,
1152 return NT_STATUS_OK;
1155 static void dcesrv_netr_LogonSamLogon_base_auth_done(struct tevent_req *subreq)
1157 struct dcesrv_netr_LogonSamLogon_base_state *state =
1158 tevent_req_callback_data(subreq,
1159 struct dcesrv_netr_LogonSamLogon_base_state);
1160 TALLOC_CTX *mem_ctx = state->mem_ctx;
1161 struct netr_LogonSamLogonEx *r = &state->r;
1162 struct auth_user_info_dc *user_info_dc = NULL;
1163 struct netr_SamInfo2 *sam2 = NULL;
1164 struct netr_SamInfo3 *sam3 = NULL;
1165 struct netr_SamInfo6 *sam6 = NULL;
1168 nt_status = auth_check_password_recv(subreq, mem_ctx,
1170 r->out.authoritative);
1171 TALLOC_FREE(subreq);
1172 if (!NT_STATUS_IS_OK(nt_status)) {
1173 r->out.result = nt_status;
1174 dcesrv_netr_LogonSamLogon_base_reply(state);
1178 switch (r->in.validation_level) {
1180 nt_status = auth_convert_user_info_dc_saminfo2(mem_ctx,
1183 if (!NT_STATUS_IS_OK(nt_status)) {
1184 r->out.result = nt_status;
1185 dcesrv_netr_LogonSamLogon_base_reply(state);
1189 r->out.validation->sam2 = sam2;
1193 nt_status = auth_convert_user_info_dc_saminfo3(mem_ctx,
1196 if (!NT_STATUS_IS_OK(nt_status)) {
1197 r->out.result = nt_status;
1198 dcesrv_netr_LogonSamLogon_base_reply(state);
1202 r->out.validation->sam3 = sam3;
1206 nt_status = auth_convert_user_info_dc_saminfo6(mem_ctx,
1209 if (!NT_STATUS_IS_OK(nt_status)) {
1210 r->out.result = nt_status;
1211 dcesrv_netr_LogonSamLogon_base_reply(state);
1215 r->out.validation->sam6 = sam6;
1219 if (!NT_STATUS_IS_OK(nt_status)) {
1220 r->out.result = NT_STATUS_INVALID_INFO_CLASS;
1221 dcesrv_netr_LogonSamLogon_base_reply(state);
1226 /* TODO: Describe and deal with these flags */
1229 r->out.result = NT_STATUS_OK;
1231 dcesrv_netr_LogonSamLogon_base_reply(state);
1234 static void dcesrv_netr_LogonSamLogon_base_krb5_done(struct tevent_req *subreq)
1236 struct dcesrv_netr_LogonSamLogon_base_state *state =
1237 tevent_req_callback_data(subreq,
1238 struct dcesrv_netr_LogonSamLogon_base_state);
1239 TALLOC_CTX *mem_ctx = state->mem_ctx;
1240 struct netr_LogonSamLogonEx *r = &state->r;
1241 struct netr_GenericInfo2 *generic = NULL;
1244 status = dcerpc_kdc_check_generic_kerberos_r_recv(subreq, mem_ctx);
1245 TALLOC_FREE(subreq);
1246 if (!NT_STATUS_IS_OK(status)) {
1247 r->out.result = status;
1248 dcesrv_netr_LogonSamLogon_base_reply(state);
1252 generic = r->out.validation->generic;
1253 generic->length = state->kr.out.generic_reply.length;
1254 generic->data = state->kr.out.generic_reply.data;
1256 /* TODO: Describe and deal with these flags */
1259 r->out.result = NT_STATUS_OK;
1261 dcesrv_netr_LogonSamLogon_base_reply(state);
1264 static void dcesrv_netr_LogonSamLogon_base_reply(
1265 struct dcesrv_netr_LogonSamLogon_base_state *state)
1267 struct netr_LogonSamLogonEx *r = &state->r;
1270 if (NT_STATUS_IS_OK(r->out.result)) {
1271 status = netlogon_creds_encrypt_samlogon_validation(state->creds,
1272 r->in.validation_level,
1274 if (!NT_STATUS_IS_OK(status)) {
1275 DBG_ERR("netlogon_creds_encrypt_samlogon_validation() "
1281 if (state->_r.lslex != NULL) {
1282 struct netr_LogonSamLogonEx *_r = state->_r.lslex;
1283 _r->out.result = r->out.result;
1284 } else if (state->_r.lslwf != NULL) {
1285 struct netr_LogonSamLogonWithFlags *_r = state->_r.lslwf;
1286 _r->out.result = r->out.result;
1287 } else if (state->_r.lsl != NULL) {
1288 struct netr_LogonSamLogon *_r = state->_r.lsl;
1289 _r->out.result = r->out.result;
1292 status = dcesrv_reply(state->dce_call);
1293 if (!NT_STATUS_IS_OK(status)) {
1294 DBG_ERR("dcesrv_reply() failed - %s\n",
1299 static NTSTATUS dcesrv_netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1300 struct netr_LogonSamLogonEx *r)
1302 enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
1303 struct dcesrv_netr_LogonSamLogon_base_state *state;
1306 *r->out.authoritative = 1;
1308 state = talloc_zero(mem_ctx, struct dcesrv_netr_LogonSamLogon_base_state);
1309 if (state == NULL) {
1310 return NT_STATUS_NO_MEMORY;
1313 state->dce_call = dce_call;
1314 state->mem_ctx = mem_ctx;
1316 state->r.in.server_name = r->in.server_name;
1317 state->r.in.computer_name = r->in.computer_name;
1318 state->r.in.logon_level = r->in.logon_level;
1319 state->r.in.logon = r->in.logon;
1320 state->r.in.validation_level = r->in.validation_level;
1321 state->r.in.flags = r->in.flags;
1322 state->r.out.validation = r->out.validation;
1323 state->r.out.authoritative = r->out.authoritative;
1324 state->r.out.flags = r->out.flags;
1326 state->_r.lslex = r;
1328 nt_status = dcesrv_netr_LogonSamLogon_check(dce_call, &state->r);
1329 if (!NT_STATUS_IS_OK(nt_status)) {
1333 nt_status = schannel_get_creds_state(mem_ctx,
1334 dce_call->conn->dce_ctx->lp_ctx,
1335 r->in.computer_name, &state->creds);
1336 if (!NT_STATUS_IS_OK(nt_status)) {
1340 dcesrv_call_auth_info(dce_call, &auth_type, NULL);
1342 if (auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
1343 return NT_STATUS_ACCESS_DENIED;
1346 nt_status = dcesrv_netr_LogonSamLogon_base_call(state);
1348 if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1356 netr_LogonSamLogonWithFlags
1359 static NTSTATUS dcesrv_netr_LogonSamLogonWithFlags(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1360 struct netr_LogonSamLogonWithFlags *r)
1362 struct dcesrv_netr_LogonSamLogon_base_state *state;
1365 *r->out.authoritative = 1;
1367 state = talloc_zero(mem_ctx, struct dcesrv_netr_LogonSamLogon_base_state);
1368 if (state == NULL) {
1369 return NT_STATUS_NO_MEMORY;
1372 state->dce_call = dce_call;
1373 state->mem_ctx = mem_ctx;
1375 state->r.in.server_name = r->in.server_name;
1376 state->r.in.computer_name = r->in.computer_name;
1377 state->r.in.logon_level = r->in.logon_level;
1378 state->r.in.logon = r->in.logon;
1379 state->r.in.validation_level = r->in.validation_level;
1380 state->r.in.flags = r->in.flags;
1381 state->r.out.validation = r->out.validation;
1382 state->r.out.authoritative = r->out.authoritative;
1383 state->r.out.flags = r->out.flags;
1385 state->_r.lslwf = r;
1387 nt_status = dcesrv_netr_LogonSamLogon_check(dce_call, &state->r);
1388 if (!NT_STATUS_IS_OK(nt_status)) {
1392 r->out.return_authenticator = talloc_zero(mem_ctx,
1393 struct netr_Authenticator);
1394 if (r->out.return_authenticator == NULL) {
1395 return NT_STATUS_NO_MEMORY;
1398 nt_status = dcesrv_netr_creds_server_step_check(dce_call,
1400 r->in.computer_name,
1402 r->out.return_authenticator,
1404 if (!NT_STATUS_IS_OK(nt_status)) {
1408 nt_status = dcesrv_netr_LogonSamLogon_base_call(state);
1410 if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1420 static NTSTATUS dcesrv_netr_LogonSamLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1421 struct netr_LogonSamLogon *r)
1423 struct dcesrv_netr_LogonSamLogon_base_state *state;
1426 *r->out.authoritative = 1;
1428 state = talloc_zero(mem_ctx, struct dcesrv_netr_LogonSamLogon_base_state);
1429 if (state == NULL) {
1430 return NT_STATUS_NO_MEMORY;
1433 state->dce_call = dce_call;
1434 state->mem_ctx = mem_ctx;
1436 state->r.in.server_name = r->in.server_name;
1437 state->r.in.computer_name = r->in.computer_name;
1438 state->r.in.logon_level = r->in.logon_level;
1439 state->r.in.logon = r->in.logon;
1440 state->r.in.validation_level = r->in.validation_level;
1441 state->r.in.flags = &state->_ignored_flags;
1442 state->r.out.validation = r->out.validation;
1443 state->r.out.authoritative = r->out.authoritative;
1444 state->r.out.flags = &state->_ignored_flags;
1448 nt_status = dcesrv_netr_LogonSamLogon_check(dce_call, &state->r);
1449 if (!NT_STATUS_IS_OK(nt_status)) {
1453 r->out.return_authenticator = talloc_zero(mem_ctx,
1454 struct netr_Authenticator);
1455 if (r->out.return_authenticator == NULL) {
1456 return NT_STATUS_NO_MEMORY;
1459 nt_status = dcesrv_netr_creds_server_step_check(dce_call,
1461 r->in.computer_name,
1463 r->out.return_authenticator,
1465 if (!NT_STATUS_IS_OK(nt_status)) {
1469 nt_status = dcesrv_netr_LogonSamLogon_base_call(state);
1471 if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1482 static NTSTATUS dcesrv_netr_LogonSamLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1483 struct netr_LogonSamLogoff *r)
1485 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1493 static NTSTATUS dcesrv_netr_DatabaseDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1494 struct netr_DatabaseDeltas *r)
1496 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1503 static NTSTATUS dcesrv_netr_DatabaseSync2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1504 struct netr_DatabaseSync2 *r)
1506 /* win2k3 native mode returns "NOT IMPLEMENTED" for this call */
1507 return NT_STATUS_NOT_IMPLEMENTED;
1514 static NTSTATUS dcesrv_netr_DatabaseSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1515 struct netr_DatabaseSync *r)
1517 struct netr_DatabaseSync2 r2;
1522 r2.in.logon_server = r->in.logon_server;
1523 r2.in.computername = r->in.computername;
1524 r2.in.credential = r->in.credential;
1525 r2.in.database_id = r->in.database_id;
1526 r2.in.restart_state = SYNCSTATE_NORMAL_STATE;
1527 r2.in.sync_context = r->in.sync_context;
1528 r2.out.sync_context = r->out.sync_context;
1529 r2.out.delta_enum_array = r->out.delta_enum_array;
1530 r2.in.preferredmaximumlength = r->in.preferredmaximumlength;
1532 status = dcesrv_netr_DatabaseSync2(dce_call, mem_ctx, &r2);
1541 static NTSTATUS dcesrv_netr_AccountDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1542 struct netr_AccountDeltas *r)
1544 /* w2k3 returns "NOT IMPLEMENTED" for this call */
1545 return NT_STATUS_NOT_IMPLEMENTED;
1552 static NTSTATUS dcesrv_netr_AccountSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1553 struct netr_AccountSync *r)
1555 /* w2k3 returns "NOT IMPLEMENTED" for this call */
1556 return NT_STATUS_NOT_IMPLEMENTED;
1563 static WERROR dcesrv_netr_GetDcName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1564 struct netr_GetDcName *r)
1566 struct auth_session_info *session_info =
1567 dcesrv_call_session_info(dce_call);
1568 const char * const attrs[] = { NULL };
1569 struct ldb_context *sam_ctx;
1570 struct ldb_message **res;
1571 struct ldb_dn *domain_dn;
1576 * [MS-NRPC] 3.5.5.3.4 NetrGetDCName says
1577 * that the domainname needs to be a valid netbios domain
1578 * name, if it is not NULL.
1580 if (r->in.domainname) {
1581 const char *dot = strchr(r->in.domainname, '.');
1582 size_t len = strlen(r->in.domainname);
1584 if (dot || len > 15) {
1585 return WERR_NERR_DCNOTFOUND;
1589 * TODO: Should we also varify that only valid
1590 * netbios name characters are used?
1594 sam_ctx = samdb_connect(mem_ctx,
1595 dce_call->event_ctx,
1596 dce_call->conn->dce_ctx->lp_ctx,
1598 dce_call->conn->remote_address,
1600 if (sam_ctx == NULL) {
1601 return WERR_DS_UNAVAILABLE;
1604 domain_dn = samdb_domain_to_dn(sam_ctx, mem_ctx,
1606 if (domain_dn == NULL) {
1607 return WERR_NO_SUCH_DOMAIN;
1610 ret = gendb_search_dn(sam_ctx, mem_ctx,
1611 domain_dn, &res, attrs);
1613 return WERR_NO_SUCH_DOMAIN;
1616 /* TODO: - return real IP address
1617 * - check all r->in.* parameters (server_unc is ignored by w2k3!)
1619 dcname = talloc_asprintf(mem_ctx, "\\\\%s",
1620 lpcfg_netbios_name(dce_call->conn->dce_ctx->lp_ctx));
1621 W_ERROR_HAVE_NO_MEMORY(dcname);
1623 *r->out.dcname = dcname;
1627 struct dcesrv_netr_LogonControl_base_state {
1628 struct dcesrv_call_state *dce_call;
1630 TALLOC_CTX *mem_ctx;
1632 struct netr_LogonControl2Ex r;
1635 struct netr_LogonControl *l;
1636 struct netr_LogonControl2 *l2;
1637 struct netr_LogonControl2Ex *l2ex;
1641 static void dcesrv_netr_LogonControl_base_done(struct tevent_req *subreq);
1643 static WERROR dcesrv_netr_LogonControl_base_call(struct dcesrv_netr_LogonControl_base_state *state)
1645 struct loadparm_context *lp_ctx = state->dce_call->conn->dce_ctx->lp_ctx;
1646 struct auth_session_info *session_info =
1647 dcesrv_call_session_info(state->dce_call);
1648 enum security_user_level security_level;
1649 struct dcerpc_binding_handle *irpc_handle;
1650 struct tevent_req *subreq;
1653 /* TODO: check for WERR_INVALID_COMPUTERNAME ? */
1655 if (state->_r.l != NULL) {
1659 if (state->r.in.level == 0x00000002) {
1660 return WERR_NOT_SUPPORTED;
1661 } else if (state->r.in.level != 0x00000001) {
1662 return WERR_INVALID_LEVEL;
1665 switch (state->r.in.function_code) {
1666 case NETLOGON_CONTROL_QUERY:
1667 case NETLOGON_CONTROL_REPLICATE:
1668 case NETLOGON_CONTROL_SYNCHRONIZE:
1669 case NETLOGON_CONTROL_PDC_REPLICATE:
1670 case NETLOGON_CONTROL_BREAKPOINT:
1671 case NETLOGON_CONTROL_BACKUP_CHANGE_LOG:
1672 case NETLOGON_CONTROL_TRUNCATE_LOG:
1675 return WERR_NOT_SUPPORTED;
1679 if (state->r.in.level < 0x00000001) {
1680 return WERR_INVALID_LEVEL;
1683 if (state->r.in.level > 0x00000004) {
1684 return WERR_INVALID_LEVEL;
1687 if (state->r.in.function_code == NETLOGON_CONTROL_QUERY) {
1688 struct netr_NETLOGON_INFO_1 *info1 = NULL;
1689 struct netr_NETLOGON_INFO_3 *info3 = NULL;
1691 switch (state->r.in.level) {
1693 info1 = talloc_zero(state->mem_ctx,
1694 struct netr_NETLOGON_INFO_1);
1695 if (info1 == NULL) {
1696 return WERR_NOT_ENOUGH_MEMORY;
1698 state->r.out.query->info1 = info1;
1702 info3 = talloc_zero(state->mem_ctx,
1703 struct netr_NETLOGON_INFO_3);
1704 if (info3 == NULL) {
1705 return WERR_NOT_ENOUGH_MEMORY;
1707 state->r.out.query->info3 = info3;
1711 return WERR_INVALID_PARAMETER;
1716 * Some validations are done before the access check
1717 * and some after the access check
1719 security_level = security_session_user_level(session_info, NULL);
1720 if (security_level < SECURITY_ADMINISTRATOR) {
1721 return WERR_ACCESS_DENIED;
1724 if (state->_r.l2 != NULL) {
1726 * netr_LogonControl2
1728 if (state->r.in.level == 0x00000004) {
1729 return WERR_INVALID_LEVEL;
1733 switch (state->r.in.level) {
1738 switch (state->r.in.function_code) {
1739 case NETLOGON_CONTROL_REDISCOVER:
1740 case NETLOGON_CONTROL_TC_QUERY:
1741 case NETLOGON_CONTROL_TC_VERIFY:
1744 return WERR_INVALID_PARAMETER;
1753 if (state->r.in.function_code != NETLOGON_CONTROL_FIND_USER) {
1754 return WERR_INVALID_PARAMETER;
1760 return WERR_INVALID_LEVEL;
1763 switch (state->r.in.function_code) {
1764 case NETLOGON_CONTROL_REDISCOVER:
1765 case NETLOGON_CONTROL_TC_QUERY:
1766 case NETLOGON_CONTROL_TC_VERIFY:
1767 if (state->r.in.level != 2) {
1768 return WERR_INVALID_PARAMETER;
1771 if (state->r.in.data == NULL) {
1772 return WERR_INVALID_PARAMETER;
1775 if (state->r.in.data->domain == NULL) {
1776 return WERR_INVALID_PARAMETER;
1781 case NETLOGON_CONTROL_CHANGE_PASSWORD:
1782 if (state->r.in.level != 1) {
1783 return WERR_INVALID_PARAMETER;
1786 if (state->r.in.data == NULL) {
1787 return WERR_INVALID_PARAMETER;
1790 if (state->r.in.data->domain == NULL) {
1791 return WERR_INVALID_PARAMETER;
1794 ok = lpcfg_is_my_domain_or_realm(lp_ctx,
1795 state->r.in.data->domain);
1797 struct ldb_context *sam_ctx;
1799 sam_ctx = samdb_connect(
1801 state->dce_call->event_ctx,
1803 system_session(lp_ctx),
1804 state->dce_call->conn->remote_address,
1806 if (sam_ctx == NULL) {
1807 return WERR_DS_UNAVAILABLE;
1811 * Secrets for trusted domains can only be triggered on
1814 ok = samdb_is_pdc(sam_ctx);
1815 TALLOC_FREE(sam_ctx);
1817 return WERR_INVALID_DOMAIN_ROLE;
1823 return WERR_NOT_SUPPORTED;
1826 irpc_handle = irpc_binding_handle_by_name(state,
1827 state->dce_call->msg_ctx,
1829 &ndr_table_winbind);
1830 if (irpc_handle == NULL) {
1831 DEBUG(0,("Failed to get binding_handle for winbind_server task\n"));
1832 state->dce_call->fault_code = DCERPC_FAULT_CANT_PERFORM;
1833 return WERR_SERVICE_NOT_FOUND;
1837 * 60 seconds timeout should be enough
1839 dcerpc_binding_handle_set_timeout(irpc_handle, 60);
1841 subreq = dcerpc_winbind_LogonControl_send(state,
1842 state->dce_call->event_ctx,
1844 state->r.in.function_code,
1847 state->r.out.query);
1848 if (subreq == NULL) {
1849 return WERR_NOT_ENOUGH_MEMORY;
1851 state->dce_call->state_flags |= DCESRV_CALL_STATE_FLAG_ASYNC;
1852 tevent_req_set_callback(subreq,
1853 dcesrv_netr_LogonControl_base_done,
1859 static void dcesrv_netr_LogonControl_base_done(struct tevent_req *subreq)
1861 struct dcesrv_netr_LogonControl_base_state *state =
1862 tevent_req_callback_data(subreq,
1863 struct dcesrv_netr_LogonControl_base_state);
1866 status = dcerpc_winbind_LogonControl_recv(subreq, state->mem_ctx,
1867 &state->r.out.result);
1868 TALLOC_FREE(subreq);
1869 if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
1870 state->r.out.result = WERR_TIMEOUT;
1871 } else if (!NT_STATUS_IS_OK(status)) {
1872 state->dce_call->fault_code = DCERPC_FAULT_CANT_PERFORM;
1873 DEBUG(0,(__location__ ": IRPC callback failed %s\n",
1874 nt_errstr(status)));
1877 if (state->_r.l2ex != NULL) {
1878 struct netr_LogonControl2Ex *r = state->_r.l2ex;
1879 r->out.result = state->r.out.result;
1880 } else if (state->_r.l2 != NULL) {
1881 struct netr_LogonControl2 *r = state->_r.l2;
1882 r->out.result = state->r.out.result;
1883 } else if (state->_r.l != NULL) {
1884 struct netr_LogonControl *r = state->_r.l;
1885 r->out.result = state->r.out.result;
1888 status = dcesrv_reply(state->dce_call);
1889 if (!NT_STATUS_IS_OK(status)) {
1890 DEBUG(0,(__location__ ": dcesrv_reply() failed - %s\n", nt_errstr(status)));
1897 static WERROR dcesrv_netr_LogonControl(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1898 struct netr_LogonControl *r)
1900 struct dcesrv_netr_LogonControl_base_state *state;
1903 state = talloc_zero(mem_ctx, struct dcesrv_netr_LogonControl_base_state);
1904 if (state == NULL) {
1905 return WERR_NOT_ENOUGH_MEMORY;
1908 state->dce_call = dce_call;
1909 state->mem_ctx = mem_ctx;
1911 state->r.in.logon_server = r->in.logon_server;
1912 state->r.in.function_code = r->in.function_code;
1913 state->r.in.level = r->in.level;
1914 state->r.in.data = NULL;
1915 state->r.out.query = r->out.query;
1919 werr = dcesrv_netr_LogonControl_base_call(state);
1921 if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1931 static WERROR dcesrv_netr_LogonControl2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1932 struct netr_LogonControl2 *r)
1934 struct dcesrv_netr_LogonControl_base_state *state;
1937 state = talloc_zero(mem_ctx, struct dcesrv_netr_LogonControl_base_state);
1938 if (state == NULL) {
1939 return WERR_NOT_ENOUGH_MEMORY;
1942 state->dce_call = dce_call;
1943 state->mem_ctx = mem_ctx;
1945 state->r.in.logon_server = r->in.logon_server;
1946 state->r.in.function_code = r->in.function_code;
1947 state->r.in.level = r->in.level;
1948 state->r.in.data = r->in.data;
1949 state->r.out.query = r->out.query;
1953 werr = dcesrv_netr_LogonControl_base_call(state);
1955 if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1963 netr_LogonControl2Ex
1965 static WERROR dcesrv_netr_LogonControl2Ex(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1966 struct netr_LogonControl2Ex *r)
1968 struct dcesrv_netr_LogonControl_base_state *state;
1971 state = talloc_zero(mem_ctx, struct dcesrv_netr_LogonControl_base_state);
1972 if (state == NULL) {
1973 return WERR_NOT_ENOUGH_MEMORY;
1976 state->dce_call = dce_call;
1977 state->mem_ctx = mem_ctx;
1982 werr = dcesrv_netr_LogonControl_base_call(state);
1984 if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1991 static WERROR fill_trusted_domains_array(TALLOC_CTX *mem_ctx,
1992 struct ldb_context *sam_ctx,
1993 struct netr_DomainTrustList *trusts,
1994 uint32_t trust_flags);
1999 static WERROR dcesrv_netr_GetAnyDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2000 struct netr_GetAnyDCName *r)
2002 struct auth_session_info *session_info =
2003 dcesrv_call_session_info(dce_call);
2004 struct netr_DomainTrustList *trusts;
2005 struct ldb_context *sam_ctx;
2006 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
2010 *r->out.dcname = NULL;
2012 if ((r->in.domainname == NULL) || (r->in.domainname[0] == '\0')) {
2013 /* if the domainname parameter wasn't set assume our domain */
2014 r->in.domainname = lpcfg_workgroup(lp_ctx);
2017 sam_ctx = samdb_connect(mem_ctx,
2018 dce_call->event_ctx,
2021 dce_call->conn->remote_address,
2023 if (sam_ctx == NULL) {
2024 return WERR_DS_UNAVAILABLE;
2027 if (strcasecmp(r->in.domainname, lpcfg_workgroup(lp_ctx)) == 0) {
2028 /* well we asked for a DC of our own domain */
2029 if (samdb_is_pdc(sam_ctx)) {
2030 /* we are the PDC of the specified domain */
2031 return WERR_NO_SUCH_DOMAIN;
2034 *r->out.dcname = talloc_asprintf(mem_ctx, "\\%s",
2035 lpcfg_netbios_name(lp_ctx));
2036 W_ERROR_HAVE_NO_MEMORY(*r->out.dcname);
2041 /* Okay, now we have to consider the trusted domains */
2043 trusts = talloc_zero(mem_ctx, struct netr_DomainTrustList);
2044 W_ERROR_HAVE_NO_MEMORY(trusts);
2048 werr = fill_trusted_domains_array(mem_ctx, sam_ctx, trusts,
2049 NETR_TRUST_FLAG_INBOUND
2050 | NETR_TRUST_FLAG_OUTBOUND);
2051 W_ERROR_NOT_OK_RETURN(werr);
2053 for (i = 0; i < trusts->count; i++) {
2054 if (strcasecmp(r->in.domainname, trusts->array[i].netbios_name) == 0) {
2055 /* FIXME: Here we need to find a DC for the specified
2056 * trusted domain. */
2058 /* return WERR_OK; */
2059 return WERR_NO_SUCH_DOMAIN;
2063 return WERR_NO_SUCH_DOMAIN;
2070 static NTSTATUS dcesrv_netr_DatabaseRedo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2071 struct netr_DatabaseRedo *r)
2073 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2078 netr_NetrEnumerateTrustedDomains
2080 static NTSTATUS dcesrv_netr_NetrEnumerateTrustedDomains(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2081 struct netr_NetrEnumerateTrustedDomains *r)
2083 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2088 netr_LogonGetCapabilities
2090 static NTSTATUS dcesrv_netr_LogonGetCapabilities(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2091 struct netr_LogonGetCapabilities *r)
2093 struct netlogon_creds_CredentialState *creds;
2096 status = dcesrv_netr_creds_server_step_check(dce_call,
2098 r->in.computer_name,
2100 r->out.return_authenticator,
2102 if (!NT_STATUS_IS_OK(status)) {
2103 DEBUG(0,(__location__ " Bad credentials - error\n"));
2105 NT_STATUS_NOT_OK_RETURN(status);
2107 if (r->in.query_level != 1) {
2108 return NT_STATUS_NOT_SUPPORTED;
2111 r->out.capabilities->server_capabilities = creds->negotiate_flags;
2113 return NT_STATUS_OK;
2118 netr_NETRLOGONSETSERVICEBITS
2120 static WERROR dcesrv_netr_NETRLOGONSETSERVICEBITS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2121 struct netr_NETRLOGONSETSERVICEBITS *r)
2123 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2128 netr_LogonGetTrustRid
2130 static WERROR dcesrv_netr_LogonGetTrustRid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2131 struct netr_LogonGetTrustRid *r)
2133 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2138 netr_NETRLOGONCOMPUTESERVERDIGEST
2140 static WERROR dcesrv_netr_NETRLOGONCOMPUTESERVERDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2141 struct netr_NETRLOGONCOMPUTESERVERDIGEST *r)
2143 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2148 netr_NETRLOGONCOMPUTECLIENTDIGEST
2150 static WERROR dcesrv_netr_NETRLOGONCOMPUTECLIENTDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2151 struct netr_NETRLOGONCOMPUTECLIENTDIGEST *r)
2153 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2161 static WERROR dcesrv_netr_DsRGetSiteName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2162 struct netr_DsRGetSiteName *r)
2164 struct auth_session_info *session_info =
2165 dcesrv_call_session_info(dce_call);
2166 struct ldb_context *sam_ctx;
2167 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
2169 sam_ctx = samdb_connect(mem_ctx,
2170 dce_call->event_ctx,
2173 dce_call->conn->remote_address,
2175 if (sam_ctx == NULL) {
2176 return WERR_DS_UNAVAILABLE;
2180 * We assume to be a DC when we get called over NETLOGON. Hence we
2181 * get our site name always by using "samdb_server_site_name()"
2182 * and not "samdb_client_site_name()".
2184 *r->out.site = samdb_server_site_name(sam_ctx, mem_ctx);
2185 W_ERROR_HAVE_NO_MEMORY(*r->out.site);
2192 fill in a netr_OneDomainInfo from our own domain/forest
2194 static NTSTATUS fill_our_one_domain_info(TALLOC_CTX *mem_ctx,
2195 const struct lsa_TrustDomainInfoInfoEx *our_tdo,
2196 struct GUID domain_guid,
2197 struct netr_OneDomainInfo *info,
2202 if (is_trust_list) {
2203 struct netr_trust_extension *tei = NULL;
2205 /* w2k8 only fills this on trusted domains */
2206 tei = talloc_zero(mem_ctx, struct netr_trust_extension);
2208 return NT_STATUS_NO_MEMORY;
2210 tei->flags |= NETR_TRUST_FLAG_PRIMARY;
2213 * We're always within a native forest
2215 tei->flags |= NETR_TRUST_FLAG_IN_FOREST;
2216 tei->flags |= NETR_TRUST_FLAG_NATIVE;
2218 /* For now we assume we're always the tree root */
2219 tei->flags |= NETR_TRUST_FLAG_TREEROOT;
2220 tei->parent_index = 0;
2222 tei->trust_type = our_tdo->trust_type;
2224 * This needs to be 0 instead of our_tdo->trust_attributes
2225 * It means LSA_TRUST_ATTRIBUTE_WITHIN_FOREST won't
2226 * be set, while NETR_TRUST_FLAG_IN_FOREST is set above.
2228 tei->trust_attributes = 0;
2230 info->trust_extension.info = tei;
2231 info->trust_extension.length = 16;
2234 if (is_trust_list) {
2235 info->dns_domainname.string = our_tdo->domain_name.string;
2237 /* MS-NRPC 3.5.4.3.9 - must be set to NULL for trust list */
2238 info->dns_forestname.string = NULL;
2240 info->dns_domainname.string = talloc_asprintf(mem_ctx, "%s.",
2241 our_tdo->domain_name.string);
2242 if (info->dns_domainname.string == NULL) {
2243 return NT_STATUS_NO_MEMORY;
2246 info->dns_forestname.string = info->dns_domainname.string;
2249 info->domainname.string = our_tdo->netbios_name.string;
2250 info->domain_sid = our_tdo->sid;
2251 info->domain_guid = domain_guid;
2253 return NT_STATUS_OK;
2257 fill in a netr_OneDomainInfo from a trust tdo
2259 static NTSTATUS fill_trust_one_domain_info(TALLOC_CTX *mem_ctx,
2260 struct GUID domain_guid,
2261 const struct lsa_TrustDomainInfoInfoEx *tdo,
2262 struct netr_OneDomainInfo *info)
2264 struct netr_trust_extension *tei = NULL;
2268 /* w2k8 only fills this on trusted domains */
2269 tei = talloc_zero(mem_ctx, struct netr_trust_extension);
2271 return NT_STATUS_NO_MEMORY;
2274 if (tdo->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
2275 tei->flags |= NETR_TRUST_FLAG_INBOUND;
2277 if (tdo->trust_direction & LSA_TRUST_DIRECTION_OUTBOUND) {
2278 tei->flags |= NETR_TRUST_FLAG_OUTBOUND;
2280 if (tdo->trust_attributes & LSA_TRUST_ATTRIBUTE_WITHIN_FOREST) {
2281 tei->flags |= NETR_TRUST_FLAG_IN_FOREST;
2285 * TODO: once we support multiple domains within our forest,
2286 * we need to fill this correct (or let the caller do it
2287 * for all domains marked with NETR_TRUST_FLAG_IN_FOREST).
2289 tei->parent_index = 0;
2291 tei->trust_type = tdo->trust_type;
2292 tei->trust_attributes = tdo->trust_attributes;
2294 info->trust_extension.info = tei;
2295 info->trust_extension.length = 16;
2297 info->domainname.string = tdo->netbios_name.string;
2298 if (tdo->trust_type != LSA_TRUST_TYPE_DOWNLEVEL) {
2299 info->dns_domainname.string = tdo->domain_name.string;
2301 info->dns_domainname.string = NULL;
2303 info->domain_sid = tdo->sid;
2304 info->domain_guid = domain_guid;
2306 /* MS-NRPC 3.5.4.3.9 - must be set to NULL for trust list */
2307 info->dns_forestname.string = NULL;
2309 return NT_STATUS_OK;
2313 netr_LogonGetDomainInfo
2314 this is called as part of the ADS domain logon procedure.
2316 It has an important role in convaying details about the client, such
2317 as Operating System, Version, Service Pack etc.
2319 static NTSTATUS dcesrv_netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_call,
2320 TALLOC_CTX *mem_ctx, struct netr_LogonGetDomainInfo *r)
2322 struct netlogon_creds_CredentialState *creds;
2323 const char * const trusts_attrs[] = {
2324 "securityIdentifier",
2332 const char * const attrs2[] = { "sAMAccountName", "dNSHostName",
2333 "msDS-SupportedEncryptionTypes", NULL };
2334 const char *sam_account_name, *old_dns_hostname, *prefix1, *prefix2;
2335 struct ldb_context *sam_ctx;
2336 const struct GUID *our_domain_guid = NULL;
2337 struct lsa_TrustDomainInfoInfoEx *our_tdo = NULL;
2338 struct ldb_message **res1, *new_msg;
2339 struct ldb_result *trusts_res = NULL;
2340 struct ldb_dn *workstation_dn;
2341 struct netr_DomainInformation *domain_info;
2342 struct netr_LsaPolicyInformation *lsa_policy_info;
2343 uint32_t default_supported_enc_types = 0xFFFFFFFF;
2344 bool update_dns_hostname = true;
2348 status = dcesrv_netr_creds_server_step_check(dce_call,
2350 r->in.computer_name,
2352 r->out.return_authenticator,
2354 if (!NT_STATUS_IS_OK(status)) {
2356 char* remote = NULL;
2357 TALLOC_CTX *frame = talloc_stackframe();
2358 remote = tsocket_address_string(dce_call->conn->remote_address,
2360 local = tsocket_address_string(dce_call->conn->local_address,
2362 DBG_ERR(("Bad credentials - "
2363 "computer[%s] remote[%s] local[%s]\n"),
2364 log_escape(frame, r->in.computer_name),
2369 NT_STATUS_NOT_OK_RETURN(status);
2371 sam_ctx = samdb_connect(mem_ctx,
2372 dce_call->event_ctx,
2373 dce_call->conn->dce_ctx->lp_ctx,
2374 system_session(dce_call->conn->dce_ctx->lp_ctx),
2375 dce_call->conn->remote_address,
2377 if (sam_ctx == NULL) {
2378 return NT_STATUS_INVALID_SYSTEM_SERVICE;
2381 switch (r->in.level) {
2382 case 1: /* Domain information */
2384 if (r->in.query->workstation_info == NULL) {
2385 return NT_STATUS_INVALID_PARAMETER;
2388 /* Prepares the workstation DN */
2389 workstation_dn = ldb_dn_new_fmt(mem_ctx, sam_ctx, "<SID=%s>",
2390 dom_sid_string(mem_ctx, creds->sid));
2391 NT_STATUS_HAVE_NO_MEMORY(workstation_dn);
2393 /* Lookup for attributes in workstation object */
2394 ret = gendb_search_dn(sam_ctx, mem_ctx, workstation_dn, &res1,
2397 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2400 /* Gets the sam account name which is checked against the DNS
2401 * hostname parameter. */
2402 sam_account_name = ldb_msg_find_attr_as_string(res1[0],
2405 if (sam_account_name == NULL) {
2406 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2410 * Checks that the sam account name without a possible "$"
2411 * matches as prefix with the DNS hostname in the workstation
2414 prefix1 = talloc_strndup(mem_ctx, sam_account_name,
2415 strcspn(sam_account_name, "$"));
2416 NT_STATUS_HAVE_NO_MEMORY(prefix1);
2417 if (r->in.query->workstation_info->dns_hostname != NULL) {
2418 prefix2 = talloc_strndup(mem_ctx,
2419 r->in.query->workstation_info->dns_hostname,
2420 strcspn(r->in.query->workstation_info->dns_hostname, "."));
2421 NT_STATUS_HAVE_NO_MEMORY(prefix2);
2423 if (strcasecmp(prefix1, prefix2) != 0) {
2424 update_dns_hostname = false;
2427 update_dns_hostname = false;
2430 /* Gets the old DNS hostname */
2431 old_dns_hostname = ldb_msg_find_attr_as_string(res1[0],
2436 * Updates the DNS hostname when the client wishes that the
2437 * server should handle this for him
2438 * ("NETR_WS_FLAG_HANDLES_SPN_UPDATE" not set). And this is
2439 * obviously only checked when we do already have a
2441 * See MS-NRPC section 3.5.4.3.9
2443 if ((old_dns_hostname != NULL) &&
2444 (r->in.query->workstation_info->workstation_flags
2445 & NETR_WS_FLAG_HANDLES_SPN_UPDATE) != 0) {
2446 update_dns_hostname = false;
2449 /* Gets host information and put them into our directory */
2451 new_msg = ldb_msg_new(mem_ctx);
2452 NT_STATUS_HAVE_NO_MEMORY(new_msg);
2454 new_msg->dn = workstation_dn;
2456 /* Sets the OS name */
2458 if (r->in.query->workstation_info->os_name.string == NULL) {
2459 return NT_STATUS_INVALID_PARAMETER;
2462 ret = ldb_msg_add_string(new_msg, "operatingSystem",
2463 r->in.query->workstation_info->os_name.string);
2464 if (ret != LDB_SUCCESS) {
2465 return NT_STATUS_NO_MEMORY;
2469 * Sets information from "os_version". On an empty structure
2470 * the values are cleared.
2472 if (r->in.query->workstation_info->os_version.os != NULL) {
2473 struct netr_OsVersionInfoEx *os_version;
2474 const char *os_version_str;
2476 os_version = &r->in.query->workstation_info->os_version.os->os;
2478 if (os_version->CSDVersion == NULL) {
2479 return NT_STATUS_INVALID_PARAMETER;
2482 os_version_str = talloc_asprintf(new_msg, "%u.%u (%u)",
2483 os_version->MajorVersion,
2484 os_version->MinorVersion,
2485 os_version->BuildNumber);
2486 NT_STATUS_HAVE_NO_MEMORY(os_version_str);
2488 ret = ldb_msg_add_string(new_msg,
2489 "operatingSystemServicePack",
2490 os_version->CSDVersion);
2491 if (ret != LDB_SUCCESS) {
2492 return NT_STATUS_NO_MEMORY;
2495 ret = ldb_msg_add_string(new_msg,
2496 "operatingSystemVersion",
2498 if (ret != LDB_SUCCESS) {
2499 return NT_STATUS_NO_MEMORY;
2502 ret = samdb_msg_add_delete(sam_ctx, mem_ctx, new_msg,
2503 "operatingSystemServicePack");
2504 if (ret != LDB_SUCCESS) {
2505 return NT_STATUS_NO_MEMORY;
2508 ret = samdb_msg_add_delete(sam_ctx, mem_ctx, new_msg,
2509 "operatingSystemVersion");
2510 if (ret != LDB_SUCCESS) {
2511 return NT_STATUS_NO_MEMORY;
2516 * If the boolean "update_dns_hostname" remained true, then we
2517 * are fine to start the update.
2519 if (update_dns_hostname) {
2520 ret = ldb_msg_add_string(new_msg,
2522 r->in.query->workstation_info->dns_hostname);
2523 if (ret != LDB_SUCCESS) {
2524 return NT_STATUS_NO_MEMORY;
2527 /* This manual "servicePrincipalName" generation is
2528 * still needed! Since the update in the samldb LDB
2529 * module does only work if the entries already exist
2530 * which isn't always the case. */
2531 ret = ldb_msg_add_string(new_msg,
2532 "servicePrincipalName",
2533 talloc_asprintf(new_msg, "HOST/%s",
2534 r->in.computer_name));
2535 if (ret != LDB_SUCCESS) {
2536 return NT_STATUS_NO_MEMORY;
2539 ret = ldb_msg_add_string(new_msg,
2540 "servicePrincipalName",
2541 talloc_asprintf(new_msg, "HOST/%s",
2542 r->in.query->workstation_info->dns_hostname));
2543 if (ret != LDB_SUCCESS) {
2544 return NT_STATUS_NO_MEMORY;
2548 if (dsdb_replace(sam_ctx, new_msg, 0) != LDB_SUCCESS) {
2549 DEBUG(3,("Impossible to update samdb: %s\n",
2550 ldb_errstring(sam_ctx)));
2553 talloc_free(new_msg);
2555 /* Writes back the domain information */
2557 our_domain_guid = samdb_domain_guid(sam_ctx);
2558 if (our_domain_guid == NULL) {
2559 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2562 status = dsdb_trust_local_tdo_info(mem_ctx, sam_ctx, &our_tdo);
2563 if (!NT_STATUS_IS_OK(status)) {
2567 status = dsdb_trust_search_tdos(sam_ctx,
2572 if (!NT_STATUS_IS_OK(status)) {
2576 domain_info = talloc(mem_ctx, struct netr_DomainInformation);
2577 NT_STATUS_HAVE_NO_MEMORY(domain_info);
2579 ZERO_STRUCTP(domain_info);
2581 /* Informations about the local and trusted domains */
2583 status = fill_our_one_domain_info(mem_ctx,
2586 &domain_info->primary_domain,
2588 if (!NT_STATUS_IS_OK(status)) {
2592 domain_info->trusted_domain_count = trusts_res->count + 1;
2593 domain_info->trusted_domains = talloc_zero_array(mem_ctx,
2594 struct netr_OneDomainInfo,
2595 domain_info->trusted_domain_count);
2596 NT_STATUS_HAVE_NO_MEMORY(domain_info->trusted_domains);
2598 for (i=0; i < trusts_res->count; i++) {
2599 struct netr_OneDomainInfo *o =
2600 &domain_info->trusted_domains[i];
2601 /* we can't know the guid of trusts outside our forest */
2602 struct GUID trust_domain_guid = GUID_zero();
2603 struct lsa_TrustDomainInfoInfoEx *tdo = NULL;
2605 status = dsdb_trust_parse_tdo_info(mem_ctx,
2606 trusts_res->msgs[i],
2608 if (!NT_STATUS_IS_OK(status)) {
2612 status = fill_trust_one_domain_info(mem_ctx,
2616 if (!NT_STATUS_IS_OK(status)) {
2621 status = fill_our_one_domain_info(mem_ctx,
2624 &domain_info->trusted_domains[i],
2626 if (!NT_STATUS_IS_OK(status)) {
2630 /* Sets the supported encryption types */
2631 domain_info->supported_enc_types = ldb_msg_find_attr_as_uint(res1[0],
2632 "msDS-SupportedEncryptionTypes",
2633 default_supported_enc_types);
2635 /* Other host domain information */
2637 lsa_policy_info = talloc(mem_ctx,
2638 struct netr_LsaPolicyInformation);
2639 NT_STATUS_HAVE_NO_MEMORY(lsa_policy_info);
2640 ZERO_STRUCTP(lsa_policy_info);
2642 domain_info->lsa_policy = *lsa_policy_info;
2644 /* The DNS hostname is only returned back when there is a chance
2646 if ((r->in.query->workstation_info->workstation_flags
2647 & NETR_WS_FLAG_HANDLES_SPN_UPDATE) != 0) {
2648 domain_info->dns_hostname.string = old_dns_hostname;
2650 domain_info->dns_hostname.string = NULL;
2653 domain_info->workstation_flags =
2654 r->in.query->workstation_info->workstation_flags & (
2655 NETR_WS_FLAG_HANDLES_SPN_UPDATE | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS);
2657 r->out.info->domain_info = domain_info;
2659 case 2: /* LSA policy information - not used at the moment */
2660 lsa_policy_info = talloc(mem_ctx,
2661 struct netr_LsaPolicyInformation);
2662 NT_STATUS_HAVE_NO_MEMORY(lsa_policy_info);
2663 ZERO_STRUCTP(lsa_policy_info);
2665 r->out.info->lsa_policy_info = lsa_policy_info;
2668 return NT_STATUS_INVALID_LEVEL;
2672 return NT_STATUS_OK;
2677 netr_ServerPasswordGet
2679 static NTSTATUS dcesrv_netr_ServerPasswordGet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2680 struct netr_ServerPasswordGet *r)
2682 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2685 static bool sam_rodc_access_check(struct ldb_context *sam_ctx,
2686 TALLOC_CTX *mem_ctx,
2687 struct dom_sid *user_sid,
2688 struct ldb_dn *obj_dn)
2690 const char *rodc_attrs[] = { "msDS-KrbTgtLink", "msDS-NeverRevealGroup", "msDS-RevealOnDemandGroup", "objectGUID", NULL };
2691 const char *obj_attrs[] = { "tokenGroups", "objectSid", "UserAccountControl", "msDS-KrbTgtLinkBL", NULL };
2692 struct ldb_dn *rodc_dn;
2694 struct ldb_result *rodc_res = NULL, *obj_res = NULL;
2695 const struct dom_sid *additional_sids[] = { NULL, NULL };
2697 struct dom_sid *object_sid;
2698 const struct dom_sid **never_reveal_sids, **reveal_sids, **token_sids;
2700 rodc_dn = ldb_dn_new_fmt(mem_ctx, sam_ctx, "<SID=%s>",
2701 dom_sid_string(mem_ctx, user_sid));
2702 if (!ldb_dn_validate(rodc_dn)) goto denied;
2704 /* do the two searches we need */
2705 ret = dsdb_search_dn(sam_ctx, mem_ctx, &rodc_res, rodc_dn, rodc_attrs,
2706 DSDB_SEARCH_SHOW_EXTENDED_DN);
2707 if (ret != LDB_SUCCESS || rodc_res->count != 1) goto denied;
2709 ret = dsdb_search_dn(sam_ctx, mem_ctx, &obj_res, obj_dn, obj_attrs, 0);
2710 if (ret != LDB_SUCCESS || obj_res->count != 1) goto denied;
2712 object_sid = samdb_result_dom_sid(mem_ctx, obj_res->msgs[0], "objectSid");
2714 additional_sids[0] = object_sid;
2716 werr = samdb_result_sid_array_dn(sam_ctx, rodc_res->msgs[0],
2717 mem_ctx, "msDS-NeverRevealGroup", &never_reveal_sids);
2718 if (!W_ERROR_IS_OK(werr)) {
2722 werr = samdb_result_sid_array_dn(sam_ctx, rodc_res->msgs[0],
2723 mem_ctx, "msDS-RevealOnDemandGroup", &reveal_sids);
2724 if (!W_ERROR_IS_OK(werr)) {
2729 * The SID list needs to include itself as well as the tokenGroups.
2731 * TODO determine if sIDHistory is required for this check
2733 werr = samdb_result_sid_array_ndr(sam_ctx, obj_res->msgs[0],
2734 mem_ctx, "tokenGroups", &token_sids,
2735 additional_sids, 1);
2736 if (!W_ERROR_IS_OK(werr) || token_sids==NULL) {
2740 if (never_reveal_sids &&
2741 sid_list_match(token_sids, never_reveal_sids)) {
2746 sid_list_match(token_sids, reveal_sids)) {
2758 netr_NetrLogonSendToSam
2760 static NTSTATUS dcesrv_netr_NetrLogonSendToSam(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2761 struct netr_NetrLogonSendToSam *r)
2763 struct netlogon_creds_CredentialState *creds;
2764 struct ldb_context *sam_ctx;
2766 DATA_BLOB decrypted_blob;
2767 enum ndr_err_code ndr_err;
2768 struct netr_SendToSamBase base_msg = { 0 };
2770 nt_status = dcesrv_netr_creds_server_step_check(dce_call,
2772 r->in.computer_name,
2774 r->out.return_authenticator,
2777 NT_STATUS_NOT_OK_RETURN(nt_status);
2779 switch (creds->secure_channel_type) {
2783 case SEC_CHAN_WKSTA:
2784 case SEC_CHAN_DNS_DOMAIN:
2785 case SEC_CHAN_DOMAIN:
2787 return NT_STATUS_INVALID_PARAMETER;
2789 DEBUG(1, ("Client asked for an invalid secure channel type: %d\n",
2790 creds->secure_channel_type));
2791 return NT_STATUS_INVALID_PARAMETER;
2794 sam_ctx = samdb_connect(mem_ctx,
2795 dce_call->event_ctx,
2796 dce_call->conn->dce_ctx->lp_ctx,
2797 system_session(dce_call->conn->dce_ctx->lp_ctx),
2798 dce_call->conn->remote_address,
2800 if (sam_ctx == NULL) {
2801 return NT_STATUS_INVALID_SYSTEM_SERVICE;
2804 /* Buffer is meant to be 16-bit aligned */
2805 if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
2806 netlogon_creds_aes_decrypt(creds, r->in.opaque_buffer, r->in.buffer_len);
2808 nt_status = netlogon_creds_arcfour_crypt(creds,
2809 r->in.opaque_buffer,
2811 if (!NT_STATUS_IS_OK(nt_status)) {
2816 decrypted_blob.data = r->in.opaque_buffer;
2817 decrypted_blob.length = r->in.buffer_len;
2819 ndr_err = ndr_pull_struct_blob(&decrypted_blob, mem_ctx, &base_msg,
2820 (ndr_pull_flags_fn_t)ndr_pull_netr_SendToSamBase);
2822 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2823 /* We only partially implement SendToSam */
2824 return NT_STATUS_NOT_IMPLEMENTED;
2827 /* Now 'send' to SAM */
2828 switch (base_msg.message_type) {
2829 case SendToSamResetBadPasswordCount:
2831 struct ldb_message *msg = ldb_msg_new(mem_ctx);
2832 struct ldb_dn *dn = NULL;
2836 ret = ldb_transaction_start(sam_ctx);
2837 if (ret != LDB_SUCCESS) {
2838 return NT_STATUS_INTERNAL_ERROR;
2841 ret = dsdb_find_dn_by_guid(sam_ctx,
2843 &base_msg.message.reset_bad_password.guid,
2846 if (ret != LDB_SUCCESS) {
2847 ldb_transaction_cancel(sam_ctx);
2848 return NT_STATUS_INVALID_PARAMETER;
2851 if (creds->secure_channel_type == SEC_CHAN_RODC &&
2852 !sam_rodc_access_check(sam_ctx, mem_ctx, creds->sid, dn)) {
2853 DEBUG(1, ("Client asked to reset bad password on "
2854 "an arbitrary user: %s\n",
2855 ldb_dn_get_linearized(dn)));
2856 ldb_transaction_cancel(sam_ctx);
2857 return NT_STATUS_INVALID_PARAMETER;
2862 ret = samdb_msg_add_int(sam_ctx, mem_ctx, msg, "badPwdCount", 0);
2863 if (ret != LDB_SUCCESS) {
2864 ldb_transaction_cancel(sam_ctx);
2865 return NT_STATUS_INVALID_PARAMETER;
2868 ret = dsdb_replace(sam_ctx, msg, 0);
2869 if (ret != LDB_SUCCESS) {
2870 ldb_transaction_cancel(sam_ctx);
2871 return NT_STATUS_INVALID_PARAMETER;
2874 ret = ldb_transaction_commit(sam_ctx);
2875 if (ret != LDB_SUCCESS) {
2876 ldb_transaction_cancel(sam_ctx);
2877 return NT_STATUS_INTERNAL_ERROR;
2883 return NT_STATUS_NOT_IMPLEMENTED;
2886 return NT_STATUS_OK;
2889 struct dcesrv_netr_DsRGetDCName_base_state {
2890 struct dcesrv_call_state *dce_call;
2891 TALLOC_CTX *mem_ctx;
2893 struct netr_DsRGetDCNameEx2 r;
2894 const char *client_site;
2897 struct netr_DsRGetDCName *dc;
2898 struct netr_DsRGetDCNameEx *dcex;
2899 struct netr_DsRGetDCNameEx2 *dcex2;
2903 static void dcesrv_netr_DsRGetDCName_base_done(struct tevent_req *subreq);
2905 static WERROR dcesrv_netr_DsRGetDCName_base_call(struct dcesrv_netr_DsRGetDCName_base_state *state)
2907 struct dcesrv_call_state *dce_call = state->dce_call;
2908 struct auth_session_info *session_info =
2909 dcesrv_call_session_info(dce_call);
2910 TALLOC_CTX *mem_ctx = state->mem_ctx;
2911 struct netr_DsRGetDCNameEx2 *r = &state->r;
2912 struct ldb_context *sam_ctx;
2913 struct netr_DsRGetDCNameInfo *info;
2914 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
2915 const struct tsocket_address *local_address;
2916 char *local_addr = NULL;
2917 const struct tsocket_address *remote_address;
2918 char *remote_addr = NULL;
2919 const char *server_site_name;
2921 struct netlogon_samlogon_response response;
2923 const char *dc_name = NULL;
2924 const char *domain_name = NULL;
2926 bool different_domain = true;
2928 ZERO_STRUCTP(r->out.info);
2930 sam_ctx = samdb_connect(state,
2931 dce_call->event_ctx,
2934 dce_call->conn->remote_address,
2936 if (sam_ctx == NULL) {
2937 return WERR_DS_UNAVAILABLE;
2940 local_address = dcesrv_connection_get_local_address(dce_call->conn);
2941 if (tsocket_address_is_inet(local_address, "ip")) {
2942 local_addr = tsocket_address_inet_addr_string(local_address, state);
2943 W_ERROR_HAVE_NO_MEMORY(local_addr);
2946 remote_address = dcesrv_connection_get_remote_address(dce_call->conn);
2947 if (tsocket_address_is_inet(remote_address, "ip")) {
2948 remote_addr = tsocket_address_inet_addr_string(remote_address, state);
2949 W_ERROR_HAVE_NO_MEMORY(remote_addr);
2952 /* "server_unc" is ignored by w2k3 */
2954 if (r->in.flags & ~(DSGETDC_VALID_FLAGS)) {
2955 return WERR_INVALID_FLAGS;
2958 if (r->in.flags & DS_GC_SERVER_REQUIRED &&
2959 r->in.flags & DS_PDC_REQUIRED &&
2960 r->in.flags & DS_KDC_REQUIRED) {
2961 return WERR_INVALID_FLAGS;
2963 if (r->in.flags & DS_IS_FLAT_NAME &&
2964 r->in.flags & DS_IS_DNS_NAME) {
2965 return WERR_INVALID_FLAGS;
2967 if (r->in.flags & DS_RETURN_DNS_NAME &&
2968 r->in.flags & DS_RETURN_FLAT_NAME) {
2969 return WERR_INVALID_FLAGS;
2971 if (r->in.flags & DS_DIRECTORY_SERVICE_REQUIRED &&
2972 r->in.flags & DS_DIRECTORY_SERVICE_6_REQUIRED) {
2973 return WERR_INVALID_FLAGS;
2976 if (r->in.flags & DS_GOOD_TIMESERV_PREFERRED &&
2978 (DS_DIRECTORY_SERVICE_REQUIRED |
2979 DS_DIRECTORY_SERVICE_PREFERRED |
2980 DS_GC_SERVER_REQUIRED |
2983 return WERR_INVALID_FLAGS;
2986 if (r->in.flags & DS_TRY_NEXTCLOSEST_SITE &&
2988 return WERR_INVALID_FLAGS;
2992 * If we send an all-zero GUID, we should ignore it as winbind actually
2993 * checks it with a DNS query. Windows also appears to ignore it.
2995 if (r->in.domain_guid != NULL && GUID_all_zero(r->in.domain_guid)) {
2996 r->in.domain_guid = NULL;
2999 /* Attempt winbind search only if we suspect the domain is incorrect */
3000 if (r->in.domain_name != NULL && strcmp("", r->in.domain_name) != 0) {
3001 if (r->in.flags & DS_IS_FLAT_NAME) {
3002 if (strcasecmp_m(r->in.domain_name,
3003 lpcfg_sam_name(lp_ctx)) == 0) {
3004 different_domain = false;
3006 } else if (r->in.flags & DS_IS_DNS_NAME) {
3007 if (strcasecmp_m(r->in.domain_name,
3008 lpcfg_dnsdomain(lp_ctx)) == 0) {
3009 different_domain = false;
3012 if (strcasecmp_m(r->in.domain_name,
3013 lpcfg_sam_name(lp_ctx)) == 0 ||
3014 strcasecmp_m(r->in.domain_name,
3015 lpcfg_dnsdomain(lp_ctx)) == 0) {
3016 different_domain = false;
3021 * We need to be able to handle empty domain names, where we
3022 * revert to our domain by default.
3024 different_domain = false;
3027 /* Proof server site parameter "site_name" if it was specified */
3028 server_site_name = samdb_server_site_name(sam_ctx, state);
3029 W_ERROR_HAVE_NO_MEMORY(server_site_name);
3030 if (different_domain || (r->in.site_name != NULL &&
3031 (strcasecmp_m(r->in.site_name,
3032 server_site_name) != 0))) {
3034 struct dcerpc_binding_handle *irpc_handle = NULL;
3035 struct tevent_req *subreq = NULL;
3038 * Retrieve the client site to override the winbind response.
3040 * DO NOT use Windows fallback for client site.
3041 * In the case of multiple domains, this is plainly wrong.
3043 * Note: It's possible that the client may belong to multiple
3044 * subnets across domains. It's not clear what this would mean,
3045 * but here we only return what this domain knows.
3047 state->client_site = samdb_client_site_name(sam_ctx,
3053 irpc_handle = irpc_binding_handle_by_name(state,
3056 &ndr_table_winbind);
3057 if (irpc_handle == NULL) {
3058 DEBUG(0,("Failed to get binding_handle for "
3059 "winbind_server task\n"));
3060 dce_call->fault_code = DCERPC_FAULT_CANT_PERFORM;
3061 return WERR_SERVICE_NOT_FOUND;
3064 dcerpc_binding_handle_set_timeout(irpc_handle, 60);
3066 dce_call->state_flags |= DCESRV_CALL_STATE_FLAG_ASYNC;
3068 subreq = dcerpc_wbint_DsGetDcName_send(state,
3069 dce_call->event_ctx,
3076 if (subreq == NULL) {
3077 return WERR_NOT_ENOUGH_MEMORY;
3080 tevent_req_set_callback(subreq,
3081 dcesrv_netr_DsRGetDCName_base_done,
3087 guid_str = r->in.domain_guid != NULL ?
3088 GUID_string(state, r->in.domain_guid) : NULL;
3090 status = fill_netlogon_samlogon_response(sam_ctx, mem_ctx,
3094 r->in.client_account,
3095 r->in.mask, remote_addr,
3096 NETLOGON_NT_VERSION_5EX_WITH_IP,
3097 lp_ctx, &response, true);
3098 if (!NT_STATUS_IS_OK(status)) {
3099 return ntstatus_to_werror(status);
3103 * According to MS-NRPC 2.2.1.2.1 we should set the "DS_DNS_FOREST_ROOT"
3104 * (O) flag when the returned forest name is in DNS format. This is here
3105 * always the case (see below).
3107 response.data.nt5_ex.server_type |= DS_DNS_FOREST_ROOT;
3109 if (r->in.flags & DS_RETURN_DNS_NAME) {
3110 dc_name = response.data.nt5_ex.pdc_dns_name;
3111 domain_name = response.data.nt5_ex.dns_domain;
3113 * According to MS-NRPC 2.2.1.2.1 we should set the
3114 * "DS_DNS_CONTROLLER" (M) and "DS_DNS_DOMAIN" (N) flags when
3115 * the returned information is in DNS form.
3117 response.data.nt5_ex.server_type |=
3118 DS_DNS_CONTROLLER | DS_DNS_DOMAIN;
3119 } else if (r->in.flags & DS_RETURN_FLAT_NAME) {
3120 dc_name = response.data.nt5_ex.pdc_name;
3121 domain_name = response.data.nt5_ex.domain_name;
3125 * TODO: autodetect what we need to return
3126 * based on the given arguments
3128 dc_name = response.data.nt5_ex.pdc_name;
3129 domain_name = response.data.nt5_ex.domain_name;
3132 if (!dc_name || !dc_name[0]) {
3133 return WERR_NO_SUCH_DOMAIN;
3136 if (!domain_name || !domain_name[0]) {
3137 return WERR_NO_SUCH_DOMAIN;
3140 info = talloc(mem_ctx, struct netr_DsRGetDCNameInfo);
3141 W_ERROR_HAVE_NO_MEMORY(info);
3142 info->dc_unc = talloc_asprintf(mem_ctx, "%s%s",
3143 dc_name[0] != '\\'? "\\\\":"",
3144 talloc_strdup(mem_ctx, dc_name));
3145 W_ERROR_HAVE_NO_MEMORY(info->dc_unc);
3147 pdc_ip = local_addr;
3148 if (pdc_ip == NULL) {
3149 pdc_ip = "127.0.0.1";
3151 info->dc_address = talloc_asprintf(mem_ctx, "\\\\%s", pdc_ip);
3152 W_ERROR_HAVE_NO_MEMORY(info->dc_address);
3153 info->dc_address_type = DS_ADDRESS_TYPE_INET;
3154 info->domain_guid = response.data.nt5_ex.domain_uuid;
3155 info->domain_name = domain_name;
3156 info->forest_name = response.data.nt5_ex.forest;
3157 info->dc_flags = response.data.nt5_ex.server_type;
3158 if (r->in.flags & DS_RETURN_DNS_NAME) {
3159 /* As MS-NRPC.pdf in 2.2.1.2.1 the DS_DNS_CONTROLLER flag should be
3160 * returned if we are returning info->dc_unc containing a FQDN.
3161 * This attribute is called DomainControllerName in the specs,
3162 * it seems that we decide to return FQDN or netbios depending on
3163 * DS_RETURN_DNS_NAME.
3165 info->dc_flags |= DS_DNS_CONTROLLER;
3167 info->dc_site_name = response.data.nt5_ex.server_site;
3168 info->client_site_name = response.data.nt5_ex.client_site;
3170 *r->out.info = info;
3175 static void dcesrv_netr_DsRGetDCName_base_done(struct tevent_req *subreq)
3177 struct dcesrv_netr_DsRGetDCName_base_state *state =
3178 tevent_req_callback_data(subreq,
3179 struct dcesrv_netr_DsRGetDCName_base_state);
3180 struct dcesrv_call_state *dce_call = state->dce_call;
3181 NTSTATUS result, status;
3183 status = dcerpc_wbint_DsGetDcName_recv(subreq,
3186 TALLOC_FREE(subreq);
3188 if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
3189 state->r.out.result = WERR_TIMEOUT;
3193 if (!NT_STATUS_IS_OK(status)) {
3194 DBG_ERR(__location__ ": IRPC callback failed %s\n",
3196 state->r.out.result = WERR_GEN_FAILURE;
3200 if (!NT_STATUS_IS_OK(result)) {
3201 DBG_NOTICE("DC location via winbind failed - %s\n",
3203 state->r.out.result = WERR_NO_SUCH_DOMAIN;
3207 if (state->r.out.info == NULL || state->r.out.info[0] == NULL) {
3208 DBG_ERR("DC location via winbind returned no results\n");
3209 state->r.out.result = WERR_GEN_FAILURE;
3213 if (state->r.out.info[0]->dc_unc == NULL) {
3214 DBG_ERR("DC location via winbind returned no DC unc\n");
3215 state->r.out.result = WERR_GEN_FAILURE;
3220 * Either the supplied site name is NULL (possibly via
3221 * TRY_NEXT_CLOSEST_SITE) or the resulting site name matches
3222 * the input match name.
3224 * TODO: Currently this means that requests with NETBIOS domain
3225 * names can fail because they do not return the site name.
3227 if (state->r.in.site_name == NULL ||
3228 strcasecmp_m("", state->r.in.site_name) == 0 ||
3229 (state->r.out.info[0]->dc_site_name != NULL &&
3230 strcasecmp_m(state->r.out.info[0]->dc_site_name,
3231 state->r.in.site_name) == 0)) {
3233 state->r.out.info[0]->client_site_name =
3234 talloc_move(state->mem_ctx, &state->client_site);
3237 * Make sure to return our DC UNC with // prefix.
3238 * Winbind currently doesn't send the leading slashes
3241 if (strlen(state->r.out.info[0]->dc_unc) > 2 &&
3242 strncmp("\\\\", state->r.out.info[0]->dc_unc, 2) != 0) {
3243 const char *dc_unc = NULL;
3245 dc_unc = talloc_asprintf(state->mem_ctx,
3247 state->r.out.info[0]->dc_unc);
3248 state->r.out.info[0]->dc_unc = dc_unc;
3251 state->r.out.result = WERR_OK;
3253 state->r.out.info = NULL;
3254 state->r.out.result = WERR_NO_SUCH_DOMAIN;
3258 if (state->_r.dcex2 != NULL) {
3259 struct netr_DsRGetDCNameEx2 *r = state->_r.dcex2;
3260 r->out.result = state->r.out.result;
3261 } else if (state->_r.dcex != NULL) {
3262 struct netr_DsRGetDCNameEx *r = state->_r.dcex;
3263 r->out.result = state->r.out.result;
3264 } else if (state->_r.dc != NULL) {
3265 struct netr_DsRGetDCName *r = state->_r.dc;
3266 r->out.result = state->r.out.result;
3270 status = dcesrv_reply(dce_call);
3271 if (!NT_STATUS_IS_OK(status)) {
3272 DEBUG(0,(__location__ ": dcesrv_reply() failed - %s\n",
3273 nt_errstr(status)));
3278 netr_DsRGetDCNameEx2
3280 static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call,
3281 TALLOC_CTX *mem_ctx,
3282 struct netr_DsRGetDCNameEx2 *r)
3284 struct dcesrv_netr_DsRGetDCName_base_state *state;
3286 state = talloc_zero(mem_ctx, struct dcesrv_netr_DsRGetDCName_base_state);
3287 if (state == NULL) {
3288 return WERR_NOT_ENOUGH_MEMORY;
3291 state->dce_call = dce_call;
3292 state->mem_ctx = mem_ctx;
3295 state->_r.dcex2 = r;
3297 return dcesrv_netr_DsRGetDCName_base_call(state);
3303 static WERROR dcesrv_netr_DsRGetDCNameEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3304 struct netr_DsRGetDCNameEx *r)
3306 struct dcesrv_netr_DsRGetDCName_base_state *state;
3308 state = talloc_zero(mem_ctx, struct dcesrv_netr_DsRGetDCName_base_state);
3309 if (state == NULL) {
3310 return WERR_NOT_ENOUGH_MEMORY;
3313 state->dce_call = dce_call;
3314 state->mem_ctx = mem_ctx;
3316 state->r.in.server_unc = r->in.server_unc;
3317 state->r.in.client_account = NULL;
3318 state->r.in.mask = 0;
3319 state->r.in.domain_guid = r->in.domain_guid;
3320 state->r.in.domain_name = r->in.domain_name;
3321 state->r.in.site_name = r->in.site_name;
3322 state->r.in.flags = r->in.flags;
3323 state->r.out.info = r->out.info;
3327 return dcesrv_netr_DsRGetDCName_base_call(state);
3333 * This function is a predecessor to DsrGetDcNameEx2 according to [MS-NRPC].
3334 * Although it has a site-guid parameter, the documentation 3.5.4.3.3 DsrGetDcName
3335 * insists that it be ignored.
3337 static WERROR dcesrv_netr_DsRGetDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3338 struct netr_DsRGetDCName *r)
3340 struct dcesrv_netr_DsRGetDCName_base_state *state;
3342 state = talloc_zero(mem_ctx, struct dcesrv_netr_DsRGetDCName_base_state);
3343 if (state == NULL) {
3344 return WERR_NOT_ENOUGH_MEMORY;
3347 state->dce_call = dce_call;
3348 state->mem_ctx = mem_ctx;
3350 state->r.in.server_unc = r->in.server_unc;
3351 state->r.in.client_account = NULL;
3352 state->r.in.mask = 0;
3353 state->r.in.domain_name = r->in.domain_name;
3354 state->r.in.domain_guid = r->in.domain_guid;
3356 state->r.in.site_name = NULL; /* this is correct, we should ignore site GUID */
3357 state->r.in.flags = r->in.flags;
3358 state->r.out.info = r->out.info;
3362 return dcesrv_netr_DsRGetDCName_base_call(state);
3365 netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN
3367 static WERROR dcesrv_netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3368 struct netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN *r)
3370 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3375 netr_NetrEnumerateTrustedDomainsEx
3377 static WERROR dcesrv_netr_NetrEnumerateTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3378 struct netr_NetrEnumerateTrustedDomainsEx *r)
3380 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3385 netr_DsRAddressToSitenamesExW
3387 static WERROR dcesrv_netr_DsRAddressToSitenamesExW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3388 struct netr_DsRAddressToSitenamesExW *r)
3390 struct auth_session_info *session_info =
3391 dcesrv_call_session_info(dce_call);
3392 struct ldb_context *sam_ctx;
3393 struct netr_DsRAddressToSitenamesExWCtr *ctr;
3394 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
3395 sa_family_t sin_family;
3396 struct sockaddr_in *addr;
3398 struct sockaddr_in6 *addr6;
3399 char addr_str[INET6_ADDRSTRLEN];
3401 char addr_str[INET_ADDRSTRLEN];
3407 sam_ctx = samdb_connect(mem_ctx,
3408 dce_call->event_ctx,
3411 dce_call->conn->remote_address,
3413 if (sam_ctx == NULL) {
3414 return WERR_DS_UNAVAILABLE;
3417 ctr = talloc(mem_ctx, struct netr_DsRAddressToSitenamesExWCtr);
3418 W_ERROR_HAVE_NO_MEMORY(ctr);
3422 ctr->count = r->in.count;
3423 ctr->sitename = talloc_array(ctr, struct lsa_String, ctr->count);
3424 W_ERROR_HAVE_NO_MEMORY(ctr->sitename);
3425 ctr->subnetname = talloc_array(ctr, struct lsa_String, ctr->count);
3426 W_ERROR_HAVE_NO_MEMORY(ctr->subnetname);
3428 for (i=0; i<ctr->count; i++) {
3429 ctr->sitename[i].string = NULL;
3430 ctr->subnetname[i].string = NULL;
3432 if (r->in.addresses[i].size < sizeof(sa_family_t)) {
3435 /* The first two byte of the buffer are reserved for the
3436 * "sin_family" but for now only the first one is used. */
3437 sin_family = r->in.addresses[i].buffer[0];
3439 switch (sin_family) {
3441 if (r->in.addresses[i].size < sizeof(struct sockaddr_in)) {
3444 addr = (struct sockaddr_in *) r->in.addresses[i].buffer;
3445 res = inet_ntop(AF_INET, &addr->sin_addr,
3446 addr_str, sizeof(addr_str));
3450 if (r->in.addresses[i].size < sizeof(struct sockaddr_in6)) {
3453 addr6 = (struct sockaddr_in6 *) r->in.addresses[i].buffer;
3454 res = inet_ntop(AF_INET6, &addr6->sin6_addr,
3455 addr_str, sizeof(addr_str));
3466 ctr->sitename[i].string = samdb_client_site_name(sam_ctx,
3471 W_ERROR_HAVE_NO_MEMORY(ctr->sitename[i].string);
3472 ctr->subnetname[i].string = subnet_name;
3480 netr_DsRAddressToSitenamesW
3482 static WERROR dcesrv_netr_DsRAddressToSitenamesW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3483 struct netr_DsRAddressToSitenamesW *r)
3485 struct netr_DsRAddressToSitenamesExW r2;
3486 struct netr_DsRAddressToSitenamesWCtr *ctr;
3492 r2.in.server_name = r->in.server_name;
3493 r2.in.count = r->in.count;
3494 r2.in.addresses = r->in.addresses;
3496 r2.out.ctr = talloc(mem_ctx, struct netr_DsRAddressToSitenamesExWCtr *);
3497 W_ERROR_HAVE_NO_MEMORY(r2.out.ctr);
3499 ctr = talloc(mem_ctx, struct netr_DsRAddressToSitenamesWCtr);
3500 W_ERROR_HAVE_NO_MEMORY(ctr);
3504 ctr->count = r->in.count;
3505 ctr->sitename = talloc_array(ctr, struct lsa_String, ctr->count);
3506 W_ERROR_HAVE_NO_MEMORY(ctr->sitename);
3508 werr = dcesrv_netr_DsRAddressToSitenamesExW(dce_call, mem_ctx, &r2);
3510 for (i=0; i<ctr->count; i++) {
3511 ctr->sitename[i].string = (*r2.out.ctr)->sitename[i].string;
3519 netr_DsrGetDcSiteCoverageW
3521 static WERROR dcesrv_netr_DsrGetDcSiteCoverageW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3522 struct netr_DsrGetDcSiteCoverageW *r)
3524 struct auth_session_info *session_info =
3525 dcesrv_call_session_info(dce_call);
3526 struct ldb_context *sam_ctx;
3527 struct DcSitesCtr *ctr;
3528 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
3530 sam_ctx = samdb_connect(mem_ctx,
3531 dce_call->event_ctx,
3534 dce_call->conn->remote_address,
3536 if (sam_ctx == NULL) {
3537 return WERR_DS_UNAVAILABLE;
3540 ctr = talloc(mem_ctx, struct DcSitesCtr);
3541 W_ERROR_HAVE_NO_MEMORY(ctr);
3545 /* For now only return our default site */
3547 ctr->sites = talloc_array(ctr, struct lsa_String, ctr->num_sites);
3548 W_ERROR_HAVE_NO_MEMORY(ctr->sites);
3549 ctr->sites[0].string = samdb_server_site_name(sam_ctx, mem_ctx);
3550 W_ERROR_HAVE_NO_MEMORY(ctr->sites[0].string);
3556 static WERROR fill_trusted_domains_array(TALLOC_CTX *mem_ctx,
3557 struct ldb_context *sam_ctx,
3558 struct netr_DomainTrustList *trusts,
3559 uint32_t trust_flags)
3561 struct ldb_dn *system_dn;
3562 struct ldb_message **dom_res = NULL;
3563 const char *trust_attrs[] = { "flatname", "trustPartner",
3564 "securityIdentifier", "trustDirection",
3565 "trustType", "trustAttributes", NULL };
3570 if (!(trust_flags & (NETR_TRUST_FLAG_INBOUND |
3571 NETR_TRUST_FLAG_OUTBOUND))) {
3572 return WERR_INVALID_FLAGS;
3575 system_dn = samdb_search_dn(sam_ctx, mem_ctx,
3576 ldb_get_default_basedn(sam_ctx),
3577 "(&(objectClass=container)(cn=System))");
3579 return WERR_GEN_FAILURE;
3582 ret = gendb_search(sam_ctx, mem_ctx, system_dn,
3583 &dom_res, trust_attrs,
3584 "(objectclass=trustedDomain)");
3586 for (i = 0; i < ret; i++) {
3587 unsigned int trust_dir;
3590 trust_dir = ldb_msg_find_attr_as_uint(dom_res[i],
3591 "trustDirection", 0);
3593 if (trust_dir & LSA_TRUST_DIRECTION_INBOUND) {
3594 flags |= NETR_TRUST_FLAG_INBOUND;
3596 if (trust_dir & LSA_TRUST_DIRECTION_OUTBOUND) {
3597 flags |= NETR_TRUST_FLAG_OUTBOUND;
3600 if (!(flags & trust_flags)) {
3601 /* this trust direction was not requested */
3606 trusts->array = talloc_realloc(trusts, trusts->array,
3607 struct netr_DomainTrust,
3609 W_ERROR_HAVE_NO_MEMORY(trusts->array);
3611 trusts->array[n].netbios_name = talloc_steal(trusts->array, ldb_msg_find_attr_as_string(dom_res[i], "flatname", NULL));
3612 if (!trusts->array[n].netbios_name) {
3613 DEBUG(0, ("DB Error, TrustedDomain entry (%s) "
3614 "without flatname\n",
3615 ldb_dn_get_linearized(dom_res[i]->dn)));
3618 trusts->array[n].dns_name = talloc_steal(trusts->array, ldb_msg_find_attr_as_string(dom_res[i], "trustPartner", NULL));
3620 trusts->array[n].trust_flags = flags;
3621 if ((trust_flags & NETR_TRUST_FLAG_IN_FOREST) &&
3622 !(flags & NETR_TRUST_FLAG_TREEROOT)) {
3623 /* TODO: find if we have parent in the list */
3624 trusts->array[n].parent_index = 0;
3627 trusts->array[n].trust_type =
3628 ldb_msg_find_attr_as_uint(dom_res[i],
3630 trusts->array[n].trust_attributes =
3631 ldb_msg_find_attr_as_uint(dom_res[i],
3632 "trustAttributes", 0);
3634 if ((trusts->array[n].trust_type == LSA_TRUST_TYPE_MIT) ||
3635 (trusts->array[n].trust_type == LSA_TRUST_TYPE_DCE)) {
3636 struct dom_sid zero_sid;
3637 ZERO_STRUCT(zero_sid);
3638 trusts->array[n].sid =
3639 dom_sid_dup(trusts, &zero_sid);
3641 trusts->array[n].sid =
3642 samdb_result_dom_sid(trusts, dom_res[i],
3643 "securityIdentifier");
3645 trusts->array[n].guid = GUID_zero();
3647 trusts->count = n + 1;
3650 talloc_free(dom_res);
3655 netr_DsrEnumerateDomainTrusts
3657 static WERROR dcesrv_netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce_call,
3658 TALLOC_CTX *mem_ctx,
3659 struct netr_DsrEnumerateDomainTrusts *r)
3661 struct auth_session_info *session_info =
3662 dcesrv_call_session_info(dce_call);
3663 struct netr_DomainTrustList *trusts;
3664 struct ldb_context *sam_ctx;
3666 struct ldb_message **dom_res;
3667 const char * const dom_attrs[] = { "objectSid", "objectGUID", NULL };
3668 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
3669 const char *dnsdomain = lpcfg_dnsdomain(lp_ctx);
3673 if (r->in.trust_flags & 0xFFFFFE00) {
3674 return WERR_INVALID_FLAGS;
3677 /* TODO: turn to hard check once we are sure this is 100% correct */
3678 if (!r->in.server_name) {
3679 DEBUG(3, ("Invalid domain! Expected name in domain [%s]. "
3680 "But received NULL!\n", dnsdomain));
3682 p = strchr(r->in.server_name, '.');
3684 DEBUG(3, ("Invalid domain! Expected name in domain "
3685 "[%s]. But received [%s]!\n",
3686 dnsdomain, r->in.server_name));
3687 p = r->in.server_name;
3691 if (strcasecmp(p, dnsdomain)) {
3692 DEBUG(3, ("Invalid domain! Expected name in domain "
3693 "[%s]. But received [%s]!\n",
3694 dnsdomain, r->in.server_name));
3698 trusts = talloc_zero(mem_ctx, struct netr_DomainTrustList);
3699 W_ERROR_HAVE_NO_MEMORY(trusts);
3702 r->out.trusts = trusts;
3704 sam_ctx = samdb_connect(mem_ctx,
3705 dce_call->event_ctx,
3708 dce_call->conn->remote_address,
3710 if (sam_ctx == NULL) {
3711 return WERR_GEN_FAILURE;
3714 if ((r->in.trust_flags & NETR_TRUST_FLAG_INBOUND) ||
3715 (r->in.trust_flags & NETR_TRUST_FLAG_OUTBOUND)) {
3717 werr = fill_trusted_domains_array(mem_ctx, sam_ctx,
3718 trusts, r->in.trust_flags);
3719 W_ERROR_NOT_OK_RETURN(werr);
3722 /* NOTE: we currently are always the root of the forest */
3723 if (r->in.trust_flags & NETR_TRUST_FLAG_IN_FOREST) {
3724 uint32_t n = trusts->count;
3726 ret = gendb_search_dn(sam_ctx, mem_ctx, NULL,
3727 &dom_res, dom_attrs);
3729 return WERR_GEN_FAILURE;
3732 trusts->count = n + 1;
3733 trusts->array = talloc_realloc(trusts, trusts->array,
3734 struct netr_DomainTrust,
3736 W_ERROR_HAVE_NO_MEMORY(trusts->array);
3738 trusts->array[n].netbios_name = lpcfg_workgroup(lp_ctx);
3739 trusts->array[n].dns_name = lpcfg_dnsdomain(lp_ctx);
3740 trusts->array[n].trust_flags =
3741 NETR_TRUST_FLAG_NATIVE |
3742 NETR_TRUST_FLAG_TREEROOT |
3743 NETR_TRUST_FLAG_IN_FOREST |
3744 NETR_TRUST_FLAG_PRIMARY;
3745 /* we are always the root domain for now */
3746 trusts->array[n].parent_index = 0;
3747 trusts->array[n].trust_type = LSA_TRUST_TYPE_UPLEVEL;
3748 trusts->array[n].trust_attributes = 0;
3749 trusts->array[n].sid = samdb_result_dom_sid(mem_ctx,
3752 trusts->array[n].guid = samdb_result_guid(dom_res[0],
3754 talloc_free(dom_res);
3762 netr_DsrDeregisterDNSHostRecords
3764 static WERROR dcesrv_netr_DsrDeregisterDNSHostRecords(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3765 struct netr_DsrDeregisterDNSHostRecords *r)
3767 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3771 static NTSTATUS dcesrv_netr_ServerGetTrustInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3772 struct netr_ServerGetTrustInfo *r);
3775 netr_ServerTrustPasswordsGet
3777 static NTSTATUS dcesrv_netr_ServerTrustPasswordsGet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3778 struct netr_ServerTrustPasswordsGet *r)
3780 struct netr_ServerGetTrustInfo r2 = {};
3781 struct netr_TrustInfo *_ti = NULL;
3784 r2.in.server_name = r->in.server_name;
3785 r2.in.account_name = r->in.account_name;
3786 r2.in.secure_channel_type = r->in.secure_channel_type;
3787 r2.in.computer_name = r->in.computer_name;
3788 r2.in.credential = r->in.credential;
3790 r2.out.return_authenticator = r->out.return_authenticator;
3791 r2.out.new_owf_password = r->out.new_owf_password;
3792 r2.out.old_owf_password = r->out.old_owf_password;
3793 r2.out.trust_info = &_ti;
3795 status = dcesrv_netr_ServerGetTrustInfo(dce_call, mem_ctx, &r2);
3797 r->out.return_authenticator = r2.out.return_authenticator;
3798 r->out.new_owf_password = r2.out.new_owf_password;
3799 r->out.old_owf_password = r2.out.old_owf_password;
3805 netr_DsRGetForestTrustInformation
3807 struct dcesrv_netr_DsRGetForestTrustInformation_state {
3808 struct dcesrv_call_state *dce_call;
3809 TALLOC_CTX *mem_ctx;
3810 struct netr_DsRGetForestTrustInformation *r;
3813 static void dcesrv_netr_DsRGetForestTrustInformation_done(struct tevent_req *subreq);
3815 static WERROR dcesrv_netr_DsRGetForestTrustInformation(struct dcesrv_call_state *dce_call,
3816 TALLOC_CTX *mem_ctx,
3817 struct netr_DsRGetForestTrustInformation *r)
3819 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
3820 struct auth_session_info *session_info =
3821 dcesrv_call_session_info(dce_call);
3822 enum security_user_level security_level;
3823 struct ldb_context *sam_ctx = NULL;
3824 struct dcesrv_netr_DsRGetForestTrustInformation_state *state = NULL;
3825 struct dcerpc_binding_handle *irpc_handle = NULL;
3826 struct tevent_req *subreq = NULL;
3827 struct ldb_dn *domain_dn = NULL;
3828 struct ldb_dn *forest_dn = NULL;
3832 security_level = security_session_user_level(session_info, NULL);
3833 if (security_level < SECURITY_USER) {
3834 return WERR_ACCESS_DENIED;
3837 if (r->in.flags & 0xFFFFFFFE) {
3838 return WERR_INVALID_FLAGS;
3841 sam_ctx = samdb_connect(mem_ctx,
3842 dce_call->event_ctx,
3845 dce_call->conn->remote_address,
3847 if (sam_ctx == NULL) {
3848 return WERR_GEN_FAILURE;
3851 domain_dn = ldb_get_default_basedn(sam_ctx);
3852 if (domain_dn == NULL) {
3853 return WERR_GEN_FAILURE;
3856 forest_dn = ldb_get_root_basedn(sam_ctx);
3857 if (forest_dn == NULL) {
3858 return WERR_GEN_FAILURE;
3861 cmp = ldb_dn_compare(domain_dn, forest_dn);
3863 return WERR_NERR_ACFNOTLOADED;
3866 forest_level = dsdb_forest_functional_level(sam_ctx);
3867 if (forest_level < DS_DOMAIN_FUNCTION_2003) {
3868 return WERR_INVALID_FUNCTION;
3871 if (r->in.flags & DS_GFTI_UPDATE_TDO) {
3872 if (!samdb_is_pdc(sam_ctx)) {
3873 return WERR_NERR_NOTPRIMARY;
3876 if (r->in.trusted_domain_name == NULL) {
3877 return WERR_INVALID_FLAGS;
3881 if (r->in.trusted_domain_name == NULL) {
3885 * information about our own domain
3887 status = dsdb_trust_xref_forest_info(mem_ctx, sam_ctx,
3888 r->out.forest_trust_info);
3889 if (!NT_STATUS_IS_OK(status)) {
3890 return ntstatus_to_werror(status);
3897 * Forward the request to winbindd
3900 state = talloc_zero(mem_ctx,
3901 struct dcesrv_netr_DsRGetForestTrustInformation_state);
3902 if (state == NULL) {
3903 return WERR_NOT_ENOUGH_MEMORY;
3905 state->dce_call = dce_call;
3906 state->mem_ctx = mem_ctx;
3909 irpc_handle = irpc_binding_handle_by_name(state,
3910 state->dce_call->msg_ctx,
3912 &ndr_table_winbind);
3913 if (irpc_handle == NULL) {
3914 DEBUG(0,("Failed to get binding_handle for winbind_server task\n"));
3915 state->dce_call->fault_code = DCERPC_FAULT_CANT_PERFORM;
3916 return WERR_SERVICE_NOT_FOUND;
3920 * 60 seconds timeout should be enough
3922 dcerpc_binding_handle_set_timeout(irpc_handle, 60);
3924 subreq = dcerpc_winbind_GetForestTrustInformation_send(state,
3925 state->dce_call->event_ctx,
3927 r->in.trusted_domain_name,
3929 r->out.forest_trust_info);
3930 if (subreq == NULL) {
3931 return WERR_NOT_ENOUGH_MEMORY;
3933 state->dce_call->state_flags |= DCESRV_CALL_STATE_FLAG_ASYNC;
3934 tevent_req_set_callback(subreq,
3935 dcesrv_netr_DsRGetForestTrustInformation_done,
3941 static void dcesrv_netr_DsRGetForestTrustInformation_done(struct tevent_req *subreq)
3943 struct dcesrv_netr_DsRGetForestTrustInformation_state *state =
3944 tevent_req_callback_data(subreq,
3945 struct dcesrv_netr_DsRGetForestTrustInformation_state);
3948 status = dcerpc_winbind_GetForestTrustInformation_recv(subreq,
3950 &state->r->out.result);
3951 TALLOC_FREE(subreq);
3952 if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
3953 state->r->out.result = WERR_TIMEOUT;
3954 } else if (!NT_STATUS_IS_OK(status)) {
3955 state->dce_call->fault_code = DCERPC_FAULT_CANT_PERFORM;
3956 DEBUG(0,(__location__ ": IRPC callback failed %s\n",
3957 nt_errstr(status)));
3960 status = dcesrv_reply(state->dce_call);
3961 if (!NT_STATUS_IS_OK(status)) {
3962 DEBUG(0,(__location__ ": dcesrv_reply() failed - %s\n", nt_errstr(status)));
3967 netr_GetForestTrustInformation
3969 static NTSTATUS dcesrv_netr_GetForestTrustInformation(struct dcesrv_call_state *dce_call,
3970 TALLOC_CTX *mem_ctx,
3971 struct netr_GetForestTrustInformation *r)
3973 struct auth_session_info *session_info =
3974 dcesrv_call_session_info(dce_call);
3975 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
3976 struct netlogon_creds_CredentialState *creds = NULL;
3977 struct ldb_context *sam_ctx = NULL;
3978 struct ldb_dn *domain_dn = NULL;
3979 struct ldb_dn *forest_dn = NULL;
3984 status = dcesrv_netr_creds_server_step_check(dce_call,
3986 r->in.computer_name,
3988 r->out.return_authenticator,
3990 if (!NT_STATUS_IS_OK(status)) {
3994 if ((creds->secure_channel_type != SEC_CHAN_DNS_DOMAIN) &&
3995 (creds->secure_channel_type != SEC_CHAN_DOMAIN)) {
3996 return NT_STATUS_NOT_IMPLEMENTED;
3999 sam_ctx = samdb_connect(mem_ctx,
4000 dce_call->event_ctx,
4003 dce_call->conn->remote_address,
4005 if (sam_ctx == NULL) {
4006 return NT_STATUS_INTERNAL_ERROR;
4009 /* TODO: check r->in.server_name is our name */
4011 domain_dn = ldb_get_default_basedn(sam_ctx);
4012 if (domain_dn == NULL) {
4013 return NT_STATUS_INTERNAL_ERROR;
4016 forest_dn = ldb_get_root_basedn(sam_ctx);
4017 if (forest_dn == NULL) {
4018 return NT_STATUS_INTERNAL_ERROR;
4021 cmp = ldb_dn_compare(domain_dn, forest_dn);
4023 return NT_STATUS_INVALID_DOMAIN_STATE;
4026 forest_level = dsdb_forest_functional_level(sam_ctx);
4027 if (forest_level < DS_DOMAIN_FUNCTION_2003) {
4028 return NT_STATUS_INVALID_DOMAIN_STATE;
4031 status = dsdb_trust_xref_forest_info(mem_ctx, sam_ctx,
4032 r->out.forest_trust_info);
4033 if (!NT_STATUS_IS_OK(status)) {
4037 return NT_STATUS_OK;
4042 netr_ServerGetTrustInfo
4044 static NTSTATUS dcesrv_netr_ServerGetTrustInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4045 struct netr_ServerGetTrustInfo *r)
4047 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
4048 struct netlogon_creds_CredentialState *creds = NULL;
4049 struct ldb_context *sam_ctx = NULL;
4050 const char * const attrs[] = {
4053 "userAccountControl",
4056 struct ldb_message **res = NULL;
4057 struct samr_Password *curNtHash = NULL, *prevNtHash = NULL;
4060 const char *asid = NULL;
4062 const char *aname = NULL;
4063 struct ldb_message *tdo_msg = NULL;
4064 const char * const tdo_attrs[] = {
4065 "trustAuthIncoming",
4069 struct netr_TrustInfo *trust_info = NULL;
4071 ZERO_STRUCTP(r->out.new_owf_password);
4072 ZERO_STRUCTP(r->out.old_owf_password);
4074 nt_status = dcesrv_netr_creds_server_step_check(dce_call,
4076 r->in.computer_name,
4078 r->out.return_authenticator,
4080 if (!NT_STATUS_IS_OK(nt_status)) {
4084 /* TODO: check r->in.server_name is our name */
4086 if (strcasecmp_m(r->in.account_name, creds->account_name) != 0) {
4087 return NT_STATUS_INVALID_PARAMETER;
4090 if (r->in.secure_channel_type != creds->secure_channel_type) {
4091 return NT_STATUS_INVALID_PARAMETER;
4094 if (strcasecmp_m(r->in.computer_name, creds->computer_name) != 0) {
4095 return NT_STATUS_INVALID_PARAMETER;
4098 sam_ctx = samdb_connect(mem_ctx,
4099 dce_call->event_ctx,
4101 system_session(lp_ctx),
4102 dce_call->conn->remote_address,
4104 if (sam_ctx == NULL) {
4105 return NT_STATUS_INVALID_SYSTEM_SERVICE;
4108 asid = ldap_encode_ndr_dom_sid(mem_ctx, creds->sid);
4110 return NT_STATUS_NO_MEMORY;
4113 ret = gendb_search(sam_ctx, mem_ctx, NULL, &res, attrs,
4114 "(&(objectClass=user)(objectSid=%s))",
4117 return NT_STATUS_ACCOUNT_DISABLED;
4120 switch (creds->secure_channel_type) {
4121 case SEC_CHAN_DNS_DOMAIN:
4122 case SEC_CHAN_DOMAIN:
4123 uac = ldb_msg_find_attr_as_uint(res[0], "userAccountControl", 0);
4125 if (uac & UF_ACCOUNTDISABLE) {
4126 return NT_STATUS_ACCOUNT_DISABLED;
4129 if (!(uac & UF_INTERDOMAIN_TRUST_ACCOUNT)) {
4130 return NT_STATUS_ACCOUNT_DISABLED;
4133 aname = ldb_msg_find_attr_as_string(res[0], "sAMAccountName", NULL);
4134 if (aname == NULL) {
4135 return NT_STATUS_ACCOUNT_DISABLED;
4138 nt_status = dsdb_trust_search_tdo_by_type(sam_ctx,
4139 SEC_CHAN_DOMAIN, aname,
4140 tdo_attrs, mem_ctx, &tdo_msg);
4141 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4142 return NT_STATUS_ACCOUNT_DISABLED;
4144 if (!NT_STATUS_IS_OK(nt_status)) {
4148 nt_status = dsdb_trust_get_incoming_passwords(tdo_msg, mem_ctx,
4151 if (!NT_STATUS_IS_OK(nt_status)) {
4155 trust_info = talloc_zero(mem_ctx, struct netr_TrustInfo);
4156 if (trust_info == NULL) {
4157 return NT_STATUS_NO_MEMORY;
4160 trust_info->count = 1;
4161 trust_info->data = talloc_array(trust_info, uint32_t,
4163 if (trust_info->data == NULL) {
4164 return NT_STATUS_NO_MEMORY;
4167 trust_info->data[0] = ldb_msg_find_attr_as_uint(tdo_msg,
4173 nt_status = samdb_result_passwords_no_lockout(mem_ctx, lp_ctx,
4176 if (!NT_STATUS_IS_OK(nt_status)) {
4180 prevNtHash = talloc(mem_ctx, struct samr_Password);
4181 if (prevNtHash == NULL) {
4182 return NT_STATUS_NO_MEMORY;
4185 E_md4hash("", prevNtHash->hash);
4189 if (curNtHash != NULL) {
4190 *r->out.new_owf_password = *curNtHash;
4191 netlogon_creds_des_encrypt(creds, r->out.new_owf_password);
4193 if (prevNtHash != NULL) {
4194 *r->out.old_owf_password = *prevNtHash;
4195 netlogon_creds_des_encrypt(creds, r->out.old_owf_password);
4198 if (trust_info != NULL) {
4199 *r->out.trust_info = trust_info;
4202 return NT_STATUS_OK;
4208 static NTSTATUS dcesrv_netr_Unused47(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4209 struct netr_Unused47 *r)
4211 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4215 struct netr_dnsupdate_RODC_state {
4216 struct dcesrv_call_state *dce_call;
4217 struct netr_DsrUpdateReadOnlyServerDnsRecords *r;
4218 struct dnsupdate_RODC *r2;
4222 called when the forwarded RODC dns update request is finished
4224 static void netr_dnsupdate_RODC_callback(struct tevent_req *subreq)
4226 struct netr_dnsupdate_RODC_state *st =
4227 tevent_req_callback_data(subreq,
4228 struct netr_dnsupdate_RODC_state);
4231 status = dcerpc_dnsupdate_RODC_r_recv(subreq, st->dce_call);
4232 TALLOC_FREE(subreq);
4233 if (!NT_STATUS_IS_OK(status)) {
4234 DEBUG(0,(__location__ ": IRPC callback failed %s\n", nt_errstr(status)));
4235 st->dce_call->fault_code = DCERPC_FAULT_CANT_PERFORM;
4238 st->r->out.dns_names = talloc_steal(st->dce_call, st->r2->out.dns_names);
4240 status = dcesrv_reply(st->dce_call);
4241 if (!NT_STATUS_IS_OK(status)) {
4242 DEBUG(0,(__location__ ": dcesrv_reply() failed - %s\n", nt_errstr(status)));
4247 netr_DsrUpdateReadOnlyServerDnsRecords
4249 static NTSTATUS dcesrv_netr_DsrUpdateReadOnlyServerDnsRecords(struct dcesrv_call_state *dce_call,
4250 TALLOC_CTX *mem_ctx,
4251 struct netr_DsrUpdateReadOnlyServerDnsRecords *r)
4253 struct netlogon_creds_CredentialState *creds;
4255 struct dcerpc_binding_handle *binding_handle;
4256 struct netr_dnsupdate_RODC_state *st;
4257 struct tevent_req *subreq;
4259 nt_status = dcesrv_netr_creds_server_step_check(dce_call,
4261 r->in.computer_name,
4263 r->out.return_authenticator,
4265 NT_STATUS_NOT_OK_RETURN(nt_status);
4267 if (creds->secure_channel_type != SEC_CHAN_RODC) {
4268 return NT_STATUS_ACCESS_DENIED;
4271 st = talloc_zero(mem_ctx, struct netr_dnsupdate_RODC_state);
4272 NT_STATUS_HAVE_NO_MEMORY(st);
4274 st->dce_call = dce_call;
4276 st->r2 = talloc_zero(st, struct dnsupdate_RODC);
4277 NT_STATUS_HAVE_NO_MEMORY(st->r2);
4279 st->r2->in.dom_sid = creds->sid;
4280 st->r2->in.site_name = r->in.site_name;
4281 st->r2->in.dns_ttl = r->in.dns_ttl;
4282 st->r2->in.dns_names = r->in.dns_names;
4283 st->r2->out.dns_names = r->out.dns_names;
4285 binding_handle = irpc_binding_handle_by_name(st, dce_call->msg_ctx,
4286 "dnsupdate", &ndr_table_irpc);
4287 if (binding_handle == NULL) {
4288 DEBUG(0,("Failed to get binding_handle for dnsupdate task\n"));
4289 dce_call->fault_code = DCERPC_FAULT_CANT_PERFORM;
4290 return NT_STATUS_INTERNAL_DB_CORRUPTION;
4293 /* forward the call */
4294 subreq = dcerpc_dnsupdate_RODC_r_send(st, dce_call->event_ctx,
4295 binding_handle, st->r2);
4296 NT_STATUS_HAVE_NO_MEMORY(subreq);
4298 dce_call->state_flags |= DCESRV_CALL_STATE_FLAG_ASYNC;
4300 /* setup the callback */
4301 tevent_req_set_callback(subreq, netr_dnsupdate_RODC_callback, st);
4303 return NT_STATUS_OK;
4307 /* include the generated boilerplate */
4308 #include "librpc/gen_ndr/ndr_netlogon_s.c"