summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJakub Hrozek <jhrozek@redhat.com>2010-10-05 14:22:00 +0200
committerStephen Gallagher <sgallagh@redhat.com>2010-10-08 19:26:55 -0400
commit57bd514e16e954c03bd32497b6b430142335761e (patch)
treedcd17a3f213771ce5b0e4a3056d618d0770caa41 /src
parent8971b82a5acba9baf85230dbd13b07373904dca1 (diff)
downloadsssd-57bd514e16e954c03bd32497b6b430142335761e.tar.gz
sssd-57bd514e16e954c03bd32497b6b430142335761e.tar.xz
sssd-57bd514e16e954c03bd32497b6b430142335761e.zip
sysdb interface for adding expired user entries
Diffstat (limited to 'src')
-rw-r--r--src/db/sysdb.h8
-rw-r--r--src/db/sysdb_ops.c185
-rw-r--r--src/providers/ldap/ldap_id_cleanup.c7
-rw-r--r--src/responder/nss/nsssrv_cmd.c2
4 files changed, 198 insertions, 4 deletions
diff --git a/src/db/sysdb.h b/src/db/sysdb.h
index 0ae26ac9e..e3e69d3b0 100644
--- a/src/db/sysdb.h
+++ b/src/db/sysdb.h
@@ -451,6 +451,14 @@ struct tevent_req *sysdb_add_basic_user_send(TALLOC_CTX *mem_ctx,
const char *shell);
int sysdb_add_basic_user_recv(struct tevent_req *req);
+/* Add fake (expired) user */
+struct tevent_req *sysdb_add_fake_user_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct sysdb_handle *handle,
+ struct sss_domain_info *domain,
+ const char *name);
+int sysdb_add_fake_user_recv(struct tevent_req *req);
+
/* Add user (all checks) */
struct tevent_req *sysdb_add_user_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c
index 6a696b73e..1c88e7d03 100644
--- a/src/db/sysdb_ops.c
+++ b/src/db/sysdb_ops.c
@@ -2061,6 +2061,191 @@ int sysdb_add_user_recv(struct tevent_req *req)
return sysdb_op_default_recv(req);
}
+/* =Add-A-Fake-User====================================================== */
+
+struct sysdb_add_fake_user_state {
+ struct tevent_context *ev;
+ struct sysdb_handle *handle;
+ struct sss_domain_info *domain;
+
+ const char *name;
+};
+
+static void sysdb_add_fake_user_group_check(struct tevent_req *subreq);
+static int sysdb_add_fake_user_op(struct tevent_req *req);
+static void sysdb_add_fake_user_op_done(struct tevent_req *subreq);
+
+struct tevent_req *sysdb_add_fake_user_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct sysdb_handle *handle,
+ struct sss_domain_info *domain,
+ const char *name)
+{
+ struct tevent_req *req, *subreq;
+ struct sysdb_add_fake_user_state *state;
+ int ret;
+
+ req = tevent_req_create(mem_ctx, &state,
+ struct sysdb_add_fake_user_state);
+ if (!req) return NULL;
+
+ state->ev = ev;
+ state->handle = handle;
+ state->domain = domain;
+ state->name = name;
+
+ if (handle->ctx->mpg) {
+ /* In MPG domains you can't have groups with the same name as users,
+ * search if a user with the same name exists.
+ * Don't worry about users, if we try to add a user with the same
+ * name the operation will fail */
+ subreq = sysdb_search_group_by_name_send(state, ev, NULL, handle,
+ domain, name, NULL);
+ if (!subreq) {
+ ERROR_OUT(ret, ENOMEM, fail);
+ }
+ tevent_req_set_callback(subreq, sysdb_add_fake_user_group_check, req);
+ return req;
+ }
+
+ /* try to add the user */
+ ret = sysdb_add_fake_user_op(req);
+ if (ret != EOK) goto fail;
+
+ return req;
+
+fail:
+ DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
+ tevent_req_error(req, ret);
+ tevent_req_post(req, ev);
+ return req;
+}
+
+static void sysdb_add_fake_user_group_check(struct tevent_req *subreq)
+{
+ struct tevent_req *req = tevent_req_callback_data(subreq,
+ struct tevent_req);
+ struct sysdb_add_fake_user_state *state = tevent_req_data(req,
+ struct sysdb_add_fake_user_state);
+ struct ldb_message *msg;
+ int ret;
+
+ /* We can succeed only if we get an ENOENT error, which means no users
+ * with the same name exist.
+ * If any other error is returned fail as well. */
+ ret = sysdb_search_user_recv(subreq, state, &msg);
+ talloc_zfree(subreq);
+ if (ret != ENOENT) {
+ if (ret == EOK) ret = EEXIST;
+ tevent_req_error(req, ret);
+ return;
+ }
+
+ /* try to add the user */
+ ret = sysdb_add_fake_user_op(req);
+ if (ret != EOK) {
+ tevent_req_error(req, ret);
+ }
+}
+
+static int sysdb_add_fake_user_op(struct tevent_req *req)
+{
+ struct sysdb_add_fake_user_state *state = tevent_req_data(req,
+ struct sysdb_add_fake_user_state);
+ struct ldb_message *msg;
+ struct tevent_req *subreq;
+ struct ldb_request *ldbreq;
+ int ret;
+ time_t now;
+
+ msg = ldb_msg_new(state);
+ if (!msg) {
+ return ENOMEM;
+ }
+
+ /* user dn */
+ msg->dn = sysdb_user_dn(state->handle->ctx, msg,
+ state->domain->name, state->name);
+ if (!msg->dn) {
+ return ENOMEM;
+ }
+
+ now = time(NULL);
+
+ ret = add_string(msg, LDB_FLAG_MOD_ADD, "objectClass", SYSDB_USER_CLASS);
+ if (ret) return ret;
+
+ ret = add_string(msg, LDB_FLAG_MOD_ADD, SYSDB_NAME, state->name);
+ if (ret) return ret;
+
+ ret = add_ulong(msg, LDB_FLAG_MOD_ADD, SYSDB_CREATE_TIME,
+ (unsigned long) now);
+ if (ret) return ret;
+
+ ret = add_ulong(msg, LDB_FLAG_MOD_ADD, SYSDB_LAST_UPDATE,
+ (unsigned long) now);
+ if (ret) return ret;
+
+ /* set last login so that the fake entry does not get cleaned up
+ * immediately */
+ ret = add_ulong(msg, LDB_FLAG_MOD_ADD, SYSDB_LAST_LOGIN,
+ (unsigned long) now);
+ if (ret) return ret;
+
+ ret = add_ulong(msg, LDB_FLAG_MOD_ADD, SYSDB_CACHE_EXPIRE,
+ (unsigned long) now-1);
+ if (ret) return ret;
+
+ ret = ldb_build_add_req(&ldbreq, state->handle->ctx->ldb, state, msg,
+ NULL, NULL, NULL, NULL);
+ if (ret != LDB_SUCCESS) {
+ DEBUG(1, ("Failed to build modify request: %s(%d)[%s]\n",
+ ldb_strerror(ret), ret, ldb_errstring(state->handle->ctx->ldb)));
+ return sysdb_error_to_errno(ret);
+ }
+
+ subreq = sldb_request_send(state, state->ev,
+ state->handle->ctx->ldb, ldbreq);
+ if (!subreq) {
+ return ENOMEM;
+ }
+ tevent_req_set_callback(subreq, sysdb_add_fake_user_op_done, req);
+
+ return EOK;
+}
+
+static void sysdb_add_fake_user_op_done(struct tevent_req *subreq)
+{
+ struct tevent_req *req = tevent_req_callback_data(subreq,
+ struct tevent_req);
+ struct sysdb_add_fake_user_state *state = tevent_req_data(req,
+ struct sysdb_add_fake_user_state);
+ struct ldb_reply *ldbreply;
+ int ret;
+
+ ret = sldb_request_recv(subreq, state, &ldbreply);
+ talloc_zfree(subreq);
+ if (ret) {
+ DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
+ tevent_req_error(req, ret);
+ return;
+ }
+
+ if (ldbreply->type != LDB_REPLY_DONE) {
+ DEBUG(6, ("Error: %d (%s)\n", EIO, strerror(EIO)));
+ tevent_req_error(req, EIO);
+ return;
+ }
+
+ tevent_req_done(req);
+}
+
+int sysdb_add_fake_user_recv(struct tevent_req *req)
+{
+ TEVENT_REQ_RETURN_ON_ERROR(req);
+
+ return EOK;
+}
/* =Add-Basic-Group-NO-CHECKS============================================= */
diff --git a/src/providers/ldap/ldap_id_cleanup.c b/src/providers/ldap/ldap_id_cleanup.c
index 330094f70..bb7c0ea78 100644
--- a/src/providers/ldap/ldap_id_cleanup.c
+++ b/src/providers/ldap/ldap_id_cleanup.c
@@ -413,7 +413,8 @@ static void cleanup_users_delete(struct tevent_req *req)
ret = cleanup_users_logged_in(state->uid_table, state->msgs[state->cur]);
if (ret == EOK) {
/* If the user is logged in, proceed to the next one */
- DEBUG(5, ("User %s is still logged in, keeping his data\n", name));
+ DEBUG(5, ("User %s is still logged in or a dummy entry, "
+ "keeping his data\n", name));
cleanup_users_next(req);
return;
} else if (ret != ENOENT) {
@@ -446,9 +447,9 @@ static int cleanup_users_logged_in(hash_table_t *table,
uid = ldb_msg_find_attr_as_uint64(msg,
SYSDB_UIDNUM, 0);
if (!uid) {
- DEBUG(2, ("Entry %s has no UID Attribute ?!?\n",
+ DEBUG(2, ("Entry %s has no UID Attribute, fake user perhaps?\n",
ldb_dn_get_linearized(msg->dn)));
- return EFAULT;
+ return ENOENT;
}
key.type = HASH_KEY_ULONG;
diff --git a/src/responder/nss/nsssrv_cmd.c b/src/responder/nss/nsssrv_cmd.c
index 45334e23c..7a8645385 100644
--- a/src/responder/nss/nsssrv_cmd.c
+++ b/src/responder/nss/nsssrv_cmd.c
@@ -159,7 +159,7 @@ static int fill_pwent(struct sss_packet *packet,
gid = ldb_msg_find_attr_as_uint64(msg, SYSDB_GIDNUM, 0);
if (!name || !uid || !gid) {
- DEBUG(1, ("Incomplete user object for %s[%llu]! Skipping\n",
+ DEBUG(1, ("Incomplete or fake user object for %s[%llu]! Skipping\n",
name?name:"<NULL>", (unsigned long long int)uid));
continue;
}