mirror of
https://github.com/samba-team/samba.git
synced 2025-01-27 14:04:05 +03:00
Fixed W2K SP2 joining a Samba PDC hosted domain.
Jermey. (This used to be commit 05a2911403a0710d994a618e72743205a3b0b87a)
This commit is contained in:
parent
6fb063b4d5
commit
3f1254bee1
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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:"));
|
||||
|
@ -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);
|
||||
|
@ -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:"));
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user