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