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((struct ldb_context *)sam_ctx,
155 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((struct ldb_context *)sam_ctx, mem_ctx,
189 "(&(sAMAccountName=%s)(objectclass=user))",
190 ldb_binary_encode_string(mem_ctx, account_name));
192 if (num_records == 0) {
193 DEBUG(3,("Couldn't find user [%s] in samdb.\n",
194 r->in.account_name));
195 return NT_STATUS_ACCESS_DENIED;
198 if (num_records > 1) {
199 DEBUG(0,("Found %d records matching user [%s]\n", num_records, r->in.account_name));
200 return NT_STATUS_INTERNAL_DB_CORRUPTION;
204 user_account_control = ldb_msg_find_attr_as_uint(msgs[0], "userAccountControl", 0);
206 if (user_account_control & UF_ACCOUNTDISABLE) {
207 DEBUG(1, ("Account [%s] is disabled\n", r->in.account_name));
208 return NT_STATUS_ACCESS_DENIED;
211 if (r->in.secure_channel_type == SEC_CHAN_WKSTA) {
212 if (!(user_account_control & UF_WORKSTATION_TRUST_ACCOUNT)) {
213 DEBUG(1, ("Client asked for a workstation secure channel, but is not a workstation (member server) acb flags: 0x%x\n", user_account_control));
214 return NT_STATUS_ACCESS_DENIED;
216 } else if (r->in.secure_channel_type == SEC_CHAN_DOMAIN ||
217 r->in.secure_channel_type == SEC_CHAN_DNS_DOMAIN) {
218 if (!(user_account_control & UF_INTERDOMAIN_TRUST_ACCOUNT)) {
219 DEBUG(1, ("Client asked for a trusted domain secure channel, but is not a trusted domain: acb flags: 0x%x\n", user_account_control));
221 return NT_STATUS_ACCESS_DENIED;
223 } else if (r->in.secure_channel_type == SEC_CHAN_BDC) {
224 if (!(user_account_control & UF_SERVER_TRUST_ACCOUNT)) {
225 DEBUG(1, ("Client asked for a server secure channel, but is not a server (domain controller): acb flags: 0x%x\n", user_account_control));
226 return NT_STATUS_ACCESS_DENIED;
229 DEBUG(1, ("Client asked for an invalid secure channel type: %d\n",
230 r->in.secure_channel_type));
231 return NT_STATUS_ACCESS_DENIED;
234 *r->out.rid = samdb_result_rid_from_sid(mem_ctx, msgs[0],
237 mach_pwd = samdb_result_hash(mem_ctx, msgs[0], "unicodePwd");
238 if (mach_pwd == NULL) {
239 return NT_STATUS_ACCESS_DENIED;
242 creds = netlogon_creds_server_init(mem_ctx,
245 r->in.secure_channel_type,
246 &pipe_state->client_challenge,
247 &pipe_state->server_challenge,
250 r->out.return_credentials,
251 *r->in.negotiate_flags);
254 return NT_STATUS_ACCESS_DENIED;
257 creds->sid = samdb_result_dom_sid(creds, msgs[0], "objectSid");
259 schannel_ldb = schannel_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx);
261 return NT_STATUS_ACCESS_DENIED;
264 nt_status = schannel_store_session_key(schannel_ldb, mem_ctx, creds);
265 talloc_free(schannel_ldb);
270 static NTSTATUS dcesrv_netr_ServerAuthenticate(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
271 struct netr_ServerAuthenticate *r)
273 struct netr_ServerAuthenticate3 a;
276 * negotiate_flags is used as an [in] parameter
277 * so it need to be initialised.
279 * (I think ... = 0; seems wrong here --metze)
281 uint32_t negotiate_flags_in = 0;
282 uint32_t negotiate_flags_out = 0;
284 a.in.server_name = r->in.server_name;
285 a.in.account_name = r->in.account_name;
286 a.in.secure_channel_type = r->in.secure_channel_type;
287 a.in.computer_name = r->in.computer_name;
288 a.in.credentials = r->in.credentials;
289 a.in.negotiate_flags = &negotiate_flags_in;
291 a.out.return_credentials = r->out.return_credentials;
293 a.out.negotiate_flags = &negotiate_flags_out;
295 return dcesrv_netr_ServerAuthenticate3(dce_call, mem_ctx, &a);
298 static NTSTATUS dcesrv_netr_ServerAuthenticate2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
299 struct netr_ServerAuthenticate2 *r)
301 struct netr_ServerAuthenticate3 r3;
304 r3.in.server_name = r->in.server_name;
305 r3.in.account_name = r->in.account_name;
306 r3.in.secure_channel_type = r->in.secure_channel_type;
307 r3.in.computer_name = r->in.computer_name;
308 r3.in.credentials = r->in.credentials;
309 r3.out.return_credentials = r->out.return_credentials;
310 r3.in.negotiate_flags = r->in.negotiate_flags;
311 r3.out.negotiate_flags = r->out.negotiate_flags;
314 return dcesrv_netr_ServerAuthenticate3(dce_call, mem_ctx, &r3);
318 Validate an incoming authenticator against the credentials for the remote machine.
320 The credentials are (re)read and from the schannel database, and
321 written back after the caclulations are performed.
323 The creds_out parameter (if not NULL) returns the credentials, if
324 the caller needs some of that information.
327 static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dce_call,
329 const char *computer_name,
330 struct netr_Authenticator *received_authenticator,
331 struct netr_Authenticator *return_authenticator,
332 struct netlogon_creds_CredentialState **creds_out)
335 struct ldb_context *ldb;
336 bool schannel_global_required = false; /* Should be lp_schannel_server() == true */
337 bool schannel_in_use = dce_call->conn->auth_state.auth_info
338 && dce_call->conn->auth_state.auth_info->auth_type == DCERPC_AUTH_TYPE_SCHANNEL
339 && (dce_call->conn->auth_state.auth_info->auth_level == DCERPC_AUTH_LEVEL_INTEGRITY
340 || dce_call->conn->auth_state.auth_info->auth_level == DCERPC_AUTH_LEVEL_PRIVACY);
342 ldb = schannel_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx);
344 return NT_STATUS_ACCESS_DENIED;
346 nt_status = schannel_creds_server_step_check(ldb, mem_ctx,
348 schannel_global_required,
350 received_authenticator,
351 return_authenticator, creds_out);
357 Change the machine account password for the currently connected
358 client. Supplies only the NT#.
361 static NTSTATUS dcesrv_netr_ServerPasswordSet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
362 struct netr_ServerPasswordSet *r)
364 struct netlogon_creds_CredentialState *creds;
365 struct ldb_context *sam_ctx;
368 nt_status = dcesrv_netr_creds_server_step_check(dce_call,
371 r->in.credential, r->out.return_authenticator,
373 NT_STATUS_NOT_OK_RETURN(nt_status);
375 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));
376 if (sam_ctx == NULL) {
377 return NT_STATUS_INVALID_SYSTEM_SERVICE;
380 netlogon_creds_des_decrypt(creds, r->in.new_password);
382 /* Using the sid for the account as the key, set the password */
383 nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
385 NULL, /* Don't have plaintext */
386 NULL, r->in.new_password,
387 true, /* Password change */
393 Change the machine account password for the currently connected
394 client. Supplies new plaintext.
396 static NTSTATUS dcesrv_netr_ServerPasswordSet2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
397 struct netr_ServerPasswordSet2 *r)
399 struct netlogon_creds_CredentialState *creds;
400 struct ldb_context *sam_ctx;
402 DATA_BLOB new_password;
404 struct samr_CryptPassword password_buf;
406 nt_status = dcesrv_netr_creds_server_step_check(dce_call,
409 r->in.credential, r->out.return_authenticator,
411 NT_STATUS_NOT_OK_RETURN(nt_status);
413 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));
414 if (sam_ctx == NULL) {
415 return NT_STATUS_INVALID_SYSTEM_SERVICE;
418 memcpy(password_buf.data, r->in.new_password->data, 512);
419 SIVAL(password_buf.data, 512, r->in.new_password->length);
420 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
422 if (!extract_pw_from_buffer(mem_ctx, password_buf.data, &new_password)) {
423 DEBUG(3,("samr: failed to decode password buffer\n"));
424 return NT_STATUS_WRONG_PASSWORD;
427 /* Using the sid for the account as the key, set the password */
428 nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
430 &new_password, /* we have plaintext */
432 true, /* Password change */
441 static WERROR dcesrv_netr_LogonUasLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
442 struct netr_LogonUasLogon *r)
444 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
451 static WERROR dcesrv_netr_LogonUasLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
452 struct netr_LogonUasLogoff *r)
454 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
459 netr_LogonSamLogon_base
461 This version of the function allows other wrappers to say 'do not check the credentials'
463 We can't do the traditional 'wrapping' format completly, as this function must only run under schannel
465 static NTSTATUS dcesrv_netr_LogonSamLogon_base(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
466 struct netr_LogonSamLogonEx *r, struct netlogon_creds_CredentialState *creds)
468 struct auth_context *auth_context;
469 struct auth_usersupplied_info *user_info;
470 struct auth_serversupplied_info *server_info;
472 static const char zeros[16];
473 struct netr_SamBaseInfo *sam;
474 struct netr_SamInfo2 *sam2;
475 struct netr_SamInfo3 *sam3;
476 struct netr_SamInfo6 *sam6;
478 user_info = talloc(mem_ctx, struct auth_usersupplied_info);
479 NT_STATUS_HAVE_NO_MEMORY(user_info);
481 user_info->flags = 0;
482 user_info->mapped_state = false;
483 user_info->remote_host = NULL;
485 switch (r->in.logon_level) {
486 case NetlogonInteractiveInformation:
487 case NetlogonServiceInformation:
488 case NetlogonInteractiveTransitiveInformation:
489 case NetlogonServiceTransitiveInformation:
490 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
491 netlogon_creds_arcfour_crypt(creds,
492 r->in.logon->password->lmpassword.hash,
493 sizeof(r->in.logon->password->lmpassword.hash));
494 netlogon_creds_arcfour_crypt(creds,
495 r->in.logon->password->ntpassword.hash,
496 sizeof(r->in.logon->password->ntpassword.hash));
498 netlogon_creds_des_decrypt(creds, &r->in.logon->password->lmpassword);
499 netlogon_creds_des_decrypt(creds, &r->in.logon->password->ntpassword);
502 /* TODO: we need to deny anonymous access here */
503 nt_status = auth_context_create(mem_ctx,
504 dce_call->event_ctx, dce_call->msg_ctx,
505 dce_call->conn->dce_ctx->lp_ctx,
507 NT_STATUS_NOT_OK_RETURN(nt_status);
509 user_info->logon_parameters = r->in.logon->password->identity_info.parameter_control;
510 user_info->client.account_name = r->in.logon->password->identity_info.account_name.string;
511 user_info->client.domain_name = r->in.logon->password->identity_info.domain_name.string;
512 user_info->workstation_name = r->in.logon->password->identity_info.workstation.string;
514 user_info->flags |= USER_INFO_INTERACTIVE_LOGON;
515 user_info->password_state = AUTH_PASSWORD_HASH;
517 user_info->password.hash.lanman = talloc(user_info, struct samr_Password);
518 NT_STATUS_HAVE_NO_MEMORY(user_info->password.hash.lanman);
519 *user_info->password.hash.lanman = r->in.logon->password->lmpassword;
521 user_info->password.hash.nt = talloc(user_info, struct samr_Password);
522 NT_STATUS_HAVE_NO_MEMORY(user_info->password.hash.nt);
523 *user_info->password.hash.nt = r->in.logon->password->ntpassword;
526 case NetlogonNetworkInformation:
527 case NetlogonNetworkTransitiveInformation:
529 /* TODO: we need to deny anonymous access here */
530 nt_status = auth_context_create(mem_ctx,
531 dce_call->event_ctx, dce_call->msg_ctx,
532 dce_call->conn->dce_ctx->lp_ctx,
534 NT_STATUS_NOT_OK_RETURN(nt_status);
536 nt_status = auth_context_set_challenge(auth_context, r->in.logon->network->challenge, "netr_LogonSamLogonWithFlags");
537 NT_STATUS_NOT_OK_RETURN(nt_status);
539 user_info->logon_parameters = r->in.logon->network->identity_info.parameter_control;
540 user_info->client.account_name = r->in.logon->network->identity_info.account_name.string;
541 user_info->client.domain_name = r->in.logon->network->identity_info.domain_name.string;
542 user_info->workstation_name = r->in.logon->network->identity_info.workstation.string;
544 user_info->password_state = AUTH_PASSWORD_RESPONSE;
545 user_info->password.response.lanman = data_blob_talloc(mem_ctx, r->in.logon->network->lm.data, r->in.logon->network->lm.length);
546 user_info->password.response.nt = data_blob_talloc(mem_ctx, r->in.logon->network->nt.data, r->in.logon->network->nt.length);
551 case NetlogonGenericInformation:
553 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
554 netlogon_creds_arcfour_crypt(creds,
555 r->in.logon->generic->data, r->in.logon->generic->length);
557 /* Using DES to verify kerberos tickets makes no sense */
558 return NT_STATUS_INVALID_PARAMETER;
561 if (strcmp(r->in.logon->generic->package_name.string, "Kerberos") == 0) {
563 struct server_id *kdc;
564 struct kdc_check_generic_kerberos check;
565 struct netr_GenericInfo2 *generic = talloc_zero(mem_ctx, struct netr_GenericInfo2);
566 NT_STATUS_HAVE_NO_MEMORY(generic);
567 *r->out.authoritative = 1;
569 /* TODO: Describe and deal with these flags */
572 r->out.validation->generic = generic;
574 kdc = irpc_servers_byname(dce_call->msg_ctx, mem_ctx, "kdc_server");
575 if ((kdc == NULL) || (kdc[0].id == 0)) {
576 return NT_STATUS_NO_LOGON_SERVERS;
579 check.in.generic_request =
580 data_blob_const(r->in.logon->generic->data,
581 r->in.logon->generic->length);
583 status = irpc_call(dce_call->msg_ctx, kdc[0],
584 &ndr_table_irpc, NDR_KDC_CHECK_GENERIC_KERBEROS,
586 if (!NT_STATUS_IS_OK(status)) {
589 generic->length = check.out.generic_reply.length;
590 generic->data = check.out.generic_reply.data;
594 /* Until we get an implemetnation of these other packages */
595 return NT_STATUS_INVALID_PARAMETER;
598 return NT_STATUS_INVALID_PARAMETER;
601 nt_status = auth_check_password(auth_context, mem_ctx, user_info, &server_info);
602 NT_STATUS_NOT_OK_RETURN(nt_status);
604 nt_status = auth_convert_server_info_sambaseinfo(mem_ctx, server_info, &sam);
605 NT_STATUS_NOT_OK_RETURN(nt_status);
607 /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
608 /* It appears that level 6 is not individually encrypted */
609 if ((r->in.validation_level != 6) &&
610 memcmp(sam->key.key, zeros, sizeof(sam->key.key)) != 0) {
611 /* This key is sent unencrypted without the ARCFOUR flag set */
612 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
613 netlogon_creds_arcfour_crypt(creds,
615 sizeof(sam->key.key));
619 /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
620 /* It appears that level 6 is not individually encrypted */
621 if ((r->in.validation_level != 6) &&
622 memcmp(sam->LMSessKey.key, zeros, sizeof(sam->LMSessKey.key)) != 0) {
623 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
624 netlogon_creds_arcfour_crypt(creds,
626 sizeof(sam->LMSessKey.key));
628 netlogon_creds_des_encrypt_LMKey(creds,
633 switch (r->in.validation_level) {
635 sam2 = talloc_zero(mem_ctx, struct netr_SamInfo2);
636 NT_STATUS_HAVE_NO_MEMORY(sam2);
638 r->out.validation->sam2 = sam2;
642 sam3 = talloc_zero(mem_ctx, struct netr_SamInfo3);
643 NT_STATUS_HAVE_NO_MEMORY(sam3);
645 r->out.validation->sam3 = sam3;
649 sam6 = talloc_zero(mem_ctx, struct netr_SamInfo6);
650 NT_STATUS_HAVE_NO_MEMORY(sam6);
652 sam6->forest.string = lp_realm(dce_call->conn->dce_ctx->lp_ctx);
653 sam6->principle.string = talloc_asprintf(mem_ctx, "%s@%s",
654 sam->account_name.string, sam6->forest.string);
655 NT_STATUS_HAVE_NO_MEMORY(sam6->principle.string);
656 r->out.validation->sam6 = sam6;
663 *r->out.authoritative = 1;
665 /* TODO: Describe and deal with these flags */
671 static NTSTATUS dcesrv_netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
672 struct netr_LogonSamLogonEx *r)
675 struct netlogon_creds_CredentialState *creds;
676 struct ldb_context *ldb = schannel_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx);
678 return NT_STATUS_ACCESS_DENIED;
681 nt_status = schannel_fetch_session_key(ldb, mem_ctx, r->in.computer_name, &creds);
682 if (!NT_STATUS_IS_OK(nt_status)) {
686 if (!dce_call->conn->auth_state.auth_info ||
687 dce_call->conn->auth_state.auth_info->auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
688 return NT_STATUS_ACCESS_DENIED;
690 return dcesrv_netr_LogonSamLogon_base(dce_call, mem_ctx, r, creds);
694 netr_LogonSamLogonWithFlags
697 static NTSTATUS dcesrv_netr_LogonSamLogonWithFlags(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
698 struct netr_LogonSamLogonWithFlags *r)
701 struct netlogon_creds_CredentialState *creds;
702 struct netr_LogonSamLogonEx r2;
704 struct netr_Authenticator *return_authenticator;
706 return_authenticator = talloc(mem_ctx, struct netr_Authenticator);
707 NT_STATUS_HAVE_NO_MEMORY(return_authenticator);
709 nt_status = dcesrv_netr_creds_server_step_check(dce_call,
712 r->in.credential, return_authenticator,
714 NT_STATUS_NOT_OK_RETURN(nt_status);
718 r2.in.server_name = r->in.server_name;
719 r2.in.computer_name = r->in.computer_name;
720 r2.in.logon_level = r->in.logon_level;
721 r2.in.logon = r->in.logon;
722 r2.in.validation_level = r->in.validation_level;
723 r2.in.flags = r->in.flags;
724 r2.out.validation = r->out.validation;
725 r2.out.authoritative = r->out.authoritative;
726 r2.out.flags = r->out.flags;
728 nt_status = dcesrv_netr_LogonSamLogon_base(dce_call, mem_ctx, &r2, creds);
730 r->out.return_authenticator = return_authenticator;
738 static NTSTATUS dcesrv_netr_LogonSamLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
739 struct netr_LogonSamLogon *r)
741 struct netr_LogonSamLogonWithFlags r2;
747 r2.in.server_name = r->in.server_name;
748 r2.in.computer_name = r->in.computer_name;
749 r2.in.credential = r->in.credential;
750 r2.in.return_authenticator = r->in.return_authenticator;
751 r2.in.logon_level = r->in.logon_level;
752 r2.in.logon = r->in.logon;
753 r2.in.validation_level = r->in.validation_level;
754 r2.in.flags = &flags;
755 r2.out.validation = r->out.validation;
756 r2.out.authoritative = r->out.authoritative;
757 r2.out.flags = &flags;
759 status = dcesrv_netr_LogonSamLogonWithFlags(dce_call, mem_ctx, &r2);
761 r->out.return_authenticator = r2.out.return_authenticator;
770 static NTSTATUS dcesrv_netr_LogonSamLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
771 struct netr_LogonSamLogoff *r)
773 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
781 static NTSTATUS dcesrv_netr_DatabaseDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
782 struct netr_DatabaseDeltas *r)
784 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
791 static NTSTATUS dcesrv_netr_DatabaseSync2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
792 struct netr_DatabaseSync2 *r)
794 /* win2k3 native mode returns "NOT IMPLEMENTED" for this call */
795 return NT_STATUS_NOT_IMPLEMENTED;
802 static NTSTATUS dcesrv_netr_DatabaseSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
803 struct netr_DatabaseSync *r)
805 struct netr_DatabaseSync2 r2;
810 r2.in.logon_server = r->in.logon_server;
811 r2.in.computername = r->in.computername;
812 r2.in.credential = r->in.credential;
813 r2.in.database_id = r->in.database_id;
814 r2.in.restart_state = SYNCSTATE_NORMAL_STATE;
815 r2.in.sync_context = r->in.sync_context;
816 r2.out.sync_context = r->out.sync_context;
817 r2.out.delta_enum_array = r->out.delta_enum_array;
818 r2.in.preferredmaximumlength = r->in.preferredmaximumlength;
820 status = dcesrv_netr_DatabaseSync2(dce_call, mem_ctx, &r2);
829 static NTSTATUS dcesrv_netr_AccountDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
830 struct netr_AccountDeltas *r)
832 /* w2k3 returns "NOT IMPLEMENTED" for this call */
833 return NT_STATUS_NOT_IMPLEMENTED;
840 static NTSTATUS dcesrv_netr_AccountSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
841 struct netr_AccountSync *r)
843 /* w2k3 returns "NOT IMPLEMENTED" for this call */
844 return NT_STATUS_NOT_IMPLEMENTED;
851 static WERROR dcesrv_netr_GetDcName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
852 struct netr_GetDcName *r)
854 const char * const attrs[] = { NULL };
856 struct ldb_message **res;
857 struct ldb_dn *domain_dn;
861 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx,
862 dce_call->conn->dce_ctx->lp_ctx,
863 dce_call->conn->auth_state.session_info);
864 if (sam_ctx == NULL) {
865 return WERR_DS_SERVICE_UNAVAILABLE;
868 domain_dn = samdb_domain_to_dn((struct ldb_context *)sam_ctx, mem_ctx,
870 if (domain_dn == NULL) {
871 return WERR_DS_SERVICE_UNAVAILABLE;
874 ret = gendb_search_dn((struct ldb_context *)sam_ctx, mem_ctx,
875 domain_dn, &res, attrs);
877 return WERR_NO_SUCH_DOMAIN;
880 /* TODO: - return real IP address
881 * - check all r->in.* parameters (server_unc is ignored by w2k3!)
883 dcname = talloc_asprintf(mem_ctx, "\\\\%s",
884 lp_netbios_name(dce_call->conn->dce_ctx->lp_ctx));
885 W_ERROR_HAVE_NO_MEMORY(dcname);
887 *r->out.dcname = dcname;
895 static WERROR dcesrv_netr_LogonControl2Ex(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
896 struct netr_LogonControl2Ex *r)
898 return WERR_NOT_SUPPORTED;
905 static WERROR dcesrv_netr_LogonControl(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
906 struct netr_LogonControl *r)
908 struct netr_LogonControl2Ex r2;
911 if (r->in.level == 0x00000001) {
914 r2.in.logon_server = r->in.logon_server;
915 r2.in.function_code = r->in.function_code;
916 r2.in.level = r->in.level;
918 r2.out.query = r->out.query;
920 werr = dcesrv_netr_LogonControl2Ex(dce_call, mem_ctx, &r2);
921 } else if (r->in.level == 0x00000002) {
922 werr = WERR_NOT_SUPPORTED;
924 werr = WERR_UNKNOWN_LEVEL;
934 static WERROR dcesrv_netr_LogonControl2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
935 struct netr_LogonControl2 *r)
937 struct netr_LogonControl2Ex r2;
942 r2.in.logon_server = r->in.logon_server;
943 r2.in.function_code = r->in.function_code;
944 r2.in.level = r->in.level;
945 r2.in.data = r->in.data;
946 r2.out.query = r->out.query;
948 werr = dcesrv_netr_LogonControl2Ex(dce_call, mem_ctx, &r2);
957 static WERROR dcesrv_netr_GetAnyDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
958 struct netr_GetAnyDCName *r)
960 struct netr_GetDcName r2;
965 r2.in.logon_server = r->in.logon_server;
966 r2.in.domainname = r->in.domainname;
967 r2.out.dcname = r->out.dcname;
969 werr = dcesrv_netr_GetDcName(dce_call, mem_ctx, &r2);
978 static NTSTATUS dcesrv_netr_DatabaseRedo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
979 struct netr_DatabaseRedo *r)
981 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
986 netr_NetrEnumerateTurstedDomains
988 static WERROR dcesrv_netr_NetrEnumerateTrustedDomains(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
989 struct netr_NetrEnumerateTrustedDomains *r)
991 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
996 netr_LogonGetCapabilities
998 static NTSTATUS dcesrv_netr_LogonGetCapabilities(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
999 struct netr_LogonGetCapabilities *r)
1001 /* we don't support AES yet */
1002 return NT_STATUS_NOT_IMPLEMENTED;
1007 netr_NETRLOGONSETSERVICEBITS
1009 static WERROR dcesrv_netr_NETRLOGONSETSERVICEBITS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1010 struct netr_NETRLOGONSETSERVICEBITS *r)
1012 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1017 netr_LogonGetTrustRid
1019 static WERROR dcesrv_netr_LogonGetTrustRid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1020 struct netr_LogonGetTrustRid *r)
1022 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1027 netr_NETRLOGONCOMPUTESERVERDIGEST
1029 static WERROR dcesrv_netr_NETRLOGONCOMPUTESERVERDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1030 struct netr_NETRLOGONCOMPUTESERVERDIGEST *r)
1032 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1037 netr_NETRLOGONCOMPUTECLIENTDIGEST
1039 static WERROR dcesrv_netr_NETRLOGONCOMPUTECLIENTDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1040 struct netr_NETRLOGONCOMPUTECLIENTDIGEST *r)
1042 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1050 static WERROR dcesrv_netr_DsRGetSiteName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1051 struct netr_DsRGetSiteName *r)
1053 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1058 fill in a netr_DomainTrustInfo from a ldb search result
1060 static NTSTATUS fill_domain_trust_info(TALLOC_CTX *mem_ctx,
1061 struct loadparm_context *lp_ctx,
1062 struct ldb_context *sam_ctx,
1063 struct ldb_message *res,
1064 struct netr_DomainTrustInfo *info,
1065 bool is_local, bool is_trust_list)
1069 info->trust_extension.info = talloc_zero(mem_ctx, struct netr_trust_extension);
1070 info->trust_extension.length = 16;
1071 info->trust_extension.info->flags =
1072 NETR_TRUST_FLAG_TREEROOT |
1073 NETR_TRUST_FLAG_IN_FOREST |
1074 NETR_TRUST_FLAG_PRIMARY;
1076 info->trust_extension.info->parent_index = 0; /* should be index into array
1078 info->trust_extension.info->trust_type = LSA_TRUST_TYPE_UPLEVEL; /* should be based on ldb search for trusts */
1079 info->trust_extension.info->trust_attributes = LSA_TRUST_ATTRIBUTE_NON_TRANSITIVE; /* needs to be based on ldb search */
1081 if (is_trust_list) {
1082 /* MS-NRPC 3.5.4.3.9 - must be set to NULL for trust list */
1083 info->forest.string = NULL;
1086 /* TODO: we need a common function for pulling the forest */
1087 info->forest.string = ldb_dn_canonical_string(info, ldb_get_root_basedn(sam_ctx));
1088 if (!info->forest.string) {
1089 return NT_STATUS_NO_SUCH_DOMAIN;
1091 p = strchr(info->forest.string, '/');
1098 info->domainname.string = lp_sam_name(lp_ctx);
1099 info->fulldomainname.string = lp_realm(lp_ctx);
1100 info->guid = samdb_result_guid(res, "objectGUID");
1101 info->sid = samdb_result_dom_sid(mem_ctx, res, "objectSid");
1103 info->domainname.string = samdb_result_string(res, "flatName", NULL);
1104 info->fulldomainname.string = samdb_result_string(res, "trustPartner", NULL);
1105 info->guid = samdb_result_guid(res, "objectGUID");
1106 info->sid = samdb_result_dom_sid(mem_ctx, res, "securityIdentifier");
1109 return NT_STATUS_OK;
1113 netr_LogonGetDomainInfo
1114 this is called as part of the ADS domain logon procedure.
1116 It has an important role in convaying details about the client, such
1117 as Operating System, Version, Service Pack etc.
1119 static NTSTATUS dcesrv_netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1120 struct netr_LogonGetDomainInfo *r)
1122 const char * const attrs[] = { "objectSid",
1123 "objectGUID", "flatName", "securityIdentifier",
1124 "trustPartner", NULL };
1125 struct ldb_context *sam_ctx;
1126 struct ldb_message **res1, **res2;
1127 struct netr_DomainInfo1 *info1;
1131 const char *local_domain;
1133 status = dcesrv_netr_creds_server_step_check(dce_call,
1135 r->in.computer_name,
1137 r->out.return_authenticator,
1139 if (!NT_STATUS_IS_OK(status)) {
1140 DEBUG(0,(__location__ " Bad credentials - error\n"));
1142 NT_STATUS_NOT_OK_RETURN(status);
1144 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
1145 if (sam_ctx == NULL) {
1146 return NT_STATUS_INVALID_SYSTEM_SERVICE;
1149 /* we need to do two searches. The first will pull our primary
1150 domain and the second will pull any trusted domains. Our
1151 primary domain is also a "trusted" domain, so we need to
1152 put the primary domain into the lists of returned trusts as
1154 ret1 = gendb_search_dn(sam_ctx, mem_ctx, samdb_base_dn(sam_ctx), &res1, attrs);
1156 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1159 /* try and find the domain */
1160 local_domain = lp_sam_name(dce_call->conn->dce_ctx->lp_ctx);
1162 ret2 = gendb_search(sam_ctx, mem_ctx, NULL, &res2, attrs, "(objectClass=trustedDomain)");
1164 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1167 info1 = talloc(mem_ctx, struct netr_DomainInfo1);
1168 NT_STATUS_HAVE_NO_MEMORY(info1);
1170 ZERO_STRUCTP(info1);
1172 info1->num_trusts = ret2 + 1;
1173 info1->trusts = talloc_array(mem_ctx, struct netr_DomainTrustInfo,
1175 NT_STATUS_HAVE_NO_MEMORY(info1->trusts);
1177 status = fill_domain_trust_info(mem_ctx, dce_call->conn->dce_ctx->lp_ctx, sam_ctx, res1[0], &info1->domaininfo,
1179 NT_STATUS_NOT_OK_RETURN(status);
1181 for (i=0;i<ret2;i++) {
1182 status = fill_domain_trust_info(mem_ctx, dce_call->conn->dce_ctx->lp_ctx, sam_ctx, res2[i], &info1->trusts[i],
1184 NT_STATUS_NOT_OK_RETURN(status);
1187 status = fill_domain_trust_info(mem_ctx, dce_call->conn->dce_ctx->lp_ctx, sam_ctx, res1[0], &info1->trusts[i],
1189 NT_STATUS_NOT_OK_RETURN(status);
1191 info1->dns_hostname.string = lp_realm(dce_call->conn->dce_ctx->lp_ctx);
1192 info1->workstation_flags =
1193 NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS | NETR_WS_FLAG_HANDLES_SPN_UPDATE;
1194 info1->supported_enc_types = 0; /* w2008 gives this 0 */
1196 r->out.info->info1 = info1;
1198 return NT_STATUS_OK;
1204 netr_ServerPasswordGet
1206 static WERROR dcesrv_netr_ServerPasswordGet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1207 struct netr_ServerPasswordGet *r)
1209 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1214 netr_NETRLOGONSENDTOSAM
1216 static WERROR dcesrv_netr_NETRLOGONSENDTOSAM(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1217 struct netr_NETRLOGONSENDTOSAM *r)
1219 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1224 netr_DsRAddressToSitenamesW
1226 static WERROR dcesrv_netr_DsRAddressToSitenamesW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1227 struct netr_DsRAddressToSitenamesW *r)
1229 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1234 netr_DsRGetDCNameEx2
1236 static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1237 struct netr_DsRGetDCNameEx2 *r)
1239 const char * const attrs[] = { "objectGUID", NULL };
1240 struct ldb_context *sam_ctx;
1241 struct ldb_message **res;
1242 struct ldb_dn *domain_dn;
1244 struct netr_DsRGetDCNameInfo *info;
1246 ZERO_STRUCTP(r->out.info);
1248 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
1249 if (sam_ctx == NULL) {
1250 return WERR_DS_SERVICE_UNAVAILABLE;
1253 /* Win7-beta will send the domain name in the form the user typed, so we have to cope
1254 with both the short and long form here */
1255 if (r->in.domain_name != NULL && !lp_is_my_domain_or_realm(dce_call->conn->dce_ctx->lp_ctx,
1256 r->in.domain_name)) {
1257 return WERR_NO_SUCH_DOMAIN;
1260 domain_dn = ldb_get_default_basedn(sam_ctx);
1261 if (domain_dn == NULL) {
1262 return WERR_DS_SERVICE_UNAVAILABLE;
1265 ret = gendb_search_dn(sam_ctx, mem_ctx,
1266 domain_dn, &res, attrs);
1270 info = talloc(mem_ctx, struct netr_DsRGetDCNameInfo);
1271 W_ERROR_HAVE_NO_MEMORY(info);
1273 /* TODO: - return real IP address
1274 * - check all r->in.* parameters (server_unc is ignored by w2k3!)
1276 info->dc_unc = talloc_asprintf(mem_ctx, "\\\\%s.%s",
1277 lp_netbios_name(dce_call->conn->dce_ctx->lp_ctx),
1278 lp_realm(dce_call->conn->dce_ctx->lp_ctx));
1279 W_ERROR_HAVE_NO_MEMORY(info->dc_unc);
1280 info->dc_address = talloc_strdup(mem_ctx, "\\\\0.0.0.0");
1281 W_ERROR_HAVE_NO_MEMORY(info->dc_address);
1282 info->dc_address_type = DS_ADDRESS_TYPE_INET;
1283 info->domain_guid = samdb_result_guid(res[0], "objectGUID");
1284 info->domain_name = lp_realm(dce_call->conn->dce_ctx->lp_ctx);
1285 info->forest_name = lp_realm(dce_call->conn->dce_ctx->lp_ctx);
1286 info->dc_flags = DS_DNS_FOREST |
1289 DS_SERVER_WRITABLE |
1291 DS_SERVER_TIMESERV |
1297 info->dc_site_name = talloc_strdup(mem_ctx, "Default-First-Site-Name");
1298 W_ERROR_HAVE_NO_MEMORY(info->dc_site_name);
1299 info->client_site_name = talloc_strdup(mem_ctx, "Default-First-Site-Name");
1300 W_ERROR_HAVE_NO_MEMORY(info->client_site_name);
1302 *r->out.info = info;
1310 static WERROR dcesrv_netr_DsRGetDCNameEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1311 struct netr_DsRGetDCNameEx *r)
1313 struct netr_DsRGetDCNameEx2 r2;
1318 r2.in.server_unc = r->in.server_unc;
1319 r2.in.client_account = NULL;
1321 r2.in.domain_guid = r->in.domain_guid;
1322 r2.in.domain_name = r->in.domain_name;
1323 r2.in.site_name = r->in.site_name;
1324 r2.in.flags = r->in.flags;
1325 r2.out.info = r->out.info;
1327 werr = dcesrv_netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1335 static WERROR dcesrv_netr_DsRGetDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1336 struct netr_DsRGetDCName *r)
1338 struct netr_DsRGetDCNameEx2 r2;
1343 r2.in.server_unc = r->in.server_unc;
1344 r2.in.client_account = NULL;
1346 r2.in.domain_name = r->in.domain_name;
1347 r2.in.domain_guid = r->in.domain_guid;
1349 r2.in.site_name = NULL; /* should fill in from site GUID */
1350 r2.in.flags = r->in.flags;
1351 r2.out.info = r->out.info;
1353 werr = dcesrv_netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1358 netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN
1360 static WERROR dcesrv_netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1361 struct netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN *r)
1363 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1368 netr_NetrEnumerateTrustedDomainsEx
1370 static WERROR dcesrv_netr_NetrEnumerateTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1371 struct netr_NetrEnumerateTrustedDomainsEx *r)
1373 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1378 netr_DsRAddressToSitenamesExW
1380 static WERROR dcesrv_netr_DsRAddressToSitenamesExW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1381 struct netr_DsRAddressToSitenamesExW *r)
1383 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1388 netr_DsrGetDcSiteCoverageW
1390 static WERROR dcesrv_netr_DsrGetDcSiteCoverageW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1391 struct netr_DsrGetDcSiteCoverageW *r)
1393 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1398 netr_DsrEnumerateDomainTrusts
1400 static WERROR dcesrv_netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1401 struct netr_DsrEnumerateDomainTrusts *r)
1403 struct netr_DomainTrustList *trusts;
1406 struct ldb_message **dom_res;
1407 const char * const dom_attrs[] = { "objectSid", "objectGUID", NULL };
1409 ZERO_STRUCT(r->out);
1411 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
1412 if (sam_ctx == NULL) {
1413 return WERR_GENERAL_FAILURE;
1416 ret = gendb_search_dn((struct ldb_context *)sam_ctx, mem_ctx, NULL,
1417 &dom_res, dom_attrs);
1419 return WERR_GENERAL_FAILURE;
1422 return WERR_GENERAL_FAILURE;
1425 trusts = talloc(mem_ctx, struct netr_DomainTrustList);
1426 W_ERROR_HAVE_NO_MEMORY(trusts);
1428 trusts->array = talloc_array(trusts, struct netr_DomainTrust, ret);
1429 W_ERROR_HAVE_NO_MEMORY(trusts->array);
1431 trusts->count = 1; /* ?? */
1433 r->out.trusts = trusts;
1435 /* TODO: add filtering by trust_flags, and correct trust_type
1437 trusts->array[0].netbios_name = lp_sam_name(dce_call->conn->dce_ctx->lp_ctx);
1438 trusts->array[0].dns_name = lp_realm(dce_call->conn->dce_ctx->lp_ctx);
1439 trusts->array[0].trust_flags =
1440 NETR_TRUST_FLAG_TREEROOT |
1441 NETR_TRUST_FLAG_IN_FOREST |
1442 NETR_TRUST_FLAG_PRIMARY;
1443 trusts->array[0].parent_index = 0;
1444 trusts->array[0].trust_type = 2;
1445 trusts->array[0].trust_attributes = 0;
1446 trusts->array[0].sid = samdb_result_dom_sid(mem_ctx, dom_res[0], "objectSid");
1447 trusts->array[0].guid = samdb_result_guid(dom_res[0], "objectGUID");
1454 netr_DsrDeregisterDNSHostRecords
1456 static WERROR dcesrv_netr_DsrDeregisterDNSHostRecords(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1457 struct netr_DsrDeregisterDNSHostRecords *r)
1459 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1464 netr_ServerTrustPasswordsGet
1466 static NTSTATUS dcesrv_netr_ServerTrustPasswordsGet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1467 struct netr_ServerTrustPasswordsGet *r)
1469 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1474 netr_DsRGetForestTrustInformation
1476 static WERROR dcesrv_netr_DsRGetForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1477 struct netr_DsRGetForestTrustInformation *r)
1479 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1484 netr_GetForestTrustInformation
1486 static WERROR dcesrv_netr_GetForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1487 struct netr_GetForestTrustInformation *r)
1489 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1494 netr_ServerGetTrustInfo
1496 static NTSTATUS dcesrv_netr_ServerGetTrustInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1497 struct netr_ServerGetTrustInfo *r)
1499 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1503 /* include the generated boilerplate */
1504 #include "librpc/gen_ndr/ndr_netlogon_s.c"