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