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.
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
,
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
;
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
,
57 NT_STATUS_UNSUCCESSFUL
);
63 if (NT_STATUS_IS_OK(result
)) {
64 /* Store the returned server challenge. */
65 *srv_chal_out
= r
.srv_chal
;
72 /****************************************************************************
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
,
82 uint32
*neg_flags
, DOM_CHAL
*srv_chal
)
84 prs_struct qbuf
, rbuf
;
87 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
90 if ( sec_chan
== SEC_CHAN_DOMAIN
)
91 fstr_sprintf( machine_acct
, "%s$", lp_workgroup() );
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
,
107 /* turn parameters into data stream */
109 CLI_DO_RPC(cli
, mem_ctx
, PI_NETLOGON
, NET_AUTH2
,
114 NT_STATUS_UNSUCCESSFUL
);
118 if (NT_STATUS_IS_OK(result
)) {
122 * Check the returned value using the initial
123 * server received challenge.
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
;
143 /****************************************************************************
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
,
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
;
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
,
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
,
184 NT_STATUS_UNSUCCESSFUL
);
188 *neg_flags_inout
= r
.srv_flgs
.neg_flags
;
190 if (NT_STATUS_IS_OK(result
)) {
191 *srv_chal_out
= r
.srv_chal
;
197 #if 0 /* not currebntly used */
198 /****************************************************************************
201 Send the client credential, receive back a server credential.
202 The caller *must* ensure that the server credential returned matches the session key
203 encrypt of the server challenge originally received. JRA.
204 ****************************************************************************/
206 static NTSTATUS
rpccli_net_auth3(struct rpc_pipe_client
*cli
,
208 const char *server_name
,
209 const char *account_name
,
210 uint16 sec_chan_type
,
211 const char *computer_name
,
212 uint32
*neg_flags_inout
,
213 const DOM_CHAL
*clnt_chal_in
,
214 DOM_CHAL
*srv_chal_out
)
216 prs_struct qbuf
, rbuf
;
219 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
221 /* create and send a MSRPC command with api NET_AUTH2 */
223 DEBUG(4,("cli_net_auth3: srv:%s acct:%s sc:%x mc: %s chal %s neg: %x\n",
224 server_name
, account_name
, sec_chan_type
, computer_name
,
225 credstr(clnt_chal_in
->data
), *neg_flags_inout
));
227 /* store the parameters */
228 init_q_auth_3(&q
, server_name
, account_name
, sec_chan_type
,
229 computer_name
, clnt_chal_in
, *neg_flags_inout
);
231 /* turn parameters into data stream */
233 CLI_DO_RPC(cli
, mem_ctx
, PI_NETLOGON
, NET_AUTH3
,
238 NT_STATUS_UNSUCCESSFUL
);
240 if (NT_STATUS_IS_OK(result
)) {
241 *srv_chal_out
= r
.srv_chal
;
242 *neg_flags_inout
= r
.srv_flgs
.neg_flags
;
247 #endif /* not currebntly used */
249 /****************************************************************************
250 Wrapper function that uses the auth and auth2 calls to set up a NETLOGON
251 credentials chain. Stores the credentials in the struct dcinfo in the
252 netlogon pipe struct.
253 ****************************************************************************/
255 NTSTATUS
rpccli_netlogon_setup_creds(struct rpc_pipe_client
*cli
,
256 const char *server_name
,
258 const char *clnt_name
,
259 const char *machine_account
,
260 const unsigned char machine_pwd
[16],
261 uint32 sec_chan_type
,
262 uint32
*neg_flags_inout
)
264 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
265 DOM_CHAL clnt_chal_send
;
266 DOM_CHAL srv_chal_recv
;
268 bool retried
= false;
270 SMB_ASSERT(cli
->pipe_idx
== PI_NETLOGON
);
274 return NT_STATUS_INVALID_PARAMETER
;
277 /* Ensure we don't reuse any of this state. */
280 /* Store the machine account password we're going to use. */
281 memcpy(dc
->mach_pw
, machine_pwd
, 16);
283 fstrcpy(dc
->remote_machine
, "\\\\");
284 fstrcat(dc
->remote_machine
, server_name
);
286 fstrcpy(dc
->domain
, domain
);
288 fstr_sprintf( dc
->mach_acct
, "%s$", machine_account
);
291 /* Create the client challenge. */
292 generate_random_buffer(clnt_chal_send
.data
, 8);
294 /* Get the server challenge. */
295 result
= rpccli_net_req_chal(cli
,
302 if (!NT_STATUS_IS_OK(result
)) {
306 /* Calculate the session key and client credentials */
307 creds_client_init(*neg_flags_inout
,
315 * Send client auth-2 challenge and receive server repy.
318 result
= rpccli_net_auth2(cli
,
325 &clnt_chal_send
, /* input. */
326 &srv_chal_recv
); /* output */
328 /* we might be talking to NT4, so let's downgrade in that case and retry
329 * with the returned neg_flags - gd */
331 if (NT_STATUS_EQUAL(result
, NT_STATUS_ACCESS_DENIED
) && !retried
) {
336 if (!NT_STATUS_IS_OK(result
)) {
341 * Check the returned value using the initial
342 * server received challenge.
345 if (!creds_client_check(dc
, &srv_chal_recv
)) {
347 * Server replied with bad credential. Fail.
349 DEBUG(0,("rpccli_netlogon_setup_creds: server %s "
350 "replied with bad credential\n",
351 cli
->cli
->desthost
));
352 return NT_STATUS_ACCESS_DENIED
;
355 DEBUG(5,("rpccli_netlogon_setup_creds: server %s credential "
356 "chain established.\n",
357 cli
->cli
->desthost
));
362 /* Logon Control 2 */
364 NTSTATUS
rpccli_netlogon_logon_ctrl2(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
367 prs_struct qbuf
, rbuf
;
370 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
376 /* Initialise input parameters */
378 slprintf(server
, sizeof(fstring
)-1, "\\\\%s", cli
->cli
->desthost
);
379 init_net_q_logon_ctrl2(&q
, server
, query_level
);
381 /* Marshall data and send request */
383 CLI_DO_RPC(cli
, mem_ctx
, PI_NETLOGON
, NET_LOGON_CTRL2
,
386 net_io_q_logon_ctrl2
,
387 net_io_r_logon_ctrl2
,
388 NT_STATUS_UNSUCCESSFUL
);
396 WERROR
rpccli_netlogon_getanydcname(struct rpc_pipe_client
*cli
,
397 TALLOC_CTX
*mem_ctx
, const char *mydcname
,
398 const char *domainname
, fstring newdcname
)
400 prs_struct qbuf
, rbuf
;
401 NET_Q_GETANYDCNAME q
;
402 NET_R_GETANYDCNAME r
;
404 fstring mydcname_slash
;
409 /* Initialise input parameters */
411 slprintf(mydcname_slash
, sizeof(fstring
)-1, "\\\\%s", mydcname
);
412 init_net_q_getanydcname(&q
, mydcname_slash
, domainname
);
414 /* Marshall data and send request */
416 CLI_DO_RPC_WERR(cli
, mem_ctx
, PI_NETLOGON
, NET_GETANYDCNAME
,
419 net_io_q_getanydcname
,
420 net_io_r_getanydcname
,
421 WERR_GENERAL_FAILURE
);
425 if (W_ERROR_IS_OK(result
)) {
426 rpcstr_pull_unistr2_fstring(newdcname
, &r
.uni_dcname
);
432 static WERROR
pull_domain_controller_info_from_getdcname_reply(TALLOC_CTX
*mem_ctx
,
433 struct DS_DOMAIN_CONTROLLER_INFO
**info_out
,
434 NET_R_DSR_GETDCNAME
*r
)
436 struct DS_DOMAIN_CONTROLLER_INFO
*info
;
438 info
= TALLOC_ZERO_P(mem_ctx
, struct DS_DOMAIN_CONTROLLER_INFO
);
443 if (&r
->uni_dc_unc
) {
446 tmp
= rpcstr_pull_unistr2_talloc(mem_ctx
, &r
->uni_dc_unc
);
448 return WERR_GENERAL_FAILURE
;
450 if (*tmp
== '\\') tmp
+= 1;
451 if (*tmp
== '\\') tmp
+= 1;
453 info
->domain_controller_name
= talloc_strdup(mem_ctx
, tmp
);
454 if (info
->domain_controller_name
== NULL
) {
455 return WERR_GENERAL_FAILURE
;
459 if (&r
->uni_dc_address
) {
462 tmp
= rpcstr_pull_unistr2_talloc(mem_ctx
, &r
->uni_dc_address
);
464 return WERR_GENERAL_FAILURE
;
466 if (*tmp
== '\\') tmp
+= 1;
467 if (*tmp
== '\\') tmp
+= 1;
469 info
->domain_controller_address
= talloc_strdup(mem_ctx
, tmp
);
470 if (info
->domain_controller_address
== NULL
) {
471 return WERR_GENERAL_FAILURE
;
475 info
->domain_controller_address_type
= r
->dc_address_type
;
477 info
->domain_guid
= talloc_memdup(mem_ctx
, &r
->domain_guid
, sizeof(struct GUID
));
478 if (!info
->domain_guid
) {
479 return WERR_GENERAL_FAILURE
;
482 if (&r
->uni_domain_name
) {
483 info
->domain_name
= rpcstr_pull_unistr2_talloc(mem_ctx
, &r
->uni_domain_name
);
484 if (!info
->domain_name
) {
485 return WERR_GENERAL_FAILURE
;
489 if (&r
->uni_forest_name
) {
490 info
->dns_forest_name
= rpcstr_pull_unistr2_talloc(mem_ctx
, &r
->uni_forest_name
);
491 if (!info
->dns_forest_name
) {
492 return WERR_GENERAL_FAILURE
;
496 info
->flags
= r
->dc_flags
;
498 if (&r
->uni_dc_site_name
) {
499 info
->dc_site_name
= rpcstr_pull_unistr2_talloc(mem_ctx
, &r
->uni_dc_site_name
);
500 if (!info
->dc_site_name
) {
501 return WERR_GENERAL_FAILURE
;
505 if (&r
->uni_client_site_name
) {
506 info
->client_site_name
= rpcstr_pull_unistr2_talloc(mem_ctx
, &r
->uni_client_site_name
);
507 if (!info
->client_site_name
) {
508 return WERR_GENERAL_FAILURE
;
519 WERROR
rpccli_netlogon_dsr_getdcname(struct rpc_pipe_client
*cli
,
521 const char *server_name
,
522 const char *domain_name
,
523 struct GUID
*domain_guid
,
524 struct GUID
*site_guid
,
526 struct DS_DOMAIN_CONTROLLER_INFO
**info_out
)
528 prs_struct qbuf
, rbuf
;
529 NET_Q_DSR_GETDCNAME q
;
530 NET_R_DSR_GETDCNAME r
;
536 /* Initialize input parameters */
538 tmp_str
= talloc_asprintf(mem_ctx
, "\\\\%s", server_name
);
539 if (tmp_str
== NULL
) {
543 init_net_q_dsr_getdcname(&q
, tmp_str
, domain_name
, domain_guid
,
546 /* Marshall data and send request */
548 CLI_DO_RPC_WERR(cli
, mem_ctx
, PI_NETLOGON
, NET_DSR_GETDCNAME
,
551 net_io_q_dsr_getdcname
,
552 net_io_r_dsr_getdcname
,
553 WERR_GENERAL_FAILURE
);
555 if (!W_ERROR_IS_OK(r
.result
)) {
559 r
.result
= pull_domain_controller_info_from_getdcname_reply(mem_ctx
, info_out
, &r
);
560 if (!W_ERROR_IS_OK(r
.result
)) {
567 /* Dsr_GetDCNameEx */
569 WERROR
rpccli_netlogon_dsr_getdcnameex(struct rpc_pipe_client
*cli
,
571 const char *server_name
,
572 const char *domain_name
,
573 struct GUID
*domain_guid
,
574 const char *site_name
,
576 struct DS_DOMAIN_CONTROLLER_INFO
**info_out
)
578 prs_struct qbuf
, rbuf
;
579 NET_Q_DSR_GETDCNAMEEX q
;
580 NET_R_DSR_GETDCNAME r
;
586 /* Initialize input parameters */
588 tmp_str
= talloc_asprintf(mem_ctx
, "\\\\%s", server_name
);
589 if (tmp_str
== NULL
) {
593 init_net_q_dsr_getdcnameex(&q
, server_name
, domain_name
, domain_guid
,
596 /* Marshall data and send request */
598 CLI_DO_RPC_WERR(cli
, mem_ctx
, PI_NETLOGON
, NET_DSR_GETDCNAMEEX
,
601 net_io_q_dsr_getdcnameex
,
602 net_io_r_dsr_getdcname
,
603 WERR_GENERAL_FAILURE
);
605 if (!W_ERROR_IS_OK(r
.result
)) {
609 r
.result
= pull_domain_controller_info_from_getdcname_reply(mem_ctx
, info_out
, &r
);
610 if (!W_ERROR_IS_OK(r
.result
)) {
617 /* Dsr_GetDCNameEx */
619 WERROR
rpccli_netlogon_dsr_getdcnameex2(struct rpc_pipe_client
*cli
,
621 const char *server_name
,
622 const char *client_account
,
624 const char *domain_name
,
625 struct GUID
*domain_guid
,
626 const char *site_name
,
628 struct DS_DOMAIN_CONTROLLER_INFO
**info_out
)
630 prs_struct qbuf
, rbuf
;
631 NET_Q_DSR_GETDCNAMEEX2 q
;
632 NET_R_DSR_GETDCNAME r
;
638 /* Initialize input parameters */
640 tmp_str
= talloc_asprintf(mem_ctx
, "\\\\%s", server_name
);
641 if (tmp_str
== NULL
) {
645 init_net_q_dsr_getdcnameex2(&q
, server_name
, domain_name
, client_account
,
646 mask
, domain_guid
, site_name
, flags
);
648 /* Marshall data and send request */
650 CLI_DO_RPC_WERR(cli
, mem_ctx
, PI_NETLOGON
, NET_DSR_GETDCNAMEEX2
,
653 net_io_q_dsr_getdcnameex2
,
654 net_io_r_dsr_getdcname
,
655 WERR_GENERAL_FAILURE
);
657 if (!W_ERROR_IS_OK(r
.result
)) {
661 r
.result
= pull_domain_controller_info_from_getdcname_reply(mem_ctx
, info_out
, &r
);
662 if (!W_ERROR_IS_OK(r
.result
)) {
670 /* Dsr_GetSiteName */
672 WERROR
rpccli_netlogon_dsr_getsitename(struct rpc_pipe_client
*cli
,
674 const char *computer_name
,
677 prs_struct qbuf
, rbuf
;
678 NET_Q_DSR_GETSITENAME q
;
679 NET_R_DSR_GETSITENAME r
;
684 /* Initialize input parameters */
686 init_net_q_dsr_getsitename(&q
, computer_name
);
688 /* Marshall data and send request */
690 CLI_DO_RPC_WERR(cli
, mem_ctx
, PI_NETLOGON
, NET_DSR_GETSITENAME
,
693 net_io_q_dsr_getsitename
,
694 net_io_r_dsr_getsitename
,
695 WERR_GENERAL_FAILURE
);
697 if (!W_ERROR_IS_OK(r
.result
)) {
701 if ((site_name
!= NULL
) &&
702 ((*site_name
= rpcstr_pull_unistr2_talloc(
703 mem_ctx
, &r
.uni_site_name
)) == NULL
)) {
704 return WERR_GENERAL_FAILURE
;
712 /* Sam synchronisation */
714 NTSTATUS
rpccli_netlogon_sam_sync(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
715 uint32 database_id
, uint32 next_rid
, uint32
*num_deltas
,
716 SAM_DELTA_HDR
**hdr_deltas
,
717 SAM_DELTA_CTR
**deltas
)
719 prs_struct qbuf
, rbuf
;
722 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
729 ZERO_STRUCT(ret_creds
);
731 /* Initialise input parameters */
733 creds_client_step(cli
->dc
, &clnt_creds
);
735 init_net_q_sam_sync(&q
, cli
->dc
->remote_machine
, global_myname(),
736 &clnt_creds
, &ret_creds
, database_id
, next_rid
);
738 /* Marshall data and send request */
740 CLI_DO_RPC_COPY_SESS_KEY(cli
, mem_ctx
, PI_NETLOGON
, NET_SAM_SYNC
,
745 NT_STATUS_UNSUCCESSFUL
);
750 *num_deltas
= r
.num_deltas2
;
751 *hdr_deltas
= r
.hdr_deltas
;
754 if (!NT_STATUS_IS_ERR(result
)) {
755 /* Check returned credentials. */
756 if (!creds_client_check(cli
->dc
, &r
.srv_creds
.challenge
)) {
757 DEBUG(0,("cli_netlogon_sam_sync: credentials chain check failed\n"));
758 return NT_STATUS_ACCESS_DENIED
;
765 /* Sam synchronisation */
767 NTSTATUS
rpccli_netlogon_sam_deltas(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
768 uint32 database_id
, uint64 seqnum
,
770 SAM_DELTA_HDR
**hdr_deltas
,
771 SAM_DELTA_CTR
**deltas
)
773 prs_struct qbuf
, rbuf
;
776 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
782 /* Initialise input parameters */
784 creds_client_step(cli
->dc
, &clnt_creds
);
786 init_net_q_sam_deltas(&q
, cli
->dc
->remote_machine
,
787 global_myname(), &clnt_creds
,
788 database_id
, seqnum
);
790 /* Marshall data and send request */
792 CLI_DO_RPC(cli
, mem_ctx
, PI_NETLOGON
, NET_SAM_DELTAS
,
797 NT_STATUS_UNSUCCESSFUL
);
802 *num_deltas
= r
.num_deltas2
;
803 *hdr_deltas
= r
.hdr_deltas
;
806 if (!NT_STATUS_IS_ERR(result
)) {
807 /* Check returned credentials. */
808 if (!creds_client_check(cli
->dc
, &r
.srv_creds
.challenge
)) {
809 DEBUG(0,("cli_netlogon_sam_sync: credentials chain check failed\n"));
810 return NT_STATUS_ACCESS_DENIED
;
817 /* Logon domain user */
819 NTSTATUS
rpccli_netlogon_sam_logon(struct rpc_pipe_client
*cli
,
821 uint32 logon_parameters
,
823 const char *username
,
824 const char *password
,
825 const char *workstation
,
828 prs_struct qbuf
, rbuf
;
831 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
835 NET_USER_INFO_3 user
;
836 int validation_level
= 3;
837 fstring clnt_name_slash
;
841 ZERO_STRUCT(ret_creds
);
844 fstr_sprintf( clnt_name_slash
, "\\\\%s", workstation
);
846 fstr_sprintf( clnt_name_slash
, "\\\\%s", global_myname() );
849 /* Initialise input parameters */
851 creds_client_step(cli
->dc
, &clnt_creds
);
853 q
.validation_level
= validation_level
;
855 ctr
.switch_value
= logon_type
;
857 switch (logon_type
) {
858 case INTERACTIVE_LOGON_TYPE
: {
859 unsigned char lm_owf_user_pwd
[16], nt_owf_user_pwd
[16];
861 nt_lm_owf_gen(password
, nt_owf_user_pwd
, lm_owf_user_pwd
);
863 init_id_info1(&ctr
.auth
.id1
, domain
,
864 logon_parameters
, /* param_ctrl */
865 0xdead, 0xbeef, /* LUID? */
866 username
, clnt_name_slash
,
867 (const char *)cli
->dc
->sess_key
, lm_owf_user_pwd
,
872 case NET_LOGON_TYPE
: {
874 unsigned char local_lm_response
[24];
875 unsigned char local_nt_response
[24];
877 generate_random_buffer(chal
, 8);
879 SMBencrypt(password
, chal
, local_lm_response
);
880 SMBNTencrypt(password
, chal
, local_nt_response
);
882 init_id_info2(&ctr
.auth
.id2
, domain
,
883 logon_parameters
, /* param_ctrl */
884 0xdead, 0xbeef, /* LUID? */
885 username
, clnt_name_slash
, chal
,
886 local_lm_response
, 24, local_nt_response
, 24);
890 DEBUG(0, ("switch value %d not supported\n",
892 return NT_STATUS_INVALID_INFO_CLASS
;
897 init_sam_info(&q
.sam_id
, cli
->dc
->remote_machine
, global_myname(),
898 &clnt_creds
, &ret_creds
, logon_type
,
901 /* Marshall data and send request */
903 CLI_DO_RPC(cli
, mem_ctx
, PI_NETLOGON
, NET_SAMLOGON
,
908 NT_STATUS_UNSUCCESSFUL
);
914 if (r
.buffer_creds
) {
915 /* Check returned credentials if present. */
916 if (!creds_client_check(cli
->dc
, &r
.srv_creds
.challenge
)) {
917 DEBUG(0,("rpccli_netlogon_sam_logon: credentials chain check failed\n"));
918 return NT_STATUS_ACCESS_DENIED
;
927 * Logon domain user with an 'network' SAM logon
929 * @param info3 Pointer to a NET_USER_INFO_3 already allocated by the caller.
932 NTSTATUS
rpccli_netlogon_sam_network_logon(struct rpc_pipe_client
*cli
,
934 uint32 logon_parameters
,
936 const char *username
,
938 const char *workstation
,
940 DATA_BLOB lm_response
,
941 DATA_BLOB nt_response
,
942 NET_USER_INFO_3
*info3
)
944 prs_struct qbuf
, rbuf
;
947 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
949 int validation_level
= 3;
950 const char *workstation_name_slash
;
951 const char *server_name_slash
;
952 static uint8 zeros
[16];
959 ZERO_STRUCT(ret_creds
);
961 creds_client_step(cli
->dc
, &clnt_creds
);
963 if (server
[0] != '\\' && server
[1] != '\\') {
964 server_name_slash
= talloc_asprintf(mem_ctx
, "\\\\%s", server
);
966 server_name_slash
= server
;
969 if (workstation
[0] != '\\' && workstation
[1] != '\\') {
970 workstation_name_slash
= talloc_asprintf(mem_ctx
, "\\\\%s", workstation
);
972 workstation_name_slash
= workstation
;
975 if (!workstation_name_slash
|| !server_name_slash
) {
976 DEBUG(0, ("talloc_asprintf failed!\n"));
977 return NT_STATUS_NO_MEMORY
;
980 /* Initialise input parameters */
982 q
.validation_level
= validation_level
;
984 ctr
.switch_value
= NET_LOGON_TYPE
;
986 init_id_info2(&ctr
.auth
.id2
, domain
,
987 logon_parameters
, /* param_ctrl */
988 0xdead, 0xbeef, /* LUID? */
989 username
, workstation_name_slash
, (const uchar
*)chal
,
990 lm_response
.data
, lm_response
.length
, nt_response
.data
, nt_response
.length
);
992 init_sam_info(&q
.sam_id
, server_name_slash
, global_myname(),
993 &clnt_creds
, &ret_creds
, NET_LOGON_TYPE
,
998 /* Marshall data and send request */
1000 CLI_DO_RPC(cli
, mem_ctx
, PI_NETLOGON
, NET_SAMLOGON
,
1005 NT_STATUS_UNSUCCESSFUL
);
1007 if (memcmp(zeros
, info3
->user_sess_key
, 16) != 0) {
1008 SamOEMhash(info3
->user_sess_key
, cli
->dc
->sess_key
, 16);
1010 memset(info3
->user_sess_key
, '\0', 16);
1013 if (memcmp(zeros
, info3
->lm_sess_key
, 8) != 0) {
1014 SamOEMhash(info3
->lm_sess_key
, cli
->dc
->sess_key
, 8);
1016 memset(info3
->lm_sess_key
, '\0', 8);
1019 for (i
=0; i
< 7; i
++) {
1020 memset(&info3
->unknown
[i
], '\0', 4);
1023 /* Return results */
1027 if (r
.buffer_creds
) {
1028 /* Check returned credentials if present. */
1029 if (!creds_client_check(cli
->dc
, &r
.srv_creds
.challenge
)) {
1030 DEBUG(0,("rpccli_netlogon_sam_network_logon: credentials chain check failed\n"));
1031 return NT_STATUS_ACCESS_DENIED
;
1038 /***************************************************************************
1039 LSA Server Password Set.
1040 ****************************************************************************/
1042 NTSTATUS
rpccli_net_srv_pwset(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
1043 const char *machine_name
, const uint8 hashed_mach_pwd
[16])
1047 DOM_CRED clnt_creds
;
1050 uint16 sec_chan_type
= 2;
1053 creds_client_step(cli
->dc
, &clnt_creds
);
1055 DEBUG(4,("cli_net_srv_pwset: srv:%s acct:%s sc: %d mc: %s\n",
1056 cli
->dc
->remote_machine
, cli
->dc
->mach_acct
, sec_chan_type
, machine_name
));
1058 /* store the parameters */
1059 init_q_srv_pwset(&q
, cli
->dc
->remote_machine
, (const char *)cli
->dc
->sess_key
,
1060 cli
->dc
->mach_acct
, sec_chan_type
, machine_name
,
1061 &clnt_creds
, hashed_mach_pwd
);
1063 CLI_DO_RPC(cli
, mem_ctx
, PI_NETLOGON
, NET_SRVPWSET
,
1068 NT_STATUS_UNSUCCESSFUL
);
1072 if (!NT_STATUS_IS_OK(result
)) {
1073 /* report error code */
1074 DEBUG(0,("cli_net_srv_pwset: %s\n", nt_errstr(result
)));
1077 /* Always check returned credentials. */
1078 if (!creds_client_check(cli
->dc
, &r
.srv_cred
.challenge
)) {
1079 DEBUG(0,("rpccli_net_srv_pwset: credentials chain check failed\n"));
1080 return NT_STATUS_ACCESS_DENIED
;