mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2024-12-22 23:23:30 -06:00
Remove generation and handling of LM hashes
https://fedorahosted.org/freeipa/ticket/3795
This commit is contained in:
parent
b5e60c2020
commit
d876a22732
@ -2637,10 +2637,9 @@ static bool init_sam_from_td(struct samu *user, struct pdb_trusted_domain *td,
|
||||
char *name;
|
||||
char *trustpw = NULL;
|
||||
char *trustpw_utf8 = NULL;
|
||||
char *trustpw_utf8_uc = NULL;
|
||||
char *tmp_str = NULL;
|
||||
int ret;
|
||||
struct ntlm_keys ntlm_keys;
|
||||
uint8_t nt_key[16];
|
||||
size_t converted_size;
|
||||
bool res;
|
||||
char *sid_str;
|
||||
@ -2706,23 +2705,13 @@ static bool init_sam_from_td(struct samu *user, struct pdb_trusted_domain *td,
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!push_utf8_talloc(user, &trustpw_utf8_uc, tmp_str, &converted_size)) {
|
||||
res = false;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = encode_ntlm_keys(trustpw_utf8, trustpw_utf8_uc, true, true,
|
||||
&ntlm_keys);
|
||||
ret = encode_nt_key(trustpw_utf8, nt_key);
|
||||
if (ret != 0) {
|
||||
res = false;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!pdb_set_lanman_passwd(user, ntlm_keys.lm, PDB_SET)) {
|
||||
res = false;
|
||||
goto done;
|
||||
}
|
||||
if (!pdb_set_nt_passwd(user, ntlm_keys.nt, PDB_SET)) {
|
||||
if (!pdb_set_nt_passwd(user, nt_key, PDB_SET)) {
|
||||
res = false;
|
||||
goto done;
|
||||
}
|
||||
@ -2741,10 +2730,6 @@ done:
|
||||
memset(tmp_str, 0, strlen(tmp_str));
|
||||
talloc_free(tmp_str);
|
||||
}
|
||||
if (trustpw_utf8_uc != NULL) {
|
||||
memset(trustpw_utf8_uc, 0, strlen(trustpw_utf8_uc));
|
||||
talloc_free(trustpw_utf8_uc);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
@ -366,7 +366,6 @@ static struct ipapwd_krbcfg *ipapwd_getConfig(void)
|
||||
slapi_entry_free(config_entry);
|
||||
|
||||
/* get the ipa etc/ipaConfig entry */
|
||||
config->allow_lm_hash = false;
|
||||
config->allow_nt_hash = false;
|
||||
ret = ipapwd_getEntry(ipa_etc_config_dn, &config_entry, NULL);
|
||||
if (ret != LDAP_SUCCESS) {
|
||||
@ -376,10 +375,6 @@ static struct ipapwd_krbcfg *ipapwd_getConfig(void)
|
||||
tmparray = slapi_entry_attr_get_charray(config_entry,
|
||||
"ipaConfigString");
|
||||
for (i = 0; tmparray && tmparray[i]; i++) {
|
||||
if (strcasecmp(tmparray[i], "AllowLMhash") == 0) {
|
||||
config->allow_lm_hash = true;
|
||||
continue;
|
||||
}
|
||||
if (strcasecmp(tmparray[i], "AllowNThash") == 0) {
|
||||
config->allow_nt_hash = true;
|
||||
continue;
|
||||
@ -928,7 +923,6 @@ int ipapwd_SetPassword(struct ipapwd_krbcfg *krbcfg,
|
||||
Slapi_Value **pwvals = NULL;
|
||||
struct tm utctime;
|
||||
char timestr[GENERALIZED_TIME_LENGTH+1];
|
||||
char *lm = NULL;
|
||||
char *nt = NULL;
|
||||
int is_smb = 0;
|
||||
int is_ipant = 0;
|
||||
@ -965,7 +959,7 @@ int ipapwd_SetPassword(struct ipapwd_krbcfg *krbcfg,
|
||||
ret = ipapwd_gen_hashes(krbcfg, data,
|
||||
data->password,
|
||||
is_krb, is_smb, is_ipant,
|
||||
&svals, &nt, &lm, &ntvals, &errMesg);
|
||||
&svals, &nt, &ntvals, &errMesg);
|
||||
if (ret) {
|
||||
goto free_and_return;
|
||||
}
|
||||
@ -1004,11 +998,6 @@ int ipapwd_SetPassword(struct ipapwd_krbcfg *krbcfg,
|
||||
}
|
||||
}
|
||||
|
||||
if (lm && is_smb) {
|
||||
slapi_mods_add_string(smods, LDAP_MOD_REPLACE,
|
||||
"sambaLMPassword", lm);
|
||||
}
|
||||
|
||||
if (nt && is_smb) {
|
||||
slapi_mods_add_string(smods, LDAP_MOD_REPLACE,
|
||||
"sambaNTPassword", nt);
|
||||
@ -1069,7 +1058,6 @@ int ipapwd_SetPassword(struct ipapwd_krbcfg *krbcfg,
|
||||
LOG_TRACE("<= result: %d\n", ret);
|
||||
|
||||
free_and_return:
|
||||
if (lm) slapi_ch_free((void **)&lm);
|
||||
if (nt) slapi_ch_free((void **)&nt);
|
||||
if (modtime) slapi_ch_free((void **)&modtime);
|
||||
slapi_mods_free(&smods);
|
||||
|
@ -201,15 +201,13 @@ enc_error:
|
||||
int ipapwd_gen_hashes(struct ipapwd_krbcfg *krbcfg,
|
||||
struct ipapwd_data *data, char *userpw,
|
||||
int is_krb, int is_smb, int is_ipant, Slapi_Value ***svals,
|
||||
char **nthash, char **lmhash, Slapi_Value ***ntvals,
|
||||
char **nthash, Slapi_Value ***ntvals,
|
||||
char **errMesg)
|
||||
{
|
||||
int rc;
|
||||
char *userpw_uc = NULL;
|
||||
|
||||
*svals = NULL;
|
||||
*nthash = NULL;
|
||||
*lmhash = NULL;
|
||||
*errMesg = NULL;
|
||||
|
||||
if (is_krb) {
|
||||
@ -225,40 +223,24 @@ int ipapwd_gen_hashes(struct ipapwd_krbcfg *krbcfg,
|
||||
}
|
||||
|
||||
if (is_smb || is_ipant) {
|
||||
char lm[33], nt[33];
|
||||
struct ntlm_keys ntlm;
|
||||
char nt[33];
|
||||
uint8_t nt_key[16];
|
||||
int ret;
|
||||
|
||||
userpw_uc = (char *) slapi_utf8StrToUpper((unsigned char *) userpw);
|
||||
if (!userpw_uc) {
|
||||
*errMesg = "Failed to generate upper case password\n";
|
||||
LOG_FATAL("%s", *errMesg);
|
||||
rc = LDAP_OPERATIONS_ERROR;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = encode_ntlm_keys(userpw,
|
||||
userpw_uc,
|
||||
krbcfg->allow_lm_hash,
|
||||
krbcfg->allow_nt_hash,
|
||||
&ntlm);
|
||||
memset(userpw_uc, 0, strlen(userpw_uc));
|
||||
slapi_ch_free_string(&userpw_uc);
|
||||
if (ret) {
|
||||
*errMesg = "Failed to generate NT/LM hashes\n";
|
||||
LOG_FATAL("%s", *errMesg);
|
||||
rc = LDAP_OPERATIONS_ERROR;
|
||||
goto done;
|
||||
}
|
||||
if (krbcfg->allow_lm_hash) {
|
||||
hexbuf(lm, ntlm.lm);
|
||||
lm[32] = '\0';
|
||||
*lmhash = slapi_ch_strdup(lm);
|
||||
}
|
||||
if (krbcfg->allow_nt_hash) {
|
||||
hexbuf(nt, ntlm.nt);
|
||||
ret = encode_nt_key(userpw, nt_key);
|
||||
if (ret) {
|
||||
*errMesg = "Failed to generate NT/LM hashes\n";
|
||||
LOG_FATAL("%s", *errMesg);
|
||||
rc = LDAP_OPERATIONS_ERROR;
|
||||
goto done;
|
||||
}
|
||||
|
||||
hexbuf(nt, nt_key);
|
||||
nt[32] = '\0';
|
||||
*nthash = slapi_ch_strdup(nt);
|
||||
} else {
|
||||
memset(nt_key, 0, 16);
|
||||
}
|
||||
|
||||
if (is_ipant) {
|
||||
@ -269,7 +251,7 @@ int ipapwd_gen_hashes(struct ipapwd_krbcfg *krbcfg,
|
||||
goto done;
|
||||
}
|
||||
(*ntvals)[0] = slapi_value_new();
|
||||
if (slapi_value_set((*ntvals)[0], ntlm.nt, 16) == NULL) {
|
||||
if (slapi_value_set((*ntvals)[0], nt_key, 16) == NULL) {
|
||||
rc = LDAP_OPERATIONS_ERROR;
|
||||
goto done;
|
||||
}
|
||||
|
@ -132,7 +132,6 @@ struct ipapwd_krbcfg {
|
||||
krb5_key_salt_tuple *pref_encsalts;
|
||||
char **passsync_mgrs;
|
||||
int num_passsync_mgrs;
|
||||
bool allow_lm_hash;
|
||||
bool allow_nt_hash;
|
||||
};
|
||||
|
||||
@ -172,7 +171,7 @@ void ipapwd_keyset_free(struct ipapwd_keyset **pkset);
|
||||
int ipapwd_gen_hashes(struct ipapwd_krbcfg *krbcfg,
|
||||
struct ipapwd_data *data, char *userpw,
|
||||
int is_krb, int is_smb, int is_ipant,
|
||||
Slapi_Value ***svals, char **nthash, char **lmhash,
|
||||
Slapi_Value ***svals, char **nthash,
|
||||
Slapi_Value ***ntvals, char **errMesg);
|
||||
|
||||
/* from prepost.c */
|
||||
|
@ -325,13 +325,12 @@ static int ipapwd_pre_add(Slapi_PBlock *pb)
|
||||
Slapi_Value **svals = NULL;
|
||||
Slapi_Value **ntvals = NULL;
|
||||
char *nt = NULL;
|
||||
char *lm = NULL;
|
||||
|
||||
pwdop->is_krb = is_krb;
|
||||
|
||||
rc = ipapwd_gen_hashes(krbcfg, &pwdop->pwdata,
|
||||
userpw, is_krb, is_smb, is_ipant,
|
||||
&svals, &nt, &lm, &ntvals, &errMesg);
|
||||
&svals, &nt, &ntvals, &errMesg);
|
||||
if (rc != LDAP_SUCCESS) {
|
||||
goto done;
|
||||
}
|
||||
@ -349,11 +348,6 @@ static int ipapwd_pre_add(Slapi_PBlock *pb)
|
||||
ipapwd_free_slapi_value_array(&svals);
|
||||
}
|
||||
|
||||
if (lm && is_smb) {
|
||||
/* set value */
|
||||
slapi_entry_attr_set_charptr(e, "sambaLMPassword", lm);
|
||||
slapi_ch_free_string(&lm);
|
||||
}
|
||||
if (nt && is_smb) {
|
||||
/* set value */
|
||||
slapi_entry_attr_set_charptr(e, "sambaNTPassword", nt);
|
||||
@ -814,11 +808,10 @@ static int ipapwd_pre_mod(Slapi_PBlock *pb)
|
||||
Slapi_Value **svals = NULL;
|
||||
Slapi_Value **ntvals = NULL;
|
||||
char *nt = NULL;
|
||||
char *lm = NULL;
|
||||
|
||||
rc = ipapwd_gen_hashes(krbcfg, &pwdop->pwdata, unhashedpw,
|
||||
gen_krb_keys, is_smb, is_ipant,
|
||||
&svals, &nt, &lm, &ntvals, &errMesg);
|
||||
&svals, &nt, &ntvals, &errMesg);
|
||||
if (rc) {
|
||||
goto done;
|
||||
}
|
||||
@ -830,12 +823,6 @@ static int ipapwd_pre_mod(Slapi_PBlock *pb)
|
||||
ipapwd_free_slapi_value_array(&svals);
|
||||
}
|
||||
|
||||
if (lm && is_smb) {
|
||||
/* replace value */
|
||||
slapi_mods_add_string(smods, LDAP_MOD_REPLACE,
|
||||
"sambaLMPassword", lm);
|
||||
slapi_ch_free_string(&lm);
|
||||
}
|
||||
if (nt && is_smb) {
|
||||
/* replace value */
|
||||
slapi_mods_add_string(smods, LDAP_MOD_REPLACE,
|
||||
|
@ -74,15 +74,6 @@ int ipapwd_generate_new_history(char *password,
|
||||
char ***new_pwd_history,
|
||||
int *new_pwd_hlen);
|
||||
|
||||
struct ntlm_keys {
|
||||
uint8_t lm[16];
|
||||
uint8_t nt[16];
|
||||
};
|
||||
|
||||
int encode_ntlm_keys(char *newPasswd,
|
||||
char *upperPasswd,
|
||||
bool do_lm_hash,
|
||||
bool do_nt_hash,
|
||||
struct ntlm_keys *keys);
|
||||
int encode_nt_key(char *newPasswd, uint8_t *nt_key);
|
||||
|
||||
#endif
|
||||
|
@ -32,178 +32,70 @@
|
||||
#define KTF_UTF8 "UTF-8"
|
||||
#define KTF_UCS2 "UCS-2LE"
|
||||
|
||||
static const uint8_t parity_table[128] = {
|
||||
1, 2, 4, 7, 8, 11, 13, 14, 16, 19, 21, 22, 25, 26, 28, 31,
|
||||
32, 35, 37, 38, 41, 42, 44, 47, 49, 50, 52, 55, 56, 59, 61, 62,
|
||||
64, 67, 69, 70, 73, 74, 76, 79, 81, 82, 84, 87, 88, 91, 93, 94,
|
||||
97, 98,100,103,104,107,109,110,112,115,117,118,121,122,124,127,
|
||||
128,131,133,134,137,138,140,143,145,146,148,151,152,155,157,158,
|
||||
161,162,164,167,168,171,173,174,176,179,181,182,185,186,188,191,
|
||||
193,194,196,199,200,203,205,206,208,211,213,214,217,218,220,223,
|
||||
224,227,229,230,233,234,236,239,241,242,244,247,248,251,253,254
|
||||
};
|
||||
|
||||
static void lm_shuffle(uint8_t *out, uint8_t *in)
|
||||
{
|
||||
out[0] = parity_table[in[0]>>1];
|
||||
out[1] = parity_table[((in[0]<<6)|(in[1]>>2)) & 0x7F];
|
||||
out[2] = parity_table[((in[1]<<5)|(in[2]>>3)) & 0x7F];
|
||||
out[3] = parity_table[((in[2]<<4)|(in[3]>>4)) & 0x7F];
|
||||
out[4] = parity_table[((in[3]<<3)|(in[4]>>5)) & 0x7F];
|
||||
out[5] = parity_table[((in[4]<<2)|(in[5]>>6)) & 0x7F];
|
||||
out[6] = parity_table[((in[5]<<1)|(in[6]>>7)) & 0x7F];
|
||||
out[7] = parity_table[in[6] & 0x7F];
|
||||
}
|
||||
|
||||
/* create the lm and nt hashes
|
||||
/* create the nt hash
|
||||
newPassword: the clear text utf8 password
|
||||
upperPasswd: upper case version of clear text utf8 password
|
||||
do_lm_hash: determine if LM hash is generated
|
||||
do_nt_hash: determine if NT hash is generated
|
||||
keys[out]: array with generated hashes
|
||||
nt_key[out]: array with generated hash
|
||||
*/
|
||||
int encode_ntlm_keys(char *newPasswd,
|
||||
char *upperPasswd,
|
||||
bool do_lm_hash,
|
||||
bool do_nt_hash,
|
||||
struct ntlm_keys *keys)
|
||||
int encode_nt_key(char *newPasswd, uint8_t *nt_key)
|
||||
{
|
||||
int ret = 0;
|
||||
iconv_t cd;
|
||||
size_t cs, il, ol, sl;
|
||||
char *inc, *outc;
|
||||
char *ucs2Passwd;
|
||||
MD4_CTX md4ctx;
|
||||
|
||||
/* do lanman first */
|
||||
if (do_lm_hash) {
|
||||
iconv_t cd;
|
||||
size_t cs, il, ol;
|
||||
char *inc, *outc;
|
||||
char *asciiPasswd;
|
||||
DES_key_schedule schedule;
|
||||
DES_cblock deskey;
|
||||
DES_cblock magic = "KGS!@#$%";
|
||||
|
||||
if (upperPasswd == NULL) {
|
||||
ret = -1;
|
||||
goto done;
|
||||
}
|
||||
il = strlen(upperPasswd);
|
||||
|
||||
/* TODO: must store the dos charset somewhere in the directory */
|
||||
cd = iconv_open(KTF_DOS_CHARSET, KTF_UTF8);
|
||||
if (cd == (iconv_t)(-1)) {
|
||||
ret = -1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* an ascii string can only be smaller than or equal to an utf8 one */
|
||||
ol = il;
|
||||
if (ol < 14) ol = 14;
|
||||
asciiPasswd = calloc(ol+1, 1);
|
||||
if (!asciiPasswd) {
|
||||
iconv_close(cd);
|
||||
ret = -1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
inc = upperPasswd;
|
||||
outc = asciiPasswd;
|
||||
cs = iconv(cd, &inc, &il, &outc, &ol);
|
||||
if (cs == -1) {
|
||||
ret = -1;
|
||||
free(asciiPasswd);
|
||||
iconv_close(cd);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* done with these */
|
||||
iconv_close(cd);
|
||||
|
||||
/* we are interested only in the first 14 ASCII chars for lanman */
|
||||
if (strlen(asciiPasswd) > 14) {
|
||||
asciiPasswd[14] = '\0';
|
||||
}
|
||||
|
||||
/* first half */
|
||||
lm_shuffle(deskey, (uint8_t *)asciiPasswd);
|
||||
|
||||
DES_set_key_unchecked(&deskey, &schedule);
|
||||
DES_ecb_encrypt(&magic, (DES_cblock *)keys->lm,
|
||||
&schedule, DES_ENCRYPT);
|
||||
|
||||
/* second half */
|
||||
lm_shuffle(deskey, (uint8_t *)&asciiPasswd[7]);
|
||||
|
||||
DES_set_key_unchecked(&deskey, &schedule);
|
||||
DES_ecb_encrypt(&magic, (DES_cblock *)&(keys->lm[8]),
|
||||
&schedule, DES_ENCRYPT);
|
||||
|
||||
/* done with it */
|
||||
free(asciiPasswd);
|
||||
|
||||
} else {
|
||||
memset(keys->lm, 0, 16);
|
||||
/* TODO: must store the dos charset somewhere in the directory */
|
||||
cd = iconv_open(KTF_UCS2, KTF_UTF8);
|
||||
if (cd == (iconv_t)(-1)) {
|
||||
ret = -1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (do_nt_hash) {
|
||||
iconv_t cd;
|
||||
size_t cs, il, ol, sl;
|
||||
char *inc, *outc;
|
||||
char *ucs2Passwd;
|
||||
MD4_CTX md4ctx;
|
||||
il = strlen(newPasswd);
|
||||
|
||||
/* TODO: must store the dos charset somewhere in the directory */
|
||||
cd = iconv_open(KTF_UCS2, KTF_UTF8);
|
||||
if (cd == (iconv_t)(-1)) {
|
||||
ret = -1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
il = strlen(newPasswd);
|
||||
|
||||
/* an ucs2 string can be at most double than an utf8 one */
|
||||
sl = ol = (il+1)*2;
|
||||
ucs2Passwd = calloc(ol, 1);
|
||||
if (!ucs2Passwd) {
|
||||
ret = -1;
|
||||
iconv_close(cd);
|
||||
goto done;
|
||||
}
|
||||
|
||||
inc = newPasswd;
|
||||
outc = ucs2Passwd;
|
||||
cs = iconv(cd, &inc, &il, &outc, &ol);
|
||||
if (cs == -1) {
|
||||
ret = -1;
|
||||
free(ucs2Passwd);
|
||||
iconv_close(cd);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* done with it */
|
||||
/* an ucs2 string can be at most double than an utf8 one */
|
||||
sl = ol = (il+1)*2;
|
||||
ucs2Passwd = calloc(ol, 1);
|
||||
if (!ucs2Passwd) {
|
||||
ret = -1;
|
||||
iconv_close(cd);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* get the final ucs2 string length */
|
||||
sl -= ol;
|
||||
inc = newPasswd;
|
||||
outc = ucs2Passwd;
|
||||
cs = iconv(cd, &inc, &il, &outc, &ol);
|
||||
if (cs == -1) {
|
||||
ret = -1;
|
||||
free(ucs2Passwd);
|
||||
iconv_close(cd);
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = MD4_Init(&md4ctx);
|
||||
if (ret == 0) {
|
||||
ret = -1;
|
||||
free(ucs2Passwd);
|
||||
goto done;
|
||||
}
|
||||
ret = MD4_Update(&md4ctx, ucs2Passwd, sl);
|
||||
if (ret == 0) {
|
||||
ret = -1;
|
||||
free(ucs2Passwd);
|
||||
goto done;
|
||||
}
|
||||
ret = MD4_Final(keys->nt, &md4ctx);
|
||||
if (ret == 0) {
|
||||
ret = -1;
|
||||
free(ucs2Passwd);
|
||||
goto done;
|
||||
}
|
||||
/* done with it */
|
||||
iconv_close(cd);
|
||||
|
||||
} else {
|
||||
memset(keys->nt, 0, 16);
|
||||
/* get the final ucs2 string length */
|
||||
sl -= ol;
|
||||
|
||||
ret = MD4_Init(&md4ctx);
|
||||
if (ret == 0) {
|
||||
ret = -1;
|
||||
free(ucs2Passwd);
|
||||
goto done;
|
||||
}
|
||||
ret = MD4_Update(&md4ctx, ucs2Passwd, sl);
|
||||
if (ret == 0) {
|
||||
ret = -1;
|
||||
free(ucs2Passwd);
|
||||
goto done;
|
||||
}
|
||||
ret = MD4_Final(nt_key, &md4ctx);
|
||||
if (ret == 0) {
|
||||
ret = -1;
|
||||
free(ucs2Passwd);
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user