s4-ldbwrap: added re-use of ldb contexts in ldb_wrap_connect()
[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-2008
7    Copyright (C) Stefan Metzmacher <metze@samba.org>  2005
8    Copyright (C) Matthias Dieter Wallnöfer            2009
9    
10    This program is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 3 of the License, or
13    (at your option) any later version.
14    
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19    
20    You should have received a copy of the GNU General Public License
21    along with this program.  If not, see <http://www.gnu.org/licenses/>.
22 */
23
24 #include "includes.h"
25 #include "rpc_server/dcerpc_server.h"
26 #include "auth/auth.h"
27 #include "auth/auth_sam_reply.h"
28 #include "dsdb/samdb/samdb.h"
29 #include "../lib/util/util_ldb.h"
30 #include "../libcli/auth/schannel.h"
31 #include "auth/gensec/schannel_state.h"
32 #include "libcli/security/security.h"
33 #include "param/param.h"
34 #include "lib/messaging/irpc.h"
35 #include "librpc/gen_ndr/ndr_irpc.h"
36
37 struct netlogon_server_pipe_state {
38         struct netr_Credential client_challenge;
39         struct netr_Credential server_challenge;
40 };
41
42
43 static NTSTATUS dcesrv_netr_ServerReqChallenge(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
44                                         struct netr_ServerReqChallenge *r)
45 {
46         struct netlogon_server_pipe_state *pipe_state =
47                 talloc_get_type(dce_call->context->private_data, struct netlogon_server_pipe_state);
48
49         ZERO_STRUCTP(r->out.return_credentials);
50
51         /* destroyed on pipe shutdown */
52
53         if (pipe_state) {
54                 talloc_free(pipe_state);
55                 dce_call->context->private_data = NULL;
56         }
57         
58         pipe_state = talloc(dce_call->context, struct netlogon_server_pipe_state);
59         NT_STATUS_HAVE_NO_MEMORY(pipe_state);
60
61         pipe_state->client_challenge = *r->in.credentials;
62
63         generate_random_buffer(pipe_state->server_challenge.data, 
64                                sizeof(pipe_state->server_challenge.data));
65
66         *r->out.return_credentials = pipe_state->server_challenge;
67
68         dce_call->context->private_data = pipe_state;
69
70         return NT_STATUS_OK;
71 }
72
73 static NTSTATUS dcesrv_netr_ServerAuthenticate3(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
74                                          struct netr_ServerAuthenticate3 *r)
75 {
76         struct netlogon_server_pipe_state *pipe_state =
77                 talloc_get_type(dce_call->context->private_data, struct netlogon_server_pipe_state);
78         struct netlogon_creds_CredentialState *creds;
79         struct ldb_context *schannel_ldb;
80         struct ldb_context *sam_ctx;
81         struct samr_Password *mach_pwd;
82         uint32_t user_account_control;
83         int num_records;
84         struct ldb_message **msgs;
85         NTSTATUS nt_status;
86         const char *attrs[] = {"unicodePwd", "userAccountControl", 
87                                "objectSid", NULL};
88
89         const char *trust_dom_attrs[] = {"flatname", NULL};
90         const char *account_name;
91
92         ZERO_STRUCTP(r->out.return_credentials);
93         *r->out.rid = 0;
94
95         /*
96          * According to Microsoft (see bugid #6099)
97          * Windows 7 looks at the negotiate_flags
98          * returned in this structure *even if the
99          * call fails with access denied!
100          */
101         *r->out.negotiate_flags = NETLOGON_NEG_ACCOUNT_LOCKOUT |
102                                   NETLOGON_NEG_PERSISTENT_SAMREPL |
103                                   NETLOGON_NEG_ARCFOUR |
104                                   NETLOGON_NEG_PROMOTION_COUNT |
105                                   NETLOGON_NEG_CHANGELOG_BDC |
106                                   NETLOGON_NEG_FULL_SYNC_REPL |
107                                   NETLOGON_NEG_MULTIPLE_SIDS |
108                                   NETLOGON_NEG_REDO |
109                                   NETLOGON_NEG_PASSWORD_CHANGE_REFUSAL |
110                                   NETLOGON_NEG_SEND_PASSWORD_INFO_PDC |
111                                   NETLOGON_NEG_GENERIC_PASSTHROUGH |
112                                   NETLOGON_NEG_CONCURRENT_RPC |
113                                   NETLOGON_NEG_AVOID_ACCOUNT_DB_REPL |
114                                   NETLOGON_NEG_AVOID_SECURITYAUTH_DB_REPL |
115                                   NETLOGON_NEG_STRONG_KEYS |
116                                   NETLOGON_NEG_TRANSITIVE_TRUSTS |
117                                   NETLOGON_NEG_DNS_DOMAIN_TRUSTS |
118                                   NETLOGON_NEG_PASSWORD_SET2 |
119                                   NETLOGON_NEG_GETDOMAININFO |
120                                   NETLOGON_NEG_CROSS_FOREST_TRUSTS |
121                                   NETLOGON_NEG_NEUTRALIZE_NT4_EMULATION |
122                                   NETLOGON_NEG_RODC_PASSTHROUGH |
123                                   NETLOGON_NEG_AUTHENTICATED_RPC_LSASS |
124                                   NETLOGON_NEG_AUTHENTICATED_RPC;
125
126         if (!pipe_state) {
127                 DEBUG(1, ("No challenge requested by client, cannot authenticate\n"));
128                 return NT_STATUS_ACCESS_DENIED;
129         }
130
131         sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, 
132                                 system_session(dce_call->conn->dce_ctx->lp_ctx));
133         if (sam_ctx == NULL) {
134                 return NT_STATUS_INVALID_SYSTEM_SERVICE;
135         }
136
137         if (r->in.secure_channel_type == SEC_CHAN_DNS_DOMAIN) {
138                 char *encoded_account = ldb_binary_encode_string(mem_ctx, r->in.account_name);
139                 const char *flatname;
140                 if (!encoded_account) {
141                         return NT_STATUS_NO_MEMORY;
142                 }
143
144                 /* Kill the trailing dot */
145                 if (encoded_account[strlen(encoded_account)-1] == '.') {
146                         encoded_account[strlen(encoded_account)-1] = '\0';
147                 }
148
149                 /* pull the user attributes */
150                 num_records = gendb_search(sam_ctx, mem_ctx, NULL, &msgs,
151                                            trust_dom_attrs,
152                                            "(&(trustPartner=%s)(objectclass=trustedDomain))", 
153                                            encoded_account);
154                 
155                 if (num_records == 0) {
156                         DEBUG(3,("Couldn't find trust [%s] in samdb.\n", 
157                                  encoded_account));
158                         return NT_STATUS_ACCESS_DENIED;
159                 }
160                 
161                 if (num_records > 1) {
162                         DEBUG(0,("Found %d records matching user [%s]\n", num_records, r->in.account_name));
163                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
164                 }
165                 
166                 flatname = ldb_msg_find_attr_as_string(msgs[0], "flatname", NULL);
167                 if (!flatname) {
168                         /* No flatname for this trust - we can't proceed */
169                         return NT_STATUS_ACCESS_DENIED;
170                 }
171                 account_name = talloc_asprintf(mem_ctx, "%s$", flatname);
172
173                 if (!account_name) {
174                         return NT_STATUS_NO_MEMORY;
175                 }
176                 
177         } else {
178                 account_name = r->in.account_name;
179         }
180         
181         /* pull the user attributes */
182         num_records = gendb_search(sam_ctx, mem_ctx, NULL, &msgs, attrs,
183                                    "(&(sAMAccountName=%s)(objectclass=user))", 
184                                    ldb_binary_encode_string(mem_ctx, account_name));
185
186         if (num_records == 0) {
187                 DEBUG(3,("Couldn't find user [%s] in samdb.\n", 
188                          r->in.account_name));
189                 return NT_STATUS_ACCESS_DENIED;
190         }
191
192         if (num_records > 1) {
193                 DEBUG(0,("Found %d records matching user [%s]\n", num_records, r->in.account_name));
194                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
195         }
196
197         
198         user_account_control = ldb_msg_find_attr_as_uint(msgs[0], "userAccountControl", 0);
199
200         if (user_account_control & UF_ACCOUNTDISABLE) {
201                 DEBUG(1, ("Account [%s] is disabled\n", r->in.account_name));
202                 return NT_STATUS_ACCESS_DENIED;
203         }
204
205         if (r->in.secure_channel_type == SEC_CHAN_WKSTA) {
206                 if (!(user_account_control & UF_WORKSTATION_TRUST_ACCOUNT)) {
207                         DEBUG(1, ("Client asked for a workstation secure channel, but is not a workstation (member server) acb flags: 0x%x\n", user_account_control));
208                         return NT_STATUS_ACCESS_DENIED;
209                 }
210         } else if (r->in.secure_channel_type == SEC_CHAN_DOMAIN || 
211                    r->in.secure_channel_type == SEC_CHAN_DNS_DOMAIN) {
212                 if (!(user_account_control & UF_INTERDOMAIN_TRUST_ACCOUNT)) {
213                         DEBUG(1, ("Client asked for a trusted domain secure channel, but is not a trusted domain: acb flags: 0x%x\n", user_account_control));
214                         
215                         return NT_STATUS_ACCESS_DENIED;
216                 }
217         } else if (r->in.secure_channel_type == SEC_CHAN_BDC) {
218                 if (!(user_account_control & UF_SERVER_TRUST_ACCOUNT)) {
219                         DEBUG(1, ("Client asked for a server secure channel, but is not a server (domain controller): acb flags: 0x%x\n", user_account_control));
220                         return NT_STATUS_ACCESS_DENIED;
221                 }
222         } else {
223                 DEBUG(1, ("Client asked for an invalid secure channel type: %d\n", 
224                           r->in.secure_channel_type));
225                 return NT_STATUS_ACCESS_DENIED;
226         }
227
228         *r->out.rid = samdb_result_rid_from_sid(mem_ctx, msgs[0], 
229                                                 "objectSid", 0);
230
231         mach_pwd = samdb_result_hash(mem_ctx, msgs[0], "unicodePwd");
232         if (mach_pwd == NULL) {
233                 return NT_STATUS_ACCESS_DENIED;
234         }
235
236         creds = netlogon_creds_server_init(mem_ctx,     
237                                            r->in.account_name,
238                                            r->in.computer_name,
239                                            r->in.secure_channel_type,
240                                            &pipe_state->client_challenge, 
241                                            &pipe_state->server_challenge, 
242                                            mach_pwd,
243                                            r->in.credentials,
244                                            r->out.return_credentials,
245                                            *r->in.negotiate_flags);
246         
247         if (!creds) {
248                 return NT_STATUS_ACCESS_DENIED;
249         }
250
251         creds->sid = samdb_result_dom_sid(creds, msgs[0], "objectSid");
252
253         schannel_ldb = schannel_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx);
254         if (!schannel_ldb) {
255                 return NT_STATUS_ACCESS_DENIED;
256         }
257
258         nt_status = schannel_store_session_key_ldb(schannel_ldb, mem_ctx, creds);
259         talloc_unlink(mem_ctx, schannel_ldb);
260
261         return nt_status;
262 }
263                                                  
264 static NTSTATUS dcesrv_netr_ServerAuthenticate(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
265                                         struct netr_ServerAuthenticate *r)
266 {
267         struct netr_ServerAuthenticate3 a;
268         uint32_t rid;
269         /* TODO: 
270          * negotiate_flags is used as an [in] parameter
271          * so it need to be initialised.
272          *
273          * (I think ... = 0; seems wrong here --metze)
274          */
275         uint32_t negotiate_flags_in = 0;
276         uint32_t negotiate_flags_out = 0;
277
278         a.in.server_name                = r->in.server_name;
279         a.in.account_name               = r->in.account_name;
280         a.in.secure_channel_type        = r->in.secure_channel_type;
281         a.in.computer_name              = r->in.computer_name;
282         a.in.credentials                = r->in.credentials;
283         a.in.negotiate_flags            = &negotiate_flags_in;
284
285         a.out.return_credentials        = r->out.return_credentials;
286         a.out.rid                       = &rid;
287         a.out.negotiate_flags           = &negotiate_flags_out;
288
289         return dcesrv_netr_ServerAuthenticate3(dce_call, mem_ctx, &a);
290 }
291
292 static NTSTATUS dcesrv_netr_ServerAuthenticate2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
293                                          struct netr_ServerAuthenticate2 *r)
294 {
295         struct netr_ServerAuthenticate3 r3;
296         uint32_t rid = 0;
297
298         r3.in.server_name = r->in.server_name;
299         r3.in.account_name = r->in.account_name;
300         r3.in.secure_channel_type = r->in.secure_channel_type;
301         r3.in.computer_name = r->in.computer_name;
302         r3.in.credentials = r->in.credentials;
303         r3.out.return_credentials = r->out.return_credentials;
304         r3.in.negotiate_flags = r->in.negotiate_flags;
305         r3.out.negotiate_flags = r->out.negotiate_flags;
306         r3.out.rid = &rid;
307         
308         return dcesrv_netr_ServerAuthenticate3(dce_call, mem_ctx, &r3);
309 }
310
311 /*
312   Validate an incoming authenticator against the credentials for the remote machine.
313
314   The credentials are (re)read and from the schannel database, and
315   written back after the caclulations are performed.
316
317   The creds_out parameter (if not NULL) returns the credentials, if
318   the caller needs some of that information.
319
320 */
321 static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dce_call,
322                                                     TALLOC_CTX *mem_ctx, 
323                                                     const char *computer_name,
324                                                     struct netr_Authenticator *received_authenticator,
325                                                     struct netr_Authenticator *return_authenticator,
326                                                     struct netlogon_creds_CredentialState **creds_out) 
327 {
328         NTSTATUS nt_status;
329         struct ldb_context *ldb;
330         bool schannel_global_required = false; /* Should be lp_schannel_server() == true */
331         bool schannel_in_use = dce_call->conn->auth_state.auth_info
332                 && dce_call->conn->auth_state.auth_info->auth_type == DCERPC_AUTH_TYPE_SCHANNEL
333                 && (dce_call->conn->auth_state.auth_info->auth_level == DCERPC_AUTH_LEVEL_INTEGRITY 
334                     || dce_call->conn->auth_state.auth_info->auth_level == DCERPC_AUTH_LEVEL_PRIVACY);
335
336         ldb = schannel_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx);
337         if (!ldb) {
338                 return NT_STATUS_ACCESS_DENIED;
339         }
340         nt_status = schannel_creds_server_step_check_ldb(ldb, mem_ctx,
341                                                          computer_name,
342                                                          schannel_global_required,
343                                                          schannel_in_use,
344                                                          received_authenticator,
345                                                          return_authenticator, creds_out);
346         talloc_unlink(mem_ctx, ldb);
347         return nt_status;
348 }
349
350 /* 
351   Change the machine account password for the currently connected
352   client.  Supplies only the NT#.
353 */
354
355 static NTSTATUS dcesrv_netr_ServerPasswordSet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
356                                        struct netr_ServerPasswordSet *r)
357 {
358         struct netlogon_creds_CredentialState *creds;
359         struct ldb_context *sam_ctx;
360         NTSTATUS nt_status;
361
362         nt_status = dcesrv_netr_creds_server_step_check(dce_call,
363                                                         mem_ctx, 
364                                                         r->in.computer_name, 
365                                                         r->in.credential, r->out.return_authenticator,
366                                                         &creds);
367         NT_STATUS_NOT_OK_RETURN(nt_status);
368
369         sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(dce_call->conn->dce_ctx->lp_ctx));
370         if (sam_ctx == NULL) {
371                 return NT_STATUS_INVALID_SYSTEM_SERVICE;
372         }
373
374         netlogon_creds_des_decrypt(creds, r->in.new_password);
375
376         /* Using the sid for the account as the key, set the password */
377         nt_status = samdb_set_password_sid(sam_ctx, mem_ctx, 
378                                            creds->sid,
379                                            NULL, /* Don't have plaintext */
380                                            NULL, r->in.new_password,
381                                            true, /* Password change */
382                                            NULL, NULL);
383         return nt_status;
384 }
385
386 /* 
387   Change the machine account password for the currently connected
388   client.  Supplies new plaintext.
389 */
390 static NTSTATUS dcesrv_netr_ServerPasswordSet2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
391                                        struct netr_ServerPasswordSet2 *r)
392 {
393         struct netlogon_creds_CredentialState *creds;
394         struct ldb_context *sam_ctx;
395         NTSTATUS nt_status;
396         DATA_BLOB new_password;
397
398         struct samr_CryptPassword password_buf;
399
400         nt_status = dcesrv_netr_creds_server_step_check(dce_call,
401                                                         mem_ctx, 
402                                                         r->in.computer_name, 
403                                                         r->in.credential, r->out.return_authenticator,
404                                                         &creds);
405         NT_STATUS_NOT_OK_RETURN(nt_status);
406
407         sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(dce_call->conn->dce_ctx->lp_ctx));
408         if (sam_ctx == NULL) {
409                 return NT_STATUS_INVALID_SYSTEM_SERVICE;
410         }
411
412         memcpy(password_buf.data, r->in.new_password->data, 512);
413         SIVAL(password_buf.data, 512, r->in.new_password->length);
414         netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
415
416         if (!extract_pw_from_buffer(mem_ctx, password_buf.data, &new_password)) {
417                 DEBUG(3,("samr: failed to decode password buffer\n"));
418                 return NT_STATUS_WRONG_PASSWORD;
419         }
420                 
421         /* Using the sid for the account as the key, set the password */
422         nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
423                                            creds->sid,
424                                            &new_password, /* we have plaintext */
425                                            NULL, NULL,
426                                            true, /* Password change */
427                                            NULL, NULL);
428         return nt_status;
429 }
430
431
432 /* 
433   netr_LogonUasLogon 
434 */
435 static WERROR dcesrv_netr_LogonUasLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
436                                  struct netr_LogonUasLogon *r)
437 {
438         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
439 }
440
441
442 /* 
443   netr_LogonUasLogoff 
444 */
445 static WERROR dcesrv_netr_LogonUasLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
446                        struct netr_LogonUasLogoff *r)
447 {
448         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
449 }
450
451
452 /* 
453   netr_LogonSamLogon_base
454
455   This version of the function allows other wrappers to say 'do not check the credentials'
456
457   We can't do the traditional 'wrapping' format completly, as this function must only run under schannel
458 */
459 static NTSTATUS dcesrv_netr_LogonSamLogon_base(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
460                                         struct netr_LogonSamLogonEx *r, struct netlogon_creds_CredentialState *creds)
461 {
462         struct auth_context *auth_context;
463         struct auth_usersupplied_info *user_info;
464         struct auth_serversupplied_info *server_info;
465         NTSTATUS nt_status;
466         static const char zeros[16];
467         struct netr_SamBaseInfo *sam;
468         struct netr_SamInfo2 *sam2;
469         struct netr_SamInfo3 *sam3;
470         struct netr_SamInfo6 *sam6;
471         
472         user_info = talloc(mem_ctx, struct auth_usersupplied_info);
473         NT_STATUS_HAVE_NO_MEMORY(user_info);
474
475         user_info->flags = 0;
476         user_info->mapped_state = false;
477         user_info->remote_host = NULL;
478
479         switch (r->in.logon_level) {
480         case NetlogonInteractiveInformation:
481         case NetlogonServiceInformation:
482         case NetlogonInteractiveTransitiveInformation:
483         case NetlogonServiceTransitiveInformation:
484                 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
485                         netlogon_creds_arcfour_crypt(creds, 
486                                             r->in.logon->password->lmpassword.hash,
487                                             sizeof(r->in.logon->password->lmpassword.hash));
488                         netlogon_creds_arcfour_crypt(creds, 
489                                             r->in.logon->password->ntpassword.hash,
490                                             sizeof(r->in.logon->password->ntpassword.hash));
491                 } else {
492                         netlogon_creds_des_decrypt(creds, &r->in.logon->password->lmpassword);
493                         netlogon_creds_des_decrypt(creds, &r->in.logon->password->ntpassword);
494                 }
495
496                 /* TODO: we need to deny anonymous access here */
497                 nt_status = auth_context_create(mem_ctx, 
498                                                 dce_call->event_ctx, dce_call->msg_ctx,
499                                                 dce_call->conn->dce_ctx->lp_ctx,
500                                                 &auth_context);
501                 NT_STATUS_NOT_OK_RETURN(nt_status);
502
503                 user_info->logon_parameters = r->in.logon->password->identity_info.parameter_control;
504                 user_info->client.account_name = r->in.logon->password->identity_info.account_name.string;
505                 user_info->client.domain_name = r->in.logon->password->identity_info.domain_name.string;
506                 user_info->workstation_name = r->in.logon->password->identity_info.workstation.string;
507                 
508                 user_info->flags |= USER_INFO_INTERACTIVE_LOGON;
509                 user_info->password_state = AUTH_PASSWORD_HASH;
510
511                 user_info->password.hash.lanman = talloc(user_info, struct samr_Password);
512                 NT_STATUS_HAVE_NO_MEMORY(user_info->password.hash.lanman);
513                 *user_info->password.hash.lanman = r->in.logon->password->lmpassword;
514
515                 user_info->password.hash.nt = talloc(user_info, struct samr_Password);
516                 NT_STATUS_HAVE_NO_MEMORY(user_info->password.hash.nt);
517                 *user_info->password.hash.nt = r->in.logon->password->ntpassword;
518
519                 break;
520         case NetlogonNetworkInformation:
521         case NetlogonNetworkTransitiveInformation:
522
523                 /* TODO: we need to deny anonymous access here */
524                 nt_status = auth_context_create(mem_ctx, 
525                                                 dce_call->event_ctx, dce_call->msg_ctx,
526                                                 dce_call->conn->dce_ctx->lp_ctx,
527                                                 &auth_context);
528                 NT_STATUS_NOT_OK_RETURN(nt_status);
529
530                 nt_status = auth_context_set_challenge(auth_context, r->in.logon->network->challenge, "netr_LogonSamLogonWithFlags");
531                 NT_STATUS_NOT_OK_RETURN(nt_status);
532
533                 user_info->logon_parameters = r->in.logon->network->identity_info.parameter_control;
534                 user_info->client.account_name = r->in.logon->network->identity_info.account_name.string;
535                 user_info->client.domain_name = r->in.logon->network->identity_info.domain_name.string;
536                 user_info->workstation_name = r->in.logon->network->identity_info.workstation.string;
537                 
538                 user_info->password_state = AUTH_PASSWORD_RESPONSE;
539                 user_info->password.response.lanman = data_blob_talloc(mem_ctx, r->in.logon->network->lm.data, r->in.logon->network->lm.length);
540                 user_info->password.response.nt = data_blob_talloc(mem_ctx, r->in.logon->network->nt.data, r->in.logon->network->nt.length);
541         
542                 break;
543
544                 
545         case NetlogonGenericInformation:
546         {
547                 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
548                         netlogon_creds_arcfour_crypt(creds, 
549                                             r->in.logon->generic->data, r->in.logon->generic->length);
550                 } else {
551                         /* Using DES to verify kerberos tickets makes no sense */
552                         return NT_STATUS_INVALID_PARAMETER;
553                 }
554
555                 if (strcmp(r->in.logon->generic->package_name.string, "Kerberos") == 0) {
556                         NTSTATUS status;
557                         struct server_id *kdc;
558                         struct kdc_check_generic_kerberos check;
559                         struct netr_GenericInfo2 *generic = talloc_zero(mem_ctx, struct netr_GenericInfo2);
560                         NT_STATUS_HAVE_NO_MEMORY(generic);
561                         *r->out.authoritative = 1;
562                         
563                         /* TODO: Describe and deal with these flags */
564                         *r->out.flags = 0;
565
566                         r->out.validation->generic = generic;
567         
568                         kdc = irpc_servers_byname(dce_call->msg_ctx, mem_ctx, "kdc_server");
569                         if ((kdc == NULL) || (kdc[0].id == 0)) {
570                                 return NT_STATUS_NO_LOGON_SERVERS;
571                         }
572                         
573                         check.in.generic_request = 
574                                 data_blob_const(r->in.logon->generic->data,
575                                                 r->in.logon->generic->length);
576                         
577                         status = irpc_call(dce_call->msg_ctx, kdc[0],
578                                            &ndr_table_irpc, NDR_KDC_CHECK_GENERIC_KERBEROS,
579                                            &check, mem_ctx);
580                         if (!NT_STATUS_IS_OK(status)) {
581                                 return status;
582                         }
583                         generic->length = check.out.generic_reply.length;
584                         generic->data = check.out.generic_reply.data;
585                         return NT_STATUS_OK;
586                 }
587
588                 /* Until we get an implemetnation of these other packages */
589                 return NT_STATUS_INVALID_PARAMETER;
590         }
591         default:
592                 return NT_STATUS_INVALID_PARAMETER;
593         }
594         
595         nt_status = auth_check_password(auth_context, mem_ctx, user_info, &server_info);
596         NT_STATUS_NOT_OK_RETURN(nt_status);
597
598         nt_status = auth_convert_server_info_sambaseinfo(mem_ctx, server_info, &sam);
599         NT_STATUS_NOT_OK_RETURN(nt_status);
600
601         /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
602         /* It appears that level 6 is not individually encrypted */
603         if ((r->in.validation_level != 6) &&
604             memcmp(sam->key.key, zeros, sizeof(sam->key.key)) != 0) {
605                 /* This key is sent unencrypted without the ARCFOUR flag set */
606                 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
607                         netlogon_creds_arcfour_crypt(creds, 
608                                             sam->key.key, 
609                                             sizeof(sam->key.key));
610                 }
611         }
612
613         /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
614         /* It appears that level 6 is not individually encrypted */
615         if ((r->in.validation_level != 6) &&
616             memcmp(sam->LMSessKey.key, zeros, sizeof(sam->LMSessKey.key)) != 0) {
617                 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
618                         netlogon_creds_arcfour_crypt(creds, 
619                                             sam->LMSessKey.key, 
620                                             sizeof(sam->LMSessKey.key));
621                 } else {
622                         netlogon_creds_des_encrypt_LMKey(creds, 
623                                                 &sam->LMSessKey);
624                 }
625         }
626
627         switch (r->in.validation_level) {
628         case 2:
629                 sam2 = talloc_zero(mem_ctx, struct netr_SamInfo2);
630                 NT_STATUS_HAVE_NO_MEMORY(sam2);
631                 sam2->base = *sam;
632                 r->out.validation->sam2 = sam2;
633                 break;
634
635         case 3:
636                 sam3 = talloc_zero(mem_ctx, struct netr_SamInfo3);
637                 NT_STATUS_HAVE_NO_MEMORY(sam3);
638                 sam3->base = *sam;
639                 r->out.validation->sam3 = sam3;
640                 break;
641
642         case 6:
643                 sam6 = talloc_zero(mem_ctx, struct netr_SamInfo6);
644                 NT_STATUS_HAVE_NO_MEMORY(sam6);
645                 sam6->base = *sam;
646                 sam6->forest.string = lp_dnsdomain(dce_call->conn->dce_ctx->lp_ctx);
647                 sam6->principle.string = talloc_asprintf(mem_ctx, "%s@%s", 
648                                                          sam->account_name.string, sam6->forest.string);
649                 NT_STATUS_HAVE_NO_MEMORY(sam6->principle.string);
650                 r->out.validation->sam6 = sam6;
651                 break;
652
653         default:
654                 break;
655         }
656
657         *r->out.authoritative = 1;
658
659         /* TODO: Describe and deal with these flags */
660         *r->out.flags = 0;
661
662         return NT_STATUS_OK;
663 }
664
665 static NTSTATUS dcesrv_netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
666                                      struct netr_LogonSamLogonEx *r) 
667 {
668         NTSTATUS nt_status;
669         struct netlogon_creds_CredentialState *creds;
670         struct ldb_context *ldb = schannel_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx);
671         if (!ldb) {
672                 return NT_STATUS_ACCESS_DENIED;
673         }
674         
675         nt_status = schannel_fetch_session_key_ldb(ldb, mem_ctx, r->in.computer_name, &creds);
676         if (!NT_STATUS_IS_OK(nt_status)) {
677                 return nt_status;
678         }
679
680         if (!dce_call->conn->auth_state.auth_info ||
681             dce_call->conn->auth_state.auth_info->auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
682                 return NT_STATUS_ACCESS_DENIED;
683         }
684         return dcesrv_netr_LogonSamLogon_base(dce_call, mem_ctx, r, creds);
685 }
686
687 /* 
688   netr_LogonSamLogonWithFlags
689
690 */
691 static NTSTATUS dcesrv_netr_LogonSamLogonWithFlags(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
692                                             struct netr_LogonSamLogonWithFlags *r)
693 {
694         NTSTATUS nt_status;
695         struct netlogon_creds_CredentialState *creds;
696         struct netr_LogonSamLogonEx r2;
697
698         struct netr_Authenticator *return_authenticator;
699
700         return_authenticator = talloc(mem_ctx, struct netr_Authenticator);
701         NT_STATUS_HAVE_NO_MEMORY(return_authenticator);
702
703         nt_status = dcesrv_netr_creds_server_step_check(dce_call,
704                                                         mem_ctx, 
705                                                         r->in.computer_name, 
706                                                         r->in.credential, return_authenticator,
707                                                         &creds);
708         NT_STATUS_NOT_OK_RETURN(nt_status);
709
710         ZERO_STRUCT(r2);
711
712         r2.in.server_name       = r->in.server_name;
713         r2.in.computer_name     = r->in.computer_name;
714         r2.in.logon_level       = r->in.logon_level;
715         r2.in.logon             = r->in.logon;
716         r2.in.validation_level  = r->in.validation_level;
717         r2.in.flags             = r->in.flags;
718         r2.out.validation       = r->out.validation;
719         r2.out.authoritative    = r->out.authoritative;
720         r2.out.flags            = r->out.flags;
721
722         nt_status = dcesrv_netr_LogonSamLogon_base(dce_call, mem_ctx, &r2, creds);
723
724         r->out.return_authenticator     = return_authenticator;
725
726         return nt_status;
727 }
728
729 /* 
730   netr_LogonSamLogon
731 */
732 static NTSTATUS dcesrv_netr_LogonSamLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
733                                    struct netr_LogonSamLogon *r)
734 {
735         struct netr_LogonSamLogonWithFlags r2;
736         uint32_t flags = 0;
737         NTSTATUS status;
738
739         ZERO_STRUCT(r2);
740
741         r2.in.server_name = r->in.server_name;
742         r2.in.computer_name = r->in.computer_name;
743         r2.in.credential  = r->in.credential;
744         r2.in.return_authenticator = r->in.return_authenticator;
745         r2.in.logon_level = r->in.logon_level;
746         r2.in.logon = r->in.logon;
747         r2.in.validation_level = r->in.validation_level;
748         r2.in.flags = &flags;
749         r2.out.validation = r->out.validation;
750         r2.out.authoritative = r->out.authoritative;
751         r2.out.flags = &flags;
752
753         status = dcesrv_netr_LogonSamLogonWithFlags(dce_call, mem_ctx, &r2);
754
755         r->out.return_authenticator = r2.out.return_authenticator;
756
757         return status;
758 }
759
760
761 /* 
762   netr_LogonSamLogoff 
763 */
764 static NTSTATUS dcesrv_netr_LogonSamLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
765                        struct netr_LogonSamLogoff *r)
766 {
767         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
768 }
769
770
771
772 /* 
773   netr_DatabaseDeltas 
774 */
775 static NTSTATUS dcesrv_netr_DatabaseDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
776                        struct netr_DatabaseDeltas *r)
777 {
778         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
779 }
780
781
782 /* 
783   netr_DatabaseSync2 
784 */
785 static NTSTATUS dcesrv_netr_DatabaseSync2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
786                        struct netr_DatabaseSync2 *r)
787 {
788         /* win2k3 native mode returns  "NOT IMPLEMENTED" for this call */
789         return NT_STATUS_NOT_IMPLEMENTED;
790 }
791
792
793 /* 
794   netr_DatabaseSync 
795 */
796 static NTSTATUS dcesrv_netr_DatabaseSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
797                        struct netr_DatabaseSync *r)
798 {
799         struct netr_DatabaseSync2 r2;
800         NTSTATUS status;
801
802         ZERO_STRUCT(r2);
803
804         r2.in.logon_server = r->in.logon_server;
805         r2.in.computername = r->in.computername;
806         r2.in.credential = r->in.credential;
807         r2.in.database_id = r->in.database_id;
808         r2.in.restart_state = SYNCSTATE_NORMAL_STATE;
809         r2.in.sync_context = r->in.sync_context;
810         r2.out.sync_context = r->out.sync_context;
811         r2.out.delta_enum_array = r->out.delta_enum_array;
812         r2.in.preferredmaximumlength = r->in.preferredmaximumlength;
813
814         status = dcesrv_netr_DatabaseSync2(dce_call, mem_ctx, &r2);
815
816         return status;
817 }
818
819
820 /* 
821   netr_AccountDeltas 
822 */
823 static NTSTATUS dcesrv_netr_AccountDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
824                        struct netr_AccountDeltas *r)
825 {
826         /* w2k3 returns "NOT IMPLEMENTED" for this call */
827         return NT_STATUS_NOT_IMPLEMENTED;
828 }
829
830
831 /* 
832   netr_AccountSync 
833 */
834 static NTSTATUS dcesrv_netr_AccountSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
835                        struct netr_AccountSync *r)
836 {
837         /* w2k3 returns "NOT IMPLEMENTED" for this call */
838         return NT_STATUS_NOT_IMPLEMENTED;
839 }
840
841
842 /* 
843   netr_GetDcName 
844 */
845 static WERROR dcesrv_netr_GetDcName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
846                        struct netr_GetDcName *r)
847 {
848         const char * const attrs[] = { NULL };
849         struct ldb_context *sam_ctx;
850         struct ldb_message **res;
851         struct ldb_dn *domain_dn;
852         int ret;
853         const char *dcname;
854
855         sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx,
856                                 dce_call->conn->dce_ctx->lp_ctx,
857                                 dce_call->conn->auth_state.session_info);
858         if (sam_ctx == NULL) {
859                 return WERR_DS_UNAVAILABLE;
860         }
861
862         domain_dn = samdb_domain_to_dn(sam_ctx, mem_ctx,
863                                        r->in.domainname);
864         if (domain_dn == NULL) {
865                 return WERR_DS_UNAVAILABLE;
866         }
867
868         ret = gendb_search_dn(sam_ctx, mem_ctx,
869                               domain_dn, &res, attrs);
870         if (ret != 1) {
871                 return WERR_NO_SUCH_DOMAIN;
872         }
873
874         /* TODO: - return real IP address
875          *       - check all r->in.* parameters (server_unc is ignored by w2k3!)
876          */
877         dcname = talloc_asprintf(mem_ctx, "\\\\%s",
878                                  lp_netbios_name(dce_call->conn->dce_ctx->lp_ctx));
879         W_ERROR_HAVE_NO_MEMORY(dcname);
880
881         *r->out.dcname = dcname;
882         return WERR_OK;
883 }
884
885
886 /* 
887   netr_LogonControl2Ex 
888 */
889 static WERROR dcesrv_netr_LogonControl2Ex(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
890                        struct netr_LogonControl2Ex *r)
891 {
892         return WERR_NOT_SUPPORTED;
893 }
894
895
896 /* 
897   netr_LogonControl 
898 */
899 static WERROR dcesrv_netr_LogonControl(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
900                        struct netr_LogonControl *r)
901 {
902         struct netr_LogonControl2Ex r2;
903         WERROR werr;
904
905         if (r->in.level == 0x00000001) {
906                 ZERO_STRUCT(r2);
907
908                 r2.in.logon_server = r->in.logon_server;
909                 r2.in.function_code = r->in.function_code;
910                 r2.in.level = r->in.level;
911                 r2.in.data = NULL;
912                 r2.out.query = r->out.query;
913
914                 werr = dcesrv_netr_LogonControl2Ex(dce_call, mem_ctx, &r2);
915         } else if (r->in.level == 0x00000002) {
916                 werr = WERR_NOT_SUPPORTED;
917         } else {
918                 werr = WERR_UNKNOWN_LEVEL;
919         }
920
921         return werr;
922 }
923
924
925 /* 
926   netr_LogonControl2 
927 */
928 static WERROR dcesrv_netr_LogonControl2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
929                        struct netr_LogonControl2 *r)
930 {
931         struct netr_LogonControl2Ex r2;
932         WERROR werr;
933
934         ZERO_STRUCT(r2);
935
936         r2.in.logon_server = r->in.logon_server;
937         r2.in.function_code = r->in.function_code;
938         r2.in.level = r->in.level;
939         r2.in.data = r->in.data;
940         r2.out.query = r->out.query;
941
942         werr = dcesrv_netr_LogonControl2Ex(dce_call, mem_ctx, &r2);
943
944         return werr;
945 }
946
947
948 /* 
949   netr_GetAnyDCName 
950 */
951 static WERROR dcesrv_netr_GetAnyDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
952                        struct netr_GetAnyDCName *r)
953 {
954         struct netr_GetDcName r2;
955         WERROR werr;
956
957         ZERO_STRUCT(r2);
958
959         r2.in.logon_server      = r->in.logon_server;
960         r2.in.domainname        = r->in.domainname;
961         r2.out.dcname           = r->out.dcname;
962
963         werr = dcesrv_netr_GetDcName(dce_call, mem_ctx, &r2);
964
965         return werr;
966 }
967
968
969 /* 
970   netr_DatabaseRedo 
971 */
972 static NTSTATUS dcesrv_netr_DatabaseRedo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
973                        struct netr_DatabaseRedo *r)
974 {
975         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
976 }
977
978
979 /* 
980   netr_NetrEnumerateTurstedDomains
981 */
982 static WERROR dcesrv_netr_NetrEnumerateTrustedDomains(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
983                        struct netr_NetrEnumerateTrustedDomains *r)
984 {
985         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
986 }
987
988
989 /* 
990   netr_LogonGetCapabilities
991 */
992 static NTSTATUS dcesrv_netr_LogonGetCapabilities(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
993                        struct netr_LogonGetCapabilities *r)
994 {
995         /* we don't support AES yet */
996         return NT_STATUS_NOT_IMPLEMENTED;
997 }
998
999
1000 /* 
1001   netr_NETRLOGONSETSERVICEBITS 
1002 */
1003 static WERROR dcesrv_netr_NETRLOGONSETSERVICEBITS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1004                        struct netr_NETRLOGONSETSERVICEBITS *r)
1005 {
1006         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1007 }
1008
1009
1010 /*
1011   netr_LogonGetTrustRid
1012 */
1013 static WERROR dcesrv_netr_LogonGetTrustRid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1014                        struct netr_LogonGetTrustRid *r)
1015 {
1016         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1017 }
1018
1019
1020 /* 
1021   netr_NETRLOGONCOMPUTESERVERDIGEST 
1022 */
1023 static WERROR dcesrv_netr_NETRLOGONCOMPUTESERVERDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1024                        struct netr_NETRLOGONCOMPUTESERVERDIGEST *r)
1025 {
1026         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1027 }
1028
1029
1030 /* 
1031   netr_NETRLOGONCOMPUTECLIENTDIGEST 
1032 */
1033 static WERROR dcesrv_netr_NETRLOGONCOMPUTECLIENTDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1034                        struct netr_NETRLOGONCOMPUTECLIENTDIGEST *r)
1035 {
1036         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1037 }
1038
1039
1040
1041 /* 
1042   netr_DsRGetSiteName
1043 */
1044 static WERROR dcesrv_netr_DsRGetSiteName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1045                                   struct netr_DsRGetSiteName *r)
1046 {
1047         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1048 }
1049
1050
1051 /*
1052   fill in a netr_OneDomainInfo from a ldb search result
1053 */
1054 static NTSTATUS fill_one_domain_info(TALLOC_CTX *mem_ctx,
1055                                      struct loadparm_context *lp_ctx,
1056                                      struct ldb_context *sam_ctx,
1057                                      struct ldb_message *res,
1058                                      struct netr_OneDomainInfo *info,
1059                                      bool is_local, bool is_trust_list)
1060 {
1061         ZERO_STRUCTP(info);
1062
1063         if (is_trust_list) {
1064                 /* w2k8 only fills this on trusted domains */
1065                 info->trust_extension.info = talloc_zero(mem_ctx, struct netr_trust_extension);
1066                 info->trust_extension.length = 16;
1067                 info->trust_extension.info->flags = 
1068                         NETR_TRUST_FLAG_TREEROOT |
1069                         NETR_TRUST_FLAG_IN_FOREST | 
1070                         NETR_TRUST_FLAG_PRIMARY |
1071                         NETR_TRUST_FLAG_NATIVE;
1072
1073                 info->trust_extension.info->parent_index = 0; /* should be index into array
1074                                                                  of parent */
1075                 info->trust_extension.info->trust_type = LSA_TRUST_TYPE_UPLEVEL; /* should be based on ldb search for trusts */
1076                 info->trust_extension.info->trust_attributes = 0; /*    TODO: base on ldb search? */
1077         }
1078
1079         if (is_trust_list) {
1080                 /* MS-NRPC 3.5.4.3.9 - must be set to NULL for trust list */
1081                 info->dns_forestname.string = NULL;
1082         } else {
1083                 char *p;
1084                 /* TODO: we need a common function for pulling the forest */
1085                 info->dns_forestname.string = ldb_dn_canonical_string(info, ldb_get_root_basedn(sam_ctx));
1086                 if (!info->dns_forestname.string) {
1087                         return NT_STATUS_NO_SUCH_DOMAIN;                
1088                 }
1089                 p = strchr(info->dns_forestname.string, '/');
1090                 if (p) {
1091                         *p = '\0';
1092                 }
1093                 info->dns_forestname.string = talloc_asprintf(mem_ctx, "%s.", info->dns_forestname.string);
1094                                         
1095         }
1096
1097         if (is_local) {
1098                 info->domainname.string = lp_sam_name(lp_ctx);
1099                 info->dns_domainname.string = lp_dnsdomain(lp_ctx);
1100                 info->domain_guid = samdb_result_guid(res, "objectGUID");
1101                 info->domain_sid = samdb_result_dom_sid(mem_ctx, res, "objectSid");
1102         } else {
1103                 info->domainname.string = samdb_result_string(res, "flatName", NULL);
1104                 info->dns_domainname.string = samdb_result_string(res, "trustPartner", NULL);
1105                 info->domain_guid = samdb_result_guid(res, "objectGUID");
1106                 info->domain_sid = samdb_result_dom_sid(mem_ctx, res, "securityIdentifier");
1107         }
1108         if (!is_trust_list) {
1109                 info->dns_domainname.string = talloc_asprintf(mem_ctx, "%s.", info->dns_domainname.string);
1110         }
1111
1112         return NT_STATUS_OK;
1113 }
1114
1115 /* 
1116   netr_LogonGetDomainInfo
1117   this is called as part of the ADS domain logon procedure.
1118
1119   It has an important role in convaying details about the client, such
1120   as Operating System, Version, Service Pack etc.
1121 */
1122 static NTSTATUS dcesrv_netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_call,
1123         TALLOC_CTX *mem_ctx, struct netr_LogonGetDomainInfo *r)
1124 {
1125         struct netlogon_creds_CredentialState *creds;
1126         const char * const attrs[] = { "objectSid", "objectGUID", "flatName",
1127                 "securityIdentifier", "trustPartner", NULL };
1128         const char * const attrs2[] = { "dNSHostName",
1129                 "msDS-SupportedEncryptionTypes", NULL };
1130         const char *temp_str;
1131         const char *old_dns_hostname;
1132         struct ldb_context *sam_ctx;
1133         struct ldb_message **res1, **res2, **res3, *new_msg;
1134         struct ldb_dn *workstation_dn;
1135         struct netr_DomainInformation *domain_info;
1136         struct netr_LsaPolicyInformation *lsa_policy_info;
1137         struct netr_OsVersionInfoEx *os_version;
1138         uint32_t default_supported_enc_types = 0xFFFFFFFF;
1139         int ret1, ret2, ret3, i;
1140         NTSTATUS status;
1141
1142         status = dcesrv_netr_creds_server_step_check(dce_call,
1143                                                      mem_ctx, 
1144                                                      r->in.computer_name, 
1145                                                      r->in.credential, 
1146                                                      r->out.return_authenticator,
1147                                                      &creds);
1148         if (!NT_STATUS_IS_OK(status)) {
1149                 DEBUG(0,(__location__ " Bad credentials - error\n"));
1150         }
1151         NT_STATUS_NOT_OK_RETURN(status);
1152
1153         sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx,
1154                 dce_call->conn->dce_ctx->lp_ctx,
1155                 system_session(dce_call->conn->dce_ctx->lp_ctx));
1156         if (sam_ctx == NULL) {
1157                 return NT_STATUS_INVALID_SYSTEM_SERVICE;
1158         }
1159
1160         switch (r->in.level) {
1161         case 1: /* Domain information */
1162
1163                 /* TODO: check NTSTATUS results - and fail also on SAMDB
1164                  * errors (needs some testing against Windows Server 2008) */
1165
1166                 /*
1167                  * Check that the computer name parameter matches as prefix with
1168                  * the DNS hostname in the workstation info structure.
1169                  */
1170                 temp_str = strndup(r->in.query->workstation_info->dns_hostname,
1171                         strcspn(r->in.query->workstation_info->dns_hostname,
1172                         "."));
1173                 if (strcasecmp(r->in.computer_name, temp_str) != 0)
1174                         return NT_STATUS_INVALID_PARAMETER;
1175
1176                 workstation_dn = ldb_dn_new_fmt(mem_ctx, sam_ctx, "<SID=%s>",
1177                         dom_sid_string(mem_ctx, creds->sid));
1178                 NT_STATUS_HAVE_NO_MEMORY(workstation_dn);
1179
1180                 /* Lookup for attributes in workstation object */
1181                 ret1 = gendb_search_dn(sam_ctx, mem_ctx, workstation_dn,
1182                         &res1, attrs2);
1183                 if (ret1 != 1) {
1184                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
1185                 }
1186
1187                 /* Gets the old DNS hostname */
1188                 old_dns_hostname = samdb_result_string(res1[0], "dNSHostName",
1189                         NULL);
1190
1191                 /* Gets host informations and put them in our directory */
1192                 new_msg = ldb_msg_new(mem_ctx);
1193                 NT_STATUS_HAVE_NO_MEMORY(new_msg);
1194
1195                 new_msg->dn = workstation_dn;
1196
1197                 /* Deletes old OS version values */
1198                 samdb_msg_add_delete(sam_ctx, mem_ctx, new_msg,
1199                         "operatingSystemServicePack");
1200                 samdb_msg_add_delete(sam_ctx, mem_ctx, new_msg,
1201                         "operatingSystemVersion");
1202
1203                 if (samdb_replace(sam_ctx, mem_ctx, new_msg) != LDB_SUCCESS) {
1204                         DEBUG(3,("Impossible to update samdb: %s\n",
1205                                 ldb_errstring(sam_ctx)));
1206                 }
1207
1208                 talloc_free(new_msg);
1209
1210                 new_msg = ldb_msg_new(mem_ctx);
1211                 NT_STATUS_HAVE_NO_MEMORY(new_msg);
1212
1213                 new_msg->dn = workstation_dn;
1214
1215                 /* Sets the OS name */
1216                 samdb_msg_set_string(sam_ctx, mem_ctx, new_msg,
1217                         "operatingSystem",
1218                         r->in.query->workstation_info->os_name.string);
1219
1220                 if (r->in.query->workstation_info->dns_hostname) {
1221                         /* TODO: should this always be done? */
1222                         samdb_msg_add_string(sam_ctx, mem_ctx, new_msg,
1223                                              "dNSHostname",
1224                                              r->in.query->workstation_info->dns_hostname);
1225                 }
1226
1227                 /*
1228                  * Sets informations from "os_version". On a empty structure
1229                  * the values are cleared.
1230                  */
1231                 if (r->in.query->workstation_info->os_version.os != NULL) {
1232                         os_version = &r->in.query->workstation_info->os_version.os->os;
1233
1234                         samdb_msg_set_string(sam_ctx, mem_ctx, new_msg,
1235                                              "operatingSystemServicePack",
1236                                              os_version->CSDVersion);
1237
1238                         samdb_msg_set_string(sam_ctx, mem_ctx, new_msg,
1239                                 "operatingSystemVersion",
1240                                 talloc_asprintf(mem_ctx, "%d.%d (%d)",
1241                                         os_version->MajorVersion,
1242                                         os_version->MinorVersion,
1243                                         os_version->BuildNumber
1244                                 )
1245                         );
1246                 }
1247
1248                 /*
1249                  * Updates the "dNSHostname" and the "servicePrincipalName"s
1250                  * since the client wishes that the server should handle this
1251                  * for him ("NETR_WS_FLAG_HANDLES_SPN_UPDATE" not set).
1252                  * See MS-NRPC section 3.5.4.3.9
1253                  */
1254                 if ((r->in.query->workstation_info->workstation_flags
1255                         & NETR_WS_FLAG_HANDLES_SPN_UPDATE) == 0) {
1256
1257                         samdb_msg_add_string(sam_ctx, mem_ctx, new_msg,
1258                                 "servicePrincipalName",
1259                                 talloc_asprintf(mem_ctx, "HOST/%s",
1260                                 r->in.computer_name)
1261                         );
1262                         samdb_msg_add_string(sam_ctx, mem_ctx, new_msg,
1263                                 "servicePrincipalName",
1264                                 talloc_asprintf(mem_ctx, "HOST/%s",
1265                                 r->in.query->workstation_info->dns_hostname)
1266                         );
1267                 }
1268
1269                 if (samdb_replace(sam_ctx, mem_ctx, new_msg) != LDB_SUCCESS) {
1270                         DEBUG(3,("Impossible to update samdb: %s\n",
1271                                 ldb_errstring(sam_ctx)));
1272                 }
1273
1274                 talloc_free(new_msg);
1275
1276                 /* Writes back the domain information */
1277
1278                 /* We need to do two searches. The first will pull our primary
1279                    domain and the second will pull any trusted domains. Our
1280                    primary domain is also a "trusted" domain, so we need to
1281                    put the primary domain into the lists of returned trusts as
1282                    well. */
1283                 ret2 = gendb_search_dn(sam_ctx, mem_ctx, samdb_base_dn(sam_ctx),
1284                         &res2, attrs);
1285                 if (ret2 != 1) {
1286                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
1287                 }
1288
1289                 ret3 = gendb_search(sam_ctx, mem_ctx, NULL, &res3, attrs,
1290                         "(objectClass=trustedDomain)");
1291                 if (ret3 == -1) {
1292                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
1293                 }
1294
1295                 domain_info = talloc(mem_ctx, struct netr_DomainInformation);
1296                 NT_STATUS_HAVE_NO_MEMORY(domain_info);
1297
1298                 ZERO_STRUCTP(domain_info);
1299
1300                 /* Informations about the local and trusted domains */
1301
1302                 status = fill_one_domain_info(mem_ctx,
1303                         dce_call->conn->dce_ctx->lp_ctx,
1304                         sam_ctx, res2[0], &domain_info->primary_domain,
1305                         true, false);
1306                 NT_STATUS_NOT_OK_RETURN(status);
1307
1308                 domain_info->trusted_domain_count = ret3 + 1;
1309                 domain_info->trusted_domains = talloc_array(mem_ctx,
1310                         struct netr_OneDomainInfo,
1311                         domain_info->trusted_domain_count);
1312                 NT_STATUS_HAVE_NO_MEMORY(domain_info->trusted_domains);
1313
1314                 for (i=0;i<ret3;i++) {
1315                         status = fill_one_domain_info(mem_ctx,
1316                                 dce_call->conn->dce_ctx->lp_ctx,
1317                                 sam_ctx, res3[i],
1318                                 &domain_info->trusted_domains[i],
1319                                 false, true);
1320                         NT_STATUS_NOT_OK_RETURN(status);
1321                 }
1322
1323                 status = fill_one_domain_info(mem_ctx,
1324                         dce_call->conn->dce_ctx->lp_ctx, sam_ctx, res2[0],
1325                         &domain_info->trusted_domains[i], true, true);
1326                 NT_STATUS_NOT_OK_RETURN(status);
1327
1328                 /* Sets the supported encryption types */
1329                 domain_info->supported_enc_types = samdb_result_uint(res1[0],
1330                         "msDS-SupportedEncryptionTypes",
1331                         default_supported_enc_types);
1332
1333                 /* Other host domain informations */
1334
1335                 lsa_policy_info = talloc(mem_ctx,
1336                         struct netr_LsaPolicyInformation);
1337                 NT_STATUS_HAVE_NO_MEMORY(lsa_policy_info);
1338                 ZERO_STRUCTP(lsa_policy_info);
1339
1340                 domain_info->lsa_policy = *lsa_policy_info;
1341
1342                 domain_info->dns_hostname.string = old_dns_hostname;
1343                 domain_info->workstation_flags =
1344                         r->in.query->workstation_info->workstation_flags;
1345
1346                 r->out.info->domain_info = domain_info;
1347         break;
1348         case 2: /* LSA policy information - not used at the moment */
1349                 lsa_policy_info = talloc(mem_ctx,
1350                         struct netr_LsaPolicyInformation);
1351                 NT_STATUS_HAVE_NO_MEMORY(lsa_policy_info);
1352                 ZERO_STRUCTP(lsa_policy_info);
1353
1354                 r->out.info->lsa_policy_info = lsa_policy_info;
1355         break;
1356         default:
1357                 return NT_STATUS_INVALID_LEVEL;
1358         break;
1359         }
1360
1361         return NT_STATUS_OK;
1362 }
1363
1364
1365
1366 /*
1367   netr_ServerPasswordGet
1368 */
1369 static WERROR dcesrv_netr_ServerPasswordGet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1370                        struct netr_ServerPasswordGet *r)
1371 {
1372         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1373 }
1374
1375
1376 /* 
1377   netr_NETRLOGONSENDTOSAM 
1378 */
1379 static WERROR dcesrv_netr_NETRLOGONSENDTOSAM(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1380                        struct netr_NETRLOGONSENDTOSAM *r)
1381 {
1382         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1383 }
1384
1385
1386 /* 
1387   netr_DsRAddressToSitenamesW 
1388 */
1389 static WERROR dcesrv_netr_DsRAddressToSitenamesW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1390                        struct netr_DsRAddressToSitenamesW *r)
1391 {
1392         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1393 }
1394
1395
1396 /* 
1397   netr_DsRGetDCNameEx2
1398 */
1399 static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1400                                    struct netr_DsRGetDCNameEx2 *r)
1401 {
1402         const char * const attrs[] = { "objectGUID", NULL };
1403         struct ldb_context *sam_ctx;
1404         struct ldb_message **res;
1405         struct ldb_dn *domain_dn;
1406         int ret;
1407         struct netr_DsRGetDCNameInfo *info;
1408
1409         ZERO_STRUCTP(r->out.info);
1410
1411         sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
1412         if (sam_ctx == NULL) {
1413                 return WERR_DS_UNAVAILABLE;
1414         }
1415
1416         /* Win7-beta will send the domain name in the form the user typed, so we have to cope
1417            with both the short and long form here */
1418         if (r->in.domain_name != NULL && !lp_is_my_domain_or_realm(dce_call->conn->dce_ctx->lp_ctx, 
1419                                                                 r->in.domain_name)) {
1420                 return WERR_NO_SUCH_DOMAIN;
1421         }
1422
1423         domain_dn = ldb_get_default_basedn(sam_ctx);
1424         if (domain_dn == NULL) {
1425                 return WERR_DS_UNAVAILABLE;
1426         }
1427
1428         ret = gendb_search_dn(sam_ctx, mem_ctx,
1429                               domain_dn, &res, attrs);
1430         if (ret != 1) {
1431         }
1432
1433         info = talloc(mem_ctx, struct netr_DsRGetDCNameInfo);
1434         W_ERROR_HAVE_NO_MEMORY(info);
1435
1436         /* TODO: - return real IP address
1437          *       - check all r->in.* parameters (server_unc is ignored by w2k3!)
1438          */
1439         info->dc_unc                    = talloc_asprintf(mem_ctx, "\\\\%s.%s",
1440                                                           lp_netbios_name(dce_call->conn->dce_ctx->lp_ctx), 
1441                                                           lp_dnsdomain(dce_call->conn->dce_ctx->lp_ctx));
1442         W_ERROR_HAVE_NO_MEMORY(info->dc_unc);
1443         info->dc_address                = talloc_strdup(mem_ctx, "\\\\0.0.0.0");
1444         W_ERROR_HAVE_NO_MEMORY(info->dc_address);
1445         info->dc_address_type           = DS_ADDRESS_TYPE_INET;
1446         info->domain_guid               = samdb_result_guid(res[0], "objectGUID");
1447         info->domain_name               = lp_dnsdomain(dce_call->conn->dce_ctx->lp_ctx);
1448         info->forest_name               = lp_dnsdomain(dce_call->conn->dce_ctx->lp_ctx);
1449         info->dc_flags                  = DS_DNS_FOREST_ROOT |
1450                                           DS_DNS_DOMAIN |
1451                                           DS_DNS_CONTROLLER |
1452                                           DS_SERVER_WRITABLE |
1453                                           DS_SERVER_CLOSEST |
1454                                           DS_SERVER_TIMESERV |
1455                                           DS_SERVER_KDC |
1456                                           DS_SERVER_DS |
1457                                           DS_SERVER_LDAP |
1458                                           DS_SERVER_GC |
1459                                           DS_SERVER_PDC;
1460         info->dc_site_name      = samdb_server_site_name(sam_ctx, mem_ctx);
1461         W_ERROR_HAVE_NO_MEMORY(info->dc_site_name);
1462         /* FIXME: Hardcoded site name */
1463         info->client_site_name  = talloc_strdup(mem_ctx, "Default-First-Site-Name");
1464         W_ERROR_HAVE_NO_MEMORY(info->client_site_name);
1465
1466         *r->out.info = info;
1467
1468         return WERR_OK;
1469 }
1470
1471 /* 
1472   netr_DsRGetDCNameEx
1473 */
1474 static WERROR dcesrv_netr_DsRGetDCNameEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1475                                   struct netr_DsRGetDCNameEx *r)
1476 {
1477         struct netr_DsRGetDCNameEx2 r2;
1478         WERROR werr;
1479
1480         ZERO_STRUCT(r2);
1481
1482         r2.in.server_unc = r->in.server_unc;
1483         r2.in.client_account = NULL;
1484         r2.in.mask = 0;
1485         r2.in.domain_guid = r->in.domain_guid;
1486         r2.in.domain_name = r->in.domain_name;
1487         r2.in.site_name = r->in.site_name;
1488         r2.in.flags = r->in.flags;
1489         r2.out.info = r->out.info;
1490
1491         werr = dcesrv_netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1492
1493         return werr;
1494 }
1495
1496 /* 
1497   netr_DsRGetDCName
1498 */
1499 static WERROR dcesrv_netr_DsRGetDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1500                                 struct netr_DsRGetDCName *r)
1501 {
1502         struct netr_DsRGetDCNameEx2 r2;
1503         WERROR werr;
1504
1505         ZERO_STRUCT(r2);
1506
1507         r2.in.server_unc = r->in.server_unc;
1508         r2.in.client_account = NULL;
1509         r2.in.mask = 0;
1510         r2.in.domain_name = r->in.domain_name;
1511         r2.in.domain_guid = r->in.domain_guid;
1512         
1513         r2.in.site_name = NULL; /* should fill in from site GUID */
1514         r2.in.flags = r->in.flags;
1515         r2.out.info = r->out.info;
1516
1517         werr = dcesrv_netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1518
1519         return werr;
1520 }
1521 /* 
1522   netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN 
1523 */
1524 static WERROR dcesrv_netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1525                        struct netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN *r)
1526 {
1527         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1528 }
1529
1530
1531 /*
1532   netr_NetrEnumerateTrustedDomainsEx
1533 */
1534 static WERROR dcesrv_netr_NetrEnumerateTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1535                        struct netr_NetrEnumerateTrustedDomainsEx *r)
1536 {
1537         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1538 }
1539
1540
1541 /* 
1542   netr_DsRAddressToSitenamesExW 
1543 */
1544 static WERROR dcesrv_netr_DsRAddressToSitenamesExW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1545                                                    struct netr_DsRAddressToSitenamesExW *r)
1546 {
1547         struct netr_DsRAddressToSitenamesExWCtr *ctr;
1548         int i;
1549
1550         /* we should map the provided IPs to site names, once we have
1551          * sites support
1552          */
1553         ctr = talloc(mem_ctx, struct netr_DsRAddressToSitenamesExWCtr);
1554         W_ERROR_HAVE_NO_MEMORY(ctr);
1555
1556         *r->out.ctr = ctr;
1557
1558         ctr->count = r->in.count;
1559         ctr->sitename = talloc_array(ctr, struct lsa_String, ctr->count);
1560         W_ERROR_HAVE_NO_MEMORY(ctr->sitename);
1561         ctr->subnetname = talloc_array(ctr, struct lsa_String, ctr->count);
1562         W_ERROR_HAVE_NO_MEMORY(ctr->subnetname);
1563
1564         for (i=0; i<ctr->count; i++) {
1565                 /* FIXME: Hardcoded site name */
1566                 ctr->sitename[i].string   = "Default-First-Site-Name";
1567                 ctr->subnetname[i].string = NULL;
1568         }
1569
1570         return WERR_OK;
1571 }
1572
1573
1574 /* 
1575   netr_DsrGetDcSiteCoverageW
1576 */
1577 static WERROR dcesrv_netr_DsrGetDcSiteCoverageW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1578                        struct netr_DsrGetDcSiteCoverageW *r)
1579 {
1580         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1581 }
1582
1583
1584 /* 
1585   netr_DsrEnumerateDomainTrusts 
1586 */
1587 static WERROR dcesrv_netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1588                                               struct netr_DsrEnumerateDomainTrusts *r)
1589 {
1590         struct netr_DomainTrustList *trusts;
1591         struct ldb_context *sam_ctx;
1592         int ret;
1593         struct ldb_message **dom_res;
1594         const char * const dom_attrs[] = { "objectSid", "objectGUID", NULL };
1595
1596         ZERO_STRUCT(r->out);
1597
1598         sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
1599         if (sam_ctx == NULL) {
1600                 return WERR_GENERAL_FAILURE;
1601         }
1602
1603         ret = gendb_search_dn(sam_ctx, mem_ctx, NULL,
1604                               &dom_res, dom_attrs);
1605         if (ret == -1) {
1606                 return WERR_GENERAL_FAILURE;            
1607         }
1608         if (ret != 1) {
1609                 return WERR_GENERAL_FAILURE;
1610         }
1611
1612         trusts = talloc(mem_ctx, struct netr_DomainTrustList);
1613         W_ERROR_HAVE_NO_MEMORY(trusts);
1614
1615         trusts->array = talloc_array(trusts, struct netr_DomainTrust, ret);
1616         W_ERROR_HAVE_NO_MEMORY(trusts->array);
1617
1618         trusts->count = 1; /* ?? */
1619
1620         r->out.trusts = trusts;
1621
1622         /* TODO: add filtering by trust_flags, and correct trust_type
1623            and attributes */
1624         trusts->array[0].netbios_name = lp_sam_name(dce_call->conn->dce_ctx->lp_ctx);
1625         trusts->array[0].dns_name     = lp_dnsdomain(dce_call->conn->dce_ctx->lp_ctx);
1626         trusts->array[0].trust_flags =
1627                 NETR_TRUST_FLAG_TREEROOT | 
1628                 NETR_TRUST_FLAG_IN_FOREST | 
1629                 NETR_TRUST_FLAG_PRIMARY;
1630         trusts->array[0].parent_index = 0;
1631         trusts->array[0].trust_type = 2;
1632         trusts->array[0].trust_attributes = 0;
1633         trusts->array[0].sid  = samdb_result_dom_sid(mem_ctx, dom_res[0], "objectSid");
1634         trusts->array[0].guid = samdb_result_guid(dom_res[0], "objectGUID");
1635
1636         return WERR_OK;
1637 }
1638
1639
1640 /*
1641   netr_DsrDeregisterDNSHostRecords
1642 */
1643 static WERROR dcesrv_netr_DsrDeregisterDNSHostRecords(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1644                        struct netr_DsrDeregisterDNSHostRecords *r)
1645 {
1646         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1647 }
1648
1649
1650 /*
1651   netr_ServerTrustPasswordsGet
1652 */
1653 static NTSTATUS dcesrv_netr_ServerTrustPasswordsGet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1654                        struct netr_ServerTrustPasswordsGet *r)
1655 {
1656         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1657 }
1658
1659
1660 /* 
1661   netr_DsRGetForestTrustInformation 
1662 */
1663 static WERROR dcesrv_netr_DsRGetForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1664                        struct netr_DsRGetForestTrustInformation *r)
1665 {
1666         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1667 }
1668
1669
1670 /*
1671   netr_GetForestTrustInformation
1672 */
1673 static WERROR dcesrv_netr_GetForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1674                        struct netr_GetForestTrustInformation *r)
1675 {
1676         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1677 }
1678
1679
1680 /*
1681   netr_ServerGetTrustInfo
1682 */
1683 static NTSTATUS dcesrv_netr_ServerGetTrustInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1684                        struct netr_ServerGetTrustInfo *r)
1685 {
1686         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1687 }
1688
1689
1690 /* include the generated boilerplate */
1691 #include "librpc/gen_ndr/ndr_netlogon_s.c"