summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRoman Rakus <rrakus@redhat.com>2012-09-07 15:02:37 +0200
committerRoman Rakus <rrakus@redhat.com>2012-09-07 15:05:58 +0200
commitaefe1e49b515b55243096098f820367e53a58493 (patch)
treeca0ccf76c3a062b57df6b8e56443ec4ec522bb0b /src
parent27f6292f6f8542c57275bf5d3734eae889bb31ee (diff)
downloadopenlmi-providers-aefe1e49b515b55243096098f820367e53a58493.tar.gz
openlmi-providers-aefe1e49b515b55243096098f820367e53a58493.tar.xz
openlmi-providers-aefe1e49b515b55243096098f820367e53a58493.zip
account: createAccount function implementation
I decided to not follow the DMTF Standard strictly here. Rather than using embedded instance I use several parameters. Signed-off-by: Roman Rakus <rrakus@redhat.com>
Diffstat (limited to 'src')
-rw-r--r--src/account/LMI_AccountManagementServiceProvider.c240
1 files changed, 238 insertions, 2 deletions
diff --git a/src/account/LMI_AccountManagementServiceProvider.c b/src/account/LMI_AccountManagementServiceProvider.c
index 17a25a2..a33df80 100644
--- a/src/account/LMI_AccountManagementServiceProvider.c
+++ b/src/account/LMI_AccountManagementServiceProvider.c
@@ -1,9 +1,20 @@
#include <konkret/konkret.h>
#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 <libuser/entity.h>
+#include <libuser/user.h>
+
+#include <sys/stat.h>
+#include <unistd.h>
+
static const CMPIBroker* _cb = NULL;
static void LMI_AccountManagementServiceInitialize()
@@ -189,14 +200,239 @@ KUint32 LMI_AccountManagementService_CreateAccount(
const CMPIContext* context,
const LMI_AccountManagementServiceRef* self,
const KRef* System,
- const KString* AccountTemplate,
+ 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);
- KSetStatus(status, ERR_NOT_SUPPORTED);
return result;
}