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