r17824: add a wrapper for the common partitions_basedn calculation
[gd/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         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
677 }
678
679
680 /* 
681   netr_AccountSync 
682 */
683 static NTSTATUS netr_AccountSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
684                        struct netr_AccountSync *r)
685 {
686         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
687 }
688
689
690 /* 
691   netr_GetDcName 
692 */
693 static NTSTATUS netr_GetDcName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
694                        struct netr_GetDcName *r)
695 {
696         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
697 }
698
699
700 /* 
701   netr_LogonControl 
702 */
703 static WERROR netr_LogonControl(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
704                        struct netr_LogonControl *r)
705 {
706         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
707 }
708
709
710 /* 
711   netr_GetAnyDCName 
712 */
713 static WERROR netr_GetAnyDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
714                        struct netr_GetAnyDCName *r)
715 {
716         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
717 }
718
719
720 /* 
721   netr_LogonControl2 
722 */
723 static WERROR netr_LogonControl2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
724                        struct netr_LogonControl2 *r)
725 {
726         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
727 }
728
729
730 /* 
731   netr_DatabaseSync2 
732 */
733 static NTSTATUS netr_DatabaseSync2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
734                        struct netr_DatabaseSync2 *r)
735 {
736         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
737 }
738
739
740 /* 
741   netr_DatabaseRedo 
742 */
743 static NTSTATUS netr_DatabaseRedo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
744                        struct netr_DatabaseRedo *r)
745 {
746         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
747 }
748
749
750 /* 
751   netr_LogonControl2Ex 
752 */
753 static WERROR netr_LogonControl2Ex(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
754                        struct netr_LogonControl2Ex *r)
755 {
756         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
757 }
758
759
760 /* 
761   netr_NETRENUMERATETRUSTEDDOMAINS 
762 */
763 static WERROR netr_NETRENUMERATETRUSTEDDOMAINS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
764                        struct netr_NETRENUMERATETRUSTEDDOMAINS *r)
765 {
766         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
767 }
768
769
770 /* 
771   netr_NETRLOGONDUMMYROUTINE1 
772 */
773 static WERROR netr_NETRLOGONDUMMYROUTINE1(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
774                        struct netr_NETRLOGONDUMMYROUTINE1 *r)
775 {
776         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
777 }
778
779
780 /* 
781   netr_NETRLOGONSETSERVICEBITS 
782 */
783 static WERROR netr_NETRLOGONSETSERVICEBITS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
784                        struct netr_NETRLOGONSETSERVICEBITS *r)
785 {
786         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
787 }
788
789
790 /* 
791   netr_NETRLOGONGETTRUSTRID 
792 */
793 static WERROR netr_NETRLOGONGETTRUSTRID(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
794                        struct netr_NETRLOGONGETTRUSTRID *r)
795 {
796         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
797 }
798
799
800 /* 
801   netr_NETRLOGONCOMPUTESERVERDIGEST 
802 */
803 static WERROR netr_NETRLOGONCOMPUTESERVERDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
804                        struct netr_NETRLOGONCOMPUTESERVERDIGEST *r)
805 {
806         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
807 }
808
809
810 /* 
811   netr_NETRLOGONCOMPUTECLIENTDIGEST 
812 */
813 static WERROR netr_NETRLOGONCOMPUTECLIENTDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
814                        struct netr_NETRLOGONCOMPUTECLIENTDIGEST *r)
815 {
816         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
817 }
818
819
820
821 /* 
822   netr_DsRGetSiteName
823 */
824 static WERROR netr_DsRGetSiteName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
825                                   struct netr_DsRGetSiteName *r)
826 {
827         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
828 }
829
830
831 /*
832   fill in a netr_DomainTrustInfo from a ldb search result
833 */
834 static NTSTATUS fill_domain_primary_info(TALLOC_CTX *mem_ctx, struct ldb_message *res,
835                                          struct netr_DomainTrustInfo *info, 
836                                          const char *local_domain)
837 {
838         ZERO_STRUCTP(info);
839
840         info->domainname.string = local_domain;
841         info->fulldomainname.string = talloc_asprintf(info, "%s.", samdb_result_string(res, "dnsDomain", NULL));
842         /* TODO: we need proper forest support */
843         info->forest.string = info->fulldomainname.string;
844         info->guid = samdb_result_guid(res, "objectGUID");
845         info->sid = samdb_result_dom_sid(mem_ctx, res, "objectSid");
846
847         return NT_STATUS_OK;
848 }
849
850 /*
851   fill in a netr_DomainTrustInfo from a ldb search result
852 */
853 static NTSTATUS fill_domain_trust_info(TALLOC_CTX *mem_ctx, struct ldb_message *res,
854                                        struct netr_DomainTrustInfo *info, 
855                                        const char *local_domain, BOOL is_local)
856 {
857         ZERO_STRUCTP(info);
858
859         if (is_local) {
860                 info->domainname.string = local_domain;
861                 info->fulldomainname.string = samdb_result_string(res, "dnsDomain", NULL);
862                 info->forest.string = NULL;
863                 info->guid = samdb_result_guid(res, "objectGUID");
864                 info->sid = samdb_result_dom_sid(mem_ctx, res, "objectSid");
865         } else {
866                 info->domainname.string = samdb_result_string(res, "flatName", NULL);
867                 info->fulldomainname.string = samdb_result_string(res, "name", NULL);
868                 info->forest.string = NULL;
869                 info->guid = samdb_result_guid(res, "objectGUID");
870                 info->sid = samdb_result_dom_sid(mem_ctx, res, "securityIdentifier");
871         }
872
873         return NT_STATUS_OK;
874 }
875
876 /* 
877   netr_LogonGetDomainInfo
878   this is called as part of the ADS domain logon procedure.
879 */
880 static NTSTATUS netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
881                                         struct netr_LogonGetDomainInfo *r)
882 {
883         const char * const attrs[] = { "dnsDomain", "objectSid", 
884                                        "objectGUID", "flatName", "securityIdentifier",
885                                        NULL };
886         const char * const ref_attrs[] = { "nETBIOSName", NULL };
887         struct ldb_context *sam_ctx;
888         struct ldb_message **res1, **res2, **ref_res;
889         struct netr_DomainInfo1 *info1;
890         int ret, ret1, ret2, i;
891         NTSTATUS status;
892         const struct ldb_dn *partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);
893
894         const char *local_domain;
895
896         status = netr_creds_server_step_check(r->in.computer_name, mem_ctx, 
897                                               r->in.credential, 
898                                               r->out.return_authenticator,
899                                               NULL);
900         NT_STATUS_NOT_OK_RETURN(status);
901
902         sam_ctx = samdb_connect(mem_ctx, dce_call->conn->auth_state.session_info);
903         if (sam_ctx == NULL) {
904                 return NT_STATUS_INVALID_SYSTEM_SERVICE;
905         }
906
907         /* we need to do two searches. The first will pull our primary
908            domain and the second will pull any trusted domains. Our
909            primary domain is also a "trusted" domain, so we need to
910            put the primary domain into the lists of returned trusts as
911            well */
912         ret1 = gendb_search(sam_ctx, mem_ctx, NULL, &res1, attrs, "(objectClass=domainDNS)");
913         if (ret1 != 1) {
914                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
915         }
916
917         /* try and find the domain */
918         ret = gendb_search(sam_ctx, mem_ctx, partitions_basedn, 
919                            &ref_res, ref_attrs, 
920                            "(&(objectClass=crossRef)(ncName=%s))", 
921                            ldb_dn_linearize(mem_ctx, res1[0]->dn));
922         if (ret != 1) {
923                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
924         }
925
926         local_domain = samdb_result_string(ref_res[0], "nETBIOSName", NULL);
927
928         ret2 = gendb_search(sam_ctx, mem_ctx, NULL, &res2, attrs, "(objectClass=trustedDomain)");
929         if (ret2 == -1) {
930                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
931         }
932
933         info1 = talloc(mem_ctx, struct netr_DomainInfo1);
934         NT_STATUS_HAVE_NO_MEMORY(info1);
935
936         ZERO_STRUCTP(info1);
937
938         info1->num_trusts = ret2 + 1;
939         info1->trusts = talloc_array(mem_ctx, struct netr_DomainTrustInfo, 
940                                        info1->num_trusts);
941         NT_STATUS_HAVE_NO_MEMORY(info1->trusts);
942
943         status = fill_domain_primary_info(mem_ctx, res1[0], &info1->domaininfo, local_domain);
944         NT_STATUS_NOT_OK_RETURN(status);
945
946         for (i=0;i<ret2;i++) {
947                 status = fill_domain_trust_info(mem_ctx, res2[i], &info1->trusts[i], NULL, False);
948                 NT_STATUS_NOT_OK_RETURN(status);
949         }
950
951         status = fill_domain_trust_info(mem_ctx, res1[0], &info1->trusts[i], local_domain, True);
952         NT_STATUS_NOT_OK_RETURN(status);
953
954         r->out.info.info1 = info1;
955
956         return NT_STATUS_OK;
957 }
958
959
960
961 /* 
962   netr_NETRSERVERPASSWORDGET 
963 */
964 static WERROR netr_NETRSERVERPASSWORDGET(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
965                        struct netr_NETRSERVERPASSWORDGET *r)
966 {
967         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
968 }
969
970
971 /* 
972   netr_NETRLOGONSENDTOSAM 
973 */
974 static WERROR netr_NETRLOGONSENDTOSAM(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
975                        struct netr_NETRLOGONSENDTOSAM *r)
976 {
977         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
978 }
979
980
981 /* 
982   netr_DSRADDRESSTOSITENAMESW 
983 */
984 static WERROR netr_DSRADDRESSTOSITENAMESW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
985                        struct netr_DSRADDRESSTOSITENAMESW *r)
986 {
987         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
988 }
989
990
991 /* 
992   netr_DsRGetDCNameEx2
993 */
994 static WERROR netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
995                                    struct netr_DsRGetDCNameEx2 *r)
996 {
997         const char * const attrs[] = { "dnsDomain", "objectGUID", NULL };
998         void *sam_ctx;
999         struct ldb_message **res;
1000         int ret;
1001
1002         ZERO_STRUCT(r->out);
1003
1004         sam_ctx = samdb_connect(mem_ctx, dce_call->conn->auth_state.session_info);
1005         if (sam_ctx == NULL) {
1006                 return WERR_DS_SERVICE_UNAVAILABLE;
1007         }
1008
1009         ret = gendb_search(sam_ctx, mem_ctx, NULL, &res, attrs,
1010                                 "(&(objectClass=domainDNS)(dnsDomain=%s))",
1011                                 r->in.domain_name);
1012         if (ret != 1) {
1013                 return WERR_NO_SUCH_DOMAIN;
1014         }
1015
1016         r->out.info = talloc(mem_ctx, struct netr_DsRGetDCNameInfo);
1017         W_ERROR_HAVE_NO_MEMORY(r->out.info);
1018
1019         /* TODO: - return real IP address
1020          *       - check all r->in.* parameters (server_unc is ignored by w2k3!)
1021          */
1022         r->out.info->dc_unc             = talloc_asprintf(mem_ctx, "\\\\%s.%s", lp_netbios_name(),lp_realm());
1023         W_ERROR_HAVE_NO_MEMORY(r->out.info->dc_unc);
1024         r->out.info->dc_address         = talloc_strdup(mem_ctx, "\\\\0.0.0.0");
1025         W_ERROR_HAVE_NO_MEMORY(r->out.info->dc_address);
1026         r->out.info->dc_address_type    = 1;
1027         r->out.info->domain_guid        = samdb_result_guid(res[0], "objectGUID");
1028         r->out.info->domain_name        = samdb_result_string(res[0], "dnsDomain", NULL);
1029         r->out.info->forest_name        = samdb_result_string(res[0], "dnsDomain", NULL);
1030         r->out.info->dc_flags           = 0xE00001FD;
1031         r->out.info->dc_site_name       = talloc_strdup(mem_ctx, "Default-First-Site-Name");
1032         W_ERROR_HAVE_NO_MEMORY(r->out.info->dc_site_name);
1033         r->out.info->client_site_name   = talloc_strdup(mem_ctx, "Default-First-Site-Name");
1034         W_ERROR_HAVE_NO_MEMORY(r->out.info->client_site_name);
1035
1036         return WERR_OK;
1037 }
1038
1039 /* 
1040   netr_DsRGetDCNameEx
1041 */
1042 static WERROR netr_DsRGetDCNameEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1043                                   struct netr_DsRGetDCNameEx *r)
1044 {
1045         struct netr_DsRGetDCNameEx2 r2;
1046         WERROR werr;
1047
1048         ZERO_STRUCT(r2);
1049
1050         r2.in.server_unc = r->in.server_unc;
1051         r2.in.client_account = NULL;
1052         r2.in.mask = 0;
1053         r2.in.domain_guid = r->in.domain_guid;
1054         r2.in.domain_name = r->in.domain_name;
1055         r2.in.site_name = r->in.site_name;
1056         r2.in.flags = r->in.flags;
1057         r2.out.info = NULL;
1058
1059         werr = netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1060         
1061         r->out.info = r2.out.info;
1062         
1063         return werr;
1064 }
1065
1066 /* 
1067   netr_DsRGetDCName
1068 */
1069 static WERROR netr_DsRGetDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1070                                 struct netr_DsRGetDCName *r)
1071 {
1072         struct netr_DsRGetDCNameEx2 r2;
1073         WERROR werr;
1074
1075         ZERO_STRUCT(r2);
1076
1077         r2.in.server_unc = r->in.server_unc;
1078         r2.in.client_account = NULL;
1079         r2.in.mask = 0;
1080         r2.in.domain_name = r->in.domain_name;
1081         r2.in.domain_guid = r->in.domain_guid;
1082         
1083         r2.in.site_name = NULL; /* should fill in from site GUID */
1084         r2.in.flags = r->in.flags;
1085         r2.out.info = NULL;
1086
1087         werr = netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1088         
1089         r->out.info = r2.out.info;
1090         
1091         return werr;
1092 }
1093
1094 /* 
1095   netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN 
1096 */
1097 static WERROR netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1098                        struct netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN *r)
1099 {
1100         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1101 }
1102
1103
1104 /* 
1105   netr_NETRENUMERATETRUSTEDDOMAINSEX 
1106 */
1107 static WERROR netr_NETRENUMERATETRUSTEDDOMAINSEX(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1108                        struct netr_NETRENUMERATETRUSTEDDOMAINSEX *r)
1109 {
1110         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1111 }
1112
1113
1114 /* 
1115   netr_DSRADDRESSTOSITENAMESEXW 
1116 */
1117 static WERROR netr_DSRADDRESSTOSITENAMESEXW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1118                        struct netr_DSRADDRESSTOSITENAMESEXW *r)
1119 {
1120         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1121 }
1122
1123
1124 /* 
1125   netr_DSRGETDCSITECOVERAGEW 
1126 */
1127 static WERROR netr_DSRGETDCSITECOVERAGEW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1128                        struct netr_DSRGETDCSITECOVERAGEW *r)
1129 {
1130         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1131 }
1132
1133
1134 /* 
1135   netr_DsrEnumerateDomainTrusts 
1136 */
1137 static WERROR netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1138                                               struct netr_DsrEnumerateDomainTrusts *r)
1139 {
1140         struct netr_DomainTrust *trusts;
1141         void *sam_ctx;
1142         int ret;
1143         struct ldb_message **dom_res, **ref_res;
1144         const char * const dom_attrs[] = { "dnsDomain", "objectSid", "objectGUID", NULL };
1145         const char * const ref_attrs[] = { "nETBIOSName", NULL };
1146         const struct ldb_dn *partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);
1147
1148         ZERO_STRUCT(r->out);
1149
1150         sam_ctx = samdb_connect(mem_ctx, dce_call->conn->auth_state.session_info);
1151         if (sam_ctx == NULL) {
1152                 return WERR_GENERAL_FAILURE;
1153         }
1154
1155         ret = gendb_search_dn(sam_ctx, mem_ctx, NULL, &dom_res, dom_attrs);
1156         if (ret == -1) {
1157                 return WERR_GENERAL_FAILURE;            
1158         }
1159         if (ret != 1) {
1160                 return WERR_GENERAL_FAILURE;
1161         }
1162
1163         ret = gendb_search(sam_ctx, mem_ctx, partitions_basedn, &ref_res, ref_attrs,
1164                            "(&(objectClass=crossRef)(ncName=%s))",
1165                            ldb_dn_linearize(mem_ctx, dom_res[0]->dn));
1166         if (ret == -1) {
1167                 return WERR_GENERAL_FAILURE;
1168         }
1169         if (ret != 1) {
1170                 return WERR_GENERAL_FAILURE;
1171         }
1172
1173         trusts = talloc_array(mem_ctx, struct netr_DomainTrust, ret);
1174         W_ERROR_HAVE_NO_MEMORY(trusts);
1175         
1176         r->out.count = 1;
1177         r->out.trusts = trusts;
1178
1179         /* TODO: add filtering by trust_flags, and correct trust_type
1180            and attributes */
1181         trusts[0].netbios_name = samdb_result_string(ref_res[0], "nETBIOSName", NULL);
1182         trusts[0].dns_name     = samdb_result_string(dom_res[0], "dnsDomain", NULL);
1183         trusts[0].trust_flags = 
1184                 NETR_TRUST_FLAG_TREEROOT | 
1185                 NETR_TRUST_FLAG_IN_FOREST | 
1186                 NETR_TRUST_FLAG_PRIMARY;
1187         trusts[0].parent_index = 0;
1188         trusts[0].trust_type = 2;
1189         trusts[0].trust_attributes = 0;
1190         trusts[0].sid  = samdb_result_dom_sid(mem_ctx, dom_res[0], "objectSid");
1191         trusts[0].guid = samdb_result_guid(dom_res[0], "objectGUID");
1192
1193         return WERR_OK;
1194 }
1195
1196
1197 /* 
1198   netr_DSRDEREGISTERDNSHOSTRECORDS 
1199 */
1200 static WERROR netr_DSRDEREGISTERDNSHOSTRECORDS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1201                        struct netr_DSRDEREGISTERDNSHOSTRECORDS *r)
1202 {
1203         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1204 }
1205
1206
1207 /* 
1208   netr_NETRSERVERTRUSTPASSWORDSGET 
1209 */
1210 static WERROR netr_NETRSERVERTRUSTPASSWORDSGET(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1211                        struct netr_NETRSERVERTRUSTPASSWORDSGET *r)
1212 {
1213         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1214 }
1215
1216
1217 /* 
1218   netr_DSRGETFORESTTRUSTINFORMATION 
1219 */
1220 static WERROR netr_DSRGETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1221                        struct netr_DSRGETFORESTTRUSTINFORMATION *r)
1222 {
1223         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1224 }
1225
1226
1227 /* 
1228   netr_NETRGETFORESTTRUSTINFORMATION 
1229 */
1230 static WERROR netr_NETRGETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1231                        struct netr_NETRGETFORESTTRUSTINFORMATION *r)
1232 {
1233         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1234 }
1235
1236
1237 /* 
1238   netr_NETRSERVERGETTRUSTINFO 
1239 */
1240 static WERROR netr_NETRSERVERGETTRUSTINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1241                        struct netr_NETRSERVERGETTRUSTINFO *r)
1242 {
1243         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1244 }
1245
1246
1247 /* include the generated boilerplate */
1248 #include "librpc/gen_ndr/ndr_netlogon_s.c"