r950: - added netr_ServerAuthenticate3(). This is used by WinXP clients who try to...
[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
7    
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #include "includes.h"
24 #include "rpc_server/common/common.h"
25
26 struct server_pipe_state {
27         TALLOC_CTX *mem_ctx;
28         struct netr_Credential client_challenge;
29         struct netr_Credential server_challenge;
30         BOOL authenticated;
31         char *account_name;
32         char *computer_name;  /* for logging only */
33         uint32_t acct_flags;
34         uint16_t sec_chan_type;
35         struct creds_CredentialState *creds;
36 };
37
38 static NTSTATUS netlogon_bind(struct dcesrv_call_state *dce_call, const struct dcesrv_interface *di) 
39 {
40         dce_call->conn->private = NULL;
41
42         return NT_STATUS_OK;
43 }
44
45 /* this function is called when the client disconnects the endpoint */
46 static void netlogon_unbind(struct dcesrv_connection *conn, const struct dcesrv_interface *di) 
47 {
48         struct server_pipe_state *pipe_state = conn->private;
49
50         if (pipe_state)
51                 talloc_destroy(pipe_state->mem_ctx);
52         
53         conn->private = NULL;
54 }
55
56 #define DCESRV_INTERFACE_NETLOGON_BIND netlogon_bind
57 #define DCESRV_INTERFACE_NETLOGON_UNBIND netlogon_unbind
58
59 /* 
60   netr_ServerReqChallenge 
61
62         NTSTATUS netr_ServerReqChallenge(
63                 [in]         unistr *server_name,
64                 [in]         unistr computer_name,
65                 [in,out,ref] netr_Credential *credentials
66                 );
67
68 */
69 static NTSTATUS netr_ServerReqChallenge(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
70                                         struct netr_ServerReqChallenge *r)
71 {
72         struct server_pipe_state *pipe_state = dce_call->conn->private;
73         TALLOC_CTX *pipe_mem_ctx;
74
75         ZERO_STRUCTP(r->out.credentials);
76
77         /* destroyed on pipe shutdown */
78
79         if (pipe_state) {
80                 talloc_destroy(pipe_state->mem_ctx);
81                 dce_call->conn->private = NULL;
82         }
83         
84         pipe_mem_ctx = talloc_init("internal netlogon pipe state for %s", 
85                                    r->in.computer_name);
86         
87         if (!pipe_mem_ctx) {
88                 return NT_STATUS_NO_MEMORY;
89         }
90
91         pipe_state = talloc_p(pipe_mem_ctx, struct server_pipe_state);
92         if (!pipe_state) {
93                 talloc_destroy(pipe_mem_ctx);
94                 return NT_STATUS_NO_MEMORY;
95         }
96
97         pipe_state->mem_ctx = pipe_mem_ctx;
98         pipe_state->authenticated = False;
99         pipe_state->creds = NULL;
100         pipe_state->account_name = NULL;
101         pipe_state->computer_name = NULL;
102
103         pipe_state->client_challenge = *r->in.credentials;
104
105         generate_random_buffer(pipe_state->server_challenge.data, 
106                                sizeof(pipe_state->server_challenge.data),
107                                False);
108
109         *r->out.credentials = pipe_state->server_challenge;
110
111         dce_call->conn->private = pipe_state;
112
113         return NT_STATUS_OK;
114 }
115
116
117 /* 
118   netr_ServerAuthenticate 
119
120          secure channel types:
121  
122         const int SEC_CHAN_WKSTA   = 2;
123         const int SEC_CHAN_DOMAIN  = 4;
124         const int SEC_CHAN_BDC     = 6;
125
126         NTSTATUS netr_ServerAuthenticate3(
127                 [in]         unistr *server_name,
128                 [in]         unistr username,
129                 [in]         uint16 secure_channel_type,
130                 [in]         unistr computer_name,
131                 [in,out,ref] netr_Credential *credentials
132                 [in,out,ref] uint32 *negotiate_flags,
133                 [out,ref]    uint32 *rid
134                 );
135 */
136 static NTSTATUS netr_ServerAuthenticate3(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
137                                          struct netr_ServerAuthenticate3 *r)
138 {
139         struct server_pipe_state *pipe_state = dce_call->conn->private;
140         void *sam_ctx;
141         uint8_t *mach_pwd;
142         uint16_t acct_flags;
143         int num_records;
144         struct ldb_message **msgs;
145         NTSTATUS nt_status;
146         const char *attrs[] = {"unicodePwd", "lmPwdHash", "ntPwdHash", "userAccountControl", 
147                                "objectSid", NULL};
148
149         ZERO_STRUCTP(r->out.credentials);
150         *r->out.negotiate_flags = 0;
151         *r->out.rid = 0;
152
153         if (!pipe_state) {
154                 DEBUG(1, ("No challange requested by client, cannot authenticate\n"));
155                 return NT_STATUS_ACCESS_DENIED;
156         }
157
158         sam_ctx = samdb_connect();
159         if (sam_ctx == NULL) {
160                 return NT_STATUS_INVALID_SYSTEM_SERVICE;
161         }
162         /* pull the user attributes */
163         num_records = samdb_search(sam_ctx, mem_ctx, NULL, &msgs, attrs,
164                                    "(&(sAMAccountName=%s)(objectclass=user))", 
165                                    r->in.username);
166
167         if (num_records == 0) {
168                 DEBUG(3,("Couldn't find user [%s] in samdb.\n", 
169                          r->in.username));
170                 samdb_close(sam_ctx);
171                 return NT_STATUS_NO_SUCH_USER;
172         }
173
174         if (num_records > 1) {
175                 DEBUG(1,("Found %d records matching user [%s]\n", num_records, r->in.username));
176                 samdb_close(sam_ctx);
177                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
178         }
179
180         acct_flags = samdb_result_acct_flags(msgs[0], 
181                                              "userAccountControl");
182
183         if (acct_flags & ACB_DISABLED) {
184                 DEBUG(1, ("Account [%s] is disabled\n", r->in.username));
185                 return NT_STATUS_ACCESS_DENIED;
186         }
187
188         if (r->in.secure_channel_type == SEC_CHAN_WKSTA) {
189                 if (!(acct_flags & ACB_WSTRUST)) {
190                         DEBUG(1, ("Client asked for a workstation secure channel, but is not a workstation (member server) acb flags: 0x%x\n", acct_flags));
191                         return NT_STATUS_ACCESS_DENIED;
192                 }
193         } else if (r->in.secure_channel_type == SEC_CHAN_DOMAIN) {
194                 if (!(acct_flags & ACB_DOMTRUST)) {
195                         DEBUG(1, ("Client asked for a trusted domain secure channel, but is not a trusted domain: acb flags: 0x%x\n", acct_flags));
196                         return NT_STATUS_ACCESS_DENIED;
197                 }
198         } else if (r->in.secure_channel_type == SEC_CHAN_BDC) {
199                 if (!(acct_flags & ACB_SVRTRUST)) {
200                         DEBUG(1, ("Client asked for a server secure channel, but is not a server (domain controller): acb flags: 0x%x\n", acct_flags));
201                         return NT_STATUS_ACCESS_DENIED;
202                 }
203         } else {
204                 DEBUG(1, ("Client asked for an invalid secure channel type: %d\n", 
205                           r->in.secure_channel_type));
206                 return NT_STATUS_ACCESS_DENIED;
207         }
208
209         pipe_state->acct_flags = acct_flags;
210         pipe_state->sec_chan_type = r->in.secure_channel_type;
211
212         *r->out.rid = samdb_result_rid_from_sid(mem_ctx, msgs[0], "objectSid", 0);
213
214         nt_status = samdb_result_passwords(mem_ctx, msgs[0], NULL, &mach_pwd);
215         if (!NT_STATUS_IS_OK(nt_status)) {
216                 samdb_close(sam_ctx);
217                 return NT_STATUS_ACCESS_DENIED;
218         }
219
220         samdb_close(sam_ctx);
221
222         if (!pipe_state->creds) {
223                 pipe_state->creds = talloc_p(pipe_state->mem_ctx, struct creds_CredentialState);
224                 if (!pipe_state->creds) {
225                         return NT_STATUS_NO_MEMORY;
226                 }
227         }
228
229         creds_server_init(pipe_state->creds, &pipe_state->client_challenge, 
230                           &pipe_state->server_challenge, mach_pwd,
231                           r->out.credentials);
232
233         if (!creds_server_check(pipe_state->creds, r->in.credentials)) {
234                 return NT_STATUS_ACCESS_DENIED;
235         }
236
237         pipe_state->authenticated = True;
238
239         if (pipe_state->account_name) {
240                 /* We don't want a memory leak on this long-lived talloc context */
241                 talloc_free(pipe_state->mem_ctx, pipe_state->account_name);
242         }
243
244         pipe_state->account_name = talloc_strdup(pipe_state->mem_ctx, r->in.username);
245         
246         if (pipe_state->computer_name) {
247                 /* We don't want a memory leak on this long-lived talloc context */
248                 talloc_free(pipe_state->mem_ctx, pipe_state->account_name);
249         }
250
251         pipe_state->computer_name = talloc_strdup(pipe_state->mem_ctx, r->in.computer_name);
252         
253         *r->out.negotiate_flags = NETLOGON_NEG_AUTH2_FLAGS;
254
255         return NT_STATUS_OK;
256 }
257                                                  
258
259 static NTSTATUS netr_ServerAuthenticate(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
260                                         struct netr_ServerAuthenticate *r)
261 {
262         struct netr_ServerAuthenticate3 r3;
263         uint32 negotiate_flags, rid;
264
265         r3.in.server_name = r->in.server_name;
266         r3.in.username = r->in.username;
267         r3.in.secure_channel_type = r->in.secure_channel_type;
268         r3.in.computer_name = r->in.computer_name;
269         r3.in.credentials = r->in.credentials;
270         r3.out.credentials = r->out.credentials;
271         r3.in.negotiate_flags = &negotiate_flags;
272         r3.out.negotiate_flags = &negotiate_flags;
273         r3.out.rid = &rid;
274         
275         return netr_ServerAuthenticate3(dce_call, mem_ctx, &r3);
276 }
277
278 static NTSTATUS netr_ServerAuthenticate2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
279                                          struct netr_ServerAuthenticate2 *r)
280 {
281         struct netr_ServerAuthenticate3 r3;
282         uint32 rid;
283
284         r3.in.server_name = r->in.server_name;
285         r3.in.username = r->in.username;
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.credentials = r->out.credentials;
290         r3.in.negotiate_flags = r->in.negotiate_flags;
291         r3.out.negotiate_flags = r->out.negotiate_flags;
292         r3.out.rid = &rid;
293         
294         return netr_ServerAuthenticate3(dce_call, mem_ctx, &r3);
295 }
296
297
298 static BOOL netr_creds_server_step_check(struct server_pipe_state *pipe_state,
299                                          struct netr_Authenticator *received_authenticator,
300                                          struct netr_Authenticator *return_authenticator) 
301 {
302         if (!pipe_state->authenticated) {
303                 return False;
304         }
305         return creds_server_step_check(pipe_state->creds, 
306                                        received_authenticator, 
307                                        return_authenticator);
308 }
309
310 /* 
311  netr_ServerPasswordSet 
312
313         NTSTATUS netr_ServerPasswordSet(
314                 [in]  unistr *server_name,
315                 [in]  unistr username,
316                 [in]  uint16 secure_channel_type,
317                 [in]  unistr computer_name,
318                 [in]  netr_Authenticator credential,
319                 [in]  netr_Password new_password,
320                 [out] netr_Authenticator return_authenticator
321                 );
322
323 */
324 static NTSTATUS netr_ServerPasswordSet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
325                                        struct netr_ServerPasswordSet *r)
326 {
327         struct server_pipe_state *pipe_state = dce_call->conn->private;
328
329         void *sam_ctx;
330         int num_records;
331         int num_records_domain;
332         int ret;
333         struct ldb_message **msgs;
334         struct ldb_message **msgs_domain;
335         NTSTATUS nt_status;
336         struct samr_Hash newNtHash;
337         struct ldb_message mod, *msg_set_pw = &mod;
338         const char *domain_dn;
339         const char *domain_sid;
340
341         const char *attrs[] = {"objectSid", NULL };
342
343         const char **domain_attrs = attrs;
344         ZERO_STRUCT(mod);
345
346         if (!netr_creds_server_step_check(pipe_state, &r->in.credential, &r->out.return_authenticator)) {
347                 return NT_STATUS_ACCESS_DENIED;
348         }
349
350         if (!pipe_state) {
351                 DEBUG(1, ("No challange requested by client, cannot authenticate\n"));
352                 return NT_STATUS_ACCESS_DENIED;
353         }
354
355         sam_ctx = samdb_connect();
356         if (sam_ctx == NULL) {
357                 return NT_STATUS_INVALID_SYSTEM_SERVICE;
358         }
359         /* pull the user attributes */
360         num_records = samdb_search(sam_ctx, mem_ctx, NULL, &msgs, attrs,
361                                    "(&(sAMAccountName=%s)(objectclass=user))", 
362                                    pipe_state->account_name);
363
364         if (num_records == 0) {
365                 DEBUG(3,("Couldn't find user [%s] in samdb.\n", 
366                          pipe_state->account_name));
367                 samdb_close(sam_ctx);
368                 return NT_STATUS_NO_SUCH_USER;
369         }
370
371         if (num_records > 1) {
372                 DEBUG(1,("Found %d records matching user [%s]\n", num_records, 
373                          pipe_state->account_name));
374                 samdb_close(sam_ctx);
375                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
376         }
377
378         domain_sid = samdb_result_sid_prefix(mem_ctx, msgs[0], "objectSid");
379         if (!domain_sid) {
380                 samdb_close(sam_ctx);
381                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
382         }
383
384         /* find the domain's DN */
385         num_records_domain = samdb_search(sam_ctx, mem_ctx, NULL, 
386                                           &msgs_domain, domain_attrs,
387                                           "(&(objectSid=%s)(objectclass=domain))", 
388                                           domain_sid);
389
390         if (num_records_domain == 0) {
391                 DEBUG(3,("check_sam_security: Couldn't find domain [%s] in passdb file.\n", 
392                          domain_sid));
393                 samdb_close(sam_ctx);
394                 return NT_STATUS_NO_SUCH_USER;
395         }
396
397         if (num_records_domain > 1) {
398                 DEBUG(1,("Found %d records matching domain [%s]\n", 
399                          num_records_domain, domain_sid));
400                 samdb_close(sam_ctx);
401                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
402         }
403
404         domain_dn = msgs_domain[0]->dn;
405         
406         mod.dn = talloc_strdup(mem_ctx, msgs[0]->dn);
407         if (!mod.dn) {
408                 samdb_close(sam_ctx);
409                 return NT_STATUS_NO_MEMORY;
410         }
411         
412         creds_des_decrypt(pipe_state->creds, &r->in.new_password);
413
414         memcpy(newNtHash.hash, r->in.new_password.data, sizeof(newNtHash.hash));
415
416         /* set the password - samdb needs to know both the domain and user DNs,
417            so the domain password policy can be used */
418         nt_status = samdb_set_password(sam_ctx, mem_ctx,
419                                        msgs[0]->dn, domain_dn,
420                                        msg_set_pw, 
421                                        NULL, /* Don't have plaintext */
422                                        NULL, &newNtHash,
423                                        False /* This is not considered a password change */,
424                                        NULL);
425         
426         if (!NT_STATUS_IS_OK(nt_status)) {
427                 samdb_close(sam_ctx);
428                 return nt_status;
429         }
430
431         ret = samdb_replace(sam_ctx, mem_ctx, msg_set_pw);
432         if (ret != 0) {
433                 /* we really need samdb.c to return NTSTATUS */
434
435                 samdb_close(sam_ctx);
436                 return NT_STATUS_UNSUCCESSFUL;
437         }
438
439         samdb_close(sam_ctx);
440         return NT_STATUS_OK;
441 }
442
443
444 /* 
445   netr_LogonUasLogon 
446 */
447 static WERROR netr_LogonUasLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
448                                  struct netr_LogonUasLogon *r)
449 {
450         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
451 }
452
453
454 /* 
455   netr_LogonUasLogoff 
456 */
457 static WERROR netr_LogonUasLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
458                        struct netr_LogonUasLogoff *r)
459 {
460         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
461 }
462
463
464 /* 
465   netr_LogonSamLogon 
466
467
468
469 */
470 static NTSTATUS netr_LogonSamLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
471                        struct netr_LogonSamLogon *r)
472 {
473         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
474 }
475
476
477 /* 
478   netr_LogonSamLogoff 
479 */
480 static NTSTATUS netr_LogonSamLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
481                        struct netr_LogonSamLogoff *r)
482 {
483         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
484 }
485
486
487
488 /* 
489   netr_DatabaseDeltas 
490 */
491 static NTSTATUS netr_DatabaseDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
492                        struct netr_DatabaseDeltas *r)
493 {
494         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
495 }
496
497
498 /* 
499   netr_DatabaseSync 
500 */
501 static NTSTATUS netr_DatabaseSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
502                        struct netr_DatabaseSync *r)
503 {
504         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
505 }
506
507
508 /* 
509   netr_AccountDeltas 
510 */
511 static NTSTATUS netr_AccountDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
512                        struct netr_AccountDeltas *r)
513 {
514         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
515 }
516
517
518 /* 
519   netr_AccountSync 
520 */
521 static NTSTATUS netr_AccountSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
522                        struct netr_AccountSync *r)
523 {
524         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
525 }
526
527
528 /* 
529   netr_GetDcName 
530 */
531 static NTSTATUS netr_GetDcName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
532                        struct netr_GetDcName *r)
533 {
534         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
535 }
536
537
538 /* 
539   netr_LogonControl 
540 */
541 static WERROR netr_LogonControl(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
542                        struct netr_LogonControl *r)
543 {
544         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
545 }
546
547
548 /* 
549   netr_GetAnyDCName 
550 */
551 static WERROR netr_GetAnyDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
552                        struct netr_GetAnyDCName *r)
553 {
554         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
555 }
556
557
558 /* 
559   netr_LogonControl2 
560 */
561 static WERROR netr_LogonControl2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
562                        struct netr_LogonControl2 *r)
563 {
564         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
565 }
566
567
568 /* 
569   netr_DatabaseSync2 
570 */
571 static NTSTATUS netr_DatabaseSync2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
572                        struct netr_DatabaseSync2 *r)
573 {
574         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
575 }
576
577
578 /* 
579   netr_DatabaseRedo 
580 */
581 static NTSTATUS netr_DatabaseRedo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
582                        struct netr_DatabaseRedo *r)
583 {
584         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
585 }
586
587
588 /* 
589   netr_LogonControl2Ex 
590 */
591 static WERROR netr_LogonControl2Ex(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
592                        struct netr_LogonControl2Ex *r)
593 {
594         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
595 }
596
597
598 /* 
599   netr_NETRENUMERATETRUSTEDDOMAINS 
600 */
601 static WERROR netr_NETRENUMERATETRUSTEDDOMAINS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
602                        struct netr_NETRENUMERATETRUSTEDDOMAINS *r)
603 {
604         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
605 }
606
607
608 /* 
609   netr_DSRGETDCNAME 
610 */
611 static WERROR netr_DSRGETDCNAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
612                        struct netr_DSRGETDCNAME *r)
613 {
614         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
615 }
616
617
618 /* 
619   netr_NETRLOGONDUMMYROUTINE1 
620 */
621 static WERROR netr_NETRLOGONDUMMYROUTINE1(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
622                        struct netr_NETRLOGONDUMMYROUTINE1 *r)
623 {
624         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
625 }
626
627
628 /* 
629   netr_NETRLOGONSETSERVICEBITS 
630 */
631 static WERROR netr_NETRLOGONSETSERVICEBITS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
632                        struct netr_NETRLOGONSETSERVICEBITS *r)
633 {
634         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
635 }
636
637
638 /* 
639   netr_NETRLOGONGETTRUSTRID 
640 */
641 static WERROR netr_NETRLOGONGETTRUSTRID(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
642                        struct netr_NETRLOGONGETTRUSTRID *r)
643 {
644         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
645 }
646
647
648 /* 
649   netr_NETRLOGONCOMPUTESERVERDIGEST 
650 */
651 static WERROR netr_NETRLOGONCOMPUTESERVERDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
652                        struct netr_NETRLOGONCOMPUTESERVERDIGEST *r)
653 {
654         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
655 }
656
657
658 /* 
659   netr_NETRLOGONCOMPUTECLIENTDIGEST 
660 */
661 static WERROR netr_NETRLOGONCOMPUTECLIENTDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
662                        struct netr_NETRLOGONCOMPUTECLIENTDIGEST *r)
663 {
664         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
665 }
666
667
668 /* 
669   netr_DSRGETDCNAMEX 
670 */
671 static WERROR netr_DSRGETDCNAMEX(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
672                        struct netr_DSRGETDCNAMEX *r)
673 {
674         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
675 }
676
677
678 /* 
679   netr_DSRGETSITENAME 
680 */
681 static WERROR netr_DSRGETSITENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
682                        struct netr_DSRGETSITENAME *r)
683 {
684         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
685 }
686
687
688 /* 
689   netr_NETRLOGONGETDOMAININFO 
690 */
691 static WERROR netr_NETRLOGONGETDOMAININFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
692                        struct netr_NETRLOGONGETDOMAININFO *r)
693 {
694         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
695 }
696
697
698 /* 
699   netr_NETRSERVERPASSWORDSET2 
700 */
701 static WERROR netr_NETRSERVERPASSWORDSET2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
702                        struct netr_NETRSERVERPASSWORDSET2 *r)
703 {
704         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
705 }
706
707
708 /* 
709   netr_NETRSERVERPASSWORDGET 
710 */
711 static WERROR netr_NETRSERVERPASSWORDGET(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
712                        struct netr_NETRSERVERPASSWORDGET *r)
713 {
714         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
715 }
716
717
718 /* 
719   netr_NETRLOGONSENDTOSAM 
720 */
721 static WERROR netr_NETRLOGONSENDTOSAM(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
722                        struct netr_NETRLOGONSENDTOSAM *r)
723 {
724         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
725 }
726
727
728 /* 
729   netr_DSRADDRESSTOSITENAMESW 
730 */
731 static WERROR netr_DSRADDRESSTOSITENAMESW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
732                        struct netr_DSRADDRESSTOSITENAMESW *r)
733 {
734         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
735 }
736
737
738 /* 
739   netr_DSRGETDCNAMEEX2 
740 */
741 static WERROR netr_DSRGETDCNAMEEX2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
742                        struct netr_DSRGETDCNAMEEX2 *r)
743 {
744         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
745 }
746
747
748 /* 
749   netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN 
750 */
751 static WERROR netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
752                        struct netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN *r)
753 {
754         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
755 }
756
757
758 /* 
759   netr_NETRENUMERATETRUSTEDDOMAINSEX 
760 */
761 static WERROR netr_NETRENUMERATETRUSTEDDOMAINSEX(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
762                        struct netr_NETRENUMERATETRUSTEDDOMAINSEX *r)
763 {
764         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
765 }
766
767
768 /* 
769   netr_DSRADDRESSTOSITENAMESEXW 
770 */
771 static WERROR netr_DSRADDRESSTOSITENAMESEXW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
772                        struct netr_DSRADDRESSTOSITENAMESEXW *r)
773 {
774         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
775 }
776
777
778 /* 
779   netr_DSRGETDCSITECOVERAGEW 
780 */
781 static WERROR netr_DSRGETDCSITECOVERAGEW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
782                        struct netr_DSRGETDCSITECOVERAGEW *r)
783 {
784         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
785 }
786
787
788 /* 
789   netr_NETRLOGONSAMLOGONEX 
790 */
791 static WERROR netr_NETRLOGONSAMLOGONEX(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
792                        struct netr_NETRLOGONSAMLOGONEX *r)
793 {
794         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
795 }
796
797
798 /* 
799   netr_DsrEnumerateDomainTrusts 
800 */
801 static WERROR netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
802                                               struct netr_DsrEnumerateDomainTrusts *r)
803 {
804         struct netr_DomainTrust *trusts;
805         void *sam_ctx;
806         int ret, i;
807         struct ldb_message **res;
808         const char * const attrs[] = { "name", "dnsDomain", "objectSid", "objectGUID", NULL };
809
810         ZERO_STRUCT(r->out);
811
812         sam_ctx = samdb_connect();
813         if (sam_ctx == NULL) {
814                 return WERR_GENERAL_FAILURE;
815         }
816
817         ret = samdb_search(sam_ctx, mem_ctx, NULL, &res, attrs, "(objectClass=domainDNS)");
818         if (ret == -1) {
819                 samdb_close(sam_ctx);
820                 return WERR_GENERAL_FAILURE;            
821         }
822
823         if (ret == 0) {
824                 return WERR_OK;
825         }
826
827         trusts = talloc_array_p(mem_ctx, struct netr_DomainTrust, ret);
828         if (trusts == NULL) {
829                 return WERR_NOMEM;
830         }
831         
832         r->out.count = ret;
833         r->out.trusts = trusts;
834
835         /* TODO: add filtering by trust_flags, and correct trust_type
836            and attributes */
837         for (i=0;i<ret;i++) {
838                 trusts[i].netbios_name = samdb_result_string(res[i], "name", NULL);
839                 trusts[i].dns_name     = samdb_result_string(res[i], "dnsDomain", NULL);
840                 trusts[i].trust_flags = 
841                         NETR_TRUST_FLAG_TREEROOT | 
842                         NETR_TRUST_FLAG_IN_FOREST | 
843                         NETR_TRUST_FLAG_PRIMARY;
844                 trusts[i].parent_index = 0;
845                 trusts[i].trust_type = 2;
846                 trusts[i].trust_attributes = 0;
847                 trusts[i].sid  = samdb_result_dom_sid(mem_ctx, res[i], "objectSid");
848                 trusts[i].guid = samdb_result_guid(res[i], "objectGUID");
849         }
850         
851
852         return WERR_OK;
853 }
854
855
856 /* 
857   netr_DSRDEREGISTERDNSHOSTRECORDS 
858 */
859 static WERROR netr_DSRDEREGISTERDNSHOSTRECORDS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
860                        struct netr_DSRDEREGISTERDNSHOSTRECORDS *r)
861 {
862         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
863 }
864
865
866 /* 
867   netr_NETRSERVERTRUSTPASSWORDSGET 
868 */
869 static WERROR netr_NETRSERVERTRUSTPASSWORDSGET(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
870                        struct netr_NETRSERVERTRUSTPASSWORDSGET *r)
871 {
872         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
873 }
874
875
876 /* 
877   netr_DSRGETFORESTTRUSTINFORMATION 
878 */
879 static WERROR netr_DSRGETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
880                        struct netr_DSRGETFORESTTRUSTINFORMATION *r)
881 {
882         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
883 }
884
885
886 /* 
887   netr_NETRGETFORESTTRUSTINFORMATION 
888 */
889 static WERROR netr_NETRGETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
890                        struct netr_NETRGETFORESTTRUSTINFORMATION *r)
891 {
892         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
893 }
894
895
896 /* 
897   netr_NETRLOGONSAMLOGONWITHFLAGS 
898 */
899 static WERROR netr_NETRLOGONSAMLOGONWITHFLAGS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
900                        struct netr_NETRLOGONSAMLOGONWITHFLAGS *r)
901 {
902         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
903 }
904
905
906 /* 
907   netr_NETRSERVERGETTRUSTINFO 
908 */
909 static WERROR netr_NETRSERVERGETTRUSTINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
910                        struct netr_NETRSERVERGETTRUSTINFO *r)
911 {
912         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
913 }
914
915
916 /* include the generated boilerplate */
917 #include "librpc/gen_ndr/ndr_netlogon_s.c"