dce/rpc
authorLuke Leighton <lkcl@samba.org>
Fri, 9 Oct 1998 23:31:50 +0000 (23:31 +0000)
committerLuke Leighton <lkcl@samba.org>
Fri, 9 Oct 1998 23:31:50 +0000 (23:31 +0000)
(This used to be commit 8a7ac4a25d177235a98c0f84f97ee50432fb6359)

source3/include/proto.h
source3/include/rpc_samr.h
source3/libsmb/clientgen.c
source3/libsmb/smbencrypt.c
source3/rpc_client/cli_samr.c
source3/rpc_parse/parse_samr.c
source3/rpcclient/cmd_samr.c

index 2d64d8df4575ee56c742261028513fcdb271a271..c473aeb38e9b8fee1d73d25cbbc2b2f82b949e18 100644 (file)
@@ -511,6 +511,7 @@ void nt_lm_owf_gen(char *pwd, uchar nt_p16[16], uchar p16[16]);
 void SMBOWFencrypt(uchar passwd[16], uchar *c8, uchar p24[24]);
 void NTLMSSPOWFencrypt(uchar passwd[8], uchar *ntlmchalresp, uchar p24[24]);
 void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24);
+BOOL make_oem_passwd_hash(char data[516], char *passwd, char old_pw_hash[16]);
 
 /*The following definitions come from  libsmb/smberr.c  */
 
@@ -1270,6 +1271,10 @@ BOOL get_samr_query_userinfo(struct cli_state *cli,
                                POLICY_HND *pol_open_domain,
                                uint32 info_level,
                                uint32 user_rid, SAM_USER_INFO_21 *usr);
+BOOL do_samr_chgpasswd_user(struct cli_state *cli,
+               char *srv_name, char *user_name,
+               char nt_newpass[516], char nt_oldhash[16],
+               char lm_newpass[516], char lm_oldhash[16]);
 BOOL do_samr_unknown_38(struct cli_state *cli, char *srv_name);
 BOOL do_samr_unknown_8(struct cli_state *cli, 
                                POLICY_HND *domain_pol, uint16 switch_value);
@@ -1709,13 +1714,6 @@ void make_samr_q_open_alias(SAMR_Q_OPEN_ALIAS *q_u,
                                uint32 unknown_0, uint32 rid);
 void samr_io_q_open_alias(char *desc,  SAMR_Q_OPEN_ALIAS *q_u, prs_struct *ps, int depth);
 void samr_io_r_open_alias(char *desc,  SAMR_R_OPEN_ALIAS *r_u, prs_struct *ps, int depth);
-void make_samr_q_unknown_38(SAMR_Q_UNKNOWN_38 *q_u, char *srv_name);
-void samr_io_q_unknown_38(char *desc,  SAMR_Q_UNKNOWN_38 *q_u, prs_struct *ps, int depth);
-void make_samr_r_unknown_38(SAMR_R_UNKNOWN_38 *r_u,
-                               uint16 level, uint32 status);
-void samr_io_r_unknown_38(char *desc,  SAMR_R_UNKNOWN_38 *r_u, prs_struct *ps, int depth);
-void samr_io_enc_passwd(char *desc, SAMR_ENC_PASSWD *pwd, prs_struct *ps, int depth);
-void samr_io_enc_hash(char *desc, SAMR_ENC_HASH *hsh, prs_struct *ps, int depth);
 void make_samr_q_unknown_12(SAMR_Q_UNKNOWN_12 *q_u,
                POLICY_HND *pol, uint32 rid,
                uint32 num_gids, uint32 *gid);
@@ -1723,6 +1721,21 @@ void make_samr_q_unknown_21(SAMR_Q_UNKNOWN_21 *q_c,
                                POLICY_HND *hnd, uint16 unk_1, uint16 unk_2);
 void make_samr_q_unknown_13(SAMR_Q_UNKNOWN_13 *q_c,
                                POLICY_HND *hnd, uint16 unk_1, uint16 unk_2);
