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