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, samdb_root_dn(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, samdb_base_dn(sam_ctx),
1240 &res0, attrs3, "(dNSHostName=%s)",
1241 r->in.query->workstation_info->dns_hostname);
1243 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1246 update_dns_hostname = false;
1251 /* Prepare the workstation DN */
1252 workstation_dn = ldb_dn_new_fmt(mem_ctx, sam_ctx, "<SID=%s>",
1253 dom_sid_string(mem_ctx, creds->sid));
1254 NT_STATUS_HAVE_NO_MEMORY(workstation_dn);
1256 /* Lookup for attributes in workstation object */
1257 ret = gendb_search_dn(sam_ctx, mem_ctx, workstation_dn,
1260 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1263 /* Gets the old DNS hostname */
1264 old_dns_hostname = samdb_result_string(res1[0], "dNSHostName",
1267 /* Gets host informations and put them in our directory */
1268 new_msg = ldb_msg_new(mem_ctx);
1269 NT_STATUS_HAVE_NO_MEMORY(new_msg);
1271 new_msg->dn = workstation_dn;
1273 /* Deletes old OS version values */
1274 samdb_msg_add_delete(sam_ctx, mem_ctx, new_msg,
1275 "operatingSystemServicePack");
1276 samdb_msg_add_delete(sam_ctx, mem_ctx, new_msg,
1277 "operatingSystemVersion");
1279 if (dsdb_replace(sam_ctx, new_msg, 0) != LDB_SUCCESS) {
1280 DEBUG(3,("Impossible to update samdb: %s\n",
1281 ldb_errstring(sam_ctx)));
1284 talloc_free(new_msg);
1286 new_msg = ldb_msg_new(mem_ctx);
1287 NT_STATUS_HAVE_NO_MEMORY(new_msg);
1289 new_msg->dn = workstation_dn;
1291 /* Sets the OS name */
1292 samdb_msg_set_string(sam_ctx, mem_ctx, new_msg,
1294 r->in.query->workstation_info->os_name.string);
1297 * Sets informations from "os_version". On a empty structure
1298 * the values are cleared.
1300 if (r->in.query->workstation_info->os_version.os != NULL) {
1301 os_version = &r->in.query->workstation_info->os_version.os->os;
1303 samdb_msg_set_string(sam_ctx, mem_ctx, new_msg,
1304 "operatingSystemServicePack",
1305 os_version->CSDVersion);
1307 samdb_msg_set_string(sam_ctx, mem_ctx, new_msg,
1308 "operatingSystemVersion",
1309 talloc_asprintf(mem_ctx, "%d.%d (%d)",
1310 os_version->MajorVersion,
1311 os_version->MinorVersion,
1312 os_version->BuildNumber
1318 * If the boolean "update_dns_hostname" remained true, then we
1319 * are fine to start the update.
1321 if (update_dns_hostname) {
1322 samdb_msg_set_string(sam_ctx, mem_ctx, new_msg,
1324 r->in.query->workstation_info->dns_hostname);
1326 samdb_msg_add_string(sam_ctx, mem_ctx, new_msg,
1327 "servicePrincipalName",
1328 talloc_asprintf(mem_ctx, "HOST/%s",
1329 r->in.computer_name)
1331 samdb_msg_add_string(sam_ctx, mem_ctx, new_msg,
1332 "servicePrincipalName",
1333 talloc_asprintf(mem_ctx, "HOST/%s",
1334 r->in.query->workstation_info->dns_hostname)
1338 if (dsdb_replace(sam_ctx, new_msg, 0) != LDB_SUCCESS) {
1339 DEBUG(3,("Impossible to update samdb: %s\n",
1340 ldb_errstring(sam_ctx)));
1343 talloc_free(new_msg);
1345 /* Writes back the domain information */
1347 /* We need to do two searches. The first will pull our primary
1348 domain and the second will pull any trusted domains. Our
1349 primary domain is also a "trusted" domain, so we need to
1350 put the primary domain into the lists of returned trusts as
1352 ret = gendb_search_dn(sam_ctx, mem_ctx, samdb_base_dn(sam_ctx),
1355 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1358 ret3 = gendb_search(sam_ctx, mem_ctx, NULL, &res3, attrs,
1359 "(objectClass=trustedDomain)");
1361 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1364 domain_info = talloc(mem_ctx, struct netr_DomainInformation);
1365 NT_STATUS_HAVE_NO_MEMORY(domain_info);
1367 ZERO_STRUCTP(domain_info);
1369 /* Informations about the local and trusted domains */
1371 status = fill_one_domain_info(mem_ctx,
1372 dce_call->conn->dce_ctx->lp_ctx,
1373 sam_ctx, res2[0], &domain_info->primary_domain,
1375 NT_STATUS_NOT_OK_RETURN(status);
1377 domain_info->trusted_domain_count = ret3 + 1;
1378 domain_info->trusted_domains = talloc_array(mem_ctx,
1379 struct netr_OneDomainInfo,
1380 domain_info->trusted_domain_count);
1381 NT_STATUS_HAVE_NO_MEMORY(domain_info->trusted_domains);
1383 for (i=0;i<ret3;i++) {
1384 status = fill_one_domain_info(mem_ctx,
1385 dce_call->conn->dce_ctx->lp_ctx,
1387 &domain_info->trusted_domains[i],
1389 NT_STATUS_NOT_OK_RETURN(status);
1392 status = fill_one_domain_info(mem_ctx,
1393 dce_call->conn->dce_ctx->lp_ctx, sam_ctx, res2[0],
1394 &domain_info->trusted_domains[i], true, true);
1395 NT_STATUS_NOT_OK_RETURN(status);
1397 /* Sets the supported encryption types */
1398 domain_info->supported_enc_types = samdb_result_uint(res1[0],
1399 "msDS-SupportedEncryptionTypes",
1400 default_supported_enc_types);
1402 /* Other host domain informations */
1404 lsa_policy_info = talloc(mem_ctx,
1405 struct netr_LsaPolicyInformation);
1406 NT_STATUS_HAVE_NO_MEMORY(lsa_policy_info);
1407 ZERO_STRUCTP(lsa_policy_info);
1409 domain_info->lsa_policy = *lsa_policy_info;
1411 /* The DNS hostname is only returned back when there is a chance
1413 if ((r->in.query->workstation_info->workstation_flags
1414 & NETR_WS_FLAG_HANDLES_SPN_UPDATE) != 0) {
1415 domain_info->dns_hostname.string = old_dns_hostname;
1417 domain_info->dns_hostname.string = NULL;
1420 domain_info->workstation_flags =
1421 r->in.query->workstation_info->workstation_flags;
1423 r->out.info->domain_info = domain_info;
1425 case 2: /* LSA policy information - not used at the moment */
1426 lsa_policy_info = talloc(mem_ctx,
1427 struct netr_LsaPolicyInformation);
1428 NT_STATUS_HAVE_NO_MEMORY(lsa_policy_info);
1429 ZERO_STRUCTP(lsa_policy_info);
1431 r->out.info->lsa_policy_info = lsa_policy_info;
1434 return NT_STATUS_INVALID_LEVEL;
1438 return NT_STATUS_OK;
1444 netr_ServerPasswordGet
1446 static WERROR dcesrv_netr_ServerPasswordGet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1447 struct netr_ServerPasswordGet *r)
1449 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1454 netr_NETRLOGONSENDTOSAM
1456 static WERROR dcesrv_netr_NETRLOGONSENDTOSAM(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1457 struct netr_NETRLOGONSENDTOSAM *r)
1459 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1464 netr_DsRAddressToSitenamesW
1466 static WERROR dcesrv_netr_DsRAddressToSitenamesW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1467 struct netr_DsRAddressToSitenamesW *r)
1469 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1474 netr_DsRGetDCNameEx2
1476 static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call,
1477 TALLOC_CTX *mem_ctx,
1478 struct netr_DsRGetDCNameEx2 *r)
1480 const char * const attrs[] = { "objectGUID", NULL };
1481 struct ldb_context *sam_ctx;
1482 struct ldb_message **res;
1483 struct ldb_dn *domain_dn;
1485 struct netr_DsRGetDCNameInfo *info;
1486 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
1488 ZERO_STRUCTP(r->out.info);
1490 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, lp_ctx,
1491 dce_call->conn->auth_state.session_info);
1492 if (sam_ctx == NULL) {
1493 return WERR_DS_UNAVAILABLE;
1496 /* Windows 7 sends the domain name in the form the user typed, so we
1497 * have to cope with both the short and long form here */
1498 if (r->in.domain_name != NULL &&
1499 !lp_is_my_domain_or_realm(lp_ctx, r->in.domain_name)) {
1500 return WERR_NO_SUCH_DOMAIN;
1503 domain_dn = ldb_get_default_basedn(sam_ctx);
1504 if (domain_dn == NULL) {
1505 return WERR_DS_UNAVAILABLE;
1508 ret = gendb_search_dn(sam_ctx, mem_ctx,
1509 domain_dn, &res, attrs);
1511 return WERR_GENERAL_FAILURE;
1514 info = talloc(mem_ctx, struct netr_DsRGetDCNameInfo);
1515 W_ERROR_HAVE_NO_MEMORY(info);
1517 /* TODO: - return real IP address
1518 * - check all r->in.* parameters
1519 * (server_unc is ignored by w2k3!)
1521 info->dc_unc = talloc_asprintf(mem_ctx, "\\\\%s.%s",
1522 lp_netbios_name(lp_ctx),
1523 lp_dnsdomain(lp_ctx));
1524 W_ERROR_HAVE_NO_MEMORY(info->dc_unc);
1526 info->dc_address = talloc_strdup(mem_ctx, "\\\\0.0.0.0");
1527 W_ERROR_HAVE_NO_MEMORY(info->dc_address);
1529 info->dc_address_type = DS_ADDRESS_TYPE_INET;
1530 info->domain_guid = samdb_result_guid(res[0], "objectGUID");
1531 info->domain_name = lp_dnsdomain(lp_ctx);
1532 info->forest_name = lp_dnsdomain(lp_ctx);
1533 info->dc_flags = DS_DNS_FOREST_ROOT |
1536 DS_SERVER_WRITABLE |
1538 DS_SERVER_TIMESERV |
1545 info->dc_site_name = samdb_server_site_name(sam_ctx, mem_ctx);
1546 W_ERROR_HAVE_NO_MEMORY(info->dc_site_name);
1548 /* FIXME: Hardcoded site name */
1549 info->client_site_name = talloc_strdup(mem_ctx,
1550 "Default-First-Site-Name");
1551 W_ERROR_HAVE_NO_MEMORY(info->client_site_name);
1553 *r->out.info = info;
1561 static WERROR dcesrv_netr_DsRGetDCNameEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1562 struct netr_DsRGetDCNameEx *r)
1564 struct netr_DsRGetDCNameEx2 r2;
1569 r2.in.server_unc = r->in.server_unc;
1570 r2.in.client_account = NULL;
1572 r2.in.domain_guid = r->in.domain_guid;
1573 r2.in.domain_name = r->in.domain_name;
1574 r2.in.site_name = r->in.site_name;
1575 r2.in.flags = r->in.flags;
1576 r2.out.info = r->out.info;
1578 werr = dcesrv_netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1586 static WERROR dcesrv_netr_DsRGetDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1587 struct netr_DsRGetDCName *r)
1589 struct netr_DsRGetDCNameEx2 r2;
1594 r2.in.server_unc = r->in.server_unc;
1595 r2.in.client_account = NULL;
1597 r2.in.domain_name = r->in.domain_name;
1598 r2.in.domain_guid = r->in.domain_guid;
1600 r2.in.site_name = NULL; /* should fill in from site GUID */
1601 r2.in.flags = r->in.flags;
1602 r2.out.info = r->out.info;
1604 werr = dcesrv_netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1609 netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN
1611 static WERROR dcesrv_netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1612 struct netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN *r)
1614 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1619 netr_NetrEnumerateTrustedDomainsEx
1621 static WERROR dcesrv_netr_NetrEnumerateTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1622 struct netr_NetrEnumerateTrustedDomainsEx *r)
1624 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1629 netr_DsRAddressToSitenamesExW
1631 static WERROR dcesrv_netr_DsRAddressToSitenamesExW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1632 struct netr_DsRAddressToSitenamesExW *r)
1634 struct netr_DsRAddressToSitenamesExWCtr *ctr;
1637 /* we should map the provided IPs to site names, once we have
1640 ctr = talloc(mem_ctx, struct netr_DsRAddressToSitenamesExWCtr);
1641 W_ERROR_HAVE_NO_MEMORY(ctr);
1645 ctr->count = r->in.count;
1646 ctr->sitename = talloc_array(ctr, struct lsa_String, ctr->count);
1647 W_ERROR_HAVE_NO_MEMORY(ctr->sitename);
1648 ctr->subnetname = talloc_array(ctr, struct lsa_String, ctr->count);
1649 W_ERROR_HAVE_NO_MEMORY(ctr->subnetname);
1651 for (i=0; i<ctr->count; i++) {
1652 /* FIXME: Hardcoded site name */
1653 ctr->sitename[i].string = "Default-First-Site-Name";
1654 ctr->subnetname[i].string = NULL;
1662 netr_DsrGetDcSiteCoverageW
1664 static WERROR dcesrv_netr_DsrGetDcSiteCoverageW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1665 struct netr_DsrGetDcSiteCoverageW *r)
1667 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1671 #define GET_CHECK_STR(dest, mem, msg, attr) \
1674 s = samdb_result_string(msg, attr, NULL); \
1676 DEBUG(0, ("DB Error, TustedDomain entry (%s) " \
1677 "without flatname\n", \
1678 ldb_dn_get_linearized(msg->dn))); \
1681 dest = talloc_strdup(mem, s); \
1682 W_ERROR_HAVE_NO_MEMORY(dest); \
1686 static WERROR fill_trusted_domains_array(TALLOC_CTX *mem_ctx,
1687 struct ldb_context *sam_ctx,
1688 struct netr_DomainTrustList *trusts,
1689 uint32_t trust_flags)
1691 struct ldb_dn *system_dn;
1692 struct ldb_message **dom_res = NULL;
1693 const char *trust_attrs[] = { "flatname", "trustPartner",
1694 "securityIdentifier", "trustDirection",
1695 "trustType", "trustAttributes", NULL };
1699 if (!(trust_flags & (NETR_TRUST_FLAG_INBOUND |
1700 NETR_TRUST_FLAG_OUTBOUND))) {
1701 return WERR_INVALID_FLAGS;
1704 system_dn = samdb_search_dn(sam_ctx, mem_ctx,
1705 ldb_get_default_basedn(sam_ctx),
1706 "(&(objectClass=container)(cn=System))");
1708 return WERR_GENERAL_FAILURE;
1711 ret = gendb_search(sam_ctx, mem_ctx, system_dn,
1712 &dom_res, trust_attrs,
1713 "(objectclass=trustedDomain)");
1715 for (i = 0; i < ret; i++) {
1716 unsigned int trust_dir;
1719 trust_dir = samdb_result_uint(dom_res[i],
1720 "trustDirection", 0);
1722 if (trust_dir & LSA_TRUST_DIRECTION_INBOUND) {
1723 flags |= NETR_TRUST_FLAG_INBOUND;
1725 if (trust_dir & LSA_TRUST_DIRECTION_OUTBOUND) {
1726 flags |= NETR_TRUST_FLAG_OUTBOUND;
1729 if (!(flags & trust_flags)) {
1730 /* this trust direction was not requested */
1735 trusts->array = talloc_realloc(trusts, trusts->array,
1736 struct netr_DomainTrust,
1738 W_ERROR_HAVE_NO_MEMORY(trusts->array);
1740 GET_CHECK_STR(trusts->array[n].netbios_name, trusts,
1741 dom_res[i], "flatname");
1742 GET_CHECK_STR(trusts->array[n].dns_name, trusts,
1743 dom_res[i], "trustPartner");
1745 trusts->array[n].trust_flags = flags;
1746 if ((trust_flags & NETR_TRUST_FLAG_IN_FOREST) &&
1747 !(flags & NETR_TRUST_FLAG_TREEROOT)) {
1748 /* TODO: find if we have parent in the list */
1749 trusts->array[n].parent_index = 0;
1752 trusts->array[n].trust_type =
1753 samdb_result_uint(dom_res[i],
1755 trusts->array[n].trust_attributes =
1756 samdb_result_uint(dom_res[i],
1757 "trustAttributes", 0);
1759 if ((trusts->array[n].trust_type == NETR_TRUST_TYPE_MIT) ||
1760 (trusts->array[n].trust_type == NETR_TRUST_TYPE_DCE)) {
1761 struct dom_sid zero_sid;
1762 ZERO_STRUCT(zero_sid);
1763 trusts->array[n].sid =
1764 dom_sid_dup(trusts, &zero_sid);
1766 trusts->array[n].sid =
1767 samdb_result_dom_sid(trusts, dom_res[i],
1768 "securityIdentifier");
1770 trusts->array[n].guid = GUID_zero();
1772 trusts->count = n + 1;
1775 talloc_free(dom_res);
1780 netr_DsrEnumerateDomainTrusts
1782 static WERROR dcesrv_netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce_call,
1783 TALLOC_CTX *mem_ctx,
1784 struct netr_DsrEnumerateDomainTrusts *r)
1786 struct netr_DomainTrustList *trusts;
1787 struct ldb_context *sam_ctx;
1789 struct ldb_message **dom_res;
1790 const char * const dom_attrs[] = { "objectSid", "objectGUID", NULL };
1791 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
1792 const char *dnsdomain = lp_dnsdomain(lp_ctx);
1796 if (r->in.trust_flags & 0xFFFFFE00) {
1797 return WERR_INVALID_FLAGS;
1800 /* TODO: turn to hard check once we are sure this is 100% correct */
1801 if (!r->in.server_name) {
1802 DEBUG(3, ("Invalid domain! Expected name in domain [%s]. "
1803 "But received NULL!\n", dnsdomain));
1805 p = strchr(r->in.server_name, '.');
1807 DEBUG(3, ("Invalid domain! Expected name in domain "
1808 "[%s]. But received [%s]!\n",
1809 dnsdomain, r->in.server_name));
1810 p = r->in.server_name;
1814 if (strcasecmp(p, dnsdomain)) {
1815 DEBUG(3, ("Invalid domain! Expected name in domain "
1816 "[%s]. But received [%s]!\n",
1817 dnsdomain, r->in.server_name));
1821 trusts = talloc_zero(mem_ctx, struct netr_DomainTrustList);
1822 W_ERROR_HAVE_NO_MEMORY(trusts);
1825 r->out.trusts = trusts;
1827 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, lp_ctx,
1828 dce_call->conn->auth_state.session_info);
1829 if (sam_ctx == NULL) {
1830 return WERR_GENERAL_FAILURE;
1833 if ((r->in.trust_flags & NETR_TRUST_FLAG_INBOUND) ||
1834 (r->in.trust_flags & NETR_TRUST_FLAG_OUTBOUND)) {
1836 werr = fill_trusted_domains_array(mem_ctx, sam_ctx,
1837 trusts, r->in.trust_flags);
1838 W_ERROR_NOT_OK_RETURN(werr);
1841 /* NOTE: we currently are always the root of the forest */
1842 if (r->in.trust_flags & NETR_TRUST_FLAG_IN_FOREST) {
1843 int n = trusts->count;
1845 ret = gendb_search_dn(sam_ctx, mem_ctx, NULL,
1846 &dom_res, dom_attrs);
1848 return WERR_GENERAL_FAILURE;
1851 trusts->count = n + 1;
1852 trusts->array = talloc_realloc(trusts, trusts->array,
1853 struct netr_DomainTrust,
1855 W_ERROR_HAVE_NO_MEMORY(trusts->array);
1857 trusts->array[n].netbios_name = lp_workgroup(lp_ctx);
1858 trusts->array[n].dns_name = lp_dnsdomain(lp_ctx);
1859 trusts->array[n].trust_flags =
1860 NETR_TRUST_FLAG_NATIVE |
1861 NETR_TRUST_FLAG_TREEROOT |
1862 NETR_TRUST_FLAG_IN_FOREST |
1863 NETR_TRUST_FLAG_PRIMARY;
1864 /* we are always the root domain for now */
1865 trusts->array[n].parent_index = 0;
1866 trusts->array[n].trust_type = NETR_TRUST_TYPE_UPLEVEL;
1867 trusts->array[n].trust_attributes = 0;
1868 trusts->array[n].sid = samdb_result_dom_sid(mem_ctx,
1871 trusts->array[n].guid = samdb_result_guid(dom_res[0],
1873 talloc_free(dom_res);
1881 netr_DsrDeregisterDNSHostRecords
1883 static WERROR dcesrv_netr_DsrDeregisterDNSHostRecords(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1884 struct netr_DsrDeregisterDNSHostRecords *r)
1886 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1891 netr_ServerTrustPasswordsGet
1893 static NTSTATUS dcesrv_netr_ServerTrustPasswordsGet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1894 struct netr_ServerTrustPasswordsGet *r)
1896 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1900 static WERROR fill_forest_trust_array(TALLOC_CTX *mem_ctx,
1901 struct ldb_context *sam_ctx,
1902 struct loadparm_context *lp_ctx,
1903 struct lsa_ForestTrustInformation *info)
1905 struct lsa_ForestTrustDomainInfo *domain_info;
1906 struct lsa_ForestTrustRecord *e;
1907 struct ldb_message **dom_res;
1908 const char * const dom_attrs[] = { "objectSid", NULL };
1911 /* we need to provide 2 entries:
1912 * 1. the Root Forest name
1913 * 2. the Domain Information
1917 info->entries = talloc_array(info, struct lsa_ForestTrustRecord *, 2);
1918 W_ERROR_HAVE_NO_MEMORY(info->entries);
1920 /* Forest root info */
1921 e = talloc(info, struct lsa_ForestTrustRecord);
1922 W_ERROR_HAVE_NO_MEMORY(e);
1925 e->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME;
1926 e->time = 0; /* so far always 0 in trces. */
1927 e->forest_trust_data.top_level_name.string = lp_dnsdomain(lp_ctx);
1929 info->entries[0] = e;
1932 e = talloc(info, struct lsa_ForestTrustRecord);
1933 W_ERROR_HAVE_NO_MEMORY(e);
1935 /* get our own domain info */
1936 ret = gendb_search_dn(sam_ctx, mem_ctx, NULL, &dom_res, dom_attrs);
1938 return WERR_GENERAL_FAILURE;
1941 /* TODO: check if disabled and set flags accordingly */
1943 e->type = LSA_FOREST_TRUST_DOMAIN_INFO;
1944 e->time = 0; /* so far always 0 in traces. */
1946 domain_info = &e->forest_trust_data.domain_info;
1947 domain_info->domain_sid = samdb_result_dom_sid(info, dom_res[0],
1949 domain_info->dns_domain_name.string = lp_dnsdomain(lp_ctx);
1950 domain_info->netbios_domain_name.string = lp_workgroup(lp_ctx);
1952 info->entries[1] = e;
1954 talloc_free(dom_res);
1960 netr_DsRGetForestTrustInformation
1962 static WERROR dcesrv_netr_DsRGetForestTrustInformation(struct dcesrv_call_state *dce_call,
1963 TALLOC_CTX *mem_ctx,
1964 struct netr_DsRGetForestTrustInformation *r)
1966 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
1967 struct lsa_ForestTrustInformation *info, **info_ptr;
1968 struct ldb_context *sam_ctx;
1971 if (lp_server_role(lp_ctx) != ROLE_DOMAIN_CONTROLLER) {
1972 return WERR_CALL_NOT_IMPLEMENTED;
1975 if (r->in.flags & 0xFFFFFFFE) {
1976 return WERR_INVALID_FLAGS;
1979 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, lp_ctx,
1980 dce_call->conn->auth_state.session_info);
1981 if (sam_ctx == NULL) {
1982 return WERR_GENERAL_FAILURE;
1985 if (r->in.flags & DS_GFTI_UPDATE_TDO) {
1986 if (!samdb_is_pdc(sam_ctx)) {
1987 return WERR_NERR_NOTPRIMARY;
1990 if (r->in.trusted_domain_name == NULL) {
1991 return WERR_INVALID_FLAGS;
1994 /* TODO: establish an schannel connection with
1995 * r->in.trusted_domain_name and perform a
1996 * netr_GetForestTrustInformation call against it */
1998 /* for now return not implementd */
1999 return WERR_CALL_NOT_IMPLEMENTED;
2002 /* TODO: check r->in.server_name is our name */
2004 info_ptr = talloc(mem_ctx, struct lsa_ForestTrustInformation *);
2005 W_ERROR_HAVE_NO_MEMORY(info_ptr);
2007 info = talloc_zero(info_ptr, struct lsa_ForestTrustInformation);
2008 W_ERROR_HAVE_NO_MEMORY(info);
2010 werr = fill_forest_trust_array(mem_ctx, sam_ctx, lp_ctx, info);
2011 W_ERROR_NOT_OK_RETURN(werr);
2014 r->out.forest_trust_info = info_ptr;
2021 netr_GetForestTrustInformation
2023 static NTSTATUS dcesrv_netr_GetForestTrustInformation(struct dcesrv_call_state *dce_call,
2024 TALLOC_CTX *mem_ctx,
2025 struct netr_GetForestTrustInformation *r)
2027 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
2028 struct netlogon_creds_CredentialState *creds;
2029 struct lsa_ForestTrustInformation *info, **info_ptr;
2030 struct ldb_context *sam_ctx;
2034 if (lp_server_role(lp_ctx) != ROLE_DOMAIN_CONTROLLER) {
2035 return NT_STATUS_NOT_IMPLEMENTED;
2038 status = dcesrv_netr_creds_server_step_check(dce_call,
2040 r->in.computer_name,
2042 r->out.return_authenticator,
2044 if (!NT_STATUS_IS_OK(status)) {
2048 if ((creds->secure_channel_type != SEC_CHAN_DNS_DOMAIN) &&
2049 (creds->secure_channel_type != SEC_CHAN_DOMAIN)) {
2050 return NT_STATUS_NOT_IMPLEMENTED;
2053 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, lp_ctx,
2054 dce_call->conn->auth_state.session_info);
2055 if (sam_ctx == NULL) {
2056 return NT_STATUS_UNSUCCESSFUL;
2059 /* TODO: check r->in.server_name is our name */
2061 info_ptr = talloc(mem_ctx, struct lsa_ForestTrustInformation *);
2063 return NT_STATUS_NO_MEMORY;
2065 info = talloc_zero(info_ptr, struct lsa_ForestTrustInformation);
2067 return NT_STATUS_NO_MEMORY;
2070 werr = fill_forest_trust_array(mem_ctx, sam_ctx, lp_ctx, info);
2071 if (!W_ERROR_IS_OK(werr)) {
2072 return werror_to_ntstatus(werr);
2076 r->out.forest_trust_info = info_ptr;
2078 return NT_STATUS_OK;
2083 netr_ServerGetTrustInfo
2085 static NTSTATUS dcesrv_netr_ServerGetTrustInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2086 struct netr_ServerGetTrustInfo *r)
2088 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2092 /* include the generated boilerplate */
2093 #include "librpc/gen_ndr/ndr_netlogon_s.c"