diff options
-rw-r--r-- | mof/LMI_Account.mof | 6 | ||||
-rw-r--r-- | src/account/LMI_AccountProvider.c | 176 | ||||
-rw-r--r-- | src/account/macros.h | 2 |
3 files changed, 155 insertions, 29 deletions
diff --git a/mof/LMI_Account.mof b/mof/LMI_Account.mof index 2ca4f5e..9901a04 100644 --- a/mof/LMI_Account.mof +++ b/mof/LMI_Account.mof @@ -33,13 +33,13 @@ class LMI_Account: CIM_Account [ Description("The date when was password last changed") ] datetime PasswordLastChange; - [ Description("The date since when can be password changed") ] + [ Description("Minimum number of days between password change") ] datetime PasswordPossibleChange; - [ Description("The date when the user should start to be warned about password expiration") ] + [ Description("Number of days of warning before password expires") ] datetime PasswordExpirationWarning; - [ Description("The date when the user will not be able to login using the user's password. The user should contact her administrator.") ] + [ Description("Maximum number of days between password change") ] datetime PasswordInactivation; [ Description("The date of expiration of the account.") ] diff --git a/src/account/LMI_AccountProvider.c b/src/account/LMI_AccountProvider.c index e765d6b..ea35eff 100644 --- a/src/account/LMI_AccountProvider.c +++ b/src/account/LMI_AccountProvider.c @@ -101,30 +101,26 @@ static CMPIStatus LMI_AccountEnumInstances( last_change = aux_lu_get_long(lue, LU_SHADOWLASTCHANGE); LMI_Account_Set_PasswordLastChange(&la, - CMNewDateTimeFromBinary(_cb, DAYSTOMS(last_change),false, rc)); + CMNewDateTimeFromBinary(_cb, DAYSTOMS(last_change), false, rc)); - min_lifetime = aux_lu_get_long(lue, LU_SHADOWMIN) + last_change; + min_lifetime = aux_lu_get_long(lue, LU_SHADOWMIN); max_lifetime = aux_lu_get_long(lue, LU_SHADOWMAX); LMI_Account_Set_PasswordPossibleChange(&la, - CMNewDateTimeFromBinary(_cb, DAYSTOMS(min_lifetime), - false, rc)); + CMNewDateTimeFromBinary(_cb, DAYSTOMS(min_lifetime), true, rc)); if (max_lifetime != 0 && max_lifetime != 99999) { - max_lifetime += last_change; LMI_Account_Set_PasswordExpiration(&la, - CMNewDateTimeFromBinary(_cb, DAYSTOMS(max_lifetime), false, rc)); + CMNewDateTimeFromBinary(_cb, DAYSTOMS(max_lifetime), true, rc)); warn = aux_lu_get_long(lue, LU_SHADOWWARNING); LMI_Account_Set_PasswordExpirationWarning(&la, - CMNewDateTimeFromBinary(_cb, DAYSTOMS(max_lifetime - warn), - false, rc)); + CMNewDateTimeFromBinary(_cb, DAYSTOMS(warn), true, rc)); inactive = aux_lu_get_long(lue, LU_SHADOWINACTIVE); if (inactive != -1) { LMI_Account_Set_PasswordInactivation(&la, - CMNewDateTimeFromBinary(_cb, - DAYSTOMS(max_lifetime + inactive), false, rc)); + CMNewDateTimeFromBinary(_cb, DAYSTOMS(inactive), true, rc)); } } else @@ -138,8 +134,7 @@ static CMPIStatus LMI_AccountEnumInstances( if (expire != -1) { LMI_Account_Set_AccountExpiration(&la, - CMNewDateTimeFromBinary(_cb, - DAYSTOMS(expire), false, rc)); + CMNewDateTimeFromBinary(_cb, DAYSTOMS(expire), false, rc)); } else { @@ -151,7 +146,7 @@ static CMPIStatus LMI_AccountEnumInstances( if (last_login != -1) { LMI_Account_Set_LastLogin(&la, - CMNewDateTimeFromBinary(_cb, last_login * 1000000, false, rc)); + CMNewDateTimeFromBinary(_cb, STOMS(last_login), false, rc)); } password = aux_lu_get_str(lue, LU_SHADOWPASSWORD); @@ -196,6 +191,14 @@ static CMPIStatus LMI_AccountCreateInstance( CMReturn(CMPI_RC_ERR_NOT_SUPPORTED); } +/* Need better view on set date time properties */ +typedef struct _date_time_prop +{ + long value; + bool null; /* True if property is set to null - has no value */ + bool interval; /* True if value is interval */ +} date_time_prop; + static CMPIStatus LMI_AccountModifyInstance( CMPIInstanceMI* mi, const CMPIContext* cc, @@ -210,7 +213,7 @@ static CMPIStatus LMI_AccountModifyInstance( * Set up account expiration * Set up password expiration */ - char* value = NULL; + char* value = NULL, *password = NULL; CMPIString* vs = NULL; CMPIArray* ar = NULL; int arsize;/* used for password */ CMPIData data; @@ -221,6 +224,10 @@ static CMPIStatus LMI_AccountModifyInstance( struct lu_error *error = NULL; GValue val; + long last_change; + date_time_prop expiration, warning, inactive_password, inactive_account; + date_time_prop possible_change; + LMI_Account la; LMI_Account_InitFromObjectPath(&la, _cb, cop); @@ -248,13 +255,17 @@ static CMPIStatus LMI_AccountModifyInstance( { vs = ar->ft->getElementAt(ar, 0, NULL).value.string; value = vs->ft->getCharPtr(vs, NULL); - if (!lu_user_setpass(luc, lue, value, TRUE, &error)) + password = aux_lu_get_str(lue, LU_SHADOWPASSWORD); + if (strcmp(password, value) != 0) { - snprintf(errmsg, 256, "Error setting password: %s", - lu_strerror(error)); - lu_end(luc); - lu_ent_free(lue); - CMReturnWithChars(_cb, CMPI_RC_ERR_FAILED, errmsg); + if (!lu_user_setpass(luc, lue, value, TRUE, &error)) + { + snprintf(errmsg, 256, "Error setting password: %s", + lu_strerror(error)); + lu_end(luc); + lu_ent_free(lue); + CMReturnWithChars(_cb, CMPI_RC_ERR_FAILED, errmsg); + } } } else @@ -269,33 +280,146 @@ static CMPIStatus LMI_AccountModifyInstance( } } -#define PARAM(ATTR, VAR)\ +#define PARAMSTR(ATTR, VAR)\ g_value_set_string(&val, (VAR));\ lu_ent_clear(lue, (ATTR));\ lu_ent_add(lue, (ATTR), &val);\ +#define PARAMLONG(ATTR, VAR)\ + g_value_set_long(&val, (VAR).value);\ + lu_ent_clear(lue, (ATTR));\ + if (!(VAR).null) lu_ent_add(lue, (ATTR), &val);\ + /* This macro will get property named NAME and save it into `value' variable */ #define GETSTRVALUE(NAME)\ data = ci->ft->getProperty(ci, (NAME), NULL);\ vs = data.value.string;\ value = vs->ft->getCharPtr(vs, NULL);\ +#define GETDATEVALUE(NAME, VAR)\ + (VAR).null = CMGetProperty(ci, (NAME), NULL).state == CMPI_nullValue;\ + if (!(VAR).null)\ + {\ + (VAR).interval = CMIsInterval(\ + CMGetProperty(ci, (NAME), NULL).value.dateTime, NULL); \ + (VAR).value = MSTODAYS(CMGetBinaryFormat(\ + CMGetProperty(ci, (NAME), NULL).value.dateTime, NULL));\ + }\ + + /* First string values */ memset(&val, 0, sizeof(val)); g_value_init(&val, G_TYPE_STRING); GETSTRVALUE("ElementName"); - PARAM(LU_GECOS, value); + PARAMSTR(LU_GECOS, value); GETSTRVALUE("HomeDirectory"); - PARAM(LU_HOMEDIRECTORY, value); + PARAMSTR(LU_HOMEDIRECTORY, value); GETSTRVALUE("LoginShell"); - PARAM(LU_LOGINSHELL, value); -#undef PARAM + PARAMSTR(LU_LOGINSHELL, value); + + /* Now long values */ + memset(&val, 0, sizeof(val)); + g_value_init(&val, G_TYPE_LONG); + + last_change = aux_lu_get_long(lue, LU_SHADOWLASTCHANGE); + + errmsg[0] = '\0'; + do + { + GETDATEVALUE("PasswordExpiration", expiration); + if (!expiration.null && !expiration.interval) + { + if ((expiration.value -= last_change) < 0) + { + snprintf(errmsg, 256, "Wrong property setting, " + "PasswordExpiration must be later than " + "PasswordLastChange\n"); + break; + } + } + + GETDATEVALUE("PasswordExpirationWarning", warning); + if (!warning.null && !warning.interval) + { + if (expiration.null) + { + snprintf(errmsg, 256, "Wrong property setting, " + "PasswordExpiration must be set if you want to set " + "PasswordExpirationWarning as time of date\n"); + break; + } + warning.value = last_change + expiration.value - warning.value; + if (warning.value < 0) + { + snprintf(errmsg, 256, "Wrong property setting, " + "PasswordExpirationWarning must be earlier than " + "PasswordExpiration\n"); + break; + } + } + + GETDATEVALUE("PasswordInactivation", inactive_password); + if (!inactive_password.null && !inactive_password.interval) + { + if (expiration.null) + { + snprintf(errmsg, 256, "Wrong property setting, " + "PasswordExpiration must be set if you want to set " + "PasswordInactivation as time of date\n"); + break; + } + inactive_password.value -= last_change + expiration.value; + if (inactive_password.value < 0) + { + snprintf(errmsg, 256, "Wrong property setting, " + "PasswordInactivation must be later than " + "PasswordExpiration\n"); + break; + } + } + + GETDATEVALUE("PasswordPossibleChange", possible_change); + if (!possible_change.null && !possible_change.interval) + { + if ((possible_change.value -= last_change) < 0) + { + snprintf(errmsg, 256, "Wrong property setting, " + "PasswordPossibleChange must be later than " + "PasswordLastChange\n"); + break; + } + } + + GETDATEVALUE("AccountExpiration", inactive_account); + if (!inactive_account.null && inactive_account.interval) + { + snprintf(errmsg, 256, "Wrong property setting, " + "AccountExpiration must be set as interval\n"); + break; + } + } while (0); + + if (errmsg[0]) + { /* There was an error, print it and return */ + lu_end(luc); + lu_ent_free(lue); + CMReturnWithChars(_cb, CMPI_RC_ERR_FAILED, errmsg); + } + + PARAMLONG(LU_SHADOWMIN, possible_change); + PARAMLONG(LU_SHADOWMAX, expiration); + PARAMLONG(LU_SHADOWWARNING, warning); + PARAMLONG(LU_SHADOWINACTIVE, inactive_password); + PARAMLONG(LU_SHADOWEXPIRE, inactive_account); + +#undef PARAMSTR +#undef PARAMLONG #undef GETSTRVALUE +#undef GETDATEVALUE g_value_unset(&val); - if (!lu_user_modify(luc, lue, &error)) { snprintf(errmsg, 256, "User modification failed: %s", diff --git a/src/account/macros.h b/src/account/macros.h index 9428c86..1e33aa9 100644 --- a/src/account/macros.h +++ b/src/account/macros.h @@ -11,5 +11,7 @@ /* convert days to microseconds */ #define DAYSTOMS(days) ((days) * 86400000000) +#define MSTODAYS(ms) ((ms) / 86400000000) +#define STOMS(s) ((s) * 1000000) #endif |