Imported Upstream version 4.0.5
This commit is contained in:
@@ -46,8 +46,6 @@
|
||||
/* Type of connection for this operation;*/
|
||||
#define LDAP_EXTOP_PASSMOD_CONN_SECURE
|
||||
|
||||
#define PROC_SYS_FIPS "/proc/sys/crypto/fips_enabled"
|
||||
|
||||
/* Uncomment the following #undef FOR TESTING:
|
||||
* allows non-SSL connections to use the password change extended op */
|
||||
/* #undef LDAP_EXTOP_PASSMOD_CONN_SECURE */
|
||||
@@ -57,34 +55,21 @@ extern const char *ipa_realm_dn;
|
||||
extern const char *ipa_etc_config_dn;
|
||||
extern const char *ipa_pwd_config_dn;
|
||||
|
||||
/* These are the default enc:salt types if nothing is defined in LDAP */
|
||||
/* These are the default enc:salt types if nothing is defined.
|
||||
* TODO: retrieve the configure set of ecntypes either from the
|
||||
* kfc.conf file or by synchronizing the file content into
|
||||
* the directory */
|
||||
static const char *ipapwd_def_encsalts[] = {
|
||||
"aes256-cts:special",
|
||||
"aes128-cts:special",
|
||||
"des3-hmac-sha1:normal",
|
||||
/* "arcfour-hmac:normal",
|
||||
"des-hmac-sha1:normal",
|
||||
"des-cbc-md5:normal", */
|
||||
"des-cbc-crc:normal",
|
||||
/* "des-cbc-crc:v4",
|
||||
"des-cbc-crc:afs3", */
|
||||
NULL
|
||||
};
|
||||
|
||||
static bool fips_enabled(void)
|
||||
{
|
||||
int fd;
|
||||
ssize_t len;
|
||||
char buf[8];
|
||||
|
||||
fd = open(PROC_SYS_FIPS, O_RDONLY);
|
||||
if (fd != -1) {
|
||||
len = read(fd, buf, sizeof(buf));
|
||||
close(fd);
|
||||
/* Assume FIPS in enabled if PROC_SYS_FIPS contains a non-0 value
|
||||
* similar to the is_fips_enabled() check in
|
||||
* ipaplatform/redhat/tasks.py */
|
||||
if (!(len == 2 && buf[0] == '0' && buf[1] == '\n')) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static struct ipapwd_krbcfg *ipapwd_getConfig(void)
|
||||
{
|
||||
krb5_error_code krberr;
|
||||
@@ -255,28 +240,24 @@ static struct ipapwd_krbcfg *ipapwd_getConfig(void)
|
||||
|
||||
/* get the ipa etc/ipaConfig entry */
|
||||
config->allow_nt_hash = false;
|
||||
if (fips_enabled()) {
|
||||
LOG("FIPS mode is enabled, NT hashes are not allowed.\n");
|
||||
ret = ipapwd_getEntry(ipa_etc_config_dn, &config_entry, NULL);
|
||||
if (ret != LDAP_SUCCESS) {
|
||||
LOG_FATAL("No config Entry?\n");
|
||||
goto free_and_error;
|
||||
} else {
|
||||
ret = ipapwd_getEntry(ipa_etc_config_dn, &config_entry, NULL);
|
||||
if (ret != LDAP_SUCCESS) {
|
||||
LOG_FATAL("No config Entry?\n");
|
||||
goto free_and_error;
|
||||
} else {
|
||||
tmparray = slapi_entry_attr_get_charray(config_entry,
|
||||
"ipaConfigString");
|
||||
for (i = 0; tmparray && tmparray[i]; i++) {
|
||||
if (strcasecmp(tmparray[i], "AllowNThash") == 0) {
|
||||
config->allow_nt_hash = true;
|
||||
continue;
|
||||
}
|
||||
tmparray = slapi_entry_attr_get_charray(config_entry,
|
||||
"ipaConfigString");
|
||||
for (i = 0; tmparray && tmparray[i]; i++) {
|
||||
if (strcasecmp(tmparray[i], "AllowNThash") == 0) {
|
||||
config->allow_nt_hash = true;
|
||||
continue;
|
||||
}
|
||||
if (tmparray) slapi_ch_array_free(tmparray);
|
||||
}
|
||||
|
||||
slapi_entry_free(config_entry);
|
||||
if (tmparray) slapi_ch_array_free(tmparray);
|
||||
}
|
||||
|
||||
slapi_entry_free(config_entry);
|
||||
|
||||
return config;
|
||||
|
||||
free_and_error:
|
||||
@@ -344,6 +325,7 @@ int ipapwd_getPolicy(const char *dn,
|
||||
int buffer_flags=0;
|
||||
Slapi_ValueSet* results = NULL;
|
||||
char *actual_type_name = NULL;
|
||||
int tmpint;
|
||||
|
||||
LOG_TRACE("Searching policy for [%s]\n", dn);
|
||||
|
||||
@@ -408,9 +390,15 @@ int ipapwd_getPolicy(const char *dn,
|
||||
/* read data out of policy object */
|
||||
policy->min_pwd_life = slapi_entry_attr_get_int(pe, "krbMinPwdLife");
|
||||
|
||||
policy->max_pwd_life = slapi_entry_attr_get_int(pe, "krbMaxPwdLife");
|
||||
tmpint = slapi_entry_attr_get_int(pe, "krbMaxPwdLife");
|
||||
if (tmpint != 0) {
|
||||
policy->max_pwd_life = tmpint;
|
||||
}
|
||||
|
||||
policy->min_pwd_length = slapi_entry_attr_get_int(pe, "krbPwdMinLength");
|
||||
tmpint = slapi_entry_attr_get_int(pe, "krbPwdMinLength");
|
||||
if (tmpint != 0) {
|
||||
policy->min_pwd_length = tmpint;
|
||||
}
|
||||
|
||||
policy->history_length = slapi_entry_attr_get_int(pe,
|
||||
"krbPwdHistoryLength");
|
||||
@@ -575,14 +563,7 @@ int ipapwd_CheckPolicy(struct ipapwd_data *data)
|
||||
pol.min_pwd_length = IPAPWD_DEFAULT_MINLEN;
|
||||
|
||||
switch(data->changetype) {
|
||||
case IPA_CHANGETYPE_NORMAL:
|
||||
/* Find the entry with the password policy */
|
||||
ret = ipapwd_getPolicy(data->dn, data->target, &pol);
|
||||
if (ret) {
|
||||
LOG_TRACE("No password policy, use defaults");
|
||||
}
|
||||
break;
|
||||
case IPA_CHANGETYPE_ADMIN:
|
||||
case IPA_CHANGETYPE_ADMIN:
|
||||
/* The expiration date needs to be older than the current time
|
||||
* otherwise the KDC may not immediately register the password
|
||||
* as expired. The last password change needs to match the
|
||||
@@ -590,11 +571,14 @@ int ipapwd_CheckPolicy(struct ipapwd_data *data)
|
||||
*/
|
||||
data->timeNow -= 1;
|
||||
data->expireTime = data->timeNow;
|
||||
|
||||
/* let set the entry password property according to its
|
||||
* entry password policy (done with ipapwd_getPolicy)
|
||||
* For this intentional fallthrough here
|
||||
*/
|
||||
break;
|
||||
case IPA_CHANGETYPE_NORMAL:
|
||||
/* Find the entry with the password policy */
|
||||
ret = ipapwd_getPolicy(data->dn, data->target, &pol);
|
||||
if (ret) {
|
||||
LOG_TRACE("No password policy, use defaults");
|
||||
}
|
||||
break;
|
||||
case IPA_CHANGETYPE_DSMGR:
|
||||
/* PassSync agents and Directory Manager can administratively
|
||||
* change the password without expiring it.
|
||||
@@ -608,7 +592,6 @@ int ipapwd_CheckPolicy(struct ipapwd_data *data)
|
||||
LOG_TRACE("No password policy, use defaults");
|
||||
} else {
|
||||
pol.max_pwd_life = tmppol.max_pwd_life;
|
||||
pol.history_length = tmppol.history_length;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -645,11 +628,7 @@ int ipapwd_CheckPolicy(struct ipapwd_data *data)
|
||||
slapi_ch_array_free(pwd_history);
|
||||
|
||||
if (data->expireTime == 0) {
|
||||
if (pol.max_pwd_life > 0) {
|
||||
/* max_pwd_life = 0 => never expire
|
||||
* set expire time only when max_pwd_life > 0 */
|
||||
data->expireTime = data->timeNow + pol.max_pwd_life;
|
||||
}
|
||||
data->expireTime = data->timeNow + pol.max_pwd_life;
|
||||
}
|
||||
|
||||
data->policy = pol;
|
||||
@@ -734,33 +713,6 @@ next:
|
||||
return kvno;
|
||||
}
|
||||
|
||||
int ipapwd_setdate(Slapi_Entry *source, Slapi_Mods *smods, const char *attr,
|
||||
time_t date, bool remove)
|
||||
{
|
||||
char timestr[GENERALIZED_TIME_LENGTH+1];
|
||||
struct tm utctime;
|
||||
Slapi_Attr *t;
|
||||
bool exists;
|
||||
|
||||
exists = (slapi_entry_attr_find(source, attr, &t) == 0);
|
||||
|
||||
if (remove) {
|
||||
if (exists) {
|
||||
slapi_mods_add_mod_values(smods, LDAP_MOD_DELETE, attr, NULL);
|
||||
}
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
|
||||
if (!gmtime_r(&date, &utctime)) {
|
||||
LOG_FATAL("failed to convert %s date\n", attr);
|
||||
return LDAP_OPERATIONS_ERROR;
|
||||
}
|
||||
strftime(timestr, GENERALIZED_TIME_LENGTH + 1, "%Y%m%d%H%M%SZ", &utctime);
|
||||
slapi_mods_add_string(smods, exists ? LDAP_MOD_REPLACE : LDAP_MOD_ADD,
|
||||
attr, timestr);
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
|
||||
/* Modify the Password attributes of the entry */
|
||||
int ipapwd_SetPassword(struct ipapwd_krbcfg *krbcfg,
|
||||
struct ipapwd_data *data, int is_krb)
|
||||
@@ -770,6 +722,8 @@ int ipapwd_SetPassword(struct ipapwd_krbcfg *krbcfg,
|
||||
Slapi_Value **svals = NULL;
|
||||
Slapi_Value **ntvals = NULL;
|
||||
Slapi_Value **pwvals = NULL;
|
||||
struct tm utctime;
|
||||
char timestr[GENERALIZED_TIME_LENGTH+1];
|
||||
char *nt = NULL;
|
||||
int is_smb = 0;
|
||||
int is_ipant = 0;
|
||||
@@ -821,19 +775,29 @@ int ipapwd_SetPassword(struct ipapwd_krbcfg *krbcfg,
|
||||
* keytab so don't set it on hosts.
|
||||
*/
|
||||
if (!is_host) {
|
||||
/* change Last Password Change field with the current date */
|
||||
ret = ipapwd_setdate(data->target, smods, "krbLastPwdChange",
|
||||
data->timeNow, false);
|
||||
if (ret != LDAP_SUCCESS)
|
||||
goto free_and_return;
|
||||
/* change Last Password Change field with the current date */
|
||||
if (!gmtime_r(&(data->timeNow), &utctime)) {
|
||||
LOG_FATAL("failed to retrieve current date (buggy gmtime_r ?)\n");
|
||||
ret = LDAP_OPERATIONS_ERROR;
|
||||
goto free_and_return;
|
||||
}
|
||||
strftime(timestr, GENERALIZED_TIME_LENGTH + 1,
|
||||
"%Y%m%d%H%M%SZ", &utctime);
|
||||
slapi_mods_add_string(smods, LDAP_MOD_REPLACE,
|
||||
"krbLastPwdChange", timestr);
|
||||
|
||||
/* set Password Expiration date */
|
||||
ret = ipapwd_setdate(data->target, smods, "krbPasswordExpiration",
|
||||
data->expireTime, (data->expireTime == 0));
|
||||
if (ret != LDAP_SUCCESS)
|
||||
goto free_and_return;
|
||||
/* set Password Expiration date */
|
||||
if (!gmtime_r(&(data->expireTime), &utctime)) {
|
||||
LOG_FATAL("failed to convert expiration date\n");
|
||||
ret = LDAP_OPERATIONS_ERROR;
|
||||
goto free_and_return;
|
||||
}
|
||||
strftime(timestr, GENERALIZED_TIME_LENGTH + 1,
|
||||
"%Y%m%d%H%M%SZ", &utctime);
|
||||
slapi_mods_add_string(smods, LDAP_MOD_REPLACE,
|
||||
"krbPasswordExpiration", timestr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (nt && is_smb) {
|
||||
slapi_mods_add_string(smods, LDAP_MOD_REPLACE,
|
||||
|
||||
Reference in New Issue
Block a user