r19143: getdcname on the NETLOGON pipe returns WERROR, not NTSTATUS.
[Samba/bb.git] / source3 / rpc_client / cli_netlogon.c
blob5396de9bf078ba2d5e5b23cdb6b33eb754d50383
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(*neg_flags_inout,
306 &clnt_chal_send,
307 &srv_chal_recv,
308 machine_pwd,
309 &clnt_chal_send);
312 * Send client auth-2 challenge and receive server repy.
315 result = rpccli_net_auth2(cli,
316 cli->mem_ctx,
317 dc->remote_machine,
318 dc->mach_acct,
319 sec_chan_type,
320 clnt_name,
321 neg_flags_inout,
322 &clnt_chal_send, /* input. */
323 &srv_chal_recv); /* output */
325 if (!NT_STATUS_IS_OK(result)) {
326 return result;
330 * Check the returned value using the initial
331 * server received challenge.
334 if (!creds_client_check(dc, &srv_chal_recv)) {
336 * Server replied with bad credential. Fail.
338 DEBUG(0,("rpccli_netlogon_setup_creds: server %s "
339 "replied with bad credential\n",
340 cli->cli->desthost ));
341 return NT_STATUS_ACCESS_DENIED;
344 DEBUG(5,("rpccli_netlogon_setup_creds: server %s credential "
345 "chain established.\n",
346 cli->cli->desthost ));
348 return NT_STATUS_OK;
351 /* Logon Control 2 */
353 NTSTATUS rpccli_netlogon_logon_ctrl2(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
354 uint32 query_level)
356 prs_struct qbuf, rbuf;
357 NET_Q_LOGON_CTRL2 q;
358 NET_R_LOGON_CTRL2 r;
359 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
360 fstring server;
362 ZERO_STRUCT(q);
363 ZERO_STRUCT(r);
365 /* Initialise input parameters */
367 slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
368 init_net_q_logon_ctrl2(&q, server, query_level);
370 /* Marshall data and send request */
372 CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_LOGON_CTRL2,
373 q, r,
374 qbuf, rbuf,
375 net_io_q_logon_ctrl2,
376 net_io_r_logon_ctrl2,
377 NT_STATUS_UNSUCCESSFUL);
379 result = r.status;
380 return result;
383 /* GetDCName */
385 WERROR rpccli_netlogon_getdcname(struct rpc_pipe_client *cli,
386 TALLOC_CTX *mem_ctx, const char *mydcname,
387 const char *domainname, fstring newdcname)
389 prs_struct qbuf, rbuf;
390 NET_Q_GETDCNAME q;
391 NET_R_GETDCNAME r;
392 WERROR result;
393 fstring mydcname_slash;
395 ZERO_STRUCT(q);
396 ZERO_STRUCT(r);
398 /* Initialise input parameters */
400 slprintf(mydcname_slash, sizeof(fstring)-1, "\\\\%s", mydcname);
401 init_net_q_getdcname(&q, mydcname_slash, domainname);
403 /* Marshall data and send request */
405 CLI_DO_RPC_WERR(cli, mem_ctx, PI_NETLOGON, NET_GETDCNAME,
406 q, r,
407 qbuf, rbuf,
408 net_io_q_getdcname,
409 net_io_r_getdcname,
410 WERR_GENERAL_FAILURE);
412 result = r.status;
414 if (W_ERROR_IS_OK(result)) {
415 rpcstr_pull_unistr2_fstring(newdcname, &r.uni_dcname);
418 return result;
421 /* Dsr_GetDCName */
423 WERROR rpccli_netlogon_dsr_getdcname(struct rpc_pipe_client *cli,
424 TALLOC_CTX *mem_ctx,
425 const char *server_name,
426 const char *domain_name,
427 struct GUID *domain_guid,
428 struct GUID *site_guid,
429 uint32_t flags,
430 char **dc_unc, char **dc_address,
431 int32 *dc_address_type,
432 struct GUID *domain_guid_out,
433 char **domain_name_out,
434 char **forest_name,
435 uint32 *dc_flags,
436 char **dc_site_name,
437 char **client_site_name)
439 prs_struct qbuf, rbuf;
440 NET_Q_DSR_GETDCNAME q;
441 NET_R_DSR_GETDCNAME r;
442 char *tmp_str;
444 ZERO_STRUCT(q);
445 ZERO_STRUCT(r);
447 /* Initialize input parameters */
449 tmp_str = talloc_asprintf(mem_ctx, "\\\\%s", server_name);
450 if (tmp_str == NULL) {
451 return WERR_NOMEM;
454 init_net_q_dsr_getdcname(&q, tmp_str, domain_name, domain_guid,
455 site_guid, flags);
457 /* Marshall data and send request */
459 CLI_DO_RPC_WERR(cli, mem_ctx, PI_NETLOGON, NET_DSR_GETDCNAME,
460 q, r,
461 qbuf, rbuf,
462 net_io_q_dsr_getdcname,
463 net_io_r_dsr_getdcname,
464 WERR_GENERAL_FAILURE);
466 if (!W_ERROR_IS_OK(r.result)) {
467 return r.result;
470 if (dc_unc != NULL) {
471 char *tmp;
472 tmp = rpcstr_pull_unistr2_talloc(mem_ctx, &r.uni_dc_unc);
473 if (tmp == NULL) {
474 return WERR_GENERAL_FAILURE;
476 if (*tmp == '\\') tmp += 1;
477 if (*tmp == '\\') tmp += 1;
479 /* We have to talloc_strdup, otherwise a talloc_steal would
480 fail */
481 *dc_unc = talloc_strdup(mem_ctx, tmp);
482 if (*dc_unc == NULL) {
483 return WERR_NOMEM;
487 if (dc_address != NULL) {
488 char *tmp;
489 tmp = rpcstr_pull_unistr2_talloc(mem_ctx, &r.uni_dc_address);
490 if (tmp == NULL) {
491 return WERR_GENERAL_FAILURE;
493 if (*tmp == '\\') tmp += 1;
494 if (*tmp == '\\') tmp += 1;
496 /* We have to talloc_strdup, otherwise a talloc_steal would
497 fail */
498 *dc_address = talloc_strdup(mem_ctx, tmp);
499 if (*dc_address == NULL) {
500 return WERR_NOMEM;
504 if (dc_address_type != NULL) {
505 *dc_address_type = r.dc_address_type;
508 if (domain_guid_out != NULL) {
509 *domain_guid_out = r.domain_guid;
512 if ((domain_name_out != NULL) &&
513 ((*domain_name_out = rpcstr_pull_unistr2_talloc(
514 mem_ctx, &r.uni_domain_name)) == NULL)) {
515 return WERR_GENERAL_FAILURE;
518 if ((forest_name != NULL) &&
519 ((*forest_name = rpcstr_pull_unistr2_talloc(
520 mem_ctx, &r.uni_forest_name)) == NULL)) {
521 return WERR_GENERAL_FAILURE;
524 if (dc_flags != NULL) {
525 *dc_flags = r.dc_flags;
528 if ((dc_site_name != NULL) &&
529 ((*dc_site_name = rpcstr_pull_unistr2_talloc(
530 mem_ctx, &r.uni_dc_site_name)) == NULL)) {
531 return WERR_GENERAL_FAILURE;
534 if ((client_site_name != NULL) &&
535 ((*client_site_name = rpcstr_pull_unistr2_talloc(
536 mem_ctx, &r.uni_client_site_name)) == NULL)) {
537 return WERR_GENERAL_FAILURE;
540 return WERR_OK;
543 /* Dsr_GetSiteName */
545 WERROR rpccli_netlogon_dsr_getsitename(struct rpc_pipe_client *cli,
546 TALLOC_CTX *mem_ctx,
547 const char *computer_name,
548 char **site_name)
550 prs_struct qbuf, rbuf;
551 NET_Q_DSR_GETSITENAME q;
552 NET_R_DSR_GETSITENAME r;
554 ZERO_STRUCT(q);
555 ZERO_STRUCT(r);
557 /* Initialize input parameters */
559 init_net_q_dsr_getsitename(&q, computer_name);
561 /* Marshall data and send request */
563 CLI_DO_RPC_WERR(cli, mem_ctx, PI_NETLOGON, NET_DSR_GETSITENAME,
564 q, r,
565 qbuf, rbuf,
566 net_io_q_dsr_getsitename,
567 net_io_r_dsr_getsitename,
568 WERR_GENERAL_FAILURE);
570 if (!W_ERROR_IS_OK(r.result)) {
571 return r.result;
574 if ((site_name != NULL) &&
575 ((*site_name = rpcstr_pull_unistr2_talloc(
576 mem_ctx, &r.uni_site_name)) == NULL)) {
577 return WERR_GENERAL_FAILURE;
580 return WERR_OK;
585 /* Sam synchronisation */
587 NTSTATUS rpccli_netlogon_sam_sync(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
588 uint32 database_id, uint32 next_rid, uint32 *num_deltas,
589 SAM_DELTA_HDR **hdr_deltas,
590 SAM_DELTA_CTR **deltas)
592 prs_struct qbuf, rbuf;
593 NET_Q_SAM_SYNC q;
594 NET_R_SAM_SYNC r;
595 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
596 DOM_CRED clnt_creds;
597 DOM_CRED ret_creds;
599 ZERO_STRUCT(q);
600 ZERO_STRUCT(r);
602 ZERO_STRUCT(ret_creds);
604 /* Initialise input parameters */
606 creds_client_step(cli->dc, &clnt_creds);
608 init_net_q_sam_sync(&q, cli->dc->remote_machine, global_myname(),
609 &clnt_creds, &ret_creds, database_id, next_rid);
611 /* Marshall data and send request */
613 CLI_DO_RPC_COPY_SESS_KEY(cli, mem_ctx, PI_NETLOGON, NET_SAM_SYNC,
614 q, r,
615 qbuf, rbuf,
616 net_io_q_sam_sync,
617 net_io_r_sam_sync,
618 NT_STATUS_UNSUCCESSFUL);
620 /* Return results */
622 result = r.status;
623 *num_deltas = r.num_deltas2;
624 *hdr_deltas = r.hdr_deltas;
625 *deltas = r.deltas;
627 if (!NT_STATUS_IS_ERR(result)) {
628 /* Check returned credentials. */
629 if (!creds_client_check(cli->dc, &r.srv_creds.challenge)) {
630 DEBUG(0,("cli_netlogon_sam_sync: credentials chain check failed\n"));
631 return NT_STATUS_ACCESS_DENIED;
635 return result;
638 /* Sam synchronisation */
640 NTSTATUS rpccli_netlogon_sam_deltas(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
641 uint32 database_id, uint64 seqnum,
642 uint32 *num_deltas,
643 SAM_DELTA_HDR **hdr_deltas,
644 SAM_DELTA_CTR **deltas)
646 prs_struct qbuf, rbuf;
647 NET_Q_SAM_DELTAS q;
648 NET_R_SAM_DELTAS r;
649 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
650 DOM_CRED clnt_creds;
652 ZERO_STRUCT(q);
653 ZERO_STRUCT(r);
655 /* Initialise input parameters */
657 creds_client_step(cli->dc, &clnt_creds);
659 init_net_q_sam_deltas(&q, cli->dc->remote_machine,
660 global_myname(), &clnt_creds,
661 database_id, seqnum);
663 /* Marshall data and send request */
665 CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_SAM_DELTAS,
666 q, r,
667 qbuf, rbuf,
668 net_io_q_sam_deltas,
669 net_io_r_sam_deltas,
670 NT_STATUS_UNSUCCESSFUL);
672 /* Return results */
674 result = r.status;
675 *num_deltas = r.num_deltas2;
676 *hdr_deltas = r.hdr_deltas;
677 *deltas = r.deltas;
679 if (!NT_STATUS_IS_ERR(result)) {
680 /* Check returned credentials. */
681 if (!creds_client_check(cli->dc, &r.srv_creds.challenge)) {
682 DEBUG(0,("cli_netlogon_sam_sync: credentials chain check failed\n"));
683 return NT_STATUS_ACCESS_DENIED;
687 return result;
690 /* Logon domain user */
692 NTSTATUS rpccli_netlogon_sam_logon(struct rpc_pipe_client *cli,
693 TALLOC_CTX *mem_ctx,
694 uint32 logon_parameters,
695 const char *domain,
696 const char *username,
697 const char *password,
698 int logon_type)
700 prs_struct qbuf, rbuf;
701 NET_Q_SAM_LOGON q;
702 NET_R_SAM_LOGON r;
703 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
704 DOM_CRED clnt_creds;
705 DOM_CRED ret_creds;
706 NET_ID_INFO_CTR ctr;
707 NET_USER_INFO_3 user;
708 int validation_level = 3;
709 fstring clnt_name_slash;
711 ZERO_STRUCT(q);
712 ZERO_STRUCT(r);
713 ZERO_STRUCT(ret_creds);
715 fstr_sprintf( clnt_name_slash, "\\\\%s", global_myname() );
717 /* Initialise input parameters */
719 creds_client_step(cli->dc, &clnt_creds);
721 q.validation_level = validation_level;
723 ctr.switch_value = logon_type;
725 switch (logon_type) {
726 case INTERACTIVE_LOGON_TYPE: {
727 unsigned char lm_owf_user_pwd[16], nt_owf_user_pwd[16];
729 nt_lm_owf_gen(password, nt_owf_user_pwd, lm_owf_user_pwd);
731 init_id_info1(&ctr.auth.id1, domain,
732 logon_parameters, /* param_ctrl */
733 0xdead, 0xbeef, /* LUID? */
734 username, clnt_name_slash,
735 (const char *)cli->dc->sess_key, lm_owf_user_pwd,
736 nt_owf_user_pwd);
738 break;
740 case NET_LOGON_TYPE: {
741 uint8 chal[8];
742 unsigned char local_lm_response[24];
743 unsigned char local_nt_response[24];
745 generate_random_buffer(chal, 8);
747 SMBencrypt(password, chal, local_lm_response);
748 SMBNTencrypt(password, chal, local_nt_response);
750 init_id_info2(&ctr.auth.id2, domain,
751 logon_parameters, /* param_ctrl */
752 0xdead, 0xbeef, /* LUID? */
753 username, clnt_name_slash, chal,
754 local_lm_response, 24, local_nt_response, 24);
755 break;
757 default:
758 DEBUG(0, ("switch value %d not supported\n",
759 ctr.switch_value));
760 return NT_STATUS_INVALID_INFO_CLASS;
763 r.user = &user;
765 init_sam_info(&q.sam_id, cli->dc->remote_machine, global_myname(),
766 &clnt_creds, &ret_creds, logon_type,
767 &ctr);
769 /* Marshall data and send request */
771 CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_SAMLOGON,
772 q, r,
773 qbuf, rbuf,
774 net_io_q_sam_logon,
775 net_io_r_sam_logon,
776 NT_STATUS_UNSUCCESSFUL);
778 /* Return results */
780 result = r.status;
782 if (r.buffer_creds) {
783 /* Check returned credentials if present. */
784 if (!creds_client_check(cli->dc, &r.srv_creds.challenge)) {
785 DEBUG(0,("rpccli_netlogon_sam_logon: credentials chain check failed\n"));
786 return NT_STATUS_ACCESS_DENIED;
790 return result;
794 /**
795 * Logon domain user with an 'network' SAM logon
797 * @param info3 Pointer to a NET_USER_INFO_3 already allocated by the caller.
800 NTSTATUS rpccli_netlogon_sam_network_logon(struct rpc_pipe_client *cli,
801 TALLOC_CTX *mem_ctx,
802 uint32 logon_parameters,
803 const char *server,
804 const char *username,
805 const char *domain,
806 const char *workstation,
807 const uint8 chal[8],
808 DATA_BLOB lm_response,
809 DATA_BLOB nt_response,
810 NET_USER_INFO_3 *info3)
812 prs_struct qbuf, rbuf;
813 NET_Q_SAM_LOGON q;
814 NET_R_SAM_LOGON r;
815 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
816 NET_ID_INFO_CTR ctr;
817 int validation_level = 3;
818 const char *workstation_name_slash;
819 const char *server_name_slash;
820 static uint8 zeros[16];
821 DOM_CRED clnt_creds;
822 DOM_CRED ret_creds;
823 int i;
825 ZERO_STRUCT(q);
826 ZERO_STRUCT(r);
827 ZERO_STRUCT(ret_creds);
829 creds_client_step(cli->dc, &clnt_creds);
831 if (server[0] != '\\' && server[1] != '\\') {
832 server_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", server);
833 } else {
834 server_name_slash = server;
837 if (workstation[0] != '\\' && workstation[1] != '\\') {
838 workstation_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", workstation);
839 } else {
840 workstation_name_slash = workstation;
843 if (!workstation_name_slash || !server_name_slash) {
844 DEBUG(0, ("talloc_asprintf failed!\n"));
845 return NT_STATUS_NO_MEMORY;
848 /* Initialise input parameters */
850 q.validation_level = validation_level;
852 ctr.switch_value = NET_LOGON_TYPE;
854 init_id_info2(&ctr.auth.id2, domain,
855 logon_parameters, /* param_ctrl */
856 0xdead, 0xbeef, /* LUID? */
857 username, workstation_name_slash, (const uchar*)chal,
858 lm_response.data, lm_response.length, nt_response.data, nt_response.length);
860 init_sam_info(&q.sam_id, server_name_slash, global_myname(),
861 &clnt_creds, &ret_creds, NET_LOGON_TYPE,
862 &ctr);
864 r.user = info3;
866 /* Marshall data and send request */
868 CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_SAMLOGON,
869 q, r,
870 qbuf, rbuf,
871 net_io_q_sam_logon,
872 net_io_r_sam_logon,
873 NT_STATUS_UNSUCCESSFUL);
875 if (memcmp(zeros, info3->user_sess_key, 16) != 0) {
876 SamOEMhash(info3->user_sess_key, cli->dc->sess_key, 16);
877 } else {
878 memset(info3->user_sess_key, '\0', 16);
881 if (memcmp(zeros, info3->lm_sess_key, 8) != 0) {
882 SamOEMhash(info3->lm_sess_key, cli->dc->sess_key, 8);
883 } else {
884 memset(info3->lm_sess_key, '\0', 8);
887 for (i=0; i < 7; i++) {
888 memset(&info3->unknown[i], '\0', 4);
891 /* Return results */
893 result = r.status;
895 if (r.buffer_creds) {
896 /* Check returned credentials if present. */
897 if (!creds_client_check(cli->dc, &r.srv_creds.challenge)) {
898 DEBUG(0,("rpccli_netlogon_sam_network_logon: credentials chain check failed\n"));
899 return NT_STATUS_ACCESS_DENIED;
903 return result;
906 /***************************************************************************
907 LSA Server Password Set.
908 ****************************************************************************/
910 NTSTATUS rpccli_net_srv_pwset(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
911 const char *machine_name, const uint8 hashed_mach_pwd[16])
913 prs_struct rbuf;
914 prs_struct qbuf;
915 DOM_CRED clnt_creds;
916 NET_Q_SRV_PWSET q;
917 NET_R_SRV_PWSET r;
918 uint16 sec_chan_type = 2;
919 NTSTATUS result;
921 creds_client_step(cli->dc, &clnt_creds);
923 DEBUG(4,("cli_net_srv_pwset: srv:%s acct:%s sc: %d mc: %s\n",
924 cli->dc->remote_machine, cli->dc->mach_acct, sec_chan_type, machine_name));
926 /* store the parameters */
927 init_q_srv_pwset(&q, cli->dc->remote_machine, (const char *)cli->dc->sess_key,
928 cli->dc->mach_acct, sec_chan_type, machine_name,
929 &clnt_creds, hashed_mach_pwd);
931 CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_SRVPWSET,
932 q, r,
933 qbuf, rbuf,
934 net_io_q_srv_pwset,
935 net_io_r_srv_pwset,
936 NT_STATUS_UNSUCCESSFUL);
938 result = r.status;
940 if (!NT_STATUS_IS_OK(result)) {
941 /* report error code */
942 DEBUG(0,("cli_net_srv_pwset: %s\n", nt_errstr(result)));
945 /* Always check returned credentials. */
946 if (!creds_client_check(cli->dc, &r.srv_cred.challenge)) {
947 DEBUG(0,("rpccli_net_srv_pwset: credentials chain check failed\n"));
948 return NT_STATUS_ACCESS_DENIED;
951 return result;