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