summaryrefslogtreecommitdiff
path: root/source3/winbindd/idmap_tdb.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/winbindd/idmap_tdb.c')
-rw-r--r--source3/winbindd/idmap_tdb.c63
1 files changed, 42 insertions, 21 deletions
diff --git a/source3/winbindd/idmap_tdb.c b/source3/winbindd/idmap_tdb.c
index f9d3a9fbff..4c8cceb691 100644
--- a/source3/winbindd/idmap_tdb.c
+++ b/source3/winbindd/idmap_tdb.c
@@ -820,10 +820,11 @@ done:
}
/**********************************
- set a mapping.
+ set a mapping.
**********************************/
-static NTSTATUS idmap_tdb_set_mapping(struct idmap_domain *dom, const struct id_map *map)
+static NTSTATUS idmap_tdb_set_mapping(struct idmap_domain *dom,
+ const struct id_map *map)
{
struct idmap_tdb_context *ctx;
NTSTATUS ret;
@@ -839,17 +840,19 @@ static NTSTATUS idmap_tdb_set_mapping(struct idmap_domain *dom, const struct id_
data.dptr = NULL;
/* TODO: should we filter a set_mapping using low/high filters ? */
-
+
ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context);
switch (map->xid.type) {
case ID_TYPE_UID:
- kidstr = talloc_asprintf(ctx, "UID %lu", (unsigned long)map->xid.id);
+ kidstr = talloc_asprintf(ctx, "UID %lu",
+ (unsigned long)map->xid.id);
break;
-
+
case ID_TYPE_GID:
- kidstr = talloc_asprintf(ctx, "GID %lu", (unsigned long)map->xid.id);
+ kidstr = talloc_asprintf(ctx, "GID %lu",
+ (unsigned long)map->xid.id);
break;
default:
@@ -875,8 +878,13 @@ static NTSTATUS idmap_tdb_set_mapping(struct idmap_domain *dom, const struct id_
ksid = string_term_tdb_data(ksidstr);
/* *DELETE* previous mappings if any.
- * This is done both SID and [U|G]ID passed in */
-
+ * This is done for both the SID and [U|G]ID passed in */
+
+ /* NOTE: We should lock both the ksid and kid records here, before
+ * making modifications. However, because tdb_chainlock() is a
+ * blocking call we could create an unrecoverable deadlock, so for now
+ * we only lock the ksid record. */
+
/* Lock the record for this SID. */
if (tdb_chainlock(ctx->tdb, ksid) != 0) {
DEBUG(10,("Failed to lock record %s. Error %s\n",
@@ -886,7 +894,8 @@ static NTSTATUS idmap_tdb_set_mapping(struct idmap_domain *dom, const struct id_
data = tdb_fetch(ctx->tdb, ksid);
if (data.dptr) {
- DEBUG(10, ("Deleting existing mapping %s <-> %s\n", (const char *)data.dptr, ksidstr ));
+ DEBUG(10, ("Deleting existing mapping %s <-> %s\n",
+ (const char *)data.dptr, ksidstr ));
tdb_delete(ctx->tdb, data);
tdb_delete(ctx->tdb, ksid);
SAFE_FREE(data.dptr);
@@ -894,20 +903,23 @@ static NTSTATUS idmap_tdb_set_mapping(struct idmap_domain *dom, const struct id_
data = tdb_fetch(ctx->tdb, kid);
if (data.dptr) {
- DEBUG(10,("Deleting existing mapping %s <-> %s\n", (const char *)data.dptr, kidstr ));
+ DEBUG(10,("Deleting existing mapping %s <-> %s\n",
+ (const char *)data.dptr, kidstr ));
tdb_delete(ctx->tdb, data);
tdb_delete(ctx->tdb, kid);
SAFE_FREE(data.dptr);
}
if (tdb_store(ctx->tdb, ksid, kid, TDB_INSERT) == -1) {
- DEBUG(0, ("Error storing SID -> ID: %s\n", tdb_errorstr(ctx->tdb)));
+ DEBUG(0, ("Error storing SID -> ID: %s\n",
+ tdb_errorstr(ctx->tdb)));
tdb_chainunlock(ctx->tdb, ksid);
ret = NT_STATUS_UNSUCCESSFUL;
goto done;
}
if (tdb_store(ctx->tdb, kid, ksid, TDB_INSERT) == -1) {
- DEBUG(0, ("Error stroing ID -> SID: %s\n", tdb_errorstr(ctx->tdb)));
+ DEBUG(0, ("Error storing ID -> SID: %s\n",
+ tdb_errorstr(ctx->tdb)));
/* try to remove the previous stored SID -> ID map */
tdb_delete(ctx->tdb, ksid);
tdb_chainunlock(ctx->tdb, ksid);
@@ -927,10 +939,11 @@ done:
}
/**********************************
- remove a mapping.
+ remove a mapping.
**********************************/
-static NTSTATUS idmap_tdb_remove_mapping(struct idmap_domain *dom, const struct id_map *map)
+static NTSTATUS idmap_tdb_remove_mapping(struct idmap_domain *dom,
+ const struct id_map *map)
{
struct idmap_tdb_context *ctx;
NTSTATUS ret;
@@ -946,17 +959,19 @@ static NTSTATUS idmap_tdb_remove_mapping(struct idmap_domain *dom, const struct
data.dptr = NULL;
/* TODO: should we filter a remove_mapping using low/high filters ? */
-
+
ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context);
switch (map->xid.type) {
case ID_TYPE_UID:
- kidstr = talloc_asprintf(ctx, "UID %lu", (unsigned long)map->xid.id);
+ kidstr = talloc_asprintf(ctx, "UID %lu",
+ (unsigned long)map->xid.id);
break;
-
+
case ID_TYPE_GID:
- kidstr = talloc_asprintf(ctx, "GID %lu", (unsigned long)map->xid.id);
+ kidstr = talloc_asprintf(ctx, "GID %lu",
+ (unsigned long)map->xid.id);
break;
default:
@@ -981,6 +996,11 @@ static NTSTATUS idmap_tdb_remove_mapping(struct idmap_domain *dom, const struct
ksid = string_term_tdb_data(ksidstr);
kid = string_term_tdb_data(kidstr);
+ /* NOTE: We should lock both the ksid and kid records here, before
+ * making modifications. However, because tdb_chainlock() is a
+ * blocking call we could create an unrecoverable deadlock, so for now
+ * we only lock the ksid record. */
+
/* Lock the record for this SID. */
if (tdb_chainlock(ctx->tdb, ksid) != 0) {
DEBUG(10,("Failed to lock record %s. Error %s\n",
@@ -1001,16 +1021,17 @@ static NTSTATUS idmap_tdb_remove_mapping(struct idmap_domain *dom, const struct
if ((data.dsize != kid.dsize) ||
(memcmp(data.dptr, kid.dptr, data.dsize) != 0)) {
DEBUG(10,("Specified SID does not map to specified ID\n"));
- DEBUGADD(10,("Actual mapping is %s -> %s\n", ksidstr, (const char *)data.dptr));
+ DEBUGADD(10,("Actual mapping is %s -> %s\n", ksidstr,
+ (const char *)data.dptr));
tdb_chainunlock(ctx->tdb, ksid);
ret = NT_STATUS_NONE_MAPPED;
goto done;
}
-
+
DEBUG(10, ("Removing %s <-> %s map\n", ksidstr, kidstr));
/* Delete previous mappings. */
-
+
DEBUG(10, ("Deleting existing mapping %s -> %s\n", ksidstr, kidstr ));
tdb_delete(ctx->tdb, ksid);