summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Gallagher <sgallagh@redhat.com>2009-03-06 08:46:03 -0500
committerSimo Sorce <ssorce@redhat.com>2009-03-06 12:36:53 -0500
commit88f6f6db02c76f4f9d17cbd665b951cdccaaa39e (patch)
tree2b2b7e654bb40a4bdce989c6dd76a54ec6a548a9
parentbaa296befe5908dde17d6e907c0071c2f65a4a88 (diff)
downloadsssd-88f6f6db02c76f4f9d17cbd665b951cdccaaa39e.tar.gz
sssd-88f6f6db02c76f4f9d17cbd665b951cdccaaa39e.tar.xz
sssd-88f6f6db02c76f4f9d17cbd665b951cdccaaa39e.zip
Implement CreateUser in InfoPipe
Changed the order of the arguments to CreateUser in the Introspection XML to match the other functions (domain belongs second on the list) A few other minor fixes as well: Fixed a typo in SYSDB_GETCACHED_FILTER and sysdb_transaction_end(). Added missing error handling in infp_do_user_set_uid().
-rw-r--r--server/db/sysdb.h2
-rw-r--r--server/db/sysdb_req.c2
-rw-r--r--server/infopipe/infopipe_users.c218
-rw-r--r--server/infopipe/org.freeipa.sssd.infopipe.Introspect.xml8
-rw-r--r--server/monitor/monitor.c2
5 files changed, 223 insertions, 9 deletions
diff --git a/server/db/sysdb.h b/server/db/sysdb.h
index c87b0b4ee..f59b56c1d 100644
--- a/server/db/sysdb.h
+++ b/server/db/sysdb.h
@@ -81,7 +81,7 @@
#define SYSDB_INITGR_LEGACY_FILTER "(&(objectclass="SYSDB_GROUP_CLASS")("SYSDB_LEGACY_MEMBER"=%s))"
-#define SYSDB_GETCACHED_FILTER "(&(objectclass="SYSDB_USER_CLASS")("SYSDB_USER_ATTR_LAST_LOGIN">=%llu))"
+#define SYSDB_GETCACHED_FILTER "(&(objectclass="SYSDB_USER_CLASS")("SYSDB_USER_ATTR_LAST_LOGIN">=%lu))"
#define SYSDB_PW_ATTRS {SYSDB_NAME, SYSDB_UIDNUM, \
SYSDB_GIDNUM, SYSDB_FULLNAME, \
diff --git a/server/db/sysdb_req.c b/server/db/sysdb_req.c
index 161431cc9..15d8aa851 100644
--- a/server/db/sysdb_req.c
+++ b/server/db/sysdb_req.c
@@ -174,7 +174,7 @@ static void sysdb_transaction_end(struct sysdb_req *req)
DEBUG(1, ("Failed to commit ldb transaction! (%d)\n", ret));
}
} else {
- DEBUG(4, ("Canceling transaction (%d[%s)\n",
+ DEBUG(4, ("Canceling transaction (%d[%s])\n",
req->status, strerror(req->status)));
ret = ldb_transaction_cancel(req->ctx->ldb);
if (ret != LDB_SUCCESS) {
diff --git a/server/infopipe/infopipe_users.c b/server/infopipe/infopipe_users.c
index a1b22e3b9..d6c00e5c7 100644
--- a/server/infopipe/infopipe_users.c
+++ b/server/infopipe/infopipe_users.c
@@ -201,17 +201,227 @@ error:
return ret;
}
+struct infp_createuser_ctx {
+ struct infp_req_ctx *infp_req;
+ struct sysdb_req *sysdb_req;
+
+ char *username;
+ char *fullname;
+ char *homedir;
+ char *shell;
+};
+
+static void infp_do_user_create_callback(void *pvt,
+ int status,
+ struct ldb_result *res)
+{
+ char *error_msg = NULL;
+ DBusMessage *reply = NULL;
+ struct infp_createuser_ctx *infp_createuser_req = talloc_get_type(pvt, struct infp_createuser_ctx);
+
+ /* Commit the transaction if it we got a successful response, or cancel it if we did not */
+ sysdb_transaction_done(infp_createuser_req->sysdb_req, status);
+
+ /* Verify that the addition completed successfully
+ * If LDB returned an error, run a search to determine
+ * if it was due the requested username already being
+ * in use
+ */
+ if (status == EOK) {
+ /* Return reply ack */
+ reply = dbus_message_new_method_return(infp_createuser_req->infp_req->req_message);
+ }
+ else if (status == EEXIST) {
+ /* Return error, user already exists */
+ error_msg = talloc_asprintf(infp_createuser_req,
+ "User [%s] already exists on domain [%s]",
+ infp_createuser_req->username,
+ infp_createuser_req->infp_req->domain->name);
+ reply = dbus_message_new_error(infp_createuser_req->infp_req->req_message,
+ DBUS_ERROR_FILE_EXISTS,
+ error_msg);
+ }
+ else {
+ /* Unknown error occurred. Print DEBUG message */
+ DEBUG(0, ("Failed to create user in the sysdb. Error code %d\n", status));
+ talloc_free(infp_createuser_req);
+ return;
+ }
+
+ if (reply) {
+ sbus_conn_send_reply(infp_createuser_req->infp_req->sconn, reply);
+ dbus_message_unref(reply);
+ }
+ talloc_free(infp_createuser_req);
+}
+
+static void infp_do_user_create(struct sysdb_req *req, void *pvt)
+{
+ int ret;
+ struct infp_createuser_ctx *infp_createuser_req = talloc_get_type(pvt, struct infp_createuser_ctx);
+ infp_createuser_req->sysdb_req = req;
+
+ ret = sysdb_add_user(infp_createuser_req->sysdb_req,
+ infp_createuser_req->infp_req->domain,
+ infp_createuser_req->username,
+ 0, 0,
+ infp_createuser_req->fullname,
+ infp_createuser_req->homedir,
+ infp_createuser_req->shell,
+ infp_do_user_create_callback,
+ infp_createuser_req);
+ if (ret != EOK) {
+ DEBUG(0, ("Could not invoke sysdb_add_user"));
+ sysdb_transaction_done(infp_createuser_req->sysdb_req, ret);
+ talloc_free(infp_createuser_req);
+ return;
+ }
+}
+
int infp_users_create(DBusMessage *message, struct sbus_conn_ctx *sconn)
{
DBusMessage *reply;
+ DBusError error;
+ dbus_bool_t dbret;
+ char *einval_msg;
+ struct infp_createuser_ctx *infp_createuser_req;
+ int ret;
- reply = dbus_message_new_error(message, DBUS_ERROR_NOT_SUPPORTED, "Not yet implemented");
+ /* Arguments */
+ const char *arg_domain;
+ const char *arg_username;
+ const char *arg_fullname;
+ const char *arg_homedir;
+ const char *arg_shell;
+
+ infp_createuser_req = talloc_zero(NULL, struct infp_createuser_ctx);
+ if (infp_createuser_req == NULL) {
+ ret = ENOMEM;
+ goto error;
+ }
+
+ /* Create an infp_req_ctx */
+ infp_createuser_req->infp_req = talloc_zero(infp_createuser_req, struct infp_req_ctx);
+ if (infp_createuser_req == NULL) {
+ ret = ENOMEM;
+ goto error;
+ }
+ infp_createuser_req->infp_req->infp = talloc_get_type(sbus_conn_get_private_data(sconn), struct infp_ctx);
+ infp_createuser_req->infp_req->sconn = sconn;
+ infp_createuser_req->infp_req->req_message = message;
+ infp_createuser_req->infp_req->caller = sysbus_get_caller(infp_createuser_req->infp_req,
+ infp_createuser_req->infp_req->req_message,
+ infp_createuser_req->infp_req->sconn);
+ if (infp_createuser_req->infp_req->caller == NULL) {
+ ret = EIO;
+ goto error;
+ }
+
+ dbus_error_init(&error);
+ dbret = dbus_message_get_args(message, &error,
+ DBUS_TYPE_STRING, &arg_username,
+ DBUS_TYPE_STRING, &arg_domain,
+ DBUS_TYPE_STRING, &arg_fullname,
+ DBUS_TYPE_STRING, &arg_homedir,
+ DBUS_TYPE_STRING, &arg_shell,
+ DBUS_TYPE_INVALID);
+ if (!dbret) {
+ DEBUG(0, ("Parsing arguments to %s failed: %s:%s\n", INFP_USERS_CREATE, error.name, error.message));
+ einval_msg = talloc_strdup(infp_createuser_req, error.message);
+ dbus_error_free(&error);
+ goto einval;
+ }
+ /* FIXME: Allow creating users on domains other than LOCAL */
+ if (strcasecmp(arg_domain, "LOCAL") != 0) {
+ goto denied;
+ }
+
+ infp_createuser_req->infp_req->domain = btreemap_get_value(infp_createuser_req->infp_req->infp->domain_map,
+ (const void *)arg_domain);
+ /* Check for a valid domain */
+ if(infp_createuser_req->infp_req->domain == NULL) {
+ einval_msg = talloc_strdup(infp_createuser_req, "Invalid domain.");
+ goto einval;
+ }
+
+ if (strlen(arg_username)) {
+ infp_createuser_req->username = talloc_strdup(infp_createuser_req, arg_username);
+ if (infp_createuser_req->username == NULL) {
+ ret = ENOMEM;
+ goto error;
+ }
+ } else {
+ einval_msg = talloc_strdup(infp_createuser_req, "No username provided");
+ goto einval;
+ }
+
+ infp_createuser_req->fullname = NULL;
+ if (strlen(arg_fullname)) {
+ infp_createuser_req->fullname = talloc_strdup(infp_createuser_req, arg_username);
+ if(infp_createuser_req->fullname == NULL) {
+ ret = ENOMEM;
+ goto error;
+ }
+ }
+
+ infp_createuser_req->homedir = NULL;
+ if (strlen(arg_homedir)) {
+ infp_createuser_req->homedir = talloc_strdup(infp_createuser_req, arg_username);
+ if(infp_createuser_req->homedir == NULL) {
+ ret = ENOMEM;
+ goto error;
+ }
+ }
+
+ /* Check permissions */
+ if(!infp_get_permissions(infp_createuser_req->infp_req->caller,
+ infp_createuser_req->infp_req->domain,
+ INFP_OBJ_TYPE_USER,
+ NULL,
+ INFP_ACTION_TYPE_CREATE,
+ INFP_ACTION_TYPE_INVALID)) goto denied;
+
+ ret = sysdb_transaction(infp_createuser_req,
+ infp_createuser_req->infp_req->infp->sysdb,
+ infp_do_user_create,
+ infp_createuser_req);
+ if (ret != EOK) {
+ DEBUG(0,("Unable to start transaction to create user\n"));
+ goto error;
+ }
+
+ return EOK;
+
+denied:
+ reply = dbus_message_new_error(message, DBUS_ERROR_ACCESS_DENIED, NULL);
+ if(reply == NULL) {
+ ret = ENOMEM;
+ goto error;
+ }
/* send reply */
sbus_conn_send_reply(sconn, reply);
+ dbus_message_unref(reply);
+
+ talloc_free(infp_createuser_req);
+ return EOK;
+einval:
+ reply = dbus_message_new_error(message,
+ DBUS_ERROR_INVALID_ARGS,
+ einval_msg);
+ if (reply == NULL) {
+ ret = ENOMEM;
+ goto error;
+ }
+ sbus_conn_send_reply(sconn, reply);
dbus_message_unref(reply);
+ talloc_free(infp_createuser_req);
return EOK;
+
+error:
+ talloc_free(infp_createuser_req);
+ return ret;
}
int infp_users_delete(DBusMessage *message, struct sbus_conn_ctx *sconn)
@@ -1368,6 +1578,12 @@ static void infp_do_user_set_uid(struct sysdb_req *req, void *pvt)
infp_setuid_req->username,
infp_setuid_req->uid_attr,
infp_do_user_set_uid_callback, infp_setuid_req);
+ if (ret != EOK) {
+ DEBUG(0, ("Could not invoke sysdb_set_user_attr"));
+ sysdb_transaction_done(infp_setuid_req->sysdb_req, ret);
+ talloc_free(infp_setuid_req);
+ return;
+ }
}
int infp_users_set_uid(DBusMessage *message, struct sbus_conn_ctx *sconn)
diff --git a/server/infopipe/org.freeipa.sssd.infopipe.Introspect.xml b/server/infopipe/org.freeipa.sssd.infopipe.Introspect.xml
index 164c9d10a..0dcd2a0d5 100644
--- a/server/infopipe/org.freeipa.sssd.infopipe.Introspect.xml
+++ b/server/infopipe/org.freeipa.sssd.infopipe.Introspect.xml
@@ -46,7 +46,7 @@
CheckPermissions(domain=>'LOCAL', object=>'user', instance=>'testuser1', actions=>[('modify','userpic'),('modify','fullname')])
returns permissions=>[1,0]
Can I add members to group wheel?
- CheckPermissions(domain=>'LOCAL', object=>'user', instance=>'wheel', actions=>[('addmember','somearg')])
+ CheckPermissions(domain=>'LOCAL', object=>'group', instance=>'wheel', actions=>[('addmember','somearg')])
returns permissions=>[1]
The argument 'somearg' is ignored, since it does not apply to addmember."
/>
@@ -79,9 +79,8 @@
<annotation
name="org.freeipa.sssd.infopipe.DocString"
value="Create a new user in a particular domain. User will initially have a disabled password.
- @param domain The domain in which to add the user
@param username Username for the new user. Must be unique within a domain.
- @param defaultgroup Default group name for the user.
+ @param domain The domain in which to add the user
@param fullname Full (display) name for the user. Will set both 'fullname' and 'gecos' to this value initially.
@param homedir Home directory path for the user. Must be a parsable path, but does not need to exist or be mounted.
@param shell Login shell. Must exist in /etc/shells.
@@ -91,9 +90,8 @@
@note CreateUser will ignore users that already exist.
@note This function will automatically generate an appropriate UID for the user."
/>
- <arg name="domain" type="s" direction="in" />
<arg name="username" type="s" direction="in" />
- <arg name="defaultgroup" type="s" direction="in" />
+ <arg name="domain" type="s" direction="in" />
<arg name="fullname" type="s" direction="in" />
<arg name="homedir" type="s" direction="in" />
<arg name="shell" type="s" direction="in" />
diff --git a/server/monitor/monitor.c b/server/monitor/monitor.c
index fb5b9b910..3c393c97d 100644
--- a/server/monitor/monitor.c
+++ b/server/monitor/monitor.c
@@ -650,7 +650,7 @@ static void identity_check(DBusPendingCall *pending, void *data)
svc = svc->next;
}
if (!svc) {
- DEBUG(0,("Unable to find peer in list of services, killing connection!\n"));
+ DEBUG(0,("Unable to find peer [%s] in list of services, killing connection!\n", svc_name));
sbus_disconnect(conn_ctx);
goto done;
}