+void make_samr_q_unknown_38(SAMR_Q_UNKNOWN_38 *q_u, char *srv_name);
+void samr_io_q_unknown_38(char *desc,  SAMR_Q_UNKNOWN_38 *q_u, prs_struct *ps, int depth);
+void make_samr_r_unknown_38(SAMR_R_UNKNOWN_38 *r_u,
+                               uint16 level, uint32 status);
+void samr_io_r_unknown_38(char *desc,  SAMR_R_UNKNOWN_38 *r_u, prs_struct *ps, int depth);
+void make_enc_passwd(SAMR_ENC_PASSWD *pwd, char pass[512]);
+void samr_io_enc_passwd(char *desc, SAMR_ENC_PASSWD *pwd, prs_struct *ps, int depth);
+void make_enc_hash(SAMR_ENC_HASH *hsh, char hash[16]);
+void samr_io_enc_hash(char *desc, SAMR_ENC_HASH *hsh, prs_struct *ps, int depth);
+void make_samr_q_chgpasswd_user(SAMR_Q_CHGPASSWD_USER *q_u,
+                               char *dest_host, char *user_name,
+                               char nt_newpass[516], char nt_oldhash[16],
+                               char lm_newpass[516], char lm_oldhash[16]);
+void samr_io_q_chgpasswd_user(char *desc, SAMR_Q_CHGPASSWD_USER *q_u, prs_struct *ps, int depth);
+void samr_io_r_chgpasswd_user(char *desc, SAMR_R_CHGPASSWD_USER *r_u, prs_struct *ps, int depth);
 
 /*The following definitions come from  rpc_parse/parse_srv.c  */
 
index 5f1a4bb36e4bde2486fd1fdbbb53142b187fcc7a..f27dc663817115dfa487302c85c31e8022580170 100644 (file)
@@ -91,6 +91,7 @@ SamrTestPrivateFunctionsUser
 #define SAMR_UNKNOWN_21        0x21
 #define SAMR_UNKNOWN_32        0x32
 #define SAMR_UNKNOWN_34        0x34
+#define SAMR_CHGPASSWD_USER    0x37
 #define SAMR_UNKNOWN_38        0x38
 #define SAMR_CONNECT           0x39
 #define SAMR_OPEN_ALIAS        0x1b
