r1150: - fixed interactive sam logon in the rpc server
[nivanova/samba-autobuild/.git] / source4 / rpc_server / netlogon / dcerpc_netlogon.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    endpoint server for the netlogon pipe
5
6    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004
7    
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #include "includes.h"
24 #include "rpc_server/common/common.h"
25
26 struct server_pipe_state {
27         TALLOC_CTX *mem_ctx;
28         struct netr_Credential client_challenge;
29         struct netr_Credential server_challenge;
30         BOOL authenticated;
31         char *account_name;
32         char *computer_name;  /* for logging only */
33         uint32_t acct_flags;
34         uint16_t sec_chan_type;
35         struct creds_CredentialState *creds;
36 };
37
38
39 /*
40   a client has connected to the netlogon server using schannel, so we need
41   to re-establish the credentials state
42 */
43 static NTSTATUS netlogon_schannel_setup(struct dcesrv_call_state *dce_call) 
44 {
45         struct server_pipe_state *state;
46         NTSTATUS status;
47         TALLOC_CTX *mem_ctx;
48
49         mem_ctx = talloc_init("netlogon_bind");
50         if (!mem_ctx) {
51                 return NT_STATUS_NO_MEMORY;
52         }
53         state = talloc_p(mem_ctx, struct server_pipe_state);
54         if (state == NULL) {
55                 talloc_destroy(mem_ctx);
56         }
57         ZERO_STRUCTP(state);
58         state->mem_ctx = mem_ctx;
59         state->authenticated = True;
60         
61         state->creds = talloc_p(mem_ctx, struct creds_CredentialState);
62         if (state->creds == NULL) {
63                 talloc_destroy(mem_ctx);
64                 return NT_STATUS_NO_MEMORY;
65         }
66         ZERO_STRUCTP(state->creds);
67         
68         if (dce_call->conn->auth_state.session_info == NULL) {
69                 talloc_destroy(mem_ctx);
70                 return NT_STATUS_NO_USER_SESSION_KEY;
71         }
72         
73         status = schannel_fetch_session_key(mem_ctx, 
74                                             dce_call->conn->auth_state.session_info->workstation, 
75                                             state->creds);
76         if (!NT_STATUS_IS_OK(status)) {
77                 talloc_destroy(mem_ctx);
78                 return status;
79         }
80         
81         dce_call->conn->private = state;
82
83         return NT_STATUS_OK;
84 }
85
86 /*
87   a hook for bind on the netlogon pipe
88 */
89 static NTSTATUS netlogon_bind(struct dcesrv_call_state *dce_call, const struct dcesrv_interface *di) 
90 {
91         dce_call->conn->private = NULL;
92
93         /* if this is a schannel bind then we need to reconstruct the pipe state */
94         if (dce_call->conn->auth_state.auth_info &&
95             dce_call->conn->auth_state.auth_info->auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
96                 NTSTATUS status;
97
98                 status = netlogon_schannel_setup(dce_call);
99                 if (!NT_STATUS_IS_OK(status)) {
100                         return status;
101                 }
102         }
103
104         return NT_STATUS_OK;
105 }
106
107 /* this function is called when the client disconnects the endpoint */
108 static void netlogon_unbind(struct dcesrv_connection *conn, const struct dcesrv_interface *di) 
109 {
110         struct server_pipe_state *pipe_state = conn->private;
111
112         if (pipe_state) {
113                 talloc_destroy(pipe_state->mem_ctx);
114         }
115
116         conn->private = NULL;
117 }
118
119 #define DCESRV_INTERFACE_NETLOGON_BIND netlogon_bind
120 #define DCESRV_INTERFACE_NETLOGON_UNBIND netlogon_unbind
121
122 static NTSTATUS netr_ServerReqChallenge(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
123                                         struct netr_ServerReqChallenge *r)
124 {
125         struct server_pipe_state *pipe_state = dce_call->conn->private;
126         TALLOC_CTX *pipe_mem_ctx;
127
128         ZERO_STRUCTP(r->out.credentials);
129
130         /* destroyed on pipe shutdown */
131
132         if (pipe_state) {
133                 talloc_destroy(pipe_state->mem_ctx);
134                 dce_call->conn->private = NULL;
135         }
136         
137         pipe_mem_ctx = talloc_init("internal netlogon pipe state for %s", 
138                                    r->in.computer_name);
139         
140         if (!pipe_mem_ctx) {
141                 return NT_STATUS_NO_MEMORY;
142         }
143
144         pipe_state = talloc_p(pipe_mem_ctx, struct server_pipe_state);
145         if (!pipe_state) {
146                 talloc_destroy(pipe_mem_ctx);
147                 return NT_STATUS_NO_MEMORY;
148         }
149
150         pipe_state->mem_ctx = pipe_mem_ctx;
151         pipe_state->authenticated = False;
152         pipe_state->creds = NULL;
153         pipe_state->account_name = NULL;
154         pipe_state->computer_name = NULL;
155
156         pipe_state->client_challenge = *r->in.credentials;
157
158         generate_random_buffer(pipe_state->server_challenge.data, 
159                                sizeof(pipe_state->server_challenge.data),
160                                False);
161
162         *r->out.credentials = pipe_state->server_challenge;
163
164         dce_call->conn->private = pipe_state;
165
166         return NT_STATUS_OK;
167 }
168
169 static NTSTATUS netr_ServerAuthenticate3(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
170                                          struct netr_ServerAuthenticate3 *r)
171 {
172         struct server_pipe_state *pipe_state = dce_call->conn->private;
173         void *sam_ctx;
174         struct samr_Password *mach_pwd;
175         uint16_t acct_flags;
176         int num_records;
177         struct ldb_message **msgs;
178         NTSTATUS nt_status;
179         const char *attrs[] = {"unicodePwd", "lmPwdHash", "ntPwdHash", "userAccountControl", 
180                                "objectSid", NULL};
181
182         ZERO_STRUCTP(r->out.credentials);
183         *r->out.rid = 0;
184         *r->out.negotiate_flags = *r->in.negotiate_flags;
185
186         if (!pipe_state) {
187                 DEBUG(1, ("No challenge requested by client, cannot authenticate\n"));
188                 return NT_STATUS_ACCESS_DENIED;
189         }
190
191         sam_ctx = samdb_connect();
192         if (sam_ctx == NULL) {
193                 return NT_STATUS_INVALID_SYSTEM_SERVICE;
194         }
195         /* pull the user attributes */
196         num_records = samdb_search(sam_ctx, mem_ctx, NULL, &msgs, attrs,
197                                    "(&(sAMAccountName=%s)(objectclass=user))", 
198                                    r->in.account_name);
199
200         if (num_records == 0) {
201                 DEBUG(3,("Couldn't find user [%s] in samdb.\n", 
202                          r->in.account_name));
203                 samdb_close(sam_ctx);
204                 return NT_STATUS_NO_SUCH_USER;
205         }
206
207         if (num_records > 1) {
208                 DEBUG(1,("Found %d records matching user [%s]\n", num_records, r->in.account_name));
209                 samdb_close(sam_ctx);
210                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
211         }
212
213         acct_flags = samdb_result_acct_flags(msgs[0], 
214                                              "userAccountControl");
215
216         if (acct_flags & ACB_DISABLED) {
217                 DEBUG(1, ("Account [%s] is disabled\n", r->in.account_name));
218                 return NT_STATUS_ACCESS_DENIED;
219         }
220
221         if (r->in.secure_channel_type == SEC_CHAN_WKSTA) {
222                 if (!(acct_flags & ACB_WSTRUST)) {
223                         DEBUG(1, ("Client asked for a workstation secure channel, but is not a workstation (member server) acb flags: 0x%x\n", acct_flags));
224                         return NT_STATUS_ACCESS_DENIED;
225                 }
226         } else if (r->in.secure_channel_type == SEC_CHAN_DOMAIN) {
227                 if (!(acct_flags & ACB_DOMTRUST)) {
228                         DEBUG(1, ("Client asked for a trusted domain secure channel, but is not a trusted domain: acb flags: 0x%x\n", acct_flags));
229                         return NT_STATUS_ACCESS_DENIED;
230                 }
231         } else if (r->in.secure_channel_type == SEC_CHAN_BDC) {
232                 if (!(acct_flags & ACB_SVRTRUST)) {
233                         DEBUG(1, ("Client asked for a server secure channel, but is not a server (domain controller): acb flags: 0x%x\n", acct_flags));
234                         return NT_STATUS_ACCESS_DENIED;
235                 }
236         } else {
237                 DEBUG(1, ("Client asked for an invalid secure channel type: %d\n", 
238                           r->in.secure_channel_type));
239                 return NT_STATUS_ACCESS_DENIED;
240         }
241
242         pipe_state->acct_flags = acct_flags;
243         pipe_state->sec_chan_type = r->in.secure_channel_type;
244
245         *r->out.rid = samdb_result_rid_from_sid(mem_ctx, msgs[0], "objectSid", 0);
246
247         nt_status = samdb_result_passwords(mem_ctx, msgs[0], NULL, &mach_pwd);
248         if (!NT_STATUS_IS_OK(nt_status) || mach_pwd == NULL) {
249                 samdb_close(sam_ctx);
250                 return NT_STATUS_ACCESS_DENIED;
251         }
252
253         samdb_close(sam_ctx);
254
255         if (!pipe_state->creds) {
256                 pipe_state->creds = talloc_p(pipe_state->mem_ctx, struct creds_CredentialState);
257                 if (!pipe_state->creds) {
258                         return NT_STATUS_NO_MEMORY;
259                 }
260         }
261
262         creds_server_init(pipe_state->creds, &pipe_state->client_challenge, 
263                           &pipe_state->server_challenge, mach_pwd,
264                           r->out.credentials,
265                           *r->in.negotiate_flags);
266         
267         if (!creds_server_check(pipe_state->creds, r->in.credentials)) {
268                 return NT_STATUS_ACCESS_DENIED;
269         }
270
271         pipe_state->authenticated = True;
272
273         if (pipe_state->account_name) {
274                 /* We don't want a memory leak on this long-lived talloc context */
275                 talloc_free(pipe_state->mem_ctx, pipe_state->account_name);
276         }
277
278         pipe_state->account_name = talloc_strdup(pipe_state->mem_ctx, r->in.account_name);
279         
280         if (pipe_state->computer_name) {
281                 /* We don't want a memory leak on this long-lived talloc context */
282                 talloc_free(pipe_state->mem_ctx, pipe_state->account_name);
283         }
284
285         pipe_state->computer_name = talloc_strdup(pipe_state->mem_ctx, r->in.computer_name);
286
287         /* remember this session key state */
288         nt_status = schannel_store_session_key(mem_ctx, pipe_state->computer_name, pipe_state->creds);
289
290         return nt_status;
291 }
292                                                  
293 static NTSTATUS netr_ServerAuthenticate(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
294                                         struct netr_ServerAuthenticate *r)
295 {
296         struct netr_ServerAuthenticate3 r3;
297         uint32 negotiate_flags, rid;
298
299         r3.in.server_name = r->in.server_name;
300         r3.in.account_name = r->in.account_name;
301         r3.in.secure_channel_type = r->in.secure_channel_type;
302         r3.in.computer_name = r->in.computer_name;
303         r3.in.credentials = r->in.credentials;
304         r3.out.credentials = r->out.credentials;
305         r3.in.negotiate_flags = &negotiate_flags;
306         r3.out.negotiate_flags = &negotiate_flags;
307         r3.out.rid = &rid;
308         
309         return netr_ServerAuthenticate3(dce_call, mem_ctx, &r3);
310 }
311
312 static NTSTATUS netr_ServerAuthenticate2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
313                                          struct netr_ServerAuthenticate2 *r)
314 {
315         struct netr_ServerAuthenticate3 r3;
316         uint32 rid;
317
318         r3.in.server_name = r->in.server_name;
319         r3.in.account_name = r->in.account_name;
320         r3.in.secure_channel_type = r->in.secure_channel_type;
321         r3.in.computer_name = r->in.computer_name;
322         r3.in.credentials = r->in.credentials;
323         r3.out.credentials = r->out.credentials;
324         r3.in.negotiate_flags = r->in.negotiate_flags;
325         r3.out.negotiate_flags = r->out.negotiate_flags;
326         r3.out.rid = &rid;
327         
328         return netr_ServerAuthenticate3(dce_call, mem_ctx, &r3);
329 }
330
331
332 static BOOL netr_creds_server_step_check(struct server_pipe_state *pipe_state,
333                                          struct netr_Authenticator *received_authenticator,
334                                          struct netr_Authenticator *return_authenticator) 
335 {
336         if (!pipe_state->authenticated) {
337                 return False;
338         }
339         return creds_server_step_check(pipe_state->creds, 
340                                        received_authenticator, 
341                                        return_authenticator);
342 }
343
344
345 static NTSTATUS netr_ServerPasswordSet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
346                                        struct netr_ServerPasswordSet *r)
347 {
348         struct server_pipe_state *pipe_state = dce_call->conn->private;
349
350         void *sam_ctx;
351         int num_records;
352         int num_records_domain;
353         int ret;
354         struct ldb_message **msgs;
355         struct ldb_message **msgs_domain;
356         NTSTATUS nt_status;
357         struct ldb_message mod, *msg_set_pw = &mod;
358         const char *domain_dn;
359         const char *domain_sid;
360
361         const char *attrs[] = {"objectSid", NULL };
362
363         const char **domain_attrs = attrs;
364         ZERO_STRUCT(mod);
365
366         if (!pipe_state) {
367                 DEBUG(1, ("No challenge requested by client, cannot authenticate\n"));
368                 return NT_STATUS_ACCESS_DENIED;
369         }
370
371         if (!netr_creds_server_step_check(pipe_state, &r->in.credential, &r->out.return_authenticator)) {
372                 return NT_STATUS_ACCESS_DENIED;
373         }
374
375         sam_ctx = samdb_connect();
376         if (sam_ctx == NULL) {
377                 return NT_STATUS_INVALID_SYSTEM_SERVICE;
378         }
379         /* pull the user attributes */
380         num_records = samdb_search(sam_ctx, mem_ctx, NULL, &msgs, attrs,
381                                    "(&(sAMAccountName=%s)(objectclass=user))", 
382                                    pipe_state->account_name);
383
384         if (num_records == 0) {
385                 DEBUG(3,("Couldn't find user [%s] in samdb.\n", 
386                          pipe_state->account_name));
387                 samdb_close(sam_ctx);
388                 return NT_STATUS_NO_SUCH_USER;
389         }
390
391         if (num_records > 1) {
392                 DEBUG(1,("Found %d records matching user [%s]\n", num_records, 
393                          pipe_state->account_name));
394                 samdb_close(sam_ctx);
395                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
396         }
397
398         domain_sid = samdb_result_sid_prefix(mem_ctx, msgs[0], "objectSid");
399         if (!domain_sid) {
400                 samdb_close(sam_ctx);
401                 DEBUG(1,("no objectSid in user record\n"));
402                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
403         }
404
405         /* find the domain's DN */
406         num_records_domain = samdb_search(sam_ctx, mem_ctx, NULL, 
407                                           &msgs_domain, domain_attrs,
408                                           "(&(objectSid=%s)(objectclass=domain))", 
409                                           domain_sid);
410
411         if (num_records_domain == 0) {
412                 DEBUG(3,("check_sam_security: Couldn't find domain [%s] in passdb file.\n", 
413                          domain_sid));
414                 samdb_close(sam_ctx);
415                 return NT_STATUS_NO_SUCH_USER;
416         }
417
418         if (num_records_domain > 1) {
419                 DEBUG(1,("Found %d records matching domain [%s]\n", 
420                          num_records_domain, domain_sid));
421                 samdb_close(sam_ctx);
422                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
423         }
424
425         domain_dn = msgs_domain[0]->dn;
426         
427         mod.dn = talloc_strdup(mem_ctx, msgs[0]->dn);
428         if (!mod.dn) {
429                 samdb_close(sam_ctx);
430                 return NT_STATUS_NO_MEMORY;
431         }
432         
433         creds_des_decrypt(pipe_state->creds, &r->in.new_password);
434
435         /* set the password - samdb needs to know both the domain and user DNs,
436            so the domain password policy can be used */
437         nt_status = samdb_set_password(sam_ctx, mem_ctx,
438                                        msgs[0]->dn, domain_dn,
439                                        msg_set_pw, 
440                                        NULL, /* Don't have plaintext */
441                                        NULL, &r->in.new_password,
442                                        False /* This is not considered a password change */,
443                                        NULL);
444         
445         if (!NT_STATUS_IS_OK(nt_status)) {
446                 samdb_close(sam_ctx);
447                 return nt_status;
448         }
449
450         ret = samdb_replace(sam_ctx, mem_ctx, msg_set_pw);
451         if (ret != 0) {
452                 /* we really need samdb.c to return NTSTATUS */
453
454                 samdb_close(sam_ctx);
455                 return NT_STATUS_UNSUCCESSFUL;
456         }
457
458         samdb_close(sam_ctx);
459         return NT_STATUS_OK;
460 }
461
462
463 /* 
464   netr_LogonUasLogon 
465 */
466 static WERROR netr_LogonUasLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
467                                  struct netr_LogonUasLogon *r)
468 {
469         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
470 }
471
472
473 /* 
474   netr_LogonUasLogoff 
475 */
476 static WERROR netr_LogonUasLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
477                        struct netr_LogonUasLogoff *r)
478 {
479         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
480 }
481
482
483 /* 
484   netr_LogonSamLogonWithFlags
485
486 */
487 static NTSTATUS netr_LogonSamLogonWithFlags(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
488                                             struct netr_LogonSamLogonWithFlags *r)
489 {
490         struct server_pipe_state *pipe_state = dce_call->conn->private;
491
492         struct auth_context *auth_context;
493         struct auth_usersupplied_info *user_info;
494         struct auth_serversupplied_info *server_info;
495         NTSTATUS nt_status;
496         const uint8_t *chal;
497         static const char zeros[16];
498         struct netr_SamBaseInfo *sam;
499         struct netr_SamInfo2 *sam2;
500         struct netr_SamInfo3 *sam3;
501         struct netr_SamInfo6 *sam6;
502         
503         if (!pipe_state) {
504                 DEBUG(1, ("No challenge requested by client, cannot authenticate\n"));
505                 return NT_STATUS_ACCESS_DENIED;
506         }
507
508         r->out.return_authenticator = talloc_p(mem_ctx, struct netr_Authenticator);
509         if (!r->out.return_authenticator) {
510                 return NT_STATUS_NO_MEMORY;
511         }
512
513         if (!netr_creds_server_step_check(pipe_state, r->in.credential, r->out.return_authenticator)) {
514                 return NT_STATUS_ACCESS_DENIED;
515         }
516
517         switch (r->in.logon_level) {
518         case 1:
519         case 3:
520         case 5:
521                 creds_arcfour_crypt(pipe_state->creds, 
522                                     r->in.logon.password->lmpassword.hash, 
523                                     sizeof(r->in.logon.password->lmpassword.hash));
524                 creds_arcfour_crypt(pipe_state->creds, 
525                                     r->in.logon.password->ntpassword.hash, 
526                                     sizeof(r->in.logon.password->ntpassword.hash));
527
528                 nt_status = make_auth_context_subsystem(&auth_context);
529                 if (!NT_STATUS_IS_OK(nt_status)) {
530                         return nt_status;
531                 }
532
533                 chal = auth_context->get_ntlm_challenge(auth_context);
534                 nt_status = make_user_info_netlogon_interactive(&user_info,
535                                                                 r->in.logon.password->identity_info.account_name.string,
536                                                                 r->in.logon.password->identity_info.domain_name.string,
537                                                                 r->in.logon.password->identity_info.workstation.string,
538                                                                 chal,
539                                                                 &r->in.logon.password->lmpassword,
540                                                                 &r->in.logon.password->ntpassword);
541                 break;
542                 
543         case 2:
544         case 6:
545                 nt_status = make_auth_context_fixed(&auth_context, r->in.logon.network->challenge);
546                 if (!NT_STATUS_IS_OK(nt_status)) {
547                         return nt_status;
548                 }
549
550                 nt_status = make_user_info_netlogon_network(&user_info,
551                                                             r->in.logon.network->identity_info.account_name.string,
552                                                             r->in.logon.network->identity_info.domain_name.string,
553                                                             r->in.logon.network->identity_info.workstation.string,
554                                                             r->in.logon.network->lm.data, r->in.logon.network->lm.length,
555                                                             r->in.logon.network->nt.data, r->in.logon.network->nt.length);
556                 break;
557         default:
558                 free_auth_context(&auth_context);
559                 return NT_STATUS_INVALID_PARAMETER;
560         }
561         
562         if (!NT_STATUS_IS_OK(nt_status)) {
563                 return nt_status;
564         }
565
566         nt_status = auth_context->check_ntlm_password(auth_context,
567                                                       user_info, 
568                                                       &server_info);
569
570         if (!NT_STATUS_IS_OK(nt_status)) {
571                 free_auth_context(&auth_context);
572                 return nt_status;
573         }
574         free_auth_context(&auth_context);
575
576         sam = talloc_p(mem_ctx, struct netr_SamBaseInfo);
577
578         ZERO_STRUCTP(sam);
579         
580         sam->last_logon = server_info->last_logon;
581         sam->last_logoff = server_info->last_logoff;
582         sam->acct_expiry = server_info->acct_expiry;
583         sam->last_password_change = server_info->last_password_change;
584         sam->allow_password_change = server_info->allow_password_change;
585         sam->force_password_change = server_info->force_password_change;
586         
587         sam->account_name.string = talloc_strdup(mem_ctx, server_info->account_name);
588         sam->full_name.string = talloc_strdup(mem_ctx, server_info->full_name);
589         sam->logon_script.string = talloc_strdup(mem_ctx, server_info->logon_script);
590         sam->profile_path.string = talloc_strdup(mem_ctx, server_info->profile_path);
591         sam->home_directory.string = talloc_strdup(mem_ctx, server_info->home_directory);
592         sam->home_drive.string = talloc_strdup(mem_ctx, server_info->home_drive);
593         
594         sam->logon_count = server_info->logon_count;
595         sam->bad_password_count = sam->bad_password_count;
596         sam->rid = server_info->user_sid->sub_auths[server_info->user_sid->num_auths-1];
597         sam->primary_gid = server_info->primary_group_sid->sub_auths[server_info->primary_group_sid->num_auths-1];
598         sam->group_count = 0;
599         sam->groupids = NULL;
600         sam->user_flags = 0; /* TODO: w2k3 uses 0x120 - what is this? */
601         sam->acct_flags = server_info->acct_flags;      
602         sam->logon_server.string = lp_netbios_name();
603         
604         sam->domain.string = talloc_strdup(mem_ctx, server_info->domain);
605         
606         sam->domain_sid = dom_sid_dup(mem_ctx, server_info->user_sid);
607         sam->domain_sid->num_auths--;
608
609         if (server_info->user_session_key.length == sizeof(sam->key.key)) {
610                 memcpy(sam->key.key, server_info->user_session_key.data, sizeof(sam->key.key));
611         } else {
612                 ZERO_STRUCT(sam->key.key);
613         }
614         
615         /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
616         if (memcmp(sam->key.key, zeros,  
617                    sizeof(sam->key.key)) != 0) {
618                 creds_arcfour_crypt(pipe_state->creds, 
619                                     sam->key.key, 
620                                     sizeof(sam->key.key));
621         }
622         
623         if (server_info->lm_session_key.length == sizeof(sam->LMSessKey.key)) {
624                 memcpy(sam->LMSessKey.key, server_info->lm_session_key.data, 
625                        sizeof(sam->LMSessKey.key));
626         } else {
627                 ZERO_STRUCT(sam->LMSessKey.key);
628         }
629         
630         /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
631         if (memcmp(sam->LMSessKey.key, zeros,  
632                    sizeof(sam->LMSessKey.key)) != 0) {
633                 creds_arcfour_crypt(pipe_state->creds, 
634                                     sam->LMSessKey.key, 
635                                     sizeof(sam->LMSessKey.key));
636         }
637
638         switch (r->in.validation_level) {
639         case 2:
640                 sam2 = talloc_p(mem_ctx, struct netr_SamInfo2);
641                 ZERO_STRUCTP(sam2);
642                 sam2->base = *sam;
643                 r->out.validation.sam2 = sam2;
644                 break;
645
646         case 3:
647                 sam3 = talloc_p(mem_ctx, struct netr_SamInfo3);
648                 ZERO_STRUCTP(sam3);
649                 sam3->base = *sam;
650                 r->out.validation.sam3 = sam3;
651                 break;
652
653         case 6:
654                 sam6 = talloc_p(mem_ctx, struct netr_SamInfo6);
655                 ZERO_STRUCTP(sam6);
656                 sam6->base = *sam;
657                 sam6->forest.string = lp_realm();
658                 sam6->principle.string = talloc_asprintf(mem_ctx, "%s@%s", 
659                                                          sam->account_name.string, sam6->forest.string);
660                 r->out.validation.sam6 = sam6;
661                 break;
662
663         default:
664                 break;
665         }
666
667         r->out.authoritative = 1;
668
669         return NT_STATUS_OK;
670 }
671
672 /* 
673   netr_LogonSamLogon
674 */
675 static NTSTATUS netr_LogonSamLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
676                                    struct netr_LogonSamLogon *r)
677 {
678         struct netr_LogonSamLogonWithFlags r2;
679         NTSTATUS status;
680
681         ZERO_STRUCT(r2);
682
683         r2.in.server_name = r->in.server_name;
684         r2.in.workstation = r->in.workstation;
685         r2.in.credential  = r->in.credential;
686         r2.in.return_authenticator = r->in.return_authenticator;
687         r2.in.logon_level = r->in.logon_level;
688         r2.in.logon = r->in.logon;
689         r2.in.validation_level = r->in.validation_level;
690         r2.in.flags = 0;
691
692         status = netr_LogonSamLogonWithFlags(dce_call, mem_ctx, &r2);
693
694         r->out.return_authenticator = r2.out.return_authenticator;
695         r->out.validation = r2.out.validation;
696         r->out.authoritative = r2.out.authoritative;
697
698         return status;
699 }
700
701
702 /* 
703   netr_LogonSamLogoff 
704 */
705 static NTSTATUS netr_LogonSamLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
706                        struct netr_LogonSamLogoff *r)
707 {
708         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
709 }
710
711
712
713 /* 
714   netr_DatabaseDeltas 
715 */
716 static NTSTATUS netr_DatabaseDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
717                        struct netr_DatabaseDeltas *r)
718 {
719         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
720 }
721
722
723 /* 
724   netr_DatabaseSync 
725 */
726 static NTSTATUS netr_DatabaseSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
727                        struct netr_DatabaseSync *r)
728 {
729         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
730 }
731
732
733 /* 
734   netr_AccountDeltas 
735 */
736 static NTSTATUS netr_AccountDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
737                        struct netr_AccountDeltas *r)
738 {
739         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
740 }
741
742
743 /* 
744   netr_AccountSync 
745 */
746 static NTSTATUS netr_AccountSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
747                        struct netr_AccountSync *r)
748 {
749         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
750 }
751
752
753 /* 
754   netr_GetDcName 
755 */
756 static NTSTATUS netr_GetDcName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
757                        struct netr_GetDcName *r)
758 {
759         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
760 }
761
762
763 /* 
764   netr_LogonControl 
765 */
766 static WERROR netr_LogonControl(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
767                        struct netr_LogonControl *r)
768 {
769         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
770 }
771
772
773 /* 
774   netr_GetAnyDCName 
775 */
776 static WERROR netr_GetAnyDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
777                        struct netr_GetAnyDCName *r)
778 {
779         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
780 }
781
782
783 /* 
784   netr_LogonControl2 
785 */
786 static WERROR netr_LogonControl2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
787                        struct netr_LogonControl2 *r)
788 {
789         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
790 }
791
792
793 /* 
794   netr_DatabaseSync2 
795 */
796 static NTSTATUS netr_DatabaseSync2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
797                        struct netr_DatabaseSync2 *r)
798 {
799         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
800 }
801
802
803 /* 
804   netr_DatabaseRedo 
805 */
806 static NTSTATUS netr_DatabaseRedo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
807                        struct netr_DatabaseRedo *r)
808 {
809         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
810 }
811
812
813 /* 
814   netr_LogonControl2Ex 
815 */
816 static WERROR netr_LogonControl2Ex(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
817                        struct netr_LogonControl2Ex *r)
818 {
819         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
820 }
821
822
823 /* 
824   netr_NETRENUMERATETRUSTEDDOMAINS 
825 */
826 static WERROR netr_NETRENUMERATETRUSTEDDOMAINS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
827                        struct netr_NETRENUMERATETRUSTEDDOMAINS *r)
828 {
829         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
830 }
831
832
833 /* 
834   netr_DSRGETDCNAME 
835 */
836 static WERROR netr_DSRGETDCNAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
837                        struct netr_DSRGETDCNAME *r)
838 {
839         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
840 }
841
842
843 /* 
844   netr_NETRLOGONDUMMYROUTINE1 
845 */
846 static WERROR netr_NETRLOGONDUMMYROUTINE1(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
847                        struct netr_NETRLOGONDUMMYROUTINE1 *r)
848 {
849         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
850 }
851
852
853 /* 
854   netr_NETRLOGONSETSERVICEBITS 
855 */
856 static WERROR netr_NETRLOGONSETSERVICEBITS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
857                        struct netr_NETRLOGONSETSERVICEBITS *r)
858 {
859         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
860 }
861
862
863 /* 
864   netr_NETRLOGONGETTRUSTRID 
865 */
866 static WERROR netr_NETRLOGONGETTRUSTRID(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
867                        struct netr_NETRLOGONGETTRUSTRID *r)
868 {
869         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
870 }
871
872
873 /* 
874   netr_NETRLOGONCOMPUTESERVERDIGEST 
875 */
876 static WERROR netr_NETRLOGONCOMPUTESERVERDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
877                        struct netr_NETRLOGONCOMPUTESERVERDIGEST *r)
878 {
879         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
880 }
881
882
883 /* 
884   netr_NETRLOGONCOMPUTECLIENTDIGEST 
885 */
886 static WERROR netr_NETRLOGONCOMPUTECLIENTDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
887                        struct netr_NETRLOGONCOMPUTECLIENTDIGEST *r)
888 {
889         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
890 }
891
892
893 /* 
894   netr_DSRGETDCNAMEX 
895 */
896 static WERROR netr_DSRGETDCNAMEX(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
897                        struct netr_DSRGETDCNAMEX *r)
898 {
899         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
900 }
901
902
903 /* 
904   netr_DSRGETSITENAME 
905 */
906 static WERROR netr_DSRGETSITENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
907                        struct netr_DSRGETSITENAME *r)
908 {
909         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
910 }
911
912
913 /*
914   fill in a netr_DomainTrustInfo from a ldb search result
915 */
916 static NTSTATUS fill_domain_trust_info(TALLOC_CTX *mem_ctx, struct ldb_message *res,
917                                        struct netr_DomainTrustInfo *info)
918 {
919         ZERO_STRUCTP(info);
920         
921         info->domainname.string = samdb_result_string(res, "flatName", NULL);
922         if (info->domainname.string == NULL) {
923                 info->domainname.string = samdb_result_string(res, "name", NULL);
924                 info->fulldomainname.string = samdb_result_string(res, "dnsDomain", NULL);
925         } else {
926                 info->fulldomainname.string = samdb_result_string(res, "name", NULL);
927         }
928
929         /* TODO: we need proper forest support */
930         info->forest.string = info->fulldomainname.string;
931
932         info->guid = samdb_result_guid(res, "objectGUID");
933         info->sid = samdb_result_dom_sid(mem_ctx, res, "objectSid");
934
935         return NT_STATUS_OK;
936 }
937
938 /* 
939   netr_LogonGetDomainInfo
940   this is called as part of the ADS domain logon procedure.
941 */
942 static NTSTATUS netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
943                                         struct netr_LogonGetDomainInfo *r)
944 {
945         struct server_pipe_state *pipe_state = dce_call->conn->private;
946         const char * const attrs[] = { "name", "dnsDomain", "objectSid", 
947                                        "objectGUID", "flatName", NULL };
948         void *sam_ctx;
949         struct ldb_message **res1, **res2;
950         struct netr_DomainInfo1 *info1;
951         int ret1, ret2, i;
952         NTSTATUS status;
953
954         if (!pipe_state) {
955                 return NT_STATUS_ACCESS_DENIED;
956         }
957
958         if (!netr_creds_server_step_check(pipe_state, 
959                                           r->in.credential, r->out.credential)) {
960                 return NT_STATUS_ACCESS_DENIED;
961         }
962
963         sam_ctx = samdb_connect();
964         if (sam_ctx == NULL) {
965                 return NT_STATUS_INVALID_SYSTEM_SERVICE;
966         }
967
968         /* we need to do two searches. The first will pull our primary
969            domain and the second will pull any trusted domains. Our
970            primary domain is also a "trusted" domain, so we need to
971            put the primary domain into the lists of returned trusts as
972            well */
973         ret1 = samdb_search(sam_ctx, mem_ctx, NULL, &res1, attrs, "(objectClass=domainDNS)");
974         if (ret1 != 1) {
975                 samdb_close(sam_ctx);
976                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
977         }
978
979         ret2 = samdb_search(sam_ctx, mem_ctx, NULL, &res2, attrs, "(objectClass=trustedDomain)");
980         if (ret2 == -1) {
981                 samdb_close(sam_ctx);
982                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
983         }
984
985         /* we don't need the db link any more */
986         samdb_close(sam_ctx);
987
988         info1 = talloc_p(mem_ctx, struct netr_DomainInfo1);
989         if (info1 == NULL) {
990                 return NT_STATUS_NO_MEMORY;
991         }
992
993         ZERO_STRUCTP(info1);
994
995         info1->num_trusts = ret2 + 1;
996         info1->trusts = talloc_array_p(mem_ctx, struct netr_DomainTrustInfo, 
997                                        info1->num_trusts);
998         if (info1->trusts == NULL) {
999                 return NT_STATUS_NO_MEMORY;
1000         }
1001
1002         status = fill_domain_trust_info(mem_ctx, res1[0], &info1->domaininfo);
1003         if (!NT_STATUS_IS_OK(status)) {
1004                 return status;
1005         }
1006
1007         status = fill_domain_trust_info(mem_ctx, res1[0], &info1->trusts[0]);
1008         if (!NT_STATUS_IS_OK(status)) {
1009                 return status;
1010         }
1011
1012         for (i=0;i<ret2;i++) {
1013                 status = fill_domain_trust_info(mem_ctx, res2[i], &info1->trusts[i+1]);
1014                 if (!NT_STATUS_IS_OK(status)) {
1015                         return status;
1016                 }
1017         }
1018
1019         r->out.info.info1 = info1;
1020
1021         return NT_STATUS_OK;
1022 }
1023
1024
1025 /* 
1026   netr_NETRSERVERPASSWORDSET2 
1027 */
1028 static WERROR netr_NETRSERVERPASSWORDSET2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1029                        struct netr_NETRSERVERPASSWORDSET2 *r)
1030 {
1031         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1032 }
1033
1034
1035 /* 
1036   netr_NETRSERVERPASSWORDGET 
1037 */
1038 static WERROR netr_NETRSERVERPASSWORDGET(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1039                        struct netr_NETRSERVERPASSWORDGET *r)
1040 {
1041         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1042 }
1043
1044
1045 /* 
1046   netr_NETRLOGONSENDTOSAM 
1047 */
1048 static WERROR netr_NETRLOGONSENDTOSAM(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1049                        struct netr_NETRLOGONSENDTOSAM *r)
1050 {
1051         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1052 }
1053
1054
1055 /* 
1056   netr_DSRADDRESSTOSITENAMESW 
1057 */
1058 static WERROR netr_DSRADDRESSTOSITENAMESW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1059                        struct netr_DSRADDRESSTOSITENAMESW *r)
1060 {
1061         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1062 }
1063
1064
1065 /* 
1066   netr_DSRGETDCNAMEEX2 
1067 */
1068 static WERROR netr_DSRGETDCNAMEEX2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1069                        struct netr_DSRGETDCNAMEEX2 *r)
1070 {
1071         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1072 }
1073
1074
1075 /* 
1076   netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN 
1077 */
1078 static WERROR netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1079                        struct netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN *r)
1080 {
1081         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1082 }
1083
1084
1085 /* 
1086   netr_NETRENUMERATETRUSTEDDOMAINSEX 
1087 */
1088 static WERROR netr_NETRENUMERATETRUSTEDDOMAINSEX(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1089                        struct netr_NETRENUMERATETRUSTEDDOMAINSEX *r)
1090 {
1091         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1092 }
1093
1094
1095 /* 
1096   netr_DSRADDRESSTOSITENAMESEXW 
1097 */
1098 static WERROR netr_DSRADDRESSTOSITENAMESEXW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1099                        struct netr_DSRADDRESSTOSITENAMESEXW *r)
1100 {
1101         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1102 }
1103
1104
1105 /* 
1106   netr_DSRGETDCSITECOVERAGEW 
1107 */
1108 static WERROR netr_DSRGETDCSITECOVERAGEW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1109                        struct netr_DSRGETDCSITECOVERAGEW *r)
1110 {
1111         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1112 }
1113
1114
1115 /* 
1116   netr_NETRLOGONSAMLOGONEX 
1117 */
1118 static WERROR netr_NETRLOGONSAMLOGONEX(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1119                        struct netr_NETRLOGONSAMLOGONEX *r)
1120 {
1121         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1122 }
1123
1124
1125 /* 
1126   netr_DsrEnumerateDomainTrusts 
1127 */
1128 static WERROR netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1129                                               struct netr_DsrEnumerateDomainTrusts *r)
1130 {
1131         struct netr_DomainTrust *trusts;
1132         void *sam_ctx;
1133         int ret, i;
1134         struct ldb_message **res;
1135         const char * const attrs[] = { "name", "dnsDomain", "objectSid", "objectGUID", NULL };
1136
1137         ZERO_STRUCT(r->out);
1138
1139         sam_ctx = samdb_connect();
1140         if (sam_ctx == NULL) {
1141                 return WERR_GENERAL_FAILURE;
1142         }
1143
1144         ret = samdb_search(sam_ctx, mem_ctx, NULL, &res, attrs, "(objectClass=domainDNS)");
1145         if (ret == -1) {
1146                 samdb_close(sam_ctx);
1147                 return WERR_GENERAL_FAILURE;            
1148         }
1149
1150         if (ret == 0) {
1151                 return WERR_OK;
1152         }
1153
1154         trusts = talloc_array_p(mem_ctx, struct netr_DomainTrust, ret);
1155         if (trusts == NULL) {
1156                 return WERR_NOMEM;
1157         }
1158         
1159         r->out.count = ret;
1160         r->out.trusts = trusts;
1161
1162         /* TODO: add filtering by trust_flags, and correct trust_type
1163            and attributes */
1164         for (i=0;i<ret;i++) {
1165                 trusts[i].netbios_name = samdb_result_string(res[i], "name", NULL);
1166                 trusts[i].dns_name     = samdb_result_string(res[i], "dnsDomain", NULL);
1167                 trusts[i].trust_flags = 
1168                         NETR_TRUST_FLAG_TREEROOT | 
1169                         NETR_TRUST_FLAG_IN_FOREST | 
1170                         NETR_TRUST_FLAG_PRIMARY;
1171                 trusts[i].parent_index = 0;
1172                 trusts[i].trust_type = 2;
1173                 trusts[i].trust_attributes = 0;
1174                 trusts[i].sid  = samdb_result_dom_sid(mem_ctx, res[i], "objectSid");
1175                 trusts[i].guid = samdb_result_guid(res[i], "objectGUID");
1176         }
1177         
1178
1179         return WERR_OK;
1180 }
1181
1182
1183 /* 
1184   netr_DSRDEREGISTERDNSHOSTRECORDS 
1185 */
1186 static WERROR netr_DSRDEREGISTERDNSHOSTRECORDS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1187                        struct netr_DSRDEREGISTERDNSHOSTRECORDS *r)
1188 {
1189         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1190 }
1191
1192
1193 /* 
1194   netr_NETRSERVERTRUSTPASSWORDSGET 
1195 */
1196 static WERROR netr_NETRSERVERTRUSTPASSWORDSGET(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1197                        struct netr_NETRSERVERTRUSTPASSWORDSGET *r)
1198 {
1199         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1200 }
1201
1202
1203 /* 
1204   netr_DSRGETFORESTTRUSTINFORMATION 
1205 */
1206 static WERROR netr_DSRGETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1207                        struct netr_DSRGETFORESTTRUSTINFORMATION *r)
1208 {
1209         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1210 }
1211
1212
1213 /* 
1214   netr_NETRGETFORESTTRUSTINFORMATION 
1215 */
1216 static WERROR netr_NETRGETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1217                        struct netr_NETRGETFORESTTRUSTINFORMATION *r)
1218 {
1219         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1220 }
1221
1222
1223 /* 
1224   netr_NETRSERVERGETTRUSTINFO 
1225 */
1226 static WERROR netr_NETRSERVERGETTRUSTINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1227                        struct netr_NETRSERVERGETTRUSTINFO *r)
1228 {
1229         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1230 }
1231
1232
1233 /* include the generated boilerplate */
1234 #include "librpc/gen_ndr/ndr_netlogon_s.c"