summaryrefslogtreecommitdiff
path: root/source3/winbindd
diff options
context:
space:
mode:
authorMichael Adam <obnox@samba.org>2013-09-18 01:54:58 +0200
committerMichael Adam <obnox@samba.org>2013-10-02 00:50:12 +0200
commit97dfa06151e8ea843c393f63c2c4b956810b2994 (patch)
tree660c497b35c40fecd451884fcf6521a8e8c09a5b /source3/winbindd
parent54a33ebf273d8f5c9d66b20257f7baf5cc920386 (diff)
downloadsamba-97dfa06151e8ea843c393f63c2c4b956810b2994.tar.gz
samba-97dfa06151e8ea843c393f63c2c4b956810b2994.tar.bz2
samba-97dfa06151e8ea843c393f63c2c4b956810b2994.zip
idmap_autorid: add idmap_autorid_iterate_domain_ranges[_read]()
Functions to perform an action on all domain range mappings for a given domain, specified by the domain sid. Inspired by a previous patch by Atul Kulkarni <atul.kulkarni@in.ibm.com>. Signed-off-by: Michael Adam <obnox@samba.org> Reviewed-by: Volker Lendecke <vl@samba.org>
Diffstat (limited to 'source3/winbindd')
-rw-r--r--source3/winbindd/idmap_autorid_tdb.c185
1 files changed, 185 insertions, 0 deletions
diff --git a/source3/winbindd/idmap_autorid_tdb.c b/source3/winbindd/idmap_autorid_tdb.c
index 91909cd17b..7419a4d90f 100644
--- a/source3/winbindd/idmap_autorid_tdb.c
+++ b/source3/winbindd/idmap_autorid_tdb.c
@@ -892,3 +892,188 @@ NTSTATUS idmap_autorid_saveconfigstr(struct db_context *db,
status = idmap_autorid_saveconfig(db, &cfg);
return status;
}
+
+
+/*
+ * iteration: Work on all range mappings for a given domain
+ */
+
+struct domain_range_visitor_ctx {
+ const char *domsid;
+ NTSTATUS (*fn)(struct db_context *db,
+ const char *domsid,
+ uint32_t index,
+ uint32_t rangenum,
+ void *private_data);
+ void *private_data;
+ int count; /* number of records worked on */
+};
+
+static int idmap_autorid_visit_domain_range(struct db_record *rec,
+ void *private_data)
+{
+ struct domain_range_visitor_ctx *vi;
+ char *domsid;
+ char *sep;
+ uint32_t range_index = 0;
+ uint32_t rangenum = 0;
+ TDB_DATA key, value;
+ NTSTATUS status;
+ int ret = 0;
+ struct db_context *db;
+
+ vi = talloc_get_type_abort(private_data,
+ struct domain_range_visitor_ctx);
+
+ key = dbwrap_record_get_key(rec);
+
+ /*
+ * split string "<sid>[#<index>]" into sid string and index number
+ */
+
+ domsid = (char *)key.dptr;
+
+ DEBUG(10, ("idmap_autorid_visit_domain_range: visiting key '%s'\n",
+ domsid));
+
+ sep = strrchr(domsid, '#');
+ if (sep != NULL) {
+ char *index_str;
+ *sep = '\0';
+ index_str = sep+1;
+ if (sscanf(index_str, "%"SCNu32, &range_index) != 1) {
+ DEBUG(10, ("Found separator '#' but '%s' is not a "
+ "valid range index. Skipping record\n",
+ index_str));
+ goto done;
+ }
+ }
+
+ if (!idmap_autorid_validate_sid(domsid)) {
+ DEBUG(10, ("String '%s' is not a valid sid. "
+ "Skipping record.\n", domsid));
+ goto done;
+ }
+
+ if (strcmp(domsid, vi->domsid) != 0) {
+ DEBUG(10, ("key sid '%s' does not match requested sid '%s'.\n",
+ domsid, vi->domsid));
+ goto done;
+ }
+
+ value = dbwrap_record_get_value(rec);
+ rangenum = IVAL(value.dptr, 0);
+
+ db = dbwrap_record_get_db(rec);
+
+ status = vi->fn(db, domsid, range_index, rangenum, vi->private_data);
+ if (!NT_STATUS_IS_OK(status)) {
+ ret = -1;
+ goto done;
+ }
+
+ vi->count++;
+ ret = 0;
+
+done:
+ return ret;
+}
+
+static NTSTATUS idmap_autorid_iterate_domain_ranges_int(struct db_context *db,
+ const char *domsid,
+ NTSTATUS (*fn)(struct db_context *db,
+ const char *domsid,
+ uint32_t index,
+ uint32_t rangnum,
+ void *private_data),
+ void *private_data,
+ int *count,
+ NTSTATUS (*traverse)(struct db_context *db,
+ int (*f)(struct db_record *, void *),
+ void *private_data,
+ int *count))
+{
+ NTSTATUS status;
+ struct domain_range_visitor_ctx *vi;
+ TALLOC_CTX *frame = talloc_stackframe();
+
+ if (domsid == NULL) {
+ DEBUG(1, ("Error: no domain sid provided\n"));
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto done;
+ }
+
+ if (fn == NULL) {
+ DEBUG(1, ("Error: missing visitor callback\n"));
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto done;
+ }
+
+ vi = talloc_zero(frame, struct domain_range_visitor_ctx);
+ if (vi == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ vi->domsid = domsid;
+ vi->fn = fn;
+ vi->private_data = private_data;
+
+ status = traverse(db, idmap_autorid_visit_domain_range, vi, NULL);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+
+ if (count != NULL) {
+ *count = vi->count;
+ }
+
+done:
+ talloc_free(frame);
+ return status;
+}
+
+NTSTATUS idmap_autorid_iterate_domain_ranges(struct db_context *db,
+ const char *domsid,
+ NTSTATUS (*fn)(struct db_context *db,
+ const char *domsid,
+ uint32_t index,
+ uint32_t rangenum,
+ void *private_data),
+ void *private_data,
+ int *count)
+{
+ NTSTATUS status;
+
+ status = idmap_autorid_iterate_domain_ranges_int(db,
+ domsid,
+ fn,
+ private_data,
+ count,
+ dbwrap_traverse);
+
+ return status;
+}
+
+
+NTSTATUS idmap_autorid_iterate_domain_ranges_read(struct db_context *db,
+ const char *domsid,
+ NTSTATUS (*fn)(struct db_context *db,
+ const char *domsid,
+ uint32_t index,
+ uint32_t rangenum,
+ void *count),
+ void *private_data,
+ int *count)
+{
+ NTSTATUS status;
+
+ status = idmap_autorid_iterate_domain_ranges_int(db,
+ domsid,
+ fn,
+ private_data,
+ count,
+ dbwrap_traverse_read);
+
+ return status;
+}