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
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 "rpc_server/common/common.h"
27 #include "lib/ldb/include/ldb.h"
28 #include "auth/auth.h"
29 #include "auth/auth_sam_reply.h"
30 #include "dsdb/samdb/samdb.h"
31 #include "../libds/common/flags.h"
32 #include "rpc_server/samr/proto.h"
33 #include "../lib/util/util_ldb.h"
34 #include "libcli/auth/libcli_auth.h"
35 #include "auth/gensec/schannel.h"
36 #include "libcli/security/security.h"
37 #include "param/param.h"
38 #include "lib/messaging/irpc.h"
39 #include "librpc/gen_ndr/ndr_irpc.h"
40 #include "librpc/gen_ndr/ndr_netlogon.h"
42 struct netlogon_server_pipe_state {
43 struct netr_Credential client_challenge;
44 struct netr_Credential server_challenge;
48 static NTSTATUS dcesrv_netr_ServerReqChallenge(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
49 struct netr_ServerReqChallenge *r)
51 struct netlogon_server_pipe_state *pipe_state =
52 talloc_get_type(dce_call->context->private_data, struct netlogon_server_pipe_state);
54 ZERO_STRUCTP(r->out.return_credentials);
56 /* destroyed on pipe shutdown */
59 talloc_free(pipe_state);
60 dce_call->context->private_data = NULL;
63 pipe_state = talloc(dce_call->context, struct netlogon_server_pipe_state);
64 NT_STATUS_HAVE_NO_MEMORY(pipe_state);
66 pipe_state->client_challenge = *r->in.credentials;
68 generate_random_buffer(pipe_state->server_challenge.data,
69 sizeof(pipe_state->server_challenge.data));
71 *r->out.return_credentials = pipe_state->server_challenge;
73 dce_call->context->private_data = pipe_state;
78 static NTSTATUS dcesrv_netr_ServerAuthenticate3(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
79 struct netr_ServerAuthenticate3 *r)
81 struct netlogon_server_pipe_state *pipe_state =
82 talloc_get_type(dce_call->context->private_data, struct netlogon_server_pipe_state);
83 struct netlogon_creds_CredentialState *creds;
84 struct ldb_context *schannel_ldb;
85 struct ldb_context *sam_ctx;
86 struct samr_Password *mach_pwd;
87 uint32_t user_account_control;
89 struct ldb_message **msgs;
91 const char *attrs[] = {"unicodePwd", "userAccountControl",
94 const char *trust_dom_attrs[] = {"flatname", NULL};
95 const char *account_name;
97 ZERO_STRUCTP(r->out.return_credentials);
101 * According to Microsoft (see bugid #6099)
102 * Windows 7 looks at the negotiate_flags
103 * returned in this structure *even if the
104 * call fails with access denied!
106 *r->out.negotiate_flags = NETLOGON_NEG_ACCOUNT_LOCKOUT |
107 NETLOGON_NEG_PERSISTENT_SAMREPL |
108 NETLOGON_NEG_ARCFOUR |
109 NETLOGON_NEG_PROMOTION_COUNT |
110 NETLOGON_NEG_CHANGELOG_BDC |
111 NETLOGON_NEG_FULL_SYNC_REPL |
112 NETLOGON_NEG_MULTIPLE_SIDS |
114 NETLOGON_NEG_PASSWORD_CHANGE_REFUSAL |
115 NETLOGON_NEG_SEND_PASSWORD_INFO_PDC |
116 NETLOGON_NEG_GENERIC_PASSTHROUGH |
117 NETLOGON_NEG_CONCURRENT_RPC |
118 NETLOGON_NEG_AVOID_ACCOUNT_DB_REPL |
119 NETLOGON_NEG_AVOID_SECURITYAUTH_DB_REPL |
120 NETLOGON_NEG_STRONG_KEYS |
121 NETLOGON_NEG_TRANSITIVE_TRUSTS |
122 NETLOGON_NEG_DNS_DOMAIN_TRUSTS |
123 NETLOGON_NEG_PASSWORD_SET2 |
124 NETLOGON_NEG_GETDOMAININFO |
125 NETLOGON_NEG_CROSS_FOREST_TRUSTS |
126 NETLOGON_NEG_NEUTRALIZE_NT4_EMULATION |
127 NETLOGON_NEG_RODC_PASSTHROUGH |
128 NETLOGON_NEG_AUTHENTICATED_RPC_LSASS |
129 NETLOGON_NEG_AUTHENTICATED_RPC;
132 DEBUG(1, ("No challenge requested by client, cannot authenticate\n"));
133 return NT_STATUS_ACCESS_DENIED;
136 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx,
137 system_session(mem_ctx, dce_call->conn->dce_ctx->lp_ctx));
138 if (sam_ctx == NULL) {
139 return NT_STATUS_INVALID_SYSTEM_SERVICE;
142 if (r->in.secure_channel_type == SEC_CHAN_DNS_DOMAIN) {
143 char *encoded_account = ldb_binary_encode_string(mem_ctx, r->in.account_name);
144 const char *flatname;
145 if (!encoded_account) {
146 return NT_STATUS_NO_MEMORY;
149 /* Kill the trailing dot */
150 if (encoded_account[strlen(encoded_account)-1] == '.') {
151 encoded_account[strlen(encoded_account)-1] = '\0';
154 /* pull the user attributes */
155 num_records = gendb_search(sam_ctx, mem_ctx, NULL, &msgs,
157 "(&(trustPartner=%s)(objectclass=trustedDomain))",
160 if (num_records == 0) {
161 DEBUG(3,("Couldn't find trust [%s] in samdb.\n",
163 return NT_STATUS_ACCESS_DENIED;
166 if (num_records > 1) {
167 DEBUG(0,("Found %d records matching user [%s]\n", num_records, r->in.account_name));
168 return NT_STATUS_INTERNAL_DB_CORRUPTION;
171 flatname = ldb_msg_find_attr_as_string(msgs[0], "flatname", NULL);
173 /* No flatname for this trust - we can't proceed */
174 return NT_STATUS_ACCESS_DENIED;
176 account_name = talloc_asprintf(mem_ctx, "%s$", flatname);
179 return NT_STATUS_NO_MEMORY;
183 account_name = r->in.account_name;
186 /* pull the user attributes */
187 num_records = gendb_search(sam_ctx, mem_ctx, NULL, &msgs, attrs,
188 "(&(sAMAccountName=%s)(objectclass=user))",
189 ldb_binary_encode_string(mem_ctx, account_name));
191 if (num_records == 0) {
192 DEBUG(3,("Couldn't find user [%s] in samdb.\n",
193 r->in.account_name));
194 return NT_STATUS_ACCESS_DENIED;
197 if (num_records > 1) {
198 DEBUG(0,("Found %d records matching user [%s]\n", num_records, r->in.account_name));
199 return NT_STATUS_INTERNAL_DB_CORRUPTION;
203 user_account_control = ldb_msg_find_attr_as_uint(msgs[0], "userAccountControl", 0);
205 if (user_account_control & UF_ACCOUNTDISABLE) {
206 DEBUG(1, ("Account [%s] is disabled\n", r->in.account_name));
207 return NT_STATUS_ACCESS_DENIED;
210 if (r->in.secure_channel_type == SEC_CHAN_WKSTA) {
211 if (!(user_account_control & UF_WORKSTATION_TRUST_ACCOUNT)) {
212 DEBUG(1, ("Client asked for a workstation secure channel, but is not a workstation (member server) acb flags: 0x%x\n", user_account_control));
213 return NT_STATUS_ACCESS_DENIED;
215 } else if (r->in.secure_channel_type == SEC_CHAN_DOMAIN ||
216 r->in.secure_channel_type == SEC_CHAN_DNS_DOMAIN) {
217 if (!(user_account_control & UF_INTERDOMAIN_TRUST_ACCOUNT)) {
218 DEBUG(1, ("Client asked for a trusted domain secure channel, but is not a trusted domain: acb flags: 0x%x\n", user_account_control));
220 return NT_STATUS_ACCESS_DENIED;
222 } else if (r->in.secure_channel_type == SEC_CHAN_BDC) {
223 if (!(user_account_control & UF_SERVER_TRUST_ACCOUNT)) {
224 DEBUG(1, ("Client asked for a server secure channel, but is not a server (domain controller): acb flags: 0x%x\n", user_account_control));
225 return NT_STATUS_ACCESS_DENIED;
228 DEBUG(1, ("Client asked for an invalid secure channel type: %d\n",
229 r->in.secure_channel_type));
230 return NT_STATUS_ACCESS_DENIED;
233 *r->out.rid = samdb_result_rid_from_sid(mem_ctx, msgs[0],
236 mach_pwd = samdb_result_hash(mem_ctx, msgs[0], "unicodePwd");
237 if (mach_pwd == NULL) {
238 return NT_STATUS_ACCESS_DENIED;
241 creds = netlogon_creds_server_init(mem_ctx,
244 r->in.secure_channel_type,
245 &pipe_state->client_challenge,
246 &pipe_state->server_challenge,
249 r->out.return_credentials,
250 *r->in.negotiate_flags);
253 return NT_STATUS_ACCESS_DENIED;
256 creds->sid = samdb_result_dom_sid(creds, msgs[0], "objectSid");
258 schannel_ldb = schannel_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx);
260 return NT_STATUS_ACCESS_DENIED;
263 nt_status = schannel_store_session_key_ldb(schannel_ldb, mem_ctx, creds);
264 talloc_free(schannel_ldb);
269 static NTSTATUS dcesrv_netr_ServerAuthenticate(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
270 struct netr_ServerAuthenticate *r)
272 struct netr_ServerAuthenticate3 a;
275 * negotiate_flags is used as an [in] parameter
276 * so it need to be initialised.
278 * (I think ... = 0; seems wrong here --metze)
280 uint32_t negotiate_flags_in = 0;
281 uint32_t negotiate_flags_out = 0;
283 a.in.server_name = r->in.server_name;
284 a.in.account_name = r->in.account_name;
285 a.in.secure_channel_type = r->in.secure_channel_type;
286 a.in.computer_name = r->in.computer_name;
287 a.in.credentials = r->in.credentials;
288 a.in.negotiate_flags = &negotiate_flags_in;
290 a.out.return_credentials = r->out.return_credentials;
292 a.out.negotiate_flags = &negotiate_flags_out;
294 return dcesrv_netr_ServerAuthenticate3(dce_call, mem_ctx, &a);
297 static NTSTATUS dcesrv_netr_ServerAuthenticate2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
298 struct netr_ServerAuthenticate2 *r)
300 struct netr_ServerAuthenticate3 r3;
303 r3.in.server_name = r->in.server_name;
304 r3.in.account_name = r->in.account_name;
305 r3.in.secure_channel_type = r->in.secure_channel_type;
306 r3.in.computer_name = r->in.computer_name;
307 r3.in.credentials = r->in.credentials;
308 r3.out.return_credentials = r->out.return_credentials;
309 r3.in.negotiate_flags = r->in.negotiate_flags;
310 r3.out.negotiate_flags = r->out.negotiate_flags;
313 return dcesrv_netr_ServerAuthenticate3(dce_call, mem_ctx, &r3);
317 Validate an incoming authenticator against the credentials for the remote machine.
319 The credentials are (re)read and from the schannel database, and
320 written back after the caclulations are performed.
322 The creds_out parameter (if not NULL) returns the credentials, if
323 the caller needs some of that information.
326 static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dce_call,
328 const char *computer_name,
329 struct netr_Authenticator *received_authenticator,
330 struct netr_Authenticator *return_authenticator,
331 struct netlogon_creds_CredentialState **creds_out)
334 struct ldb_context *ldb;
335 bool schannel_global_required = false; /* Should be lp_schannel_server() == true */
336 bool schannel_in_use = dce_call->conn->auth_state.auth_info
337 && dce_call->conn->auth_state.auth_info->auth_type == DCERPC_AUTH_TYPE_SCHANNEL
338 && (dce_call->conn->auth_state.auth_info->auth_level == DCERPC_AUTH_LEVEL_INTEGRITY
339 || dce_call->conn->auth_state.auth_info->auth_level == DCERPC_AUTH_LEVEL_PRIVACY);
341 ldb = schannel_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx);
343 return NT_STATUS_ACCESS_DENIED;
345 nt_status = schannel_creds_server_step_check_ldb(ldb, mem_ctx,
347 schannel_global_required,
349 received_authenticator,
350 return_authenticator, creds_out);
356 Change the machine account password for the currently connected
357 client. Supplies only the NT#.
360 static NTSTATUS dcesrv_netr_ServerPasswordSet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
361 struct netr_ServerPasswordSet *r)
363 struct netlogon_creds_CredentialState *creds;
364 struct ldb_context *sam_ctx;
367 nt_status = dcesrv_netr_creds_server_step_check(dce_call,
370 r->in.credential, r->out.return_authenticator,
372 NT_STATUS_NOT_OK_RETURN(nt_status);
374 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(mem_ctx, dce_call->conn->dce_ctx->lp_ctx));
375 if (sam_ctx == NULL) {
376 return NT_STATUS_INVALID_SYSTEM_SERVICE;
379 netlogon_creds_des_decrypt(creds, r->in.new_password);
381 /* Using the sid for the account as the key, set the password */
382 nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
384 NULL, /* Don't have plaintext */
385 NULL, r->in.new_password,
386 true, /* Password change */
392 Change the machine account password for the currently connected
393 client. Supplies new plaintext.
395 static NTSTATUS dcesrv_netr_ServerPasswordSet2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
396 struct netr_ServerPasswordSet2 *r)
398 struct netlogon_creds_CredentialState *creds;
399 struct ldb_context *sam_ctx;
401 DATA_BLOB new_password;
403 struct samr_CryptPassword password_buf;
405 nt_status = dcesrv_netr_creds_server_step_check(dce_call,
408 r->in.credential, r->out.return_authenticator,
410 NT_STATUS_NOT_OK_RETURN(nt_status);
412 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(mem_ctx, dce_call->conn->dce_ctx->lp_ctx));
413 if (sam_ctx == NULL) {
414 return NT_STATUS_INVALID_SYSTEM_SERVICE;
417 memcpy(password_buf.data, r->in.new_password->data, 512);
418 SIVAL(password_buf.data, 512, r->in.new_password->length);
419 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
421 if (!extract_pw_from_buffer(mem_ctx, password_buf.data, &new_password)) {
422 DEBUG(3,("samr: failed to decode password buffer\n"));
423 return NT_STATUS_WRONG_PASSWORD;
426 /* Using the sid for the account as the key, set the password */
427 nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
429 &new_password, /* we have plaintext */
431 true, /* Password change */
440 static WERROR dcesrv_netr_LogonUasLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
441 struct netr_LogonUasLogon *r)
443 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
450 static WERROR dcesrv_netr_LogonUasLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
451 struct netr_LogonUasLogoff *r)
453 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
458 netr_LogonSamLogon_base
460 This version of the function allows other wrappers to say 'do not check the credentials'
462 We can't do the traditional 'wrapping' format completly, as this function must only run under schannel
464 static NTSTATUS dcesrv_netr_LogonSamLogon_base(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
465 struct netr_LogonSamLogonEx *r, struct netlogon_creds_CredentialState *creds)
467 struct auth_context *auth_context;
468 struct auth_usersupplied_info *user_info;
469 struct auth_serversupplied_info *server_info;
471 static const char zeros[16];
472 struct netr_SamBaseInfo *sam;
473 struct netr_SamInfo2 *sam2;
474 struct netr_SamInfo3 *sam3;
475 struct netr_SamInfo6 *sam6;
477 user_info = talloc(mem_ctx, struct auth_usersupplied_info);
478 NT_STATUS_HAVE_NO_MEMORY(user_info);
480 user_info->flags = 0;
481 user_info->mapped_state = false;
482 user_info->remote_host = NULL;
484 switch (r->in.logon_level) {
485 case NetlogonInteractiveInformation:
486 case NetlogonServiceInformation:
487 case NetlogonInteractiveTransitiveInformation:
488 case NetlogonServiceTransitiveInformation:
489 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
490 netlogon_creds_arcfour_crypt(creds,
491 r->in.logon->password->lmpassword.hash,
492 sizeof(r->in.logon->password->lmpassword.hash));
493 netlogon_creds_arcfour_crypt(creds,
494 r->in.logon->password->ntpassword.hash,
495 sizeof(r->in.logon->password->ntpassword.hash));
497 netlogon_creds_des_decrypt(creds, &r->in.logon->password->lmpassword);
498 netlogon_creds_des_decrypt(creds, &r->in.logon->password->ntpassword);
501 /* TODO: we need to deny anonymous access here */
502 nt_status = auth_context_create(mem_ctx,
503 dce_call->event_ctx, dce_call->msg_ctx,
504 dce_call->conn->dce_ctx->lp_ctx,
506 NT_STATUS_NOT_OK_RETURN(nt_status);
508 user_info->logon_parameters = r->in.logon->password->identity_info.parameter_control;
509 user_info->client.account_name = r->in.logon->password->identity_info.account_name.string;
510 user_info->client.domain_name = r->in.logon->password->identity_info.domain_name.string;
511 user_info->workstation_name = r->in.logon->password->identity_info.workstation.string;
513 user_info->flags |= USER_INFO_INTERACTIVE_LOGON;
514 user_info->password_state = AUTH_PASSWORD_HASH;
516 user_info->password.hash.lanman = talloc(user_info, struct samr_Password);
517 NT_STATUS_HAVE_NO_MEMORY(user_info->password.hash.lanman);
518 *user_info->password.hash.lanman = r->in.logon->password->lmpassword;
520 user_info->password.hash.nt = talloc(user_info, struct samr_Password);
521 NT_STATUS_HAVE_NO_MEMORY(user_info->password.hash.nt);
522 *user_info->password.hash.nt = r->in.logon->password->ntpassword;
525 case NetlogonNetworkInformation:
526 case NetlogonNetworkTransitiveInformation:
528 /* TODO: we need to deny anonymous access here */
529 nt_status = auth_context_create(mem_ctx,
530 dce_call->event_ctx, dce_call->msg_ctx,
531 dce_call->conn->dce_ctx->lp_ctx,
533 NT_STATUS_NOT_OK_RETURN(nt_status);
535 nt_status = auth_context_set_challenge(auth_context, r->in.logon->network->challenge, "netr_LogonSamLogonWithFlags");
536 NT_STATUS_NOT_OK_RETURN(nt_status);
538 user_info->logon_parameters = r->in.logon->network->identity_info.parameter_control;
539 user_info->client.account_name = r->in.logon->network->identity_info.account_name.string;
540 user_info->client.domain_name = r->in.logon->network->identity_info.domain_name.string;
541 user_info->workstation_name = r->in.logon->network->identity_info.workstation.string;
543 user_info->password_state = AUTH_PASSWORD_RESPONSE;
544 user_info->password.response.lanman = data_blob_talloc(mem_ctx, r->in.logon->network->lm.data, r->in.logon->network->lm.length);
545 user_info->password.response.nt = data_blob_talloc(mem_ctx, r->in.logon->network->nt.data, r->in.logon->network->nt.length);
550 case NetlogonGenericInformation:
552 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
553 netlogon_creds_arcfour_crypt(creds,
554 r->in.logon->generic->data, r->in.logon->generic->length);
556 /* Using DES to verify kerberos tickets makes no sense */
557 return NT_STATUS_INVALID_PARAMETER;
560 if (strcmp(r->in.logon->generic->package_name.string, "Kerberos") == 0) {
562 struct server_id *kdc;
563 struct kdc_check_generic_kerberos check;
564 struct netr_GenericInfo2 *generic = talloc_zero(mem_ctx, struct netr_GenericInfo2);
565 NT_STATUS_HAVE_NO_MEMORY(generic);
566 *r->out.authoritative = 1;
568 /* TODO: Describe and deal with these flags */
571 r->out.validation->generic = generic;
573 kdc = irpc_servers_byname(dce_call->msg_ctx, mem_ctx, "kdc_server");
574 if ((kdc == NULL) || (kdc[0].id == 0)) {
575 return NT_STATUS_NO_LOGON_SERVERS;
578 check.in.generic_request =
579 data_blob_const(r->in.logon->generic->data,
580 r->in.logon->generic->length);
582 status = irpc_call(dce_call->msg_ctx, kdc[0],
583 &ndr_table_irpc, NDR_KDC_CHECK_GENERIC_KERBEROS,
585 if (!NT_STATUS_IS_OK(status)) {
588 generic->length = check.out.generic_reply.length;
589 generic->data = check.out.generic_reply.data;
593 /* Until we get an implemetnation of these other packages */
594 return NT_STATUS_INVALID_PARAMETER;
597 return NT_STATUS_INVALID_PARAMETER;
600 nt_status = auth_check_password(auth_context, mem_ctx, user_info, &server_info);
601 NT_STATUS_NOT_OK_RETURN(nt_status);
603 nt_status = auth_convert_server_info_sambaseinfo(mem_ctx, server_info, &sam);
604 NT_STATUS_NOT_OK_RETURN(nt_status);
606 /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
607 /* It appears that level 6 is not individually encrypted */
608 if ((r->in.validation_level != 6) &&
609 memcmp(sam->key.key, zeros, sizeof(sam->key.key)) != 0) {
610 /* This key is sent unencrypted without the ARCFOUR flag set */
611 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
612 netlogon_creds_arcfour_crypt(creds,
614 sizeof(sam->key.key));
618 /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
619 /* It appears that level 6 is not individually encrypted */
620 if ((r->in.validation_level != 6) &&
621 memcmp(sam->LMSessKey.key, zeros, sizeof(sam->LMSessKey.key)) != 0) {
622 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
623 netlogon_creds_arcfour_crypt(creds,
625 sizeof(sam->LMSessKey.key));
627 netlogon_creds_des_encrypt_LMKey(creds,
632 switch (r->in.validation_level) {
634 sam2 = talloc_zero(mem_ctx, struct netr_SamInfo2);
635 NT_STATUS_HAVE_NO_MEMORY(sam2);
637 r->out.validation->sam2 = sam2;
641 sam3 = talloc_zero(mem_ctx, struct netr_SamInfo3);
642 NT_STATUS_HAVE_NO_MEMORY(sam3);
644 r->out.validation->sam3 = sam3;
648 sam6 = talloc_zero(mem_ctx, struct netr_SamInfo6);
649 NT_STATUS_HAVE_NO_MEMORY(sam6);
651 sam6->forest.string = lp_realm(dce_call->conn->dce_ctx->lp_ctx);
652 sam6->principle.string = talloc_asprintf(mem_ctx, "%s@%s",
653 sam->account_name.string, sam6->forest.string);
654 NT_STATUS_HAVE_NO_MEMORY(sam6->principle.string);
655 r->out.validation->sam6 = sam6;
662 *r->out.authoritative = 1;
664 /* TODO: Describe and deal with these flags */
670 static NTSTATUS dcesrv_netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
671 struct netr_LogonSamLogonEx *r)
674 struct netlogon_creds_CredentialState *creds;
675 struct ldb_context *ldb = schannel_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx);
677 return NT_STATUS_ACCESS_DENIED;
680 nt_status = schannel_fetch_session_key_ldb(ldb, mem_ctx, r->in.computer_name, &creds);
681 if (!NT_STATUS_IS_OK(nt_status)) {
685 if (!dce_call->conn->auth_state.auth_info ||
686 dce_call->conn->auth_state.auth_info->auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
687 return NT_STATUS_ACCESS_DENIED;
689 return dcesrv_netr_LogonSamLogon_base(dce_call, mem_ctx, r, creds);
693 netr_LogonSamLogonWithFlags
696 static NTSTATUS dcesrv_netr_LogonSamLogonWithFlags(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
697 struct netr_LogonSamLogonWithFlags *r)
700 struct netlogon_creds_CredentialState *creds;
701 struct netr_LogonSamLogonEx r2;
703 struct netr_Authenticator *return_authenticator;
705 return_authenticator = talloc(mem_ctx, struct netr_Authenticator);
706 NT_STATUS_HAVE_NO_MEMORY(return_authenticator);
708 nt_status = dcesrv_netr_creds_server_step_check(dce_call,
711 r->in.credential, return_authenticator,
713 NT_STATUS_NOT_OK_RETURN(nt_status);
717 r2.in.server_name = r->in.server_name;
718 r2.in.computer_name = r->in.computer_name;
719 r2.in.logon_level = r->in.logon_level;
720 r2.in.logon = r->in.logon;
721 r2.in.validation_level = r->in.validation_level;
722 r2.in.flags = r->in.flags;
723 r2.out.validation = r->out.validation;
724 r2.out.authoritative = r->out.authoritative;
725 r2.out.flags = r->out.flags;
727 nt_status = dcesrv_netr_LogonSamLogon_base(dce_call, mem_ctx, &r2, creds);
729 r->out.return_authenticator = return_authenticator;
737 static NTSTATUS dcesrv_netr_LogonSamLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
738 struct netr_LogonSamLogon *r)
740 struct netr_LogonSamLogonWithFlags r2;
746 r2.in.server_name = r->in.server_name;
747 r2.in.computer_name = r->in.computer_name;
748 r2.in.credential = r->in.credential;
749 r2.in.return_authenticator = r->in.return_authenticator;
750 r2.in.logon_level = r->in.logon_level;
751 r2.in.logon = r->in.logon;
752 r2.in.validation_level = r->in.validation_level;
753 r2.in.flags = &flags;
754 r2.out.validation = r->out.validation;
755 r2.out.authoritative = r->out.authoritative;
756 r2.out.flags = &flags;
758 status = dcesrv_netr_LogonSamLogonWithFlags(dce_call, mem_ctx, &r2);
760 r->out.return_authenticator = r2.out.return_authenticator;
769 static NTSTATUS dcesrv_netr_LogonSamLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
770 struct netr_LogonSamLogoff *r)
772 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
780 static NTSTATUS dcesrv_netr_DatabaseDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
781 struct netr_DatabaseDeltas *r)
783 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
790 static NTSTATUS dcesrv_netr_DatabaseSync2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
791 struct netr_DatabaseSync2 *r)
793 /* win2k3 native mode returns "NOT IMPLEMENTED" for this call */
794 return NT_STATUS_NOT_IMPLEMENTED;
801 static NTSTATUS dcesrv_netr_DatabaseSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
802 struct netr_DatabaseSync *r)
804 struct netr_DatabaseSync2 r2;
809 r2.in.logon_server = r->in.logon_server;
810 r2.in.computername = r->in.computername;
811 r2.in.credential = r->in.credential;
812 r2.in.database_id = r->in.database_id;
813 r2.in.restart_state = SYNCSTATE_NORMAL_STATE;
814 r2.in.sync_context = r->in.sync_context;
815 r2.out.sync_context = r->out.sync_context;
816 r2.out.delta_enum_array = r->out.delta_enum_array;
817 r2.in.preferredmaximumlength = r->in.preferredmaximumlength;
819 status = dcesrv_netr_DatabaseSync2(dce_call, mem_ctx, &r2);
828 static NTSTATUS dcesrv_netr_AccountDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
829 struct netr_AccountDeltas *r)
831 /* w2k3 returns "NOT IMPLEMENTED" for this call */
832 return NT_STATUS_NOT_IMPLEMENTED;
839 static NTSTATUS dcesrv_netr_AccountSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
840 struct netr_AccountSync *r)
842 /* w2k3 returns "NOT IMPLEMENTED" for this call */
843 return NT_STATUS_NOT_IMPLEMENTED;
850 static WERROR dcesrv_netr_GetDcName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
851 struct netr_GetDcName *r)
853 const char * const attrs[] = { NULL };
854 struct ldb_context *sam_ctx;
855 struct ldb_message **res;
856 struct ldb_dn *domain_dn;
860 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx,
861 dce_call->conn->dce_ctx->lp_ctx,
862 dce_call->conn->auth_state.session_info);
863 if (sam_ctx == NULL) {
864 return WERR_DS_UNAVAILABLE;
867 domain_dn = samdb_domain_to_dn(sam_ctx, mem_ctx,
869 if (domain_dn == NULL) {
870 return WERR_DS_UNAVAILABLE;
873 ret = gendb_search_dn(sam_ctx, mem_ctx,
874 domain_dn, &res, attrs);
876 return WERR_NO_SUCH_DOMAIN;
879 /* TODO: - return real IP address
880 * - check all r->in.* parameters (server_unc is ignored by w2k3!)
882 dcname = talloc_asprintf(mem_ctx, "\\\\%s",
883 lp_netbios_name(dce_call->conn->dce_ctx->lp_ctx));
884 W_ERROR_HAVE_NO_MEMORY(dcname);
886 *r->out.dcname = dcname;
894 static WERROR dcesrv_netr_LogonControl2Ex(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
895 struct netr_LogonControl2Ex *r)
897 return WERR_NOT_SUPPORTED;
904 static WERROR dcesrv_netr_LogonControl(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
905 struct netr_LogonControl *r)
907 struct netr_LogonControl2Ex r2;
910 if (r->in.level == 0x00000001) {
913 r2.in.logon_server = r->in.logon_server;
914 r2.in.function_code = r->in.function_code;
915 r2.in.level = r->in.level;
917 r2.out.query = r->out.query;
919 werr = dcesrv_netr_LogonControl2Ex(dce_call, mem_ctx, &r2);
920 } else if (r->in.level == 0x00000002) {
921 werr = WERR_NOT_SUPPORTED;
923 werr = WERR_UNKNOWN_LEVEL;
933 static WERROR dcesrv_netr_LogonControl2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
934 struct netr_LogonControl2 *r)
936 struct netr_LogonControl2Ex r2;
941 r2.in.logon_server = r->in.logon_server;
942 r2.in.function_code = r->in.function_code;
943 r2.in.level = r->in.level;
944 r2.in.data = r->in.data;
945 r2.out.query = r->out.query;
947 werr = dcesrv_netr_LogonControl2Ex(dce_call, mem_ctx, &r2);
956 static WERROR dcesrv_netr_GetAnyDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
957 struct netr_GetAnyDCName *r)
959 struct netr_GetDcName r2;
964 r2.in.logon_server = r->in.logon_server;
965 r2.in.domainname = r->in.domainname;
966 r2.out.dcname = r->out.dcname;
968 werr = dcesrv_netr_GetDcName(dce_call, mem_ctx, &r2);
977 static NTSTATUS dcesrv_netr_DatabaseRedo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
978 struct netr_DatabaseRedo *r)
980 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
985 netr_NetrEnumerateTurstedDomains
987 static WERROR dcesrv_netr_NetrEnumerateTrustedDomains(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
988 struct netr_NetrEnumerateTrustedDomains *r)
990 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
995 netr_LogonGetCapabilities
997 static NTSTATUS dcesrv_netr_LogonGetCapabilities(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
998 struct netr_LogonGetCapabilities *r)
1000 /* we don't support AES yet */
1001 return NT_STATUS_NOT_IMPLEMENTED;
1006 netr_NETRLOGONSETSERVICEBITS
1008 static WERROR dcesrv_netr_NETRLOGONSETSERVICEBITS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1009 struct netr_NETRLOGONSETSERVICEBITS *r)
1011 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1016 netr_LogonGetTrustRid
1018 static WERROR dcesrv_netr_LogonGetTrustRid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1019 struct netr_LogonGetTrustRid *r)
1021 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1026 netr_NETRLOGONCOMPUTESERVERDIGEST
1028 static WERROR dcesrv_netr_NETRLOGONCOMPUTESERVERDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1029 struct netr_NETRLOGONCOMPUTESERVERDIGEST *r)
1031 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1036 netr_NETRLOGONCOMPUTECLIENTDIGEST
1038 static WERROR dcesrv_netr_NETRLOGONCOMPUTECLIENTDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1039 struct netr_NETRLOGONCOMPUTECLIENTDIGEST *r)
1041 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1049 static WERROR dcesrv_netr_DsRGetSiteName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1050 struct netr_DsRGetSiteName *r)
1052 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1057 fill in a netr_OneDomainInfo from a ldb search result
1059 static NTSTATUS fill_one_domain_info(TALLOC_CTX *mem_ctx,
1060 struct loadparm_context *lp_ctx,
1061 struct ldb_context *sam_ctx,
1062 struct ldb_message *res,
1063 struct netr_OneDomainInfo *info,
1064 bool is_local, bool is_trust_list)
1068 info->trust_extension.info = talloc_zero(mem_ctx, struct netr_trust_extension);
1069 info->trust_extension.length = 16;
1070 info->trust_extension.info->flags =
1071 NETR_TRUST_FLAG_TREEROOT |
1072 NETR_TRUST_FLAG_IN_FOREST |
1073 NETR_TRUST_FLAG_PRIMARY;
1075 info->trust_extension.info->parent_index = 0; /* should be index into array
1077 info->trust_extension.info->trust_type = LSA_TRUST_TYPE_UPLEVEL; /* should be based on ldb search for trusts */
1078 info->trust_extension.info->trust_attributes = LSA_TRUST_ATTRIBUTE_NON_TRANSITIVE; /* needs to be based on ldb search */
1080 if (is_trust_list) {
1081 /* MS-NRPC 3.5.4.3.9 - must be set to NULL for trust list */
1082 info->dns_forestname.string = NULL;
1085 /* TODO: we need a common function for pulling the forest */
1086 info->dns_forestname.string = ldb_dn_canonical_string(info, ldb_get_root_basedn(sam_ctx));
1087 if (!info->dns_forestname.string) {
1088 return NT_STATUS_NO_SUCH_DOMAIN;
1090 p = strchr(info->dns_forestname.string, '/');
1097 info->domainname.string = lp_sam_name(lp_ctx);
1098 info->dns_domainname.string = lp_realm(lp_ctx);
1099 info->domain_guid = samdb_result_guid(res, "objectGUID");
1100 info->domain_sid = samdb_result_dom_sid(mem_ctx, res, "objectSid");
1102 info->domainname.string = samdb_result_string(res, "flatName", NULL);
1103 info->dns_domainname.string = samdb_result_string(res, "trustPartner", NULL);
1104 info->domain_guid = samdb_result_guid(res, "objectGUID");
1105 info->domain_sid = samdb_result_dom_sid(mem_ctx, res, "securityIdentifier");
1108 return NT_STATUS_OK;
1112 netr_LogonGetDomainInfo
1113 this is called as part of the ADS domain logon procedure.
1115 It has an important role in convaying details about the client, such
1116 as Operating System, Version, Service Pack etc.
1118 static NTSTATUS dcesrv_netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_call,
1119 TALLOC_CTX *mem_ctx, struct netr_LogonGetDomainInfo *r)
1121 struct netlogon_creds_CredentialState *creds;
1122 const char * const attrs[] = { "objectSid", "objectGUID", "flatName",
1123 "securityIdentifier", "trustPartner", NULL };
1124 const char *temp_str;
1125 const char *old_dns_hostname;
1126 struct ldb_context *sam_ctx;
1127 struct ldb_message **res1, **res2, *new_msg;
1128 struct ldb_dn *workstation_dn;
1129 struct netr_DomainInformation *domain_info;
1130 struct netr_LsaPolicyInformation *lsa_policy_info;
1131 struct netr_OsVersionInfoEx *os_version;
1133 uint32_t client_supported_enc;
1134 uint32_t default_supported_enc = ENC_CRC32|ENC_RSA_MD5|ENC_RC4_HMAC_MD5;
1137 status = dcesrv_netr_creds_server_step_check(dce_call,
1139 r->in.computer_name,
1141 r->out.return_authenticator,
1143 if (!NT_STATUS_IS_OK(status)) {
1144 DEBUG(0,(__location__ " Bad credentials - error\n"));
1146 NT_STATUS_NOT_OK_RETURN(status);
1148 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx,
1149 dce_call->conn->dce_ctx->lp_ctx,
1150 system_session(mem_ctx, dce_call->conn->dce_ctx->lp_ctx));
1151 if (sam_ctx == NULL) {
1152 return NT_STATUS_INVALID_SYSTEM_SERVICE;
1155 switch (r->in.level) {
1156 case 1: /* Domain information */
1158 /* TODO: check NTSTATUS results - and fail also on SAMDB
1159 * errors (needs some testing against Windows Server 2008) */
1162 * Check that the computer name parameter matches as prefix with
1163 * the DNS hostname in the workstation info structure.
1165 temp_str = strndup(r->in.query->workstation_info->dns_hostname,
1166 strcspn(r->in.query->workstation_info->dns_hostname,
1168 if (strcasecmp(r->in.computer_name, temp_str) != 0)
1169 return NT_STATUS_INVALID_PARAMETER;
1171 workstation_dn = ldb_dn_new_fmt(mem_ctx, sam_ctx, "<SID=%s>",
1172 dom_sid_string(mem_ctx, creds->sid));
1173 NT_STATUS_HAVE_NO_MEMORY(workstation_dn);
1175 /* Gets the old DNS hostname */
1176 old_dns_hostname = samdb_search_string(sam_ctx, mem_ctx,
1181 client_supported_enc = samdb_search_int64(sam_ctx, mem_ctx, default_supported_enc,
1182 workstation_dn, "msDS-SupportedEncryptionTypes",
1184 /* Gets host informations and put them in our directory */
1185 new_msg = ldb_msg_new(mem_ctx);
1186 NT_STATUS_HAVE_NO_MEMORY(new_msg);
1188 new_msg->dn = workstation_dn;
1190 /* Deletes old OS version values */
1191 samdb_msg_add_delete(sam_ctx, mem_ctx, new_msg,
1192 "operatingSystemServicePack");
1193 samdb_msg_add_delete(sam_ctx, mem_ctx, new_msg,
1194 "operatingSystemVersion");
1196 if (samdb_replace(sam_ctx, mem_ctx, new_msg) != LDB_SUCCESS) {
1197 DEBUG(3,("Impossible to update samdb: %s\n",
1198 ldb_errstring(sam_ctx)));
1201 talloc_free(new_msg);
1203 new_msg = ldb_msg_new(mem_ctx);
1204 NT_STATUS_HAVE_NO_MEMORY(new_msg);
1206 new_msg->dn = workstation_dn;
1208 /* Sets the OS name */
1209 samdb_msg_set_string(sam_ctx, mem_ctx, new_msg,
1211 r->in.query->workstation_info->os_name.string);
1214 * Sets informations from "os_version". On a empty structure
1215 * the values are cleared.
1217 if (r->in.query->workstation_info->os_version.os != NULL) {
1218 os_version = &r->in.query->workstation_info->os_version.os->os;
1220 samdb_msg_set_string(sam_ctx, mem_ctx, new_msg,
1221 "operatingSystemServicePack",
1222 os_version->CSDVersion);
1224 samdb_msg_set_string(sam_ctx, mem_ctx, new_msg,
1225 "operatingSystemVersion",
1226 talloc_asprintf(mem_ctx, "%d.%d (%d)",
1227 os_version->MajorVersion,
1228 os_version->MinorVersion,
1229 os_version->BuildNumber
1235 * Updates the "dNSHostname" and the "servicePrincipalName"s
1236 * since the client wishes that the server should handle this
1237 * for him ("NETR_WS_FLAG_HANDLES_SPN_UPDATE" not set).
1238 * See MS-NRPC section 3.5.4.3.9
1240 if ((r->in.query->workstation_info->workstation_flags
1241 & NETR_WS_FLAG_HANDLES_SPN_UPDATE) == 0) {
1243 samdb_msg_add_string(sam_ctx, mem_ctx, new_msg,
1245 r->in.query->workstation_info->dns_hostname);
1246 samdb_msg_add_string(sam_ctx, mem_ctx, new_msg,
1247 "servicePrincipalName",
1248 talloc_asprintf(mem_ctx, "HOST/%s",
1249 r->in.computer_name)
1251 samdb_msg_add_string(sam_ctx, mem_ctx, new_msg,
1252 "servicePrincipalName",
1253 talloc_asprintf(mem_ctx, "HOST/%s",
1254 r->in.query->workstation_info->dns_hostname)
1258 if (samdb_replace(sam_ctx, mem_ctx, new_msg) != LDB_SUCCESS) {
1259 DEBUG(3,("Impossible to update samdb: %s\n",
1260 ldb_errstring(sam_ctx)));
1263 talloc_free(new_msg);
1265 /* Writes back the domain information */
1267 /* We need to do two searches. The first will pull our primary
1268 domain and the second will pull any trusted domains. Our
1269 primary domain is also a "trusted" domain, so we need to
1270 put the primary domain into the lists of returned trusts as
1272 ret1 = gendb_search_dn(sam_ctx, mem_ctx, samdb_base_dn(sam_ctx),
1275 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1278 ret2 = gendb_search(sam_ctx, mem_ctx, NULL, &res2, attrs,
1279 "(objectClass=trustedDomain)");
1281 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1284 domain_info = talloc(mem_ctx, struct netr_DomainInformation);
1285 NT_STATUS_HAVE_NO_MEMORY(domain_info);
1287 ZERO_STRUCTP(domain_info);
1289 /* Informations about the local and trusted domains */
1291 status = fill_one_domain_info(mem_ctx,
1292 dce_call->conn->dce_ctx->lp_ctx,
1293 sam_ctx, res1[0], &domain_info->primary_domain,
1295 NT_STATUS_NOT_OK_RETURN(status);
1297 domain_info->trusted_domain_count = ret2 + 1;
1298 domain_info->trusted_domains = talloc_array(mem_ctx,
1299 struct netr_OneDomainInfo,
1300 domain_info->trusted_domain_count);
1301 NT_STATUS_HAVE_NO_MEMORY(domain_info->trusted_domains);
1303 for (i=0;i<ret2;i++) {
1304 status = fill_one_domain_info(mem_ctx,
1305 dce_call->conn->dce_ctx->lp_ctx,
1307 &domain_info->trusted_domains[i],
1309 NT_STATUS_NOT_OK_RETURN(status);
1312 status = fill_one_domain_info(mem_ctx,
1313 dce_call->conn->dce_ctx->lp_ctx, sam_ctx, res1[0],
1314 &domain_info->trusted_domains[i], true, true);
1315 NT_STATUS_NOT_OK_RETURN(status);
1317 /* Other host domain informations */
1319 lsa_policy_info = talloc(mem_ctx,
1320 struct netr_LsaPolicyInformation);
1321 NT_STATUS_HAVE_NO_MEMORY(lsa_policy_info);
1322 ZERO_STRUCTP(lsa_policy_info);
1324 domain_info->lsa_policy = *lsa_policy_info;
1326 domain_info->dns_hostname.string = old_dns_hostname;
1327 domain_info->workstation_flags =
1328 r->in.query->workstation_info->workstation_flags;
1329 domain_info->supported_enc_types = client_supported_enc;
1331 r->out.info->domain_info = domain_info;
1333 case 2: /* LSA policy information - not used at the moment */
1334 lsa_policy_info = talloc(mem_ctx,
1335 struct netr_LsaPolicyInformation);
1336 NT_STATUS_HAVE_NO_MEMORY(lsa_policy_info);
1337 ZERO_STRUCTP(lsa_policy_info);
1339 r->out.info->lsa_policy_info = lsa_policy_info;
1342 return NT_STATUS_INVALID_LEVEL;
1346 return NT_STATUS_OK;
1352 netr_ServerPasswordGet
1354 static WERROR dcesrv_netr_ServerPasswordGet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1355 struct netr_ServerPasswordGet *r)
1357 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1362 netr_NETRLOGONSENDTOSAM
1364 static WERROR dcesrv_netr_NETRLOGONSENDTOSAM(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1365 struct netr_NETRLOGONSENDTOSAM *r)
1367 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1372 netr_DsRAddressToSitenamesW
1374 static WERROR dcesrv_netr_DsRAddressToSitenamesW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1375 struct netr_DsRAddressToSitenamesW *r)
1377 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1382 netr_DsRGetDCNameEx2
1384 static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1385 struct netr_DsRGetDCNameEx2 *r)
1387 const char * const attrs[] = { "objectGUID", NULL };
1388 struct ldb_context *sam_ctx;
1389 struct ldb_message **res;
1390 struct ldb_dn *domain_dn;
1392 struct netr_DsRGetDCNameInfo *info;
1394 ZERO_STRUCTP(r->out.info);
1396 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
1397 if (sam_ctx == NULL) {
1398 return WERR_DS_UNAVAILABLE;
1401 /* Win7-beta will send the domain name in the form the user typed, so we have to cope
1402 with both the short and long form here */
1403 if (r->in.domain_name != NULL && !lp_is_my_domain_or_realm(dce_call->conn->dce_ctx->lp_ctx,
1404 r->in.domain_name)) {
1405 return WERR_NO_SUCH_DOMAIN;
1408 domain_dn = ldb_get_default_basedn(sam_ctx);
1409 if (domain_dn == NULL) {
1410 return WERR_DS_UNAVAILABLE;
1413 ret = gendb_search_dn(sam_ctx, mem_ctx,
1414 domain_dn, &res, attrs);
1418 info = talloc(mem_ctx, struct netr_DsRGetDCNameInfo);
1419 W_ERROR_HAVE_NO_MEMORY(info);
1421 /* TODO: - return real IP address
1422 * - check all r->in.* parameters (server_unc is ignored by w2k3!)
1424 info->dc_unc = talloc_asprintf(mem_ctx, "\\\\%s.%s",
1425 lp_netbios_name(dce_call->conn->dce_ctx->lp_ctx),
1426 lp_realm(dce_call->conn->dce_ctx->lp_ctx));
1427 W_ERROR_HAVE_NO_MEMORY(info->dc_unc);
1428 info->dc_address = talloc_strdup(mem_ctx, "\\\\0.0.0.0");
1429 W_ERROR_HAVE_NO_MEMORY(info->dc_address);
1430 info->dc_address_type = DS_ADDRESS_TYPE_INET;
1431 info->domain_guid = samdb_result_guid(res[0], "objectGUID");
1432 info->domain_name = lp_realm(dce_call->conn->dce_ctx->lp_ctx);
1433 info->forest_name = lp_realm(dce_call->conn->dce_ctx->lp_ctx);
1434 info->dc_flags = DS_DNS_FOREST |
1437 DS_SERVER_WRITABLE |
1439 DS_SERVER_TIMESERV |
1445 info->dc_site_name = talloc_strdup(mem_ctx, "Default-First-Site-Name");
1446 W_ERROR_HAVE_NO_MEMORY(info->dc_site_name);
1447 info->client_site_name = talloc_strdup(mem_ctx, "Default-First-Site-Name");
1448 W_ERROR_HAVE_NO_MEMORY(info->client_site_name);
1450 *r->out.info = info;
1458 static WERROR dcesrv_netr_DsRGetDCNameEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1459 struct netr_DsRGetDCNameEx *r)
1461 struct netr_DsRGetDCNameEx2 r2;
1466 r2.in.server_unc = r->in.server_unc;
1467 r2.in.client_account = NULL;
1469 r2.in.domain_guid = r->in.domain_guid;
1470 r2.in.domain_name = r->in.domain_name;
1471 r2.in.site_name = r->in.site_name;
1472 r2.in.flags = r->in.flags;
1473 r2.out.info = r->out.info;
1475 werr = dcesrv_netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1483 static WERROR dcesrv_netr_DsRGetDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1484 struct netr_DsRGetDCName *r)
1486 struct netr_DsRGetDCNameEx2 r2;
1491 r2.in.server_unc = r->in.server_unc;
1492 r2.in.client_account = NULL;
1494 r2.in.domain_name = r->in.domain_name;
1495 r2.in.domain_guid = r->in.domain_guid;
1497 r2.in.site_name = NULL; /* should fill in from site GUID */
1498 r2.in.flags = r->in.flags;
1499 r2.out.info = r->out.info;
1501 werr = dcesrv_netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1506 netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN
1508 static WERROR dcesrv_netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1509 struct netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN *r)
1511 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1516 netr_NetrEnumerateTrustedDomainsEx
1518 static WERROR dcesrv_netr_NetrEnumerateTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1519 struct netr_NetrEnumerateTrustedDomainsEx *r)
1521 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1526 netr_DsRAddressToSitenamesExW
1528 static WERROR dcesrv_netr_DsRAddressToSitenamesExW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1529 struct netr_DsRAddressToSitenamesExW *r)
1531 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1536 netr_DsrGetDcSiteCoverageW
1538 static WERROR dcesrv_netr_DsrGetDcSiteCoverageW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1539 struct netr_DsrGetDcSiteCoverageW *r)
1541 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1546 netr_DsrEnumerateDomainTrusts
1548 static WERROR dcesrv_netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1549 struct netr_DsrEnumerateDomainTrusts *r)
1551 struct netr_DomainTrustList *trusts;
1552 struct ldb_context *sam_ctx;
1554 struct ldb_message **dom_res;
1555 const char * const dom_attrs[] = { "objectSid", "objectGUID", NULL };
1557 ZERO_STRUCT(r->out);
1559 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
1560 if (sam_ctx == NULL) {
1561 return WERR_GENERAL_FAILURE;
1564 ret = gendb_search_dn(sam_ctx, mem_ctx, NULL,
1565 &dom_res, dom_attrs);
1567 return WERR_GENERAL_FAILURE;
1570 return WERR_GENERAL_FAILURE;
1573 trusts = talloc(mem_ctx, struct netr_DomainTrustList);
1574 W_ERROR_HAVE_NO_MEMORY(trusts);
1576 trusts->array = talloc_array(trusts, struct netr_DomainTrust, ret);
1577 W_ERROR_HAVE_NO_MEMORY(trusts->array);
1579 trusts->count = 1; /* ?? */
1581 r->out.trusts = trusts;
1583 /* TODO: add filtering by trust_flags, and correct trust_type
1585 trusts->array[0].netbios_name = lp_sam_name(dce_call->conn->dce_ctx->lp_ctx);
1586 trusts->array[0].dns_name = lp_realm(dce_call->conn->dce_ctx->lp_ctx);
1587 trusts->array[0].trust_flags =
1588 NETR_TRUST_FLAG_TREEROOT |
1589 NETR_TRUST_FLAG_IN_FOREST |
1590 NETR_TRUST_FLAG_PRIMARY;
1591 trusts->array[0].parent_index = 0;
1592 trusts->array[0].trust_type = 2;
1593 trusts->array[0].trust_attributes = 0;
1594 trusts->array[0].sid = samdb_result_dom_sid(mem_ctx, dom_res[0], "objectSid");
1595 trusts->array[0].guid = samdb_result_guid(dom_res[0], "objectGUID");
1602 netr_DsrDeregisterDNSHostRecords
1604 static WERROR dcesrv_netr_DsrDeregisterDNSHostRecords(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1605 struct netr_DsrDeregisterDNSHostRecords *r)
1607 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1612 netr_ServerTrustPasswordsGet
1614 static NTSTATUS dcesrv_netr_ServerTrustPasswordsGet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1615 struct netr_ServerTrustPasswordsGet *r)
1617 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1622 netr_DsRGetForestTrustInformation
1624 static WERROR dcesrv_netr_DsRGetForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1625 struct netr_DsRGetForestTrustInformation *r)
1627 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1632 netr_GetForestTrustInformation
1634 static WERROR dcesrv_netr_GetForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1635 struct netr_GetForestTrustInformation *r)
1637 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1642 netr_ServerGetTrustInfo
1644 static NTSTATUS dcesrv_netr_ServerGetTrustInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1645 struct netr_ServerGetTrustInfo *r)
1647 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1651 /* include the generated boilerplate */
1652 #include "librpc/gen_ndr/ndr_netlogon_s.c"