2 Unix SMB/CIFS implementation.
4 endpoint server for the netlogon pipe
6 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2008
7 Copyright (C) Stefan Metzmacher <metze@samba.org> 2005
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "rpc_server/dcerpc_server.h"
25 #include "rpc_server/common/common.h"
26 #include "lib/ldb/include/ldb.h"
27 #include "auth/auth.h"
28 #include "auth/auth_sam_reply.h"
29 #include "dsdb/samdb/samdb.h"
30 #include "dsdb/common/flags.h"
31 #include "rpc_server/samr/proto.h"
32 #include "util/util_ldb.h"
33 #include "libcli/auth/libcli_auth.h"
34 #include "auth/gensec/schannel_state.h"
35 #include "libcli/security/security.h"
36 #include "param/param.h"
37 #include "lib/messaging/irpc.h"
38 #include "librpc/gen_ndr/ndr_irpc.h"
39 #include "librpc/gen_ndr/ndr_netlogon.h"
41 struct server_pipe_state {
42 struct netr_Credential client_challenge;
43 struct netr_Credential server_challenge;
47 static NTSTATUS dcesrv_netr_ServerReqChallenge(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
48 struct netr_ServerReqChallenge *r)
50 struct server_pipe_state *pipe_state = dce_call->context->private;
52 ZERO_STRUCTP(r->out.credentials);
54 /* destroyed on pipe shutdown */
57 talloc_free(pipe_state);
58 dce_call->context->private = NULL;
61 pipe_state = talloc(dce_call->context, struct server_pipe_state);
62 NT_STATUS_HAVE_NO_MEMORY(pipe_state);
64 pipe_state->client_challenge = *r->in.credentials;
66 generate_random_buffer(pipe_state->server_challenge.data,
67 sizeof(pipe_state->server_challenge.data));
69 *r->out.credentials = pipe_state->server_challenge;
71 dce_call->context->private = pipe_state;
76 static NTSTATUS dcesrv_netr_ServerAuthenticate3(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
77 struct netr_ServerAuthenticate3 *r)
79 struct server_pipe_state *pipe_state = dce_call->context->private;
80 struct creds_CredentialState *creds;
82 struct samr_Password *mach_pwd;
83 uint32_t user_account_control;
85 struct ldb_message **msgs;
87 const char *attrs[] = {"unicodePwd", "userAccountControl",
90 ZERO_STRUCTP(r->out.credentials);
92 *r->out.negotiate_flags = *r->in.negotiate_flags;
95 DEBUG(1, ("No challenge requested by client, cannot authenticate\n"));
96 return NT_STATUS_ACCESS_DENIED;
99 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx,
100 system_session(mem_ctx, dce_call->conn->dce_ctx->lp_ctx));
101 if (sam_ctx == NULL) {
102 return NT_STATUS_INVALID_SYSTEM_SERVICE;
104 /* pull the user attributes */
105 num_records = gendb_search(sam_ctx, mem_ctx, NULL, &msgs, attrs,
106 "(&(sAMAccountName=%s)(objectclass=user))",
109 if (num_records == 0) {
110 DEBUG(3,("Couldn't find user [%s] in samdb.\n",
111 r->in.account_name));
112 return NT_STATUS_ACCESS_DENIED;
115 if (num_records > 1) {
116 DEBUG(0,("Found %d records matching user [%s]\n", num_records, r->in.account_name));
117 return NT_STATUS_INTERNAL_DB_CORRUPTION;
121 user_account_control = ldb_msg_find_attr_as_uint(msgs[0], "userAccountControl", 0);
123 if (user_account_control & UF_ACCOUNTDISABLE) {
124 DEBUG(1, ("Account [%s] is disabled\n", r->in.account_name));
125 return NT_STATUS_ACCESS_DENIED;
128 if (r->in.secure_channel_type == SEC_CHAN_WKSTA) {
129 if (!(user_account_control & UF_WORKSTATION_TRUST_ACCOUNT)) {
130 DEBUG(1, ("Client asked for a workstation secure channel, but is not a workstation (member server) acb flags: 0x%x\n", user_account_control));
131 return NT_STATUS_ACCESS_DENIED;
133 } else if (r->in.secure_channel_type == SEC_CHAN_DOMAIN) {
134 if (!(user_account_control & UF_INTERDOMAIN_TRUST_ACCOUNT)) {
135 DEBUG(1, ("Client asked for a trusted domain secure channel, but is not a trusted domain: acb flags: 0x%x\n", user_account_control));
137 return NT_STATUS_ACCESS_DENIED;
139 } else if (r->in.secure_channel_type == SEC_CHAN_BDC) {
140 if (!(user_account_control & UF_SERVER_TRUST_ACCOUNT)) {
141 DEBUG(1, ("Client asked for a server secure channel, but is not a server (domain controller): acb flags: 0x%x\n", user_account_control));
142 return NT_STATUS_ACCESS_DENIED;
145 DEBUG(1, ("Client asked for an invalid secure channel type: %d\n",
146 r->in.secure_channel_type));
147 return NT_STATUS_ACCESS_DENIED;
150 *r->out.rid = samdb_result_rid_from_sid(mem_ctx, msgs[0],
153 mach_pwd = samdb_result_hash(mem_ctx, msgs[0], "unicodePwd");
154 if (mach_pwd == NULL) {
155 return NT_STATUS_ACCESS_DENIED;
158 creds = talloc(mem_ctx, struct creds_CredentialState);
159 NT_STATUS_HAVE_NO_MEMORY(creds);
161 creds_server_init(creds, &pipe_state->client_challenge,
162 &pipe_state->server_challenge, mach_pwd,
164 *r->in.negotiate_flags);
166 if (!creds_server_check(creds, r->in.credentials)) {
168 return NT_STATUS_ACCESS_DENIED;
171 creds->account_name = talloc_steal(creds, r->in.account_name);
173 creds->computer_name = talloc_steal(creds, r->in.computer_name);
174 creds->domain = talloc_strdup(creds, lp_workgroup(dce_call->conn->dce_ctx->lp_ctx));
176 creds->secure_channel_type = r->in.secure_channel_type;
178 creds->sid = samdb_result_dom_sid(creds, msgs[0], "objectSid");
181 /* remember this session key state */
182 nt_status = schannel_store_session_key(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, creds);
187 static NTSTATUS dcesrv_netr_ServerAuthenticate(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
188 struct netr_ServerAuthenticate *r)
190 struct netr_ServerAuthenticate3 r3;
193 * negotiate_flags is used as an [in] parameter
194 * so it need to be initialised.
196 * (I think ... = 0; seems wrong here --metze)
198 uint32_t negotiate_flags = 0;
200 r3.in.server_name = r->in.server_name;
201 r3.in.account_name = r->in.account_name;
202 r3.in.secure_channel_type = r->in.secure_channel_type;
203 r3.in.computer_name = r->in.computer_name;
204 r3.in.credentials = r->in.credentials;
205 r3.out.credentials = r->out.credentials;
206 r3.in.negotiate_flags = &negotiate_flags;
207 r3.out.negotiate_flags = &negotiate_flags;
210 return dcesrv_netr_ServerAuthenticate3(dce_call, mem_ctx, &r3);
213 static NTSTATUS dcesrv_netr_ServerAuthenticate2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
214 struct netr_ServerAuthenticate2 *r)
216 struct netr_ServerAuthenticate3 r3;
219 r3.in.server_name = r->in.server_name;
220 r3.in.account_name = r->in.account_name;
221 r3.in.secure_channel_type = r->in.secure_channel_type;
222 r3.in.computer_name = r->in.computer_name;
223 r3.in.credentials = r->in.credentials;
224 r3.out.credentials = r->out.credentials;
225 r3.in.negotiate_flags = r->in.negotiate_flags;
226 r3.out.negotiate_flags = r->out.negotiate_flags;
229 return dcesrv_netr_ServerAuthenticate3(dce_call, mem_ctx, &r3);
233 Validate an incoming authenticator against the credentials for the remote machine.
235 The credentials are (re)read and from the schannel database, and
236 written back after the caclulations are performed.
238 The creds_out parameter (if not NULL) returns the credentials, if
239 the caller needs some of that information.
242 static NTSTATUS dcesrv_netr_creds_server_step_check(struct event_context *event_ctx,
243 struct loadparm_context *lp_ctx,
244 const char *computer_name,
246 struct netr_Authenticator *received_authenticator,
247 struct netr_Authenticator *return_authenticator,
248 struct creds_CredentialState **creds_out)
250 struct creds_CredentialState *creds;
252 struct ldb_context *ldb;
255 ldb = schannel_db_connect(mem_ctx, event_ctx, lp_ctx);
257 return NT_STATUS_ACCESS_DENIED;
260 ret = ldb_transaction_start(ldb);
263 return NT_STATUS_INTERNAL_DB_CORRUPTION;
266 /* Because this is a shared structure (even across
267 * disconnects) we must update the database every time we
268 * update the structure */
270 nt_status = schannel_fetch_session_key_ldb(ldb, ldb, computer_name,
271 lp_workgroup(lp_ctx),
273 if (NT_STATUS_IS_OK(nt_status)) {
274 nt_status = creds_server_step_check(creds,
275 received_authenticator,
276 return_authenticator);
278 if (NT_STATUS_IS_OK(nt_status)) {
279 nt_status = schannel_store_session_key_ldb(ldb, ldb, creds);
282 if (NT_STATUS_IS_OK(nt_status)) {
283 ldb_transaction_commit(ldb);
286 talloc_steal(mem_ctx, creds);
289 ldb_transaction_cancel(ldb);
296 Change the machine account password for the currently connected
297 client. Supplies only the NT#.
300 static NTSTATUS dcesrv_netr_ServerPasswordSet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
301 struct netr_ServerPasswordSet *r)
303 struct creds_CredentialState *creds;
304 struct ldb_context *sam_ctx;
307 nt_status = dcesrv_netr_creds_server_step_check(dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx,
308 r->in.computer_name, mem_ctx,
309 &r->in.credential, &r->out.return_authenticator,
311 NT_STATUS_NOT_OK_RETURN(nt_status);
313 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(mem_ctx, dce_call->conn->dce_ctx->lp_ctx));
314 if (sam_ctx == NULL) {
315 return NT_STATUS_INVALID_SYSTEM_SERVICE;
318 creds_des_decrypt(creds, &r->in.new_password);
320 /* Using the sid for the account as the key, set the password */
321 nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
323 NULL, /* Don't have plaintext */
324 NULL, &r->in.new_password,
325 false, /* This is not considered a password change */
331 Change the machine account password for the currently connected
332 client. Supplies new plaintext.
334 static NTSTATUS dcesrv_netr_ServerPasswordSet2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
335 struct netr_ServerPasswordSet2 *r)
337 struct creds_CredentialState *creds;
338 struct ldb_context *sam_ctx;
343 struct samr_CryptPassword password_buf;
345 nt_status = dcesrv_netr_creds_server_step_check(dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx,
346 r->in.computer_name, mem_ctx,
347 &r->in.credential, &r->out.return_authenticator,
349 NT_STATUS_NOT_OK_RETURN(nt_status);
351 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(mem_ctx, dce_call->conn->dce_ctx->lp_ctx));
352 if (sam_ctx == NULL) {
353 return NT_STATUS_INVALID_SYSTEM_SERVICE;
356 memcpy(password_buf.data, r->in.new_password.data, 512);
357 SIVAL(password_buf.data,512,r->in.new_password.length);
358 creds_arcfour_crypt(creds, password_buf.data, 516);
360 ret = decode_pw_buffer(password_buf.data, new_pass, sizeof(new_pass),
363 DEBUG(3,("netr_ServerPasswordSet2: failed to decode password buffer\n"));
364 return NT_STATUS_ACCESS_DENIED;
367 /* Using the sid for the account as the key, set the password */
368 nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
370 new_pass, /* we have plaintext */
372 false, /* This is not considered a password change */
381 static WERROR dcesrv_netr_LogonUasLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
382 struct netr_LogonUasLogon *r)
384 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
391 static WERROR dcesrv_netr_LogonUasLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
392 struct netr_LogonUasLogoff *r)
394 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
399 netr_LogonSamLogon_base
401 This version of the function allows other wrappers to say 'do not check the credentials'
403 We can't do the traditional 'wrapping' format completly, as this function must only run under schannel
405 static NTSTATUS dcesrv_netr_LogonSamLogon_base(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
406 struct netr_LogonSamLogonEx *r, struct creds_CredentialState *creds)
408 struct auth_context *auth_context;
409 struct auth_usersupplied_info *user_info;
410 struct auth_serversupplied_info *server_info;
412 static const char zeros[16];
413 struct netr_SamBaseInfo *sam;
414 struct netr_SamInfo2 *sam2;
415 struct netr_SamInfo3 *sam3;
416 struct netr_SamInfo6 *sam6;
418 user_info = talloc(mem_ctx, struct auth_usersupplied_info);
419 NT_STATUS_HAVE_NO_MEMORY(user_info);
421 user_info->flags = 0;
422 user_info->mapped_state = false;
423 user_info->remote_host = NULL;
425 switch (r->in.logon_level) {
426 case NetlogonInteractiveInformation:
427 case NetlogonServiceInformation:
428 case NetlogonInteractiveTransitiveInformation:
429 case NetlogonServiceTransitiveInformation:
430 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
431 creds_arcfour_crypt(creds,
432 r->in.logon.password->lmpassword.hash,
433 sizeof(r->in.logon.password->lmpassword.hash));
434 creds_arcfour_crypt(creds,
435 r->in.logon.password->ntpassword.hash,
436 sizeof(r->in.logon.password->ntpassword.hash));
438 creds_des_decrypt(creds, &r->in.logon.password->lmpassword);
439 creds_des_decrypt(creds, &r->in.logon.password->ntpassword);
442 /* TODO: we need to deny anonymous access here */
443 nt_status = auth_context_create(mem_ctx,
444 dce_call->event_ctx, dce_call->msg_ctx,
445 dce_call->conn->dce_ctx->lp_ctx,
447 NT_STATUS_NOT_OK_RETURN(nt_status);
449 user_info->logon_parameters = r->in.logon.password->identity_info.parameter_control;
450 user_info->client.account_name = r->in.logon.password->identity_info.account_name.string;
451 user_info->client.domain_name = r->in.logon.password->identity_info.domain_name.string;
452 user_info->workstation_name = r->in.logon.password->identity_info.workstation.string;
454 user_info->flags |= USER_INFO_INTERACTIVE_LOGON;
455 user_info->password_state = AUTH_PASSWORD_HASH;
457 user_info->password.hash.lanman = talloc(user_info, struct samr_Password);
458 NT_STATUS_HAVE_NO_MEMORY(user_info->password.hash.lanman);
459 *user_info->password.hash.lanman = r->in.logon.password->lmpassword;
461 user_info->password.hash.nt = talloc(user_info, struct samr_Password);
462 NT_STATUS_HAVE_NO_MEMORY(user_info->password.hash.nt);
463 *user_info->password.hash.nt = r->in.logon.password->ntpassword;
466 case NetlogonNetworkInformation:
467 case NetlogonNetworkTransitiveInformation:
469 /* TODO: we need to deny anonymous access here */
470 nt_status = auth_context_create(mem_ctx,
471 dce_call->event_ctx, dce_call->msg_ctx,
472 dce_call->conn->dce_ctx->lp_ctx,
474 NT_STATUS_NOT_OK_RETURN(nt_status);
476 nt_status = auth_context_set_challenge(auth_context, r->in.logon.network->challenge, "netr_LogonSamLogonWithFlags");
477 NT_STATUS_NOT_OK_RETURN(nt_status);
479 user_info->logon_parameters = r->in.logon.network->identity_info.parameter_control;
480 user_info->client.account_name = r->in.logon.network->identity_info.account_name.string;
481 user_info->client.domain_name = r->in.logon.network->identity_info.domain_name.string;
482 user_info->workstation_name = r->in.logon.network->identity_info.workstation.string;
484 user_info->password_state = AUTH_PASSWORD_RESPONSE;
485 user_info->password.response.lanman = data_blob_talloc(mem_ctx, r->in.logon.network->lm.data, r->in.logon.network->lm.length);
486 user_info->password.response.nt = data_blob_talloc(mem_ctx, r->in.logon.network->nt.data, r->in.logon.network->nt.length);
491 case NetlogonGenericInformation:
493 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
494 creds_arcfour_crypt(creds,
495 r->in.logon.generic->data, r->in.logon.generic->length);
497 /* Using DES to verify kerberos tickets makes no sense */
498 return NT_STATUS_INVALID_PARAMETER;
501 if (strcmp(r->in.logon.generic->package_name.string, "Kerberos") == 0) {
503 struct server_id *kdc;
504 struct kdc_check_generic_kerberos check;
505 struct netr_GenericInfo2 *generic = talloc_zero(mem_ctx, struct netr_GenericInfo2);
506 NT_STATUS_HAVE_NO_MEMORY(generic);
507 r->out.authoritative = 1;
509 /* TODO: Describe and deal with these flags */
512 r->out.validation.generic = generic;
514 kdc = irpc_servers_byname(dce_call->msg_ctx, mem_ctx, "kdc_server");
515 if ((kdc == NULL) || (kdc[0].id == 0)) {
516 return NT_STATUS_NO_LOGON_SERVERS;
519 check.in.generic_request =
520 data_blob_const(r->in.logon.generic->data,
521 r->in.logon.generic->length);
523 status = irpc_call(dce_call->msg_ctx, kdc[0],
524 &ndr_table_irpc, NDR_KDC_CHECK_GENERIC_KERBEROS,
526 if (!NT_STATUS_IS_OK(status)) {
529 generic->length = check.out.generic_reply.length;
530 generic->data = check.out.generic_reply.data;
534 /* Until we get an implemetnation of these other packages */
535 return NT_STATUS_INVALID_PARAMETER;
538 return NT_STATUS_INVALID_PARAMETER;
541 nt_status = auth_check_password(auth_context, mem_ctx, user_info, &server_info);
542 NT_STATUS_NOT_OK_RETURN(nt_status);
544 nt_status = auth_convert_server_info_sambaseinfo(mem_ctx, server_info, &sam);
545 NT_STATUS_NOT_OK_RETURN(nt_status);
547 /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
548 /* It appears that level 6 is not individually encrypted */
549 if ((r->in.validation_level != 6) &&
550 memcmp(sam->key.key, zeros, sizeof(sam->key.key)) != 0) {
551 /* This key is sent unencrypted without the ARCFOUR flag set */
552 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
553 creds_arcfour_crypt(creds,
555 sizeof(sam->key.key));
559 /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
560 /* It appears that level 6 is not individually encrypted */
561 if ((r->in.validation_level != 6) &&
562 memcmp(sam->LMSessKey.key, zeros, sizeof(sam->LMSessKey.key)) != 0) {
563 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
564 creds_arcfour_crypt(creds,
566 sizeof(sam->LMSessKey.key));
568 creds_des_encrypt_LMKey(creds,
573 switch (r->in.validation_level) {
575 sam2 = talloc_zero(mem_ctx, struct netr_SamInfo2);
576 NT_STATUS_HAVE_NO_MEMORY(sam2);
578 r->out.validation.sam2 = sam2;
582 sam3 = talloc_zero(mem_ctx, struct netr_SamInfo3);
583 NT_STATUS_HAVE_NO_MEMORY(sam3);
585 r->out.validation.sam3 = sam3;
589 sam6 = talloc_zero(mem_ctx, struct netr_SamInfo6);
590 NT_STATUS_HAVE_NO_MEMORY(sam6);
592 sam6->forest.string = lp_realm(dce_call->conn->dce_ctx->lp_ctx);
593 sam6->principle.string = talloc_asprintf(mem_ctx, "%s@%s",
594 sam->account_name.string, sam6->forest.string);
595 NT_STATUS_HAVE_NO_MEMORY(sam6->principle.string);
596 r->out.validation.sam6 = sam6;
603 r->out.authoritative = 1;
605 /* TODO: Describe and deal with these flags */
611 static NTSTATUS dcesrv_netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
612 struct netr_LogonSamLogonEx *r)
615 struct creds_CredentialState *creds;
616 nt_status = schannel_fetch_session_key(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, r->in.computer_name, lp_workgroup(dce_call->conn->dce_ctx->lp_ctx), &creds);
617 if (!NT_STATUS_IS_OK(nt_status)) {
621 if (!dce_call->conn->auth_state.auth_info ||
622 dce_call->conn->auth_state.auth_info->auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
623 return NT_STATUS_INTERNAL_ERROR;
625 return dcesrv_netr_LogonSamLogon_base(dce_call, mem_ctx, r, creds);
629 netr_LogonSamLogonWithFlags
632 static NTSTATUS dcesrv_netr_LogonSamLogonWithFlags(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
633 struct netr_LogonSamLogonWithFlags *r)
636 struct creds_CredentialState *creds;
637 struct netr_LogonSamLogonEx r2;
639 struct netr_Authenticator *return_authenticator;
641 return_authenticator = talloc(mem_ctx, struct netr_Authenticator);
642 NT_STATUS_HAVE_NO_MEMORY(return_authenticator);
644 nt_status = dcesrv_netr_creds_server_step_check(dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx,
645 r->in.computer_name, mem_ctx,
646 r->in.credential, return_authenticator,
648 NT_STATUS_NOT_OK_RETURN(nt_status);
652 r2.in.server_name = r->in.server_name;
653 r2.in.computer_name = r->in.computer_name;
654 r2.in.logon_level = r->in.logon_level;
655 r2.in.logon = r->in.logon;
656 r2.in.validation_level = r->in.validation_level;
657 r2.in.flags = r->in.flags;
659 nt_status = dcesrv_netr_LogonSamLogon_base(dce_call, mem_ctx, &r2, creds);
661 r->out.return_authenticator = return_authenticator;
662 r->out.validation = r2.out.validation;
663 r->out.authoritative = r2.out.authoritative;
664 r->out.flags = r2.out.flags;
672 static NTSTATUS dcesrv_netr_LogonSamLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
673 struct netr_LogonSamLogon *r)
675 struct netr_LogonSamLogonWithFlags r2;
680 r2.in.server_name = r->in.server_name;
681 r2.in.computer_name = r->in.computer_name;
682 r2.in.credential = r->in.credential;
683 r2.in.return_authenticator = r->in.return_authenticator;
684 r2.in.logon_level = r->in.logon_level;
685 r2.in.logon = r->in.logon;
686 r2.in.validation_level = r->in.validation_level;
689 status = dcesrv_netr_LogonSamLogonWithFlags(dce_call, mem_ctx, &r2);
691 r->out.return_authenticator = r2.out.return_authenticator;
692 r->out.validation = r2.out.validation;
693 r->out.authoritative = r2.out.authoritative;
702 static NTSTATUS dcesrv_netr_LogonSamLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
703 struct netr_LogonSamLogoff *r)
705 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
713 static NTSTATUS dcesrv_netr_DatabaseDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
714 struct netr_DatabaseDeltas *r)
716 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
723 static NTSTATUS dcesrv_netr_DatabaseSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
724 struct netr_DatabaseSync *r)
726 /* win2k3 native mode returns "NOT IMPLEMENTED" for this call */
727 return NT_STATUS_NOT_IMPLEMENTED;
734 static NTSTATUS dcesrv_netr_AccountDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
735 struct netr_AccountDeltas *r)
737 /* w2k3 returns "NOT IMPLEMENTED" for this call */
738 return NT_STATUS_NOT_IMPLEMENTED;
745 static NTSTATUS dcesrv_netr_AccountSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
746 struct netr_AccountSync *r)
748 /* w2k3 returns "NOT IMPLEMENTED" for this call */
749 return NT_STATUS_NOT_IMPLEMENTED;
756 static WERROR dcesrv_netr_GetDcName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
757 struct netr_GetDcName *r)
759 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
766 static WERROR dcesrv_netr_LogonControl(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
767 struct netr_LogonControl *r)
769 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
776 static WERROR dcesrv_netr_GetAnyDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
777 struct netr_GetAnyDCName *r)
779 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
786 static WERROR dcesrv_netr_LogonControl2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
787 struct netr_LogonControl2 *r)
789 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
796 static NTSTATUS dcesrv_netr_DatabaseSync2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
797 struct netr_DatabaseSync2 *r)
799 /* win2k3 native mode returns "NOT IMPLEMENTED" for this call */
800 return NT_STATUS_NOT_IMPLEMENTED;
807 static NTSTATUS dcesrv_netr_DatabaseRedo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
808 struct netr_DatabaseRedo *r)
810 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
817 static WERROR dcesrv_netr_LogonControl2Ex(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
818 struct netr_LogonControl2Ex *r)
820 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
825 netr_NetrEnumerateTurstedDomains
827 static WERROR dcesrv_netr_NetrEnumerateTrustedDomains(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
828 struct netr_NetrEnumerateTrustedDomains *r)
830 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
835 netr_NETRLOGONDUMMYROUTINE1
837 static WERROR dcesrv_netr_NETRLOGONDUMMYROUTINE1(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
838 struct netr_NETRLOGONDUMMYROUTINE1 *r)
840 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
845 netr_NETRLOGONSETSERVICEBITS
847 static WERROR dcesrv_netr_NETRLOGONSETSERVICEBITS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
848 struct netr_NETRLOGONSETSERVICEBITS *r)
850 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
855 netr_LogonGetTrustRid
857 static WERROR dcesrv_netr_LogonGetTrustRid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
858 struct netr_LogonGetTrustRid *r)
860 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
865 netr_NETRLOGONCOMPUTESERVERDIGEST
867 static WERROR dcesrv_netr_NETRLOGONCOMPUTESERVERDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
868 struct netr_NETRLOGONCOMPUTESERVERDIGEST *r)
870 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
875 netr_NETRLOGONCOMPUTECLIENTDIGEST
877 static WERROR dcesrv_netr_NETRLOGONCOMPUTECLIENTDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
878 struct netr_NETRLOGONCOMPUTECLIENTDIGEST *r)
880 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
888 static WERROR dcesrv_netr_DsRGetSiteName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
889 struct netr_DsRGetSiteName *r)
891 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
896 fill in a netr_DomainTrustInfo from a ldb search result
898 static NTSTATUS fill_domain_trust_info(TALLOC_CTX *mem_ctx,
899 struct ldb_message *res,
900 struct ldb_message *ref_res,
901 struct netr_DomainTrustInfo *info,
902 bool is_local, bool is_trust_list)
906 info->trust_extension.info = talloc_zero(mem_ctx, struct netr_trust_extension);
907 info->trust_extension.length = 16;
908 info->trust_extension.info->flags =
909 NETR_TRUST_FLAG_TREEROOT |
910 NETR_TRUST_FLAG_IN_FOREST |
911 NETR_TRUST_FLAG_PRIMARY;
912 info->trust_extension.info->parent_index = 0; /* should be index into array
914 info->trust_extension.info->trust_type = LSA_TRUST_TYPE_UPLEVEL; /* should be based on ldb search for trusts */
915 info->trust_extension.info->trust_attributes = LSA_TRUST_ATTRIBUTE_NON_TRANSITIVE; /* needs to be based on ldb search */
918 /* MS-NRPC 3.5.4.3.9 - must be set to NULL for trust list */
919 info->forest.string = NULL;
921 info->forest.string = "bludom.tridgell.net"; /* need ldb search */
925 info->domainname.string = samdb_result_string(ref_res, "nETBIOSName", NULL);
926 info->fulldomainname.string = samdb_result_string(ref_res, "dnsRoot", NULL);
927 info->guid = samdb_result_guid(res, "objectGUID");
928 info->sid = samdb_result_dom_sid(mem_ctx, res, "objectSid");
930 info->domainname.string = samdb_result_string(res, "flatName", NULL);
931 info->fulldomainname.string = samdb_result_string(res, "trustPartner", NULL);
932 info->guid = samdb_result_guid(res, "objectGUID");
933 info->sid = samdb_result_dom_sid(mem_ctx, res, "securityIdentifier");
940 netr_LogonGetDomainInfo
941 this is called as part of the ADS domain logon procedure.
943 It has an important role in convaying details about the client, such
944 as Operating System, Version, Service Pack etc.
946 static NTSTATUS dcesrv_netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
947 struct netr_LogonGetDomainInfo *r)
949 const char * const attrs[] = { "objectSid",
950 "objectGUID", "flatName", "securityIdentifier",
951 "trustPartner", NULL };
952 const char * const ref_attrs[] = { "nETBIOSName", "dnsRoot", NULL };
953 struct ldb_context *sam_ctx;
954 struct ldb_message **res1, **res2, **ref_res;
955 struct netr_DomainInfo1 *info1;
956 int ret, ret1, ret2, i;
958 struct ldb_dn *partitions_basedn;
960 const char *local_domain;
962 NDR_PRINT_IN_DEBUG(netr_LogonGetDomainInfo, r);
964 status = dcesrv_netr_creds_server_step_check(dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx,
965 r->in.computer_name, mem_ctx,
967 r->out.return_authenticator,
969 if (!NT_STATUS_IS_OK(status)) {
970 DEBUG(0,(__location__ " Bad credentials - error\n"));
972 NT_STATUS_NOT_OK_RETURN(status);
974 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
975 if (sam_ctx == NULL) {
976 return NT_STATUS_INVALID_SYSTEM_SERVICE;
979 partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);
981 /* we need to do two searches. The first will pull our primary
982 domain and the second will pull any trusted domains. Our
983 primary domain is also a "trusted" domain, so we need to
984 put the primary domain into the lists of returned trusts as
986 ret1 = gendb_search_dn(sam_ctx, mem_ctx, samdb_base_dn(sam_ctx), &res1, attrs);
988 return NT_STATUS_INTERNAL_DB_CORRUPTION;
991 /* try and find the domain */
992 ret = gendb_search(sam_ctx, mem_ctx, partitions_basedn,
994 "(&(objectClass=crossRef)(ncName=%s))",
995 ldb_dn_get_linearized(res1[0]->dn));
997 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1000 local_domain = samdb_result_string(ref_res[0], "nETBIOSName", NULL);
1002 ret2 = gendb_search(sam_ctx, mem_ctx, NULL, &res2, attrs, "(objectClass=trustedDomain)");
1004 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1007 info1 = talloc(mem_ctx, struct netr_DomainInfo1);
1008 NT_STATUS_HAVE_NO_MEMORY(info1);
1010 ZERO_STRUCTP(info1);
1012 info1->num_trusts = ret2 + 1;
1013 info1->trusts = talloc_array(mem_ctx, struct netr_DomainTrustInfo,
1015 NT_STATUS_HAVE_NO_MEMORY(info1->trusts);
1017 status = fill_domain_trust_info(mem_ctx, res1[0], ref_res[0], &info1->domaininfo,
1019 NT_STATUS_NOT_OK_RETURN(status);
1021 for (i=0;i<ret2;i++) {
1022 status = fill_domain_trust_info(mem_ctx, res2[i], NULL, &info1->trusts[i],
1024 NT_STATUS_NOT_OK_RETURN(status);
1027 status = fill_domain_trust_info(mem_ctx, res1[0], ref_res[0], &info1->trusts[i],
1029 NT_STATUS_NOT_OK_RETURN(status);
1031 info1->dns_hostname.string = "blu.bludom.tridgell.net";
1032 info1->workstation_flags =
1033 NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS | NETR_WS_FLAG_HANDLES_SPN_UPDATE;
1034 info1->supported_enc_types = 0; /* w2008 gives this 0 */
1036 r->out.info.info1 = info1;
1038 NDR_PRINT_OUT_DEBUG(netr_LogonGetDomainInfo, r);
1040 return NT_STATUS_OK;
1046 netr_ServerPasswordGet
1048 static WERROR dcesrv_netr_ServerPasswordGet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1049 struct netr_ServerPasswordGet *r)
1051 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1056 netr_NETRLOGONSENDTOSAM
1058 static WERROR dcesrv_netr_NETRLOGONSENDTOSAM(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1059 struct netr_NETRLOGONSENDTOSAM *r)
1061 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1066 netr_DsRAddressToSitenamesW
1068 static WERROR dcesrv_netr_DsRAddressToSitenamesW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1069 struct netr_DsRAddressToSitenamesW *r)
1071 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1076 netr_DsRGetDCNameEx2
1078 static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1079 struct netr_DsRGetDCNameEx2 *r)
1081 const char * const attrs[] = { "dnsDomain", "objectGUID", NULL };
1083 struct ldb_message **res;
1084 struct ldb_dn *domain_dn;
1087 ZERO_STRUCT(r->out);
1089 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
1090 if (sam_ctx == NULL) {
1091 return WERR_DS_SERVICE_UNAVAILABLE;
1094 domain_dn = samdb_dns_domain_to_dn(sam_ctx, mem_ctx,
1096 if (domain_dn == NULL) {
1097 return WERR_DS_SERVICE_UNAVAILABLE;
1100 ret = gendb_search_dn(sam_ctx, mem_ctx, domain_dn, &res, attrs);
1102 return WERR_NO_SUCH_DOMAIN;
1105 r->out.info = talloc(mem_ctx, struct netr_DsRGetDCNameInfo);
1106 W_ERROR_HAVE_NO_MEMORY(r->out.info);
1108 /* TODO: - return real IP address
1109 * - check all r->in.* parameters (server_unc is ignored by w2k3!)
1111 r->out.info->dc_unc = talloc_asprintf(mem_ctx, "\\\\%s.%s",
1112 lp_netbios_name(dce_call->conn->dce_ctx->lp_ctx),
1113 lp_realm(dce_call->conn->dce_ctx->lp_ctx));
1114 W_ERROR_HAVE_NO_MEMORY(r->out.info->dc_unc);
1115 r->out.info->dc_address = talloc_strdup(mem_ctx, "\\\\0.0.0.0");
1116 W_ERROR_HAVE_NO_MEMORY(r->out.info->dc_address);
1117 r->out.info->dc_address_type = DS_ADDRESS_TYPE_INET;
1118 r->out.info->domain_guid = samdb_result_guid(res[0], "objectGUID");
1119 r->out.info->domain_name = samdb_result_string(res[0], "dnsDomain", NULL);
1120 r->out.info->forest_name = samdb_result_string(res[0], "dnsDomain", NULL);
1121 r->out.info->dc_flags = DS_DNS_FOREST |
1124 DS_SERVER_WRITABLE |
1126 DS_SERVER_TIMESERV |
1132 r->out.info->dc_site_name = talloc_strdup(mem_ctx, "Default-First-Site-Name");
1133 W_ERROR_HAVE_NO_MEMORY(r->out.info->dc_site_name);
1134 r->out.info->client_site_name = talloc_strdup(mem_ctx, "Default-First-Site-Name");
1135 W_ERROR_HAVE_NO_MEMORY(r->out.info->client_site_name);
1143 static WERROR dcesrv_netr_DsRGetDCNameEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1144 struct netr_DsRGetDCNameEx *r)
1146 struct netr_DsRGetDCNameEx2 r2;
1151 r2.in.server_unc = r->in.server_unc;
1152 r2.in.client_account = NULL;
1154 r2.in.domain_guid = r->in.domain_guid;
1155 r2.in.domain_name = r->in.domain_name;
1156 r2.in.site_name = r->in.site_name;
1157 r2.in.flags = r->in.flags;
1160 werr = dcesrv_netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1162 r->out.info = r2.out.info;
1170 static WERROR dcesrv_netr_DsRGetDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1171 struct netr_DsRGetDCName *r)
1173 struct netr_DsRGetDCNameEx2 r2;
1178 r2.in.server_unc = r->in.server_unc;
1179 r2.in.client_account = NULL;
1181 r2.in.domain_name = r->in.domain_name;
1182 r2.in.domain_guid = r->in.domain_guid;
1184 r2.in.site_name = NULL; /* should fill in from site GUID */
1185 r2.in.flags = r->in.flags;
1188 werr = dcesrv_netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1190 r->out.info = r2.out.info;
1196 netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN
1198 static WERROR dcesrv_netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1199 struct netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN *r)
1201 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1206 netr_NetrEnumerateTrustedDomainsEx
1208 static WERROR dcesrv_netr_NetrEnumerateTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1209 struct netr_NetrEnumerateTrustedDomainsEx *r)
1211 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1216 netr_DsRAddressToSitenamesExW
1218 static WERROR dcesrv_netr_DsRAddressToSitenamesExW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1219 struct netr_DsRAddressToSitenamesExW *r)
1221 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1226 netr_DsrGetDcSiteCoverageW
1228 static WERROR dcesrv_netr_DsrGetDcSiteCoverageW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1229 struct netr_DsrGetDcSiteCoverageW *r)
1231 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1236 netr_DsrEnumerateDomainTrusts
1238 static WERROR dcesrv_netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1239 struct netr_DsrEnumerateDomainTrusts *r)
1241 struct netr_DomainTrust *trusts;
1244 struct ldb_message **dom_res, **ref_res;
1245 const char * const dom_attrs[] = { "objectSid", "objectGUID", NULL };
1246 const char * const ref_attrs[] = { "nETBIOSName", "dnsRoot", NULL };
1247 struct ldb_dn *partitions_basedn;
1249 ZERO_STRUCT(r->out);
1251 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
1252 if (sam_ctx == NULL) {
1253 return WERR_GENERAL_FAILURE;
1256 partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);
1258 ret = gendb_search_dn(sam_ctx, mem_ctx, NULL, &dom_res, dom_attrs);
1260 return WERR_GENERAL_FAILURE;
1263 return WERR_GENERAL_FAILURE;
1266 ret = gendb_search(sam_ctx, mem_ctx, partitions_basedn, &ref_res, ref_attrs,
1267 "(&(objectClass=crossRef)(ncName=%s))",
1268 ldb_dn_get_linearized(dom_res[0]->dn));
1270 return WERR_GENERAL_FAILURE;
1273 return WERR_GENERAL_FAILURE;
1276 trusts = talloc_array(mem_ctx, struct netr_DomainTrust, ret);
1277 W_ERROR_HAVE_NO_MEMORY(trusts);
1280 r->out.trusts = trusts;
1282 /* TODO: add filtering by trust_flags, and correct trust_type
1284 trusts[0].netbios_name = samdb_result_string(ref_res[0], "nETBIOSName", NULL);
1285 trusts[0].dns_name = samdb_result_string(ref_res[0], "dnsRoot", NULL);
1286 trusts[0].trust_flags =
1287 NETR_TRUST_FLAG_TREEROOT |
1288 NETR_TRUST_FLAG_IN_FOREST |
1289 NETR_TRUST_FLAG_PRIMARY;
1290 trusts[0].parent_index = 0;
1291 trusts[0].trust_type = 2;
1292 trusts[0].trust_attributes = 0;
1293 trusts[0].sid = samdb_result_dom_sid(mem_ctx, dom_res[0], "objectSid");
1294 trusts[0].guid = samdb_result_guid(dom_res[0], "objectGUID");
1301 netr_DsrDeregisterDNSHostRecords
1303 static WERROR dcesrv_netr_DsrDeregisterDNSHostRecords(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1304 struct netr_DsrDeregisterDNSHostRecords *r)
1306 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1311 netr_ServerTrustPasswordsGet
1313 static NTSTATUS dcesrv_netr_ServerTrustPasswordsGet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1314 struct netr_ServerTrustPasswordsGet *r)
1316 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1321 netr_DsRGetForestTrustInformation
1323 static WERROR dcesrv_netr_DsRGetForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1324 struct netr_DsRGetForestTrustInformation *r)
1326 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1331 netr_GetForestTrustInformation
1333 static WERROR dcesrv_netr_GetForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1334 struct netr_GetForestTrustInformation *r)
1336 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1341 netr_NETRSERVERGETTRUSTINFO
1343 static WERROR dcesrv_netr_NETRSERVERGETTRUSTINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1344 struct netr_NETRSERVERGETTRUSTINFO *r)
1346 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1350 /* include the generated boilerplate */
1351 #include "librpc/gen_ndr/ndr_netlogon_s.c"