summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/rpc_samr.h53
-rw-r--r--source3/libsmb/smbdes.c2
-rw-r--r--source3/libsmb/smbencrypt.c2
-rw-r--r--source3/rpc_parse/parse_net.c4
-rw-r--r--source3/rpc_parse/parse_samr.c138
-rw-r--r--source3/rpc_server/srv_netlog_nt.c4
-rw-r--r--source3/rpc_server/srv_samr_nt.c40
-rw-r--r--source3/smbd/chgpasswd.c2
8 files changed, 227 insertions, 18 deletions
diff --git a/source3/include/rpc_samr.h b/source3/include/rpc_samr.h
index d996170200..cfe856b07f 100644
--- a/source3/include/rpc_samr.h
+++ b/source3/include/rpc_samr.h
@@ -219,6 +219,58 @@ typedef struct sam_user_info_24
uint8 pass[516];
} SAM_USER_INFO_24;
+/*
+ * NB. This structure is *definately* incorrect. It's my best guess
+ * currently for W2K SP2. The password field is encrypted in a different
+ * way than normal... And there are definately other problems. JRA.
+ */
+
+/* SAM_USER_INFO_25 */
+typedef struct sam_user_info_25
+{
+ /* TIMES MAY NOT IN RIGHT ORDER!!!! */
+ NTTIME logon_time; /* logon time */
+ NTTIME logoff_time; /* logoff time */
+ NTTIME kickoff_time; /* kickoff time */
+ NTTIME pass_last_set_time; /* password last set time */
+ NTTIME pass_can_change_time; /* password can change time */
+ NTTIME pass_must_change_time; /* password must change time */
+
+ UNIHDR hdr_user_name; /* NULL - user name unicode string header */
+ UNIHDR hdr_full_name; /* user's full name unicode string header */
+ UNIHDR hdr_home_dir; /* home directory unicode string header */
+ UNIHDR hdr_dir_drive; /* home drive unicode string header */
+ UNIHDR hdr_logon_script; /* logon script unicode string header */
+ UNIHDR hdr_profile_path; /* profile path unicode string header */
+ UNIHDR hdr_acct_desc ; /* user description */
+ UNIHDR hdr_workstations; /* comma-separated workstations user can log in from */
+ UNIHDR hdr_unknown_str ; /* don't know what this is, yet. */
+ UNIHDR hdr_munged_dial ; /* munged path name and dial-back tel number */
+
+ uint8 lm_pwd[16]; /* lm user passwords */
+ uint8 nt_pwd[16]; /* nt user passwords */
+
+ uint32 user_rid; /* Primary User ID */
+ uint32 group_rid; /* Primary Group ID */
+
+ uint32 acb_info; /* account info (ACB_xxxx bit-mask) */
+
+ uint32 unknown_6[6];
+
+ uint8 pass[532];
+
+ UNISTR2 uni_user_name; /* NULL - username unicode string */
+ UNISTR2 uni_full_name; /* user's full name unicode string */
+ UNISTR2 uni_home_dir; /* home directory unicode string */
+ UNISTR2 uni_dir_drive; /* home directory drive unicode string */
+ UNISTR2 uni_logon_script; /* logon script unicode string */
+ UNISTR2 uni_profile_path; /* profile path unicode string */
+ UNISTR2 uni_acct_desc ; /* user description unicode string */
+ UNISTR2 uni_workstations; /* login from workstations unicode string */
+ UNISTR2 uni_unknown_str ; /* don't know what this is, yet. */
+ UNISTR2 uni_munged_dial ; /* munged path name and dial-back tel no */
+} SAM_USER_INFO_25;
+
/* SAM_USER_INFO_21 */
typedef struct sam_user_info_21
@@ -1140,6 +1192,7 @@ typedef struct sam_userinfo_ctr_info
SAM_USER_INFO_21 *id21; /* auth-level 21 */
SAM_USER_INFO_23 *id23; /* auth-level 0x17 */
SAM_USER_INFO_24 *id24; /* auth-level 0x18 */
+ SAM_USER_INFO_25 *id25; /* auth-level 0x19 */
void* id; /* to make typecasting easy */
} info;
diff --git a/source3/libsmb/smbdes.c b/source3/libsmb/smbdes.c
index d0e1c6e85f..7e8a9a5b89 100644
--- a/source3/libsmb/smbdes.c
+++ b/source3/libsmb/smbdes.c
@@ -381,7 +381,7 @@ void SamOEMhash( unsigned char *data, unsigned char *key, int val)
s_box[ind] = s_box[j];
s_box[j] = tc;
}
- for( ind = 0; ind < (val ? 516 : 16); ind++)
+ for( ind = 0; ind < val; ind++)
{
unsigned char tc;
unsigned char t;
diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c
index 68af1b4941..b9827333d8 100644
--- a/source3/libsmb/smbencrypt.c
+++ b/source3/libsmb/smbencrypt.c
@@ -223,7 +223,7 @@ BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[
DEBUG(100,("make_oem_passwd_hash\n"));
dump_data(100, data, 516);
#endif
- SamOEMhash( (unsigned char *)data, (unsigned char *)old_pw_hash, True);
+ SamOEMhash( (unsigned char *)data, (unsigned char *)old_pw_hash, 516);
return True;
}
diff --git a/source3/rpc_parse/parse_net.c b/source3/rpc_parse/parse_net.c
index 85de667b00..c0d9544ba8 100644
--- a/source3/rpc_parse/parse_net.c
+++ b/source3/rpc_parse/parse_net.c
@@ -883,9 +883,9 @@ void init_id_info1(NET_ID_INFO_1 *id, char *domain_name,
memcpy(key, sess_key, 8);
memcpy(lm_owf, lm_cypher, 16);
- SamOEMhash(lm_owf, key, False);
+ SamOEMhash(lm_owf, key, 16);
memcpy(nt_owf, nt_cypher, 16);
- SamOEMhash(nt_owf, key, False);
+ SamOEMhash(nt_owf, key, 16);
#ifdef DEBUG_PASSWORD
DEBUG(100,("encrypt of lm owf password:"));
diff --git a/source3/rpc_parse/parse_samr.c b/source3/rpc_parse/parse_samr.c
index 6e94b62d40..395931edd9 100644
--- a/source3/rpc_parse/parse_samr.c
+++ b/source3/rpc_parse/parse_samr.c
@@ -5340,6 +5340,126 @@ static BOOL sam_io_user_info23(char *desc, SAM_USER_INFO_23 * usr,
return True;
}
+/*******************************************************************
+ reads or writes a structure.
+ NB. This structure is *definately* incorrect. It's my best guess
+ currently for W2K SP2. The password field is encrypted in a different
+ way than normal... And there are definately other problems. JRA.
+********************************************************************/
+
+static BOOL sam_io_user_info25(char *desc, SAM_USER_INFO_25 * usr, prs_struct *ps, int depth)
+{
+ if (usr == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "sam_io_user_info23");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!smb_io_time("logon_time ", &usr->logon_time, ps, depth))
+ return False;
+ if(!smb_io_time("logoff_time ", &usr->logoff_time, ps, depth))
+ return False;
+ if(!smb_io_time("kickoff_time ", &usr->kickoff_time, ps, depth))
+ return False;
+ if(!smb_io_time("pass_last_set_time ", &usr->pass_last_set_time, ps, depth))
+ return False;
+ if(!smb_io_time("pass_can_change_time ", &usr->pass_can_change_time, ps, depth))
+ return False;
+ if(!smb_io_time("pass_must_change_time", &usr->pass_must_change_time, ps, depth))
+ return False;
+
+ if(!smb_io_unihdr("hdr_user_name ", &usr->hdr_user_name, ps, depth)) /* username unicode string header */
+ return False;
+ if(!smb_io_unihdr("hdr_full_name ", &usr->hdr_full_name, ps, depth)) /* user's full name unicode string header */
+ return False;
+ if(!smb_io_unihdr("hdr_home_dir ", &usr->hdr_home_dir, ps, depth)) /* home directory unicode string header */
+ return False;
+ if(!smb_io_unihdr("hdr_dir_drive ", &usr->hdr_dir_drive, ps, depth)) /* home directory drive */
+ return False;
+ if(!smb_io_unihdr("hdr_logon_script", &usr->hdr_logon_script, ps, depth)) /* logon script unicode string header */
+ return False;
+ if(!smb_io_unihdr("hdr_profile_path", &usr->hdr_profile_path, ps, depth)) /* profile path unicode string header */
+ return False;
+ if(!smb_io_unihdr("hdr_acct_desc ", &usr->hdr_acct_desc, ps, depth)) /* account desc */
+ return False;
+ if(!smb_io_unihdr("hdr_workstations", &usr->hdr_workstations, ps, depth)) /* wkstas user can log on from */
+ return False;
+ if(!smb_io_unihdr("hdr_unknown_str ", &usr->hdr_unknown_str, ps, depth)) /* unknown string */
+ return False;
+ if(!smb_io_unihdr("hdr_munged_dial ", &usr->hdr_munged_dial, ps, depth)) /* wkstas user can log on from */
+ return False;
+
+ if(!prs_uint8s(False, "lm_pwd ", ps, depth, usr->lm_pwd, sizeof(usr->lm_pwd)))
+ return False;
+ if(!prs_uint8s(False, "nt_pwd ", ps, depth, usr->nt_pwd, sizeof(usr->nt_pwd)))
+ return False;
+
+ if(!prs_uint32("user_rid ", ps, depth, &usr->user_rid)) /* User ID */
+ return False;
+ if(!prs_uint32("group_rid ", ps, depth, &usr->group_rid)) /* Group ID */
+ return False;
+ if(!prs_uint32("acb_info ", ps, depth, &usr->acb_info))
+ return False;
+
+ if(!prs_uint32s(False, "unknown_6 ", ps, depth, usr->unknown_6, 6))
+ return False;
+
+ if(!prs_uint8s(False, "password ", ps, depth, usr->pass, sizeof(usr->pass)))
+ return False;
+
+ /* here begins pointed-to data */
+
+ if(!smb_io_unistr2("uni_user_name ", &usr->uni_user_name, usr->hdr_user_name.buffer, ps, depth)) /* username unicode string */
+ return False;
+
+ if(!smb_io_unistr2("uni_full_name ", &usr->uni_full_name, usr->hdr_full_name.buffer, ps, depth)) /* user's full name unicode string */
+ return False;
+
+ if(!smb_io_unistr2("uni_home_dir ", &usr->uni_home_dir, usr->hdr_home_dir.buffer, ps, depth)) /* home directory unicode string */
+ return False;
+
+ if(!smb_io_unistr2("uni_dir_drive ", &usr->uni_dir_drive, usr->hdr_dir_drive.buffer, ps, depth)) /* home directory drive unicode string */
+ return False;
+
+ if(!smb_io_unistr2("uni_logon_script", &usr->uni_logon_script, usr->hdr_logon_script.buffer, ps, depth)) /* logon script unicode string */
+ return False;
+
+ if(!smb_io_unistr2("uni_profile_path", &usr->uni_profile_path, usr->hdr_profile_path.buffer, ps, depth)) /* profile path unicode string */
+ return False;
+
+ if(!smb_io_unistr2("uni_acct_desc ", &usr->uni_acct_desc, usr->hdr_acct_desc.buffer, ps, depth)) /* user desc unicode string */
+ return False;
+
+ if(!smb_io_unistr2("uni_workstations", &usr->uni_workstations, usr->hdr_workstations.buffer, ps, depth)) /* worksations user can log on from */
+ return False;
+
+ if(!smb_io_unistr2("uni_unknown_str ", &usr->uni_unknown_str, usr->hdr_unknown_str.buffer, ps, depth)) /* unknown string */
+ return False;
+
+ if(!smb_io_unistr2("uni_munged_dial ", &usr->uni_munged_dial, usr->hdr_munged_dial.buffer, ps, depth))
+ return False;
+
+#if 0 /* JRA - unknown... */
+ /* ok, this is only guess-work (as usual) */
+ if (usr->ptr_logon_hrs) {
+ if(!prs_uint32("unknown_6 ", ps, depth, &usr->unknown_6))
+ return False;
+ if(!prs_uint32("padding4 ", ps, depth, &usr->padding4))
+ return False;
+ if(!sam_io_logon_hrs("logon_hrs", &usr->logon_hrs, ps, depth))
+ return False;
+ } else if (UNMARSHALLING(ps)) {
+ usr->unknown_6 = 0;
+ usr->padding4 = 0;
+ }
+#endif
+
+ return True;
+}
+
/*************************************************************************
init_sam_user_info21W
@@ -5740,12 +5860,12 @@ void init_samr_userinfo_ctr(SAM_USERINFO_CTR * ctr, uchar * sess_key,
switch (switch_value) {
case 0x18:
- SamOEMhash(ctr->info.id24->pass, sess_key, 1);
+ SamOEMhash(ctr->info.id24->pass, sess_key, 516);
dump_data(100, (char *)sess_key, 16);
dump_data(100, (char *)ctr->info.id24->pass, 516);
break;
case 0x17:
- SamOEMhash(ctr->info.id23->pass, sess_key, 1);
+ SamOEMhash(ctr->info.id23->pass, sess_key, 516);
dump_data(100, (char *)sess_key, 16);
dump_data(100, (char *)ctr->info.id23->pass, 516);
break;
@@ -5845,6 +5965,16 @@ static BOOL samr_io_userinfo_ctr(char *desc, SAM_USERINFO_CTR **ppctr,
}
ret = sam_io_user_info24("", ctr->info.id24, ps, depth);
break;
+ case 25:
+ if (UNMARSHALLING(ps))
+ ctr->info.id25 = (SAM_USER_INFO_25 *)prs_alloc_mem(ps,sizeof(SAM_USER_INFO_25));
+
+ if (ctr->info.id25 == NULL) {
+ DEBUG(2,("samr_io_userinfo_ctr: info pointer not initialised\n"));
+ return False;
+ }
+ ret = sam_io_user_info25("", ctr->info.id25, ps, depth);
+ break;
default:
DEBUG(2, ("samr_io_userinfo_ctr: unknown switch level 0x%x\n", ctr->switch_value));
ret = False;
@@ -5999,8 +6129,8 @@ void init_samr_q_set_userinfo2(SAMR_Q_SET_USERINFO2 * q_u,
switch (switch_value) {
case 0x12:
- SamOEMhash(ctr->info.id12->lm_pwd, sess_key, 0);
- SamOEMhash(ctr->info.id12->nt_pwd, sess_key, 0);
+ SamOEMhash(ctr->info.id12->lm_pwd, sess_key, 16);
+ SamOEMhash(ctr->info.id12->nt_pwd, sess_key, 16);
dump_data(100, (char *)sess_key, 16);
dump_data(100, (char *)ctr->info.id12->lm_pwd, 16);
dump_data(100, (char *)ctr->info.id12->nt_pwd, 16);
diff --git a/source3/rpc_server/srv_netlog_nt.c b/source3/rpc_server/srv_netlog_nt.c
index eb026a1f98..bbda4060f2 100644
--- a/source3/rpc_server/srv_netlog_nt.c
+++ b/source3/rpc_server/srv_netlog_nt.c
@@ -470,8 +470,8 @@ static uint32 net_login_interactive(NET_ID_INFO_1 *id1, SAM_ACCOUNT *sampass, pi
dump_data(100, nt_pwd, 16);
#endif
- SamOEMhash((uchar *)lm_pwd, key, False);
- SamOEMhash((uchar *)nt_pwd, key, False);
+ SamOEMhash((uchar *)lm_pwd, key, 16);
+ SamOEMhash((uchar *)nt_pwd, key, 16);
#ifdef DEBUG_PASSWORD
DEBUG(100,("decrypt of lm owf password:"));
diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c
index 0a82c90a1d..502774e986 100644
--- a/source3/rpc_server/srv_samr_nt.c
+++ b/source3/rpc_server/srv_samr_nt.c
@@ -2259,10 +2259,10 @@ static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, uint32 rid)
}
/*******************************************************************
- set_user_info_24
+ set_user_info_pw
********************************************************************/
-static BOOL set_user_info_24(SAM_USER_INFO_24 *id24, uint32 rid)
+static BOOL set_user_info_pw(char *pass, uint32 rid)
{
SAM_ACCOUNT *pwd = NULL;
uchar nt_hash[16];
@@ -2282,7 +2282,7 @@ static BOOL set_user_info_24(SAM_USER_INFO_24 *id24, uint32 rid)
memset(buf, 0, sizeof(buf));
- if (!decode_pw_buffer((char*)id24->pass, buf, 256, &len, nt_hash, lm_hash)) {
+ if (!decode_pw_buffer(pass, buf, 256, &len, nt_hash, lm_hash)) {
pdb_free_sam(pwd);
return False;
}
@@ -2306,7 +2306,7 @@ static BOOL set_user_info_24(SAM_USER_INFO_24 *id24, uint32 rid)
memset(buf, 0, sizeof(buf));
- DEBUG(0,("set_user_info_24: pdb_update_sam_account()\n"));
+ DEBUG(5,("set_user_info_pw: pdb_update_sam_account()\n"));
/* update the SAMBA password */
if(!pdb_update_sam_account(pwd, True)) {
@@ -2390,13 +2390,39 @@ uint32 _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_
break;
case 24:
- SamOEMhash(ctr->info.id24->pass, sess_key, 1);
- if (!set_user_info_24(ctr->info.id24, rid))
+ SamOEMhash(ctr->info.id24->pass, sess_key, 516);
+
+ dump_data(100, (char *)ctr->info.id24->pass, 516);
+
+ if (!set_user_info_pw(ctr->info.id24->pass, rid))
return NT_STATUS_ACCESS_DENIED;
break;
+ case 25:
+#if 0
+ /*
+ * Currently we don't really know how to unmarshall
+ * the level 25 struct, and the password encryption
+ * is different. This is a placeholder for when we
+ * do understand it. In the meantime just return INVALID
+ * info level and W2K SP2 drops down to level 23... JRA.
+ */
+
+ SamOEMhash(ctr->info.id25->pass, sess_key, 532);
+
+ dump_data(100, (char *)ctr->info.id25->pass, 532);
+
+ if (!set_user_info_pw(ctr->info.id25->pass, rid))
+ return NT_STATUS_ACCESS_DENIED;
+ break;
+#endif
+ return NT_STATUS_INVALID_INFO_CLASS;
+
case 23:
- SamOEMhash(ctr->info.id23->pass, sess_key, 1);
+ SamOEMhash(ctr->info.id23->pass, sess_key, 516);
+
+ dump_data(100, (char *)ctr->info.id23->pass, 516);
+
if (!set_user_info_23(ctr->info.id23, rid))
return NT_STATUS_ACCESS_DENIED;
break;
diff --git a/source3/smbd/chgpasswd.c b/source3/smbd/chgpasswd.c
index cf1fca405a..c6f6eca0ba 100644
--- a/source3/smbd/chgpasswd.c
+++ b/source3/smbd/chgpasswd.c
@@ -776,7 +776,7 @@ BOOL check_oem_password(char *user,
/*
* Call the hash function to get the new password.
*/
- SamOEMhash((uchar *) lmdata, (uchar *)lanman_pw, True);
+ SamOEMhash((uchar *) lmdata, (uchar *)lanman_pw, 516);
/*
* The length of the new password is in the last 4 bytes of