Make pwd-extop aware of new ipaNTHash attribute

This commit is contained in:
Sumit Bose 2011-11-24 18:38:38 +01:00 committed by Simo Sorce
parent 3de257fe54
commit 27f02881c1
5 changed files with 89 additions and 29 deletions

View File

@ -156,7 +156,7 @@ static int ipapwd_chpwop(Slapi_PBlock *pb, struct ipapwd_krbcfg *krbcfg)
Slapi_Value *objectclass=NULL; Slapi_Value *objectclass=NULL;
char *attrlist[] = {"*", "passwordHistory", NULL }; char *attrlist[] = {"*", "passwordHistory", NULL };
struct ipapwd_data pwdata; struct ipapwd_data pwdata;
int is_krb, is_smb; int is_krb, is_smb, is_ipant;
char *principal = NULL; char *principal = NULL;
/* Get the ber value of the extended operation */ /* Get the ber value of the extended operation */
@ -365,7 +365,7 @@ parse_req_done:
} }
rc = ipapwd_entry_checks(pb, targetEntry, rc = ipapwd_entry_checks(pb, targetEntry,
&is_root, &is_krb, &is_smb, &is_root, &is_krb, &is_smb, &is_ipant,
SLAPI_USERPWD_ATTR, SLAPI_ACL_WRITE); SLAPI_USERPWD_ATTR, SLAPI_ACL_WRITE);
if (rc) { if (rc) {
goto free_and_return; goto free_and_return;

View File

@ -113,7 +113,7 @@ struct ipapwd_krbcfg {
}; };
int ipapwd_entry_checks(Slapi_PBlock *pb, struct slapi_entry *e, int ipapwd_entry_checks(Slapi_PBlock *pb, struct slapi_entry *e,
int *is_root, int *is_krb, int *is_smb, int *is_root, int *is_krb, int *is_smb, int *is_ipant,
char *attr, int access); char *attr, int access);
int ipapwd_gen_checks(Slapi_PBlock *pb, char **errMesg, int ipapwd_gen_checks(Slapi_PBlock *pb, char **errMesg,
struct ipapwd_krbcfg **config, int check_flags); struct ipapwd_krbcfg **config, int check_flags);
@ -144,8 +144,9 @@ void ipapwd_keyset_free(struct ipapwd_keyset **pkset);
int ipapwd_gen_hashes(struct ipapwd_krbcfg *krbcfg, int ipapwd_gen_hashes(struct ipapwd_krbcfg *krbcfg,
struct ipapwd_data *data, char *userpw, struct ipapwd_data *data, char *userpw,
int is_krb, int is_smb, Slapi_Value ***svals, int is_krb, int is_smb, int is_ipant,
char **nthash, char **lmhash, char **errMesg); Slapi_Value ***svals, char **nthash, char **lmhash,
Slapi_Value ***ntvals, char **errMesg);
/* from ipapwd_prepost.c */ /* from ipapwd_prepost.c */
int ipapwd_ext_init(void); int ipapwd_ext_init(void);

View File

@ -498,7 +498,7 @@ done:
/*==Common-public-functions=============================================*/ /*==Common-public-functions=============================================*/
int ipapwd_entry_checks(Slapi_PBlock *pb, struct slapi_entry *e, int ipapwd_entry_checks(Slapi_PBlock *pb, struct slapi_entry *e,
int *is_root, int *is_krb, int *is_smb, int *is_root, int *is_krb, int *is_smb, int *is_ipant,
char *attr, int acc) char *attr, int acc)
{ {
Slapi_Value *sval; Slapi_Value *sval;
@ -535,6 +535,15 @@ int ipapwd_entry_checks(Slapi_PBlock *pb, struct slapi_entry *e,
*is_smb = slapi_entry_attr_has_syntax_value(e, SLAPI_ATTR_OBJECTCLASS, sval); *is_smb = slapi_entry_attr_has_syntax_value(e, SLAPI_ATTR_OBJECTCLASS, sval);
slapi_value_free(&sval); slapi_value_free(&sval);
sval = slapi_value_new_string("ipaNTUserAttrs");
if (!sval) {
rc = LDAP_OPERATIONS_ERROR;
goto done;
}
*is_ipant = slapi_entry_attr_has_syntax_value(e, SLAPI_ATTR_OBJECTCLASS,
sval);
slapi_value_free(&sval);
rc = LDAP_SUCCESS; rc = LDAP_SUCCESS;
done: done:
@ -765,14 +774,17 @@ int ipapwd_SetPassword(struct ipapwd_krbcfg *krbcfg,
int ret = 0; int ret = 0;
Slapi_Mods *smods = NULL; Slapi_Mods *smods = NULL;
Slapi_Value **svals = NULL; Slapi_Value **svals = NULL;
Slapi_Value **ntvals = NULL;
Slapi_Value **pwvals = NULL; Slapi_Value **pwvals = NULL;
struct tm utctime; struct tm utctime;
char timestr[GENERALIZED_TIME_LENGTH+1]; char timestr[GENERALIZED_TIME_LENGTH+1];
char *lm = NULL; char *lm = NULL;
char *nt = NULL; char *nt = NULL;
int is_smb = 0; int is_smb = 0;
int is_ipant = 0;
int is_host = 0; int is_host = 0;
Slapi_Value *sambaSamAccount; Slapi_Value *sambaSamAccount;
Slapi_Value *ipaNTUserAttrs;
Slapi_Value *ipaHost; Slapi_Value *ipaHost;
char *errMesg = NULL; char *errMesg = NULL;
char *modtime = NULL; char *modtime = NULL;
@ -782,10 +794,17 @@ int ipapwd_SetPassword(struct ipapwd_krbcfg *krbcfg,
sambaSamAccount = slapi_value_new_string("sambaSamAccount"); sambaSamAccount = slapi_value_new_string("sambaSamAccount");
if (slapi_entry_attr_has_syntax_value(data->target, if (slapi_entry_attr_has_syntax_value(data->target,
"objectClass", sambaSamAccount)) { "objectClass", sambaSamAccount)) {
is_smb = 1;; is_smb = 1;
} }
slapi_value_free(&sambaSamAccount); slapi_value_free(&sambaSamAccount);
ipaNTUserAttrs = slapi_value_new_string("ipaNTUserAttrs");
if (slapi_entry_attr_has_syntax_value(data->target,
"objectClass", ipaNTUserAttrs)) {
is_ipant = 1;
}
slapi_value_free(&ipaNTUserAttrs);
ipaHost = slapi_value_new_string("ipaHost"); ipaHost = slapi_value_new_string("ipaHost");
if (slapi_entry_attr_has_syntax_value(data->target, if (slapi_entry_attr_has_syntax_value(data->target,
"objectClass", ipaHost)) { "objectClass", ipaHost)) {
@ -795,8 +814,8 @@ int ipapwd_SetPassword(struct ipapwd_krbcfg *krbcfg,
ret = ipapwd_gen_hashes(krbcfg, data, ret = ipapwd_gen_hashes(krbcfg, data,
data->password, data->password,
is_krb, is_smb, is_krb, is_smb, is_ipant,
&svals, &nt, &lm, &errMesg); &svals, &nt, &lm, &ntvals, &errMesg);
if (ret) { if (ret) {
goto free_and_return; goto free_and_return;
} }
@ -835,15 +854,21 @@ int ipapwd_SetPassword(struct ipapwd_krbcfg *krbcfg,
} }
} }
if (lm) { if (lm && is_smb) {
slapi_mods_add_string(smods, LDAP_MOD_REPLACE, slapi_mods_add_string(smods, LDAP_MOD_REPLACE,
"sambaLMPassword", lm); "sambaLMPassword", lm);
} }
if (nt) { if (nt && is_smb) {
slapi_mods_add_string(smods, LDAP_MOD_REPLACE, slapi_mods_add_string(smods, LDAP_MOD_REPLACE,
"sambaNTPassword", nt); "sambaNTPassword", nt);
} }
if (ntvals && is_ipant) {
slapi_mods_add_mod_values(smods, LDAP_MOD_REPLACE,
"ipaNTHash", ntvals);
}
if (is_smb) { if (is_smb) {
/* with samba integration we need to also set sambaPwdLastSet or /* with samba integration we need to also set sambaPwdLastSet or
* samba will decide the user has to change the password again */ * samba will decide the user has to change the password again */
@ -899,6 +924,7 @@ free_and_return:
if (modtime) slapi_ch_free((void **)&modtime); if (modtime) slapi_ch_free((void **)&modtime);
slapi_mods_free(&smods); slapi_mods_free(&smods);
ipapwd_free_slapi_value_array(&svals); ipapwd_free_slapi_value_array(&svals);
ipapwd_free_slapi_value_array(&ntvals);
ipapwd_free_slapi_value_array(&pwvals); ipapwd_free_slapi_value_array(&pwvals);
return ret; return ret;

View File

@ -395,8 +395,9 @@ done:
int ipapwd_gen_hashes(struct ipapwd_krbcfg *krbcfg, int ipapwd_gen_hashes(struct ipapwd_krbcfg *krbcfg,
struct ipapwd_data *data, char *userpw, struct ipapwd_data *data, char *userpw,
int is_krb, int is_smb, Slapi_Value ***svals, int is_krb, int is_smb, int is_ipant, Slapi_Value ***svals,
char **nthash, char **lmhash, char **errMesg) char **nthash, char **lmhash, Slapi_Value ***ntvals,
char **errMesg)
{ {
int rc; int rc;
@ -417,7 +418,7 @@ int ipapwd_gen_hashes(struct ipapwd_krbcfg *krbcfg,
} }
} }
if (is_smb) { if (is_smb || is_ipant) {
char lm[33], nt[33]; char lm[33], nt[33];
struct ntlm_keys ntlm; struct ntlm_keys ntlm;
int ret; int ret;
@ -442,6 +443,20 @@ int ipapwd_gen_hashes(struct ipapwd_krbcfg *krbcfg,
nt[32] = '\0'; nt[32] = '\0';
*nthash = slapi_ch_strdup(nt); *nthash = slapi_ch_strdup(nt);
} }
if (is_ipant) {
*ntvals = (Slapi_Value **)calloc(2, sizeof(Slapi_Value *));
if (!svals) {
LOG_OOM();
rc = LDAP_OPERATIONS_ERROR;
goto done;
}
(*ntvals)[0] = slapi_value_new();
if (slapi_value_set((*ntvals)[0], ntlm.nt, 16) == NULL) {
rc = LDAP_OPERATIONS_ERROR;
goto done;
}
}
} }
rc = LDAP_SUCCESS; rc = LDAP_SUCCESS;
@ -451,6 +466,7 @@ done:
/* when error, free possibly allocated output parameters */ /* when error, free possibly allocated output parameters */
if (rc) { if (rc) {
ipapwd_free_slapi_value_array(svals); ipapwd_free_slapi_value_array(svals);
ipapwd_free_slapi_value_array(ntvals);
} }
return rc; return rc;

View File

@ -163,7 +163,7 @@ static int ipapwd_pre_add(Slapi_PBlock *pb)
char *dn = NULL; char *dn = NULL;
struct ipapwd_operation *pwdop = NULL; struct ipapwd_operation *pwdop = NULL;
void *op; void *op;
int is_repl_op, is_root, is_krb, is_smb; int is_repl_op, is_root, is_krb, is_smb, is_ipant;
int ret; int ret;
int rc = LDAP_SUCCESS; int rc = LDAP_SUCCESS;
@ -240,7 +240,7 @@ static int ipapwd_pre_add(Slapi_PBlock *pb)
} }
rc = ipapwd_entry_checks(pb, e, rc = ipapwd_entry_checks(pb, e,
&is_root, &is_krb, &is_smb, &is_root, &is_krb, &is_smb, &is_ipant,
NULL, SLAPI_ACL_ADD); NULL, SLAPI_ACL_ADD);
if (rc != LDAP_SUCCESS) { if (rc != LDAP_SUCCESS) {
goto done; goto done;
@ -307,17 +307,18 @@ static int ipapwd_pre_add(Slapi_PBlock *pb)
goto done; goto done;
} }
if (is_krb || is_smb) { if (is_krb || is_smb || is_ipant) {
Slapi_Value **svals = NULL; Slapi_Value **svals = NULL;
Slapi_Value **ntvals = NULL;
char *nt = NULL; char *nt = NULL;
char *lm = NULL; char *lm = NULL;
pwdop->is_krb = is_krb; pwdop->is_krb = is_krb;
rc = ipapwd_gen_hashes(krbcfg, &pwdop->pwdata, rc = ipapwd_gen_hashes(krbcfg, &pwdop->pwdata,
userpw, is_krb, is_smb, userpw, is_krb, is_smb, is_ipant,
&svals, &nt, &lm, &errMesg); &svals, &nt, &lm, &ntvals, &errMesg);
if (rc != LDAP_SUCCESS) { if (rc != LDAP_SUCCESS) {
goto done; goto done;
} }
@ -335,17 +336,22 @@ static int ipapwd_pre_add(Slapi_PBlock *pb)
ipapwd_free_slapi_value_array(&svals); ipapwd_free_slapi_value_array(&svals);
} }
if (lm) { if (lm && is_smb) {
/* set value */ /* set value */
slapi_entry_attr_set_charptr(e, "sambaLMPassword", lm); slapi_entry_attr_set_charptr(e, "sambaLMPassword", lm);
slapi_ch_free_string(&lm); slapi_ch_free_string(&lm);
} }
if (nt) { if (nt && is_smb) {
/* set value */ /* set value */
slapi_entry_attr_set_charptr(e, "sambaNTPassword", nt); slapi_entry_attr_set_charptr(e, "sambaNTPassword", nt);
slapi_ch_free_string(&nt); slapi_ch_free_string(&nt);
} }
if (ntvals && is_ipant) {
slapi_entry_attr_replace_sv(e, "ipaNTHash", ntvals);
ipapwd_free_slapi_value_array(&ntvals);
}
if (is_smb) { if (is_smb) {
/* with samba integration we need to also set sambaPwdLastSet or /* with samba integration we need to also set sambaPwdLastSet or
* samba will decide the user has to change the password again */ * samba will decide the user has to change the password again */
@ -397,7 +403,7 @@ static int ipapwd_pre_mod(Slapi_PBlock *pb)
struct slapi_entry *e = NULL; struct slapi_entry *e = NULL;
struct ipapwd_operation *pwdop = NULL; struct ipapwd_operation *pwdop = NULL;
void *op; void *op;
int is_repl_op, is_pwd_op, is_root, is_krb, is_smb; int is_repl_op, is_pwd_op, is_root, is_krb, is_smb, is_ipant;
int has_krb_keys = 0; int has_krb_keys = 0;
int has_history = 0; int has_history = 0;
int gen_krb_keys = 0; int gen_krb_keys = 0;
@ -514,7 +520,7 @@ static int ipapwd_pre_mod(Slapi_PBlock *pb)
} }
rc = ipapwd_entry_checks(pb, e, rc = ipapwd_entry_checks(pb, e,
&is_root, &is_krb, &is_smb, &is_root, &is_krb, &is_smb, &is_ipant,
SLAPI_USERPWD_ATTR, SLAPI_ACL_WRITE); SLAPI_USERPWD_ATTR, SLAPI_ACL_WRITE);
if (rc) { if (rc) {
goto done; goto done;
@ -585,6 +591,7 @@ static int ipapwd_pre_mod(Slapi_PBlock *pb)
* flags, so we sero them out and see if they get set again */ * flags, so we sero them out and see if they get set again */
is_krb = 0; is_krb = 0;
is_smb = 0; is_smb = 0;
is_ipant = 0;
case LDAP_MOD_ADD: case LDAP_MOD_ADD:
bv = slapi_mod_get_first_value(smod); bv = slapi_mod_get_first_value(smod);
@ -598,6 +605,8 @@ static int ipapwd_pre_mod(Slapi_PBlock *pb)
is_krb = 1; is_krb = 1;
if (0 == strncasecmp("sambaSamAccount", bv->bv_val, bv->bv_len)) if (0 == strncasecmp("sambaSamAccount", bv->bv_val, bv->bv_len))
is_smb = 1; is_smb = 1;
if (0 == strncasecmp("ipaNTUserAttrs", bv->bv_val, bv->bv_len))
is_ipant = 1;
} while ((bv = slapi_mod_get_next_value(smod)) != NULL); } while ((bv = slapi_mod_get_next_value(smod)) != NULL);
break; break;
@ -606,6 +615,7 @@ static int ipapwd_pre_mod(Slapi_PBlock *pb)
/* can this happen for objectclasses ? */ /* can this happen for objectclasses ? */
is_krb = 0; is_krb = 0;
is_smb = 0; is_smb = 0;
is_ipant = 0;
default: default:
break; break;
@ -654,7 +664,7 @@ static int ipapwd_pre_mod(Slapi_PBlock *pb)
/* Check this is a clear text password, or refuse operation (only if we need /* Check this is a clear text password, or refuse operation (only if we need
* to comput other hashes */ * to comput other hashes */
if (! unhashedpw && (gen_krb_keys || is_smb)) { if (! unhashedpw && (gen_krb_keys || is_smb || is_ipant)) {
if ('{' == userpw[0]) { if ('{' == userpw[0]) {
if (0 == strncasecmp(userpw, "{CLEAR}", strlen("{CLEAR}"))) { if (0 == strncasecmp(userpw, "{CLEAR}", strlen("{CLEAR}"))) {
unhashedpw = slapi_ch_strdup(&userpw[strlen("{CLEAR}")]); unhashedpw = slapi_ch_strdup(&userpw[strlen("{CLEAR}")]);
@ -746,15 +756,16 @@ static int ipapwd_pre_mod(Slapi_PBlock *pb)
} }
} }
if (gen_krb_keys || is_smb) { if (gen_krb_keys || is_smb || is_ipant) {
Slapi_Value **svals = NULL; Slapi_Value **svals = NULL;
Slapi_Value **ntvals = NULL;
char *nt = NULL; char *nt = NULL;
char *lm = NULL; char *lm = NULL;
rc = ipapwd_gen_hashes(krbcfg, &pwdop->pwdata, unhashedpw, rc = ipapwd_gen_hashes(krbcfg, &pwdop->pwdata, unhashedpw,
gen_krb_keys, is_smb, gen_krb_keys, is_smb, is_ipant,
&svals, &nt, &lm, &errMesg); &svals, &nt, &lm, &ntvals, &errMesg);
if (rc) { if (rc) {
goto done; goto done;
} }
@ -766,19 +777,25 @@ static int ipapwd_pre_mod(Slapi_PBlock *pb)
ipapwd_free_slapi_value_array(&svals); ipapwd_free_slapi_value_array(&svals);
} }
if (lm) { if (lm && is_smb) {
/* replace value */ /* replace value */
slapi_mods_add_string(smods, LDAP_MOD_REPLACE, slapi_mods_add_string(smods, LDAP_MOD_REPLACE,
"sambaLMPassword", lm); "sambaLMPassword", lm);
slapi_ch_free_string(&lm); slapi_ch_free_string(&lm);
} }
if (nt) { if (nt && is_smb) {
/* replace value */ /* replace value */
slapi_mods_add_string(smods, LDAP_MOD_REPLACE, slapi_mods_add_string(smods, LDAP_MOD_REPLACE,
"sambaNTPassword", nt); "sambaNTPassword", nt);
slapi_ch_free_string(&nt); slapi_ch_free_string(&nt);
} }
if (ntvals && is_ipant) {
slapi_mods_add_mod_values(smods, LDAP_MOD_REPLACE,
"ipaNTHash", ntvals);
ipapwd_free_slapi_value_array(&ntvals);
}
if (is_smb) { if (is_smb) {
/* with samba integration we need to also set sambaPwdLastSet or /* with samba integration we need to also set sambaPwdLastSet or
* samba will decide the user has to change the password again */ * samba will decide the user has to change the password again */