@@ -997,8 +998,8 @@ typedef struct q_samr_chgpasswd_user_info
 {
        uint32 ptr_0;
 
-       UNIHDR hdr_server; /* server name unicode header */
-       UNISTR2 uni_server; /* server name unicode string */
+       UNIHDR hdr_dest_host; /* server name unicode header */
+       UNISTR2 uni_dest_host; /* server name unicode string */
 
        UNIHDR hdr_user_name;    /* username unicode string header */
        UNISTR2 uni_user_name;    /* username unicode string */
@@ -1006,7 +1007,7 @@ typedef struct q_samr_chgpasswd_user_info
        SAMR_ENC_PASSWD nt_newpass;
        SAMR_ENC_HASH nt_oldhash;
 
-       uint32 unknown_1; /* seems to always contain 0001 */
+       uint32 unknown; /* 0x0000 0001 */
 
        SAMR_ENC_PASSWD lm_newpass;
        SAMR_ENC_HASH lm_oldhash;
@@ -1016,7 +1017,7 @@ typedef struct q_samr_chgpasswd_user_info
 /* SAMR_R_CHGPASSWD_USER */
 typedef struct r_samr_chgpasswd_user_info
 {
-       uint32 result; /* 0 == OK, C000006A (NT_STATUS_WRONG_PASSWORD) */
+       uint32 status; /* 0 == OK, C000006A (NT_STATUS_WRONG_PASSWORD) */
 
 } SAMR_R_CHGPASSWD_USER;
 
index 025ec5e73f0ac5e4b92043a0c6ab5e479c99e720..72d7ca935b27b8ccaff33948c83a17ecf0356d30 100644 (file)
@@ -2021,7 +2021,6 @@ BOOL cli_oem_change_password(struct cli_state *cli, char *user, char *new_passwo
   unsigned char new_pw_hash[16];
   int data_len;
   int param_len = 0;
-  int new_pw_len = strlen(new_password);
   char *rparam = NULL;
   char *rdata = NULL;
   int rprcnt, rdrcnt;
@@ -2031,11 +2030,6 @@ BOOL cli_oem_change_password(struct cli_state *cli, char *user, char *new_passwo
     return False;
   }
 
-  if (new_pw_len > 512) {
-    DEBUG(0,("cli_oem_change_password: new password for user %s is too long.\n", user));
-    return False;
-  }
-
   SSVAL(p,0,214); /* SamOEMChangePassword command. */
   p += 2;
   pstrcpy(p, "zsT");
@@ -2049,26 +2043,19 @@ BOOL cli_oem_change_password(struct cli_state *cli, char *user, char *new_passwo
 
   param_len = PTR_DIFF(p,param);
 
-  /*
-   * Now setup the data area.
-   * We need to generate a random fill
-   * for this area to make it harder to
-   * decrypt. JRA.
-   */
-  generate_random_buffer((unsigned char *)data, sizeof(data), False);
-  fstrcpy( &data[512 - new_pw_len], new_password);
-  SIVAL(data, 512, new_pw_len);
-
   /*
    * Get the Lanman hash of the old password, we
-   * use this as the key to SamOEMHash().
+   * use this as the key to make_oem_passwd_hash().
    */
   memset(upper_case_old_pw, '\0', sizeof(upper_case_old_pw));
   fstrcpy(upper_case_old_pw, old_password);
   strupper(upper_case_old_pw);
   E_P16((uchar *)upper_case_old_pw, old_pw_hash);
 
-  SamOEMhash( (unsigned char *)data, (unsigned char *)old_pw_hash, True);
+       if (!make_oem_passwd_hash( data, new_password, old_pw_hash))
+       {
+               return False;
+       }
 
   /* 
    * Now place the old password hash in the data.
index a9e680ccdd5875a5e492e4f9cb1885f3cac12c12..27c19d58365d09fc0d5aeb67bc3afa23b3ee8398 100644 (file)
@@ -191,3 +191,26 @@ void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24)
 }
 
 
+BOOL make_oem_passwd_hash(char data[516], char *passwd, char old_pw_hash[16])
+{
+       int new_pw_len = strlen(passwd);
+
+       if (new_pw_len > 512)
+       {
+               DEBUG(0,("make_oem_passwd_hash: new password is too long.\n"));
+               return False;
+       }
+
+       /*
+        * Now setup the data area.
+        * We need to generate a random fill
+        * for this area to make it harder to
+        * decrypt. JRA.
+        */
+       generate_random_buffer((unsigned char *)data, 516, False);
+       fstrcpy( &data[512 - new_pw_len], passwd);
+       SIVAL(data, 512, new_pw_len);
+
+       SamOEMhash( (unsigned char *)data, (unsigned char *)old_pw_hash, True);
+}
+
index 1428178c26543a310d0508c9e6df67db497774f2..9fe4c0a16ab08602aec4ea8e3de9ed670bbef1da 100644 (file)
@@ -97,6 +97,63 @@ BOOL get_samr_query_userinfo(struct cli_state *cli,
        return do_samr_close(cli, &pol_open_user);
 }
 
+/****************************************************************************
+do a SAMR change user password command
+****************************************************************************/
+BOOL do_samr_chgpasswd_user(struct cli_state *cli,
+               char *srv_name, char *user_name,
+               char nt_newpass[516], char nt_oldhash[16],
+               char lm_newpass[516], char lm_oldhash[16])
+{
+       prs_struct data;
+       prs_struct rdata;
+
+       SAMR_Q_CHGPASSWD_USER q_e;
+       BOOL valid_pwc = False;
+
+       /* create and send a MSRPC command with api SAMR_CHGPASSWD_USER */
+
+       prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
+       prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
+
+       DEBUG(4,("SAMR Change User Password. server:%s username:%s\n",
+               srv_name, user_name));
+
+       make_samr_q_chgpasswd_user(&q_e, srv_name, user_name,
+                                  nt_newpass, nt_oldhash,
+                                  lm_newpass, lm_oldhash);
+
+       /* turn parameters into data stream */
+       samr_io_q_chgpasswd_user("", &q_e, &data, 0);
+
+       /* send the data on \PIPE\ */
+       if (rpc_api_pipe_req(cli, SAMR_CHGPASSWD_USER, &data, &rdata))
+       {
+               SAMR_R_CHGPASSWD_USER r_e;
+               BOOL p;
+
+               samr_io_r_chgpasswd_user("", &r_e, &rdata, 0);
+
+               p = rdata.offset != 0;
+               if (p && r_e.status != 0)
+               {
+                       /* report error code */
+                       DEBUG(0,("SAMR_R_CHGPASSWD_USER: %s\n", get_nt_error_msg(r_e.status)));
+                       p = False;
+               }
+
+               if (p)
+               {
+                       valid_pwc = True;
+               }
+       }
+
+       prs_mem_free(&data   );
+       prs_mem_free(&rdata  );
+
+       return valid_pwc;
+}
+
 /****************************************************************************
 do a SAMR unknown 0x38 command
 ****************************************************************************/
index ab07e375f5add39060bf5e1c813d66ab2da467f5..b71c209845a99e7a972b20f894653948971a3441 100644 (file)
@@ -2452,37 +2452,64 @@ void samr_io_r_open_alias(char *desc,  SAMR_R_OPEN_ALIAS *r_u, prs_struct *ps, i
        prs_uint32("status", ps, depth, &(r_u->status));
 }
 
-
-#if 0
-/* SAMR_Q_CHGPASSWD_USER */
-typedef struct q_samr_chgpasswd_user_info
+/*******************************************************************
+makes a SAMR_Q_UNKNOWN_12 structure.
+********************************************************************/
+void make_samr_q_unknown_12(SAMR_Q_UNKNOWN_12 *q_u,
+               POLICY_HND *pol, uint32 rid,
+               uint32 num_gids, uint32 *gid)
 {
-       uint32 ptr_0;
+       int i;
+       if (q_u == NULL) return;
+
+       DEBUG(5,("make_samr_r_unknwon_12\n"));
+
+       memcpy(&(q_u->pol), pol, sizeof(*pol));
+
+       q_u->num_gids1 = num_gids;
+       q_u->rid       = rid;
+       q_u->ptr       = 0;
+       q_u->num_gids2 = num_gids;
 
-       UNIHDR hdr_server; /* server name unicode header */
-       UNISTR2 uni_server; /* server name unicode string */
+       for (i = 0; i < num_gids; i++)
+       {
+               q_u->gid[i] = gid[i];
+       }
+}
 
-       UNIHDR hdr_user_name;    /* username unicode string header */
-       UNISTR2 uni_user_name;    /* username unicode string */
 
-       SAMR_ENC_PASSWD nt_newpass;
-       SAMR_ENC_HASH nt_oldhash;
 
-       uint32 unknown_1; /* seems to always contain 0001 */
 
-       SAMR_ENC_PASSWD lm_newpass;
-       SAMR_ENC_HASH lm_oldhash;
+/*******************************************************************
+makes a SAMR_Q_UNKNOWN_21 structure.
+********************************************************************/
+void make_samr_q_unknown_21(SAMR_Q_UNKNOWN_21 *q_c,
+                               POLICY_HND *hnd, uint16 unk_1, uint16 unk_2)
+{
+       if (q_c == NULL || hnd == NULL) return;
+
+       DEBUG(5,("make_samr_q_unknown_21\n"));
+
+       memcpy(&(q_c->group_pol), hnd, sizeof(q_c->group_pol));
+       q_c->unknown_1 = unk_1;
+       q_c->unknown_2 = unk_2;
+}
 
-} SAMR_Q_CHGPASSWD_USER;
 
-/* SAMR_R_CHGPASSWD_USER */
-typedef struct r_samr_chgpasswd_user_info
+/*******************************************************************
+makes a SAMR_Q_UNKNOWN_13 structure.
+********************************************************************/
+void make_samr_q_unknown_13(SAMR_Q_UNKNOWN_13 *q_c,
+                               POLICY_HND *hnd, uint16 unk_1, uint16 unk_2)
 {
-       uint32 result; /* 0 == OK, C000006A (NT_STATUS_WRONG_PASSWORD) */
+       if (q_c == NULL || hnd == NULL) return;
 
-} SAMR_R_CHGPASSWD_USER;
+       DEBUG(5,("make_samr_q_unknown_13\n"));
 
-#endif /* 0 */
+       memcpy(&(q_c->alias_pol), hnd, sizeof(q_c->alias_pol));
+       q_c->unknown_1 = unk_1;
+       q_c->unknown_2 = unk_2;
+}
 
 
 /*******************************************************************
@@ -2554,6 +2581,17 @@ void samr_io_r_unknown_38(char *desc,  SAMR_R_UNKNOWN_38 *r_u, prs_struct *ps, i
        prs_uint32("status", ps, depth, &(r_u->status));
 }
 
+/*******************************************************************
+make a SAMR_ENC_PASSWD structure.
+********************************************************************/
+void make_enc_passwd(SAMR_ENC_PASSWD *pwd, char pass[512])
+{
+       if (pwd == NULL) return;
+
+       pwd->ptr = 1;
+       memcpy(&(pwd->pass), pass, sizeof(pwd->pass)); 
+}
+
 /*******************************************************************
 reads or writes a SAMR_ENC_PASSWD structure.
 ********************************************************************/
