#include #include "LMI_AccountManagementService.h" #include "LMI_HostedAccountManagementService.h" #include "CIM_ComputerSystem.h" #include "LMI_Account.h" #include "LMI_Identity.h" #include "macros.h" #include "globals.h" #include "aux_lu.h" #include #include #include #include static const CMPIBroker* _cb = NULL; static void LMI_AccountManagementServiceInitialize() { } static CMPIStatus LMI_AccountManagementServiceCleanup( CMPIInstanceMI* mi, const CMPIContext* cc, CMPIBoolean term) { CMReturn(CMPI_RC_OK); } static CMPIStatus LMI_AccountManagementServiceEnumInstanceNames( CMPIInstanceMI* mi, const CMPIContext* cc, const CMPIResult* cr, const CMPIObjectPath* cop) { return KDefaultEnumerateInstanceNames( _cb, mi, cc, cr, cop); } static CMPIStatus LMI_AccountManagementServiceEnumInstances( CMPIInstanceMI* mi, const CMPIContext* cc, const CMPIResult* cr, const CMPIObjectPath* cop, const char** properties) { LMI_AccountManagementService lams; const char *hostname = get_system_name(); LMI_AccountManagementService_Init(&lams, _cb, KNameSpace(cop)); LMI_AccountManagementService_Set_CreationClassName(&lams, LMI_AccountManagementService_ClassName); LMI_AccountManagementService_Set_SystemName(&lams, hostname); LMI_AccountManagementService_Set_Name(&lams, LAMSNAME); LMI_AccountManagementService_Set_ElementName(&lams, LAMSNAME); LMI_AccountManagementService_Set_SystemCreationClassName(&lams, get_system_creation_class_name()); LMI_AccountManagementService_Set_RequestedState(&lams, LMI_AccountManagementService_RequestedState_Not_Applicable); LMI_AccountManagementService_Set_EnabledState(&lams, LMI_AccountManagementService_EnabledState_Enabled); KReturnInstance(cr, lams); CMReturn(CMPI_RC_OK); } static CMPIStatus LMI_AccountManagementServiceGetInstance( 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_AccountManagementServiceCreateInstance( CMPIInstanceMI* mi, const CMPIContext* cc, const CMPIResult* cr, const CMPIObjectPath* cop, const CMPIInstance* ci) { CMReturn(CMPI_RC_ERR_NOT_SUPPORTED); } static CMPIStatus LMI_AccountManagementServiceModifyInstance( CMPIInstanceMI* mi, const CMPIContext* cc, const CMPIResult* cr, const CMPIObjectPath* cop, const CMPIInstance* ci, const char** properties) { CMReturn(CMPI_RC_ERR_NOT_SUPPORTED); } static CMPIStatus LMI_AccountManagementServiceDeleteInstance( CMPIInstanceMI* mi, const CMPIContext* cc, const CMPIResult* cr, const CMPIObjectPath* cop) { CMReturn(CMPI_RC_ERR_NOT_SUPPORTED); } static CMPIStatus LMI_AccountManagementServiceExecQuery( 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_AccountManagementService, LMI_AccountManagementService, _cb, LMI_AccountManagementServiceInitialize()) static CMPIStatus LMI_AccountManagementServiceMethodCleanup( CMPIMethodMI* mi, const CMPIContext* cc, CMPIBoolean term) { CMReturn(CMPI_RC_OK); } static CMPIStatus LMI_AccountManagementServiceInvokeMethod( CMPIMethodMI* mi, const CMPIContext* cc, const CMPIResult* cr, const CMPIObjectPath* cop, const char* meth, const CMPIArgs* in, CMPIArgs* out) { return LMI_AccountManagementService_DispatchMethod( _cb, mi, cc, cr, cop, meth, in, out); } CMMethodMIStub( LMI_AccountManagementService, LMI_AccountManagementService, _cb, LMI_AccountManagementServiceInitialize()) KUint32 LMI_AccountManagementService_RequestStateChange( const CMPIBroker* cb, CMPIMethodMI* mi, const CMPIContext* context, const LMI_AccountManagementServiceRef* self, const KUint16* RequestedState, KRef* Job, const KDateTime* TimeoutPeriod, CMPIStatus* status) { KUint32 result = KUINT32_INIT; KSetStatus(status, ERR_NOT_SUPPORTED); return result; } KUint32 LMI_AccountManagementService_StartService( const CMPIBroker* cb, CMPIMethodMI* mi, const CMPIContext* context, const LMI_AccountManagementServiceRef* self, CMPIStatus* status) { KUint32 result = KUINT32_INIT; KSetStatus(status, ERR_NOT_SUPPORTED); return result; } KUint32 LMI_AccountManagementService_StopService( const CMPIBroker* cb, CMPIMethodMI* mi, const CMPIContext* context, const LMI_AccountManagementServiceRef* self, CMPIStatus* status) { KUint32 result = KUINT32_INIT; KSetStatus(status, ERR_NOT_SUPPORTED); return result; } KUint32 LMI_AccountManagementService_CreateAccount( const CMPIBroker* cb, CMPIMethodMI* mi, const CMPIContext* context, const LMI_AccountManagementServiceRef* self, const KRef* System, const KString* Name, const KString* GECOS, const KString* HomeDirectory, const KBoolean* DontCreateHome, const KString* Shell, const KUint32* UID, const KUint32* GID, const KBoolean* SystemAccount, const KString* Password, const KBoolean* DontCreateGroup, KRef* Account, KRefA* Identities, CMPIStatus* status) { /* TODO - Use embedded instance? */ /* XXX - split to functions and/or macros */ char *errmsg = NULL; #define FAIL(MSG, ERROR, STATUS, RETVAL)\ errmsg = malloc(256 * sizeof(char));\ snprintf(errmsg, 256, (MSG), (ERROR));\ KSetStatus2(cb, status, STATUS, errmsg);\ KUint32_Set(&result, (RETVAL));\ free(errmsg); KUint32 result = KUINT32_INIT; struct lu_context *luc = NULL; struct lu_error *error = NULL; struct lu_ent *lue = NULL, *lue_group = NULL; GValue val; int create_group = 0; gid_t gid = LU_VALUE_INVALID_ID, uid = LU_VALUE_INVALID_ID; char *group_name = NULL, *home = NULL, *instanceid = NULL; const char *nameSpace = LMI_AccountManagementServiceRef_NameSpace(self); const char *hostname = get_system_name(); CMPIStatus st; CMPIEnumeration *instances = NULL; LMI_AccountRef Accountref; LMI_IdentityRef Identityref; CMPIObjectPath *AccountOP = NULL, *IdentityOP = NULL; KSetStatus(status, OK); KUint32_Set(&result, 0); if (!(Name->exists && !Name->null) || !(System->exists && !System->null)) { FAIL("Required parameters not specified%s\n", "", ERR_FAILED, 2); goto clean; } luc = lu_start(NULL, lu_user, NULL, NULL, lu_prompt_console_quiet, NULL, &error); if (!luc) { FAIL("Error initializing: %s\n", lu_strerror(error), ERR_FAILED, 2); goto clean; } instances = cb->bft->associatorNames(cb, context, LMI_AccountManagementServiceRef_ToObjectPath(self, NULL), LMI_HostedAccountManagementService_ClassName, NULL, NULL, NULL, &st); if (!instances || !instances->ft->hasNext(instances, NULL) || !KMatch(System->value, instances->ft->getNext(instances,NULL).value.ref)) { /* This service is not linked with provided system */ FAIL("Unable to create account on the System%s\n", "", ERR_FAILED, 2); goto clean; } lue = lu_ent_new(); lu_user_default(luc, Name->chars, SystemAccount->exists && !SystemAccount->null && SystemAccount->value, lue); memset(&val, 0, sizeof(val)); /* UID */ if (UID->exists && !UID->null) { lu_value_init_set_id(&val, UID->value); lu_ent_clear(lue, LU_UIDNUMBER); lu_ent_add(lue, LU_UIDNUMBER, &val); g_value_unset(&val); } /* GID */ /* if specified GID, the group should exists and don't create it * if unspecified GID, check dontcreategroup, dont create "users" group, * create group with same name as user name */ lue_group = lu_ent_new(); if (GID->exists && !GID->null) { /* Specified GID */ gid = GID->value; if (!lu_group_lookup_id(luc, gid, lue_group, &error)) { FAIL("Non existing group: %d\n", gid, ERR_FAILED, 2); goto clean; } } else { /* Not specified GID */ if (DontCreateGroup->exists && !DontCreateGroup->null && DontCreateGroup->value) { /* add user to "users" group */ group_name = malloc((strlen("users")+1) * sizeof(char)); strcpy(group_name, "users"); } else { /* add user to the group with same name as user name */ group_name = malloc((strlen(Name->chars)+1) * sizeof(char)); strcpy(group_name, Name->chars); } if (lu_group_lookup_name(luc, group_name, lue_group, &error)) { gid = aux_lu_get_long(lue_group, LU_GIDNUMBER); } else { create_group = 1; } if (create_group) { lu_group_default(luc, group_name, 0, lue_group); if (!lu_group_add(luc, lue_group, &error)) { FAIL("Error creating group: %s\n", lu_strerror(error), ERR_FAILED, 2); goto clean; } } } gid = aux_lu_get_long(lue_group, LU_GIDNUMBER); lu_value_init_set_id(&val, gid); lu_ent_clear(lue, LU_GIDNUMBER); lu_ent_add(lue, LU_GIDNUMBER, &val); g_value_unset(&val); g_value_init(&val, G_TYPE_STRING); #define PARAM(ATTR, VAR)\ if ((VAR)->exists && !(VAR)->null){\ g_value_set_string(&val, (VAR)->chars);\ lu_ent_clear(lue, (ATTR));\ lu_ent_add(lue, (ATTR), &val);\ } PARAM(LU_GECOS, GECOS); PARAM(LU_HOMEDIRECTORY, HomeDirectory); PARAM(LU_LOGINSHELL, Shell); #undef PARAM g_value_unset(&val); if (!lu_user_add(luc, lue, &error)) { FAIL("Account Creation failed: %s\n", lu_strerror(error), ERR_FAILED, 2); goto clean; } /* Finally create home dir */ if (!(DontCreateHome->exists && !DontCreateHome->null && DontCreateHome->value) && !(SystemAccount->exists && !SystemAccount->null && SystemAccount->value)) { /* Yes, create home */ uid = aux_lu_get_long(lue, LU_UIDNUMBER); gid = aux_lu_get_long(lue, LU_GIDNUMBER); home = aux_lu_get_str(lue, LU_HOMEDIRECTORY); /* TODO - copy /etc/skel */ /* XXX - libuser will add/export function in the future */ if(mkdir(home, 0700) != 0) { FAIL("Error creating homedir: %s\n", strerror(errno), ERR_FAILED, 3); goto clean; } if (chown(home, uid, gid) != 0) { FAIL("Error setting ownership of homedir: %s\n", strerror(errno), ERR_FAILED, 3); goto clean; errmsg = malloc(256 * sizeof(char)); } } /* Output created Account reference */ LMI_AccountRef_Init(&Accountref, cb, nameSpace); LMI_AccountRef_Set_Name(&Accountref, Name->chars); LMI_AccountRef_Set_SystemName(&Accountref, hostname); LMI_AccountRef_Set_SystemCreationClassName(&Accountref, get_system_creation_class_name()); LMI_AccountRef_Set_CreationClassName(&Accountref, LMI_Account_ClassName); AccountOP = LMI_AccountRef_ToObjectPath(&Accountref, &st); KRef_SetObjectPath(Account, AccountOP); /* Output created (or already existed) identities references * it means reference to Identity of Account and Group */ KRefA_Init(Identities, cb, 2); instanceid = malloc(256 * sizeof(char)); /* Identity of Account */ LMI_IdentityRef_Init(&Identityref, cb, nameSpace); snprintf(instanceid, 255, ORGID":UID:%ld", aux_lu_get_long(lue, LU_UIDNUMBER)); LMI_IdentityRef_Set_InstanceID(&Identityref, instanceid); IdentityOP = LMI_IdentityRef_ToObjectPath(&Identityref, &st); KRefA_Set(Identities, 0, IdentityOP); /* Identity of Group */ snprintf(instanceid, 255, ORGID":GID:%ld", aux_lu_get_long(lue, LU_GIDNUMBER)); LMI_IdentityRef_Set_InstanceID(&Identityref, instanceid); IdentityOP = LMI_IdentityRef_ToObjectPath(&Identityref, &st); KRefA_Set(Identities, 1, IdentityOP); clean: #undef FAIL free(group_name); free(instanceid); if (lue) lu_ent_free(lue); if (lue_group) lu_ent_free(lue_group); if (luc) lu_end(luc); return result; } KUint32 LMI_AccountManagementService_ChangeAffectedElementsAssignedSequence( const CMPIBroker* cb, CMPIMethodMI* mi, const CMPIContext* context, const LMI_AccountManagementServiceRef* self, const KRefA* ManagedElements, const KUint16A* AssignedSequence, KRef* Job, CMPIStatus* status) { KUint32 result = KUINT32_INIT; KSetStatus(status, ERR_NOT_SUPPORTED); return result; } KUint32 LMI_AccountManagementService_CreateUserContact( const CMPIBroker* cb, CMPIMethodMI* mi, const CMPIContext* context, const LMI_AccountManagementServiceRef* self, const KRef* System, const KString* UserContactTemplate, KRef* UserContact, KRefA* Identities, CMPIStatus* status) { KUint32 result = KUINT32_INIT; KSetStatus(status, ERR_NOT_SUPPORTED); return result; } KUint32 LMI_AccountManagementService_getAccount( const CMPIBroker* cb, CMPIMethodMI* mi, const CMPIContext* context, const LMI_AccountManagementServiceRef* self, const KString* UserID, KRef* Account, CMPIStatus* status) { KUint32 result = KUINT32_INIT; KSetStatus(status, ERR_NOT_SUPPORTED); return result; } KEXTERN KUint32 LMI_AccountManagementService_getUserContact( const CMPIBroker* cb, CMPIMethodMI* mi, const CMPIContext* context, const LMI_AccountManagementServiceRef* self, const KString* UserID, KRef* UserContact, CMPIStatus* status) { KUint32 result = KUINT32_INIT; KSetStatus(status, ERR_NOT_SUPPORTED); return result; } KONKRET_REGISTRATION( "root/cimv2", "LMI_AccountManagementService", "LMI_AccountManagementService", "instance method")