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