summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoman Rakus <rrakus@redhat.com>2013-08-29 13:18:29 +0200
committerRoman Rakus <rrakus@redhat.com>2013-09-02 09:33:42 +0200
commit59a8167d1bb3db1a4ffa6d42f2b0f3d6a7454b09 (patch)
tree8b47ab5334e712e9c4cc70428ab4fb87ecb31e3a
parent116a038f697311ceea810b74396055d9dc366f8e (diff)
downloadopenlmi-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.mof27
-rw-r--r--src/account/LMI_AccountProvider.c194
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",