1
0
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:
Jeremy Allison 2001-06-20 19:55:59 +00:00
parent 6fb063b4d5
commit 3f1254bee1
8 changed files with 227 additions and 18 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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:"));

View File

@ -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);

View File

@ -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:"));

View File

@ -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;

View File

@ -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