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 if (NT_STATUS_IS_OK(result)) {
189 *srv_chal_out = r.srv_chal;
190 *neg_flags_inout = r.srv_flgs.neg_flags;
196 #if 0 /* not currebntly used */
197 /****************************************************************************
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,
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;
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,
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;
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,
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;
268 SMB_ASSERT(cli->pipe_idx == PI_NETLOGON);
272 return NT_STATUS_INVALID_PARAMETER;
275 /* Ensure we don't reuse any of this state. */
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,
299 if (!NT_STATUS_IS_OK(result)) {
303 /* Calculate the session key and client credentials */
304 creds_client_init(dc,
311 * Send client auth-2 challenge and receive server repy.
314 result = rpccli_net_auth2(cli,
321 &clnt_chal_send, /* input. */
322 &srv_chal_recv); /* output */
324 if (!NT_STATUS_IS_OK(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 ));
350 /* Logon Control 2 */
352 NTSTATUS rpccli_netlogon_logon_ctrl2(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
355 prs_struct qbuf, rbuf;
358 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
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,
374 net_io_q_logon_ctrl2,
375 net_io_r_logon_ctrl2,
376 NT_STATUS_UNSUCCESSFUL);
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;
392 fstring mydcname_slash;
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,
409 NT_STATUS_UNSUCCESSFUL);
413 if (NT_STATUS_IS_OK(result)) {
414 rpcstr_pull_unistr2_fstring(newdcname, &r.uni_dcname);
422 WERROR rpccli_netlogon_dsr_getdcname(struct rpc_pipe_client *cli,
424 const char *server_name,
425 const char *domain_name,
426 struct uuid *domain_guid,
427 struct uuid *site_guid,
429 char **dc_unc, char **dc_address,
430 int32 *dc_address_type,
431 struct uuid *domain_guid_out,
432 char **domain_name_out,
436 char **client_site_name)
438 prs_struct qbuf, rbuf;
439 NET_Q_DSR_GETDCNAME q;
440 NET_R_DSR_GETDCNAME r;
446 /* Initialize input parameters */
448 tmp_str = talloc_asprintf(mem_ctx, "\\\\%s", server_name);
449 if (tmp_str == NULL) {
453 init_net_q_dsr_getdcname(&q, tmp_str, domain_name, domain_guid,
456 /* Marshall data and send request */
458 CLI_DO_RPC_WERR(cli, mem_ctx, PI_NETLOGON, NET_DSR_GETDCNAME,
461 net_io_q_dsr_getdcname,
462 net_io_r_dsr_getdcname,
463 WERR_GENERAL_FAILURE);
465 if (!W_ERROR_IS_OK(r.result)) {
469 if (dc_unc != NULL) {
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
480 *dc_unc = talloc_strdup(mem_ctx, tmp);
481 if (*dc_unc == NULL) {
486 if (dc_address != NULL) {
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
497 *dc_address = talloc_strdup(mem_ctx, tmp);
498 if (*dc_address == NULL) {
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;
542 /* Dsr_GetSiteName */
544 WERROR rpccli_netlogon_dsr_getsitename(struct rpc_pipe_client *cli,
546 const char *computer_name,
549 prs_struct qbuf, rbuf;
550 NET_Q_DSR_GETSITENAME q;
551 NET_R_DSR_GETSITENAME 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,
565 net_io_q_dsr_getsitename,
566 net_io_r_dsr_getsitename,
567 WERR_GENERAL_FAILURE);
569 if (!W_ERROR_IS_OK(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;
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;
594 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
601 ZERO_STRUCT(ret_creds);
603 /* Initialise input parameters */
605 creds_client_step(cli->dc, &clnt_creds);
607 init_net_q_sam_sync(&q, cli->dc->remote_machine, global_myname(),
608 &clnt_creds, &ret_creds, database_id, next_rid);
610 /* Marshall data and send request */
612 CLI_DO_RPC_COPY_SESS_KEY(cli, mem_ctx, PI_NETLOGON, NET_SAM_SYNC,
617 NT_STATUS_UNSUCCESSFUL);
622 *num_deltas = r.num_deltas2;
623 *hdr_deltas = r.hdr_deltas;
626 if (!NT_STATUS_IS_ERR(result)) {
627 /* Check returned credentials. */
628 if (!creds_client_check(cli->dc, &r.srv_creds.challenge)) {
629 DEBUG(0,("cli_netlogon_sam_sync: credentials chain check failed\n"));
630 return NT_STATUS_ACCESS_DENIED;
637 /* Sam synchronisation */
639 NTSTATUS rpccli_netlogon_sam_deltas(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
640 uint32 database_id, UINT64_S seqnum,
642 SAM_DELTA_HDR **hdr_deltas,
643 SAM_DELTA_CTR **deltas)
645 prs_struct qbuf, rbuf;
648 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
654 /* Initialise input parameters */
656 creds_client_step(cli->dc, &clnt_creds);
658 init_net_q_sam_deltas(&q, cli->dc->remote_machine,
659 global_myname(), &clnt_creds,
660 database_id, seqnum);
662 /* Marshall data and send request */
664 CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_SAM_DELTAS,
669 NT_STATUS_UNSUCCESSFUL);
674 *num_deltas = r.num_deltas2;
675 *hdr_deltas = r.hdr_deltas;
678 if (!NT_STATUS_IS_ERR(result)) {
679 /* Check returned credentials. */
680 if (!creds_client_check(cli->dc, &r.srv_creds.challenge)) {
681 DEBUG(0,("cli_netlogon_sam_sync: credentials chain check failed\n"));
682 return NT_STATUS_ACCESS_DENIED;
689 /* Logon domain user */
691 NTSTATUS rpccli_netlogon_sam_logon(struct rpc_pipe_client *cli,
693 uint32 logon_parameters,
695 const char *username,
696 const char *password,
699 prs_struct qbuf, rbuf;
702 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
706 NET_USER_INFO_3 user;
707 int validation_level = 3;
708 fstring clnt_name_slash;
712 ZERO_STRUCT(ret_creds);
714 fstr_sprintf( clnt_name_slash, "\\\\%s", global_myname() );
716 /* Initialise input parameters */
718 creds_client_step(cli->dc, &clnt_creds);
720 q.validation_level = validation_level;
722 ctr.switch_value = logon_type;
724 switch (logon_type) {
725 case INTERACTIVE_LOGON_TYPE: {
726 unsigned char lm_owf_user_pwd[16], nt_owf_user_pwd[16];
728 nt_lm_owf_gen(password, nt_owf_user_pwd, lm_owf_user_pwd);
730 init_id_info1(&ctr.auth.id1, domain,
731 logon_parameters, /* param_ctrl */
732 0xdead, 0xbeef, /* LUID? */
733 username, clnt_name_slash,
734 (const char *)cli->dc->sess_key, lm_owf_user_pwd,
739 case NET_LOGON_TYPE: {
741 unsigned char local_lm_response[24];
742 unsigned char local_nt_response[24];
744 generate_random_buffer(chal, 8);
746 SMBencrypt(password, chal, local_lm_response);
747 SMBNTencrypt(password, chal, local_nt_response);
749 init_id_info2(&ctr.auth.id2, domain,
750 logon_parameters, /* param_ctrl */
751 0xdead, 0xbeef, /* LUID? */
752 username, clnt_name_slash, chal,
753 local_lm_response, 24, local_nt_response, 24);
757 DEBUG(0, ("switch value %d not supported\n",
759 return NT_STATUS_INVALID_INFO_CLASS;
764 init_sam_info(&q.sam_id, cli->dc->remote_machine, global_myname(),
765 &clnt_creds, &ret_creds, logon_type,
768 /* Marshall data and send request */
770 CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_SAMLOGON,
775 NT_STATUS_UNSUCCESSFUL);
781 if (r.buffer_creds) {
782 /* Check returned credentials if present. */
783 if (!creds_client_check(cli->dc, &r.srv_creds.challenge)) {
784 DEBUG(0,("rpccli_netlogon_sam_logon: credentials chain check failed\n"));
785 return NT_STATUS_ACCESS_DENIED;
794 * Logon domain user with an 'network' SAM logon
796 * @param info3 Pointer to a NET_USER_INFO_3 already allocated by the caller.
799 NTSTATUS rpccli_netlogon_sam_network_logon(struct rpc_pipe_client *cli,
801 uint32 logon_parameters,
803 const char *username,
805 const char *workstation,
807 DATA_BLOB lm_response,
808 DATA_BLOB nt_response,
809 NET_USER_INFO_3 *info3)
811 prs_struct qbuf, rbuf;
814 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
816 int validation_level = 3;
817 const char *workstation_name_slash;
818 const char *server_name_slash;
819 static uint8 zeros[16];
826 ZERO_STRUCT(ret_creds);
828 creds_client_step(cli->dc, &clnt_creds);
830 if (server[0] != '\\' && server[1] != '\\') {
831 server_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", server);
833 server_name_slash = server;
836 if (workstation[0] != '\\' && workstation[1] != '\\') {
837 workstation_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", workstation);
839 workstation_name_slash = workstation;
842 if (!workstation_name_slash || !server_name_slash) {
843 DEBUG(0, ("talloc_asprintf failed!\n"));
844 return NT_STATUS_NO_MEMORY;
847 /* Initialise input parameters */
849 q.validation_level = validation_level;
851 ctr.switch_value = NET_LOGON_TYPE;
853 init_id_info2(&ctr.auth.id2, domain,
854 logon_parameters, /* param_ctrl */
855 0xdead, 0xbeef, /* LUID? */
856 username, workstation_name_slash, (const uchar*)chal,
857 lm_response.data, lm_response.length, nt_response.data, nt_response.length);
859 init_sam_info(&q.sam_id, server_name_slash, global_myname(),
860 &clnt_creds, &ret_creds, NET_LOGON_TYPE,
865 /* Marshall data and send request */
867 CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_SAMLOGON,
872 NT_STATUS_UNSUCCESSFUL);
874 if (memcmp(zeros, info3->user_sess_key, 16) != 0) {
875 SamOEMhash(info3->user_sess_key, cli->dc->sess_key, 16);
877 memset(info3->user_sess_key, '\0', 16);
880 if (memcmp(zeros, info3->lm_sess_key, 8) != 0) {
881 SamOEMhash(info3->lm_sess_key, cli->dc->sess_key, 8);
883 memset(info3->lm_sess_key, '\0', 8);
886 memset(&info3->acct_flags, '\0', 4);
887 for (i=0; i < 7; i++) {
888 memset(&info3->unknown[i], '\0', 4);
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;
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])
918 uint16 sec_chan_type = 2;
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,
936 NT_STATUS_UNSUCCESSFUL);
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;