@@ -2570,6 +2608,17 @@ void samr_io_enc_passwd(char *desc, SAMR_ENC_PASSWD *pwd, prs_struct *ps, int de
        prs_uint8s(False, "pwd", ps, depth, pwd->pass, sizeof(pwd->pass)); 
 }
 
+/*******************************************************************
+makes a SAMR_ENC_HASH structure.
+********************************************************************/
+void make_enc_hash(SAMR_ENC_HASH *hsh, char hash[16])
+{
+       if (hsh == NULL) return;
+
+       hsh->ptr = 1;
+       memcpy(&(hsh->hash), hash, sizeof(hsh->hash));
+}
+
 /*******************************************************************
 reads or writes a SAMR_ENC_HASH structure.
 ********************************************************************/
@@ -2586,95 +2635,77 @@ void samr_io_enc_hash(char *desc, SAMR_ENC_HASH *hsh, prs_struct *ps, int depth)
        prs_uint8s(False, "hash", ps, depth, hsh->hash, sizeof(hsh->hash)); 
 }
 
-#if 0
-/* SAMR_Q_CHGPASSWD_USER */
-typedef struct q_samr_chgpasswd_user_info
+/*******************************************************************
+makes a SAMR_R_UNKNOWN_38 structure.
+********************************************************************/
+void make_samr_q_chgpasswd_user(SAMR_Q_CHGPASSWD_USER *q_u,
+                               char *dest_host, char *user_name,
+                               char nt_newpass[516], char nt_oldhash[16],
+                               char lm_newpass[516], char lm_oldhash[16])
 {
-       uint32 ptr_0;
-
-       UNIHDR hdr_server; /* server name unicode header */
-       UNISTR2 uni_server; /* server name unicode string */
-
-       UNIHDR hdr_user_name;    /* username unicode string header */
-       UNISTR2 uni_user_name;    /* username unicode string */
-
-       SAMR_ENC_PASSWD nt_newpass;
-       SAMR_ENC_HASH nt_oldhash;
+       int len_dest_host = strlen(dest_host);
+       int len_user_name = strlen(user_name);
 
-       uint32 unknown_1; /* seems to always contain 0001 */
-
-       SAMR_ENC_PASSWD lm_newpass;
-       SAMR_ENC_HASH lm_oldhash;
+       if (q_u == NULL) return;
 
-} SAMR_Q_CHGPASSWD_USER;
+       DEBUG(5,("make_samr_q_chgpasswd_user\n"));
 
