Merge commit 'release-4-0-0alpha1' into v4-0-test
[ira/wip.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 3 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, see <http://www.gnu.org/licenses/>.
21 */
22
23 #include "includes.h"
24 #include "rpc_server/dcerpc_server.h"
25 #include "rpc_server/common/common.h"
26 #include "lib/ldb/include/ldb.h"
27 #include "auth/auth.h"
28 #include "auth/auth_sam.h"
29 #include "dsdb/samdb/samdb.h"
30 #include "rpc_server/samr/proto.h"
31 #include "db_wrap.h"
32 #include "libcli/auth/libcli_auth.h"
33 #include "auth/gensec/schannel_state.h"
34 #include "libcli/security/security.h"
35 #include "param/param.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 dcesrv_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 dcesrv_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[] = {"unicodePwd", "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], "unicodePwd");
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(global_loadparm));
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 dcesrv_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 dcesrv_netr_ServerAuthenticate3(dce_call, mem_ctx, &r3);
205 }
206
207 static NTSTATUS dcesrv_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 dcesrv_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 dcesrv_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, 
263                                                    lp_workgroup(global_loadparm),
264                                                    &creds);
265         if (NT_STATUS_IS_OK(nt_status)) {
266                 nt_status = creds_server_step_check(creds, 
267                                                     received_authenticator, 
268                                                     return_authenticator);
269         }
270         if (NT_STATUS_IS_OK(nt_status)) {
271                 nt_status = schannel_store_session_key_ldb(ldb, ldb, creds);
272         }
273
274         if (NT_STATUS_IS_OK(nt_status)) {
275                 ldb_transaction_commit(ldb);
276                 if (creds_out) {
277                         *creds_out = creds;
278                         talloc_steal(mem_ctx, creds);
279                 }
280         } else {
281                 ldb_transaction_cancel(ldb);
282         }
283         talloc_free(ldb);
284         return nt_status;
285 }
286
287 /* 
288   Change the machine account password for the currently connected
289   client.  Supplies only the NT#.
290 */
291
292 static NTSTATUS dcesrv_netr_ServerPasswordSet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
293                                        struct netr_ServerPasswordSet *r)
294 {
295         struct creds_CredentialState *creds;
296         struct ldb_context *sam_ctx;
297         NTSTATUS nt_status;
298
299         nt_status = dcesrv_netr_creds_server_step_check(r->in.computer_name, mem_ctx, 
300                                                  &r->in.credential, &r->out.return_authenticator,
301                                                  &creds);
302         NT_STATUS_NOT_OK_RETURN(nt_status);
303
304         sam_ctx = samdb_connect(mem_ctx, system_session(mem_ctx));
305         if (sam_ctx == NULL) {
306                 return NT_STATUS_INVALID_SYSTEM_SERVICE;
307         }
308
309         creds_des_decrypt(creds, &r->in.new_password);
310
311         /* Using the sid for the account as the key, set the password */
312         nt_status = samdb_set_password_sid(sam_ctx, mem_ctx, 
313                                            creds->sid,
314                                            NULL, /* Don't have plaintext */
315                                            NULL, &r->in.new_password,
316                                            false, /* This is not considered a password change */
317                                            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 dcesrv_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 = dcesrv_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                                            NULL, NULL);
365         return nt_status;
366 }
367
368
369 /* 
370   netr_LogonUasLogon 
371 */
372 static WERROR dcesrv_netr_LogonUasLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
373                                  struct netr_LogonUasLogon *r)
374 {
375         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
376 }
377
378
379 /* 
380   netr_LogonUasLogoff 
381 */
382 static WERROR dcesrv_netr_LogonUasLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
383                        struct netr_LogonUasLogoff *r)
384 {
385         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
386 }
387
388
389 /* 
390   netr_LogonSamLogon_base
391
392   This version of the function allows other wrappers to say 'do not check the credentials'
393
394   We can't do the traditional 'wrapping' format completly, as this function must only run under schannel
395 */
396 static NTSTATUS dcesrv_netr_LogonSamLogon_base(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
397                                         struct netr_LogonSamLogonEx *r, struct creds_CredentialState *creds)
398 {
399         struct auth_context *auth_context;
400         struct auth_usersupplied_info *user_info;
401         struct auth_serversupplied_info *server_info;
402         NTSTATUS nt_status;
403         static const char zeros[16];
404         struct netr_SamBaseInfo *sam;
405         struct netr_SamInfo2 *sam2;
406         struct netr_SamInfo3 *sam3;
407         struct netr_SamInfo6 *sam6;
408         
409         user_info = talloc(mem_ctx, struct auth_usersupplied_info);
410         NT_STATUS_HAVE_NO_MEMORY(user_info);
411
412         user_info->flags = 0;
413         user_info->mapped_state = false;
414         user_info->remote_host = NULL;
415
416         switch (r->in.logon_level) {
417         case 1:
418         case 3:
419         case 5:
420                 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
421                         creds_arcfour_crypt(creds, 
422                                             r->in.logon.password->lmpassword.hash, 
423                                             sizeof(r->in.logon.password->lmpassword.hash));
424                         creds_arcfour_crypt(creds, 
425                                             r->in.logon.password->ntpassword.hash, 
426                                             sizeof(r->in.logon.password->ntpassword.hash));
427                 } else {
428                         creds_des_decrypt(creds, &r->in.logon.password->lmpassword);
429                         creds_des_decrypt(creds, &r->in.logon.password->ntpassword);
430                 }
431
432                 /* TODO: we need to deny anonymous access here */
433                 nt_status = auth_context_create(mem_ctx, 
434                                                 dce_call->event_ctx, dce_call->msg_ctx,
435                                                 &auth_context);
436                 NT_STATUS_NOT_OK_RETURN(nt_status);
437
438                 user_info->logon_parameters = r->in.logon.password->identity_info.parameter_control;
439                 user_info->client.account_name = r->in.logon.password->identity_info.account_name.string;
440                 user_info->client.domain_name = r->in.logon.password->identity_info.domain_name.string;
441                 user_info->workstation_name = r->in.logon.password->identity_info.workstation.string;
442                 
443                 user_info->flags |= USER_INFO_INTERACTIVE_LOGON;
444                 user_info->password_state = AUTH_PASSWORD_HASH;
445
446                 user_info->password.hash.lanman = talloc(user_info, struct samr_Password);
447                 NT_STATUS_HAVE_NO_MEMORY(user_info->password.hash.lanman);
448                 *user_info->password.hash.lanman = r->in.logon.password->lmpassword;
449
450                 user_info->password.hash.nt = talloc(user_info, struct samr_Password);
451                 NT_STATUS_HAVE_NO_MEMORY(user_info->password.hash.nt);
452                 *user_info->password.hash.nt = r->in.logon.password->ntpassword;
453
454                 break;
455         case 2:
456         case 6:
457
458                 /* TODO: we need to deny anonymous access here */
459                 nt_status = auth_context_create(mem_ctx, 
460                                                 dce_call->event_ctx, dce_call->msg_ctx,
461                                                 &auth_context);
462                 NT_STATUS_NOT_OK_RETURN(nt_status);
463
464                 nt_status = auth_context_set_challenge(auth_context, r->in.logon.network->challenge, "netr_LogonSamLogonWithFlags");
465                 NT_STATUS_NOT_OK_RETURN(nt_status);
466
467                 user_info->logon_parameters = r->in.logon.network->identity_info.parameter_control;
468                 user_info->client.account_name = r->in.logon.network->identity_info.account_name.string;
469                 user_info->client.domain_name = r->in.logon.network->identity_info.domain_name.string;
470                 user_info->workstation_name = r->in.logon.network->identity_info.workstation.string;
471                 
472                 user_info->password_state = AUTH_PASSWORD_RESPONSE;
473                 user_info->password.response.lanman = data_blob_talloc(mem_ctx, r->in.logon.network->lm.data, r->in.logon.network->lm.length);
474                 user_info->password.response.nt = data_blob_talloc(mem_ctx, r->in.logon.network->nt.data, r->in.logon.network->nt.length);
475         
476                 break;
477         default:
478                 return NT_STATUS_INVALID_PARAMETER;
479         }
480         
481         nt_status = auth_check_password(auth_context, mem_ctx, user_info, &server_info);
482         NT_STATUS_NOT_OK_RETURN(nt_status);
483
484         nt_status = auth_convert_server_info_sambaseinfo(mem_ctx, server_info, &sam);
485         NT_STATUS_NOT_OK_RETURN(nt_status);
486
487         /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
488         /* It appears that level 6 is not individually encrypted */
489         if ((r->in.validation_level != 6) &&
490             memcmp(sam->key.key, zeros, sizeof(sam->key.key)) != 0) {
491                 /* This key is sent unencrypted without the ARCFOUR flag set */
492                 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
493                         creds_arcfour_crypt(creds, 
494                                             sam->key.key, 
495                                             sizeof(sam->key.key));
496                 }
497         }
498
499         /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
500         /* It appears that level 6 is not individually encrypted */
501         if ((r->in.validation_level != 6) &&
502             memcmp(sam->LMSessKey.key, zeros, sizeof(sam->LMSessKey.key)) != 0) {
503                 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
504                         creds_arcfour_crypt(creds, 
505                                             sam->LMSessKey.key, 
506                                             sizeof(sam->LMSessKey.key));
507                 } else {
508                         creds_des_encrypt_LMKey(creds, 
509                                                 &sam->LMSessKey);
510                 }
511         }
512
513         switch (r->in.validation_level) {
514         case 2:
515                 sam2 = talloc_zero(mem_ctx, struct netr_SamInfo2);
516                 NT_STATUS_HAVE_NO_MEMORY(sam2);
517                 sam2->base = *sam;
518                 r->out.validation.sam2 = sam2;
519                 break;
520
521         case 3:
522                 sam3 = talloc_zero(mem_ctx, struct netr_SamInfo3);
523                 NT_STATUS_HAVE_NO_MEMORY(sam3);
524                 sam3->base = *sam;
525                 r->out.validation.sam3 = sam3;
526                 break;
527
528         case 6:
529                 sam6 = talloc_zero(mem_ctx, struct netr_SamInfo6);
530                 NT_STATUS_HAVE_NO_MEMORY(sam6);
531                 sam6->base = *sam;
532                 sam6->forest.string = lp_realm(global_loadparm);
533                 sam6->principle.string = talloc_asprintf(mem_ctx, "%s@%s", 
534                                                          sam->account_name.string, sam6->forest.string);
535                 NT_STATUS_HAVE_NO_MEMORY(sam6->principle.string);
536                 r->out.validation.sam6 = sam6;
537                 break;
538
539         default:
540                 break;
541         }
542
543         r->out.authoritative = 1;
544
545         /* TODO: Describe and deal with these flags */
546         r->out.flags = 0;
547
548         return NT_STATUS_OK;
549 }
550
551 static NTSTATUS dcesrv_netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
552                                      struct netr_LogonSamLogonEx *r) 
553 {
554         NTSTATUS nt_status;
555         struct creds_CredentialState *creds;
556         nt_status = schannel_fetch_session_key(mem_ctx, r->in.computer_name, lp_workgroup(global_loadparm), &creds);
557         if (!NT_STATUS_IS_OK(nt_status)) {
558                 return nt_status;
559         }
560
561         if (!dce_call->conn->auth_state.auth_info ||
562             dce_call->conn->auth_state.auth_info->auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
563                 return NT_STATUS_INTERNAL_ERROR;
564         }
565         return dcesrv_netr_LogonSamLogon_base(dce_call, mem_ctx, r, creds);
566 }
567
568 /* 
569   netr_LogonSamLogonWithFlags
570
571 */
572 static NTSTATUS dcesrv_netr_LogonSamLogonWithFlags(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
573                                             struct netr_LogonSamLogonWithFlags *r)
574 {
575         NTSTATUS nt_status;
576         struct creds_CredentialState *creds;
577         struct netr_LogonSamLogonEx r2;
578
579         struct netr_Authenticator *return_authenticator;
580
581         return_authenticator = talloc(mem_ctx, struct netr_Authenticator);
582         NT_STATUS_HAVE_NO_MEMORY(return_authenticator);
583
584         nt_status = dcesrv_netr_creds_server_step_check(r->in.computer_name, mem_ctx, 
585                                                  r->in.credential, return_authenticator,
586                                                  &creds);
587         NT_STATUS_NOT_OK_RETURN(nt_status);
588
589         ZERO_STRUCT(r2);
590
591         r2.in.server_name       = r->in.server_name;
592         r2.in.computer_name     = r->in.computer_name;
593         r2.in.logon_level       = r->in.logon_level;
594         r2.in.logon             = r->in.logon;
595         r2.in.validation_level  = r->in.validation_level;
596         r2.in.flags             = r->in.flags;
597
598         nt_status = dcesrv_netr_LogonSamLogon_base(dce_call, mem_ctx, &r2, creds);
599
600         r->out.return_authenticator     = return_authenticator;
601         r->out.validation               = r2.out.validation;
602         r->out.authoritative            = r2.out.authoritative;
603         r->out.flags                    = r2.out.flags;
604
605         return nt_status;
606 }
607
608 /* 
609   netr_LogonSamLogon
610 */
611 static NTSTATUS dcesrv_netr_LogonSamLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
612                                    struct netr_LogonSamLogon *r)
613 {
614         struct netr_LogonSamLogonWithFlags r2;
615         NTSTATUS status;
616
617         ZERO_STRUCT(r2);
618
619         r2.in.server_name = r->in.server_name;
620         r2.in.computer_name = r->in.computer_name;
621         r2.in.credential  = r->in.credential;
622         r2.in.return_authenticator = r->in.return_authenticator;
623         r2.in.logon_level = r->in.logon_level;
624         r2.in.logon = r->in.logon;
625         r2.in.validation_level = r->in.validation_level;
626         r2.in.flags = 0;
627
628         status = dcesrv_netr_LogonSamLogonWithFlags(dce_call, mem_ctx, &r2);
629
630         r->out.return_authenticator = r2.out.return_authenticator;
631         r->out.validation = r2.out.validation;
632         r->out.authoritative = r2.out.authoritative;
633
634         return status;
635 }
636
637
638 /* 
639   netr_LogonSamLogoff 
640 */
641 static NTSTATUS dcesrv_netr_LogonSamLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
642                        struct netr_LogonSamLogoff *r)
643 {
644         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
645 }
646
647
648
649 /* 
650   netr_DatabaseDeltas 
651 */
652 static NTSTATUS dcesrv_netr_DatabaseDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
653                        struct netr_DatabaseDeltas *r)
654 {
655         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
656 }
657
658
659 /* 
660   netr_DatabaseSync 
661 */
662 static NTSTATUS dcesrv_netr_DatabaseSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
663                        struct netr_DatabaseSync *r)
664 {
665         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
666 }
667
668
669 /* 
670   netr_AccountDeltas 
671 */
672 static NTSTATUS dcesrv_netr_AccountDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
673                        struct netr_AccountDeltas *r)
674 {
675         /* w2k3 returns "NOT IMPLEMENTED" for this call */
676         return NT_STATUS_NOT_IMPLEMENTED;
677 }
678
679
680 /* 
681   netr_AccountSync 
682 */
683 static NTSTATUS dcesrv_netr_AccountSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
684                        struct netr_AccountSync *r)
685 {
686         /* w2k3 returns "NOT IMPLEMENTED" for this call */
687         return NT_STATUS_NOT_IMPLEMENTED;
688 }
689
690
691 /* 
692   netr_GetDcName 
693 */
694 static WERROR dcesrv_netr_GetDcName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
695                        struct netr_GetDcName *r)
696 {
697         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
698 }
699
700
701 /* 
702   netr_LogonControl 
703 */
704 static WERROR dcesrv_netr_LogonControl(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
705                        struct netr_LogonControl *r)
706 {
707         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
708 }
709
710
711 /* 
712   netr_GetAnyDCName 
713 */
714 static WERROR dcesrv_netr_GetAnyDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
715                        struct netr_GetAnyDCName *r)
716 {
717         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
718 }
719
720
721 /* 
722   netr_LogonControl2 
723 */
724 static WERROR dcesrv_netr_LogonControl2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
725                        struct netr_LogonControl2 *r)
726 {
727         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
728 }
729
730
731 /* 
732   netr_DatabaseSync2 
733 */
734 static NTSTATUS dcesrv_netr_DatabaseSync2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
735                        struct netr_DatabaseSync2 *r)
736 {
737         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
738 }
739
740
741 /* 
742   netr_DatabaseRedo 
743 */
744 static NTSTATUS dcesrv_netr_DatabaseRedo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
745                        struct netr_DatabaseRedo *r)
746 {
747         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
748 }
749
750
751 /* 
752   netr_LogonControl2Ex 
753 */
754 static WERROR dcesrv_netr_LogonControl2Ex(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
755                        struct netr_LogonControl2Ex *r)
756 {
757         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
758 }
759
760
761 /* 
762   netr_NETRENUMERATETRUSTEDDOMAINS 
763 */
764 static WERROR dcesrv_netr_NETRENUMERATETRUSTEDDOMAINS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
765                        struct netr_NETRENUMERATETRUSTEDDOMAINS *r)
766 {
767         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
768 }
769
770
771 /* 
772   netr_NETRLOGONDUMMYROUTINE1 
773 */
774 static WERROR dcesrv_netr_NETRLOGONDUMMYROUTINE1(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
775                        struct netr_NETRLOGONDUMMYROUTINE1 *r)
776 {
777         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
778 }
779
780
781 /* 
782   netr_NETRLOGONSETSERVICEBITS 
783 */
784 static WERROR dcesrv_netr_NETRLOGONSETSERVICEBITS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
785                        struct netr_NETRLOGONSETSERVICEBITS *r)
786 {
787         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
788 }
789
790
791 /* 
792   netr_NETRLOGONGETTRUSTRID 
793 */
794 static WERROR dcesrv_netr_NETRLOGONGETTRUSTRID(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
795                        struct netr_NETRLOGONGETTRUSTRID *r)
796 {
797         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
798 }
799
800
801 /* 
802   netr_NETRLOGONCOMPUTESERVERDIGEST 
803 */
804 static WERROR dcesrv_netr_NETRLOGONCOMPUTESERVERDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
805                        struct netr_NETRLOGONCOMPUTESERVERDIGEST *r)
806 {
807         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
808 }
809
810
811 /* 
812   netr_NETRLOGONCOMPUTECLIENTDIGEST 
813 */
814 static WERROR dcesrv_netr_NETRLOGONCOMPUTECLIENTDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
815                        struct netr_NETRLOGONCOMPUTECLIENTDIGEST *r)
816 {
817         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
818 }
819
820
821
822 /* 
823   netr_DsRGetSiteName
824 */
825 static WERROR dcesrv_netr_DsRGetSiteName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
826                                   struct netr_DsRGetSiteName *r)
827 {
828         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
829 }
830
831
832 /*
833   fill in a netr_DomainTrustInfo from a ldb search result
834 */
835 static NTSTATUS fill_domain_trust_info(TALLOC_CTX *mem_ctx,
836                                        struct ldb_message *res,
837                                        struct ldb_message *ref_res,
838                                        struct netr_DomainTrustInfo *info, 
839                                        bool is_local)
840 {
841         ZERO_STRUCTP(info);
842
843         if (is_local) {
844                 info->domainname.string = samdb_result_string(ref_res, "nETBIOSName", NULL);
845                 info->fulldomainname.string = samdb_result_string(ref_res, "dnsRoot", NULL);
846                 info->forest.string = NULL;
847                 info->guid = samdb_result_guid(res, "objectGUID");
848                 info->sid = samdb_result_dom_sid(mem_ctx, res, "objectSid");
849         } else {
850                 info->domainname.string = samdb_result_string(res, "flatName", NULL);
851                 info->fulldomainname.string = samdb_result_string(res, "trustPartner", NULL);
852                 info->forest.string = NULL;
853                 info->guid = samdb_result_guid(res, "objectGUID");
854                 info->sid = samdb_result_dom_sid(mem_ctx, res, "securityIdentifier");
855         }
856
857         return NT_STATUS_OK;
858 }
859
860 /* 
861   netr_LogonGetDomainInfo
862   this is called as part of the ADS domain logon procedure.
863 */
864 static NTSTATUS dcesrv_netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
865                                         struct netr_LogonGetDomainInfo *r)
866 {
867         const char * const attrs[] = { "objectSid", 
868                                        "objectGUID", "flatName", "securityIdentifier",
869                                        "trustPartner", NULL };
870         const char * const ref_attrs[] = { "nETBIOSName", "dnsRoot", NULL };
871         struct ldb_context *sam_ctx;
872         struct ldb_message **res1, **res2, **ref_res;
873         struct netr_DomainInfo1 *info1;
874         int ret, ret1, ret2, i;
875         NTSTATUS status;
876         struct ldb_dn *partitions_basedn;
877
878         const char *local_domain;
879
880         status = dcesrv_netr_creds_server_step_check(r->in.computer_name, mem_ctx, 
881                                               r->in.credential, 
882                                               r->out.return_authenticator,
883                                               NULL);
884         NT_STATUS_NOT_OK_RETURN(status);
885
886         sam_ctx = samdb_connect(mem_ctx, dce_call->conn->auth_state.session_info);
887         if (sam_ctx == NULL) {
888                 return NT_STATUS_INVALID_SYSTEM_SERVICE;
889         }
890
891         partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);
892
893         /* we need to do two searches. The first will pull our primary
894            domain and the second will pull any trusted domains. Our
895            primary domain is also a "trusted" domain, so we need to
896            put the primary domain into the lists of returned trusts as
897            well */
898         ret1 = gendb_search_dn(sam_ctx, mem_ctx, samdb_base_dn(sam_ctx), &res1, attrs);
899         if (ret1 != 1) {
900                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
901         }
902
903         /* try and find the domain */
904         ret = gendb_search(sam_ctx, mem_ctx, partitions_basedn, 
905                            &ref_res, ref_attrs, 
906                            "(&(objectClass=crossRef)(ncName=%s))", 
907                            ldb_dn_get_linearized(res1[0]->dn));
908         if (ret != 1) {
909                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
910         }
911
912         local_domain = samdb_result_string(ref_res[0], "nETBIOSName", NULL);
913
914         ret2 = gendb_search(sam_ctx, mem_ctx, NULL, &res2, attrs, "(objectClass=trustedDomain)");
915         if (ret2 == -1) {
916                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
917         }
918
919         info1 = talloc(mem_ctx, struct netr_DomainInfo1);
920         NT_STATUS_HAVE_NO_MEMORY(info1);
921
922         ZERO_STRUCTP(info1);
923
924         info1->num_trusts = ret2 + 1;
925         info1->trusts = talloc_array(mem_ctx, struct netr_DomainTrustInfo, 
926                                        info1->num_trusts);
927         NT_STATUS_HAVE_NO_MEMORY(info1->trusts);
928
929         status = fill_domain_trust_info(mem_ctx, res1[0], ref_res[0], &info1->domaininfo, true);
930         NT_STATUS_NOT_OK_RETURN(status);
931
932         for (i=0;i<ret2;i++) {
933                 status = fill_domain_trust_info(mem_ctx, res2[i], NULL, &info1->trusts[i], false);
934                 NT_STATUS_NOT_OK_RETURN(status);
935         }
936
937         status = fill_domain_trust_info(mem_ctx, res1[0], ref_res[0], &info1->trusts[i], true);
938         NT_STATUS_NOT_OK_RETURN(status);
939
940         r->out.info.info1 = info1;
941
942         return NT_STATUS_OK;
943 }
944
945
946
947 /* 
948   netr_NETRSERVERPASSWORDGET 
949 */
950 static WERROR dcesrv_netr_NETRSERVERPASSWORDGET(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
951                        struct netr_NETRSERVERPASSWORDGET *r)
952 {
953         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
954 }
955
956
957 /* 
958   netr_NETRLOGONSENDTOSAM 
959 */
960 static WERROR dcesrv_netr_NETRLOGONSENDTOSAM(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
961                        struct netr_NETRLOGONSENDTOSAM *r)
962 {
963         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
964 }
965
966
967 /* 
968   netr_DSRADDRESSTOSITENAMESW 
969 */
970 static WERROR dcesrv_netr_DSRADDRESSTOSITENAMESW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
971                        struct netr_DSRADDRESSTOSITENAMESW *r)
972 {
973         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
974 }
975
976
977 /* 
978   netr_DsRGetDCNameEx2
979 */
980 static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
981                                    struct netr_DsRGetDCNameEx2 *r)
982 {
983         const char * const attrs[] = { "dnsDomain", "objectGUID", NULL };
984         void *sam_ctx;
985         struct ldb_message **res;
986         int ret;
987
988         ZERO_STRUCT(r->out);
989
990         sam_ctx = samdb_connect(mem_ctx, dce_call->conn->auth_state.session_info);
991         if (sam_ctx == NULL) {
992                 return WERR_DS_SERVICE_UNAVAILABLE;
993         }
994
995         ret = gendb_search(sam_ctx, mem_ctx, NULL, &res, attrs,
996                                 "(&(objectClass=domainDNS)(dnsDomain=%s))",
997                                 r->in.domain_name);
998         if (ret != 1) {
999                 return WERR_NO_SUCH_DOMAIN;
1000         }
1001
1002         r->out.info = talloc(mem_ctx, struct netr_DsRGetDCNameInfo);
1003         W_ERROR_HAVE_NO_MEMORY(r->out.info);
1004
1005         /* TODO: - return real IP address
1006          *       - check all r->in.* parameters (server_unc is ignored by w2k3!)
1007          */
1008         r->out.info->dc_unc             = talloc_asprintf(mem_ctx, "\\\\%s.%s", 
1009                                                           lp_netbios_name(global_loadparm), 
1010                                                           lp_realm(global_loadparm));
1011         W_ERROR_HAVE_NO_MEMORY(r->out.info->dc_unc);
1012         r->out.info->dc_address         = talloc_strdup(mem_ctx, "\\\\0.0.0.0");
1013         W_ERROR_HAVE_NO_MEMORY(r->out.info->dc_address);
1014         r->out.info->dc_address_type    = DS_ADDRESS_TYPE_INET;
1015         r->out.info->domain_guid        = samdb_result_guid(res[0], "objectGUID");
1016         r->out.info->domain_name        = samdb_result_string(res[0], "dnsDomain", NULL);
1017         r->out.info->forest_name        = samdb_result_string(res[0], "dnsDomain", NULL);
1018         r->out.info->dc_flags           = DS_DNS_FOREST |
1019                                           DS_DNS_DOMAIN |
1020                                           DS_DNS_CONTROLLER |
1021                                           DS_SERVER_WRITABLE |
1022                                           DS_SERVER_CLOSEST |
1023                                           DS_SERVER_TIMESERV |
1024                                           DS_SERVER_KDC |
1025                                           DS_SERVER_DS |
1026                                           DS_SERVER_LDAP |
1027                                           DS_SERVER_GC |
1028                                           DS_SERVER_PDC;
1029         r->out.info->dc_site_name       = talloc_strdup(mem_ctx, "Default-First-Site-Name");
1030         W_ERROR_HAVE_NO_MEMORY(r->out.info->dc_site_name);
1031         r->out.info->client_site_name   = talloc_strdup(mem_ctx, "Default-First-Site-Name");
1032         W_ERROR_HAVE_NO_MEMORY(r->out.info->client_site_name);
1033
1034         return WERR_OK;
1035 }
1036
1037 /* 
1038   netr_DsRGetDCNameEx
1039 */
1040 static WERROR dcesrv_netr_DsRGetDCNameEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1041                                   struct netr_DsRGetDCNameEx *r)
1042 {
1043         struct netr_DsRGetDCNameEx2 r2;
1044         WERROR werr;
1045
1046         ZERO_STRUCT(r2);
1047
1048         r2.in.server_unc = r->in.server_unc;
1049         r2.in.client_account = NULL;
1050         r2.in.mask = 0;
1051         r2.in.domain_guid = r->in.domain_guid;
1052         r2.in.domain_name = r->in.domain_name;
1053         r2.in.site_name = r->in.site_name;
1054         r2.in.flags = r->in.flags;
1055         r2.out.info = NULL;
1056
1057         werr = dcesrv_netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1058         
1059         r->out.info = r2.out.info;
1060         
1061         return werr;
1062 }
1063
1064 /* 
1065   netr_DsRGetDCName
1066 */
1067 static WERROR dcesrv_netr_DsRGetDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1068                                 struct netr_DsRGetDCName *r)
1069 {
1070         struct netr_DsRGetDCNameEx2 r2;
1071         WERROR werr;
1072
1073         ZERO_STRUCT(r2);
1074
1075         r2.in.server_unc = r->in.server_unc;
1076         r2.in.client_account = NULL;
1077         r2.in.mask = 0;
1078         r2.in.domain_name = r->in.domain_name;
1079         r2.in.domain_guid = r->in.domain_guid;
1080         
1081         r2.in.site_name = NULL; /* should fill in from site GUID */
1082         r2.in.flags = r->in.flags;
1083         r2.out.info = NULL;
1084
1085         werr = dcesrv_netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1086         
1087         r->out.info = r2.out.info;
1088         
1089         return werr;
1090 }
1091
1092 /* 
1093   netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN 
1094 */
1095 static WERROR dcesrv_netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1096                        struct netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN *r)
1097 {
1098         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1099 }
1100
1101
1102 /* 
1103   netr_NETRENUMERATETRUSTEDDOMAINSEX 
1104 */
1105 static WERROR dcesrv_netr_NETRENUMERATETRUSTEDDOMAINSEX(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1106                        struct netr_NETRENUMERATETRUSTEDDOMAINSEX *r)
1107 {
1108         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1109 }
1110
1111
1112 /* 
1113   netr_DSRADDRESSTOSITENAMESEXW 
1114 */
1115 static WERROR dcesrv_netr_DSRADDRESSTOSITENAMESEXW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1116                        struct netr_DSRADDRESSTOSITENAMESEXW *r)
1117 {
1118         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1119 }
1120
1121
1122 /* 
1123   netr_DsrGetDcSiteCoverageW
1124 */
1125 static WERROR dcesrv_netr_DsrGetDcSiteCoverageW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1126                        struct netr_DsrGetDcSiteCoverageW *r)
1127 {
1128         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1129 }
1130
1131
1132 /* 
1133   netr_DsrEnumerateDomainTrusts 
1134 */
1135 static WERROR dcesrv_netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1136                                               struct netr_DsrEnumerateDomainTrusts *r)
1137 {
1138         struct netr_DomainTrust *trusts;
1139         void *sam_ctx;
1140         int ret;
1141         struct ldb_message **dom_res, **ref_res;
1142         const char * const dom_attrs[] = { "objectSid", "objectGUID", NULL };
1143         const char * const ref_attrs[] = { "nETBIOSName", "dnsRoot", NULL };
1144         struct ldb_dn *partitions_basedn;
1145
1146         ZERO_STRUCT(r->out);
1147
1148         sam_ctx = samdb_connect(mem_ctx, dce_call->conn->auth_state.session_info);
1149         if (sam_ctx == NULL) {
1150                 return WERR_GENERAL_FAILURE;
1151         }
1152
1153         partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);
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_get_linearized(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(ref_res[0], "dnsRoot", 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 dcesrv_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 dcesrv_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 dcesrv_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 dcesrv_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 dcesrv_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"