r26286: IDL and torture test for netr_ServerTrustPasswordsGet().
[jelmer/samba4-debian.git] / source / rpc_server / netlogon / dcerpc_netlogon.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    endpoint server for the netlogon pipe
5
6    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004
7    Copyright (C) Stefan Metzmacher <metze@samba.org>  2005
8    
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 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 "util/util_ldb.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, global_loadparm, system_session(mem_ctx, global_loadparm));
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, global_loadparm, 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, global_loadparm);
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, global_loadparm, system_session(mem_ctx, global_loadparm));
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, global_loadparm, system_session(mem_ctx, global_loadparm));
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                                                 global_loadparm,
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, 
461                                                 dce_call->event_ctx, dce_call->msg_ctx,
462                                                 global_loadparm,
463                                                 &auth_context);
464                 NT_STATUS_NOT_OK_RETURN(nt_status);
465
466                 nt_status = auth_context_set_challenge(auth_context, r->in.logon.network->challenge, "netr_LogonSamLogonWithFlags");
467                 NT_STATUS_NOT_OK_RETURN(nt_status);
468
469                 user_info->logon_parameters = r->in.logon.network->identity_info.parameter_control;
470                 user_info->client.account_name = r->in.logon.network->identity_info.account_name.string;
471                 user_info->client.domain_name = r->in.logon.network->identity_info.domain_name.string;
472                 user_info->workstation_name = r->in.logon.network->identity_info.workstation.string;
473                 
474                 user_info->password_state = AUTH_PASSWORD_RESPONSE;
475                 user_info->password.response.lanman = data_blob_talloc(mem_ctx, r->in.logon.network->lm.data, r->in.logon.network->lm.length);
476                 user_info->password.response.nt = data_blob_talloc(mem_ctx, r->in.logon.network->nt.data, r->in.logon.network->nt.length);
477         
478                 break;
479         default:
480                 return NT_STATUS_INVALID_PARAMETER;
481         }
482         
483         nt_status = auth_check_password(auth_context, mem_ctx, user_info, &server_info);
484         NT_STATUS_NOT_OK_RETURN(nt_status);
485
486         nt_status = auth_convert_server_info_sambaseinfo(mem_ctx, server_info, &sam);
487         NT_STATUS_NOT_OK_RETURN(nt_status);
488
489         /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
490         /* It appears that level 6 is not individually encrypted */
491         if ((r->in.validation_level != 6) &&
492             memcmp(sam->key.key, zeros, sizeof(sam->key.key)) != 0) {
493                 /* This key is sent unencrypted without the ARCFOUR flag set */
494                 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
495                         creds_arcfour_crypt(creds, 
496                                             sam->key.key, 
497                                             sizeof(sam->key.key));
498                 }
499         }
500
501         /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
502         /* It appears that level 6 is not individually encrypted */
503         if ((r->in.validation_level != 6) &&
504             memcmp(sam->LMSessKey.key, zeros, sizeof(sam->LMSessKey.key)) != 0) {
505                 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
506                         creds_arcfour_crypt(creds, 
507                                             sam->LMSessKey.key, 
508                                             sizeof(sam->LMSessKey.key));
509                 } else {
510                         creds_des_encrypt_LMKey(creds, 
511                                                 &sam->LMSessKey);
512                 }
513         }
514
515         switch (r->in.validation_level) {
516         case 2:
517                 sam2 = talloc_zero(mem_ctx, struct netr_SamInfo2);
518                 NT_STATUS_HAVE_NO_MEMORY(sam2);
519                 sam2->base = *sam;
520                 r->out.validation.sam2 = sam2;
521                 break;
522
523         case 3:
524                 sam3 = talloc_zero(mem_ctx, struct netr_SamInfo3);
525                 NT_STATUS_HAVE_NO_MEMORY(sam3);
526                 sam3->base = *sam;
527                 r->out.validation.sam3 = sam3;
528                 break;
529
530         case 6:
531                 sam6 = talloc_zero(mem_ctx, struct netr_SamInfo6);
532                 NT_STATUS_HAVE_NO_MEMORY(sam6);
533                 sam6->base = *sam;
534                 sam6->forest.string = lp_realm(global_loadparm);
535                 sam6->principle.string = talloc_asprintf(mem_ctx, "%s@%s", 
536                                                          sam->account_name.string, sam6->forest.string);
537                 NT_STATUS_HAVE_NO_MEMORY(sam6->principle.string);
538                 r->out.validation.sam6 = sam6;
539                 break;
540
541         default:
542                 break;
543         }
544
545         r->out.authoritative = 1;
546
547         /* TODO: Describe and deal with these flags */
548         r->out.flags = 0;
549
550         return NT_STATUS_OK;
551 }
552
553 static NTSTATUS dcesrv_netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
554                                      struct netr_LogonSamLogonEx *r) 
555 {
556         NTSTATUS nt_status;
557         struct creds_CredentialState *creds;
558         nt_status = schannel_fetch_session_key(mem_ctx, global_loadparm, r->in.computer_name, lp_workgroup(global_loadparm), &creds);
559         if (!NT_STATUS_IS_OK(nt_status)) {
560                 return nt_status;
561         }
562
563         if (!dce_call->conn->auth_state.auth_info ||
564             dce_call->conn->auth_state.auth_info->auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
565                 return NT_STATUS_INTERNAL_ERROR;
566         }
567         return dcesrv_netr_LogonSamLogon_base(dce_call, mem_ctx, r, creds);
568 }
569
570 /* 
571   netr_LogonSamLogonWithFlags
572
573 */
574 static NTSTATUS dcesrv_netr_LogonSamLogonWithFlags(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
575                                             struct netr_LogonSamLogonWithFlags *r)
576 {
577         NTSTATUS nt_status;
578         struct creds_CredentialState *creds;
579         struct netr_LogonSamLogonEx r2;
580
581         struct netr_Authenticator *return_authenticator;
582
583         return_authenticator = talloc(mem_ctx, struct netr_Authenticator);
584         NT_STATUS_HAVE_NO_MEMORY(return_authenticator);
585
586         nt_status = dcesrv_netr_creds_server_step_check(r->in.computer_name, mem_ctx, 
587                                                  r->in.credential, return_authenticator,
588                                                  &creds);
589         NT_STATUS_NOT_OK_RETURN(nt_status);
590
591         ZERO_STRUCT(r2);
592
593         r2.in.server_name       = r->in.server_name;
594         r2.in.computer_name     = r->in.computer_name;
595         r2.in.logon_level       = r->in.logon_level;
596         r2.in.logon             = r->in.logon;
597         r2.in.validation_level  = r->in.validation_level;
598         r2.in.flags             = r->in.flags;
599
600         nt_status = dcesrv_netr_LogonSamLogon_base(dce_call, mem_ctx, &r2, creds);
601
602         r->out.return_authenticator     = return_authenticator;
603         r->out.validation               = r2.out.validation;
604         r->out.authoritative            = r2.out.authoritative;
605         r->out.flags                    = r2.out.flags;
606
607         return nt_status;
608 }
609
610 /* 
611   netr_LogonSamLogon
612 */
613 static NTSTATUS dcesrv_netr_LogonSamLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
614                                    struct netr_LogonSamLogon *r)
615 {
616         struct netr_LogonSamLogonWithFlags r2;
617         NTSTATUS status;
618
619         ZERO_STRUCT(r2);
620
621         r2.in.server_name = r->in.server_name;
622         r2.in.computer_name = r->in.computer_name;
623         r2.in.credential  = r->in.credential;
624         r2.in.return_authenticator = r->in.return_authenticator;
625         r2.in.logon_level = r->in.logon_level;
626         r2.in.logon = r->in.logon;
627         r2.in.validation_level = r->in.validation_level;
628         r2.in.flags = 0;
629
630         status = dcesrv_netr_LogonSamLogonWithFlags(dce_call, mem_ctx, &r2);
631
632         r->out.return_authenticator = r2.out.return_authenticator;
633         r->out.validation = r2.out.validation;
634         r->out.authoritative = r2.out.authoritative;
635
636         return status;
637 }
638
639
640 /* 
641   netr_LogonSamLogoff 
642 */
643 static NTSTATUS dcesrv_netr_LogonSamLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
644                        struct netr_LogonSamLogoff *r)
645 {
646         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
647 }
648
649
650
651 /* 
652   netr_DatabaseDeltas 
653 */
654 static NTSTATUS dcesrv_netr_DatabaseDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
655                        struct netr_DatabaseDeltas *r)
656 {
657         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
658 }
659
660
661 /* 
662   netr_DatabaseSync 
663 */
664 static NTSTATUS dcesrv_netr_DatabaseSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
665                        struct netr_DatabaseSync *r)
666 {
667         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
668 }
669
670
671 /* 
672   netr_AccountDeltas 
673 */
674 static NTSTATUS dcesrv_netr_AccountDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
675                        struct netr_AccountDeltas *r)
676 {
677         /* w2k3 returns "NOT IMPLEMENTED" for this call */
678         return NT_STATUS_NOT_IMPLEMENTED;
679 }
680
681
682 /* 
683   netr_AccountSync 
684 */
685 static NTSTATUS dcesrv_netr_AccountSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
686                        struct netr_AccountSync *r)
687 {
688         /* w2k3 returns "NOT IMPLEMENTED" for this call */
689         return NT_STATUS_NOT_IMPLEMENTED;
690 }
691
692
693 /* 
694   netr_GetDcName 
695 */
696 static WERROR dcesrv_netr_GetDcName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
697                        struct netr_GetDcName *r)
698 {
699         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
700 }
701
702
703 /* 
704   netr_LogonControl 
705 */
706 static WERROR dcesrv_netr_LogonControl(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
707                        struct netr_LogonControl *r)
708 {
709         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
710 }
711
712
713 /* 
714   netr_GetAnyDCName 
715 */
716 static WERROR dcesrv_netr_GetAnyDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
717                        struct netr_GetAnyDCName *r)
718 {
719         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
720 }
721
722
723 /* 
724   netr_LogonControl2 
725 */
726 static WERROR dcesrv_netr_LogonControl2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
727                        struct netr_LogonControl2 *r)
728 {
729         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
730 }
731
732
733 /* 
734   netr_DatabaseSync2 
735 */
736 static NTSTATUS dcesrv_netr_DatabaseSync2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
737                        struct netr_DatabaseSync2 *r)
738 {
739         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
740 }
741
742
743 /* 
744   netr_DatabaseRedo 
745 */
746 static NTSTATUS dcesrv_netr_DatabaseRedo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
747                        struct netr_DatabaseRedo *r)
748 {
749         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
750 }
751
752
753 /* 
754   netr_LogonControl2Ex 
755 */
756 static WERROR dcesrv_netr_LogonControl2Ex(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
757                        struct netr_LogonControl2Ex *r)
758 {
759         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
760 }
761
762
763 /* 
764   netr_NetrEnumerateTurstedDomains
765 */
766 static WERROR dcesrv_netr_NetrEnumerateTrustedDomains(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
767                        struct netr_NetrEnumerateTrustedDomains *r)
768 {
769         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
770 }
771
772
773 /* 
774   netr_NETRLOGONDUMMYROUTINE1 
775 */
776 static WERROR dcesrv_netr_NETRLOGONDUMMYROUTINE1(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
777                        struct netr_NETRLOGONDUMMYROUTINE1 *r)
778 {
779         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
780 }
781
782
783 /* 
784   netr_NETRLOGONSETSERVICEBITS 
785 */
786 static WERROR dcesrv_netr_NETRLOGONSETSERVICEBITS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
787                        struct netr_NETRLOGONSETSERVICEBITS *r)
788 {
789         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
790 }
791
792
793 /* 
794   netr_NETRLOGONGETTRUSTRID 
795 */
796 static WERROR dcesrv_netr_NETRLOGONGETTRUSTRID(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
797                        struct netr_NETRLOGONGETTRUSTRID *r)
798 {
799         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
800 }
801
802
803 /* 
804   netr_NETRLOGONCOMPUTESERVERDIGEST 
805 */
806 static WERROR dcesrv_netr_NETRLOGONCOMPUTESERVERDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
807                        struct netr_NETRLOGONCOMPUTESERVERDIGEST *r)
808 {
809         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
810 }
811
812
813 /* 
814   netr_NETRLOGONCOMPUTECLIENTDIGEST 
815 */
816 static WERROR dcesrv_netr_NETRLOGONCOMPUTECLIENTDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
817                        struct netr_NETRLOGONCOMPUTECLIENTDIGEST *r)
818 {
819         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
820 }
821
822
823
824 /* 
825   netr_DsRGetSiteName
826 */
827 static WERROR dcesrv_netr_DsRGetSiteName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
828                                   struct netr_DsRGetSiteName *r)
829 {
830         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
831 }
832
833
834 /*
835   fill in a netr_DomainTrustInfo from a ldb search result
836 */
837 static NTSTATUS fill_domain_trust_info(TALLOC_CTX *mem_ctx,
838                                        struct ldb_message *res,
839                                        struct ldb_message *ref_res,
840                                        struct netr_DomainTrustInfo *info, 
841                                        bool is_local)
842 {
843         ZERO_STRUCTP(info);
844
845         if (is_local) {
846                 info->domainname.string = samdb_result_string(ref_res, "nETBIOSName", NULL);
847                 info->fulldomainname.string = samdb_result_string(ref_res, "dnsRoot", NULL);
848                 info->forest.string = NULL;
849                 info->guid = samdb_result_guid(res, "objectGUID");
850                 info->sid = samdb_result_dom_sid(mem_ctx, res, "objectSid");
851         } else {
852                 info->domainname.string = samdb_result_string(res, "flatName", NULL);
853                 info->fulldomainname.string = samdb_result_string(res, "trustPartner", NULL);
854                 info->forest.string = NULL;
855                 info->guid = samdb_result_guid(res, "objectGUID");
856                 info->sid = samdb_result_dom_sid(mem_ctx, res, "securityIdentifier");
857         }
858
859         return NT_STATUS_OK;
860 }
861
862 /* 
863   netr_LogonGetDomainInfo
864   this is called as part of the ADS domain logon procedure.
865 */
866 static NTSTATUS dcesrv_netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
867                                         struct netr_LogonGetDomainInfo *r)
868 {
869         const char * const attrs[] = { "objectSid", 
870                                        "objectGUID", "flatName", "securityIdentifier",
871                                        "trustPartner", NULL };
872         const char * const ref_attrs[] = { "nETBIOSName", "dnsRoot", NULL };
873         struct ldb_context *sam_ctx;
874         struct ldb_message **res1, **res2, **ref_res;
875         struct netr_DomainInfo1 *info1;
876         int ret, ret1, ret2, i;
877         NTSTATUS status;
878         struct ldb_dn *partitions_basedn;
879
880         const char *local_domain;
881
882         status = dcesrv_netr_creds_server_step_check(r->in.computer_name, mem_ctx, 
883                                               r->in.credential, 
884                                               r->out.return_authenticator,
885                                               NULL);
886         NT_STATUS_NOT_OK_RETURN(status);
887
888         sam_ctx = samdb_connect(mem_ctx, global_loadparm, dce_call->conn->auth_state.session_info);
889         if (sam_ctx == NULL) {
890                 return NT_STATUS_INVALID_SYSTEM_SERVICE;
891         }
892
893         partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);
894
895         /* we need to do two searches. The first will pull our primary
896            domain and the second will pull any trusted domains. Our
897            primary domain is also a "trusted" domain, so we need to
898            put the primary domain into the lists of returned trusts as
899            well */
900         ret1 = gendb_search_dn(sam_ctx, mem_ctx, samdb_base_dn(sam_ctx), &res1, attrs);
901         if (ret1 != 1) {
902                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
903         }
904
905         /* try and find the domain */
906         ret = gendb_search(sam_ctx, mem_ctx, partitions_basedn, 
907                            &ref_res, ref_attrs, 
908                            "(&(objectClass=crossRef)(ncName=%s))", 
909                            ldb_dn_get_linearized(res1[0]->dn));
910         if (ret != 1) {
911                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
912         }
913
914         local_domain = samdb_result_string(ref_res[0], "nETBIOSName", NULL);
915
916         ret2 = gendb_search(sam_ctx, mem_ctx, NULL, &res2, attrs, "(objectClass=trustedDomain)");
917         if (ret2 == -1) {
918                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
919         }
920
921         info1 = talloc(mem_ctx, struct netr_DomainInfo1);
922         NT_STATUS_HAVE_NO_MEMORY(info1);
923
924         ZERO_STRUCTP(info1);
925
926         info1->num_trusts = ret2 + 1;
927         info1->trusts = talloc_array(mem_ctx, struct netr_DomainTrustInfo, 
928                                        info1->num_trusts);
929         NT_STATUS_HAVE_NO_MEMORY(info1->trusts);
930
931         status = fill_domain_trust_info(mem_ctx, res1[0], ref_res[0], &info1->domaininfo, true);
932         NT_STATUS_NOT_OK_RETURN(status);
933
934         for (i=0;i<ret2;i++) {
935                 status = fill_domain_trust_info(mem_ctx, res2[i], NULL, &info1->trusts[i], false);
936                 NT_STATUS_NOT_OK_RETURN(status);
937         }
938
939         status = fill_domain_trust_info(mem_ctx, res1[0], ref_res[0], &info1->trusts[i], true);
940         NT_STATUS_NOT_OK_RETURN(status);
941
942         r->out.info.info1 = info1;
943
944         return NT_STATUS_OK;
945 }
946
947
948
949 /*
950   netr_ServerPasswordGet
951 */
952 static WERROR dcesrv_netr_ServerPasswordGet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
953                        struct netr_ServerPasswordGet *r)
954 {
955         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
956 }
957
958
959 /* 
960   netr_NETRLOGONSENDTOSAM 
961 */
962 static WERROR dcesrv_netr_NETRLOGONSENDTOSAM(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
963                        struct netr_NETRLOGONSENDTOSAM *r)
964 {
965         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
966 }
967
968
969 /* 
970   netr_DsRAddressToSitenamesW 
971 */
972 static WERROR dcesrv_netr_DsRAddressToSitenamesW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
973                        struct netr_DsRAddressToSitenamesW *r)
974 {
975         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
976 }
977
978
979 /* 
980   netr_DsRGetDCNameEx2
981 */
982 static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
983                                    struct netr_DsRGetDCNameEx2 *r)
984 {
985         const char * const attrs[] = { "dnsDomain", "objectGUID", NULL };
986         void *sam_ctx;
987         struct ldb_message **res;
988         int ret;
989
990         ZERO_STRUCT(r->out);
991
992         sam_ctx = samdb_connect(mem_ctx, global_loadparm, dce_call->conn->auth_state.session_info);
993         if (sam_ctx == NULL) {
994                 return WERR_DS_SERVICE_UNAVAILABLE;
995         }
996
997         ret = gendb_search(sam_ctx, mem_ctx, NULL, &res, attrs,
998                                 "(&(objectClass=domainDNS)(dnsDomain=%s))",
999                                 r->in.domain_name);
1000         if (ret != 1) {
1001                 return WERR_NO_SUCH_DOMAIN;
1002         }
1003
1004         r->out.info = talloc(mem_ctx, struct netr_DsRGetDCNameInfo);
1005         W_ERROR_HAVE_NO_MEMORY(r->out.info);
1006
1007         /* TODO: - return real IP address
1008          *       - check all r->in.* parameters (server_unc is ignored by w2k3!)
1009          */
1010         r->out.info->dc_unc             = talloc_asprintf(mem_ctx, "\\\\%s.%s", 
1011                                                           lp_netbios_name(global_loadparm), 
1012                                                           lp_realm(global_loadparm));
1013         W_ERROR_HAVE_NO_MEMORY(r->out.info->dc_unc);
1014         r->out.info->dc_address         = talloc_strdup(mem_ctx, "\\\\0.0.0.0");
1015         W_ERROR_HAVE_NO_MEMORY(r->out.info->dc_address);
1016         r->out.info->dc_address_type    = DS_ADDRESS_TYPE_INET;
1017         r->out.info->domain_guid        = samdb_result_guid(res[0], "objectGUID");
1018         r->out.info->domain_name        = samdb_result_string(res[0], "dnsDomain", NULL);
1019         r->out.info->forest_name        = samdb_result_string(res[0], "dnsDomain", NULL);
1020         r->out.info->dc_flags           = DS_DNS_FOREST |
1021                                           DS_DNS_DOMAIN |
1022                                           DS_DNS_CONTROLLER |
1023                                           DS_SERVER_WRITABLE |
1024                                           DS_SERVER_CLOSEST |
1025                                           DS_SERVER_TIMESERV |
1026                                           DS_SERVER_KDC |
1027                                           DS_SERVER_DS |
1028                                           DS_SERVER_LDAP |
1029                                           DS_SERVER_GC |
1030                                           DS_SERVER_PDC;
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 dcesrv_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 = dcesrv_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 dcesrv_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 = dcesrv_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 dcesrv_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 dcesrv_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 dcesrv_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 dcesrv_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 dcesrv_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[] = { "objectSid", "objectGUID", NULL };
1145         const char * const ref_attrs[] = { "nETBIOSName", "dnsRoot", NULL };
1146         struct ldb_dn *partitions_basedn;
1147
1148         ZERO_STRUCT(r->out);
1149
1150         sam_ctx = samdb_connect(mem_ctx, global_loadparm, dce_call->conn->auth_state.session_info);
1151         if (sam_ctx == NULL) {
1152                 return WERR_GENERAL_FAILURE;
1153         }
1154
1155         partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);
1156
1157         ret = gendb_search_dn(sam_ctx, mem_ctx, NULL, &dom_res, dom_attrs);
1158         if (ret == -1) {
1159                 return WERR_GENERAL_FAILURE;            
1160         }
1161         if (ret != 1) {
1162                 return WERR_GENERAL_FAILURE;
1163         }
1164
1165         ret = gendb_search(sam_ctx, mem_ctx, partitions_basedn, &ref_res, ref_attrs,
1166                            "(&(objectClass=crossRef)(ncName=%s))",
1167                            ldb_dn_get_linearized(dom_res[0]->dn));
1168         if (ret == -1) {
1169                 return WERR_GENERAL_FAILURE;
1170         }
1171         if (ret != 1) {
1172                 return WERR_GENERAL_FAILURE;
1173         }
1174
1175         trusts = talloc_array(mem_ctx, struct netr_DomainTrust, ret);
1176         W_ERROR_HAVE_NO_MEMORY(trusts);
1177         
1178         r->out.count = 1;
1179         r->out.trusts = trusts;
1180
1181         /* TODO: add filtering by trust_flags, and correct trust_type
1182            and attributes */
1183         trusts[0].netbios_name = samdb_result_string(ref_res[0], "nETBIOSName", NULL);
1184         trusts[0].dns_name     = samdb_result_string(ref_res[0], "dnsRoot", NULL);
1185         trusts[0].trust_flags = 
1186                 NETR_TRUST_FLAG_TREEROOT | 
1187                 NETR_TRUST_FLAG_IN_FOREST | 
1188                 NETR_TRUST_FLAG_PRIMARY;
1189         trusts[0].parent_index = 0;
1190         trusts[0].trust_type = 2;
1191         trusts[0].trust_attributes = 0;
1192         trusts[0].sid  = samdb_result_dom_sid(mem_ctx, dom_res[0], "objectSid");
1193         trusts[0].guid = samdb_result_guid(dom_res[0], "objectGUID");
1194
1195         return WERR_OK;
1196 }
1197
1198
1199 /* 
1200   netr_DSRDEREGISTERDNSHOSTRECORDS 
1201 */
1202 static WERROR dcesrv_netr_DSRDEREGISTERDNSHOSTRECORDS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1203                        struct netr_DSRDEREGISTERDNSHOSTRECORDS *r)
1204 {
1205         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1206 }
1207
1208
1209 /*
1210   netr_ServerTrustPasswordsGet
1211 */
1212 static NTSTATUS dcesrv_netr_ServerTrustPasswordsGet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1213                        struct netr_ServerTrustPasswordsGet *r)
1214 {
1215         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1216 }
1217
1218
1219 /* 
1220   netr_DsRGetForestTrustInformation 
1221 */
1222 static WERROR dcesrv_netr_DsRGetForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1223                        struct netr_DsRGetForestTrustInformation *r)
1224 {
1225         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1226 }
1227
1228
1229 /* 
1230   netr_NETRGETFORESTTRUSTINFORMATION 
1231 */
1232 static WERROR dcesrv_netr_NETRGETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1233                        struct netr_NETRGETFORESTTRUSTINFORMATION *r)
1234 {
1235         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1236 }
1237
1238
1239 /* 
1240   netr_NETRSERVERGETTRUSTINFO 
1241 */
1242 static WERROR dcesrv_netr_NETRSERVERGETTRUSTINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1243                        struct netr_NETRSERVERGETTRUSTINFO *r)
1244 {
1245         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1246 }
1247
1248
1249 /* include the generated boilerplate */
1250 #include "librpc/gen_ndr/ndr_netlogon_s.c"