-/* SAMR_R_CHGPASSWD_USER */
-typedef struct r_samr_chgpasswd_user_info
-{
-       uint32 result; /* 0 == OK, C000006A (NT_STATUS_WRONG_PASSWORD) */
+       q_u->ptr_0 = 1;
+       make_uni_hdr(&(q_u->hdr_dest_host), len_dest_host, len_dest_host, len_dest_host != 0);
+       make_unistr2(&(q_u->uni_dest_host), dest_host, len_dest_host);  
+       make_uni_hdr(&(q_u->hdr_user_name), len_user_name, len_user_name, len_user_name != 0);
+       make_unistr2(&(q_u->uni_user_name), user_name, len_user_name);  
 
-} SAMR_R_CHGPASSWD_USER;
+       make_enc_passwd(&(q_u->nt_newpass), nt_newpass);
+       make_enc_hash  (&(q_u->nt_oldhash), nt_oldhash);
 
-#endif /* 0 */
+       q_u->unknown = 0x01;
 
+       make_enc_passwd(&(q_u->lm_newpass), lm_newpass);
+       make_enc_hash  (&(q_u->lm_oldhash), lm_oldhash);
+};
 
 /*******************************************************************
-makes a SAMR_Q_UNKNOWN_12 structure.
+reads or writes a structure.
 ********************************************************************/
