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