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;
1126 /* TODO: we need a common function for pulling the forest */
1127 info->dns_forestname.string = ldb_dn_canonical_string(info, ldb_get_root_basedn(sam_ctx));
1128 if (!info->dns_forestname.string) {
1129 return NT_STATUS_NO_SUCH_DOMAIN;
1131 p = strchr(info->dns_forestname.string, '/');
1135 info->dns_forestname.string = talloc_asprintf(mem_ctx, "%s.", info->dns_forestname.string);
1140 info->domainname.string = lp_sam_name(lp_ctx);
1141 info->dns_domainname.string = lp_dnsdomain(lp_ctx);
1142 info->domain_guid = samdb_result_guid(res, "objectGUID");
1143 info->domain_sid = samdb_result_dom_sid(mem_ctx, res, "objectSid");
1145 info->domainname.string = samdb_result_string(res, "flatName", NULL);
1146 info->dns_domainname.string = samdb_result_string(res, "trustPartner", NULL);
1147 info->domain_guid = samdb_result_guid(res, "objectGUID");
1148 info->domain_sid = samdb_result_dom_sid(mem_ctx, res, "securityIdentifier");
1150 if (!is_trust_list) {
1151 info->dns_domainname.string = talloc_asprintf(mem_ctx, "%s.", info->dns_domainname.string);
1154 return NT_STATUS_OK;
1158 netr_LogonGetDomainInfo
1159 this is called as part of the ADS domain logon procedure.
1161 It has an important role in convaying details about the client, such
1162 as Operating System, Version, Service Pack etc.
1164 static NTSTATUS dcesrv_netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_call,
1165 TALLOC_CTX *mem_ctx, struct netr_LogonGetDomainInfo *r)
1167 struct netlogon_creds_CredentialState *creds;
1168 const char * const attrs[] = { "objectSid", "objectGUID", "flatName",
1169 "securityIdentifier", "trustPartner", NULL };
1170 const char * const attrs2[] = { "dNSHostName",
1171 "msDS-SupportedEncryptionTypes", NULL };
1172 const char * const attrs3[] = { NULL };
1173 const char *temp_str, *temp_str2;
1174 const char *old_dns_hostname;
1175 struct ldb_context *sam_ctx;
1176 struct ldb_message **res0, **res1, **res2, **res3, *new_msg;
1177 struct ldb_dn *workstation_dn;
1178 struct netr_DomainInformation *domain_info;
1179 struct netr_LsaPolicyInformation *lsa_policy_info;
1180 struct netr_OsVersionInfoEx *os_version;
1181 uint32_t default_supported_enc_types = 0xFFFFFFFF;
1182 bool update_dns_hostname = true;
1186 status = dcesrv_netr_creds_server_step_check(dce_call,
1188 r->in.computer_name,
1190 r->out.return_authenticator,
1192 if (!NT_STATUS_IS_OK(status)) {
1193 DEBUG(0,(__location__ " Bad credentials - error\n"));
1195 NT_STATUS_NOT_OK_RETURN(status);
1197 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx,
1198 dce_call->conn->dce_ctx->lp_ctx,
1199 system_session(dce_call->conn->dce_ctx->lp_ctx));
1200 if (sam_ctx == NULL) {
1201 return NT_STATUS_INVALID_SYSTEM_SERVICE;
1204 switch (r->in.level) {
1205 case 1: /* Domain information */
1208 * Updates the DNS hostname when the client wishes that the
1209 * server should handle this for him
1210 * ("NETR_WS_FLAG_HANDLES_SPN_UPDATE" not set).
1211 * See MS-NRPC section 3.5.4.3.9
1213 if ((r->in.query->workstation_info->workstation_flags
1214 & NETR_WS_FLAG_HANDLES_SPN_UPDATE) != 0) {
1215 update_dns_hostname = false;
1219 * Checks that the computer name parameter without possible "$"
1220 * matches as prefix with the DNS hostname in the workstation
1223 temp_str = talloc_strndup(mem_ctx,
1224 r->in.computer_name,
1225 strcspn(r->in.computer_name, "$"));
1226 NT_STATUS_HAVE_NO_MEMORY(temp_str);
1227 temp_str2 = talloc_strndup(mem_ctx,
1228 r->in.query->workstation_info->dns_hostname,
1229 strcspn(r->in.query->workstation_info->dns_hostname, "."));
1230 NT_STATUS_HAVE_NO_MEMORY(temp_str2);
1231 if (strcasecmp(temp_str, temp_str2) != 0) {
1232 update_dns_hostname = false;
1236 * Check that the DNS hostname when it should be updated
1237 * will be used only by maximum one host.
1239 ret = gendb_search(sam_ctx, mem_ctx,
1240 ldb_get_default_basedn(sam_ctx),
1241 &res0, attrs3, "(dNSHostName=%s)",
1242 r->in.query->workstation_info->dns_hostname);
1244 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1247 update_dns_hostname = false;
1252 /* Prepare the workstation DN */
1253 workstation_dn = ldb_dn_new_fmt(mem_ctx, sam_ctx, "<SID=%s>",
1254 dom_sid_string(mem_ctx, creds->sid));
1255 NT_STATUS_HAVE_NO_MEMORY(workstation_dn);
1257 /* Lookup for attributes in workstation object */
1258 ret = gendb_search_dn(sam_ctx, mem_ctx, workstation_dn,
1261 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1264 /* Gets the old DNS hostname */
1265 old_dns_hostname = samdb_result_string(res1[0], "dNSHostName",
1268 /* Gets host informations and put them in our directory */
1269 new_msg = ldb_msg_new(mem_ctx);
1270 NT_STATUS_HAVE_NO_MEMORY(new_msg);
1272 new_msg->dn = workstation_dn;
1274 /* Deletes old OS version values */
1275 samdb_msg_add_delete(sam_ctx, mem_ctx, new_msg,
1276 "operatingSystemServicePack");
1277 samdb_msg_add_delete(sam_ctx, mem_ctx, new_msg,
1278 "operatingSystemVersion");
1280 if (dsdb_replace(sam_ctx, new_msg, 0) != LDB_SUCCESS) {
1281 DEBUG(3,("Impossible to update samdb: %s\n",
1282 ldb_errstring(sam_ctx)));
1285 talloc_free(new_msg);
1287 new_msg = ldb_msg_new(mem_ctx);
1288 NT_STATUS_HAVE_NO_MEMORY(new_msg);
1290 new_msg->dn = workstation_dn;
1292 /* Sets the OS name */
1293 samdb_msg_set_string(sam_ctx, mem_ctx, new_msg,
1295 r->in.query->workstation_info->os_name.string);
1298 * Sets informations from "os_version". On a empty structure
1299 * the values are cleared.
1301 if (r->in.query->workstation_info->os_version.os != NULL) {
1302 os_version = &r->in.query->workstation_info->os_version.os->os;
1304 samdb_msg_set_string(sam_ctx, mem_ctx, new_msg,
1305 "operatingSystemServicePack",
1306 os_version->CSDVersion);
1308 samdb_msg_set_string(sam_ctx, mem_ctx, new_msg,
1309 "operatingSystemVersion",
1310 talloc_asprintf(mem_ctx, "%d.%d (%d)",
1311 os_version->MajorVersion,
1312 os_version->MinorVersion,
1313 os_version->BuildNumber
1319 * If the boolean "update_dns_hostname" remained true, then we
1320 * are fine to start the update.
1322 if (update_dns_hostname) {
1323 samdb_msg_set_string(sam_ctx, mem_ctx, new_msg,
1325 r->in.query->workstation_info->dns_hostname);
1327 samdb_msg_add_string(sam_ctx, mem_ctx, new_msg,
1328 "servicePrincipalName",
1329 talloc_asprintf(mem_ctx, "HOST/%s",
1330 r->in.computer_name)
1332 samdb_msg_add_string(sam_ctx, mem_ctx, new_msg,
1333 "servicePrincipalName",
1334 talloc_asprintf(mem_ctx, "HOST/%s",
1335 r->in.query->workstation_info->dns_hostname)
1339 if (dsdb_replace(sam_ctx, new_msg, 0) != LDB_SUCCESS) {
1340 DEBUG(3,("Impossible to update samdb: %s\n",
1341 ldb_errstring(sam_ctx)));
1344 talloc_free(new_msg);
1346 /* Writes back the domain information */
1348 /* We need to do two searches. The first will pull our primary
1349 domain and the second will pull any trusted domains. Our
1350 primary domain is also a "trusted" domain, so we need to
1351 put the primary domain into the lists of returned trusts as
1353 ret = gendb_search_dn(sam_ctx, mem_ctx, ldb_get_default_basedn(sam_ctx),
1356 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1359 ret3 = gendb_search(sam_ctx, mem_ctx, NULL, &res3, attrs,
1360 "(objectClass=trustedDomain)");
1362 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1365 domain_info = talloc(mem_ctx, struct netr_DomainInformation);
1366 NT_STATUS_HAVE_NO_MEMORY(domain_info);
1368 ZERO_STRUCTP(domain_info);
1370 /* Informations about the local and trusted domains */
1372 status = fill_one_domain_info(mem_ctx,
1373 dce_call->conn->dce_ctx->lp_ctx,
1374 sam_ctx, res2[0], &domain_info->primary_domain,
1376 NT_STATUS_NOT_OK_RETURN(status);
1378 domain_info->trusted_domain_count = ret3 + 1;
1379 domain_info->trusted_domains = talloc_array(mem_ctx,
1380 struct netr_OneDomainInfo,
1381 domain_info->trusted_domain_count);
1382 NT_STATUS_HAVE_NO_MEMORY(domain_info->trusted_domains);
1384 for (i=0;i<ret3;i++) {
1385 status = fill_one_domain_info(mem_ctx,
1386 dce_call->conn->dce_ctx->lp_ctx,
1388 &domain_info->trusted_domains[i],
1390 NT_STATUS_NOT_OK_RETURN(status);
1393 status = fill_one_domain_info(mem_ctx,
1394 dce_call->conn->dce_ctx->lp_ctx, sam_ctx, res2[0],
1395 &domain_info->trusted_domains[i], true, true);
1396 NT_STATUS_NOT_OK_RETURN(status);
1398 /* Sets the supported encryption types */
1399 domain_info->supported_enc_types = samdb_result_uint(res1[0],
1400 "msDS-SupportedEncryptionTypes",
1401 default_supported_enc_types);
1403 /* Other host domain informations */
1405 lsa_policy_info = talloc(mem_ctx,
1406 struct netr_LsaPolicyInformation);
1407 NT_STATUS_HAVE_NO_MEMORY(lsa_policy_info);
1408 ZERO_STRUCTP(lsa_policy_info);
1410 domain_info->lsa_policy = *lsa_policy_info;
1412 /* The DNS hostname is only returned back when there is a chance
1414 if ((r->in.query->workstation_info->workstation_flags
1415 & NETR_WS_FLAG_HANDLES_SPN_UPDATE) != 0) {
1416 domain_info->dns_hostname.string = old_dns_hostname;
1418 domain_info->dns_hostname.string = NULL;
1421 domain_info->workstation_flags =
1422 r->in.query->workstation_info->workstation_flags;
1424 r->out.info->domain_info = domain_info;
1426 case 2: /* LSA policy information - not used at the moment */
1427 lsa_policy_info = talloc(mem_ctx,
1428 struct netr_LsaPolicyInformation);
1429 NT_STATUS_HAVE_NO_MEMORY(lsa_policy_info);
1430 ZERO_STRUCTP(lsa_policy_info);
1432 r->out.info->lsa_policy_info = lsa_policy_info;
1435 return NT_STATUS_INVALID_LEVEL;
1439 return NT_STATUS_OK;
1445 netr_ServerPasswordGet
1447 static WERROR dcesrv_netr_ServerPasswordGet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1448 struct netr_ServerPasswordGet *r)
1450 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1455 netr_NETRLOGONSENDTOSAM
1457 static WERROR dcesrv_netr_NETRLOGONSENDTOSAM(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1458 struct netr_NETRLOGONSENDTOSAM *r)
1460 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1465 netr_DsRAddressToSitenamesW
1467 static WERROR dcesrv_netr_DsRAddressToSitenamesW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1468 struct netr_DsRAddressToSitenamesW *r)
1470 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1475 netr_DsRGetDCNameEx2
1477 static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call,
1478 TALLOC_CTX *mem_ctx,
1479 struct netr_DsRGetDCNameEx2 *r)
1481 const char * const attrs[] = { "objectGUID", NULL };
1482 struct ldb_context *sam_ctx;
1483 struct ldb_message **res;
1484 struct ldb_dn *domain_dn;
1486 struct netr_DsRGetDCNameInfo *info;
1487 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
1489 ZERO_STRUCTP(r->out.info);
1491 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, lp_ctx,
1492 dce_call->conn->auth_state.session_info);
1493 if (sam_ctx == NULL) {
1494 return WERR_DS_UNAVAILABLE;
1497 /* Windows 7 sends the domain name in the form the user typed, so we
1498 * have to cope with both the short and long form here */
1499 if (r->in.domain_name != NULL &&
1500 !lp_is_my_domain_or_realm(lp_ctx, r->in.domain_name)) {
1501 return WERR_NO_SUCH_DOMAIN;
1504 domain_dn = ldb_get_default_basedn(sam_ctx);
1505 if (domain_dn == NULL) {
1506 return WERR_DS_UNAVAILABLE;
1509 ret = gendb_search_dn(sam_ctx, mem_ctx,
1510 domain_dn, &res, attrs);
1512 return WERR_GENERAL_FAILURE;
1515 info = talloc(mem_ctx, struct netr_DsRGetDCNameInfo);
1516 W_ERROR_HAVE_NO_MEMORY(info);
1518 /* TODO: - return real IP address
1519 * - check all r->in.* parameters
1520 * (server_unc is ignored by w2k3!)
1522 info->dc_unc = talloc_asprintf(mem_ctx, "\\\\%s.%s",
1523 lp_netbios_name(lp_ctx),
1524 lp_dnsdomain(lp_ctx));
1525 W_ERROR_HAVE_NO_MEMORY(info->dc_unc);
1527 info->dc_address = talloc_strdup(mem_ctx, "\\\\0.0.0.0");
1528 W_ERROR_HAVE_NO_MEMORY(info->dc_address);
1530 info->dc_address_type = DS_ADDRESS_TYPE_INET;
1531 info->domain_guid = samdb_result_guid(res[0], "objectGUID");
1532 info->domain_name = lp_dnsdomain(lp_ctx);
1533 info->forest_name = lp_dnsdomain(lp_ctx);
1534 info->dc_flags = DS_DNS_FOREST_ROOT |
1537 DS_SERVER_WRITABLE |
1539 DS_SERVER_TIMESERV |
1546 info->dc_site_name = samdb_server_site_name(sam_ctx, mem_ctx);
1547 W_ERROR_HAVE_NO_MEMORY(info->dc_site_name);
1549 /* FIXME: Hardcoded site name */
1550 info->client_site_name = talloc_strdup(mem_ctx,
1551 "Default-First-Site-Name");
1552 W_ERROR_HAVE_NO_MEMORY(info->client_site_name);
1554 *r->out.info = info;
1562 static WERROR dcesrv_netr_DsRGetDCNameEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1563 struct netr_DsRGetDCNameEx *r)
1565 struct netr_DsRGetDCNameEx2 r2;
1570 r2.in.server_unc = r->in.server_unc;
1571 r2.in.client_account = NULL;
1573 r2.in.domain_guid = r->in.domain_guid;
1574 r2.in.domain_name = r->in.domain_name;
1575 r2.in.site_name = r->in.site_name;
1576 r2.in.flags = r->in.flags;
1577 r2.out.info = r->out.info;
1579 werr = dcesrv_netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1587 static WERROR dcesrv_netr_DsRGetDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1588 struct netr_DsRGetDCName *r)
1590 struct netr_DsRGetDCNameEx2 r2;
1595 r2.in.server_unc = r->in.server_unc;
1596 r2.in.client_account = NULL;
1598 r2.in.domain_name = r->in.domain_name;
1599 r2.in.domain_guid = r->in.domain_guid;
1601 r2.in.site_name = NULL; /* should fill in from site GUID */
1602 r2.in.flags = r->in.flags;
1603 r2.out.info = r->out.info;
1605 werr = dcesrv_netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1610 netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN
1612 static WERROR dcesrv_netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1613 struct netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN *r)
1615 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1620 netr_NetrEnumerateTrustedDomainsEx
1622 static WERROR dcesrv_netr_NetrEnumerateTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1623 struct netr_NetrEnumerateTrustedDomainsEx *r)
1625 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1630 netr_DsRAddressToSitenamesExW
1632 static WERROR dcesrv_netr_DsRAddressToSitenamesExW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1633 struct netr_DsRAddressToSitenamesExW *r)
1635 struct netr_DsRAddressToSitenamesExWCtr *ctr;
1638 /* we should map the provided IPs to site names, once we have
1641 ctr = talloc(mem_ctx, struct netr_DsRAddressToSitenamesExWCtr);
1642 W_ERROR_HAVE_NO_MEMORY(ctr);
1646 ctr->count = r->in.count;
1647 ctr->sitename = talloc_array(ctr, struct lsa_String, ctr->count);
1648 W_ERROR_HAVE_NO_MEMORY(ctr->sitename);
1649 ctr->subnetname = talloc_array(ctr, struct lsa_String, ctr->count);
1650 W_ERROR_HAVE_NO_MEMORY(ctr->subnetname);
1652 for (i=0; i<ctr->count; i++) {
1653 /* FIXME: Hardcoded site name */
1654 ctr->sitename[i].string = "Default-First-Site-Name";
1655 ctr->subnetname[i].string = NULL;
1663 netr_DsrGetDcSiteCoverageW
1665 static WERROR dcesrv_netr_DsrGetDcSiteCoverageW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1666 struct netr_DsrGetDcSiteCoverageW *r)
1668 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1672 #define GET_CHECK_STR(dest, mem, msg, attr) \
1675 s = samdb_result_string(msg, attr, NULL); \
1677 DEBUG(0, ("DB Error, TustedDomain entry (%s) " \
1678 "without flatname\n", \
1679 ldb_dn_get_linearized(msg->dn))); \
1682 dest = talloc_strdup(mem, s); \
1683 W_ERROR_HAVE_NO_MEMORY(dest); \
1687 static WERROR fill_trusted_domains_array(TALLOC_CTX *mem_ctx,
1688 struct ldb_context *sam_ctx,
1689 struct netr_DomainTrustList *trusts,
1690 uint32_t trust_flags)
1692 struct ldb_dn *system_dn;
1693 struct ldb_message **dom_res = NULL;
1694 const char *trust_attrs[] = { "flatname", "trustPartner",
1695 "securityIdentifier", "trustDirection",
1696 "trustType", "trustAttributes", NULL };
1700 if (!(trust_flags & (NETR_TRUST_FLAG_INBOUND |
1701 NETR_TRUST_FLAG_OUTBOUND))) {
1702 return WERR_INVALID_FLAGS;
1705 system_dn = samdb_search_dn(sam_ctx, mem_ctx,
1706 ldb_get_default_basedn(sam_ctx),
1707 "(&(objectClass=container)(cn=System))");
1709 return WERR_GENERAL_FAILURE;
1712 ret = gendb_search(sam_ctx, mem_ctx, system_dn,
1713 &dom_res, trust_attrs,
1714 "(objectclass=trustedDomain)");
1716 for (i = 0; i < ret; i++) {
1717 unsigned int trust_dir;
1720 trust_dir = samdb_result_uint(dom_res[i],
1721 "trustDirection", 0);
1723 if (trust_dir & LSA_TRUST_DIRECTION_INBOUND) {
1724 flags |= NETR_TRUST_FLAG_INBOUND;
1726 if (trust_dir & LSA_TRUST_DIRECTION_OUTBOUND) {
1727 flags |= NETR_TRUST_FLAG_OUTBOUND;
1730 if (!(flags & trust_flags)) {
1731 /* this trust direction was not requested */
1736 trusts->array = talloc_realloc(trusts, trusts->array,
1737 struct netr_DomainTrust,
1739 W_ERROR_HAVE_NO_MEMORY(trusts->array);
1741 GET_CHECK_STR(trusts->array[n].netbios_name, trusts,
1742 dom_res[i], "flatname");
1743 GET_CHECK_STR(trusts->array[n].dns_name, trusts,
1744 dom_res[i], "trustPartner");
1746 trusts->array[n].trust_flags = flags;
1747 if ((trust_flags & NETR_TRUST_FLAG_IN_FOREST) &&
1748 !(flags & NETR_TRUST_FLAG_TREEROOT)) {
1749 /* TODO: find if we have parent in the list */
1750 trusts->array[n].parent_index = 0;
1753 trusts->array[n].trust_type =
1754 samdb_result_uint(dom_res[i],
1756 trusts->array[n].trust_attributes =
1757 samdb_result_uint(dom_res[i],
1758 "trustAttributes", 0);
1760 if ((trusts->array[n].trust_type == NETR_TRUST_TYPE_MIT) ||
1761 (trusts->array[n].trust_type == NETR_TRUST_TYPE_DCE)) {
1762 struct dom_sid zero_sid;
1763 ZERO_STRUCT(zero_sid);
1764 trusts->array[n].sid =
1765 dom_sid_dup(trusts, &zero_sid);
1767 trusts->array[n].sid =
1768 samdb_result_dom_sid(trusts, dom_res[i],
1769 "securityIdentifier");
1771 trusts->array[n].guid = GUID_zero();
1773 trusts->count = n + 1;
1776 talloc_free(dom_res);
1781 netr_DsrEnumerateDomainTrusts
1783 static WERROR dcesrv_netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce_call,
1784 TALLOC_CTX *mem_ctx,
1785 struct netr_DsrEnumerateDomainTrusts *r)
1787 struct netr_DomainTrustList *trusts;
1788 struct ldb_context *sam_ctx;
1790 struct ldb_message **dom_res;
1791 const char * const dom_attrs[] = { "objectSid", "objectGUID", NULL };
1792 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
1793 const char *dnsdomain = lp_dnsdomain(lp_ctx);
1797 if (r->in.trust_flags & 0xFFFFFE00) {
1798 return WERR_INVALID_FLAGS;
1801 /* TODO: turn to hard check once we are sure this is 100% correct */
1802 if (!r->in.server_name) {
1803 DEBUG(3, ("Invalid domain! Expected name in domain [%s]. "
1804 "But received NULL!\n", dnsdomain));
1806 p = strchr(r->in.server_name, '.');
1808 DEBUG(3, ("Invalid domain! Expected name in domain "
1809 "[%s]. But received [%s]!\n",
1810 dnsdomain, r->in.server_name));
1811 p = r->in.server_name;
1815 if (strcasecmp(p, dnsdomain)) {
1816 DEBUG(3, ("Invalid domain! Expected name in domain "
1817 "[%s]. But received [%s]!\n",
1818 dnsdomain, r->in.server_name));
1822 trusts = talloc_zero(mem_ctx, struct netr_DomainTrustList);
1823 W_ERROR_HAVE_NO_MEMORY(trusts);
1826 r->out.trusts = trusts;
1828 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, lp_ctx,
1829 dce_call->conn->auth_state.session_info);
1830 if (sam_ctx == NULL) {
1831 return WERR_GENERAL_FAILURE;
1834 if ((r->in.trust_flags & NETR_TRUST_FLAG_INBOUND) ||
1835 (r->in.trust_flags & NETR_TRUST_FLAG_OUTBOUND)) {
1837 werr = fill_trusted_domains_array(mem_ctx, sam_ctx,
1838 trusts, r->in.trust_flags);
1839 W_ERROR_NOT_OK_RETURN(werr);
1842 /* NOTE: we currently are always the root of the forest */
1843 if (r->in.trust_flags & NETR_TRUST_FLAG_IN_FOREST) {
1844 int n = trusts->count;
1846 ret = gendb_search_dn(sam_ctx, mem_ctx, NULL,
1847 &dom_res, dom_attrs);
1849 return WERR_GENERAL_FAILURE;
1852 trusts->count = n + 1;
1853 trusts->array = talloc_realloc(trusts, trusts->array,
1854 struct netr_DomainTrust,
1856 W_ERROR_HAVE_NO_MEMORY(trusts->array);
1858 trusts->array[n].netbios_name = lp_workgroup(lp_ctx);
1859 trusts->array[n].dns_name = lp_dnsdomain(lp_ctx);
1860 trusts->array[n].trust_flags =
1861 NETR_TRUST_FLAG_NATIVE |
1862 NETR_TRUST_FLAG_TREEROOT |
1863 NETR_TRUST_FLAG_IN_FOREST |
1864 NETR_TRUST_FLAG_PRIMARY;
1865 /* we are always the root domain for now */
1866 trusts->array[n].parent_index = 0;
1867 trusts->array[n].trust_type = NETR_TRUST_TYPE_UPLEVEL;
1868 trusts->array[n].trust_attributes = 0;
1869 trusts->array[n].sid = samdb_result_dom_sid(mem_ctx,
1872 trusts->array[n].guid = samdb_result_guid(dom_res[0],
1874 talloc_free(dom_res);
1882 netr_DsrDeregisterDNSHostRecords
1884 static WERROR dcesrv_netr_DsrDeregisterDNSHostRecords(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1885 struct netr_DsrDeregisterDNSHostRecords *r)
1887 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1892 netr_ServerTrustPasswordsGet
1894 static NTSTATUS dcesrv_netr_ServerTrustPasswordsGet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1895 struct netr_ServerTrustPasswordsGet *r)
1897 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1901 static WERROR fill_forest_trust_array(TALLOC_CTX *mem_ctx,
1902 struct ldb_context *sam_ctx,
1903 struct loadparm_context *lp_ctx,
1904 struct lsa_ForestTrustInformation *info)
1906 struct lsa_ForestTrustDomainInfo *domain_info;
1907 struct lsa_ForestTrustRecord *e;
1908 struct ldb_message **dom_res;
1909 const char * const dom_attrs[] = { "objectSid", NULL };
1912 /* we need to provide 2 entries:
1913 * 1. the Root Forest name
1914 * 2. the Domain Information
1918 info->entries = talloc_array(info, struct lsa_ForestTrustRecord *, 2);
1919 W_ERROR_HAVE_NO_MEMORY(info->entries);
1921 /* Forest root info */
1922 e = talloc(info, struct lsa_ForestTrustRecord);
1923 W_ERROR_HAVE_NO_MEMORY(e);
1926 e->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME;
1927 e->time = 0; /* so far always 0 in trces. */
1928 e->forest_trust_data.top_level_name.string = lp_dnsdomain(lp_ctx);
1930 info->entries[0] = e;
1933 e = talloc(info, struct lsa_ForestTrustRecord);
1934 W_ERROR_HAVE_NO_MEMORY(e);
1936 /* get our own domain info */
1937 ret = gendb_search_dn(sam_ctx, mem_ctx, NULL, &dom_res, dom_attrs);
1939 return WERR_GENERAL_FAILURE;
1942 /* TODO: check if disabled and set flags accordingly */
1944 e->type = LSA_FOREST_TRUST_DOMAIN_INFO;
1945 e->time = 0; /* so far always 0 in traces. */
1947 domain_info = &e->forest_trust_data.domain_info;
1948 domain_info->domain_sid = samdb_result_dom_sid(info, dom_res[0],
1950 domain_info->dns_domain_name.string = lp_dnsdomain(lp_ctx);
1951 domain_info->netbios_domain_name.string = lp_workgroup(lp_ctx);
1953 info->entries[1] = e;
1955 talloc_free(dom_res);
1961 netr_DsRGetForestTrustInformation
1963 static WERROR dcesrv_netr_DsRGetForestTrustInformation(struct dcesrv_call_state *dce_call,
1964 TALLOC_CTX *mem_ctx,
1965 struct netr_DsRGetForestTrustInformation *r)
1967 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
1968 struct lsa_ForestTrustInformation *info, **info_ptr;
1969 struct ldb_context *sam_ctx;
1972 if (lp_server_role(lp_ctx) != ROLE_DOMAIN_CONTROLLER) {
1973 return WERR_CALL_NOT_IMPLEMENTED;
1976 if (r->in.flags & 0xFFFFFFFE) {
1977 return WERR_INVALID_FLAGS;
1980 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, lp_ctx,
1981 dce_call->conn->auth_state.session_info);
1982 if (sam_ctx == NULL) {
1983 return WERR_GENERAL_FAILURE;
1986 if (r->in.flags & DS_GFTI_UPDATE_TDO) {
1987 if (!samdb_is_pdc(sam_ctx)) {
1988 return WERR_NERR_NOTPRIMARY;
1991 if (r->in.trusted_domain_name == NULL) {
1992 return WERR_INVALID_FLAGS;
1995 /* TODO: establish an schannel connection with
1996 * r->in.trusted_domain_name and perform a
1997 * netr_GetForestTrustInformation call against it */
1999 /* for now return not implementd */
2000 return WERR_CALL_NOT_IMPLEMENTED;
2003 /* TODO: check r->in.server_name is our name */
2005 info_ptr = talloc(mem_ctx, struct lsa_ForestTrustInformation *);
2006 W_ERROR_HAVE_NO_MEMORY(info_ptr);
2008 info = talloc_zero(info_ptr, struct lsa_ForestTrustInformation);
2009 W_ERROR_HAVE_NO_MEMORY(info);
2011 werr = fill_forest_trust_array(mem_ctx, sam_ctx, lp_ctx, info);
2012 W_ERROR_NOT_OK_RETURN(werr);
2015 r->out.forest_trust_info = info_ptr;
2022 netr_GetForestTrustInformation
2024 static NTSTATUS dcesrv_netr_GetForestTrustInformation(struct dcesrv_call_state *dce_call,
2025 TALLOC_CTX *mem_ctx,
2026 struct netr_GetForestTrustInformation *r)
2028 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
2029 struct netlogon_creds_CredentialState *creds;
2030 struct lsa_ForestTrustInformation *info, **info_ptr;
2031 struct ldb_context *sam_ctx;
2035 if (lp_server_role(lp_ctx) != ROLE_DOMAIN_CONTROLLER) {
2036 return NT_STATUS_NOT_IMPLEMENTED;
2039 status = dcesrv_netr_creds_server_step_check(dce_call,
2041 r->in.computer_name,
2043 r->out.return_authenticator,
2045 if (!NT_STATUS_IS_OK(status)) {
2049 if ((creds->secure_channel_type != SEC_CHAN_DNS_DOMAIN) &&
2050 (creds->secure_channel_type != SEC_CHAN_DOMAIN)) {
2051 return NT_STATUS_NOT_IMPLEMENTED;
2054 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, lp_ctx,
2055 dce_call->conn->auth_state.session_info);
2056 if (sam_ctx == NULL) {
2057 return NT_STATUS_UNSUCCESSFUL;
2060 /* TODO: check r->in.server_name is our name */
2062 info_ptr = talloc(mem_ctx, struct lsa_ForestTrustInformation *);
2064 return NT_STATUS_NO_MEMORY;
2066 info = talloc_zero(info_ptr, struct lsa_ForestTrustInformation);
2068 return NT_STATUS_NO_MEMORY;
2071 werr = fill_forest_trust_array(mem_ctx, sam_ctx, lp_ctx, info);
2072 if (!W_ERROR_IS_OK(werr)) {
2073 return werror_to_ntstatus(werr);
2077 r->out.forest_trust_info = info_ptr;
2079 return NT_STATUS_OK;
2084 netr_ServerGetTrustInfo
2086 static NTSTATUS dcesrv_netr_ServerGetTrustInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2087 struct netr_ServerGetTrustInfo *r)
2089 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2093 /* include the generated boilerplate */
2094 #include "librpc/gen_ndr/ndr_netlogon_s.c"