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