From 086f5b87aa6ac3ea3cacf4e81903c6851a02f32d Mon Sep 17 00:00:00 2001 From: Tomas Bzatek Date: Wed, 14 May 2014 16:14:40 +0200 Subject: account: Don't expose the LMI_Account.UserPassword value According to the Simple Identity Management Profile (DSP1034) document the LMI_Account.UserPassword property should not contain the password itself, no matter how encrypted it is. It should either contain an array of zero elements when password has been set or NULL when password is missing or not configured. Another change this commit brings is a more precise behaviour of LMI_Account.ModifyInstance() method. When the UserPassword property is array of zero elements, no change regarding password is made. This case was previously treated as a request for password removal. The DSP1034 profile doesn't specify such scenario, let's treat it the same way as the GetInstance() operation. --- mof/60_LMI_Account.mof | 17 +++++++++++++++- src/account/LMI_AccountProvider.c | 41 ++++++++++++++++++++++++++------------- 2 files changed, 43 insertions(+), 15 deletions(-) diff --git a/mof/60_LMI_Account.mof b/mof/60_LMI_Account.mof index 6bc99c8..a15c6fd 100644 --- a/mof/60_LMI_Account.mof +++ b/mof/60_LMI_Account.mof @@ -18,7 +18,7 @@ * Authors: Roman Rakus */ -[ Version("0.4.2"), +[ Version("0.4.3"), Description("Class representing Linux Account"), Provider("cmpi:cmpiLMI_Account") ] @@ -45,6 +45,21 @@ class LMI_Account: CIM_Account [ Description("The date of expiration of the account.") ] datetime AccountExpiration; + [ Description ( + "In the case of an LDAP-derived instance, the " + "UserPassword property may contain an encrypted password " + "used to access the person\'s resources in a directory.\n" + "\n" + "When an instance of CIM_Account is retrieved and the underlying " + "account has a valid password, the value of the CIM_Account.UserPassword " + "property shall be an array of length zero to indicate that the " + "account has a password configured.\n" + "\n" + "When the underlying account does not have a valid password, " + "the CIM_Account.UserPassword property shall be NULL." ), + OctetString ] + string UserPassword[]; + [ Description ( "Delete the user. Along with the user, the home directory and user's " "primary group are deleted. If the user is not owner of the home " diff --git a/src/account/LMI_AccountProvider.c b/src/account/LMI_AccountProvider.c index fdb06ff..9e09959 100644 --- a/src/account/LMI_AccountProvider.c +++ b/src/account/LMI_AccountProvider.c @@ -212,10 +212,11 @@ static CMPIStatus LMI_AccountEnumInstances( password = aux_lu_get_str(lue, LU_USERPASSWORD); } if (password) { - LMI_Account_Init_UserPassword(&la, 1); - LMI_Account_Set_UserPassword(&la, 0, password); + /* see DSP1034 note below */ + LMI_Account_Init_UserPassword(&la, 0); /* Assume all passwords (encrypted or not) are in ascii encoding */ LMI_Account_Set_UserPasswordEncoding(&la, 2); + password = NULL; } KReturnInstance(cr, la); @@ -329,23 +330,35 @@ static CMPIStatus LMI_AccountModifyInstance( goto fail; } + /* from DSP1034: + When an instance of CIM_Account is retrieved and the underlying account + has a valid password, the value of the CIM_Account.UserPassword property + shall be an array of length zero to indicate that the account has a + password configured. + When the underlying account does not have a valid password, the + CIM_Account.UserPassword property shall be NULL. + */ data = ci->ft->getProperty(ci, "UserPassword", NULL); ar = data.value.array; - if (ar && (arsize = ar->ft->getSize(ar, NULL) > 0)) + if (ar != NULL) { - vs = ar->ft->getElementAt(ar, 0, NULL).value.string; - value = vs->ft->getCharPtr(vs, NULL); - password = aux_lu_get_str(lue, LU_SHADOWPASSWORD); - if (strcmp(password, value) != 0) + if ((arsize = ar->ft->getSize(ar, NULL) > 0)) { - if (!lu_user_setpass(luc, lue, value, TRUE, &error)) + vs = ar->ft->getElementAt(ar, 0, NULL).value.string; + value = vs->ft->getCharPtr(vs, NULL); + password = aux_lu_get_str(lue, LU_SHADOWPASSWORD); + if (strcmp(password, value) != 0) { - rc = CMPI_RC_ERR_FAILED; - asprintf(&errmsg, "Error setting password: %s", - lu_strerror(error)); - goto fail; + if (!lu_user_setpass(luc, lue, value, TRUE, &error)) + { + rc = CMPI_RC_ERR_FAILED; + asprintf(&errmsg, "Error setting password: %s", + lu_strerror(error)); + goto fail; + } } } + /* zero array length means no change; password is configured */ } else { @@ -360,7 +373,7 @@ static CMPIStatus LMI_AccountModifyInstance( #define PARAMSTR(ATTR, VAR)\ g_value_init(&val, G_TYPE_STRING);\ - g_value_set_string(&val, (VAR));\ + g_value_set_string(&val, (VAR)); /* can handle NULL */ \ lu_ent_clear(lue, (ATTR));\ lu_ent_add(lue, (ATTR), &val);\ g_value_unset(&val);\ @@ -375,7 +388,7 @@ static CMPIStatus LMI_AccountModifyInstance( #define GETSTRVALUE(NAME)\ data = ci->ft->getProperty(ci, (NAME), NULL);\ vs = data.value.string;\ - value = vs->ft->getCharPtr(vs, NULL);\ + value = vs ? vs->ft->getCharPtr(vs, NULL) : NULL;\ #define GETDATEVALUE(NAME, VAR)\ (VAR).null = CMGetProperty(ci, (NAME), NULL).state == CMPI_nullValue;\ -- cgit