-void make_samr_q_unknown_12(SAMR_Q_UNKNOWN_12 *q_u,
-               POLICY_HND *pol, uint32 rid,
-               uint32 num_gids, uint32 *gid)
+void samr_io_q_chgpasswd_user(char *desc, SAMR_Q_CHGPASSWD_USER *q_u, prs_struct *ps, int depth)
 {
-       int i;
        if (q_u == NULL) return;
 
-       DEBUG(5,("make_samr_r_unknwon_12\n"));
-
-       memcpy(&(q_u->pol), pol, sizeof(*pol));
-
-       q_u->num_gids1 = num_gids;
-       q_u->rid       = rid;
-       q_u->ptr       = 0;
-       q_u->num_gids2 = num_gids;
-
-       for (i = 0; i < num_gids; i++)
-       {
-               q_u->gid[i] = gid[i];
-       }
-}
+       prs_debug(ps, depth, desc, "samr_io_q_chgpasswd_user");
+       depth++;
 
+       prs_align(ps);
 
+       prs_uint32("ptr_0", ps, depth, &(q_u->ptr_0));
 
+       smb_io_unihdr ("", &(q_u->hdr_dest_host), ps, depth); 
+       smb_io_unistr2("", &(q_u->uni_dest_host), q_u->hdr_dest_host.buffer, ps, depth); 
+       smb_io_unihdr ("", &(q_u->hdr_user_name), ps, depth); 
+       smb_io_unistr2("", &(q_u->uni_user_name), q_u->hdr_user_name.buffer, ps, depth); 
 
-/*******************************************************************
-makes a SAMR_Q_UNKNOWN_21 structure.
-********************************************************************/
-void make_samr_q_unknown_21(SAMR_Q_UNKNOWN_21 *q_c,
-                               POLICY_HND *hnd, uint16 unk_1, uint16 unk_2)
-{
-       if (q_c == NULL || hnd == NULL) return;
+       samr_io_enc_passwd("nt_newpass", &(q_u->nt_newpass), ps, depth); 
+       samr_io_enc_hash  ("nt_oldhash", &(q_u->nt_oldhash), ps, depth); 
 
-       DEBUG(5,("make_samr_q_unknown_21\n"));
+       prs_uint32("unknown", ps, depth, &(q_u->unknown));
 
-       memcpy(&(q_c->group_pol), hnd, sizeof(q_c->group_pol));
-       q_c->unknown_1 = unk_1;
-       q_c->unknown_2 = unk_2;
+       samr_io_enc_passwd("lm_newpass", &(q_u->lm_newpass), ps, depth); 
+       samr_io_enc_hash  ("lm_oldhash", &(q_u->lm_oldhash), ps, depth); 
 }
 
