2 * idmap_autorid_tdb: This file contains common code used by
3 * idmap_autorid and net idmap autorid utilities. The common
4 * code provides functions for performing various operations
7 * Copyright (C) Christian Ambach, 2010-2012
8 * Copyright (C) Atul Kulkarni, 2013
9 * Copyright (C) Michael Adam, 2012-2013
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 3 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, see <http://www.gnu.org/licenses/>.
26 #include "idmap_autorid_tdb.h"
27 #include "../libcli/security/dom_sid.h"
30 * Build the database keystring for getting a range
31 * belonging to a domain sid and a range index.
33 static void idmap_autorid_build_keystr(const char *domsid,
34 uint32_t domain_range_index,
37 if (domain_range_index > 0) {
38 fstr_sprintf(keystr, "%s#%"PRIu32,
39 domsid, domain_range_index);
41 fstrcpy(keystr, domsid);
45 static char *idmap_autorid_build_keystr_talloc(TALLOC_CTX *mem_ctx,
47 uint32_t domain_range_index)
51 if (domain_range_index > 0) {
52 keystr = talloc_asprintf(mem_ctx, "%s#%"PRIu32, domsid,
55 keystr = talloc_strdup(mem_ctx, domsid);
62 static bool idmap_autorid_validate_sid(const char *sid)
64 struct dom_sid ignore;
69 if (strcmp(sid, ALLOC_RANGE) == 0) {
73 return dom_sid_parse(sid, &ignore);
76 struct idmap_autorid_addrange_ctx {
77 struct autorid_range_config *range;
81 static NTSTATUS idmap_autorid_addrange_action(struct db_context *db,
84 struct idmap_autorid_addrange_ctx *ctx;
85 uint32_t requested_rangenum, stored_rangenum;
86 struct autorid_range_config *range;
91 struct autorid_global_config *globalcfg;
94 TALLOC_CTX *mem_ctx = NULL;
96 ctx = (struct idmap_autorid_addrange_ctx *)private_data;
98 acquire = ctx->acquire;
99 requested_rangenum = range->rangenum;
102 DEBUG(3, ("Invalid database argument: NULL"));
103 return NT_STATUS_INVALID_PARAMETER;
107 DEBUG(3, ("Invalid range argument: NULL"));
108 return NT_STATUS_INVALID_PARAMETER;
111 DEBUG(10, ("Adding new range for domain %s "
112 "(domain_range_index=%"PRIu32")\n",
113 range->domsid, range->domain_range_index));
115 if (!idmap_autorid_validate_sid(range->domsid)) {
116 DEBUG(3, ("Invalid SID: %s\n", range->domsid));
117 return NT_STATUS_INVALID_PARAMETER;
120 idmap_autorid_build_keystr(range->domsid, range->domain_range_index,
123 ret = dbwrap_fetch_uint32_bystring(db, keystr, &stored_rangenum);
125 if (NT_STATUS_IS_OK(ret)) {
126 /* entry is already present*/
128 DEBUG(10, ("domain range already allocated - "
133 if (stored_rangenum != requested_rangenum) {
134 DEBUG(1, ("Error: requested rangenumber (%u) differs "
135 "from stored one (%u).\n",
136 requested_rangenum, stored_rangenum));
137 return NT_STATUS_UNSUCCESSFUL;
140 DEBUG(10, ("Note: stored range agrees with requested "
145 /* fetch the current HWM */
146 ret = dbwrap_fetch_uint32_bystring(db, HWM, &hwm);
147 if (!NT_STATUS_IS_OK(ret)) {
148 DEBUG(1, ("Fatal error while fetching current "
149 "HWM value: %s\n", nt_errstr(ret)));
150 return NT_STATUS_INTERNAL_ERROR;
153 mem_ctx = talloc_stackframe();
155 ret = idmap_autorid_loadconfig(db, mem_ctx, &globalcfg);
156 if (!NT_STATUS_IS_OK(ret)) {
157 DEBUG(1, ("Fatal error while fetching configuration: %s\n",
164 * automatically acquire the next range
166 requested_rangenum = hwm;
169 if (requested_rangenum >= globalcfg->maxranges) {
170 DEBUG(1, ("Not enough ranges available: New range %u must be "
171 "smaller than configured maximum number of ranges "
173 requested_rangenum, globalcfg->maxranges));
174 ret = NT_STATUS_NO_MEMORY;
178 if (requested_rangenum < hwm) {
180 * Set a specified range below the HWM:
181 * We need to check that it is not yet taken.
184 numstr = talloc_asprintf(mem_ctx, "%u", requested_rangenum);
186 ret = NT_STATUS_NO_MEMORY;
190 if (dbwrap_exists(db, string_term_tdb_data(numstr))) {
191 DEBUG(1, ("Requested range already in use.\n"));
192 ret = NT_STATUS_INVALID_PARAMETER;
199 * requested or automatic range >= HWM:
203 /* HWM always contains current max range + 1 */
204 increment = requested_rangenum + 1 - hwm;
206 /* increase the HWM */
207 ret = dbwrap_change_uint32_atomic_bystring(db, HWM, &hwm,
209 if (!NT_STATUS_IS_OK(ret)) {
210 DEBUG(1, ("Fatal error while incrementing the HWM "
211 "value in the database: %s\n",
218 * store away the new mapping in both directions
221 ret = dbwrap_store_uint32_bystring(db, keystr, requested_rangenum);
222 if (!NT_STATUS_IS_OK(ret)) {
223 DEBUG(1, ("Fatal error while storing new "
224 "domain->range assignment: %s\n", nt_errstr(ret)));
228 numstr = talloc_asprintf(mem_ctx, "%u", requested_rangenum);
230 ret = NT_STATUS_NO_MEMORY;
234 ret = dbwrap_store_bystring(db, numstr,
235 string_term_tdb_data(keystr), TDB_INSERT);
237 if (!NT_STATUS_IS_OK(ret)) {
238 DEBUG(1, ("Fatal error while storing new "
239 "domain->range assignment: %s\n", nt_errstr(ret)));
242 DEBUG(5, ("Acquired new range #%d for domain %s "
243 "(domain_range_index=%"PRIu32")\n", requested_rangenum, keystr,
244 range->domain_range_index));
246 range->rangenum = requested_rangenum;
248 range->low_id = globalcfg->minvalue
249 + range->rangenum * globalcfg->rangesize;
254 talloc_free(mem_ctx);
258 static NTSTATUS idmap_autorid_addrange(struct db_context *db,
259 struct autorid_range_config *range,
263 struct idmap_autorid_addrange_ctx ctx;
265 ctx.acquire = acquire;
268 status = dbwrap_trans_do(db, idmap_autorid_addrange_action, &ctx);
272 NTSTATUS idmap_autorid_setrange(struct db_context *db,
274 uint32_t domain_range_index,
278 struct autorid_range_config range;
281 fstrcpy(range.domsid, domsid);
282 range.domain_range_index = domain_range_index;
283 range.rangenum = rangenum;
285 status = idmap_autorid_addrange(db, &range, false);
289 static NTSTATUS idmap_autorid_acquire_range(struct db_context *db,
290 struct autorid_range_config *range)
292 return idmap_autorid_addrange(db, range, true);
295 static NTSTATUS idmap_autorid_getrange_int(struct db_context *db,
296 struct autorid_range_config *range)
298 NTSTATUS status = NT_STATUS_INVALID_PARAMETER;
299 struct autorid_global_config *globalcfg = NULL;
302 if (db == NULL || range == NULL) {
303 DEBUG(3, ("Invalid arguments received\n"));
307 if (!idmap_autorid_validate_sid(range->domsid)) {
308 DEBUG(3, ("Invalid SID: '%s'\n", range->domsid));
309 status = NT_STATUS_INVALID_PARAMETER;
313 idmap_autorid_build_keystr(range->domsid, range->domain_range_index,
316 DEBUG(10, ("reading domain range for key %s\n", keystr));
317 status = dbwrap_fetch_uint32_bystring(db, keystr, &(range->rangenum));
318 if (!NT_STATUS_IS_OK(status)) {
319 DEBUG(1, ("Failed to read database for key '%s': %s\n",
320 keystr, nt_errstr(status)));
324 status = idmap_autorid_loadconfig(db, talloc_tos(), &globalcfg);
325 if (!NT_STATUS_IS_OK(status)) {
326 DEBUG(1, ("Failed to read global configuration"));
329 range->low_id = globalcfg->minvalue
330 + range->rangenum * globalcfg->rangesize;
332 TALLOC_FREE(globalcfg);
337 NTSTATUS idmap_autorid_getrange(struct db_context *db,
339 uint32_t domain_range_index,
344 struct autorid_range_config range;
346 if (rangenum == NULL) {
347 return NT_STATUS_INVALID_PARAMETER;
351 fstrcpy(range.domsid, domsid);
352 range.domain_range_index = domain_range_index;
354 status = idmap_autorid_getrange_int(db, &range);
355 if (!NT_STATUS_IS_OK(status)) {
359 *rangenum = range.rangenum;
361 if (low_id != NULL) {
362 *low_id = range.low_id;
368 NTSTATUS idmap_autorid_get_domainrange(struct db_context *db,
369 struct autorid_range_config *range,
374 ret = idmap_autorid_getrange_int(db, range);
375 if (!NT_STATUS_IS_OK(ret)) {
377 return NT_STATUS_NOT_FOUND;
380 ret = idmap_autorid_acquire_range(db, range);
383 DEBUG(10, ("Using range #%d for domain %s "
384 "(domain_range_index=%"PRIu32", low_id=%"PRIu32")\n",
385 range->rangenum, range->domsid, range->domain_range_index,
391 /* initialize the given HWM to 0 if it does not exist yet */
392 NTSTATUS idmap_autorid_init_hwm(struct db_context *db, const char *hwm)
397 status = dbwrap_fetch_uint32_bystring(db, hwm, &hwmval);
398 if (NT_STATUS_IS_OK(status)) {
399 DEBUG(1, ("HWM (%s) already initialized in autorid database "
400 "(value %"PRIu32").\n", hwm, hwmval));
403 if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
404 DEBUG(0, ("unable to fetch HWM (%s) from autorid "
405 "database: %s\n", hwm, nt_errstr(status)));
409 status = dbwrap_trans_store_uint32_bystring(db, hwm, 0);
410 if (!NT_STATUS_IS_OK(status)) {
411 DEBUG(0, ("Error initializing HWM (%s) in autorid database: "
412 "%s\n", hwm, nt_errstr(status)));
413 return NT_STATUS_INTERNAL_DB_ERROR;
416 DEBUG(1, ("Initialized HWM (%s) in autorid database.\n", hwm));
422 * Delete a domain#index <-> range mapping from the database.
423 * The mapping is specified by the sid and index.
424 * If force == true, invalid mapping records are deleted as far
425 * as possible, otherwise they are left untouched.
428 struct idmap_autorid_delete_range_by_sid_ctx {
430 uint32_t domain_range_index;
434 static NTSTATUS idmap_autorid_delete_range_by_sid_action(struct db_context *db,
437 struct idmap_autorid_delete_range_by_sid_ctx *ctx =
438 (struct idmap_autorid_delete_range_by_sid_ctx *)private_data;
440 uint32_t domain_range_index;
446 TALLOC_CTX *frame = talloc_stackframe();
447 bool is_valid_range_mapping = true;
450 domsid = ctx->domsid;
451 domain_range_index = ctx->domain_range_index;
454 keystr = idmap_autorid_build_keystr_talloc(frame, domsid,
456 if (keystr == NULL) {
457 status = NT_STATUS_NO_MEMORY;
461 status = dbwrap_fetch_uint32_bystring(db, keystr, &rangenum);
462 if (!NT_STATUS_IS_OK(status)) {
466 range_keystr = talloc_asprintf(frame, "%"PRIu32, rangenum);
467 if (range_keystr == NULL) {
468 status = NT_STATUS_NO_MEMORY;
472 status = dbwrap_fetch_bystring(db, frame, range_keystr, &data);
473 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
474 DEBUG(1, ("Incomplete mapping %s -> %s: no backward mapping\n",
475 keystr, range_keystr));
476 is_valid_range_mapping = false;
477 } else if (!NT_STATUS_IS_OK(status)) {
478 DEBUG(1, ("Error fetching reverse mapping for %s -> %s: %s\n",
479 keystr, range_keystr, nt_errstr(status)));
481 } else if (strncmp((const char *)data.dptr, keystr, strlen(keystr))
484 DEBUG(1, ("Invalid mapping: %s -> %s -> %s\n",
485 keystr, range_keystr, (const char *)data.dptr));
486 is_valid_range_mapping = false;
489 if (!is_valid_range_mapping && !force) {
490 DEBUG(10, ("Not deleting invalid mapping, since not in force "
492 status = NT_STATUS_FILE_INVALID;
496 status = dbwrap_delete_bystring(db, keystr);
497 if (!NT_STATUS_IS_OK(status)) {
498 DEBUG(1, ("Deletion of '%s' failed: %s\n",
499 keystr, nt_errstr(status)));
503 if (!is_valid_range_mapping) {
507 status = dbwrap_delete_bystring(db, range_keystr);
508 if (!NT_STATUS_IS_OK(status)) {
509 DEBUG(1, ("Deletion of '%s' failed: %s\n",
510 range_keystr, nt_errstr(status)));
514 DEBUG(10, ("Deleted range mapping %s <--> %s\n", keystr,
522 NTSTATUS idmap_autorid_delete_range_by_sid(struct db_context *db,
524 uint32_t domain_range_index,
528 struct idmap_autorid_delete_range_by_sid_ctx ctx;
530 ctx.domain_range_index = domain_range_index;
534 status = dbwrap_trans_do(db, idmap_autorid_delete_range_by_sid_action,
540 * Delete a domain#index <-> range mapping from the database.
541 * The mapping is specified by the range number.
542 * If force == true, invalid mapping records are deleted as far
543 * as possible, otherwise they are left untouched.
545 struct idmap_autorid_delete_range_by_num_ctx {
550 static NTSTATUS idmap_autorid_delete_range_by_num_action(struct db_context *db,
553 struct idmap_autorid_delete_range_by_num_ctx *ctx =
554 (struct idmap_autorid_delete_range_by_num_ctx *)private_data;
560 TALLOC_CTX *frame = talloc_stackframe();
561 bool is_valid_range_mapping = true;
564 rangenum = ctx->rangenum;
567 range_keystr = talloc_asprintf(frame, "%"PRIu32, rangenum);
568 if (range_keystr == NULL) {
569 status = NT_STATUS_NO_MEMORY;
575 status = dbwrap_fetch_bystring(db, frame, range_keystr, &val);
576 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
577 DEBUG(10, ("Did not find range '%s' in database.\n",
580 } else if (!NT_STATUS_IS_OK(status)) {
581 DEBUG(5, ("Error fetching rang key: %s\n", nt_errstr(status)));
585 if (val.dptr == NULL) {
586 DEBUG(1, ("Invalid mapping: %s -> empty value\n",
588 is_valid_range_mapping = false;
590 uint32_t reverse_rangenum = 0;
592 keystr = (char *)val.dptr;
594 status = dbwrap_fetch_uint32_bystring(db, keystr,
596 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
597 DEBUG(1, ("Incomplete mapping %s -> %s: "
598 "no backward mapping\n",
599 range_keystr, keystr));
600 is_valid_range_mapping = false;
601 } else if (!NT_STATUS_IS_OK(status)) {
602 DEBUG(1, ("Error fetching reverse mapping for "
604 range_keystr, keystr, nt_errstr(status)));
606 } else if (rangenum != reverse_rangenum) {
607 is_valid_range_mapping = false;
611 if (!is_valid_range_mapping && !force) {
612 DEBUG(10, ("Not deleting invalid mapping, since not in force "
614 status = NT_STATUS_FILE_INVALID;
618 status = dbwrap_delete_bystring(db, range_keystr);
619 if (!NT_STATUS_IS_OK(status)) {
620 DEBUG(1, ("Deletion of '%s' failed: %s\n",
621 range_keystr, nt_errstr(status)));
625 if (!is_valid_range_mapping) {
629 status = dbwrap_delete_bystring(db, keystr);
630 if (!NT_STATUS_IS_OK(status)) {
631 DEBUG(1, ("Deletion of '%s' failed: %s\n",
632 keystr, nt_errstr(status)));
636 DEBUG(10, ("Deleted range mapping %s <--> %s\n", range_keystr,
644 NTSTATUS idmap_autorid_delete_range_by_num(struct db_context *db,
649 struct idmap_autorid_delete_range_by_num_ctx ctx;
651 ctx.rangenum = rangenum;
654 status = dbwrap_trans_do(db, idmap_autorid_delete_range_by_num_action,
660 * open and initialize the database which stores the ranges for the domains
662 NTSTATUS idmap_autorid_db_init(const char *path,
664 struct db_context **db)
669 /* its already open */
673 /* Open idmap repository */
674 *db = db_open(mem_ctx, path, 0, TDB_DEFAULT, O_RDWR | O_CREAT, 0644,
675 DBWRAP_LOCK_ORDER_1, DBWRAP_FLAG_NONE);
678 DEBUG(0, ("Unable to open idmap_autorid database '%s'\n", path));
679 return NT_STATUS_UNSUCCESSFUL;
682 /* Initialize high water mark for the currently used range to 0 */
684 status = idmap_autorid_init_hwm(*db, HWM);
685 NT_STATUS_NOT_OK_RETURN(status);
687 status = idmap_autorid_init_hwm(*db, ALLOC_HWM_UID);
688 NT_STATUS_NOT_OK_RETURN(status);
690 status = idmap_autorid_init_hwm(*db, ALLOC_HWM_GID);
695 struct idmap_autorid_fetch_config_state {
700 static void idmap_autorid_config_parser(TDB_DATA key, TDB_DATA value,
703 struct idmap_autorid_fetch_config_state *state;
705 state = (struct idmap_autorid_fetch_config_state *)private_data;
708 * strndup because we have non-nullterminated strings in the db
710 state->configstr = talloc_strndup(
711 state->mem_ctx, (const char *)value.dptr, value.dsize);
714 NTSTATUS idmap_autorid_getconfigstr(struct db_context *db, TALLOC_CTX *mem_ctx,
719 struct idmap_autorid_fetch_config_state state;
721 if (result == NULL) {
722 return NT_STATUS_INVALID_PARAMETER;
725 key = string_term_tdb_data(CONFIGKEY);
727 state.mem_ctx = mem_ctx;
728 state.configstr = NULL;
730 status = dbwrap_parse_record(db, key, idmap_autorid_config_parser,
732 if (!NT_STATUS_IS_OK(status)) {
733 DEBUG(1, ("Error while retrieving config: %s\n",
738 if (state.configstr == NULL) {
739 DEBUG(1, ("Error while retrieving config\n"));
740 return NT_STATUS_NO_MEMORY;
743 DEBUG(5, ("found CONFIG: %s\n", state.configstr));
745 *result = state.configstr;
749 bool idmap_autorid_parse_configstr(const char *configstr,
750 struct autorid_global_config *cfg)
752 unsigned long minvalue, rangesize, maxranges;
754 if (sscanf(configstr,
755 "minvalue:%lu rangesize:%lu maxranges:%lu",
756 &minvalue, &rangesize, &maxranges) != 3) {
758 ("Found invalid configuration data. "
759 "Creating new config\n"));
763 cfg->minvalue = minvalue;
764 cfg->rangesize = rangesize;
765 cfg->maxranges = maxranges;
770 NTSTATUS idmap_autorid_loadconfig(struct db_context *db,
772 struct autorid_global_config **result)
774 struct autorid_global_config *cfg;
777 char *configstr = NULL;
779 if (result == NULL) {
780 return NT_STATUS_INVALID_PARAMETER;
783 status = idmap_autorid_getconfigstr(db, mem_ctx, &configstr);
784 if (!NT_STATUS_IS_OK(status)) {
788 cfg = talloc_zero(mem_ctx, struct autorid_global_config);
790 return NT_STATUS_NO_MEMORY;
793 ok = idmap_autorid_parse_configstr(configstr, cfg);
796 return NT_STATUS_INVALID_PARAMETER;
799 DEBUG(10, ("Loaded previously stored configuration "
800 "minvalue:%d rangesize:%d\n",
801 cfg->minvalue, cfg->rangesize));
808 NTSTATUS idmap_autorid_saveconfig(struct db_context *db,
809 struct autorid_global_config *cfg)
812 struct autorid_global_config *storedconfig = NULL;
813 NTSTATUS status = NT_STATUS_INVALID_PARAMETER;
817 TALLOC_CTX *frame = talloc_stackframe();
819 DEBUG(10, ("New configuration provided for storing is "
820 "minvalue:%d rangesize:%d maxranges:%d\n",
821 cfg->minvalue, cfg->rangesize, cfg->maxranges));
823 if (cfg->rangesize < 2000) {
824 DEBUG(1, ("autorid rangesize must be at least 2000\n"));
828 if (cfg->maxranges == 0) {
829 DEBUG(1, ("An autorid maxranges value of 0 is invalid. "
830 "Must have at least one range available.\n"));
834 status = idmap_autorid_loadconfig(db, frame, &storedconfig);
835 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
836 DEBUG(5, ("No configuration found. Storing initial "
837 "configuration.\n"));
838 } else if (!NT_STATUS_IS_OK(status)) {
842 /* did the minimum value or rangesize change? */
844 ((storedconfig->minvalue != cfg->minvalue) ||
845 (storedconfig->rangesize != cfg->rangesize)))
847 DEBUG(1, ("New configuration values for rangesize or "
848 "minimum uid value conflict with previously "
849 "used values! Not storing new config.\n"));
850 status = NT_STATUS_INVALID_PARAMETER;
854 status = dbwrap_fetch_uint32_bystring(db, HWM, &hwm);
855 if (!NT_STATUS_IS_OK(status)) {
856 DEBUG(1, ("Fatal error while fetching current "
857 "HWM value: %s\n", nt_errstr(status)));
858 status = NT_STATUS_INTERNAL_ERROR;
863 * has the highest uid value been reduced to setting that is not
864 * sufficient any more for already existing ranges?
866 if (hwm > cfg->maxranges) {
867 DEBUG(1, ("New upper uid limit is too low to cover "
868 "existing mappings! Not storing new config.\n"));
869 status = NT_STATUS_INVALID_PARAMETER;
874 talloc_asprintf(frame,
875 "minvalue:%u rangesize:%u maxranges:%u",
876 cfg->minvalue, cfg->rangesize, cfg->maxranges);
878 if (cfgstr == NULL) {
879 status = NT_STATUS_NO_MEMORY;
883 data = string_tdb_data(cfgstr);
885 status = dbwrap_trans_store_bystring(db, CONFIGKEY, data, TDB_REPLACE);
892 NTSTATUS idmap_autorid_saveconfigstr(struct db_context *db,
893 const char *configstr)
897 struct autorid_global_config cfg;
899 ok = idmap_autorid_parse_configstr(configstr, &cfg);
901 return NT_STATUS_INVALID_PARAMETER;
904 status = idmap_autorid_saveconfig(db, &cfg);
910 * iteration: Work on all range mappings for a given domain
913 struct domain_range_visitor_ctx {
915 NTSTATUS (*fn)(struct db_context *db,
921 int count; /* number of records worked on */
924 static int idmap_autorid_visit_domain_range(struct db_record *rec,
927 struct domain_range_visitor_ctx *vi;
930 uint32_t range_index = 0;
931 uint32_t rangenum = 0;
935 struct db_context *db;
937 vi = talloc_get_type_abort(private_data,
938 struct domain_range_visitor_ctx);
940 key = dbwrap_record_get_key(rec);
943 * split string "<sid>[#<index>]" into sid string and index number
946 domsid = (char *)key.dptr;
948 DEBUG(10, ("idmap_autorid_visit_domain_range: visiting key '%s'\n",
951 sep = strrchr(domsid, '#');
956 if (sscanf(index_str, "%"SCNu32, &range_index) != 1) {
957 DEBUG(10, ("Found separator '#' but '%s' is not a "
958 "valid range index. Skipping record\n",
964 if (!idmap_autorid_validate_sid(domsid)) {
965 DEBUG(10, ("String '%s' is not a valid sid. "
966 "Skipping record.\n", domsid));
970 if ((vi->domsid != NULL) && (strcmp(domsid, vi->domsid) != 0)) {
971 DEBUG(10, ("key sid '%s' does not match requested sid '%s'.\n",
972 domsid, vi->domsid));
976 value = dbwrap_record_get_value(rec);
978 if (value.dsize != sizeof(uint32_t)) {
979 /* it might be a mapping of a well known sid */
980 DEBUG(10, ("value size %u != sizeof(uint32_t) for sid '%s', "
981 "skipping.\n", (unsigned)value.dsize, vi->domsid));
985 rangenum = IVAL(value.dptr, 0);
987 db = dbwrap_record_get_db(rec);
989 status = vi->fn(db, domsid, range_index, rangenum, vi->private_data);
990 if (!NT_STATUS_IS_OK(status)) {
1002 static NTSTATUS idmap_autorid_iterate_domain_ranges_int(struct db_context *db,
1004 NTSTATUS (*fn)(struct db_context *db,
1008 void *private_data),
1011 NTSTATUS (*traverse)(struct db_context *db,
1012 int (*f)(struct db_record *, void *),
1017 struct domain_range_visitor_ctx *vi;
1018 TALLOC_CTX *frame = talloc_stackframe();
1020 if (domsid == NULL) {
1021 DEBUG(10, ("No sid provided, operating on all ranges\n"));
1025 DEBUG(1, ("Error: missing visitor callback\n"));
1026 status = NT_STATUS_INVALID_PARAMETER;
1030 vi = talloc_zero(frame, struct domain_range_visitor_ctx);
1032 status = NT_STATUS_NO_MEMORY;
1036 vi->domsid = domsid;
1038 vi->private_data = private_data;
1040 status = traverse(db, idmap_autorid_visit_domain_range, vi, NULL);
1041 if (!NT_STATUS_IS_OK(status)) {
1045 if (count != NULL) {
1054 NTSTATUS idmap_autorid_iterate_domain_ranges(struct db_context *db,
1056 NTSTATUS (*fn)(struct db_context *db,
1060 void *private_data),
1066 status = idmap_autorid_iterate_domain_ranges_int(db,
1077 NTSTATUS idmap_autorid_iterate_domain_ranges_read(struct db_context *db,
1079 NTSTATUS (*fn)(struct db_context *db,
1089 status = idmap_autorid_iterate_domain_ranges_int(db,
1094 dbwrap_traverse_read);
1101 * Delete all ranges configured for a given domain
1104 struct delete_domain_ranges_visitor_ctx {
1108 static NTSTATUS idmap_autorid_delete_domain_ranges_visitor(
1109 struct db_context *db,
1111 uint32_t domain_range_index,
1115 struct delete_domain_ranges_visitor_ctx *ctx;
1118 ctx = (struct delete_domain_ranges_visitor_ctx *)private_data;
1120 status = idmap_autorid_delete_range_by_sid(
1121 db, domsid, domain_range_index, ctx->force);
1125 struct idmap_autorid_delete_domain_ranges_ctx {
1128 int count; /* output: count records operated on */
1131 static NTSTATUS idmap_autorid_delete_domain_ranges_action(struct db_context *db,
1134 struct idmap_autorid_delete_domain_ranges_ctx *ctx;
1135 struct delete_domain_ranges_visitor_ctx visitor_ctx;
1139 ctx = (struct idmap_autorid_delete_domain_ranges_ctx *)private_data;
1141 ZERO_STRUCT(visitor_ctx);
1142 visitor_ctx.force = ctx->force;
1144 status = idmap_autorid_iterate_domain_ranges(db,
1146 idmap_autorid_delete_domain_ranges_visitor,
1149 if (!NT_STATUS_IS_OK(status)) {
1155 return NT_STATUS_OK;
1158 NTSTATUS idmap_autorid_delete_domain_ranges(struct db_context *db,
1164 struct idmap_autorid_delete_domain_ranges_ctx ctx;
1167 ctx.domsid = domsid;
1170 status = dbwrap_trans_do(db, idmap_autorid_delete_domain_ranges_action,
1172 if (!NT_STATUS_IS_OK(status)) {
1178 return NT_STATUS_OK;