#include #include "LMI_Account.h" #include #include #include #include #include #include #include #include #include #include "aux_lu.h" #include "macros.h" #include "globals.h" static const CMPIBroker* _cb = NULL; static void LMI_AccountInitialize() { } static CMPIStatus LMI_AccountCleanup( CMPIInstanceMI* mi, const CMPIContext* cc, CMPIBoolean term) { CMReturn(CMPI_RC_OK); } static CMPIStatus LMI_AccountEnumInstanceNames( CMPIInstanceMI* mi, const CMPIContext* cc, const CMPIResult* cr, const CMPIObjectPath* cop) { return KDefaultEnumerateInstanceNames( _cb, mi, cc, cr, cop); } static CMPIStatus LMI_AccountEnumInstances( CMPIInstanceMI* mi, const CMPIContext* cc, const CMPIResult* cr, const CMPIObjectPath* cop, const char** properties) { LMI_Account la; struct lu_context *luc = NULL; struct lu_error *error = NULL; GPtrArray *accounts = NULL; struct lu_ent *lue = NULL; size_t i; const char *nameSpace = KNameSpace(cop); const char *hostname = get_system_name(); char *uid = NULL; long expire, last_change, min_lifetime, max_lifetime; time_t last_login; CMPIUint64 binTime = 0; CMPIStatus *rc = NULL; char *password = NULL; luc = lu_start(NULL, lu_user, NULL, NULL, lu_prompt_console_quiet, NULL, &error); if (!luc) { fprintf(stderr, "Error initializing: %s\n", lu_strerror(error)); exit(1); } uid = malloc(256 * sizeof(char)); accounts = lu_users_enumerate_full(luc, "*", &error); for (i = 0; (accounts != NULL) && (i < accounts->len); i++) { lue = g_ptr_array_index(accounts, i); LMI_Account_Init(&la, _cb, nameSpace); LMI_Account_Set_CreationClassName(&la, LMI_Account_ClassName); LMI_Account_Set_SystemName(&la, hostname); LMI_Account_Set_SystemCreationClassName(&la, get_system_creation_class_name()); LMI_Account_Set_Name(&la, aux_lu_get_str(lue, LU_USERNAME)); LMI_Account_Init_OrganizationName(&la, 1); /* XXX */ LMI_Account_Set_OrganizationName(&la, 0, ""); /* XXX */ /* Need to convert long int UID to the string */ snprintf(uid, 255, "%ld", aux_lu_get_long(lue, LU_UIDNUMBER)); LMI_Account_Set_UserID(&la, uid); LMI_Account_Init_Host(&la, 1); LMI_Account_Set_Host(&la, 0, hostname); LMI_Account_Set_ElementName(&la, aux_lu_get_str(lue, LU_GECOS)); LMI_Account_Set_HomeDirectory(&la, aux_lu_get_str(lue, LU_HOMEDIRECTORY)); LMI_Account_Set_LoginShell(&la, aux_lu_get_str(lue, LU_LOGINSHELL)); last_change = aux_lu_get_long(lue, LU_SHADOWLASTCHANGE); LMI_Account_Set_PasswordLastChange(&la, CMNewDateTimeFromBinary(_cb, DAYSTOMS(last_change),false, rc)); min_lifetime = aux_lu_get_long(lue, LU_SHADOWMIN) + last_change; max_lifetime = aux_lu_get_long(lue, LU_SHADOWMAX) + last_change; LMI_Account_Set_PasswordMinLifetime(&la, CMNewDateTimeFromBinary(_cb, DAYSTOMS(min_lifetime), false, rc)); LMI_Account_Set_PasswordMaxLifetime(&la, CMNewDateTimeFromBinary(_cb, DAYSTOMS(max_lifetime), false, rc)); last_login = aux_utmp_latest(aux_lu_get_str(lue, LU_USERNAME)); if (last_login != -1) { LMI_Account_Set_LastLogin(&la, CMNewDateTimeFromBinary(_cb, last_login * 1000000, false, rc)); } binTime = DAYSTOMS(aux_lu_get_long(lue, LU_SHADOWMIN)); password = aux_lu_get_str(lue, LU_SHADOWPASSWORD); LMI_Account_Init_UserPassword(&la, 1); LMI_Account_Set_UserPassword(&la, 0, password); /* Assume all passwords (encrypted or not) are in ascii encoding */ LMI_Account_Set_UserPasswordEncoding(&la, 2); if(strstr(password, "")) expire = aux_lu_get_long(lue, LU_SHADOWEXPIRE); if (expire != -1) { binTime = DAYSTOMS(expire); LMI_Account_Set_PasswordExpiration(&la, CMNewDateTimeFromBinary(_cb, binTime, false, rc)); } else { LMI_Account_Null_PasswordExpiration(&la); } KReturnInstance(cr, la); lu_ent_free(lue); } /* for */ free(uid); if (accounts) { g_ptr_array_free(accounts, TRUE); } lu_end(luc); CMReturn(CMPI_RC_OK); } static CMPIStatus LMI_AccountGetInstance( CMPIInstanceMI* mi, const CMPIContext* cc, const CMPIResult* cr, const CMPIObjectPath* cop, const char** properties) { return KDefaultGetInstance( _cb, mi, cc, cr, cop, properties); } static CMPIStatus LMI_AccountCreateInstance( CMPIInstanceMI* mi, const CMPIContext* cc, const CMPIResult* cr, const CMPIObjectPath* cop, const CMPIInstance* ci) { CMReturn(CMPI_RC_ERR_NOT_SUPPORTED); } static CMPIStatus LMI_AccountModifyInstance( CMPIInstanceMI* mi, const CMPIContext* cc, const CMPIResult* cr, const CMPIObjectPath* cop, const CMPIInstance* ci, const char** properties) { /* TODO: * * Allow to modify the following: * Set up account expiration * Set up password expiration */ char* value = NULL; CMPIString* vs = NULL; CMPIArray* ar = NULL; int arsize;/* used for password */ CMPIData data; char errmsg[256]; struct lu_context *luc = NULL; struct lu_ent *lue = NULL; struct lu_error *error = NULL; GValue val; LMI_Account la; LMI_Account_InitFromObjectPath(&la, _cb, cop); luc = lu_start(NULL, lu_user, NULL, NULL, lu_prompt_console_quiet, NULL, &error); if (!luc) { fprintf(stderr, "Error initializing: %s\n", lu_strerror(error)); exit(1); } lue = lu_ent_new(); if (!lu_user_lookup_name(luc, la.Name.chars, lue, &error)) { snprintf(errmsg, 256, "User %s not found: %s", la.Name.chars, lu_strerror(error)); lu_end(luc); lu_ent_free(lue); CMReturnWithChars(_cb, CMPI_RC_ERR_NOT_FOUND, errmsg); } data = ci->ft->getProperty(ci, "UserPassword", NULL); ar = data.value.array; if (ar && (arsize = ar->ft->getSize(ar, NULL) > 0)) { vs = ar->ft->getElementAt(ar, 0, NULL).value.string; value = vs->ft->getCharPtr(vs, NULL); 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 { if (!lu_user_removepass(luc, lue, &error)) { snprintf(errmsg, 256, "Error removing password: %s", lu_strerror(error)); lu_end(luc); lu_ent_free(lue); CMReturnWithChars(_cb, CMPI_RC_ERR_FAILED, errmsg); } } #define PARAM(ATTR, VAR)\ g_value_set_string(&val, (VAR));\ lu_ent_clear(lue, (ATTR));\ 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);\ memset(&val, 0, sizeof(val)); g_value_init(&val, G_TYPE_STRING); GETSTRVALUE("ElementName"); PARAM(LU_GECOS, value); GETSTRVALUE("HomeDirectory"); PARAM(LU_HOMEDIRECTORY, value); GETSTRVALUE("LoginShell"); PARAM(LU_LOGINSHELL, value); #undef PARAM #undef GETSTRVALUE g_value_unset(&val); if (!lu_user_modify(luc, lue, &error)) { snprintf(errmsg, 256, "User modification failed: %s", lu_strerror(error)); lu_end(luc); lu_ent_free(lue); CMReturnWithChars(_cb, CMPI_RC_ERR_FAILED, errmsg); } lu_ent_free(lue); lu_end(luc); CMReturn(CMPI_RC_OK); } static CMPIStatus LMI_AccountDeleteInstance( CMPIInstanceMI* mi, const CMPIContext* cc, const CMPIResult* cr, const CMPIObjectPath* cop) { LMI_Account acc; const char* username = NULL; char errmsg[256]; struct lu_context *luc = NULL; struct lu_error *error = NULL; struct lu_ent *lue = NULL; LMI_Account_InitFromObjectPath(&acc, _cb, cop); username = acc.Name.chars; luc = lu_start(NULL, 0, NULL, NULL, lu_prompt_console_quiet, NULL, &error); if (!luc) { fprintf(stderr, "Error initializing: %s\n", lu_strerror(error)); exit(1); } lue = lu_ent_new(); if (!lu_user_lookup_name(luc, username, lue, &error)) { snprintf(errmsg, 256, "Non existing user: %s\n", username); lu_ent_free(lue); lu_end(luc); CMReturnWithChars(_cb, CMPI_RC_ERR_NOT_FOUND, errmsg); } if (!lu_user_delete(luc, lue, &error)) { snprintf(errmsg, 256, "User %s could not be deleted: %s\n", username, lu_strerror(error)); lu_ent_free(lue); lu_end(luc); CMReturnWithChars(_cb, CMPI_RC_ERR_FAILED, errmsg); } lu_ent_free(lue); lu_end(luc); CMReturn(CMPI_RC_OK); } static CMPIStatus LMI_AccountExecQuery( CMPIInstanceMI* mi, const CMPIContext* cc, const CMPIResult* cr, const CMPIObjectPath* cop, const char* lang, const char* query) { CMReturn(CMPI_RC_ERR_NOT_SUPPORTED); } CMInstanceMIStub( LMI_Account, LMI_Account, _cb, LMI_AccountInitialize()) static CMPIStatus LMI_AccountMethodCleanup( CMPIMethodMI* mi, const CMPIContext* cc, CMPIBoolean term) { CMReturn(CMPI_RC_OK); } static CMPIStatus LMI_AccountInvokeMethod( CMPIMethodMI* mi, const CMPIContext* cc, const CMPIResult* cr, const CMPIObjectPath* cop, const char* meth, const CMPIArgs* in, CMPIArgs* out) { return LMI_Account_DispatchMethod( _cb, mi, cc, cr, cop, meth, in, out); } CMMethodMIStub( LMI_Account, LMI_Account, _cb, LMI_AccountInitialize()) KUint32 LMI_Account_RequestStateChange( const CMPIBroker* cb, CMPIMethodMI* mi, const CMPIContext* context, const LMI_AccountRef* self, const KUint16* RequestedState, KRef* Job, const KDateTime* TimeoutPeriod, CMPIStatus* status) { KUint32 result = KUINT32_INIT; KSetStatus(status, ERR_NOT_SUPPORTED); return result; } KONKRET_REGISTRATION( "root/cimv2", "LMI_Account", "LMI_Account", "instance method")