-
 /*******************************************************************
-makes a SAMR_Q_UNKNOWN_13 structure.
+reads or writes a structure.
 ********************************************************************/
-void make_samr_q_unknown_13(SAMR_Q_UNKNOWN_13 *q_c,
-                               POLICY_HND *hnd, uint16 unk_1, uint16 unk_2)
+void samr_io_r_chgpasswd_user(char *desc, SAMR_R_CHGPASSWD_USER *r_u, prs_struct *ps, int depth)
 {
-       if (q_c == NULL || hnd == NULL) return;
+       if (r_u == NULL) return;
 
-       DEBUG(5,("make_samr_q_unknown_13\n"));
+       prs_debug(ps, depth, desc, "samr_io_r_chgpasswd_user");
+       depth++;
 
-       memcpy(&(q_c->alias_pol), hnd, sizeof(q_c->alias_pol));
-       q_c->unknown_1 = unk_1;
-       q_c->unknown_2 = unk_2;
+       prs_align(ps);
+
+       prs_uint32("status", ps, depth, &(r_u->status));
 }
 
 
index 783bc128e7c4cd6b7bfae1352c2f0f3886b43fcf..5cf6e612452deab07695984708ac4355af6cce59 100644 (file)
@@ -46,7 +46,16 @@ void cmd_sam_test(struct client_info *info)
        fstring srv_name;
        fstring domain;
        fstring sid;
+       char *new_passwd;
        BOOL res = True;
+       char nt_newpass[516];
+       char nt_hshhash[16];
+       char nt_newhash[16];
+       char nt_oldhash[16];
+       char lm_newpass[516];
+       char lm_newhash[16];
+       char lm_hshhash[16];
+       char lm_oldhash[16];
 
        fstrcpy(sid   , info->dom.level5_sid);
        fstrcpy(domain, info->dom.level5_dom);
@@ -58,17 +67,36 @@ void cmd_sam_test(struct client_info *info)
        }
 
        fstrcpy(srv_name, "\\\\");
-       fstrcat(srv_name, info->myhostname);
+       fstrcat(srv_name, info->dest_host);
        strupper(srv_name);
 
        fprintf(out_hnd, "SAM Encryption Test\n");
 
+#if 0
+       struct pwd_info new_pwd;
+       pwd_read(&new_pwd, "New Password (ONCE: this is test code!):", True);
+#endif
+       new_passwd = (char*)getpass("New Password (ONCE: this is test code!):");
+
+       nt_lm_owf_gen(new_passwd, lm_newhash, nt_newhash);
+       pwd_get_lm_nt_16(&(smb_cli->pwd), lm_oldhash , nt_oldhash );
+       make_oem_passwd_hash(nt_newpass, new_passwd, nt_oldhash);
+       make_oem_passwd_hash(lm_newpass, new_passwd, lm_oldhash);
+       E_old_pw_hash(lm_newhash, lm_oldhash, lm_hshhash);
+       E_old_pw_hash(lm_newhash, nt_oldhash, nt_hshhash);
+
        /* open SAMR session.  */
-       res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR, True) : False;
+       res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR, False) : False;
 
        /* establish a connection. */
        res = res ? do_samr_unknown_38(smb_cli, srv_name) : False;
 
+       /* establish a connection. */
+       res = res ? do_samr_chgpasswd_user(smb_cli,
+                                          srv_name, smb_cli->user_name,
+                                          nt_newpass, nt_hshhash,
+                                          lm_newpass, lm_hshhash) : False;
+
        /* close the session */
        cli_nt_session_close(smb_cli);