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