2 Unix SMB/CIFS implementation.
4 endpoint server for the netlogon pipe
6 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2008
7 Copyright (C) Stefan Metzmacher <metze@samba.org> 2005
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "rpc_server/dcerpc_server.h"
25 #include "rpc_server/common/common.h"
26 #include "lib/ldb/include/ldb.h"
27 #include "auth/auth.h"
28 #include "auth/auth_sam_reply.h"
29 #include "dsdb/samdb/samdb.h"
30 #include "../libds/common/flags.h"
31 #include "rpc_server/samr/proto.h"
32 #include "../lib/util/util_ldb.h"
33 #include "libcli/auth/libcli_auth.h"
34 #include "auth/gensec/schannel.h"
35 #include "libcli/security/security.h"
36 #include "param/param.h"
37 #include "lib/messaging/irpc.h"
38 #include "librpc/gen_ndr/ndr_irpc.h"
39 #include "librpc/gen_ndr/ndr_netlogon.h"
41 struct netlogon_server_pipe_state {
42 struct netr_Credential client_challenge;
43 struct netr_Credential server_challenge;
47 static NTSTATUS dcesrv_netr_ServerReqChallenge(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
48 struct netr_ServerReqChallenge *r)
50 struct netlogon_server_pipe_state *pipe_state =
51 talloc_get_type(dce_call->context->private_data, struct netlogon_server_pipe_state);
53 ZERO_STRUCTP(r->out.return_credentials);
55 /* destroyed on pipe shutdown */
58 talloc_free(pipe_state);
59 dce_call->context->private_data = NULL;
62 pipe_state = talloc(dce_call->context, struct netlogon_server_pipe_state);
63 NT_STATUS_HAVE_NO_MEMORY(pipe_state);
65 pipe_state->client_challenge = *r->in.credentials;
67 generate_random_buffer(pipe_state->server_challenge.data,
68 sizeof(pipe_state->server_challenge.data));
70 *r->out.return_credentials = pipe_state->server_challenge;
72 dce_call->context->private_data = pipe_state;
77 static NTSTATUS dcesrv_netr_ServerAuthenticate3(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
78 struct netr_ServerAuthenticate3 *r)
80 struct netlogon_server_pipe_state *pipe_state =
81 talloc_get_type(dce_call->context->private_data, struct netlogon_server_pipe_state);
82 struct netlogon_creds_CredentialState *creds;
83 struct ldb_context *schannel_ldb;
84 struct ldb_context *sam_ctx;
85 struct samr_Password *mach_pwd;
86 uint32_t user_account_control;
88 struct ldb_message **msgs;
90 const char *attrs[] = {"unicodePwd", "userAccountControl",
93 const char *trust_dom_attrs[] = {"flatname", NULL};
94 const char *account_name;
96 ZERO_STRUCTP(r->out.return_credentials);
100 * According to Microsoft (see bugid #6099)
101 * Windows 7 looks at the negotiate_flags
102 * returned in this structure *even if the
103 * call fails with access denied!
105 *r->out.negotiate_flags = NETLOGON_NEG_ACCOUNT_LOCKOUT |
106 NETLOGON_NEG_PERSISTENT_SAMREPL |
107 NETLOGON_NEG_ARCFOUR |
108 NETLOGON_NEG_PROMOTION_COUNT |
109 NETLOGON_NEG_CHANGELOG_BDC |
110 NETLOGON_NEG_FULL_SYNC_REPL |
111 NETLOGON_NEG_MULTIPLE_SIDS |
113 NETLOGON_NEG_PASSWORD_CHANGE_REFUSAL |
114 NETLOGON_NEG_SEND_PASSWORD_INFO_PDC |
115 NETLOGON_NEG_GENERIC_PASSTHROUGH |
116 NETLOGON_NEG_CONCURRENT_RPC |
117 NETLOGON_NEG_AVOID_ACCOUNT_DB_REPL |
118 NETLOGON_NEG_AVOID_SECURITYAUTH_DB_REPL |
119 NETLOGON_NEG_STRONG_KEYS |
120 NETLOGON_NEG_TRANSITIVE_TRUSTS |
121 NETLOGON_NEG_DNS_DOMAIN_TRUSTS |
122 NETLOGON_NEG_PASSWORD_SET2 |
123 NETLOGON_NEG_GETDOMAININFO |
124 NETLOGON_NEG_CROSS_FOREST_TRUSTS |
125 NETLOGON_NEG_NEUTRALIZE_NT4_EMULATION |
126 NETLOGON_NEG_RODC_PASSTHROUGH |
127 NETLOGON_NEG_AUTHENTICATED_RPC_LSASS |
128 NETLOGON_NEG_AUTHENTICATED_RPC;
131 DEBUG(1, ("No challenge requested by client, cannot authenticate\n"));
132 return NT_STATUS_ACCESS_DENIED;
135 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx,
136 system_session(mem_ctx, dce_call->conn->dce_ctx->lp_ctx));
137 if (sam_ctx == NULL) {
138 return NT_STATUS_INVALID_SYSTEM_SERVICE;
141 if (r->in.secure_channel_type == SEC_CHAN_DNS_DOMAIN) {
142 char *encoded_account = ldb_binary_encode_string(mem_ctx, r->in.account_name);
143 const char *flatname;
144 if (!encoded_account) {
145 return NT_STATUS_NO_MEMORY;
148 /* Kill the trailing dot */
149 if (encoded_account[strlen(encoded_account)-1] == '.') {
150 encoded_account[strlen(encoded_account)-1] = '\0';
153 /* pull the user attributes */
154 num_records = gendb_search(sam_ctx, mem_ctx, NULL, &msgs,
156 "(&(trustPartner=%s)(objectclass=trustedDomain))",
159 if (num_records == 0) {
160 DEBUG(3,("Couldn't find trust [%s] in samdb.\n",
162 return NT_STATUS_ACCESS_DENIED;
165 if (num_records > 1) {
166 DEBUG(0,("Found %d records matching user [%s]\n", num_records, r->in.account_name));
167 return NT_STATUS_INTERNAL_DB_CORRUPTION;
170 flatname = ldb_msg_find_attr_as_string(msgs[0], "flatname", NULL);
172 /* No flatname for this trust - we can't proceed */
173 return NT_STATUS_ACCESS_DENIED;
175 account_name = talloc_asprintf(mem_ctx, "%s$", flatname);
178 return NT_STATUS_NO_MEMORY;
182 account_name = r->in.account_name;
185 /* pull the user attributes */
186 num_records = gendb_search(sam_ctx, mem_ctx, NULL, &msgs, attrs,
187 "(&(sAMAccountName=%s)(objectclass=user))",
188 ldb_binary_encode_string(mem_ctx, account_name));
190 if (num_records == 0) {
191 DEBUG(3,("Couldn't find user [%s] in samdb.\n",
192 r->in.account_name));
193 return NT_STATUS_ACCESS_DENIED;
196 if (num_records > 1) {
197 DEBUG(0,("Found %d records matching user [%s]\n", num_records, r->in.account_name));
198 return NT_STATUS_INTERNAL_DB_CORRUPTION;
202 user_account_control = ldb_msg_find_attr_as_uint(msgs[0], "userAccountControl", 0);
204 if (user_account_control & UF_ACCOUNTDISABLE) {
205 DEBUG(1, ("Account [%s] is disabled\n", r->in.account_name));
206 return NT_STATUS_ACCESS_DENIED;
209 if (r->in.secure_channel_type == SEC_CHAN_WKSTA) {
210 if (!(user_account_control & UF_WORKSTATION_TRUST_ACCOUNT)) {
211 DEBUG(1, ("Client asked for a workstation secure channel, but is not a workstation (member server) acb flags: 0x%x\n", user_account_control));
212 return NT_STATUS_ACCESS_DENIED;
214 } else if (r->in.secure_channel_type == SEC_CHAN_DOMAIN ||
215 r->in.secure_channel_type == SEC_CHAN_DNS_DOMAIN) {
216 if (!(user_account_control & UF_INTERDOMAIN_TRUST_ACCOUNT)) {
217 DEBUG(1, ("Client asked for a trusted domain secure channel, but is not a trusted domain: acb flags: 0x%x\n", user_account_control));
219 return NT_STATUS_ACCESS_DENIED;
221 } else if (r->in.secure_channel_type == SEC_CHAN_BDC) {
222 if (!(user_account_control & UF_SERVER_TRUST_ACCOUNT)) {
223 DEBUG(1, ("Client asked for a server secure channel, but is not a server (domain controller): acb flags: 0x%x\n", user_account_control));
224 return NT_STATUS_ACCESS_DENIED;
227 DEBUG(1, ("Client asked for an invalid secure channel type: %d\n",
228 r->in.secure_channel_type));
229 return NT_STATUS_ACCESS_DENIED;
232 *r->out.rid = samdb_result_rid_from_sid(mem_ctx, msgs[0],
235 mach_pwd = samdb_result_hash(mem_ctx, msgs[0], "unicodePwd");
236 if (mach_pwd == NULL) {
237 return NT_STATUS_ACCESS_DENIED;
240 creds = netlogon_creds_server_init(mem_ctx,
243 r->in.secure_channel_type,
244 &pipe_state->client_challenge,
245 &pipe_state->server_challenge,
248 r->out.return_credentials,
249 *r->in.negotiate_flags);
252 return NT_STATUS_ACCESS_DENIED;
255 creds->sid = samdb_result_dom_sid(creds, msgs[0], "objectSid");
257 schannel_ldb = schannel_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx);
259 return NT_STATUS_ACCESS_DENIED;
262 nt_status = schannel_store_session_key(schannel_ldb, mem_ctx, creds);
263 talloc_free(schannel_ldb);
268 static NTSTATUS dcesrv_netr_ServerAuthenticate(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
269 struct netr_ServerAuthenticate *r)
271 struct netr_ServerAuthenticate3 a;
274 * negotiate_flags is used as an [in] parameter
275 * so it need to be initialised.
277 * (I think ... = 0; seems wrong here --metze)
279 uint32_t negotiate_flags_in = 0;
280 uint32_t negotiate_flags_out = 0;
282 a.in.server_name = r->in.server_name;
283 a.in.account_name = r->in.account_name;
284 a.in.secure_channel_type = r->in.secure_channel_type;
285 a.in.computer_name = r->in.computer_name;
286 a.in.credentials = r->in.credentials;
287 a.in.negotiate_flags = &negotiate_flags_in;
289 a.out.return_credentials = r->out.return_credentials;
291 a.out.negotiate_flags = &negotiate_flags_out;
293 return dcesrv_netr_ServerAuthenticate3(dce_call, mem_ctx, &a);
296 static NTSTATUS dcesrv_netr_ServerAuthenticate2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
297 struct netr_ServerAuthenticate2 *r)
299 struct netr_ServerAuthenticate3 r3;
302 r3.in.server_name = r->in.server_name;
303 r3.in.account_name = r->in.account_name;
304 r3.in.secure_channel_type = r->in.secure_channel_type;
305 r3.in.computer_name = r->in.computer_name;
306 r3.in.credentials = r->in.credentials;
307 r3.out.return_credentials = r->out.return_credentials;
308 r3.in.negotiate_flags = r->in.negotiate_flags;
309 r3.out.negotiate_flags = r->out.negotiate_flags;
312 return dcesrv_netr_ServerAuthenticate3(dce_call, mem_ctx, &r3);
316 Validate an incoming authenticator against the credentials for the remote machine.
318 The credentials are (re)read and from the schannel database, and
319 written back after the caclulations are performed.
321 The creds_out parameter (if not NULL) returns the credentials, if
322 the caller needs some of that information.
325 static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dce_call,
327 const char *computer_name,
328 struct netr_Authenticator *received_authenticator,
329 struct netr_Authenticator *return_authenticator,
330 struct netlogon_creds_CredentialState **creds_out)
333 struct ldb_context *ldb;
334 bool schannel_global_required = false; /* Should be lp_schannel_server() == true */
335 bool schannel_in_use = dce_call->conn->auth_state.auth_info
336 && dce_call->conn->auth_state.auth_info->auth_type == DCERPC_AUTH_TYPE_SCHANNEL
337 && (dce_call->conn->auth_state.auth_info->auth_level == DCERPC_AUTH_LEVEL_INTEGRITY
338 || dce_call->conn->auth_state.auth_info->auth_level == DCERPC_AUTH_LEVEL_PRIVACY);
340 ldb = schannel_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx);
342 return NT_STATUS_ACCESS_DENIED;
344 nt_status = schannel_creds_server_step_check(ldb, mem_ctx,
346 schannel_global_required,
348 received_authenticator,
349 return_authenticator, creds_out);
355 Change the machine account password for the currently connected
356 client. Supplies only the NT#.
359 static NTSTATUS dcesrv_netr_ServerPasswordSet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
360 struct netr_ServerPasswordSet *r)
362 struct netlogon_creds_CredentialState *creds;
363 struct ldb_context *sam_ctx;
366 nt_status = dcesrv_netr_creds_server_step_check(dce_call,
369 r->in.credential, r->out.return_authenticator,
371 NT_STATUS_NOT_OK_RETURN(nt_status);
373 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));
374 if (sam_ctx == NULL) {
375 return NT_STATUS_INVALID_SYSTEM_SERVICE;
378 netlogon_creds_des_decrypt(creds, r->in.new_password);
380 /* Using the sid for the account as the key, set the password */
381 nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
383 NULL, /* Don't have plaintext */
384 NULL, r->in.new_password,
385 true, /* Password change */
391 Change the machine account password for the currently connected
392 client. Supplies new plaintext.
394 static NTSTATUS dcesrv_netr_ServerPasswordSet2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
395 struct netr_ServerPasswordSet2 *r)
397 struct netlogon_creds_CredentialState *creds;
398 struct ldb_context *sam_ctx;
400 DATA_BLOB new_password;
402 struct samr_CryptPassword password_buf;
404 nt_status = dcesrv_netr_creds_server_step_check(dce_call,
407 r->in.credential, r->out.return_authenticator,
409 NT_STATUS_NOT_OK_RETURN(nt_status);
411 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));
412 if (sam_ctx == NULL) {
413 return NT_STATUS_INVALID_SYSTEM_SERVICE;
416 memcpy(password_buf.data, r->in.new_password->data, 512);
417 SIVAL(password_buf.data, 512, r->in.new_password->length);
418 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
420 if (!extract_pw_from_buffer(mem_ctx, password_buf.data, &new_password)) {
421 DEBUG(3,("samr: failed to decode password buffer\n"));
422 return NT_STATUS_WRONG_PASSWORD;
425 /* Using the sid for the account as the key, set the password */
426 nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
428 &new_password, /* we have plaintext */
430 true, /* Password change */
439 static WERROR dcesrv_netr_LogonUasLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
440 struct netr_LogonUasLogon *r)
442 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
449 static WERROR dcesrv_netr_LogonUasLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
450 struct netr_LogonUasLogoff *r)
452 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
457 netr_LogonSamLogon_base
459 This version of the function allows other wrappers to say 'do not check the credentials'
461 We can't do the traditional 'wrapping' format completly, as this function must only run under schannel
463 static NTSTATUS dcesrv_netr_LogonSamLogon_base(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
464 struct netr_LogonSamLogonEx *r, struct netlogon_creds_CredentialState *creds)
466 struct auth_context *auth_context;
467 struct auth_usersupplied_info *user_info;
468 struct auth_serversupplied_info *server_info;
470 static const char zeros[16];
471 struct netr_SamBaseInfo *sam;
472 struct netr_SamInfo2 *sam2;
473 struct netr_SamInfo3 *sam3;
474 struct netr_SamInfo6 *sam6;
476 user_info = talloc(mem_ctx, struct auth_usersupplied_info);
477 NT_STATUS_HAVE_NO_MEMORY(user_info);
479 user_info->flags = 0;
480 user_info->mapped_state = false;
481 user_info->remote_host = NULL;
483 switch (r->in.logon_level) {
484 case NetlogonInteractiveInformation:
485 case NetlogonServiceInformation:
486 case NetlogonInteractiveTransitiveInformation:
487 case NetlogonServiceTransitiveInformation:
488 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
489 netlogon_creds_arcfour_crypt(creds,
490 r->in.logon->password->lmpassword.hash,
491 sizeof(r->in.logon->password->lmpassword.hash));
492 netlogon_creds_arcfour_crypt(creds,
493 r->in.logon->password->ntpassword.hash,
494 sizeof(r->in.logon->password->ntpassword.hash));
496 netlogon_creds_des_decrypt(creds, &r->in.logon->password->lmpassword);
497 netlogon_creds_des_decrypt(creds, &r->in.logon->password->ntpassword);
500 /* TODO: we need to deny anonymous access here */
501 nt_status = auth_context_create(mem_ctx,
502 dce_call->event_ctx, dce_call->msg_ctx,
503 dce_call->conn->dce_ctx->lp_ctx,
505 NT_STATUS_NOT_OK_RETURN(nt_status);
507 user_info->logon_parameters = r->in.logon->password->identity_info.parameter_control;
508 user_info->client.account_name = r->in.logon->password->identity_info.account_name.string;
509 user_info->client.domain_name = r->in.logon->password->identity_info.domain_name.string;
510 user_info->workstation_name = r->in.logon->password->identity_info.workstation.string;
512 user_info->flags |= USER_INFO_INTERACTIVE_LOGON;
513 user_info->password_state = AUTH_PASSWORD_HASH;
515 user_info->password.hash.lanman = talloc(user_info, struct samr_Password);
516 NT_STATUS_HAVE_NO_MEMORY(user_info->password.hash.lanman);
517 *user_info->password.hash.lanman = r->in.logon->password->lmpassword;
519 user_info->password.hash.nt = talloc(user_info, struct samr_Password);
520 NT_STATUS_HAVE_NO_MEMORY(user_info->password.hash.nt);
521 *user_info->password.hash.nt = r->in.logon->password->ntpassword;
524 case NetlogonNetworkInformation:
525 case NetlogonNetworkTransitiveInformation:
527 /* TODO: we need to deny anonymous access here */
528 nt_status = auth_context_create(mem_ctx,
529 dce_call->event_ctx, dce_call->msg_ctx,
530 dce_call->conn->dce_ctx->lp_ctx,
532 NT_STATUS_NOT_OK_RETURN(nt_status);
534 nt_status = auth_context_set_challenge(auth_context, r->in.logon->network->challenge, "netr_LogonSamLogonWithFlags");
535 NT_STATUS_NOT_OK_RETURN(nt_status);
537 user_info->logon_parameters = r->in.logon->network->identity_info.parameter_control;
538 user_info->client.account_name = r->in.logon->network->identity_info.account_name.string;
539 user_info->client.domain_name = r->in.logon->network->identity_info.domain_name.string;
540 user_info->workstation_name = r->in.logon->network->identity_info.workstation.string;
542 user_info->password_state = AUTH_PASSWORD_RESPONSE;
543 user_info->password.response.lanman = data_blob_talloc(mem_ctx, r->in.logon->network->lm.data, r->in.logon->network->lm.length);
544 user_info->password.response.nt = data_blob_talloc(mem_ctx, r->in.logon->network->nt.data, r->in.logon->network->nt.length);
549 case NetlogonGenericInformation:
551 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
552 netlogon_creds_arcfour_crypt(creds,
553 r->in.logon->generic->data, r->in.logon->generic->length);
555 /* Using DES to verify kerberos tickets makes no sense */
556 return NT_STATUS_INVALID_PARAMETER;
559 if (strcmp(r->in.logon->generic->package_name.string, "Kerberos") == 0) {
561 struct server_id *kdc;
562 struct kdc_check_generic_kerberos check;
563 struct netr_GenericInfo2 *generic = talloc_zero(mem_ctx, struct netr_GenericInfo2);
564 NT_STATUS_HAVE_NO_MEMORY(generic);
565 *r->out.authoritative = 1;
567 /* TODO: Describe and deal with these flags */
570 r->out.validation->generic = generic;
572 kdc = irpc_servers_byname(dce_call->msg_ctx, mem_ctx, "kdc_server");
573 if ((kdc == NULL) || (kdc[0].id == 0)) {
574 return NT_STATUS_NO_LOGON_SERVERS;
577 check.in.generic_request =
578 data_blob_const(r->in.logon->generic->data,
579 r->in.logon->generic->length);
581 status = irpc_call(dce_call->msg_ctx, kdc[0],
582 &ndr_table_irpc, NDR_KDC_CHECK_GENERIC_KERBEROS,
584 if (!NT_STATUS_IS_OK(status)) {
587 generic->length = check.out.generic_reply.length;
588 generic->data = check.out.generic_reply.data;
592 /* Until we get an implemetnation of these other packages */
593 return NT_STATUS_INVALID_PARAMETER;
596 return NT_STATUS_INVALID_PARAMETER;
599 nt_status = auth_check_password(auth_context, mem_ctx, user_info, &server_info);
600 NT_STATUS_NOT_OK_RETURN(nt_status);
602 nt_status = auth_convert_server_info_sambaseinfo(mem_ctx, server_info, &sam);
603 NT_STATUS_NOT_OK_RETURN(nt_status);
605 /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
606 /* It appears that level 6 is not individually encrypted */
607 if ((r->in.validation_level != 6) &&
608 memcmp(sam->key.key, zeros, sizeof(sam->key.key)) != 0) {
609 /* This key is sent unencrypted without the ARCFOUR flag set */
610 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
611 netlogon_creds_arcfour_crypt(creds,
613 sizeof(sam->key.key));
617 /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
618 /* It appears that level 6 is not individually encrypted */
619 if ((r->in.validation_level != 6) &&
620 memcmp(sam->LMSessKey.key, zeros, sizeof(sam->LMSessKey.key)) != 0) {
621 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
622 netlogon_creds_arcfour_crypt(creds,
624 sizeof(sam->LMSessKey.key));
626 netlogon_creds_des_encrypt_LMKey(creds,
631 switch (r->in.validation_level) {
633 sam2 = talloc_zero(mem_ctx, struct netr_SamInfo2);
634 NT_STATUS_HAVE_NO_MEMORY(sam2);
636 r->out.validation->sam2 = sam2;
640 sam3 = talloc_zero(mem_ctx, struct netr_SamInfo3);
641 NT_STATUS_HAVE_NO_MEMORY(sam3);
643 r->out.validation->sam3 = sam3;
647 sam6 = talloc_zero(mem_ctx, struct netr_SamInfo6);
648 NT_STATUS_HAVE_NO_MEMORY(sam6);
650 sam6->forest.string = lp_realm(dce_call->conn->dce_ctx->lp_ctx);
651 sam6->principle.string = talloc_asprintf(mem_ctx, "%s@%s",
652 sam->account_name.string, sam6->forest.string);
653 NT_STATUS_HAVE_NO_MEMORY(sam6->principle.string);
654 r->out.validation->sam6 = sam6;
661 *r->out.authoritative = 1;
663 /* TODO: Describe and deal with these flags */
669 static NTSTATUS dcesrv_netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
670 struct netr_LogonSamLogonEx *r)
673 struct netlogon_creds_CredentialState *creds;
674 struct ldb_context *ldb = schannel_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx);
676 return NT_STATUS_ACCESS_DENIED;
679 nt_status = schannel_fetch_session_key(ldb, mem_ctx, r->in.computer_name, &creds);
680 if (!NT_STATUS_IS_OK(nt_status)) {
684 if (!dce_call->conn->auth_state.auth_info ||
685 dce_call->conn->auth_state.auth_info->auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
686 return NT_STATUS_ACCESS_DENIED;
688 return dcesrv_netr_LogonSamLogon_base(dce_call, mem_ctx, r, creds);
692 netr_LogonSamLogonWithFlags
695 static NTSTATUS dcesrv_netr_LogonSamLogonWithFlags(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
696 struct netr_LogonSamLogonWithFlags *r)
699 struct netlogon_creds_CredentialState *creds;
700 struct netr_LogonSamLogonEx r2;
702 struct netr_Authenticator *return_authenticator;
704 return_authenticator = talloc(mem_ctx, struct netr_Authenticator);
705 NT_STATUS_HAVE_NO_MEMORY(return_authenticator);
707 nt_status = dcesrv_netr_creds_server_step_check(dce_call,
710 r->in.credential, return_authenticator,
712 NT_STATUS_NOT_OK_RETURN(nt_status);
716 r2.in.server_name = r->in.server_name;
717 r2.in.computer_name = r->in.computer_name;
718 r2.in.logon_level = r->in.logon_level;
719 r2.in.logon = r->in.logon;
720 r2.in.validation_level = r->in.validation_level;
721 r2.in.flags = r->in.flags;
722 r2.out.validation = r->out.validation;
723 r2.out.authoritative = r->out.authoritative;
724 r2.out.flags = r->out.flags;
726 nt_status = dcesrv_netr_LogonSamLogon_base(dce_call, mem_ctx, &r2, creds);
728 r->out.return_authenticator = return_authenticator;
736 static NTSTATUS dcesrv_netr_LogonSamLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
737 struct netr_LogonSamLogon *r)
739 struct netr_LogonSamLogonWithFlags r2;
745 r2.in.server_name = r->in.server_name;
746 r2.in.computer_name = r->in.computer_name;
747 r2.in.credential = r->in.credential;
748 r2.in.return_authenticator = r->in.return_authenticator;
749 r2.in.logon_level = r->in.logon_level;
750 r2.in.logon = r->in.logon;
751 r2.in.validation_level = r->in.validation_level;
752 r2.in.flags = &flags;
753 r2.out.validation = r->out.validation;
754 r2.out.authoritative = r->out.authoritative;
755 r2.out.flags = &flags;
757 status = dcesrv_netr_LogonSamLogonWithFlags(dce_call, mem_ctx, &r2);
759 r->out.return_authenticator = r2.out.return_authenticator;
768 static NTSTATUS dcesrv_netr_LogonSamLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
769 struct netr_LogonSamLogoff *r)
771 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
779 static NTSTATUS dcesrv_netr_DatabaseDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
780 struct netr_DatabaseDeltas *r)
782 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
789 static NTSTATUS dcesrv_netr_DatabaseSync2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
790 struct netr_DatabaseSync2 *r)
792 /* win2k3 native mode returns "NOT IMPLEMENTED" for this call */
793 return NT_STATUS_NOT_IMPLEMENTED;
800 static NTSTATUS dcesrv_netr_DatabaseSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
801 struct netr_DatabaseSync *r)
803 struct netr_DatabaseSync2 r2;
808 r2.in.logon_server = r->in.logon_server;
809 r2.in.computername = r->in.computername;
810 r2.in.credential = r->in.credential;
811 r2.in.database_id = r->in.database_id;
812 r2.in.restart_state = SYNCSTATE_NORMAL_STATE;
813 r2.in.sync_context = r->in.sync_context;
814 r2.out.sync_context = r->out.sync_context;
815 r2.out.delta_enum_array = r->out.delta_enum_array;
816 r2.in.preferredmaximumlength = r->in.preferredmaximumlength;
818 status = dcesrv_netr_DatabaseSync2(dce_call, mem_ctx, &r2);
827 static NTSTATUS dcesrv_netr_AccountDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
828 struct netr_AccountDeltas *r)
830 /* w2k3 returns "NOT IMPLEMENTED" for this call */
831 return NT_STATUS_NOT_IMPLEMENTED;
838 static NTSTATUS dcesrv_netr_AccountSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
839 struct netr_AccountSync *r)
841 /* w2k3 returns "NOT IMPLEMENTED" for this call */
842 return NT_STATUS_NOT_IMPLEMENTED;
849 static WERROR dcesrv_netr_GetDcName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
850 struct netr_GetDcName *r)
852 const char * const attrs[] = { NULL };
853 struct ldb_context *sam_ctx;
854 struct ldb_message **res;
855 struct ldb_dn *domain_dn;
859 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx,
860 dce_call->conn->dce_ctx->lp_ctx,
861 dce_call->conn->auth_state.session_info);
862 if (sam_ctx == NULL) {
863 return WERR_DS_SERVICE_UNAVAILABLE;
866 domain_dn = samdb_domain_to_dn(sam_ctx, mem_ctx,
868 if (domain_dn == NULL) {
869 return WERR_DS_SERVICE_UNAVAILABLE;
872 ret = gendb_search_dn(sam_ctx, mem_ctx,
873 domain_dn, &res, attrs);
875 return WERR_NO_SUCH_DOMAIN;
878 /* TODO: - return real IP address
879 * - check all r->in.* parameters (server_unc is ignored by w2k3!)
881 dcname = talloc_asprintf(mem_ctx, "\\\\%s",
882 lp_netbios_name(dce_call->conn->dce_ctx->lp_ctx));
883 W_ERROR_HAVE_NO_MEMORY(dcname);
885 *r->out.dcname = dcname;
893 static WERROR dcesrv_netr_LogonControl2Ex(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
894 struct netr_LogonControl2Ex *r)
896 return WERR_NOT_SUPPORTED;
903 static WERROR dcesrv_netr_LogonControl(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
904 struct netr_LogonControl *r)
906 struct netr_LogonControl2Ex r2;
909 if (r->in.level == 0x00000001) {
912 r2.in.logon_server = r->in.logon_server;
913 r2.in.function_code = r->in.function_code;
914 r2.in.level = r->in.level;
916 r2.out.query = r->out.query;
918 werr = dcesrv_netr_LogonControl2Ex(dce_call, mem_ctx, &r2);
919 } else if (r->in.level == 0x00000002) {
920 werr = WERR_NOT_SUPPORTED;
922 werr = WERR_UNKNOWN_LEVEL;
932 static WERROR dcesrv_netr_LogonControl2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
933 struct netr_LogonControl2 *r)
935 struct netr_LogonControl2Ex r2;
940 r2.in.logon_server = r->in.logon_server;
941 r2.in.function_code = r->in.function_code;
942 r2.in.level = r->in.level;
943 r2.in.data = r->in.data;
944 r2.out.query = r->out.query;
946 werr = dcesrv_netr_LogonControl2Ex(dce_call, mem_ctx, &r2);
955 static WERROR dcesrv_netr_GetAnyDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
956 struct netr_GetAnyDCName *r)
958 struct netr_GetDcName r2;
963 r2.in.logon_server = r->in.logon_server;
964 r2.in.domainname = r->in.domainname;
965 r2.out.dcname = r->out.dcname;
967 werr = dcesrv_netr_GetDcName(dce_call, mem_ctx, &r2);
976 static NTSTATUS dcesrv_netr_DatabaseRedo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
977 struct netr_DatabaseRedo *r)
979 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
984 netr_NetrEnumerateTurstedDomains
986 static WERROR dcesrv_netr_NetrEnumerateTrustedDomains(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
987 struct netr_NetrEnumerateTrustedDomains *r)
989 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
994 netr_LogonGetCapabilities
996 static NTSTATUS dcesrv_netr_LogonGetCapabilities(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
997 struct netr_LogonGetCapabilities *r)
999 /* we don't support AES yet */
1000 return NT_STATUS_NOT_IMPLEMENTED;
1005 netr_NETRLOGONSETSERVICEBITS
1007 static WERROR dcesrv_netr_NETRLOGONSETSERVICEBITS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1008 struct netr_NETRLOGONSETSERVICEBITS *r)
1010 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1015 netr_LogonGetTrustRid
1017 static WERROR dcesrv_netr_LogonGetTrustRid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1018 struct netr_LogonGetTrustRid *r)
1020 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1025 netr_NETRLOGONCOMPUTESERVERDIGEST
1027 static WERROR dcesrv_netr_NETRLOGONCOMPUTESERVERDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1028 struct netr_NETRLOGONCOMPUTESERVERDIGEST *r)
1030 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1035 netr_NETRLOGONCOMPUTECLIENTDIGEST
1037 static WERROR dcesrv_netr_NETRLOGONCOMPUTECLIENTDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1038 struct netr_NETRLOGONCOMPUTECLIENTDIGEST *r)
1040 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1048 static WERROR dcesrv_netr_DsRGetSiteName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1049 struct netr_DsRGetSiteName *r)
1051 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1056 fill in a netr_DomainTrustInfo from a ldb search result
1058 static NTSTATUS fill_domain_trust_info(TALLOC_CTX *mem_ctx,
1059 struct loadparm_context *lp_ctx,
1060 struct ldb_context *sam_ctx,
1061 struct ldb_message *res,
1062 struct netr_DomainTrustInfo *info,
1063 bool is_local, bool is_trust_list)
1067 info->trust_extension.info = talloc_zero(mem_ctx, struct netr_trust_extension);
1068 info->trust_extension.length = 16;
1069 info->trust_extension.info->flags =
1070 NETR_TRUST_FLAG_TREEROOT |
1071 NETR_TRUST_FLAG_IN_FOREST |
1072 NETR_TRUST_FLAG_PRIMARY;
1074 info->trust_extension.info->parent_index = 0; /* should be index into array
1076 info->trust_extension.info->trust_type = LSA_TRUST_TYPE_UPLEVEL; /* should be based on ldb search for trusts */
1077 info->trust_extension.info->trust_attributes = LSA_TRUST_ATTRIBUTE_NON_TRANSITIVE; /* needs to be based on ldb search */
1079 if (is_trust_list) {
1080 /* MS-NRPC 3.5.4.3.9 - must be set to NULL for trust list */
1081 info->forest.string = NULL;
1084 /* TODO: we need a common function for pulling the forest */
1085 info->forest.string = ldb_dn_canonical_string(info, ldb_get_root_basedn(sam_ctx));
1086 if (!info->forest.string) {
1087 return NT_STATUS_NO_SUCH_DOMAIN;
1089 p = strchr(info->forest.string, '/');
1096 info->domainname.string = lp_sam_name(lp_ctx);
1097 info->fulldomainname.string = lp_realm(lp_ctx);
1098 info->guid = samdb_result_guid(res, "objectGUID");
1099 info->sid = samdb_result_dom_sid(mem_ctx, res, "objectSid");
1101 info->domainname.string = samdb_result_string(res, "flatName", NULL);
1102 info->fulldomainname.string = samdb_result_string(res, "trustPartner", NULL);
1103 info->guid = samdb_result_guid(res, "objectGUID");
1104 info->sid = samdb_result_dom_sid(mem_ctx, res, "securityIdentifier");
1107 return NT_STATUS_OK;
1111 netr_LogonGetDomainInfo
1112 this is called as part of the ADS domain logon procedure.
1114 It has an important role in convaying details about the client, such
1115 as Operating System, Version, Service Pack etc.
1117 static NTSTATUS dcesrv_netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1118 struct netr_LogonGetDomainInfo *r)
1120 const char * const attrs[] = { "objectSid",
1121 "objectGUID", "flatName", "securityIdentifier",
1122 "trustPartner", NULL };
1123 struct ldb_context *sam_ctx;
1124 struct ldb_message **res1, **res2;
1125 struct netr_DomainInfo1 *info1;
1129 const char *local_domain;
1131 status = dcesrv_netr_creds_server_step_check(dce_call,
1133 r->in.computer_name,
1135 r->out.return_authenticator,
1137 if (!NT_STATUS_IS_OK(status)) {
1138 DEBUG(0,(__location__ " Bad credentials - error\n"));
1140 NT_STATUS_NOT_OK_RETURN(status);
1142 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
1143 if (sam_ctx == NULL) {
1144 return NT_STATUS_INVALID_SYSTEM_SERVICE;
1147 /* we need to do two searches. The first will pull our primary
1148 domain and the second will pull any trusted domains. Our
1149 primary domain is also a "trusted" domain, so we need to
1150 put the primary domain into the lists of returned trusts as
1152 ret1 = gendb_search_dn(sam_ctx, mem_ctx, samdb_base_dn(sam_ctx), &res1, attrs);
1154 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1157 /* try and find the domain */
1158 local_domain = lp_sam_name(dce_call->conn->dce_ctx->lp_ctx);
1160 ret2 = gendb_search(sam_ctx, mem_ctx, NULL, &res2, attrs, "(objectClass=trustedDomain)");
1162 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1165 info1 = talloc(mem_ctx, struct netr_DomainInfo1);
1166 NT_STATUS_HAVE_NO_MEMORY(info1);
1168 ZERO_STRUCTP(info1);
1170 info1->num_trusts = ret2 + 1;
1171 info1->trusts = talloc_array(mem_ctx, struct netr_DomainTrustInfo,
1173 NT_STATUS_HAVE_NO_MEMORY(info1->trusts);
1175 status = fill_domain_trust_info(mem_ctx, dce_call->conn->dce_ctx->lp_ctx, sam_ctx, res1[0], &info1->domaininfo,
1177 NT_STATUS_NOT_OK_RETURN(status);
1179 for (i=0;i<ret2;i++) {
1180 status = fill_domain_trust_info(mem_ctx, dce_call->conn->dce_ctx->lp_ctx, sam_ctx, res2[i], &info1->trusts[i],
1182 NT_STATUS_NOT_OK_RETURN(status);
1185 status = fill_domain_trust_info(mem_ctx, dce_call->conn->dce_ctx->lp_ctx, sam_ctx, res1[0], &info1->trusts[i],
1187 NT_STATUS_NOT_OK_RETURN(status);
1189 info1->dns_hostname.string = lp_realm(dce_call->conn->dce_ctx->lp_ctx);
1190 info1->workstation_flags =
1191 NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS | NETR_WS_FLAG_HANDLES_SPN_UPDATE;
1192 info1->supported_enc_types = 0; /* w2008 gives this 0 */
1194 r->out.info->info1 = info1;
1196 return NT_STATUS_OK;
1202 netr_ServerPasswordGet
1204 static WERROR dcesrv_netr_ServerPasswordGet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1205 struct netr_ServerPasswordGet *r)
1207 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1212 netr_NETRLOGONSENDTOSAM
1214 static WERROR dcesrv_netr_NETRLOGONSENDTOSAM(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1215 struct netr_NETRLOGONSENDTOSAM *r)
1217 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1222 netr_DsRAddressToSitenamesW
1224 static WERROR dcesrv_netr_DsRAddressToSitenamesW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1225 struct netr_DsRAddressToSitenamesW *r)
1227 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1232 netr_DsRGetDCNameEx2
1234 static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1235 struct netr_DsRGetDCNameEx2 *r)
1237 const char * const attrs[] = { "objectGUID", NULL };
1238 struct ldb_context *sam_ctx;
1239 struct ldb_message **res;
1240 struct ldb_dn *domain_dn;
1242 struct netr_DsRGetDCNameInfo *info;
1244 ZERO_STRUCTP(r->out.info);
1246 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
1247 if (sam_ctx == NULL) {
1248 return WERR_DS_SERVICE_UNAVAILABLE;
1251 /* Win7-beta will send the domain name in the form the user typed, so we have to cope
1252 with both the short and long form here */
1253 if (r->in.domain_name != NULL && !lp_is_my_domain_or_realm(dce_call->conn->dce_ctx->lp_ctx,
1254 r->in.domain_name)) {
1255 return WERR_NO_SUCH_DOMAIN;
1258 domain_dn = ldb_get_default_basedn(sam_ctx);
1259 if (domain_dn == NULL) {
1260 return WERR_DS_SERVICE_UNAVAILABLE;
1263 ret = gendb_search_dn(sam_ctx, mem_ctx,
1264 domain_dn, &res, attrs);
1268 info = talloc(mem_ctx, struct netr_DsRGetDCNameInfo);
1269 W_ERROR_HAVE_NO_MEMORY(info);
1271 /* TODO: - return real IP address
1272 * - check all r->in.* parameters (server_unc is ignored by w2k3!)
1274 info->dc_unc = talloc_asprintf(mem_ctx, "\\\\%s.%s",
1275 lp_netbios_name(dce_call->conn->dce_ctx->lp_ctx),
1276 lp_realm(dce_call->conn->dce_ctx->lp_ctx));
1277 W_ERROR_HAVE_NO_MEMORY(info->dc_unc);
1278 info->dc_address = talloc_strdup(mem_ctx, "\\\\0.0.0.0");
1279 W_ERROR_HAVE_NO_MEMORY(info->dc_address);
1280 info->dc_address_type = DS_ADDRESS_TYPE_INET;
1281 info->domain_guid = samdb_result_guid(res[0], "objectGUID");
1282 info->domain_name = lp_realm(dce_call->conn->dce_ctx->lp_ctx);
1283 info->forest_name = lp_realm(dce_call->conn->dce_ctx->lp_ctx);
1284 info->dc_flags = DS_DNS_FOREST |
1287 DS_SERVER_WRITABLE |
1289 DS_SERVER_TIMESERV |
1295 info->dc_site_name = talloc_strdup(mem_ctx, "Default-First-Site-Name");
1296 W_ERROR_HAVE_NO_MEMORY(info->dc_site_name);
1297 info->client_site_name = talloc_strdup(mem_ctx, "Default-First-Site-Name");
1298 W_ERROR_HAVE_NO_MEMORY(info->client_site_name);
1300 *r->out.info = info;
1308 static WERROR dcesrv_netr_DsRGetDCNameEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1309 struct netr_DsRGetDCNameEx *r)
1311 struct netr_DsRGetDCNameEx2 r2;
1316 r2.in.server_unc = r->in.server_unc;
1317 r2.in.client_account = NULL;
1319 r2.in.domain_guid = r->in.domain_guid;
1320 r2.in.domain_name = r->in.domain_name;
1321 r2.in.site_name = r->in.site_name;
1322 r2.in.flags = r->in.flags;
1323 r2.out.info = r->out.info;
1325 werr = dcesrv_netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1333 static WERROR dcesrv_netr_DsRGetDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1334 struct netr_DsRGetDCName *r)
1336 struct netr_DsRGetDCNameEx2 r2;
1341 r2.in.server_unc = r->in.server_unc;
1342 r2.in.client_account = NULL;
1344 r2.in.domain_name = r->in.domain_name;
1345 r2.in.domain_guid = r->in.domain_guid;
1347 r2.in.site_name = NULL; /* should fill in from site GUID */
1348 r2.in.flags = r->in.flags;
1349 r2.out.info = r->out.info;
1351 werr = dcesrv_netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1356 netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN
1358 static WERROR dcesrv_netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1359 struct netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN *r)
1361 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1366 netr_NetrEnumerateTrustedDomainsEx
1368 static WERROR dcesrv_netr_NetrEnumerateTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1369 struct netr_NetrEnumerateTrustedDomainsEx *r)
1371 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1376 netr_DsRAddressToSitenamesExW
1378 static WERROR dcesrv_netr_DsRAddressToSitenamesExW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1379 struct netr_DsRAddressToSitenamesExW *r)
1381 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1386 netr_DsrGetDcSiteCoverageW
1388 static WERROR dcesrv_netr_DsrGetDcSiteCoverageW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1389 struct netr_DsrGetDcSiteCoverageW *r)
1391 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1396 netr_DsrEnumerateDomainTrusts
1398 static WERROR dcesrv_netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1399 struct netr_DsrEnumerateDomainTrusts *r)
1401 struct netr_DomainTrustList *trusts;
1402 struct ldb_context *sam_ctx;
1404 struct ldb_message **dom_res;
1405 const char * const dom_attrs[] = { "objectSid", "objectGUID", NULL };
1407 ZERO_STRUCT(r->out);
1409 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
1410 if (sam_ctx == NULL) {
1411 return WERR_GENERAL_FAILURE;
1414 ret = gendb_search_dn(sam_ctx, mem_ctx, NULL,
1415 &dom_res, dom_attrs);
1417 return WERR_GENERAL_FAILURE;
1420 return WERR_GENERAL_FAILURE;
1423 trusts = talloc(mem_ctx, struct netr_DomainTrustList);
1424 W_ERROR_HAVE_NO_MEMORY(trusts);
1426 trusts->array = talloc_array(trusts, struct netr_DomainTrust, ret);
1427 W_ERROR_HAVE_NO_MEMORY(trusts->array);
1429 trusts->count = 1; /* ?? */
1431 r->out.trusts = trusts;
1433 /* TODO: add filtering by trust_flags, and correct trust_type
1435 trusts->array[0].netbios_name = lp_sam_name(dce_call->conn->dce_ctx->lp_ctx);
1436 trusts->array[0].dns_name = lp_realm(dce_call->conn->dce_ctx->lp_ctx);
1437 trusts->array[0].trust_flags =
1438 NETR_TRUST_FLAG_TREEROOT |
1439 NETR_TRUST_FLAG_IN_FOREST |
1440 NETR_TRUST_FLAG_PRIMARY;
1441 trusts->array[0].parent_index = 0;
1442 trusts->array[0].trust_type = 2;
1443 trusts->array[0].trust_attributes = 0;
1444 trusts->array[0].sid = samdb_result_dom_sid(mem_ctx, dom_res[0], "objectSid");
1445 trusts->array[0].guid = samdb_result_guid(dom_res[0], "objectGUID");
1452 netr_DsrDeregisterDNSHostRecords
1454 static WERROR dcesrv_netr_DsrDeregisterDNSHostRecords(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1455 struct netr_DsrDeregisterDNSHostRecords *r)
1457 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1462 netr_ServerTrustPasswordsGet
1464 static NTSTATUS dcesrv_netr_ServerTrustPasswordsGet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1465 struct netr_ServerTrustPasswordsGet *r)
1467 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1472 netr_DsRGetForestTrustInformation
1474 static WERROR dcesrv_netr_DsRGetForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1475 struct netr_DsRGetForestTrustInformation *r)
1477 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1482 netr_GetForestTrustInformation
1484 static WERROR dcesrv_netr_GetForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1485 struct netr_GetForestTrustInformation *r)
1487 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1492 netr_ServerGetTrustInfo
1494 static NTSTATUS dcesrv_netr_ServerGetTrustInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1495 struct netr_ServerGetTrustInfo *r)
1497 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1501 /* include the generated boilerplate */
1502 #include "librpc/gen_ndr/ndr_netlogon_s.c"