s4-dsdb: change samdb_replace() to dsdb_replace() and allow for dsdb_flags
[ddiss/samba.git] / source4 / rpc_server / netlogon / dcerpc_netlogon.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    endpoint server for the netlogon pipe
5
6    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2008
7    Copyright (C) Stefan Metzmacher <metze@samba.org>  2005
8    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 (dsdb_replace(sam_ctx, new_msg, 0) != 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                 /*
1221                  * Sets informations from "os_version". On a empty structure
1222                  * the values are cleared.
1223                  */
1224                 if (r->in.query->workstation_info->os_version.os != NULL) {
1225                         os_version = &r->in.query->workstation_info->os_version.os->os;
1226
1227                         samdb_msg_set_string(sam_ctx, mem_ctx, new_msg,
1228                                              "operatingSystemServicePack",
1229                                              os_version->CSDVersion);
1230
1231                         samdb_msg_set_string(sam_ctx, mem_ctx, new_msg,
1232                                 "operatingSystemVersion",
1233                                 talloc_asprintf(mem_ctx, "%d.%d (%d)",
1234                                         os_version->MajorVersion,
1235                                         os_version->MinorVersion,
1236                                         os_version->BuildNumber
1237                                 )
1238                         );
1239                 }
1240
1241                 /*
1242                  * Updates the "dNSHostname" and the "servicePrincipalName"s
1243                  * since the client wishes that the server should handle this
1244                  * for him ("NETR_WS_FLAG_HANDLES_SPN_UPDATE" not set).
1245                  * See MS-NRPC section 3.5.4.3.9
1246                  */
1247                 if ((r->in.query->workstation_info->workstation_flags
1248                         & NETR_WS_FLAG_HANDLES_SPN_UPDATE) == 0) {
1249                         samdb_msg_set_string(sam_ctx, mem_ctx, new_msg,
1250                                 "dNSHostname",
1251                         r->in.query->workstation_info->dns_hostname);
1252
1253                         samdb_msg_add_string(sam_ctx, mem_ctx, new_msg,
1254                                 "servicePrincipalName",
1255                                 talloc_asprintf(mem_ctx, "HOST/%s",
1256                                 r->in.computer_name)
1257                         );
1258                         samdb_msg_add_string(sam_ctx, mem_ctx, new_msg,
1259                                 "servicePrincipalName",
1260                                 talloc_asprintf(mem_ctx, "HOST/%s",
1261                                 r->in.query->workstation_info->dns_hostname)
1262                         );
1263                 }
1264
1265                 if (dsdb_replace(sam_ctx, new_msg, 0) != LDB_SUCCESS) {
1266                         DEBUG(3,("Impossible to update samdb: %s\n",
1267                                 ldb_errstring(sam_ctx)));
1268                 }
1269
1270                 talloc_free(new_msg);
1271
1272                 /* Writes back the domain information */
1273
1274                 /* We need to do two searches. The first will pull our primary
1275                    domain and the second will pull any trusted domains. Our
1276                    primary domain is also a "trusted" domain, so we need to
1277                    put the primary domain into the lists of returned trusts as
1278                    well. */
1279                 ret2 = gendb_search_dn(sam_ctx, mem_ctx, samdb_base_dn(sam_ctx),
1280                         &res2, attrs);
1281                 if (ret2 != 1) {
1282                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
1283                 }
1284
1285                 ret3 = gendb_search(sam_ctx, mem_ctx, NULL, &res3, attrs,
1286                         "(objectClass=trustedDomain)");
1287                 if (ret3 == -1) {
1288                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
1289                 }
1290
1291                 domain_info = talloc(mem_ctx, struct netr_DomainInformation);
1292                 NT_STATUS_HAVE_NO_MEMORY(domain_info);
1293
1294                 ZERO_STRUCTP(domain_info);
1295
1296                 /* Informations about the local and trusted domains */
1297
1298                 status = fill_one_domain_info(mem_ctx,
1299                         dce_call->conn->dce_ctx->lp_ctx,
1300                         sam_ctx, res2[0], &domain_info->primary_domain,
1301                         true, false);
1302                 NT_STATUS_NOT_OK_RETURN(status);
1303
1304                 domain_info->trusted_domain_count = ret3 + 1;
1305                 domain_info->trusted_domains = talloc_array(mem_ctx,
1306                         struct netr_OneDomainInfo,
1307                         domain_info->trusted_domain_count);
1308                 NT_STATUS_HAVE_NO_MEMORY(domain_info->trusted_domains);
1309
1310                 for (i=0;i<ret3;i++) {
1311                         status = fill_one_domain_info(mem_ctx,
1312                                 dce_call->conn->dce_ctx->lp_ctx,
1313                                 sam_ctx, res3[i],
1314                                 &domain_info->trusted_domains[i],
1315                                 false, true);
1316                         NT_STATUS_NOT_OK_RETURN(status);
1317                 }
1318
1319                 status = fill_one_domain_info(mem_ctx,
1320                         dce_call->conn->dce_ctx->lp_ctx, sam_ctx, res2[0],
1321                         &domain_info->trusted_domains[i], true, true);
1322                 NT_STATUS_NOT_OK_RETURN(status);
1323
1324                 /* Sets the supported encryption types */
1325                 domain_info->supported_enc_types = samdb_result_uint(res1[0],
1326                         "msDS-SupportedEncryptionTypes",
1327                         default_supported_enc_types);
1328
1329                 /* Other host domain informations */
1330
1331                 lsa_policy_info = talloc(mem_ctx,
1332                         struct netr_LsaPolicyInformation);
1333                 NT_STATUS_HAVE_NO_MEMORY(lsa_policy_info);
1334                 ZERO_STRUCTP(lsa_policy_info);
1335
1336                 domain_info->lsa_policy = *lsa_policy_info;
1337
1338                 domain_info->dns_hostname.string = old_dns_hostname;
1339                 domain_info->workstation_flags =
1340                         r->in.query->workstation_info->workstation_flags;
1341
1342                 r->out.info->domain_info = domain_info;
1343         break;
1344         case 2: /* LSA policy information - not used at the moment */
1345                 lsa_policy_info = talloc(mem_ctx,
1346                         struct netr_LsaPolicyInformation);
1347                 NT_STATUS_HAVE_NO_MEMORY(lsa_policy_info);
1348                 ZERO_STRUCTP(lsa_policy_info);
1349
1350                 r->out.info->lsa_policy_info = lsa_policy_info;
1351         break;
1352         default:
1353                 return NT_STATUS_INVALID_LEVEL;
1354         break;
1355         }
1356
1357         return NT_STATUS_OK;
1358 }
1359
1360
1361
1362 /*
1363   netr_ServerPasswordGet
1364 */
1365 static WERROR dcesrv_netr_ServerPasswordGet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1366                        struct netr_ServerPasswordGet *r)
1367 {
1368         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1369 }
1370
1371
1372 /* 
1373   netr_NETRLOGONSENDTOSAM 
1374 */
1375 static WERROR dcesrv_netr_NETRLOGONSENDTOSAM(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1376                        struct netr_NETRLOGONSENDTOSAM *r)
1377 {
1378         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1379 }
1380
1381
1382 /* 
1383   netr_DsRAddressToSitenamesW 
1384 */
1385 static WERROR dcesrv_netr_DsRAddressToSitenamesW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1386                        struct netr_DsRAddressToSitenamesW *r)
1387 {
1388         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1389 }
1390
1391
1392 /* 
1393   netr_DsRGetDCNameEx2
1394 */
1395 static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1396                                    struct netr_DsRGetDCNameEx2 *r)
1397 {
1398         const char * const attrs[] = { "objectGUID", NULL };
1399         struct ldb_context *sam_ctx;
1400         struct ldb_message **res;
1401         struct ldb_dn *domain_dn;
1402         int ret;
1403         struct netr_DsRGetDCNameInfo *info;
1404
1405         ZERO_STRUCTP(r->out.info);
1406
1407         sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
1408         if (sam_ctx == NULL) {
1409                 return WERR_DS_UNAVAILABLE;
1410         }
1411
1412         /* Windows 7 sends the domain name in the form the user typed, so we
1413          * have to cope  with both the short and long form here */
1414         if (r->in.domain_name != NULL &&
1415                         !lp_is_my_domain_or_realm(dce_call->conn->dce_ctx->lp_ctx,
1416                                                   r->in.domain_name)) {
1417                 return WERR_NO_SUCH_DOMAIN;
1418         }
1419
1420         domain_dn = ldb_get_default_basedn(sam_ctx);
1421         if (domain_dn == NULL) {
1422                 return WERR_DS_UNAVAILABLE;
1423         }
1424
1425         ret = gendb_search_dn(sam_ctx, mem_ctx,
1426                               domain_dn, &res, attrs);
1427         if (ret != 1) {
1428                 return WERR_GENERAL_FAILURE;
1429         }
1430
1431         info = talloc(mem_ctx, struct netr_DsRGetDCNameInfo);
1432         W_ERROR_HAVE_NO_MEMORY(info);
1433
1434         /* TODO: - return real IP address
1435          *       - check all r->in.* parameters (server_unc is ignored by w2k3!)
1436          */
1437         info->dc_unc                    = talloc_asprintf(mem_ctx, "\\\\%s.%s",
1438                                                           lp_netbios_name(dce_call->conn->dce_ctx->lp_ctx), 
1439                                                           lp_dnsdomain(dce_call->conn->dce_ctx->lp_ctx));
1440         W_ERROR_HAVE_NO_MEMORY(info->dc_unc);
1441         info->dc_address                = talloc_strdup(mem_ctx, "\\\\0.0.0.0");
1442         W_ERROR_HAVE_NO_MEMORY(info->dc_address);
1443         info->dc_address_type           = DS_ADDRESS_TYPE_INET;
1444         info->domain_guid               = samdb_result_guid(res[0], "objectGUID");
1445         info->domain_name               = lp_dnsdomain(dce_call->conn->dce_ctx->lp_ctx);
1446         info->forest_name               = lp_dnsdomain(dce_call->conn->dce_ctx->lp_ctx);
1447         info->dc_flags                  = DS_DNS_FOREST_ROOT |
1448                                           DS_DNS_DOMAIN |
1449                                           DS_DNS_CONTROLLER |
1450                                           DS_SERVER_WRITABLE |
1451                                           DS_SERVER_CLOSEST |
1452                                           DS_SERVER_TIMESERV |
1453                                           DS_SERVER_KDC |
1454                                           DS_SERVER_DS |
1455                                           DS_SERVER_LDAP |
1456                                           DS_SERVER_GC |
1457                                           DS_SERVER_PDC;
1458         info->dc_site_name      = samdb_server_site_name(sam_ctx, mem_ctx);
1459         W_ERROR_HAVE_NO_MEMORY(info->dc_site_name);
1460         /* FIXME: Hardcoded site name */
1461         info->client_site_name  = talloc_strdup(mem_ctx, "Default-First-Site-Name");
1462         W_ERROR_HAVE_NO_MEMORY(info->client_site_name);
1463
1464         *r->out.info = info;
1465
1466         return WERR_OK;
1467 }
1468
1469 /* 
1470   netr_DsRGetDCNameEx
1471 */
1472 static WERROR dcesrv_netr_DsRGetDCNameEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1473                                   struct netr_DsRGetDCNameEx *r)
1474 {
1475         struct netr_DsRGetDCNameEx2 r2;
1476         WERROR werr;
1477
1478         ZERO_STRUCT(r2);
1479
1480         r2.in.server_unc = r->in.server_unc;
1481         r2.in.client_account = NULL;
1482         r2.in.mask = 0;
1483         r2.in.domain_guid = r->in.domain_guid;
1484         r2.in.domain_name = r->in.domain_name;
1485         r2.in.site_name = r->in.site_name;
1486         r2.in.flags = r->in.flags;
1487         r2.out.info = r->out.info;
1488
1489         werr = dcesrv_netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1490
1491         return werr;
1492 }
1493
1494 /* 
1495   netr_DsRGetDCName
1496 */
1497 static WERROR dcesrv_netr_DsRGetDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1498                                 struct netr_DsRGetDCName *r)
1499 {
1500         struct netr_DsRGetDCNameEx2 r2;
1501         WERROR werr;
1502
1503         ZERO_STRUCT(r2);
1504
1505         r2.in.server_unc = r->in.server_unc;
1506         r2.in.client_account = NULL;
1507         r2.in.mask = 0;
1508         r2.in.domain_name = r->in.domain_name;
1509         r2.in.domain_guid = r->in.domain_guid;
1510         
1511         r2.in.site_name = NULL; /* should fill in from site GUID */
1512         r2.in.flags = r->in.flags;
1513         r2.out.info = r->out.info;
1514
1515         werr = dcesrv_netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1516
1517         return werr;
1518 }
1519 /* 
1520   netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN 
1521 */
1522 static WERROR dcesrv_netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1523                        struct netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN *r)
1524 {
1525         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1526 }
1527
1528
1529 /*
1530   netr_NetrEnumerateTrustedDomainsEx
1531 */
1532 static WERROR dcesrv_netr_NetrEnumerateTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1533                        struct netr_NetrEnumerateTrustedDomainsEx *r)
1534 {
1535         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1536 }
1537
1538
1539 /* 
1540   netr_DsRAddressToSitenamesExW 
1541 */
1542 static WERROR dcesrv_netr_DsRAddressToSitenamesExW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1543                                                    struct netr_DsRAddressToSitenamesExW *r)
1544 {
1545         struct netr_DsRAddressToSitenamesExWCtr *ctr;
1546         int i;
1547
1548         /* we should map the provided IPs to site names, once we have
1549          * sites support
1550          */
1551         ctr = talloc(mem_ctx, struct netr_DsRAddressToSitenamesExWCtr);
1552         W_ERROR_HAVE_NO_MEMORY(ctr);
1553
1554         *r->out.ctr = ctr;
1555
1556         ctr->count = r->in.count;
1557         ctr->sitename = talloc_array(ctr, struct lsa_String, ctr->count);
1558         W_ERROR_HAVE_NO_MEMORY(ctr->sitename);
1559         ctr->subnetname = talloc_array(ctr, struct lsa_String, ctr->count);
1560         W_ERROR_HAVE_NO_MEMORY(ctr->subnetname);
1561
1562         for (i=0; i<ctr->count; i++) {
1563                 /* FIXME: Hardcoded site name */
1564                 ctr->sitename[i].string   = "Default-First-Site-Name";
1565                 ctr->subnetname[i].string = NULL;
1566         }
1567
1568         return WERR_OK;
1569 }
1570
1571
1572 /* 
1573   netr_DsrGetDcSiteCoverageW
1574 */
1575 static WERROR dcesrv_netr_DsrGetDcSiteCoverageW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1576                        struct netr_DsrGetDcSiteCoverageW *r)
1577 {
1578         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1579 }
1580
1581
1582 /* 
1583   netr_DsrEnumerateDomainTrusts 
1584 */
1585 static WERROR dcesrv_netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1586                                               struct netr_DsrEnumerateDomainTrusts *r)
1587 {
1588         struct netr_DomainTrustList *trusts;
1589         struct ldb_context *sam_ctx;
1590         int ret;
1591         struct ldb_message **dom_res;
1592         const char * const dom_attrs[] = { "objectSid", "objectGUID", NULL };
1593
1594         ZERO_STRUCT(r->out);
1595
1596         sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
1597         if (sam_ctx == NULL) {
1598                 return WERR_GENERAL_FAILURE;
1599         }
1600
1601         ret = gendb_search_dn(sam_ctx, mem_ctx, NULL,
1602                               &dom_res, dom_attrs);
1603         if (ret != 1) {
1604                 return WERR_GENERAL_FAILURE;
1605         }
1606
1607         trusts = talloc(mem_ctx, struct netr_DomainTrustList);
1608         W_ERROR_HAVE_NO_MEMORY(trusts);
1609
1610         trusts->array = talloc_array(trusts, struct netr_DomainTrust, ret);
1611         W_ERROR_HAVE_NO_MEMORY(trusts->array);
1612
1613         trusts->count = 1; /* ?? */
1614
1615         r->out.trusts = trusts;
1616
1617         /* TODO: add filtering by trust_flags, and correct trust_type
1618            and attributes */
1619         trusts->array[0].netbios_name = lp_sam_name(dce_call->conn->dce_ctx->lp_ctx);
1620         trusts->array[0].dns_name     = lp_dnsdomain(dce_call->conn->dce_ctx->lp_ctx);
1621         trusts->array[0].trust_flags =
1622                 NETR_TRUST_FLAG_TREEROOT | 
1623                 NETR_TRUST_FLAG_IN_FOREST | 
1624                 NETR_TRUST_FLAG_PRIMARY;
1625         trusts->array[0].parent_index = 0;
1626         trusts->array[0].trust_type = 2;
1627         trusts->array[0].trust_attributes = 0;
1628         trusts->array[0].sid  = samdb_result_dom_sid(mem_ctx, dom_res[0], "objectSid");
1629         trusts->array[0].guid = samdb_result_guid(dom_res[0], "objectGUID");
1630
1631         return WERR_OK;
1632 }
1633
1634
1635 /*
1636   netr_DsrDeregisterDNSHostRecords
1637 */
1638 static WERROR dcesrv_netr_DsrDeregisterDNSHostRecords(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1639                        struct netr_DsrDeregisterDNSHostRecords *r)
1640 {
1641         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1642 }
1643
1644
1645 /*
1646   netr_ServerTrustPasswordsGet
1647 */
1648 static NTSTATUS dcesrv_netr_ServerTrustPasswordsGet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1649                        struct netr_ServerTrustPasswordsGet *r)
1650 {
1651         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1652 }
1653
1654
1655 /* 
1656   netr_DsRGetForestTrustInformation 
1657 */
1658 static WERROR dcesrv_netr_DsRGetForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1659                        struct netr_DsRGetForestTrustInformation *r)
1660 {
1661         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1662 }
1663
1664
1665 /*
1666   netr_GetForestTrustInformation
1667 */
1668 static WERROR dcesrv_netr_GetForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1669                        struct netr_GetForestTrustInformation *r)
1670 {
1671         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1672 }
1673
1674
1675 /*
1676   netr_ServerGetTrustInfo
1677 */
1678 static NTSTATUS dcesrv_netr_ServerGetTrustInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1679                        struct netr_ServerGetTrustInfo *r)
1680 {
1681         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1682 }
1683
1684
1685 /* include the generated boilerplate */
1686 #include "librpc/gen_ndr/ndr_netlogon_s.c"