diff options
author | Roman Rakus <rrakus@redhat.com> | 2013-08-29 13:18:29 +0200 |
---|---|---|
committer | Roman Rakus <rrakus@redhat.com> | 2013-09-02 09:33:42 +0200 |
commit | 59a8167d1bb3db1a4ffa6d42f2b0f3d6a7454b09 (patch) | |
tree | 8b47ab5334e712e9c4cc70428ab4fb87ecb31e3a | |
parent | 116a038f697311ceea810b74396055d9dc366f8e (diff) | |
download | openlmi-providers-59a8167d1bb3db1a4ffa6d42f2b0f3d6a7454b09.tar.gz openlmi-providers-59a8167d1bb3db1a4ffa6d42f2b0f3d6a7454b09.tar.xz openlmi-providers-59a8167d1bb3db1a4ffa6d42f2b0f3d6a7454b09.zip |
Account: New delete method
This method should be used insted of intrinsic DeleteInstace.
Signed-off-by: Roman Rakus <rrakus@redhat.com>
-rw-r--r-- | mof/60_LMI_Account.mof | 27 | ||||
-rw-r--r-- | src/account/LMI_AccountProvider.c | 194 |
2 files changed, 174 insertions, 47 deletions
diff --git a/mof/60_LMI_Account.mof b/mof/60_LMI_Account.mof index 0a79f59..fdf748f 100644 --- a/mof/60_LMI_Account.mof +++ b/mof/60_LMI_Account.mof @@ -44,6 +44,33 @@ class LMI_Account: CIM_Account [ Description("The date of expiration of the account.") ] datetime AccountExpiration; + + [ 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 " + "directory it is not deleted. However this directory can be deleted " + "if force parameter is set to True." ), + ValueMap { "0", "1", "..", "4096", "4097", "4098", "4099" }, + Values { "Operation completed successfully", + "Failed", + "DMTF Reserved", + "Non existing user", + "Unable to delete Home Direcotry", + "Unable to remove user, home directory removed", + "Unable to remove group, user and home directory removed" }] + uint32 DeleteUser( + [IN, Description ( + "By default the user's home directory is deleted. Set to true " + "to not delete the home directory.")] + boolean DontDeleteHomeDirectory, + [IN, Description ( + "By default the user's private group, if the user has one, " + "is deleted. Set to true to not delete the group.")] + boolean DontDeleteGroup, + [IN, Description ( + "Force the deletion of user's home directory, even if the user " + "is not an owner.")] + boolean Force); }; [ Version("0.2.0"), diff --git a/src/account/LMI_AccountProvider.c b/src/account/LMI_AccountProvider.c index 6ef0578..d019a7a 100644 --- a/src/account/LMI_AccountProvider.c +++ b/src/account/LMI_AccountProvider.c @@ -26,6 +26,7 @@ #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> +#include <stdint.h> #include <utmp.h> @@ -446,74 +447,138 @@ static CMPIStatus LMI_AccountModifyInstance( } /* - * DEPRECATED + * Internal function to delete user + * By default don't delete home if the user is not owner of dir + * params: + * username - name of user to delete + * deletehome - if true try to delete home + * deletegroup - if true try to delete primary group of user + * force - force to delete home dir + * errormsg - on return contains error message, called should free memory */ -static CMPIStatus LMI_AccountDeleteInstance( - CMPIInstanceMI* mi, - const CMPIContext* cc, - const CMPIResult* cr, - const CMPIObjectPath* cop) +static CMPIrc delete_user( + const char *username, + const bool deletehome, + const bool deletegroup, + const bool force, + char *errormsg) { - LMI_Account acc; - const char* username = NULL, *home = NULL; + CMPIrc rc = CMPI_RC_OK; + const char *home = NULL; 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; + struct lu_ent *lueg = NULL; luc = lu_start(NULL, 0, NULL, NULL, lu_prompt_console_quiet, NULL, &error); - if (!luc) - { + if (!luc) { fprintf(stderr, "Error initializing: %s\n", lu_strerror(error)); exit(1); - } + } lue = lu_ent_new(); + lueg = lu_ent_new(); - if (!lu_user_lookup_name(luc, username, lue, &error)) - { - lu_ent_free(lue); - lu_end(luc); - KReturn2(_cb, ERR_NOT_FOUND, "Non existing user: %s\n", - username); - } - - home = aux_lu_get_str(lue, LU_HOMEDIRECTORY); - /* Be really safe here, it can delete ANY directory */ - /* Delete home dir only if the directory is owned by the user */ - struct stat buf; - if (stat(home, &buf)) { - lu_ent_free(lue); - lu_end(luc); - KReturn2(_cb, ERR_FAILED, - "User's homedir %s could not be deleted: %s\n", home, - strerror(errno)); + if (!lu_user_lookup_name(luc, username, lue, &error)) { + asprintf(&errormsg, "Non existing user: %s\n", username); + rc = 4096; + goto clean; } - if (buf.st_uid == aux_lu_get_long(lue, LU_UIDNUMBER)) { - if (!lu_homedir_remove(home, &error)) { - lu_ent_free(lue); - lu_end(luc); - KReturn2(_cb, ERR_FAILED, - "User's homedir %s could not be deleted: %s\n", home, - lu_strerror(error)); + + if (deletehome) { + home = aux_lu_get_str(lue, LU_HOMEDIRECTORY); + /* Be really safe here, it can delete ANY directory */ + /* Delete home dir only if the directory is owned by the user */ + struct stat buf; + if (stat(home, &buf)) { + asprintf(&errormsg, "User's homedir %s could not be deleted: %s\n", + home, strerror(errno)); + rc = 4097; + goto clean; + } + /* Remove home dir if the user is owner or force is set */ + if (buf.st_uid == aux_lu_get_long(lue, LU_UIDNUMBER) || force) { + if (!lu_homedir_remove(home, &error)) { + asprintf(&errormsg, + "User's homedir %s could not be deleted: %s\n", home, + lu_strerror(error)); + rc = 4097; + goto clean; + } } } - if (!lu_user_delete(luc, lue, &error)) - { - lu_ent_free(lue); - lu_end(luc); - KReturn2(_cb, ERR_FAILED, "User %s could not be deleted: %s\n", - username, lu_strerror(error)); - } + if (!lu_user_delete(luc, lue, &error)) { + asprintf(&errormsg, "User %s could not be deleted: %s\n", + username, lu_strerror(error)); + rc = 4098; + goto clean; + } + + if (deletegroup) { + gid_t gid; + gid = lu_ent_get_first_id(lue, LU_GIDNUMBER); + + if (gid == LU_VALUE_INVALID_ID) { + asprintf(&errormsg, "%s did not have a gid number.\n", username); + rc = 4099; + goto clean; + } + if (lu_group_lookup_id(luc, gid, lueg, &error) == FALSE) { + asprintf(&errormsg, "No group with GID %jd exists, not removing.\n", + (intmax_t)gid); + rc = 4099; + goto clean; + } + const char *tmp = lu_ent_get_first_string(lueg, LU_GROUPNAME); + if (!tmp) { + asprintf(&errormsg, + "Group with GID %jd did not have a group name.\n", + (intmax_t)gid); + rc = 4099; + goto clean; + } + if (strcmp(tmp, username) == 0) { + if (lu_group_delete(luc, lueg, &error) == FALSE) { + asprintf(&errormsg, "Group %s could not be deleted: %s.\n", + tmp, lu_strerror(error)); + rc = 4099; + goto clean; + } + } + } +clean: lu_ent_free(lue); + lu_ent_free(lueg); lu_end(luc); - CMReturn(CMPI_RC_OK); + return rc; +} + +/* + * DEPRECATED + */ +static CMPIStatus LMI_AccountDeleteInstance( + CMPIInstanceMI* mi, + const CMPIContext* cc, + const CMPIResult* cr, + const CMPIObjectPath* cop) +{ + LMI_Account acc; + char *errmsg = NULL; + + LMI_Account_InitFromObjectPath(&acc, _cb, cop); + CMPIrc rc = delete_user(acc.Name.chars, true, true, false, errmsg); + if (rc != CMPI_RC_OK) { + CMPIStatus st = {CMPI_RC_ERR_FAILED, NULL}; + CMSetStatusWithChars(_cb, &st, rc, errmsg); + free(errmsg); + return st; + } + + CMReturn(rc); } static CMPIStatus LMI_AccountExecQuery( @@ -554,6 +619,7 @@ static CMPIStatus LMI_AccountInvokeMethod( _cb, mi, cc, cr, cop, meth, in, out); } + CMMethodMIStub( LMI_Account, LMI_Account, @@ -577,6 +643,40 @@ KUint32 LMI_Account_RequestStateChange( } +KUint32 LMI_Account_DeleteUser( + const CMPIBroker* cb, + CMPIMethodMI* mi, + const CMPIContext* context, + const LMI_AccountRef* self, + const KBoolean* DontDeleteHomeDirectory, + const KBoolean* DontDeleteGroup, + const KBoolean* Force, + CMPIStatus* status) +{ + KUint32 result = KUINT32_INIT; + + bool deletehome = !(DontDeleteHomeDirectory->exists && + !DontDeleteHomeDirectory->null && + DontDeleteHomeDirectory->value); + + bool deletegroup = !(DontDeleteGroup->exists && + !DontDeleteGroup->null && + DontDeleteGroup->value); + + char *errmsg = NULL; + + CMPIrc rc = delete_user( + self->Name.chars, + deletehome, + deletegroup, + (force->exists && !force->null && force->value), + errmsg); + + KUint32_Set(&result, rc); + + return result; +} + KONKRET_REGISTRATION( "root/cimv2", "LMI_Account", |