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