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