diff options
-rw-r--r-- | mof/60_LMI_Account.mof | 10 | ||||
-rw-r--r-- | src/account/LMI_GroupProvider.c | 139 | ||||
-rw-r--r-- | src/account/doc/source/usage.rst | 16 |
3 files changed, 124 insertions, 41 deletions
diff --git a/mof/60_LMI_Account.mof b/mof/60_LMI_Account.mof index 153222e..a4cfdda 100644 --- a/mof/60_LMI_Account.mof +++ b/mof/60_LMI_Account.mof @@ -216,6 +216,16 @@ class LMI_Identity: CIM_Identity [ Version("0.2.0"), Provider("cmpi:cmpiLMI_Account") ] class LMI_Group: CIM_Group { + [ Description ( + "Delete the group. The group is not deleted if it is a primary group " + "of a user." ), + ValueMap { "0", "1", "..", "4096", "4097" }, + Values { "Operation completed successfully", + "Failed", + "DMTF Reserved", + "Non existing group", + "Group is primary group of a user"}] + uint32 DeleteGroup(); }; [ Version("0.2.0"), Association, diff --git a/src/account/LMI_GroupProvider.c b/src/account/LMI_GroupProvider.c index 6e64c21..79b6cd8 100644 --- a/src/account/LMI_GroupProvider.c +++ b/src/account/LMI_GroupProvider.c @@ -29,6 +29,11 @@ #include "account_globals.h" #include "globals.h" +// Return values of functions +// Delete group +#define GROUP_NOT_EXIST 4096 +#define GROUP_IS_PRIMARY 4097 + static const CMPIBroker* _cb = NULL; static void LMI_GroupInitialize() @@ -137,6 +142,71 @@ static CMPIStatus LMI_GroupModifyInstance( CMReturn(CMPI_RC_ERR_NOT_SUPPORTED); } +/* + * Internal function to delete group + */ +static CMPIrc delete_group( + const char *groupname, + char *errormsg) +{ + struct lu_context *luc = NULL; + struct lu_error *error = NULL; + struct lu_ent *lueg = NULL; + struct lu_ent *lueu = NULL; + GValueArray *users = NULL; + char *username = NULL; + long group_gid = 0; + CMPIrc rc = CMPI_RC_OK; + + luc = lu_start(NULL, 0, NULL, NULL, lu_prompt_console_quiet, NULL, &error); + if (!luc) { + asprintf(&errormsg, "Unable to initialize libuser: %s\n", lu_strerror(error)); + return CMPI_RC_ERR_FAILED; + } + + lueg = lu_ent_new(); + if (!lu_group_lookup_name(luc, groupname, lueg, &error)) { /* Group not found */ + asprintf(&errormsg, "Non existing group: %s\n", groupname); + rc = GROUP_NOT_EXIST; + goto clean; + } + + /* check if the group is not primary group of any user */ + group_gid = aux_lu_get_long(lueg, LU_GIDNUMBER); + users = lu_users_enumerate_by_group(luc, groupname, &error); + unsigned int j; + for (j = 0; (users != NULL) && (j < users->n_values); j++) { + lueu = lu_ent_new(); + username = g_value_get_string(g_value_array_get_nth(users, j)); + lu_user_lookup_name(luc, username, lueu, &error); + if (aux_lu_get_long(lueu, LU_GIDNUMBER) == group_gid) { + asprintf(&errormsg, + "Cannot delete group %s, it is primary group of user %s\n", + groupname, username); + rc = GROUP_IS_PRIMARY; + lu_ent_free(lueu); + goto clean; + } + lu_ent_free(lueu); + } + + if (!lu_group_delete(luc, lueg, &error)) { + asprintf(&errormsg, "Group %s could not be deleted: %s\n", groupname, + lu_strerror(error)); + rc = CMPI_RC_ERR_FAILED; + goto clean; + } + +clean: + lu_ent_free(lueg); + lu_ent_free(lueu); + lu_end(luc); + return rc; +} + +/* + * DEPRECATED + */ static CMPIStatus LMI_GroupDeleteInstance( CMPIInstanceMI* mi, const CMPIContext* cc, @@ -145,49 +215,21 @@ static CMPIStatus LMI_GroupDeleteInstance( { LMI_Group lg; const char *name = NULL; - struct lu_context *luc = NULL; - struct lu_error *error = NULL; - struct lu_ent *lue = NULL; CMPIrc rc = CMPI_RC_OK; char *errmsg = NULL; LMI_Group_InitFromObjectPath(&lg, _cb, cop); name = lg.Name.chars; - luc = lu_start(NULL, 0, NULL, NULL, lu_prompt_console_quiet, NULL, &error); - if (!luc) - { - KReturn2(_cb, ERR_FAILED, - "Unable to initialize libuser: %s\n", lu_strerror(error)); - } - - lue = lu_ent_new(); - if (!lu_group_lookup_name(luc, name, lue, &error)) - { /* Group not found */ - asprintf(&errmsg, "Non existing group: %s\n", name); - rc = CMPI_RC_ERR_NOT_FOUND; - goto fail; - } - - if (!lu_group_delete(luc, lue, &error)) - { - asprintf(&errmsg, "Group %s could not be deleted: %s\n", name, - lu_strerror(error)); - rc = CMPI_RC_ERR_FAILED; - goto fail; - } - -fail: - lu_ent_free(lue); - lu_end(luc); - - if (errmsg) { - CMPIString *errstr = CMNewString(_cb, errmsg, NULL); + rc = delete_group(name, errmsg); + if (rc != CMPI_RC_OK) { + CMPIStatus st = {CMPI_RC_ERR_FAILED, NULL}; + CMSetStatusWithChars(_cb, &st, CMPI_RC_ERR_FAILED, errmsg); free(errmsg); - CMReturnWithString(rc, errstr); - } else { - CMReturn(rc); + return st; } + + CMReturn(rc); } static CMPIStatus LMI_GroupExecQuery( @@ -228,6 +270,33 @@ static CMPIStatus LMI_GroupInvokeMethod( _cb, mi, cc, cr, cop, meth, in, out); } +KUint32 LMI_Group_DeleteGroup( + const CMPIBroker* cb, + CMPIMethodMI* mi, + const CMPIContext* context, + const LMI_GroupRef* self, + CMPIStatus* status) +{ + KUint32 result = KUINT32_INIT; + + char *errmsg = NULL; + + CMPIrc rc = delete_group( + self->Name.chars, + errmsg); + + KUint32_Set(&result, rc); + + if (rc > 0 && rc < GROUP_NOT_EXIST) { + CMSetStatusWithChars(_cb, status, rc, errmsg); + } + free(errmsg); + + return result; +} + + + CMMethodMIStub( LMI_Group, LMI_Group, diff --git a/src/account/doc/source/usage.rst b/src/account/doc/source/usage.rst index ee88d40..708c42c 100644 --- a/src/account/doc/source/usage.rst +++ b/src/account/doc/source/usage.rst @@ -114,18 +114,22 @@ method on the desired :ref:`LMI_Account <LMI-Account>` object. Delete group ------------ -Group deletion is done with ``DeleteInstance`` intrinsic method on the desired -:ref:`LMI_Group <LMI-Group>` object:: +Group deletion is done with :ref:`DeleteGroup <LMI-Group-DeleteGroup>` +method on the desired :ref:`LMI_Group <LMI-Group>` object, + +:: # get the desired group grp = c.root.cimv2.LMI_Group.first_instance(key="Name", value="tobedeleted") # delete the group - grp.delete() + grp.DeleteGroup() -.. warning:: +.. note:: - Due to a bug in libuser (library used), it is possible to delete user's - primary group if the group id is not the default one. + Previous releases allowed to use ``DeleteInstance`` intrinsic method to + delete ``LMI_Group``. This method is now deprecated and + will be removed from future releases of OpenLMI Account. The reason is that + we want to have consistent way to delete user and group. Add user to group |