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