r12018: more 3.0.21 changes. This is a full sync except for changes to rpc-server...
[Samba.git] / source / rpc_client / cli_netlogon.c
blobe3cc97cdc6b7e48fb24d8a0072fcc6272a00ea35
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.
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.
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.
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.
23 #include "includes.h"
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.
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)
38 prs_struct qbuf, rbuf;
39 NET_Q_REQ_CHAL q;
40 NET_R_REQ_CHAL r;
41 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
43 /* create and send a MSRPC command with api NET_REQCHAL */
45 DEBUG(4,("cli_net_req_chal: LSA Request Challenge from %s to %s\n",
46 clnt_name, server_name));
48 /* store the parameters */
49 init_q_req_chal(&q, server_name, clnt_name, clnt_chal_in);
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);
59 result = r.status;
61 /* Return result */
63 if (NT_STATUS_IS_OK(result)) {
64 /* Store the returned server challenge. */
65 *srv_chal_out = r.srv_chal;
68 return result;
71 #if 0
72 /****************************************************************************
73 LSA Authenticate 2
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 ****************************************************************************/
80 NTSTATUS rpccli_net_auth2(struct rpc_pipe_client *cli,
81 uint16 sec_chan,
82 uint32 *neg_flags, DOM_CHAL *srv_chal)
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;
90 if ( sec_chan == SEC_CHAN_DOMAIN )
91 fstr_sprintf( machine_acct, "%s$", lp_workgroup() );
92 else
93 fstrcpy( machine_acct, cli->mach_acct );
95 /* create and send a MSRPC command with api NET_AUTH2 */
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));
101 /* store the parameters */
103 init_q_auth_2(&q, cli->srv_name_slash, machine_acct,
104 sec_chan, global_myname(), &cli->clnt_cred.challenge,
105 *neg_flags);
107 /* turn parameters into data stream */
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);
116 result = r.status;
118 if (NT_STATUS_IS_OK(result)) {
119 UTIME zerotime;
122 * Check the returned value using the initial
123 * server received challenge.
126 zerotime.time = 0;
127 if (cred_assert( &r.srv_chal, cli->sess_key, srv_chal, zerotime) == 0) {
130 * Server replied with bad credential. Fail.
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;
136 *neg_flags = r.srv_flgs.neg_flags;
139 return result;
141 #endif
143 /****************************************************************************
144 LSA Authenticate 2
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 ****************************************************************************/
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)
161 prs_struct qbuf, rbuf;
162 NET_Q_AUTH_2 q;
163 NET_R_AUTH_2 r;
164 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
166 /* create and send a MSRPC command with api NET_AUTH2 */
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));
172 /* store the parameters */
174 init_q_auth_2(&q, server_name, account_name, sec_chan_type,
175 computer_name, clnt_chal_in, *neg_flags_inout);
177 /* turn parameters into data stream */
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);
186 result = r.status;
188 if (NT_STATUS_IS_OK(result)) {
189 *srv_chal_out = r.srv_chal;
190 *neg_flags_inout = r.srv_flgs.neg_flags;
193 return result;
196 #if 0 /* not currebntly used */
197 /****************************************************************************
198 LSA Authenticate 3
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 ****************************************************************************/
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)
215 prs_struct qbuf, rbuf;
216 NET_Q_AUTH_3 q;
217 NET_R_AUTH_3 r;
218 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
220 /* create and send a MSRPC command with api NET_AUTH2 */
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));
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);
230 /* turn parameters into data stream */
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);
239 if (NT_STATUS_IS_OK(result)) {
240 *srv_chal_out = r.srv_chal;
241 *neg_flags_inout = r.srv_flgs.neg_flags;
244 return result;
246 #endif /* not currebntly used */
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 ****************************************************************************/
254 NTSTATUS rpccli_netlogon_setup_creds(struct rpc_pipe_client *cli,
255 const char *server_name,
256 const char *domain,
257 const char *clnt_name,
258 const char *machine_account,
259 const unsigned char machine_pwd[16],
260 uint32 sec_chan_type,
261 uint32 *neg_flags_inout)
263 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
264 DOM_CHAL clnt_chal_send;
265 DOM_CHAL srv_chal_recv;
266 struct dcinfo *dc;
268 SMB_ASSERT(cli->pipe_idx == PI_NETLOGON);
270 dc = cli->dc;
271 if (!dc) {
272 return NT_STATUS_INVALID_PARAMETER;
275 /* Ensure we don't reuse any of this state. */
276 ZERO_STRUCTP(dc);
278 /* Store the machine account password we're going to use. */
279 memcpy(dc->mach_pw, machine_pwd, 16);
281 fstrcpy(dc->remote_machine, "\\\\");
282 fstrcat(dc->remote_machine, server_name);
284 fstrcpy(dc->domain, domain);
286 fstr_sprintf( dc->mach_acct, "%s$", machine_account);
288 /* Create the client challenge. */
289 generate_random_buffer(clnt_chal_send.data, 8);
291 /* Get the server challenge. */
292 result = rpccli_net_req_chal(cli,
293 cli->mem_ctx,
294 dc->remote_machine,
295 clnt_name,
296 &clnt_chal_send,
297 &srv_chal_recv);
299 if (!NT_STATUS_IS_OK(result)) {
300 return result;
303 /* Calculate the session key and client credentials */
304 creds_client_init(dc,
305 &clnt_chal_send,
306 &srv_chal_recv,
307 machine_pwd,
308 &clnt_chal_send);
311 * Send client auth-2 challenge and receive server repy.
314 result = rpccli_net_auth2(cli,
315 cli->mem_ctx,
316 dc->remote_machine,
317 dc->mach_acct,
318 sec_chan_type,
319 clnt_name,
320 neg_flags_inout,
321 &clnt_chal_send, /* input. */
322 &srv_chal_recv); /* output */
324 if (!NT_STATUS_IS_OK(result)) {
325 return result;
329 * Check the returned value using the initial
330 * server received challenge.
333 if (!creds_client_check(dc, &srv_chal_recv)) {
335 * Server replied with bad credential. Fail.
337 DEBUG(0,("rpccli_netlogon_setup_creds: server %s "
338 "replied with bad credential\n",
339 cli->cli->desthost ));
340 return NT_STATUS_ACCESS_DENIED;
343 DEBUG(5,("rpccli_netlogon_setup_creds: server %s credential "
344 "chain established.\n",
345 cli->cli->desthost ));
347 return NT_STATUS_OK;
350 /* Logon Control 2 */
352 NTSTATUS rpccli_netlogon_logon_ctrl2(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
353 uint32 query_level)
355 prs_struct qbuf, rbuf;
356 NET_Q_LOGON_CTRL2 q;
357 NET_R_LOGON_CTRL2 r;
358 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
359 fstring server;
361 ZERO_STRUCT(q);
362 ZERO_STRUCT(r);
364 /* Initialise input parameters */
366 slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
367 init_net_q_logon_ctrl2(&q, server, query_level);
369 /* Marshall data and send request */
371 CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_LOGON_CTRL2,
372 q, r,
373 qbuf, rbuf,
374 net_io_q_logon_ctrl2,
375 net_io_r_logon_ctrl2,
376 NT_STATUS_UNSUCCESSFUL);
378 result = r.status;
379 return result;
382 /* GetDCName */
384 NTSTATUS rpccli_netlogon_getdcname(struct rpc_pipe_client *cli,
385 TALLOC_CTX *mem_ctx, const char *mydcname,
386 const char *domainname, fstring newdcname)
388 prs_struct qbuf, rbuf;
389 NET_Q_GETDCNAME q;
390 NET_R_GETDCNAME r;
391 NTSTATUS result;
392 fstring mydcname_slash;
394 ZERO_STRUCT(q);
395 ZERO_STRUCT(r);
397 /* Initialise input parameters */
399 slprintf(mydcname_slash, sizeof(fstring)-1, "\\\\%s", mydcname);
400 init_net_q_getdcname(&q, mydcname_slash, domainname);
402 /* Marshall data and send request */
404 CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_GETDCNAME,
405 q, r,
406 qbuf, rbuf,
407 net_io_q_getdcname,
408 net_io_r_getdcname,
409 NT_STATUS_UNSUCCESSFUL);
411 result = r.status;
413 if (NT_STATUS_IS_OK(result)) {
414 rpcstr_pull_unistr2_fstring(newdcname, &r.uni_dcname);
417 return result;
420 /* Dsr_GetDCName */
422 WERROR rpccli_netlogon_dsr_getdcname(struct rpc_pipe_client *cli,
423 TALLOC_CTX *mem_ctx,
424 const char *server_name,
425 const char *domain_name,
426 struct uuid *domain_guid,
427 struct uuid *site_guid,
428 uint32_t flags,
429 char **dc_unc, char **dc_address,
430 int32 *dc_address_type,
431 struct uuid *domain_guid_out,
432 char **domain_name_out,
433 char **forest_name,
434 uint32 *dc_flags,
435 char **dc_site_name,
436 char **client_site_name)
438 prs_struct qbuf, rbuf;
439 NET_Q_DSR_GETDCNAME q;
440 NET_R_DSR_GETDCNAME r;
441 char *tmp_str;
443 ZERO_STRUCT(q);
444 ZERO_STRUCT(r);
446 /* Initialize input parameters */
448 tmp_str = talloc_asprintf(mem_ctx, "\\\\%s", server_name);
449 if (tmp_str == NULL) {
450 return WERR_NOMEM;
453 init_net_q_dsr_getdcname(&q, tmp_str, domain_name, domain_guid,
454 site_guid, flags);
456 /* Marshall data and send request */
458 CLI_DO_RPC_WERR(cli, mem_ctx, PI_NETLOGON, NET_DSR_GETDCNAME,
459 q, r,
460 qbuf, rbuf,
461 net_io_q_dsr_getdcname,
462 net_io_r_dsr_getdcname,
463 WERR_GENERAL_FAILURE);
465 if (!W_ERROR_IS_OK(r.result)) {
466 return r.result;
469 if (dc_unc != NULL) {
470 char *tmp;
471 if (rpcstr_pull_unistr2_talloc(mem_ctx, &tmp,
472 &r.uni_dc_unc) < 0) {
473 return WERR_GENERAL_FAILURE;
475 if (*tmp == '\\') tmp += 1;
476 if (*tmp == '\\') tmp += 1;
478 /* We have to talloc_strdup, otherwise a talloc_steal would
479 fail */
480 *dc_unc = talloc_strdup(mem_ctx, tmp);
481 if (*dc_unc == NULL) {
482 return WERR_NOMEM;
486 if (dc_address != NULL) {
487 char *tmp;
488 if (rpcstr_pull_unistr2_talloc(mem_ctx, &tmp,
489 &r.uni_dc_address) < 0) {
490 return WERR_GENERAL_FAILURE;
492 if (*tmp == '\\') tmp += 1;
493 if (*tmp == '\\') tmp += 1;
495 /* We have to talloc_strdup, otherwise a talloc_steal would
496 fail */
497 *dc_address = talloc_strdup(mem_ctx, tmp);
498 if (*dc_address == NULL) {
499 return WERR_NOMEM;
503 if (dc_address_type != NULL) {
504 *dc_address_type = r.dc_address_type;
507 if (domain_guid_out != NULL) {
508 *domain_guid_out = r.domain_guid;
511 if ((domain_name_out != NULL) &&
512 (rpcstr_pull_unistr2_talloc(mem_ctx, domain_name_out,
513 &r.uni_domain_name) < 1)) {
514 return WERR_GENERAL_FAILURE;
517 if ((forest_name != NULL) &&
518 (rpcstr_pull_unistr2_talloc(mem_ctx, forest_name,
519 &r.uni_forest_name) < 1)) {
520 return WERR_GENERAL_FAILURE;
523 if (dc_flags != NULL) {
524 *dc_flags = r.dc_flags;
527 if ((dc_site_name != NULL) &&
528 (rpcstr_pull_unistr2_talloc(mem_ctx, dc_site_name,
529 &r.uni_dc_site_name) < 1)) {
530 return WERR_GENERAL_FAILURE;
533 if ((client_site_name != NULL) &&
534 (rpcstr_pull_unistr2_talloc(mem_ctx, client_site_name,
535 &r.uni_client_site_name) < 1)) {
536 return WERR_GENERAL_FAILURE;
539 return WERR_OK;
542 /* Dsr_GetSiteName */
544 WERROR rpccli_netlogon_dsr_getsitename(struct rpc_pipe_client *cli,
545 TALLOC_CTX *mem_ctx,
546 const char *computer_name,
547 char **site_name)
549 prs_struct qbuf, rbuf;
550 NET_Q_DSR_GETSITENAME q;
551 NET_R_DSR_GETSITENAME r;
553 ZERO_STRUCT(q);
554 ZERO_STRUCT(r);
556 /* Initialize input parameters */
558 init_net_q_dsr_getsitename(&q, computer_name);
560 /* Marshall data and send request */
562 CLI_DO_RPC_WERR(cli, mem_ctx, PI_NETLOGON, NET_DSR_GETSITENAME,
563 q, r,
564 qbuf, rbuf,
565 net_io_q_dsr_getsitename,
566 net_io_r_dsr_getsitename,
567 WERR_GENERAL_FAILURE);
569 if (!W_ERROR_IS_OK(r.result)) {
570 return r.result;
573 if ((site_name != NULL) &&
574 (rpcstr_pull_unistr2_talloc(mem_ctx, site_name,
575 &r.uni_site_name) < 1)) {
576 return WERR_GENERAL_FAILURE;
579 return WERR_OK;
584 /* Sam synchronisation */
586 NTSTATUS rpccli_netlogon_sam_sync(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
587 uint32 database_id, uint32 next_rid, uint32 *num_deltas,
588 SAM_DELTA_HDR **hdr_deltas,
589 SAM_DELTA_CTR **deltas)
591 prs_struct qbuf, rbuf;
592 NET_Q_SAM_SYNC q;
593 NET_R_SAM_SYNC r;
594 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
595 DOM_CRED clnt_creds;
596 DOM_CRED ret_creds;
598 ZERO_STRUCT(q);
599 ZERO_STRUCT(r);
601 ZERO_STRUCT(ret_creds);
603 /* Initialise input parameters */
605 creds_client_step(cli->dc, &clnt_creds);
607 prs_set_session_key(&qbuf, (const char *)cli->dc->sess_key);
608 prs_set_session_key(&rbuf, (const char *)cli->dc->sess_key);
610 init_net_q_sam_sync(&q, cli->dc->remote_machine, global_myname(),
611 &clnt_creds, &ret_creds, database_id, next_rid);
613 /* Marshall data and send request */
615 CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_SAM_SYNC,
616 q, r,
617 qbuf, rbuf,
618 net_io_q_sam_sync,
619 net_io_r_sam_sync,
620 NT_STATUS_UNSUCCESSFUL);
622 /* Return results */
624 result = r.status;
625 *num_deltas = r.num_deltas2;
626 *hdr_deltas = r.hdr_deltas;
627 *deltas = r.deltas;
629 if (!NT_STATUS_IS_ERR(result)) {
630 /* Check returned credentials. */
631 if (!creds_client_check(cli->dc, &r.srv_creds.challenge)) {
632 DEBUG(0,("cli_netlogon_sam_sync: credentials chain check failed\n"));
633 return NT_STATUS_ACCESS_DENIED;
637 return result;
640 /* Sam synchronisation */
642 NTSTATUS rpccli_netlogon_sam_deltas(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
643 uint32 database_id, UINT64_S seqnum,
644 uint32 *num_deltas,
645 SAM_DELTA_HDR **hdr_deltas,
646 SAM_DELTA_CTR **deltas)
648 prs_struct qbuf, rbuf;
649 NET_Q_SAM_DELTAS q;
650 NET_R_SAM_DELTAS r;
651 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
652 DOM_CRED clnt_creds;
654 ZERO_STRUCT(q);
655 ZERO_STRUCT(r);
657 /* Initialise input parameters */
659 creds_client_step(cli->dc, &clnt_creds);
661 init_net_q_sam_deltas(&q, cli->dc->remote_machine,
662 global_myname(), &clnt_creds,
663 database_id, seqnum);
665 /* Marshall data and send request */
667 CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_SAM_DELTAS,
668 q, r,
669 qbuf, rbuf,
670 net_io_q_sam_deltas,
671 net_io_r_sam_deltas,
672 NT_STATUS_UNSUCCESSFUL);
674 /* Return results */
676 result = r.status;
677 *num_deltas = r.num_deltas2;
678 *hdr_deltas = r.hdr_deltas;
679 *deltas = r.deltas;
681 if (!NT_STATUS_IS_ERR(result)) {
682 /* Check returned credentials. */
683 if (!creds_client_check(cli->dc, &r.srv_creds.challenge)) {
684 DEBUG(0,("cli_netlogon_sam_sync: credentials chain check failed\n"));
685 return NT_STATUS_ACCESS_DENIED;
689 return result;
692 /* Logon domain user */
694 NTSTATUS rpccli_netlogon_sam_logon(struct rpc_pipe_client *cli,
695 TALLOC_CTX *mem_ctx,
696 uint32 logon_parameters,
697 const char *domain,
698 const char *username,
699 const char *password,
700 int logon_type)
702 prs_struct qbuf, rbuf;
703 NET_Q_SAM_LOGON q;
704 NET_R_SAM_LOGON r;
705 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
706 DOM_CRED clnt_creds;
707 DOM_CRED ret_creds;
708 NET_ID_INFO_CTR ctr;
709 NET_USER_INFO_3 user;
710 int validation_level = 3;
711 fstring clnt_name_slash;
713 ZERO_STRUCT(q);
714 ZERO_STRUCT(r);
715 ZERO_STRUCT(ret_creds);
717 fstr_sprintf( clnt_name_slash, "\\\\%s", global_myname() );
719 /* Initialise input parameters */
721 creds_client_step(cli->dc, &clnt_creds);
723 q.validation_level = validation_level;
725 ctr.switch_value = logon_type;
727 switch (logon_type) {
728 case INTERACTIVE_LOGON_TYPE: {
729 unsigned char lm_owf_user_pwd[16], nt_owf_user_pwd[16];
731 nt_lm_owf_gen(password, nt_owf_user_pwd, lm_owf_user_pwd);
733 init_id_info1(&ctr.auth.id1, domain,
734 logon_parameters, /* param_ctrl */
735 0xdead, 0xbeef, /* LUID? */
736 username, clnt_name_slash,
737 (const char *)cli->dc->sess_key, lm_owf_user_pwd,
738 nt_owf_user_pwd);
740 break;
742 case NET_LOGON_TYPE: {
743 uint8 chal[8];
744 unsigned char local_lm_response[24];
745 unsigned char local_nt_response[24];
747 generate_random_buffer(chal, 8);
749 SMBencrypt(password, chal, local_lm_response);
750 SMBNTencrypt(password, chal, local_nt_response);
752 init_id_info2(&ctr.auth.id2, domain,
753 logon_parameters, /* param_ctrl */
754 0xdead, 0xbeef, /* LUID? */
755 username, clnt_name_slash, chal,
756 local_lm_response, 24, local_nt_response, 24);
757 break;
759 default:
760 DEBUG(0, ("switch value %d not supported\n",
761 ctr.switch_value));
762 return NT_STATUS_INVALID_INFO_CLASS;
765 r.user = &user;
767 init_sam_info(&q.sam_id, cli->dc->remote_machine, global_myname(),
768 &clnt_creds, &ret_creds, logon_type,
769 &ctr);
771 /* Marshall data and send request */
773 CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_SAMLOGON,
774 q, r,
775 qbuf, rbuf,
776 net_io_q_sam_logon,
777 net_io_r_sam_logon,
778 NT_STATUS_UNSUCCESSFUL);
780 /* Return results */
782 result = r.status;
784 if (r.buffer_creds) {
785 /* Check returned credentials if present. */
786 if (!creds_client_check(cli->dc, &r.srv_creds.challenge)) {
787 DEBUG(0,("rpccli_netlogon_sam_logon: credentials chain check failed\n"));
788 return NT_STATUS_ACCESS_DENIED;
792 return result;
796 /**
797 * Logon domain user with an 'network' SAM logon
799 * @param info3 Pointer to a NET_USER_INFO_3 already allocated by the caller.
802 NTSTATUS rpccli_netlogon_sam_network_logon(struct rpc_pipe_client *cli,
803 TALLOC_CTX *mem_ctx,
804 uint32 logon_parameters,
805 const char *server,
806 const char *username,
807 const char *domain,
808 const char *workstation,
809 const uint8 chal[8],
810 DATA_BLOB lm_response,
811 DATA_BLOB nt_response,
812 NET_USER_INFO_3 *info3)
814 prs_struct qbuf, rbuf;
815 NET_Q_SAM_LOGON q;
816 NET_R_SAM_LOGON r;
817 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
818 NET_ID_INFO_CTR ctr;
819 int validation_level = 3;
820 const char *workstation_name_slash;
821 const char *server_name_slash;
822 static uint8 zeros[16];
823 DOM_CRED clnt_creds;
824 DOM_CRED ret_creds;
825 int i;
827 ZERO_STRUCT(q);
828 ZERO_STRUCT(r);
829 ZERO_STRUCT(ret_creds);
831 creds_client_step(cli->dc, &clnt_creds);
833 if (server[0] != '\\' && server[1] != '\\') {
834 server_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", server);
835 } else {
836 server_name_slash = server;
839 if (workstation[0] != '\\' && workstation[1] != '\\') {
840 workstation_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", workstation);
841 } else {
842 workstation_name_slash = workstation;
845 if (!workstation_name_slash || !server_name_slash) {
846 DEBUG(0, ("talloc_asprintf failed!\n"));
847 return NT_STATUS_NO_MEMORY;
850 /* Initialise input parameters */
852 q.validation_level = validation_level;
854 ctr.switch_value = NET_LOGON_TYPE;
856 init_id_info2(&ctr.auth.id2, domain,
857 logon_parameters, /* param_ctrl */
858 0xdead, 0xbeef, /* LUID? */
859 username, workstation_name_slash, (const uchar*)chal,
860 lm_response.data, lm_response.length, nt_response.data, nt_response.length);
862 init_sam_info(&q.sam_id, server_name_slash, global_myname(),
863 &clnt_creds, &ret_creds, NET_LOGON_TYPE,
864 &ctr);
866 r.user = info3;
868 /* Marshall data and send request */
870 CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_SAMLOGON,
871 q, r,
872 qbuf, rbuf,
873 net_io_q_sam_logon,
874 net_io_r_sam_logon,
875 NT_STATUS_UNSUCCESSFUL);
877 if (memcmp(zeros, info3->user_sess_key, 16) != 0) {
878 SamOEMhash(info3->user_sess_key, cli->dc->sess_key, 16);
879 } else {
880 memset(info3->user_sess_key, '\0', 16);
883 if (memcmp(zeros, info3->lm_sess_key, 8) != 0) {
884 SamOEMhash(info3->lm_sess_key, cli->dc->sess_key, 8);
885 } else {
886 memset(info3->lm_sess_key, '\0', 8);
889 memset(&info3->acct_flags, '\0', 4);
890 for (i=0; i < 7; i++) {
891 memset(&info3->unknown[i], '\0', 4);
894 /* Return results */
896 result = r.status;
898 if (r.buffer_creds) {
899 /* Check returned credentials if present. */
900 if (!creds_client_check(cli->dc, &r.srv_creds.challenge)) {
901 DEBUG(0,("rpccli_netlogon_sam_network_logon: credentials chain check failed\n"));
902 return NT_STATUS_ACCESS_DENIED;
906 return result;
909 /***************************************************************************
910 LSA Server Password Set.
911 ****************************************************************************/
913 NTSTATUS rpccli_net_srv_pwset(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
914 const char *machine_name, const uint8 hashed_mach_pwd[16])
916 prs_struct rbuf;
917 prs_struct qbuf;
918 DOM_CRED clnt_creds;
919 NET_Q_SRV_PWSET q;
920 NET_R_SRV_PWSET r;
921 uint16 sec_chan_type = 2;
922 NTSTATUS result;
924 creds_client_step(cli->dc, &clnt_creds);
926 DEBUG(4,("cli_net_srv_pwset: srv:%s acct:%s sc: %d mc: %s\n",
927 cli->dc->remote_machine, cli->dc->mach_acct, sec_chan_type, machine_name));
929 /* store the parameters */
930 init_q_srv_pwset(&q, cli->dc->remote_machine, (const char *)cli->dc->sess_key,
931 cli->dc->mach_acct, sec_chan_type, machine_name,
932 &clnt_creds, hashed_mach_pwd);
934 CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_SRVPWSET,
935 q, r,
936 qbuf, rbuf,
937 net_io_q_srv_pwset,
938 net_io_r_srv_pwset,
939 NT_STATUS_UNSUCCESSFUL);
941 result = r.status;
943 if (!NT_STATUS_IS_OK(result)) {
944 /* report error code */
945 DEBUG(0,("cli_net_srv_pwset: %s\n", nt_errstr(result)));
948 /* Always check returned credentials. */
949 if (!creds_client_check(cli->dc, &r.srv_cred.challenge)) {
950 DEBUG(0,("rpccli_net_srv_pwset: credentials chain check failed\n"));
951 return NT_STATUS_ACCESS_DENIED;
954 return result;