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(*neg_flags_inout,
312 * Send client auth-2 challenge and receive server repy.
315 result = rpccli_net_auth2(cli,
322 &clnt_chal_send, /* input. */
323 &srv_chal_recv); /* output */
325 if (!NT_STATUS_IS_OK(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 ));
351 /* Logon Control 2 */
353 NTSTATUS rpccli_netlogon_logon_ctrl2(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
356 prs_struct qbuf, rbuf;
359 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
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,
375 net_io_q_logon_ctrl2,
376 net_io_r_logon_ctrl2,
377 NT_STATUS_UNSUCCESSFUL);
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;
393 fstring mydcname_slash;
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,
410 WERR_GENERAL_FAILURE);
414 if (W_ERROR_IS_OK(result)) {
415 rpcstr_pull_unistr2_fstring(newdcname, &r.uni_dcname);
423 WERROR rpccli_netlogon_getanydcname(struct rpc_pipe_client *cli,
424 TALLOC_CTX *mem_ctx, const char *mydcname,
425 const char *domainname, fstring newdcname)
427 prs_struct qbuf, rbuf;
428 NET_Q_GETANYDCNAME q;
429 NET_R_GETANYDCNAME r;
431 fstring mydcname_slash;
436 /* Initialise input parameters */
438 slprintf(mydcname_slash, sizeof(fstring)-1, "\\\\%s", mydcname);
439 init_net_q_getanydcname(&q, mydcname_slash, domainname);
441 /* Marshall data and send request */
443 CLI_DO_RPC_WERR(cli, mem_ctx, PI_NETLOGON, NET_GETANYDCNAME,
446 net_io_q_getanydcname,
447 net_io_r_getanydcname,
448 WERR_GENERAL_FAILURE);
452 if (W_ERROR_IS_OK(result)) {
453 rpcstr_pull_unistr2_fstring(newdcname, &r.uni_dcname);
461 WERROR rpccli_netlogon_dsr_getdcname(struct rpc_pipe_client *cli,
463 const char *server_name,
464 const char *domain_name,
465 struct GUID *domain_guid,
466 struct GUID *site_guid,
468 char **dc_unc, char **dc_address,
469 int32 *dc_address_type,
470 struct GUID *domain_guid_out,
471 char **domain_name_out,
475 char **client_site_name)
477 prs_struct qbuf, rbuf;
478 NET_Q_DSR_GETDCNAME q;
479 NET_R_DSR_GETDCNAME r;
485 /* Initialize input parameters */
487 tmp_str = talloc_asprintf(mem_ctx, "\\\\%s", server_name);
488 if (tmp_str == NULL) {
492 init_net_q_dsr_getdcname(&q, tmp_str, domain_name, domain_guid,
495 /* Marshall data and send request */
497 CLI_DO_RPC_WERR(cli, mem_ctx, PI_NETLOGON, NET_DSR_GETDCNAME,
500 net_io_q_dsr_getdcname,
501 net_io_r_dsr_getdcname,
502 WERR_GENERAL_FAILURE);
504 if (!W_ERROR_IS_OK(r.result)) {
508 if (dc_unc != NULL) {
510 tmp = rpcstr_pull_unistr2_talloc(mem_ctx, &r.uni_dc_unc);
512 return WERR_GENERAL_FAILURE;
514 if (*tmp == '\\') tmp += 1;
515 if (*tmp == '\\') tmp += 1;
517 /* We have to talloc_strdup, otherwise a talloc_steal would
519 *dc_unc = talloc_strdup(mem_ctx, tmp);
520 if (*dc_unc == NULL) {
525 if (dc_address != NULL) {
527 tmp = rpcstr_pull_unistr2_talloc(mem_ctx, &r.uni_dc_address);
529 return WERR_GENERAL_FAILURE;
531 if (*tmp == '\\') tmp += 1;
532 if (*tmp == '\\') tmp += 1;
534 /* We have to talloc_strdup, otherwise a talloc_steal would
536 *dc_address = talloc_strdup(mem_ctx, tmp);
537 if (*dc_address == NULL) {
542 if (dc_address_type != NULL) {
543 *dc_address_type = r.dc_address_type;
546 if (domain_guid_out != NULL) {
547 *domain_guid_out = r.domain_guid;
550 if ((domain_name_out != NULL) &&
551 ((*domain_name_out = rpcstr_pull_unistr2_talloc(
552 mem_ctx, &r.uni_domain_name)) == NULL)) {
553 return WERR_GENERAL_FAILURE;
556 if ((forest_name != NULL) &&
557 ((*forest_name = rpcstr_pull_unistr2_talloc(
558 mem_ctx, &r.uni_forest_name)) == NULL)) {
559 return WERR_GENERAL_FAILURE;
562 if (dc_flags != NULL) {
563 *dc_flags = r.dc_flags;
566 if ((dc_site_name != NULL) &&
567 ((*dc_site_name = rpcstr_pull_unistr2_talloc(
568 mem_ctx, &r.uni_dc_site_name)) == NULL)) {
569 return WERR_GENERAL_FAILURE;
572 if ((client_site_name != NULL) &&
573 ((*client_site_name = rpcstr_pull_unistr2_talloc(
574 mem_ctx, &r.uni_client_site_name)) == NULL)) {
575 return WERR_GENERAL_FAILURE;
581 /* Dsr_GetSiteName */
583 WERROR rpccli_netlogon_dsr_getsitename(struct rpc_pipe_client *cli,
585 const char *computer_name,
588 prs_struct qbuf, rbuf;
589 NET_Q_DSR_GETSITENAME q;
590 NET_R_DSR_GETSITENAME r;
595 /* Initialize input parameters */
597 init_net_q_dsr_getsitename(&q, computer_name);
599 /* Marshall data and send request */
601 CLI_DO_RPC_WERR(cli, mem_ctx, PI_NETLOGON, NET_DSR_GETSITENAME,
604 net_io_q_dsr_getsitename,
605 net_io_r_dsr_getsitename,
606 WERR_GENERAL_FAILURE);
608 if (!W_ERROR_IS_OK(r.result)) {
612 if ((site_name != NULL) &&
613 ((*site_name = rpcstr_pull_unistr2_talloc(
614 mem_ctx, &r.uni_site_name)) == NULL)) {
615 return WERR_GENERAL_FAILURE;
623 /* Sam synchronisation */
625 NTSTATUS rpccli_netlogon_sam_sync(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
626 uint32 database_id, uint32 next_rid, uint32 *num_deltas,
627 SAM_DELTA_HDR **hdr_deltas,
628 SAM_DELTA_CTR **deltas)
630 prs_struct qbuf, rbuf;
633 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
640 ZERO_STRUCT(ret_creds);
642 /* Initialise input parameters */
644 creds_client_step(cli->dc, &clnt_creds);
646 init_net_q_sam_sync(&q, cli->dc->remote_machine, global_myname(),
647 &clnt_creds, &ret_creds, database_id, next_rid);
649 /* Marshall data and send request */
651 CLI_DO_RPC_COPY_SESS_KEY(cli, mem_ctx, PI_NETLOGON, NET_SAM_SYNC,
656 NT_STATUS_UNSUCCESSFUL);
661 *num_deltas = r.num_deltas2;
662 *hdr_deltas = r.hdr_deltas;
665 if (!NT_STATUS_IS_ERR(result)) {
666 /* Check returned credentials. */
667 if (!creds_client_check(cli->dc, &r.srv_creds.challenge)) {
668 DEBUG(0,("cli_netlogon_sam_sync: credentials chain check failed\n"));
669 return NT_STATUS_ACCESS_DENIED;
676 /* Sam synchronisation */
678 NTSTATUS rpccli_netlogon_sam_deltas(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
679 uint32 database_id, uint64 seqnum,
681 SAM_DELTA_HDR **hdr_deltas,
682 SAM_DELTA_CTR **deltas)
684 prs_struct qbuf, rbuf;
687 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
693 /* Initialise input parameters */
695 creds_client_step(cli->dc, &clnt_creds);
697 init_net_q_sam_deltas(&q, cli->dc->remote_machine,
698 global_myname(), &clnt_creds,
699 database_id, seqnum);
701 /* Marshall data and send request */
703 CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_SAM_DELTAS,
708 NT_STATUS_UNSUCCESSFUL);
713 *num_deltas = r.num_deltas2;
714 *hdr_deltas = r.hdr_deltas;
717 if (!NT_STATUS_IS_ERR(result)) {
718 /* Check returned credentials. */
719 if (!creds_client_check(cli->dc, &r.srv_creds.challenge)) {
720 DEBUG(0,("cli_netlogon_sam_sync: credentials chain check failed\n"));
721 return NT_STATUS_ACCESS_DENIED;
728 /* Logon domain user */
730 NTSTATUS rpccli_netlogon_sam_logon(struct rpc_pipe_client *cli,
732 uint32 logon_parameters,
734 const char *username,
735 const char *password,
736 const char *workstation,
739 prs_struct qbuf, rbuf;
742 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
746 NET_USER_INFO_3 user;
747 int validation_level = 3;
748 fstring clnt_name_slash;
752 ZERO_STRUCT(ret_creds);
755 fstr_sprintf( clnt_name_slash, "\\\\%s", workstation );
757 fstr_sprintf( clnt_name_slash, "\\\\%s", global_myname() );
760 /* Initialise input parameters */
762 creds_client_step(cli->dc, &clnt_creds);
764 q.validation_level = validation_level;
766 ctr.switch_value = logon_type;
768 switch (logon_type) {
769 case INTERACTIVE_LOGON_TYPE: {
770 unsigned char lm_owf_user_pwd[16], nt_owf_user_pwd[16];
772 nt_lm_owf_gen(password, nt_owf_user_pwd, lm_owf_user_pwd);
774 init_id_info1(&ctr.auth.id1, domain,
775 logon_parameters, /* param_ctrl */
776 0xdead, 0xbeef, /* LUID? */
777 username, clnt_name_slash,
778 (const char *)cli->dc->sess_key, lm_owf_user_pwd,
783 case NET_LOGON_TYPE: {
785 unsigned char local_lm_response[24];
786 unsigned char local_nt_response[24];
788 generate_random_buffer(chal, 8);
790 SMBencrypt(password, chal, local_lm_response);
791 SMBNTencrypt(password, chal, local_nt_response);
793 init_id_info2(&ctr.auth.id2, domain,
794 logon_parameters, /* param_ctrl */
795 0xdead, 0xbeef, /* LUID? */
796 username, clnt_name_slash, chal,
797 local_lm_response, 24, local_nt_response, 24);
801 DEBUG(0, ("switch value %d not supported\n",
803 return NT_STATUS_INVALID_INFO_CLASS;
808 init_sam_info(&q.sam_id, cli->dc->remote_machine, global_myname(),
809 &clnt_creds, &ret_creds, logon_type,
812 /* Marshall data and send request */
814 CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_SAMLOGON,
819 NT_STATUS_UNSUCCESSFUL);
825 if (r.buffer_creds) {
826 /* Check returned credentials if present. */
827 if (!creds_client_check(cli->dc, &r.srv_creds.challenge)) {
828 DEBUG(0,("rpccli_netlogon_sam_logon: credentials chain check failed\n"));
829 return NT_STATUS_ACCESS_DENIED;
838 * Logon domain user with an 'network' SAM logon
840 * @param info3 Pointer to a NET_USER_INFO_3 already allocated by the caller.
843 NTSTATUS rpccli_netlogon_sam_network_logon(struct rpc_pipe_client *cli,
845 uint32 logon_parameters,
847 const char *username,
849 const char *workstation,
851 DATA_BLOB lm_response,
852 DATA_BLOB nt_response,
853 NET_USER_INFO_3 *info3)
855 prs_struct qbuf, rbuf;
858 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
860 int validation_level = 3;
861 const char *workstation_name_slash;
862 const char *server_name_slash;
863 static uint8 zeros[16];
870 ZERO_STRUCT(ret_creds);
872 creds_client_step(cli->dc, &clnt_creds);
874 if (server[0] != '\\' && server[1] != '\\') {
875 server_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", server);
877 server_name_slash = server;
880 if (workstation[0] != '\\' && workstation[1] != '\\') {
881 workstation_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", workstation);
883 workstation_name_slash = workstation;
886 if (!workstation_name_slash || !server_name_slash) {
887 DEBUG(0, ("talloc_asprintf failed!\n"));
888 return NT_STATUS_NO_MEMORY;
891 /* Initialise input parameters */
893 q.validation_level = validation_level;
895 ctr.switch_value = NET_LOGON_TYPE;
897 init_id_info2(&ctr.auth.id2, domain,
898 logon_parameters, /* param_ctrl */
899 0xdead, 0xbeef, /* LUID? */
900 username, workstation_name_slash, (const uchar*)chal,
901 lm_response.data, lm_response.length, nt_response.data, nt_response.length);
903 init_sam_info(&q.sam_id, server_name_slash, global_myname(),
904 &clnt_creds, &ret_creds, NET_LOGON_TYPE,
909 /* Marshall data and send request */
911 CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_SAMLOGON,
916 NT_STATUS_UNSUCCESSFUL);
918 if (memcmp(zeros, info3->user_sess_key, 16) != 0) {
919 SamOEMhash(info3->user_sess_key, cli->dc->sess_key, 16);
921 memset(info3->user_sess_key, '\0', 16);
924 if (memcmp(zeros, info3->lm_sess_key, 8) != 0) {
925 SamOEMhash(info3->lm_sess_key, cli->dc->sess_key, 8);
927 memset(info3->lm_sess_key, '\0', 8);
930 for (i=0; i < 7; i++) {
931 memset(&info3->unknown[i], '\0', 4);
938 if (r.buffer_creds) {
939 /* Check returned credentials if present. */
940 if (!creds_client_check(cli->dc, &r.srv_creds.challenge)) {
941 DEBUG(0,("rpccli_netlogon_sam_network_logon: credentials chain check failed\n"));
942 return NT_STATUS_ACCESS_DENIED;
949 /***************************************************************************
950 LSA Server Password Set.
951 ****************************************************************************/
953 NTSTATUS rpccli_net_srv_pwset(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
954 const char *machine_name, const uint8 hashed_mach_pwd[16])
961 uint16 sec_chan_type = 2;
964 creds_client_step(cli->dc, &clnt_creds);
966 DEBUG(4,("cli_net_srv_pwset: srv:%s acct:%s sc: %d mc: %s\n",
967 cli->dc->remote_machine, cli->dc->mach_acct, sec_chan_type, machine_name));
969 /* store the parameters */
970 init_q_srv_pwset(&q, cli->dc->remote_machine, (const char *)cli->dc->sess_key,
971 cli->dc->mach_acct, sec_chan_type, machine_name,
972 &clnt_creds, hashed_mach_pwd);
974 CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_SRVPWSET,
979 NT_STATUS_UNSUCCESSFUL);
983 if (!NT_STATUS_IS_OK(result)) {
984 /* report error code */
985 DEBUG(0,("cli_net_srv_pwset: %s\n", nt_errstr(result)));
988 /* Always check returned credentials. */
989 if (!creds_client_check(cli->dc, &r.srv_cred.challenge)) {
990 DEBUG(0,("rpccli_net_srv_pwset: credentials chain check failed\n"));
991 return NT_STATUS_ACCESS_DENIED;