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 "auth/auth.h"
27 #include "auth/auth_sam_reply.h"
28 #include "dsdb/samdb/samdb.h"
29 #include "../lib/util/util_ldb.h"
30 #include "../libcli/auth/schannel.h"
31 #include "libcli/security/security.h"
32 #include "param/param.h"
33 #include "lib/messaging/irpc.h"
34 #include "librpc/gen_ndr/ndr_irpc.h"
36 struct netlogon_server_pipe_state {
37 struct netr_Credential client_challenge;
38 struct netr_Credential server_challenge;
41 static NTSTATUS dcesrv_netr_ServerReqChallenge(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
42 struct netr_ServerReqChallenge *r)
44 struct netlogon_server_pipe_state *pipe_state =
45 talloc_get_type(dce_call->context->private_data, struct netlogon_server_pipe_state);
47 ZERO_STRUCTP(r->out.return_credentials);
49 /* destroyed on pipe shutdown */
52 talloc_free(pipe_state);
53 dce_call->context->private_data = NULL;
56 pipe_state = talloc(dce_call->context, struct netlogon_server_pipe_state);
57 NT_STATUS_HAVE_NO_MEMORY(pipe_state);
59 pipe_state->client_challenge = *r->in.credentials;
61 generate_random_buffer(pipe_state->server_challenge.data,
62 sizeof(pipe_state->server_challenge.data));
64 *r->out.return_credentials = pipe_state->server_challenge;
66 dce_call->context->private_data = pipe_state;
71 static NTSTATUS dcesrv_netr_ServerAuthenticate3(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
72 struct netr_ServerAuthenticate3 *r)
74 struct netlogon_server_pipe_state *pipe_state =
75 talloc_get_type(dce_call->context->private_data, struct netlogon_server_pipe_state);
76 struct netlogon_creds_CredentialState *creds;
77 struct ldb_context *sam_ctx;
78 struct samr_Password *mach_pwd;
79 uint32_t user_account_control;
81 struct ldb_message **msgs;
83 const char *attrs[] = {"unicodePwd", "userAccountControl",
86 const char *trust_dom_attrs[] = {"flatname", NULL};
87 const char *account_name;
89 ZERO_STRUCTP(r->out.return_credentials);
93 * According to Microsoft (see bugid #6099)
94 * Windows 7 looks at the negotiate_flags
95 * returned in this structure *even if the
96 * call fails with access denied!
98 *r->out.negotiate_flags = NETLOGON_NEG_ACCOUNT_LOCKOUT |
99 NETLOGON_NEG_PERSISTENT_SAMREPL |
100 NETLOGON_NEG_ARCFOUR |
101 NETLOGON_NEG_PROMOTION_COUNT |
102 NETLOGON_NEG_CHANGELOG_BDC |
103 NETLOGON_NEG_FULL_SYNC_REPL |
104 NETLOGON_NEG_MULTIPLE_SIDS |
106 NETLOGON_NEG_PASSWORD_CHANGE_REFUSAL |
107 NETLOGON_NEG_SEND_PASSWORD_INFO_PDC |
108 NETLOGON_NEG_GENERIC_PASSTHROUGH |
109 NETLOGON_NEG_CONCURRENT_RPC |
110 NETLOGON_NEG_AVOID_ACCOUNT_DB_REPL |
111 NETLOGON_NEG_AVOID_SECURITYAUTH_DB_REPL |
112 NETLOGON_NEG_STRONG_KEYS |
113 NETLOGON_NEG_TRANSITIVE_TRUSTS |
114 NETLOGON_NEG_DNS_DOMAIN_TRUSTS |
115 NETLOGON_NEG_PASSWORD_SET2 |
116 NETLOGON_NEG_GETDOMAININFO |
117 NETLOGON_NEG_CROSS_FOREST_TRUSTS |
118 NETLOGON_NEG_NEUTRALIZE_NT4_EMULATION |
119 NETLOGON_NEG_RODC_PASSTHROUGH |
120 NETLOGON_NEG_AUTHENTICATED_RPC_LSASS |
121 NETLOGON_NEG_AUTHENTICATED_RPC;
124 DEBUG(1, ("No challenge requested by client, cannot authenticate\n"));
125 return NT_STATUS_ACCESS_DENIED;
128 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx,
129 system_session(dce_call->conn->dce_ctx->lp_ctx));
130 if (sam_ctx == NULL) {
131 return NT_STATUS_INVALID_SYSTEM_SERVICE;
134 if (r->in.secure_channel_type == SEC_CHAN_DNS_DOMAIN) {
135 char *encoded_account = ldb_binary_encode_string(mem_ctx, r->in.account_name);
136 const char *flatname;
137 if (!encoded_account) {
138 return NT_STATUS_NO_MEMORY;
141 /* Kill the trailing dot */
142 if (encoded_account[strlen(encoded_account)-1] == '.') {
143 encoded_account[strlen(encoded_account)-1] = '\0';
146 /* pull the user attributes */
147 num_records = gendb_search(sam_ctx, mem_ctx, NULL, &msgs,
149 "(&(trustPartner=%s)(objectclass=trustedDomain))",
152 if (num_records == 0) {
153 DEBUG(3,("Couldn't find trust [%s] in samdb.\n",
155 return NT_STATUS_ACCESS_DENIED;
158 if (num_records > 1) {
159 DEBUG(0,("Found %d records matching user [%s]\n", num_records, r->in.account_name));
160 return NT_STATUS_INTERNAL_DB_CORRUPTION;
163 flatname = ldb_msg_find_attr_as_string(msgs[0], "flatname", NULL);
165 /* No flatname for this trust - we can't proceed */
166 return NT_STATUS_ACCESS_DENIED;
168 account_name = talloc_asprintf(mem_ctx, "%s$", flatname);
171 return NT_STATUS_NO_MEMORY;
175 account_name = r->in.account_name;
178 /* pull the user attributes */
179 num_records = gendb_search(sam_ctx, mem_ctx, NULL, &msgs, attrs,
180 "(&(sAMAccountName=%s)(objectclass=user))",
181 ldb_binary_encode_string(mem_ctx, account_name));
183 if (num_records == 0) {
184 DEBUG(3,("Couldn't find user [%s] in samdb.\n",
185 r->in.account_name));
186 return NT_STATUS_ACCESS_DENIED;
189 if (num_records > 1) {
190 DEBUG(0,("Found %d records matching user [%s]\n", num_records, r->in.account_name));
191 return NT_STATUS_INTERNAL_DB_CORRUPTION;
194 user_account_control = ldb_msg_find_attr_as_uint(msgs[0], "userAccountControl", 0);
196 if (user_account_control & UF_ACCOUNTDISABLE) {
197 DEBUG(1, ("Account [%s] is disabled\n", r->in.account_name));
198 return NT_STATUS_ACCESS_DENIED;
201 if (r->in.secure_channel_type == SEC_CHAN_WKSTA) {
202 if (!(user_account_control & UF_WORKSTATION_TRUST_ACCOUNT)) {
203 DEBUG(1, ("Client asked for a workstation secure channel, but is not a workstation (member server) acb flags: 0x%x\n", user_account_control));
204 return NT_STATUS_ACCESS_DENIED;
206 } else if (r->in.secure_channel_type == SEC_CHAN_DOMAIN ||
207 r->in.secure_channel_type == SEC_CHAN_DNS_DOMAIN) {
208 if (!(user_account_control & UF_INTERDOMAIN_TRUST_ACCOUNT)) {
209 DEBUG(1, ("Client asked for a trusted domain secure channel, but is not a trusted domain: acb flags: 0x%x\n", user_account_control));
211 return NT_STATUS_ACCESS_DENIED;
213 } else if (r->in.secure_channel_type == SEC_CHAN_BDC) {
214 if (!(user_account_control & UF_SERVER_TRUST_ACCOUNT)) {
215 DEBUG(1, ("Client asked for a server secure channel, but is not a server (domain controller): acb flags: 0x%x\n", user_account_control));
216 return NT_STATUS_ACCESS_DENIED;
219 DEBUG(1, ("Client asked for an invalid secure channel type: %d\n",
220 r->in.secure_channel_type));
221 return NT_STATUS_ACCESS_DENIED;
224 *r->out.rid = samdb_result_rid_from_sid(mem_ctx, msgs[0],
227 mach_pwd = samdb_result_hash(mem_ctx, msgs[0], "unicodePwd");
228 if (mach_pwd == NULL) {
229 return NT_STATUS_ACCESS_DENIED;
232 creds = netlogon_creds_server_init(mem_ctx,
235 r->in.secure_channel_type,
236 &pipe_state->client_challenge,
237 &pipe_state->server_challenge,
240 r->out.return_credentials,
241 *r->in.negotiate_flags);
244 return NT_STATUS_ACCESS_DENIED;
247 creds->sid = samdb_result_dom_sid(creds, msgs[0], "objectSid");
249 nt_status = schannel_save_creds_state(mem_ctx,
250 lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx),
251 lp_private_dir(dce_call->conn->dce_ctx->lp_ctx),
257 static NTSTATUS dcesrv_netr_ServerAuthenticate(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
258 struct netr_ServerAuthenticate *r)
260 struct netr_ServerAuthenticate3 a;
263 * negotiate_flags is used as an [in] parameter
264 * so it need to be initialised.
266 * (I think ... = 0; seems wrong here --metze)
268 uint32_t negotiate_flags_in = 0;
269 uint32_t negotiate_flags_out = 0;
271 a.in.server_name = r->in.server_name;
272 a.in.account_name = r->in.account_name;
273 a.in.secure_channel_type = r->in.secure_channel_type;
274 a.in.computer_name = r->in.computer_name;
275 a.in.credentials = r->in.credentials;
276 a.in.negotiate_flags = &negotiate_flags_in;
278 a.out.return_credentials = r->out.return_credentials;
280 a.out.negotiate_flags = &negotiate_flags_out;
282 return dcesrv_netr_ServerAuthenticate3(dce_call, mem_ctx, &a);
285 static NTSTATUS dcesrv_netr_ServerAuthenticate2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
286 struct netr_ServerAuthenticate2 *r)
288 struct netr_ServerAuthenticate3 r3;
291 r3.in.server_name = r->in.server_name;
292 r3.in.account_name = r->in.account_name;
293 r3.in.secure_channel_type = r->in.secure_channel_type;
294 r3.in.computer_name = r->in.computer_name;
295 r3.in.credentials = r->in.credentials;
296 r3.out.return_credentials = r->out.return_credentials;
297 r3.in.negotiate_flags = r->in.negotiate_flags;
298 r3.out.negotiate_flags = r->out.negotiate_flags;
301 return dcesrv_netr_ServerAuthenticate3(dce_call, mem_ctx, &r3);
305 * NOTE: The following functions are nearly identical to the ones available in
306 * source3/rpc_server/srv_nelog_nt.c
307 * The reason we keep 2 copies is that they use different structures to
308 * represent the auth_info and the decrpc pipes.
312 * If schannel is required for this call test that it actually is available.
314 static NTSTATUS schannel_check_required(struct dcerpc_auth *auth_info,
315 const char *computer_name,
316 bool integrity, bool privacy)
319 if (auth_info && auth_info->auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
320 if (!privacy && !integrity) {
324 if ((!privacy && integrity) &&
325 auth_info->auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
329 if ((privacy || integrity) &&
330 auth_info->auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
335 /* test didn't pass */
336 DEBUG(0, ("schannel_check_required: [%s] is not using schannel\n",
339 return NT_STATUS_ACCESS_DENIED;
342 static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dce_call,
344 const char *computer_name,
345 struct netr_Authenticator *received_authenticator,
346 struct netr_Authenticator *return_authenticator,
347 struct netlogon_creds_CredentialState **creds_out)
350 struct dcerpc_auth *auth_info = dce_call->conn->auth_state.auth_info;
351 bool schannel_global_required = false; /* Should be lp_schannel_server() == true */
353 if (schannel_global_required) {
354 nt_status = schannel_check_required(auth_info,
357 if (!NT_STATUS_IS_OK(nt_status)) {
362 nt_status = schannel_check_creds_state(mem_ctx,
363 lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx),
364 lp_private_dir(dce_call->conn->dce_ctx->lp_ctx),
366 received_authenticator,
367 return_authenticator,
373 Change the machine account password for the currently connected
374 client. Supplies only the NT#.
377 static NTSTATUS dcesrv_netr_ServerPasswordSet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
378 struct netr_ServerPasswordSet *r)
380 struct netlogon_creds_CredentialState *creds;
381 struct ldb_context *sam_ctx;
384 nt_status = dcesrv_netr_creds_server_step_check(dce_call,
387 r->in.credential, r->out.return_authenticator,
389 NT_STATUS_NOT_OK_RETURN(nt_status);
391 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(dce_call->conn->dce_ctx->lp_ctx));
392 if (sam_ctx == NULL) {
393 return NT_STATUS_INVALID_SYSTEM_SERVICE;
396 netlogon_creds_des_decrypt(creds, r->in.new_password);
398 /* Using the sid for the account as the key, set the password */
399 nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
401 NULL, /* Don't have plaintext */
402 NULL, r->in.new_password,
403 true, /* Password change */
409 Change the machine account password for the currently connected
410 client. Supplies new plaintext.
412 static NTSTATUS dcesrv_netr_ServerPasswordSet2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
413 struct netr_ServerPasswordSet2 *r)
415 struct netlogon_creds_CredentialState *creds;
416 struct ldb_context *sam_ctx;
418 DATA_BLOB new_password;
420 struct samr_CryptPassword password_buf;
422 nt_status = dcesrv_netr_creds_server_step_check(dce_call,
425 r->in.credential, r->out.return_authenticator,
427 NT_STATUS_NOT_OK_RETURN(nt_status);
429 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(dce_call->conn->dce_ctx->lp_ctx));
430 if (sam_ctx == NULL) {
431 return NT_STATUS_INVALID_SYSTEM_SERVICE;
434 memcpy(password_buf.data, r->in.new_password->data, 512);
435 SIVAL(password_buf.data, 512, r->in.new_password->length);
436 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
438 if (!extract_pw_from_buffer(mem_ctx, password_buf.data, &new_password)) {
439 DEBUG(3,("samr: failed to decode password buffer\n"));
440 return NT_STATUS_WRONG_PASSWORD;
443 /* Using the sid for the account as the key, set the password */
444 nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
446 &new_password, /* we have plaintext */
448 true, /* Password change */
457 static WERROR dcesrv_netr_LogonUasLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
458 struct netr_LogonUasLogon *r)
460 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
467 static WERROR dcesrv_netr_LogonUasLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
468 struct netr_LogonUasLogoff *r)
470 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
475 netr_LogonSamLogon_base
477 This version of the function allows other wrappers to say 'do not check the credentials'
479 We can't do the traditional 'wrapping' format completly, as this function must only run under schannel
481 static NTSTATUS dcesrv_netr_LogonSamLogon_base(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
482 struct netr_LogonSamLogonEx *r, struct netlogon_creds_CredentialState *creds)
484 struct auth_context *auth_context;
485 struct auth_usersupplied_info *user_info;
486 struct auth_serversupplied_info *server_info;
488 static const char zeros[16];
489 struct netr_SamBaseInfo *sam;
490 struct netr_SamInfo2 *sam2;
491 struct netr_SamInfo3 *sam3;
492 struct netr_SamInfo6 *sam6;
494 user_info = talloc(mem_ctx, struct auth_usersupplied_info);
495 NT_STATUS_HAVE_NO_MEMORY(user_info);
497 user_info->flags = 0;
498 user_info->mapped_state = false;
499 user_info->remote_host = NULL;
501 switch (r->in.logon_level) {
502 case NetlogonInteractiveInformation:
503 case NetlogonServiceInformation:
504 case NetlogonInteractiveTransitiveInformation:
505 case NetlogonServiceTransitiveInformation:
506 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
507 netlogon_creds_arcfour_crypt(creds,
508 r->in.logon->password->lmpassword.hash,
509 sizeof(r->in.logon->password->lmpassword.hash));
510 netlogon_creds_arcfour_crypt(creds,
511 r->in.logon->password->ntpassword.hash,
512 sizeof(r->in.logon->password->ntpassword.hash));
514 netlogon_creds_des_decrypt(creds, &r->in.logon->password->lmpassword);
515 netlogon_creds_des_decrypt(creds, &r->in.logon->password->ntpassword);
518 /* TODO: we need to deny anonymous access here */
519 nt_status = auth_context_create(mem_ctx,
520 dce_call->event_ctx, dce_call->msg_ctx,
521 dce_call->conn->dce_ctx->lp_ctx,
523 NT_STATUS_NOT_OK_RETURN(nt_status);
525 user_info->logon_parameters = r->in.logon->password->identity_info.parameter_control;
526 user_info->client.account_name = r->in.logon->password->identity_info.account_name.string;
527 user_info->client.domain_name = r->in.logon->password->identity_info.domain_name.string;
528 user_info->workstation_name = r->in.logon->password->identity_info.workstation.string;
530 user_info->flags |= USER_INFO_INTERACTIVE_LOGON;
531 user_info->password_state = AUTH_PASSWORD_HASH;
533 user_info->password.hash.lanman = talloc(user_info, struct samr_Password);
534 NT_STATUS_HAVE_NO_MEMORY(user_info->password.hash.lanman);
535 *user_info->password.hash.lanman = r->in.logon->password->lmpassword;
537 user_info->password.hash.nt = talloc(user_info, struct samr_Password);
538 NT_STATUS_HAVE_NO_MEMORY(user_info->password.hash.nt);
539 *user_info->password.hash.nt = r->in.logon->password->ntpassword;
542 case NetlogonNetworkInformation:
543 case NetlogonNetworkTransitiveInformation:
545 /* TODO: we need to deny anonymous access here */
546 nt_status = auth_context_create(mem_ctx,
547 dce_call->event_ctx, dce_call->msg_ctx,
548 dce_call->conn->dce_ctx->lp_ctx,
550 NT_STATUS_NOT_OK_RETURN(nt_status);
552 nt_status = auth_context_set_challenge(auth_context, r->in.logon->network->challenge, "netr_LogonSamLogonWithFlags");
553 NT_STATUS_NOT_OK_RETURN(nt_status);
555 user_info->logon_parameters = r->in.logon->network->identity_info.parameter_control;
556 user_info->client.account_name = r->in.logon->network->identity_info.account_name.string;
557 user_info->client.domain_name = r->in.logon->network->identity_info.domain_name.string;
558 user_info->workstation_name = r->in.logon->network->identity_info.workstation.string;
560 user_info->password_state = AUTH_PASSWORD_RESPONSE;
561 user_info->password.response.lanman = data_blob_talloc(mem_ctx, r->in.logon->network->lm.data, r->in.logon->network->lm.length);
562 user_info->password.response.nt = data_blob_talloc(mem_ctx, r->in.logon->network->nt.data, r->in.logon->network->nt.length);
567 case NetlogonGenericInformation:
569 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
570 netlogon_creds_arcfour_crypt(creds,
571 r->in.logon->generic->data, r->in.logon->generic->length);
573 /* Using DES to verify kerberos tickets makes no sense */
574 return NT_STATUS_INVALID_PARAMETER;
577 if (strcmp(r->in.logon->generic->package_name.string, "Kerberos") == 0) {
579 struct server_id *kdc;
580 struct kdc_check_generic_kerberos check;
581 struct netr_GenericInfo2 *generic = talloc_zero(mem_ctx, struct netr_GenericInfo2);
582 NT_STATUS_HAVE_NO_MEMORY(generic);
583 *r->out.authoritative = 1;
585 /* TODO: Describe and deal with these flags */
588 r->out.validation->generic = generic;
590 kdc = irpc_servers_byname(dce_call->msg_ctx, mem_ctx, "kdc_server");
591 if ((kdc == NULL) || (kdc[0].id == 0)) {
592 return NT_STATUS_NO_LOGON_SERVERS;
595 check.in.generic_request =
596 data_blob_const(r->in.logon->generic->data,
597 r->in.logon->generic->length);
599 status = irpc_call(dce_call->msg_ctx, kdc[0],
600 &ndr_table_irpc, NDR_KDC_CHECK_GENERIC_KERBEROS,
602 if (!NT_STATUS_IS_OK(status)) {
605 generic->length = check.out.generic_reply.length;
606 generic->data = check.out.generic_reply.data;
610 /* Until we get an implemetnation of these other packages */
611 return NT_STATUS_INVALID_PARAMETER;
614 return NT_STATUS_INVALID_PARAMETER;
617 nt_status = auth_check_password(auth_context, mem_ctx, user_info, &server_info);
618 NT_STATUS_NOT_OK_RETURN(nt_status);
620 switch (r->in.validation_level) {
622 nt_status = auth_convert_server_info_sambaseinfo(mem_ctx, server_info, &sam);
623 NT_STATUS_NOT_OK_RETURN(nt_status);
625 sam2 = talloc_zero(mem_ctx, struct netr_SamInfo2);
626 NT_STATUS_HAVE_NO_MEMORY(sam2);
629 /* And put into the talloc tree */
630 talloc_steal(sam2, sam);
631 r->out.validation->sam2 = sam2;
637 nt_status = auth_convert_server_info_saminfo3(mem_ctx,
640 NT_STATUS_NOT_OK_RETURN(nt_status);
642 r->out.validation->sam3 = sam3;
648 nt_status = auth_convert_server_info_saminfo3(mem_ctx,
651 NT_STATUS_NOT_OK_RETURN(nt_status);
653 sam6 = talloc_zero(mem_ctx, struct netr_SamInfo6);
654 NT_STATUS_HAVE_NO_MEMORY(sam6);
655 sam6->base = sam3->base;
657 sam6->sidcount = sam3->sidcount;
658 sam6->sids = sam3->sids;
660 sam6->dns_domainname.string = lp_dnsdomain(dce_call->conn->dce_ctx->lp_ctx);
661 sam6->principle.string = talloc_asprintf(mem_ctx, "%s@%s",
662 sam->account_name.string, sam6->dns_domainname.string);
663 NT_STATUS_HAVE_NO_MEMORY(sam6->principle.string);
664 /* And put into the talloc tree */
665 talloc_steal(sam6, sam3);
667 r->out.validation->sam6 = sam6;
674 /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
675 /* It appears that level 6 is not individually encrypted */
676 if ((r->in.validation_level != 6) &&
677 memcmp(sam->key.key, zeros, sizeof(sam->key.key)) != 0) {
678 /* This key is sent unencrypted without the ARCFOUR flag set */
679 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
680 netlogon_creds_arcfour_crypt(creds,
682 sizeof(sam->key.key));
686 /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
687 /* It appears that level 6 is not individually encrypted */
688 if ((r->in.validation_level != 6) &&
689 memcmp(sam->LMSessKey.key, zeros, sizeof(sam->LMSessKey.key)) != 0) {
690 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
691 netlogon_creds_arcfour_crypt(creds,
693 sizeof(sam->LMSessKey.key));
695 netlogon_creds_des_encrypt_LMKey(creds,
700 *r->out.authoritative = 1;
702 /* TODO: Describe and deal with these flags */
708 static NTSTATUS dcesrv_netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
709 struct netr_LogonSamLogonEx *r)
712 struct netlogon_creds_CredentialState *creds;
714 nt_status = schannel_get_creds_state(mem_ctx,
715 lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx),
716 lp_private_dir(dce_call->conn->dce_ctx->lp_ctx),
717 r->in.computer_name, &creds);
718 if (!NT_STATUS_IS_OK(nt_status)) {
722 if (!dce_call->conn->auth_state.auth_info ||
723 dce_call->conn->auth_state.auth_info->auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
724 return NT_STATUS_ACCESS_DENIED;
726 return dcesrv_netr_LogonSamLogon_base(dce_call, mem_ctx, r, creds);
730 netr_LogonSamLogonWithFlags
733 static NTSTATUS dcesrv_netr_LogonSamLogonWithFlags(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
734 struct netr_LogonSamLogonWithFlags *r)
737 struct netlogon_creds_CredentialState *creds;
738 struct netr_LogonSamLogonEx r2;
740 struct netr_Authenticator *return_authenticator;
742 return_authenticator = talloc(mem_ctx, struct netr_Authenticator);
743 NT_STATUS_HAVE_NO_MEMORY(return_authenticator);
745 nt_status = dcesrv_netr_creds_server_step_check(dce_call,
748 r->in.credential, return_authenticator,
750 NT_STATUS_NOT_OK_RETURN(nt_status);
754 r2.in.server_name = r->in.server_name;
755 r2.in.computer_name = r->in.computer_name;
756 r2.in.logon_level = r->in.logon_level;
757 r2.in.logon = r->in.logon;
758 r2.in.validation_level = r->in.validation_level;
759 r2.in.flags = r->in.flags;
760 r2.out.validation = r->out.validation;
761 r2.out.authoritative = r->out.authoritative;
762 r2.out.flags = r->out.flags;
764 nt_status = dcesrv_netr_LogonSamLogon_base(dce_call, mem_ctx, &r2, creds);
766 r->out.return_authenticator = return_authenticator;
774 static NTSTATUS dcesrv_netr_LogonSamLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
775 struct netr_LogonSamLogon *r)
777 struct netr_LogonSamLogonWithFlags r2;
783 r2.in.server_name = r->in.server_name;
784 r2.in.computer_name = r->in.computer_name;
785 r2.in.credential = r->in.credential;
786 r2.in.return_authenticator = r->in.return_authenticator;
787 r2.in.logon_level = r->in.logon_level;
788 r2.in.logon = r->in.logon;
789 r2.in.validation_level = r->in.validation_level;
790 r2.in.flags = &flags;
791 r2.out.validation = r->out.validation;
792 r2.out.authoritative = r->out.authoritative;
793 r2.out.flags = &flags;
795 status = dcesrv_netr_LogonSamLogonWithFlags(dce_call, mem_ctx, &r2);
797 r->out.return_authenticator = r2.out.return_authenticator;
806 static NTSTATUS dcesrv_netr_LogonSamLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
807 struct netr_LogonSamLogoff *r)
809 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
817 static NTSTATUS dcesrv_netr_DatabaseDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
818 struct netr_DatabaseDeltas *r)
820 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
827 static NTSTATUS dcesrv_netr_DatabaseSync2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
828 struct netr_DatabaseSync2 *r)
830 /* win2k3 native mode returns "NOT IMPLEMENTED" for this call */
831 return NT_STATUS_NOT_IMPLEMENTED;
838 static NTSTATUS dcesrv_netr_DatabaseSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
839 struct netr_DatabaseSync *r)
841 struct netr_DatabaseSync2 r2;
846 r2.in.logon_server = r->in.logon_server;
847 r2.in.computername = r->in.computername;
848 r2.in.credential = r->in.credential;
849 r2.in.database_id = r->in.database_id;
850 r2.in.restart_state = SYNCSTATE_NORMAL_STATE;
851 r2.in.sync_context = r->in.sync_context;
852 r2.out.sync_context = r->out.sync_context;
853 r2.out.delta_enum_array = r->out.delta_enum_array;
854 r2.in.preferredmaximumlength = r->in.preferredmaximumlength;
856 status = dcesrv_netr_DatabaseSync2(dce_call, mem_ctx, &r2);
865 static NTSTATUS dcesrv_netr_AccountDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
866 struct netr_AccountDeltas *r)
868 /* w2k3 returns "NOT IMPLEMENTED" for this call */
869 return NT_STATUS_NOT_IMPLEMENTED;
876 static NTSTATUS dcesrv_netr_AccountSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
877 struct netr_AccountSync *r)
879 /* w2k3 returns "NOT IMPLEMENTED" for this call */
880 return NT_STATUS_NOT_IMPLEMENTED;
887 static WERROR dcesrv_netr_GetDcName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
888 struct netr_GetDcName *r)
890 const char * const attrs[] = { NULL };
891 struct ldb_context *sam_ctx;
892 struct ldb_message **res;
893 struct ldb_dn *domain_dn;
897 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx,
898 dce_call->conn->dce_ctx->lp_ctx,
899 dce_call->conn->auth_state.session_info);
900 if (sam_ctx == NULL) {
901 return WERR_DS_UNAVAILABLE;
904 domain_dn = samdb_domain_to_dn(sam_ctx, mem_ctx,
906 if (domain_dn == NULL) {
907 return WERR_DS_UNAVAILABLE;
910 ret = gendb_search_dn(sam_ctx, mem_ctx,
911 domain_dn, &res, attrs);
913 return WERR_NO_SUCH_DOMAIN;
916 /* TODO: - return real IP address
917 * - check all r->in.* parameters (server_unc is ignored by w2k3!)
919 dcname = talloc_asprintf(mem_ctx, "\\\\%s",
920 lp_netbios_name(dce_call->conn->dce_ctx->lp_ctx));
921 W_ERROR_HAVE_NO_MEMORY(dcname);
923 *r->out.dcname = dcname;
931 static WERROR dcesrv_netr_LogonControl2Ex(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
932 struct netr_LogonControl2Ex *r)
934 return WERR_NOT_SUPPORTED;
941 static WERROR dcesrv_netr_LogonControl(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
942 struct netr_LogonControl *r)
944 struct netr_LogonControl2Ex r2;
947 if (r->in.level == 0x00000001) {
950 r2.in.logon_server = r->in.logon_server;
951 r2.in.function_code = r->in.function_code;
952 r2.in.level = r->in.level;
954 r2.out.query = r->out.query;
956 werr = dcesrv_netr_LogonControl2Ex(dce_call, mem_ctx, &r2);
957 } else if (r->in.level == 0x00000002) {
958 werr = WERR_NOT_SUPPORTED;
960 werr = WERR_UNKNOWN_LEVEL;
970 static WERROR dcesrv_netr_LogonControl2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
971 struct netr_LogonControl2 *r)
973 struct netr_LogonControl2Ex r2;
978 r2.in.logon_server = r->in.logon_server;
979 r2.in.function_code = r->in.function_code;
980 r2.in.level = r->in.level;
981 r2.in.data = r->in.data;
982 r2.out.query = r->out.query;
984 werr = dcesrv_netr_LogonControl2Ex(dce_call, mem_ctx, &r2);
993 static WERROR dcesrv_netr_GetAnyDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
994 struct netr_GetAnyDCName *r)
996 struct netr_GetDcName r2;
1001 r2.in.logon_server = r->in.logon_server;
1002 r2.in.domainname = r->in.domainname;
1003 r2.out.dcname = r->out.dcname;
1005 werr = dcesrv_netr_GetDcName(dce_call, mem_ctx, &r2);
1014 static NTSTATUS dcesrv_netr_DatabaseRedo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1015 struct netr_DatabaseRedo *r)
1017 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1022 netr_NetrEnumerateTurstedDomains
1024 static WERROR dcesrv_netr_NetrEnumerateTrustedDomains(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1025 struct netr_NetrEnumerateTrustedDomains *r)
1027 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1032 netr_LogonGetCapabilities
1034 static NTSTATUS dcesrv_netr_LogonGetCapabilities(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1035 struct netr_LogonGetCapabilities *r)
1037 /* we don't support AES yet */
1038 return NT_STATUS_NOT_IMPLEMENTED;
1043 netr_NETRLOGONSETSERVICEBITS
1045 static WERROR dcesrv_netr_NETRLOGONSETSERVICEBITS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1046 struct netr_NETRLOGONSETSERVICEBITS *r)
1048 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1053 netr_LogonGetTrustRid
1055 static WERROR dcesrv_netr_LogonGetTrustRid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1056 struct netr_LogonGetTrustRid *r)
1058 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1063 netr_NETRLOGONCOMPUTESERVERDIGEST
1065 static WERROR dcesrv_netr_NETRLOGONCOMPUTESERVERDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1066 struct netr_NETRLOGONCOMPUTESERVERDIGEST *r)
1068 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1073 netr_NETRLOGONCOMPUTECLIENTDIGEST
1075 static WERROR dcesrv_netr_NETRLOGONCOMPUTECLIENTDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1076 struct netr_NETRLOGONCOMPUTECLIENTDIGEST *r)
1078 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1086 static WERROR dcesrv_netr_DsRGetSiteName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1087 struct netr_DsRGetSiteName *r)
1089 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1094 fill in a netr_OneDomainInfo from a ldb search result
1096 static NTSTATUS fill_one_domain_info(TALLOC_CTX *mem_ctx,
1097 struct loadparm_context *lp_ctx,
1098 struct ldb_context *sam_ctx,
1099 struct ldb_message *res,
1100 struct netr_OneDomainInfo *info,
1101 bool is_local, bool is_trust_list)
1105 if (is_trust_list) {
1106 /* w2k8 only fills this on trusted domains */
1107 info->trust_extension.info = talloc_zero(mem_ctx, struct netr_trust_extension);
1108 info->trust_extension.length = 16;
1109 info->trust_extension.info->flags =
1110 NETR_TRUST_FLAG_TREEROOT |
1111 NETR_TRUST_FLAG_IN_FOREST |
1112 NETR_TRUST_FLAG_PRIMARY |
1113 NETR_TRUST_FLAG_NATIVE;
1115 info->trust_extension.info->parent_index = 0; /* should be index into array
1117 info->trust_extension.info->trust_type = LSA_TRUST_TYPE_UPLEVEL; /* should be based on ldb search for trusts */
1118 info->trust_extension.info->trust_attributes = 0; /* TODO: base on ldb search? */
1121 if (is_trust_list) {
1122 /* MS-NRPC 3.5.4.3.9 - must be set to NULL for trust list */
1123 info->dns_forestname.string = NULL;
1125 info->dns_forestname.string = samdb_forest_name(sam_ctx, mem_ctx);
1126 NT_STATUS_HAVE_NO_MEMORY(info->dns_forestname.string);
1127 info->dns_forestname.string = talloc_asprintf(mem_ctx, "%s.", info->dns_forestname.string);
1128 NT_STATUS_HAVE_NO_MEMORY(info->dns_forestname.string);
1132 info->domainname.string = lp_sam_name(lp_ctx);
1133 info->dns_domainname.string = lp_dnsdomain(lp_ctx);
1134 info->domain_guid = samdb_result_guid(res, "objectGUID");
1135 info->domain_sid = samdb_result_dom_sid(mem_ctx, res, "objectSid");
1137 info->domainname.string = samdb_result_string(res, "flatName", NULL);
1138 info->dns_domainname.string = samdb_result_string(res, "trustPartner", NULL);
1139 info->domain_guid = samdb_result_guid(res, "objectGUID");
1140 info->domain_sid = samdb_result_dom_sid(mem_ctx, res, "securityIdentifier");
1142 if (!is_trust_list) {
1143 info->dns_domainname.string = talloc_asprintf(mem_ctx, "%s.", info->dns_domainname.string);
1146 return NT_STATUS_OK;
1150 netr_LogonGetDomainInfo
1151 this is called as part of the ADS domain logon procedure.
1153 It has an important role in convaying details about the client, such
1154 as Operating System, Version, Service Pack etc.
1156 static NTSTATUS dcesrv_netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_call,
1157 TALLOC_CTX *mem_ctx, struct netr_LogonGetDomainInfo *r)
1159 struct netlogon_creds_CredentialState *creds;
1160 const char * const attrs[] = { "objectSid", "objectGUID", "flatName",
1161 "securityIdentifier", "trustPartner", NULL };
1162 const char * const attrs2[] = { "dNSHostName",
1163 "msDS-SupportedEncryptionTypes", NULL };
1164 const char * const attrs3[] = { NULL };
1165 const char *temp_str, *temp_str2;
1166 const char *old_dns_hostname;
1167 struct ldb_context *sam_ctx;
1168 struct ldb_message **res0, **res1, **res2, **res3, *new_msg;
1169 struct ldb_dn *workstation_dn;
1170 struct netr_DomainInformation *domain_info;
1171 struct netr_LsaPolicyInformation *lsa_policy_info;
1172 struct netr_OsVersionInfoEx *os_version;
1173 uint32_t default_supported_enc_types = 0xFFFFFFFF;
1174 bool update_dns_hostname = true;
1178 status = dcesrv_netr_creds_server_step_check(dce_call,
1180 r->in.computer_name,
1182 r->out.return_authenticator,
1184 if (!NT_STATUS_IS_OK(status)) {
1185 DEBUG(0,(__location__ " Bad credentials - error\n"));
1187 NT_STATUS_NOT_OK_RETURN(status);
1189 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx,
1190 dce_call->conn->dce_ctx->lp_ctx,
1191 system_session(dce_call->conn->dce_ctx->lp_ctx));
1192 if (sam_ctx == NULL) {
1193 return NT_STATUS_INVALID_SYSTEM_SERVICE;
1196 switch (r->in.level) {
1197 case 1: /* Domain information */
1200 * Updates the DNS hostname when the client wishes that the
1201 * server should handle this for him
1202 * ("NETR_WS_FLAG_HANDLES_SPN_UPDATE" not set).
1203 * See MS-NRPC section 3.5.4.3.9
1205 if ((r->in.query->workstation_info->workstation_flags
1206 & NETR_WS_FLAG_HANDLES_SPN_UPDATE) != 0) {
1207 update_dns_hostname = false;
1211 * Checks that the computer name parameter without possible "$"
1212 * matches as prefix with the DNS hostname in the workstation
1215 temp_str = talloc_strndup(mem_ctx,
1216 r->in.computer_name,
1217 strcspn(r->in.computer_name, "$"));
1218 NT_STATUS_HAVE_NO_MEMORY(temp_str);
1219 temp_str2 = talloc_strndup(mem_ctx,
1220 r->in.query->workstation_info->dns_hostname,
1221 strcspn(r->in.query->workstation_info->dns_hostname, "."));
1222 NT_STATUS_HAVE_NO_MEMORY(temp_str2);
1223 if (strcasecmp(temp_str, temp_str2) != 0) {
1224 update_dns_hostname = false;
1228 * Check that the DNS hostname when it should be updated
1229 * will be used only by maximum one host.
1231 ret = gendb_search(sam_ctx, mem_ctx,
1232 ldb_get_default_basedn(sam_ctx),
1233 &res0, attrs3, "(dNSHostName=%s)",
1234 r->in.query->workstation_info->dns_hostname);
1236 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1239 update_dns_hostname = false;
1244 /* Prepare the workstation DN */
1245 workstation_dn = ldb_dn_new_fmt(mem_ctx, sam_ctx, "<SID=%s>",
1246 dom_sid_string(mem_ctx, creds->sid));
1247 NT_STATUS_HAVE_NO_MEMORY(workstation_dn);
1249 /* Lookup for attributes in workstation object */
1250 ret = gendb_search_dn(sam_ctx, mem_ctx, workstation_dn,
1253 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1256 /* Gets the old DNS hostname */
1257 old_dns_hostname = samdb_result_string(res1[0], "dNSHostName",
1260 /* Gets host informations and put them in our directory */
1261 new_msg = ldb_msg_new(mem_ctx);
1262 NT_STATUS_HAVE_NO_MEMORY(new_msg);
1264 new_msg->dn = workstation_dn;
1266 /* Deletes old OS version values */
1267 samdb_msg_add_delete(sam_ctx, mem_ctx, new_msg,
1268 "operatingSystemServicePack");
1269 samdb_msg_add_delete(sam_ctx, mem_ctx, new_msg,
1270 "operatingSystemVersion");
1272 if (dsdb_replace(sam_ctx, new_msg, 0) != LDB_SUCCESS) {
1273 DEBUG(3,("Impossible to update samdb: %s\n",
1274 ldb_errstring(sam_ctx)));
1277 talloc_free(new_msg);
1279 new_msg = ldb_msg_new(mem_ctx);
1280 NT_STATUS_HAVE_NO_MEMORY(new_msg);
1282 new_msg->dn = workstation_dn;
1284 /* Sets the OS name */
1285 samdb_msg_set_string(sam_ctx, mem_ctx, new_msg,
1287 r->in.query->workstation_info->os_name.string);
1290 * Sets informations from "os_version". On a empty structure
1291 * the values are cleared.
1293 if (r->in.query->workstation_info->os_version.os != NULL) {
1294 os_version = &r->in.query->workstation_info->os_version.os->os;
1296 samdb_msg_set_string(sam_ctx, mem_ctx, new_msg,
1297 "operatingSystemServicePack",
1298 os_version->CSDVersion);
1300 samdb_msg_set_string(sam_ctx, mem_ctx, new_msg,
1301 "operatingSystemVersion",
1302 talloc_asprintf(mem_ctx, "%d.%d (%d)",
1303 os_version->MajorVersion,
1304 os_version->MinorVersion,
1305 os_version->BuildNumber
1311 * If the boolean "update_dns_hostname" remained true, then we
1312 * are fine to start the update.
1314 if (update_dns_hostname) {
1315 samdb_msg_set_string(sam_ctx, mem_ctx, new_msg,
1317 r->in.query->workstation_info->dns_hostname);
1319 samdb_msg_add_string(sam_ctx, mem_ctx, new_msg,
1320 "servicePrincipalName",
1321 talloc_asprintf(mem_ctx, "HOST/%s",
1322 r->in.computer_name)
1324 samdb_msg_add_string(sam_ctx, mem_ctx, new_msg,
1325 "servicePrincipalName",
1326 talloc_asprintf(mem_ctx, "HOST/%s",
1327 r->in.query->workstation_info->dns_hostname)
1331 if (dsdb_replace(sam_ctx, new_msg, 0) != LDB_SUCCESS) {
1332 DEBUG(3,("Impossible to update samdb: %s\n",
1333 ldb_errstring(sam_ctx)));
1336 talloc_free(new_msg);
1338 /* Writes back the domain information */
1340 /* We need to do two searches. The first will pull our primary
1341 domain and the second will pull any trusted domains. Our
1342 primary domain is also a "trusted" domain, so we need to
1343 put the primary domain into the lists of returned trusts as
1345 ret = gendb_search_dn(sam_ctx, mem_ctx, ldb_get_default_basedn(sam_ctx),
1348 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1351 ret3 = gendb_search(sam_ctx, mem_ctx, NULL, &res3, attrs,
1352 "(objectClass=trustedDomain)");
1354 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1357 domain_info = talloc(mem_ctx, struct netr_DomainInformation);
1358 NT_STATUS_HAVE_NO_MEMORY(domain_info);
1360 ZERO_STRUCTP(domain_info);
1362 /* Informations about the local and trusted domains */
1364 status = fill_one_domain_info(mem_ctx,
1365 dce_call->conn->dce_ctx->lp_ctx,
1366 sam_ctx, res2[0], &domain_info->primary_domain,
1368 NT_STATUS_NOT_OK_RETURN(status);
1370 domain_info->trusted_domain_count = ret3 + 1;
1371 domain_info->trusted_domains = talloc_array(mem_ctx,
1372 struct netr_OneDomainInfo,
1373 domain_info->trusted_domain_count);
1374 NT_STATUS_HAVE_NO_MEMORY(domain_info->trusted_domains);
1376 for (i=0;i<ret3;i++) {
1377 status = fill_one_domain_info(mem_ctx,
1378 dce_call->conn->dce_ctx->lp_ctx,
1380 &domain_info->trusted_domains[i],
1382 NT_STATUS_NOT_OK_RETURN(status);
1385 status = fill_one_domain_info(mem_ctx,
1386 dce_call->conn->dce_ctx->lp_ctx, sam_ctx, res2[0],
1387 &domain_info->trusted_domains[i], true, true);
1388 NT_STATUS_NOT_OK_RETURN(status);
1390 /* Sets the supported encryption types */
1391 domain_info->supported_enc_types = samdb_result_uint(res1[0],
1392 "msDS-SupportedEncryptionTypes",
1393 default_supported_enc_types);
1395 /* Other host domain informations */
1397 lsa_policy_info = talloc(mem_ctx,
1398 struct netr_LsaPolicyInformation);
1399 NT_STATUS_HAVE_NO_MEMORY(lsa_policy_info);
1400 ZERO_STRUCTP(lsa_policy_info);
1402 domain_info->lsa_policy = *lsa_policy_info;
1404 /* The DNS hostname is only returned back when there is a chance
1406 if ((r->in.query->workstation_info->workstation_flags
1407 & NETR_WS_FLAG_HANDLES_SPN_UPDATE) != 0) {
1408 domain_info->dns_hostname.string = old_dns_hostname;
1410 domain_info->dns_hostname.string = NULL;
1413 domain_info->workstation_flags =
1414 r->in.query->workstation_info->workstation_flags;
1416 r->out.info->domain_info = domain_info;
1418 case 2: /* LSA policy information - not used at the moment */
1419 lsa_policy_info = talloc(mem_ctx,
1420 struct netr_LsaPolicyInformation);
1421 NT_STATUS_HAVE_NO_MEMORY(lsa_policy_info);
1422 ZERO_STRUCTP(lsa_policy_info);
1424 r->out.info->lsa_policy_info = lsa_policy_info;
1427 return NT_STATUS_INVALID_LEVEL;
1431 return NT_STATUS_OK;
1437 netr_ServerPasswordGet
1439 static WERROR dcesrv_netr_ServerPasswordGet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1440 struct netr_ServerPasswordGet *r)
1442 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1447 netr_NETRLOGONSENDTOSAM
1449 static WERROR dcesrv_netr_NETRLOGONSENDTOSAM(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1450 struct netr_NETRLOGONSENDTOSAM *r)
1452 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1457 netr_DsRAddressToSitenamesW
1459 static WERROR dcesrv_netr_DsRAddressToSitenamesW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1460 struct netr_DsRAddressToSitenamesW *r)
1462 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1467 netr_DsRGetDCNameEx2
1469 static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call,
1470 TALLOC_CTX *mem_ctx,
1471 struct netr_DsRGetDCNameEx2 *r)
1473 const char * const attrs[] = { "objectGUID", NULL };
1474 struct ldb_context *sam_ctx;
1475 struct ldb_message **res;
1476 struct ldb_dn *domain_dn;
1478 struct netr_DsRGetDCNameInfo *info;
1479 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
1481 ZERO_STRUCTP(r->out.info);
1483 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, lp_ctx,
1484 dce_call->conn->auth_state.session_info);
1485 if (sam_ctx == NULL) {
1486 return WERR_DS_UNAVAILABLE;
1489 /* Windows 7 sends the domain name in the form the user typed, so we
1490 * have to cope with both the short and long form here */
1491 if (r->in.domain_name != NULL &&
1492 !lp_is_my_domain_or_realm(lp_ctx, r->in.domain_name)) {
1493 return WERR_NO_SUCH_DOMAIN;
1496 domain_dn = ldb_get_default_basedn(sam_ctx);
1497 if (domain_dn == NULL) {
1498 return WERR_DS_UNAVAILABLE;
1501 ret = gendb_search_dn(sam_ctx, mem_ctx,
1502 domain_dn, &res, attrs);
1504 return WERR_GENERAL_FAILURE;
1507 info = talloc(mem_ctx, struct netr_DsRGetDCNameInfo);
1508 W_ERROR_HAVE_NO_MEMORY(info);
1510 /* TODO: - return real IP address
1511 * - check all r->in.* parameters
1512 * (server_unc is ignored by w2k3!)
1514 info->dc_unc = talloc_asprintf(mem_ctx, "\\\\%s.%s",
1515 lp_netbios_name(lp_ctx),
1516 lp_dnsdomain(lp_ctx));
1517 W_ERROR_HAVE_NO_MEMORY(info->dc_unc);
1519 info->dc_address = talloc_strdup(mem_ctx, "\\\\0.0.0.0");
1520 W_ERROR_HAVE_NO_MEMORY(info->dc_address);
1522 info->dc_address_type = DS_ADDRESS_TYPE_INET;
1523 info->domain_guid = samdb_result_guid(res[0], "objectGUID");
1524 info->domain_name = lp_dnsdomain(lp_ctx);
1525 info->forest_name = samdb_forest_name(sam_ctx, mem_ctx);
1526 W_ERROR_HAVE_NO_MEMORY(info->forest_name);
1527 info->dc_flags = DS_DNS_FOREST_ROOT |
1530 DS_SERVER_WRITABLE |
1532 DS_SERVER_TIMESERV |
1539 info->dc_site_name = samdb_server_site_name(sam_ctx, mem_ctx);
1540 W_ERROR_HAVE_NO_MEMORY(info->dc_site_name);
1542 /* FIXME: Hardcoded site name */
1543 info->client_site_name = talloc_strdup(mem_ctx,
1544 "Default-First-Site-Name");
1545 W_ERROR_HAVE_NO_MEMORY(info->client_site_name);
1547 *r->out.info = info;
1555 static WERROR dcesrv_netr_DsRGetDCNameEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1556 struct netr_DsRGetDCNameEx *r)
1558 struct netr_DsRGetDCNameEx2 r2;
1563 r2.in.server_unc = r->in.server_unc;
1564 r2.in.client_account = NULL;
1566 r2.in.domain_guid = r->in.domain_guid;
1567 r2.in.domain_name = r->in.domain_name;
1568 r2.in.site_name = r->in.site_name;
1569 r2.in.flags = r->in.flags;
1570 r2.out.info = r->out.info;
1572 werr = dcesrv_netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1580 static WERROR dcesrv_netr_DsRGetDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1581 struct netr_DsRGetDCName *r)
1583 struct netr_DsRGetDCNameEx2 r2;
1588 r2.in.server_unc = r->in.server_unc;
1589 r2.in.client_account = NULL;
1591 r2.in.domain_name = r->in.domain_name;
1592 r2.in.domain_guid = r->in.domain_guid;
1594 r2.in.site_name = NULL; /* should fill in from site GUID */
1595 r2.in.flags = r->in.flags;
1596 r2.out.info = r->out.info;
1598 werr = dcesrv_netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1603 netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN
1605 static WERROR dcesrv_netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1606 struct netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN *r)
1608 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1613 netr_NetrEnumerateTrustedDomainsEx
1615 static WERROR dcesrv_netr_NetrEnumerateTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1616 struct netr_NetrEnumerateTrustedDomainsEx *r)
1618 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1623 netr_DsRAddressToSitenamesExW
1625 static WERROR dcesrv_netr_DsRAddressToSitenamesExW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1626 struct netr_DsRAddressToSitenamesExW *r)
1628 struct netr_DsRAddressToSitenamesExWCtr *ctr;
1631 /* we should map the provided IPs to site names, once we have
1634 ctr = talloc(mem_ctx, struct netr_DsRAddressToSitenamesExWCtr);
1635 W_ERROR_HAVE_NO_MEMORY(ctr);
1639 ctr->count = r->in.count;
1640 ctr->sitename = talloc_array(ctr, struct lsa_String, ctr->count);
1641 W_ERROR_HAVE_NO_MEMORY(ctr->sitename);
1642 ctr->subnetname = talloc_array(ctr, struct lsa_String, ctr->count);
1643 W_ERROR_HAVE_NO_MEMORY(ctr->subnetname);
1645 for (i=0; i<ctr->count; i++) {
1646 /* FIXME: Hardcoded site name */
1647 ctr->sitename[i].string = "Default-First-Site-Name";
1648 ctr->subnetname[i].string = NULL;
1656 netr_DsrGetDcSiteCoverageW
1658 static WERROR dcesrv_netr_DsrGetDcSiteCoverageW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1659 struct netr_DsrGetDcSiteCoverageW *r)
1661 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1665 #define GET_CHECK_STR(dest, mem, msg, attr) \
1668 s = samdb_result_string(msg, attr, NULL); \
1670 DEBUG(0, ("DB Error, TustedDomain entry (%s) " \
1671 "without flatname\n", \
1672 ldb_dn_get_linearized(msg->dn))); \
1675 dest = talloc_strdup(mem, s); \
1676 W_ERROR_HAVE_NO_MEMORY(dest); \
1680 static WERROR fill_trusted_domains_array(TALLOC_CTX *mem_ctx,
1681 struct ldb_context *sam_ctx,
1682 struct netr_DomainTrustList *trusts,
1683 uint32_t trust_flags)
1685 struct ldb_dn *system_dn;
1686 struct ldb_message **dom_res = NULL;
1687 const char *trust_attrs[] = { "flatname", "trustPartner",
1688 "securityIdentifier", "trustDirection",
1689 "trustType", "trustAttributes", NULL };
1693 if (!(trust_flags & (NETR_TRUST_FLAG_INBOUND |
1694 NETR_TRUST_FLAG_OUTBOUND))) {
1695 return WERR_INVALID_FLAGS;
1698 system_dn = samdb_search_dn(sam_ctx, mem_ctx,
1699 ldb_get_default_basedn(sam_ctx),
1700 "(&(objectClass=container)(cn=System))");
1702 return WERR_GENERAL_FAILURE;
1705 ret = gendb_search(sam_ctx, mem_ctx, system_dn,
1706 &dom_res, trust_attrs,
1707 "(objectclass=trustedDomain)");
1709 for (i = 0; i < ret; i++) {
1710 unsigned int trust_dir;
1713 trust_dir = samdb_result_uint(dom_res[i],
1714 "trustDirection", 0);
1716 if (trust_dir & LSA_TRUST_DIRECTION_INBOUND) {
1717 flags |= NETR_TRUST_FLAG_INBOUND;
1719 if (trust_dir & LSA_TRUST_DIRECTION_OUTBOUND) {
1720 flags |= NETR_TRUST_FLAG_OUTBOUND;
1723 if (!(flags & trust_flags)) {
1724 /* this trust direction was not requested */
1729 trusts->array = talloc_realloc(trusts, trusts->array,
1730 struct netr_DomainTrust,
1732 W_ERROR_HAVE_NO_MEMORY(trusts->array);
1734 GET_CHECK_STR(trusts->array[n].netbios_name, trusts,
1735 dom_res[i], "flatname");
1736 GET_CHECK_STR(trusts->array[n].dns_name, trusts,
1737 dom_res[i], "trustPartner");
1739 trusts->array[n].trust_flags = flags;
1740 if ((trust_flags & NETR_TRUST_FLAG_IN_FOREST) &&
1741 !(flags & NETR_TRUST_FLAG_TREEROOT)) {
1742 /* TODO: find if we have parent in the list */
1743 trusts->array[n].parent_index = 0;
1746 trusts->array[n].trust_type =
1747 samdb_result_uint(dom_res[i],
1749 trusts->array[n].trust_attributes =
1750 samdb_result_uint(dom_res[i],
1751 "trustAttributes", 0);
1753 if ((trusts->array[n].trust_type == NETR_TRUST_TYPE_MIT) ||
1754 (trusts->array[n].trust_type == NETR_TRUST_TYPE_DCE)) {
1755 struct dom_sid zero_sid;
1756 ZERO_STRUCT(zero_sid);
1757 trusts->array[n].sid =
1758 dom_sid_dup(trusts, &zero_sid);
1760 trusts->array[n].sid =
1761 samdb_result_dom_sid(trusts, dom_res[i],
1762 "securityIdentifier");
1764 trusts->array[n].guid = GUID_zero();
1766 trusts->count = n + 1;
1769 talloc_free(dom_res);
1774 netr_DsrEnumerateDomainTrusts
1776 static WERROR dcesrv_netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce_call,
1777 TALLOC_CTX *mem_ctx,
1778 struct netr_DsrEnumerateDomainTrusts *r)
1780 struct netr_DomainTrustList *trusts;
1781 struct ldb_context *sam_ctx;
1783 struct ldb_message **dom_res;
1784 const char * const dom_attrs[] = { "objectSid", "objectGUID", NULL };
1785 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
1786 const char *dnsdomain = lp_dnsdomain(lp_ctx);
1790 if (r->in.trust_flags & 0xFFFFFE00) {
1791 return WERR_INVALID_FLAGS;
1794 /* TODO: turn to hard check once we are sure this is 100% correct */
1795 if (!r->in.server_name) {
1796 DEBUG(3, ("Invalid domain! Expected name in domain [%s]. "
1797 "But received NULL!\n", dnsdomain));
1799 p = strchr(r->in.server_name, '.');
1801 DEBUG(3, ("Invalid domain! Expected name in domain "
1802 "[%s]. But received [%s]!\n",
1803 dnsdomain, r->in.server_name));
1804 p = r->in.server_name;
1808 if (strcasecmp(p, dnsdomain)) {
1809 DEBUG(3, ("Invalid domain! Expected name in domain "
1810 "[%s]. But received [%s]!\n",
1811 dnsdomain, r->in.server_name));
1815 trusts = talloc_zero(mem_ctx, struct netr_DomainTrustList);
1816 W_ERROR_HAVE_NO_MEMORY(trusts);
1819 r->out.trusts = trusts;
1821 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, lp_ctx,
1822 dce_call->conn->auth_state.session_info);
1823 if (sam_ctx == NULL) {
1824 return WERR_GENERAL_FAILURE;
1827 if ((r->in.trust_flags & NETR_TRUST_FLAG_INBOUND) ||
1828 (r->in.trust_flags & NETR_TRUST_FLAG_OUTBOUND)) {
1830 werr = fill_trusted_domains_array(mem_ctx, sam_ctx,
1831 trusts, r->in.trust_flags);
1832 W_ERROR_NOT_OK_RETURN(werr);
1835 /* NOTE: we currently are always the root of the forest */
1836 if (r->in.trust_flags & NETR_TRUST_FLAG_IN_FOREST) {
1837 int n = trusts->count;
1839 ret = gendb_search_dn(sam_ctx, mem_ctx, NULL,
1840 &dom_res, dom_attrs);
1842 return WERR_GENERAL_FAILURE;
1845 trusts->count = n + 1;
1846 trusts->array = talloc_realloc(trusts, trusts->array,
1847 struct netr_DomainTrust,
1849 W_ERROR_HAVE_NO_MEMORY(trusts->array);
1851 trusts->array[n].netbios_name = lp_workgroup(lp_ctx);
1852 trusts->array[n].dns_name = lp_dnsdomain(lp_ctx);
1853 trusts->array[n].trust_flags =
1854 NETR_TRUST_FLAG_NATIVE |
1855 NETR_TRUST_FLAG_TREEROOT |
1856 NETR_TRUST_FLAG_IN_FOREST |
1857 NETR_TRUST_FLAG_PRIMARY;
1858 /* we are always the root domain for now */
1859 trusts->array[n].parent_index = 0;
1860 trusts->array[n].trust_type = NETR_TRUST_TYPE_UPLEVEL;
1861 trusts->array[n].trust_attributes = 0;
1862 trusts->array[n].sid = samdb_result_dom_sid(mem_ctx,
1865 trusts->array[n].guid = samdb_result_guid(dom_res[0],
1867 talloc_free(dom_res);
1875 netr_DsrDeregisterDNSHostRecords
1877 static WERROR dcesrv_netr_DsrDeregisterDNSHostRecords(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1878 struct netr_DsrDeregisterDNSHostRecords *r)
1880 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1885 netr_ServerTrustPasswordsGet
1887 static NTSTATUS dcesrv_netr_ServerTrustPasswordsGet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1888 struct netr_ServerTrustPasswordsGet *r)
1890 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1894 static WERROR fill_forest_trust_array(TALLOC_CTX *mem_ctx,
1895 struct ldb_context *sam_ctx,
1896 struct loadparm_context *lp_ctx,
1897 struct lsa_ForestTrustInformation *info)
1899 struct lsa_ForestTrustDomainInfo *domain_info;
1900 struct lsa_ForestTrustRecord *e;
1901 struct ldb_message **dom_res;
1902 const char * const dom_attrs[] = { "objectSid", NULL };
1905 /* we need to provide 2 entries:
1906 * 1. the Root Forest name
1907 * 2. the Domain Information
1911 info->entries = talloc_array(info, struct lsa_ForestTrustRecord *, 2);
1912 W_ERROR_HAVE_NO_MEMORY(info->entries);
1914 /* Forest root info */
1915 e = talloc(info, struct lsa_ForestTrustRecord);
1916 W_ERROR_HAVE_NO_MEMORY(e);
1919 e->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME;
1920 e->time = 0; /* so far always 0 in trces. */
1921 e->forest_trust_data.top_level_name.string = samdb_forest_name(sam_ctx,
1923 W_ERROR_HAVE_NO_MEMORY(e->forest_trust_data.top_level_name.string);
1925 info->entries[0] = e;
1928 e = talloc(info, struct lsa_ForestTrustRecord);
1929 W_ERROR_HAVE_NO_MEMORY(e);
1931 /* get our own domain info */
1932 ret = gendb_search_dn(sam_ctx, mem_ctx, NULL, &dom_res, dom_attrs);
1934 return WERR_GENERAL_FAILURE;
1937 /* TODO: check if disabled and set flags accordingly */
1939 e->type = LSA_FOREST_TRUST_DOMAIN_INFO;
1940 e->time = 0; /* so far always 0 in traces. */
1942 domain_info = &e->forest_trust_data.domain_info;
1943 domain_info->domain_sid = samdb_result_dom_sid(info, dom_res[0],
1945 domain_info->dns_domain_name.string = lp_dnsdomain(lp_ctx);
1946 domain_info->netbios_domain_name.string = lp_workgroup(lp_ctx);
1948 info->entries[1] = e;
1950 talloc_free(dom_res);
1956 netr_DsRGetForestTrustInformation
1958 static WERROR dcesrv_netr_DsRGetForestTrustInformation(struct dcesrv_call_state *dce_call,
1959 TALLOC_CTX *mem_ctx,
1960 struct netr_DsRGetForestTrustInformation *r)
1962 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
1963 struct lsa_ForestTrustInformation *info, **info_ptr;
1964 struct ldb_context *sam_ctx;
1967 if (lp_server_role(lp_ctx) != ROLE_DOMAIN_CONTROLLER) {
1968 return WERR_CALL_NOT_IMPLEMENTED;
1971 if (r->in.flags & 0xFFFFFFFE) {
1972 return WERR_INVALID_FLAGS;
1975 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, lp_ctx,
1976 dce_call->conn->auth_state.session_info);
1977 if (sam_ctx == NULL) {
1978 return WERR_GENERAL_FAILURE;
1981 if (r->in.flags & DS_GFTI_UPDATE_TDO) {
1982 if (!samdb_is_pdc(sam_ctx)) {
1983 return WERR_NERR_NOTPRIMARY;
1986 if (r->in.trusted_domain_name == NULL) {
1987 return WERR_INVALID_FLAGS;
1990 /* TODO: establish an schannel connection with
1991 * r->in.trusted_domain_name and perform a
1992 * netr_GetForestTrustInformation call against it */
1994 /* for now return not implementd */
1995 return WERR_CALL_NOT_IMPLEMENTED;
1998 /* TODO: check r->in.server_name is our name */
2000 info_ptr = talloc(mem_ctx, struct lsa_ForestTrustInformation *);
2001 W_ERROR_HAVE_NO_MEMORY(info_ptr);
2003 info = talloc_zero(info_ptr, struct lsa_ForestTrustInformation);
2004 W_ERROR_HAVE_NO_MEMORY(info);
2006 werr = fill_forest_trust_array(mem_ctx, sam_ctx, lp_ctx, info);
2007 W_ERROR_NOT_OK_RETURN(werr);
2010 r->out.forest_trust_info = info_ptr;
2017 netr_GetForestTrustInformation
2019 static NTSTATUS dcesrv_netr_GetForestTrustInformation(struct dcesrv_call_state *dce_call,
2020 TALLOC_CTX *mem_ctx,
2021 struct netr_GetForestTrustInformation *r)
2023 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
2024 struct netlogon_creds_CredentialState *creds;
2025 struct lsa_ForestTrustInformation *info, **info_ptr;
2026 struct ldb_context *sam_ctx;
2030 if (lp_server_role(lp_ctx) != ROLE_DOMAIN_CONTROLLER) {
2031 return NT_STATUS_NOT_IMPLEMENTED;
2034 status = dcesrv_netr_creds_server_step_check(dce_call,
2036 r->in.computer_name,
2038 r->out.return_authenticator,
2040 if (!NT_STATUS_IS_OK(status)) {
2044 if ((creds->secure_channel_type != SEC_CHAN_DNS_DOMAIN) &&
2045 (creds->secure_channel_type != SEC_CHAN_DOMAIN)) {
2046 return NT_STATUS_NOT_IMPLEMENTED;
2049 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, lp_ctx,
2050 dce_call->conn->auth_state.session_info);
2051 if (sam_ctx == NULL) {
2052 return NT_STATUS_UNSUCCESSFUL;
2055 /* TODO: check r->in.server_name is our name */
2057 info_ptr = talloc(mem_ctx, struct lsa_ForestTrustInformation *);
2059 return NT_STATUS_NO_MEMORY;
2061 info = talloc_zero(info_ptr, struct lsa_ForestTrustInformation);
2063 return NT_STATUS_NO_MEMORY;
2066 werr = fill_forest_trust_array(mem_ctx, sam_ctx, lp_ctx, info);
2067 if (!W_ERROR_IS_OK(werr)) {
2068 return werror_to_ntstatus(werr);
2072 r->out.forest_trust_info = info_ptr;
2074 return NT_STATUS_OK;
2079 netr_ServerGetTrustInfo
2081 static NTSTATUS dcesrv_netr_ServerGetTrustInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2082 struct netr_ServerGetTrustInfo *r)
2084 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2088 /* include the generated boilerplate */
2089 #include "librpc/gen_ndr/ndr_netlogon_s.c"