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