r11137: Compile with only 2 warnings (I'm still working on that code) on a gcc4
[ira/wip.git] / source3 / rpc_client / cli_netlogon.c
1 /* 
2    Unix SMB/CIFS implementation.
3    NT Domain Authentication SMB / MSRPC client
4    Copyright (C) Andrew Tridgell 1992-2000
5    Copyright (C) Jeremy Allison                    1998.
6    Largely re-written by Jeremy Allison (C)        2005.
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #include "includes.h"
24
25 /* LSA Request Challenge. Sends our challenge to server, then gets
26    server response. These are used to generate the credentials.
27  The sent and received challenges are stored in the netlog pipe
28  private data. Only call this via rpccli_netlogon_setup_creds(). JRA.
29 */
30
31 static NTSTATUS rpccli_net_req_chal(struct rpc_pipe_client *cli,
32                                 TALLOC_CTX *mem_ctx,
33                                 const char *server_name,
34                                 const char *clnt_name,
35                                 const DOM_CHAL *clnt_chal_in,
36                                 DOM_CHAL *srv_chal_out)
37 {
38         prs_struct qbuf, rbuf;
39         NET_Q_REQ_CHAL q;
40         NET_R_REQ_CHAL r;
41         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
42
43         /* create and send a MSRPC command with api NET_REQCHAL */
44
45         DEBUG(4,("cli_net_req_chal: LSA Request Challenge from %s to %s\n",
46                 clnt_name, server_name));
47         
48         /* store the parameters */
49         init_q_req_chal(&q, server_name, clnt_name, clnt_chal_in);
50
51         /* Marshall data and send request */
52         CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_REQCHAL,
53                 q, r,
54                 qbuf, rbuf,
55                 net_io_q_req_chal,
56                 net_io_r_req_chal,
57                 NT_STATUS_UNSUCCESSFUL);
58
59         result = r.status;
60
61         /* Return result */
62
63         if (NT_STATUS_IS_OK(result)) {
64                 /* Store the returned server challenge. */
65                 *srv_chal_out = r.srv_chal;
66         }
67
68         return result;
69 }
70
71 #if 0
72 /****************************************************************************
73 LSA Authenticate 2
74
75 Send the client credential, receive back a server credential.
76 Ensure that the server credential returned matches the session key 
77 encrypt of the server challenge originally received. JRA.
78 ****************************************************************************/
79
80   NTSTATUS rpccli_net_auth2(struct rpc_pipe_client *cli, 
81                        uint16 sec_chan, 
82                        uint32 *neg_flags, DOM_CHAL *srv_chal)
83 {
84         prs_struct qbuf, rbuf;
85         NET_Q_AUTH_2 q;
86         NET_R_AUTH_2 r;
87         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
88         fstring machine_acct;
89
90         if ( sec_chan == SEC_CHAN_DOMAIN )
91                 fstr_sprintf( machine_acct, "%s$", lp_workgroup() );
92         else
93                 fstrcpy( machine_acct, cli->mach_acct );
94         
95         /* create and send a MSRPC command with api NET_AUTH2 */
96
97         DEBUG(4,("cli_net_auth2: srv:%s acct:%s sc:%x mc: %s chal %s neg: %x\n",
98                  cli->srv_name_slash, machine_acct, sec_chan, global_myname(),
99                  credstr(cli->clnt_cred.challenge.data), *neg_flags));
100
101         /* store the parameters */
102
103         init_q_auth_2(&q, cli->srv_name_slash, machine_acct, 
104                       sec_chan, global_myname(), &cli->clnt_cred.challenge, 
105                       *neg_flags);
106
107         /* turn parameters into data stream */
108
109         CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_AUTH2,
110                 q, r,
111                 qbuf, rbuf,
112                 net_io_q_auth_2,
113                 net_io_r_auth_2,
114                 NT_STATUS_UNSUCCESSFUL);
115
116         result = r.status;
117
118         if (NT_STATUS_IS_OK(result)) {
119                 UTIME zerotime;
120                 
121                 /*
122                  * Check the returned value using the initial
123                  * server received challenge.
124                  */
125
126                 zerotime.time = 0;
127                 if (cred_assert( &r.srv_chal, cli->sess_key, srv_chal, zerotime) == 0) {
128
129                         /*
130                          * Server replied with bad credential. Fail.
131                          */
132                         DEBUG(0,("cli_net_auth2: server %s replied with bad credential (bad machine \
133 password ?).\n", cli->cli->desthost ));
134                         return NT_STATUS_ACCESS_DENIED;
135                 }
136                 *neg_flags = r.srv_flgs.neg_flags;
137         }
138
139         return result;
140 }
141 #endif
142
143 /****************************************************************************
144  LSA Authenticate 2
145
146  Send the client credential, receive back a server credential.
147  The caller *must* ensure that the server credential returned matches the session key 
148  encrypt of the server challenge originally received. JRA.
149 ****************************************************************************/
150
151 static NTSTATUS rpccli_net_auth2(struct rpc_pipe_client *cli,
152                         TALLOC_CTX *mem_ctx,
153                         const char *server_name,
154                         const char *account_name,
155                         uint16 sec_chan_type,
156                         const char *computer_name,
157                         uint32 *neg_flags_inout,
158                         const DOM_CHAL *clnt_chal_in,
159                         DOM_CHAL *srv_chal_out)
160 {
161         prs_struct qbuf, rbuf;
162         NET_Q_AUTH_2 q;
163         NET_R_AUTH_2 r;
164         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
165
166         /* create and send a MSRPC command with api NET_AUTH2 */
167
168         DEBUG(4,("cli_net_auth2: srv:%s acct:%s sc:%x mc: %s neg: %x\n",
169                  server_name, account_name, sec_chan_type, computer_name,
170                  *neg_flags_inout));
171
172         /* store the parameters */
173
174         init_q_auth_2(&q, server_name, account_name, sec_chan_type,
175                       computer_name, clnt_chal_in, *neg_flags_inout);
176
177         /* turn parameters into data stream */
178
179         CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_AUTH2,
180                 q, r,
181                 qbuf, rbuf,
182                 net_io_q_auth_2,
183                 net_io_r_auth_2,
184                 NT_STATUS_UNSUCCESSFUL);
185
186         result = r.status;
187
188         if (NT_STATUS_IS_OK(result)) {
189                 *srv_chal_out = r.srv_chal;
190                 *neg_flags_inout = r.srv_flgs.neg_flags;
191         }
192
193         return result;
194 }
195
196 #if 0   /* not currebntly used */
197 /****************************************************************************
198  LSA Authenticate 3
199
200  Send the client credential, receive back a server credential.
201  The caller *must* ensure that the server credential returned matches the session key 
202  encrypt of the server challenge originally received. JRA.
203 ****************************************************************************/
204
205 static NTSTATUS rpccli_net_auth3(struct rpc_pipe_client *cli, 
206                         TALLOC_CTX *mem_ctx,
207                         const char *server_name,
208                         const char *account_name,
209                         uint16 sec_chan_type,
210                         const char *computer_name,
211                         uint32 *neg_flags_inout,
212                         const DOM_CHAL *clnt_chal_in,
213                         DOM_CHAL *srv_chal_out)
214 {
215         prs_struct qbuf, rbuf;
216         NET_Q_AUTH_3 q;
217         NET_R_AUTH_3 r;
218         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
219
220         /* create and send a MSRPC command with api NET_AUTH2 */
221
222         DEBUG(4,("cli_net_auth3: srv:%s acct:%s sc:%x mc: %s chal %s neg: %x\n",
223                 server_name, account_name, sec_chan_type, computer_name,
224                 credstr(clnt_chal_in->data), *neg_flags_inout));
225
226         /* store the parameters */
227         init_q_auth_3(&q, server_name, account_name, sec_chan_type,
228                         computer_name, clnt_chal_in, *neg_flags_inout);
229
230         /* turn parameters into data stream */
231
232         CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_AUTH3,
233                 q, r,
234                 qbuf, rbuf,
235                 net_io_q_auth_3,
236                 net_io_r_auth_3,
237                 NT_STATUS_UNSUCCESSFUL);
238
239         if (NT_STATUS_IS_OK(result)) {
240                 *srv_chal_out = r.srv_chal;
241                 *neg_flags_inout = r.srv_flgs.neg_flags;
242         }
243
244         return result;
245 }
246 #endif  /* not currebntly used */
247
248 /****************************************************************************
249  Wrapper function that uses the auth and auth2 calls to set up a NETLOGON
250  credentials chain. Stores the credentials in the struct dcinfo in the
251  netlogon pipe struct.
252 ****************************************************************************/
253
254 NTSTATUS rpccli_netlogon_setup_creds(struct rpc_pipe_client *cli,
255                                 const char *server_name,
256                                 const char *domain,
257                                 const char *machine_account,
258                                 const unsigned char machine_pwd[16],
259                                 uint32 sec_chan_type,
260                                 uint32 *neg_flags_inout)
261 {
262         NTSTATUS result;
263         DOM_CHAL clnt_chal_send;
264         DOM_CHAL srv_chal_recv;
265         struct dcinfo *dc;
266
267         SMB_ASSERT(cli->pipe_idx == PI_NETLOGON);
268
269         dc = cli->dc;
270         if (!dc) {
271                 return NT_STATUS_INVALID_PARAMETER;
272         }
273
274         /* Ensure we don't reuse any of this state. */
275         ZERO_STRUCTP(dc);
276
277         /* Store the machine account password we're going to use. */
278         memcpy(dc->mach_pw, machine_pwd, 16);
279
280         fstrcpy(dc->remote_machine, "\\\\");
281         fstrcat(dc->remote_machine, server_name);
282
283         fstrcpy(dc->domain, domain);
284
285         fstr_sprintf( dc->mach_acct, "%s$", machine_account);
286
287         /* Create the client challenge. */
288         generate_random_buffer(clnt_chal_send.data, 8);
289
290         /* Get the server challenge. */
291         result = rpccli_net_req_chal(cli,
292                                 cli->mem_ctx,
293                                 dc->remote_machine,
294                                 machine_account,
295                                 &clnt_chal_send,
296                                 &srv_chal_recv);
297
298         if (!NT_STATUS_IS_OK(result)) {
299                 return result;
300         }
301
302         /* Calculate the session key and client credentials */
303         creds_client_init(dc,
304                         &clnt_chal_send,
305                         &srv_chal_recv,
306                         machine_pwd,
307                         &clnt_chal_send);
308
309         /*  
310          * Send client auth-2 challenge and receive server repy.
311          */
312
313         result = rpccli_net_auth2(cli,
314                         cli->mem_ctx,
315                         dc->remote_machine,
316                         dc->mach_acct,
317                         sec_chan_type,
318                         machine_account,
319                         neg_flags_inout,
320                         &clnt_chal_send, /* input. */
321                         &srv_chal_recv); /* output */
322
323         if (!NT_STATUS_IS_OK(result)) {
324                 return result;
325         }
326
327         /*
328          * Check the returned value using the initial
329          * server received challenge.
330          */
331
332         if (!creds_client_check(dc, &srv_chal_recv)) {
333                 /*
334                  * Server replied with bad credential. Fail.
335                  */
336                 DEBUG(0,("rpccli_netlogon_setup_creds: server %s "
337                         "replied with bad credential\n",
338                         cli->cli->desthost ));
339                 return NT_STATUS_ACCESS_DENIED;
340         }
341
342         DEBUG(5,("rpccli_netlogon_setup_creds: server %s credential "
343                 "chain established.\n",
344                 cli->cli->desthost ));
345
346         return NT_STATUS_OK;
347 }
348
349 /* Logon Control 2 */
350
351 NTSTATUS rpccli_netlogon_logon_ctrl2(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
352                                   uint32 query_level)
353 {
354         prs_struct qbuf, rbuf;
355         NET_Q_LOGON_CTRL2 q;
356         NET_R_LOGON_CTRL2 r;
357         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
358         fstring server;
359
360         ZERO_STRUCT(q);
361         ZERO_STRUCT(r);
362
363         /* Initialise input parameters */
364
365         slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
366         init_net_q_logon_ctrl2(&q, server, query_level);
367
368         /* Marshall data and send request */
369
370         CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_LOGON_CTRL2,
371                 q, r,
372                 qbuf, rbuf,
373                 net_io_q_logon_ctrl2,
374                 net_io_r_logon_ctrl2,
375                 NT_STATUS_UNSUCCESSFUL);
376
377         result = r.status;
378         return result;
379 }
380
381 /* GetDCName */
382
383 NTSTATUS rpccli_netlogon_getdcname(struct rpc_pipe_client *cli,
384                                    TALLOC_CTX *mem_ctx, const char *mydcname,
385                                    const char *domainname, fstring newdcname)
386 {
387         prs_struct qbuf, rbuf;
388         NET_Q_GETDCNAME q;
389         NET_R_GETDCNAME r;
390         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
391
392         ZERO_STRUCT(q);
393         ZERO_STRUCT(r);
394
395         /* Initialise input parameters */
396
397         init_net_q_getdcname(&q, mydcname, domainname);
398
399         /* Marshall data and send request */
400
401         CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_GETDCNAME,
402                 q, r,
403                 qbuf, rbuf,
404                 net_io_q_getdcname,
405                 net_io_r_getdcname,
406                 NT_STATUS_UNSUCCESSFUL);
407
408         if (NT_STATUS_IS_OK(result)) {
409                 rpcstr_pull_unistr2_fstring(newdcname, &r.uni_dcname);
410         }
411
412         return result;
413 }
414
415 /* Sam synchronisation */
416
417 NTSTATUS rpccli_netlogon_sam_sync(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
418                                uint32 database_id, uint32 next_rid, uint32 *num_deltas,
419                                SAM_DELTA_HDR **hdr_deltas, 
420                                SAM_DELTA_CTR **deltas)
421 {
422         prs_struct qbuf, rbuf;
423         NET_Q_SAM_SYNC q;
424         NET_R_SAM_SYNC r;
425         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
426         DOM_CRED clnt_creds;
427         DOM_CRED ret_creds;
428
429         ZERO_STRUCT(q);
430         ZERO_STRUCT(r);
431
432         ZERO_STRUCT(ret_creds);
433
434         /* Initialise input parameters */
435
436         creds_client_step(cli->dc, &clnt_creds);
437
438         prs_set_session_key(&qbuf, (const char *)cli->dc->sess_key);
439         prs_set_session_key(&rbuf, (const char *)cli->dc->sess_key);
440
441         init_net_q_sam_sync(&q, cli->dc->remote_machine, global_myname(),
442                             &clnt_creds, &ret_creds, database_id, next_rid);
443
444         /* Marshall data and send request */
445
446         CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_SAM_SYNC,
447                 q, r,
448                 qbuf, rbuf,
449                 net_io_q_sam_sync,
450                 net_io_r_sam_sync,
451                 NT_STATUS_UNSUCCESSFUL);
452
453         /* Return results */
454
455         result = r.status;
456         *num_deltas = r.num_deltas2;
457         *hdr_deltas = r.hdr_deltas;
458         *deltas = r.deltas;
459
460         if (!NT_STATUS_IS_ERR(result)) {
461                 /* Check returned credentials. */
462                 if (!creds_client_check(cli->dc, &r.srv_creds.challenge)) {
463                         DEBUG(0,("cli_netlogon_sam_sync: credentials chain check failed\n"));
464                         return NT_STATUS_ACCESS_DENIED;
465                 }
466         }
467
468         return result;
469 }
470
471 /* Sam synchronisation */
472
473 NTSTATUS rpccli_netlogon_sam_deltas(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
474                                  uint32 database_id, UINT64_S seqnum,
475                                  uint32 *num_deltas, 
476                                  SAM_DELTA_HDR **hdr_deltas, 
477                                  SAM_DELTA_CTR **deltas)
478 {
479         prs_struct qbuf, rbuf;
480         NET_Q_SAM_DELTAS q;
481         NET_R_SAM_DELTAS r;
482         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
483         DOM_CRED clnt_creds;
484
485         ZERO_STRUCT(q);
486         ZERO_STRUCT(r);
487
488         /* Initialise input parameters */
489
490         creds_client_step(cli->dc, &clnt_creds);
491
492         init_net_q_sam_deltas(&q, cli->dc->remote_machine,
493                               global_myname(), &clnt_creds, 
494                               database_id, seqnum);
495
496         /* Marshall data and send request */
497
498         CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_SAM_DELTAS,
499                 q, r,
500                 qbuf, rbuf,
501                 net_io_q_sam_deltas,
502                 net_io_r_sam_deltas,
503                 NT_STATUS_UNSUCCESSFUL);
504
505         /* Return results */
506
507         result = r.status;
508         *num_deltas = r.num_deltas2;
509         *hdr_deltas = r.hdr_deltas;
510         *deltas = r.deltas;
511
512         if (!NT_STATUS_IS_ERR(result)) {
513                 /* Check returned credentials. */
514                 if (!creds_client_check(cli->dc, &r.srv_creds.challenge)) {
515                         DEBUG(0,("cli_netlogon_sam_sync: credentials chain check failed\n"));
516                         return NT_STATUS_ACCESS_DENIED;
517                 }
518         }
519
520         return result;
521 }
522
523 /* Logon domain user */
524
525 NTSTATUS rpccli_netlogon_sam_logon(struct rpc_pipe_client *cli,
526                                 TALLOC_CTX *mem_ctx,
527                                 const char *domain,
528                                 const char *username,
529                                 const char *password,
530                                 int logon_type)
531 {
532         prs_struct qbuf, rbuf;
533         NET_Q_SAM_LOGON q;
534         NET_R_SAM_LOGON r;
535         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
536         DOM_CRED clnt_creds;
537         DOM_CRED ret_creds;
538         NET_ID_INFO_CTR ctr;
539         NET_USER_INFO_3 user;
540         int validation_level = 3;
541         fstring clnt_name_slash;
542
543         ZERO_STRUCT(q);
544         ZERO_STRUCT(r);
545         ZERO_STRUCT(ret_creds);
546
547         fstr_sprintf( clnt_name_slash, "\\\\%s", global_myname() );
548
549         /* Initialise input parameters */
550
551         creds_client_step(cli->dc, &clnt_creds);
552
553         q.validation_level = validation_level;
554
555         ctr.switch_value = logon_type;
556
557         switch (logon_type) {
558         case INTERACTIVE_LOGON_TYPE: {
559                 unsigned char lm_owf_user_pwd[16], nt_owf_user_pwd[16];
560
561                 nt_lm_owf_gen(password, nt_owf_user_pwd, lm_owf_user_pwd);
562
563                 init_id_info1(&ctr.auth.id1, domain, 
564                               0, /* param_ctrl */
565                               0xdead, 0xbeef, /* LUID? */
566                               username, clnt_name_slash,
567                               (const char *)cli->dc->sess_key, lm_owf_user_pwd,
568                               nt_owf_user_pwd);
569
570                 break;
571         }
572         case NET_LOGON_TYPE: {
573                 uint8 chal[8];
574                 unsigned char local_lm_response[24];
575                 unsigned char local_nt_response[24];
576
577                 generate_random_buffer(chal, 8);
578
579                 SMBencrypt(password, chal, local_lm_response);
580                 SMBNTencrypt(password, chal, local_nt_response);
581
582                 init_id_info2(&ctr.auth.id2, domain, 
583                               0, /* param_ctrl */
584                               0xdead, 0xbeef, /* LUID? */
585                               username, clnt_name_slash, chal,
586                               local_lm_response, 24, local_nt_response, 24);
587                 break;
588         }
589         default:
590                 DEBUG(0, ("switch value %d not supported\n", 
591                           ctr.switch_value));
592                 return NT_STATUS_INVALID_INFO_CLASS;
593         }
594
595         r.user = &user;
596
597         init_sam_info(&q.sam_id, cli->dc->remote_machine, global_myname(),
598                       &clnt_creds, &ret_creds, logon_type,
599                       &ctr);
600
601         /* Marshall data and send request */
602
603         CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_SAMLOGON,
604                 q, r,
605                 qbuf, rbuf,
606                 net_io_q_sam_logon,
607                 net_io_r_sam_logon,
608                 NT_STATUS_UNSUCCESSFUL);
609
610         /* Return results */
611
612         result = r.status;
613
614         if (r.buffer_creds) {
615                 /* Check returned credentials if present. */
616                 if (!creds_client_check(cli->dc, &r.srv_creds.challenge)) {
617                         DEBUG(0,("rpccli_netlogon_sam_logon: credentials chain check failed\n"));
618                         return NT_STATUS_ACCESS_DENIED;
619                 }
620         }
621
622         return result;
623 }
624
625
626 /** 
627  * Logon domain user with an 'network' SAM logon 
628  *
629  * @param info3 Pointer to a NET_USER_INFO_3 already allocated by the caller.
630  **/
631
632 NTSTATUS rpccli_netlogon_sam_network_logon(struct rpc_pipe_client *cli,
633                                            TALLOC_CTX *mem_ctx,
634                                            const char *server,
635                                            const char *username,
636                                            const char *domain,
637                                            const char *workstation, 
638                                            const uint8 chal[8], 
639                                            DATA_BLOB lm_response,
640                                            DATA_BLOB nt_response,
641                                            NET_USER_INFO_3 *info3)
642 {
643         prs_struct qbuf, rbuf;
644         NET_Q_SAM_LOGON q;
645         NET_R_SAM_LOGON r;
646         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
647         NET_ID_INFO_CTR ctr;
648         int validation_level = 3;
649         const char *workstation_name_slash;
650         const char *server_name_slash;
651         static uint8 zeros[16];
652         DOM_CRED clnt_creds;
653         DOM_CRED ret_creds;
654         int i;
655         
656         ZERO_STRUCT(q);
657         ZERO_STRUCT(r);
658         ZERO_STRUCT(ret_creds);
659
660         creds_client_step(cli->dc, &clnt_creds);
661
662         if (server[0] != '\\' && server[1] != '\\') {
663                 server_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", server);
664         } else {
665                 server_name_slash = server;
666         }
667
668         if (workstation[0] != '\\' && workstation[1] != '\\') {
669                 workstation_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", workstation);
670         } else {
671                 workstation_name_slash = workstation;
672         }
673
674         if (!workstation_name_slash || !server_name_slash) {
675                 DEBUG(0, ("talloc_asprintf failed!\n"));
676                 return NT_STATUS_NO_MEMORY;
677         }
678
679         /* Initialise input parameters */
680
681         q.validation_level = validation_level;
682
683         ctr.switch_value = NET_LOGON_TYPE;
684
685         init_id_info2(&ctr.auth.id2, domain,
686                       0, /* param_ctrl */
687                       0xdead, 0xbeef, /* LUID? */
688                       username, workstation_name_slash, (const uchar*)chal,
689                       lm_response.data, lm_response.length, nt_response.data, nt_response.length);
690  
691         init_sam_info(&q.sam_id, server_name_slash, global_myname(),
692                       &clnt_creds, &ret_creds, NET_LOGON_TYPE,
693                       &ctr);
694
695         r.user = info3;
696
697         /* Marshall data and send request */
698
699         CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_SAMLOGON,
700                 q, r,
701                 qbuf, rbuf,
702                 net_io_q_sam_logon,
703                 net_io_r_sam_logon,
704                 NT_STATUS_UNSUCCESSFUL);
705
706         if (memcmp(zeros, info3->user_sess_key, 16) != 0) {
707                 SamOEMhash(info3->user_sess_key, cli->dc->sess_key, 16);
708         } else {
709                 memset(info3->user_sess_key, '\0', 16);
710         }
711
712         if (memcmp(zeros, info3->lm_sess_key, 8) != 0) {
713                 SamOEMhash(info3->lm_sess_key, cli->dc->sess_key, 8);
714         } else {
715                 memset(info3->lm_sess_key, '\0', 8);
716         }
717
718         memset(&info3->acct_flags, '\0', 4);
719         for (i=0; i < 7; i++) {
720                 memset(&info3->unknown[i], '\0', 4);
721         }
722
723         /* Return results */
724
725         result = r.status;
726
727         if (r.buffer_creds) {
728                 /* Check returned credentials if present. */
729                 if (!creds_client_check(cli->dc, &r.srv_creds.challenge)) {
730                         DEBUG(0,("rpccli_netlogon_sam_network_logon: credentials chain check failed\n"));
731                         return NT_STATUS_ACCESS_DENIED;
732                 }
733         }
734
735         return result;
736 }
737
738 /***************************************************************************
739 LSA Server Password Set.
740 ****************************************************************************/
741
742 NTSTATUS rpccli_net_srv_pwset(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, 
743                            const char *machine_name, const uint8 hashed_mach_pwd[16])
744 {
745         prs_struct rbuf;
746         prs_struct qbuf; 
747         DOM_CRED clnt_creds;
748         NET_Q_SRV_PWSET q;
749         NET_R_SRV_PWSET r;
750         uint16 sec_chan_type = 2;
751         NTSTATUS result;
752
753         creds_client_step(cli->dc, &clnt_creds);
754         
755         DEBUG(4,("cli_net_srv_pwset: srv:%s acct:%s sc: %d mc: %s\n",
756                  cli->dc->remote_machine, cli->dc->mach_acct, sec_chan_type, machine_name));
757         
758         /* store the parameters */
759         init_q_srv_pwset(&q, cli->dc->remote_machine, (const char *)cli->dc->sess_key,
760                          cli->dc->mach_acct, sec_chan_type, machine_name, 
761                          &clnt_creds, hashed_mach_pwd);
762         
763         CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_SRVPWSET,
764                 q, r,
765                 qbuf, rbuf,
766                 net_io_q_srv_pwset,
767                 net_io_r_srv_pwset,
768                 NT_STATUS_UNSUCCESSFUL);
769
770         result = r.status;
771
772         if (!NT_STATUS_IS_OK(result)) {
773                 /* report error code */
774                 DEBUG(0,("cli_net_srv_pwset: %s\n", nt_errstr(result)));
775         }
776
777         /* Always check returned credentials. */
778         if (!creds_client_check(cli->dc, &r.srv_cred.challenge)) {
779                 DEBUG(0,("rpccli_net_srv_pwset: credentials chain check failed\n"));
780                 return NT_STATUS_ACCESS_DENIED;
781         }
782
783         return result;
784 }