summaryrefslogtreecommitdiffstats
path: root/src/providers
diff options
context:
space:
mode:
Diffstat (limited to 'src/providers')
-rw-r--r--src/providers/proxy/proxy_id.c88
1 files changed, 85 insertions, 3 deletions
diff --git a/src/providers/proxy/proxy_id.c b/src/providers/proxy/proxy_id.c
index ca647f891..4f2dbd882 100644
--- a/src/providers/proxy/proxy_id.c
+++ b/src/providers/proxy/proxy_id.c
@@ -443,13 +443,19 @@ done:
} \
} while(0)
+
+static errno_t proxy_process_missing_users(struct sysdb_ctx *sysdb,
+ struct group *grp,
+ time_t now);
static int save_group(struct sysdb_ctx *sysdb, struct sss_domain_info *dom,
struct group *grp, uint64_t cache_timeout)
{
- errno_t ret;
+ errno_t ret, sret;
struct sysdb_attrs *attrs = NULL;
char *lower;
TALLOC_CTX *tmp_ctx;
+ time_t now = time(NULL);
+ bool in_transaction = false;
tmp_ctx = talloc_new(NULL);
if (!tmp_ctx) {
@@ -458,6 +464,10 @@ static int save_group(struct sysdb_ctx *sysdb, struct sss_domain_info *dom,
DEBUG_GR_MEM(7, grp);
+ ret = sysdb_transaction_start(sysdb);
+ if (ret != EOK) goto done;
+ in_transaction = true;
+
if (grp->gr_mem && grp->gr_mem[0]) {
attrs = sysdb_new_attrs(tmp_ctx);
if (!attrs) {
@@ -473,6 +483,13 @@ static int save_group(struct sysdb_ctx *sysdb, struct sss_domain_info *dom,
DEBUG(SSSDBG_OP_FAILURE, ("Could not add group members\n"));
goto done;
}
+
+ /* Create fake users if they don't already exist */
+ ret = proxy_process_missing_users(sysdb, grp, now);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, ("Could not add missing members\n"));
+ goto done;
+ }
}
if (dom->case_sensitive == false) {
@@ -505,13 +522,78 @@ static int save_group(struct sysdb_ctx *sysdb, struct sss_domain_info *dom,
grp->gr_gid,
attrs,
cache_timeout,
- 0);
+ now);
if (ret) {
DEBUG(SSSDBG_OP_FAILURE, ("Could not add group to cache\n"));
goto done;
}
- ret = EOK;
+ ret = sysdb_transaction_commit(sysdb);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ ("Could not commit transaction: [%s]\n",
+ strerror(ret)));
+ goto done;
+ }
+ in_transaction = false;
+
+done:
+ if (in_transaction) {
+ sret = sysdb_transaction_cancel(sysdb);
+ if (sret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, ("Could not cancel transaction\n"));
+ }
+ }
+ talloc_free(tmp_ctx);
+ return ret;
+}
+
+static errno_t proxy_process_missing_users(struct sysdb_ctx *sysdb,
+ struct group *grp,
+ time_t now)
+{
+ errno_t ret;
+ size_t i;
+ TALLOC_CTX *tmp_ctx = NULL;
+ struct ldb_message *msg;
+
+ if (!sysdb || !grp) return EINVAL;
+
+ tmp_ctx = talloc_new(NULL);
+ if (!tmp_ctx) return ENOMEM;
+
+ for (i = 0; grp->gr_mem[i]; i++) {
+ ret = sysdb_search_user_by_name(tmp_ctx, sysdb, grp->gr_mem[i],
+ NULL, &msg);
+ if (ret == EOK) {
+ /* Member already exists in the cache */
+ DEBUG(SSSDBG_TRACE_INTERNAL,
+ ("Member [%s] already cached\n", grp->gr_mem[i]));
+ /* clean up */
+ talloc_zfree(msg);
+ continue;
+ } else if (ret == ENOENT) {
+ /* No entry for this user. Create a fake user */
+ DEBUG(SSSDBG_TRACE_LIBS,
+ ("Member [%s] not cached, creating fake user entry\n",
+ grp->gr_mem[i]));
+
+ ret = sysdb_add_fake_user(sysdb, grp->gr_mem[i], NULL, now);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_MINOR_FAILURE,
+ ("Cannot store fake user entry: [%d]: %s\n",
+ ret, strerror(ret)));
+ goto done;
+ }
+ } else {
+ /* Unexpected error */
+ DEBUG(SSSDBG_MINOR_FAILURE,
+ ("Error searching cache for user [%s]: [%s]\n",
+ grp->gr_mem[i], strerror(ret)));
+ goto done;
+ }
+ }
+
done:
talloc_free(tmp_ctx);
return ret;