diff options
Diffstat (limited to 'source3/utils/net_idmap_check.c')
-rw-r--r-- | source3/utils/net_idmap_check.c | 224 |
1 files changed, 82 insertions, 142 deletions
diff --git a/source3/utils/net_idmap_check.c b/source3/utils/net_idmap_check.c index 25997b14c5..4174238298 100644 --- a/source3/utils/net_idmap_check.c +++ b/source3/utils/net_idmap_check.c @@ -26,27 +26,23 @@ #include "net_idmap_check.h" #include "includes.h" #include "system/filesys.h" -#include "dbwrap.h" +#include "dbwrap/dbwrap.h" +#include "dbwrap/dbwrap_open.h" +#include "dbwrap/dbwrap_rbt.h" #include "net.h" #include "../libcli/security/dom_sid.h" #include "cbuf.h" #include "srprs.h" -#include <termios.h> #include "util_tdb.h" +#include "interact.h" static int traverse_commit(struct db_record *diff_rec, void* data); static int traverse_check(struct db_record *rec, void* data); -static char* interact_edit(TALLOC_CTX* mem_ctx, const char* str); -static int interact_prompt(const char* msg, const char* accept, char def); - /* TDB_DATA *******************************************************************/ static char* print_data(TALLOC_CTX* mem_ctx, TDB_DATA d); static TDB_DATA parse_data(TALLOC_CTX* mem_ctx, const char** ptr); static TDB_DATA talloc_copy(TALLOC_CTX* mem_ctx, TDB_DATA data); -static bool is_empty(TDB_DATA data) { - return (data.dsize == 0) || (data.dptr == NULL); -} /* record *********************************************************************/ @@ -276,10 +272,10 @@ static TDB_DATA_diff unpack_diff(TDB_DATA data) { #define DEBUG_DIFF(LEV,MEM,MSG,KEY,OLD,NEW) \ DEBUG(LEV, ("%s: %s\n", MSG, print_data(MEM, KEY))); \ - if (!is_empty(OLD)) { \ + if (!tdb_data_is_empty(OLD)) { \ DEBUGADD(LEV, ("-%s\n", print_data(MEM, OLD))); \ } \ - if (!is_empty(NEW)) { \ + if (!tdb_data_is_empty(NEW)) { \ DEBUGADD(LEV, ("+%s\n", print_data(MEM, NEW))); \ } @@ -311,21 +307,29 @@ static int add_record(struct check_ctx* ctx, TDB_DATA key, TDB_DATA value) NTSTATUS status; TDB_DATA_diff diff; TALLOC_CTX* mem = talloc_new(ctx->diff); - struct db_record* rec = ctx->diff->fetch_locked(ctx->diff, mem, key); + TDB_DATA recvalue; + struct db_record *rec = dbwrap_fetch_locked(ctx->diff, mem, key); + if (rec == NULL) { return -1; - }; - if (rec->value.dptr == 0) { /* first entry */ - diff.oval = dbwrap_fetch(ctx->db, ctx->diff, key); + } + + recvalue = dbwrap_record_get_value(rec); + + if (recvalue.dptr == 0) { /* first entry */ + status = dbwrap_fetch(ctx->db, ctx->diff, key, &diff.oval); + if (!NT_STATUS_IS_OK(status)) { + diff.oval = tdb_null; + } } else { - diff = unpack_diff(rec->value); + diff = unpack_diff(recvalue); talloc_free(diff.nval.dptr); } diff.nval = talloc_copy(ctx->diff, value); DEBUG_DIFF(2, mem, "TDB DIFF", key, diff.oval, diff.nval); - status = rec->store(rec, pack_diff(&diff), 0); + status = dbwrap_record_store(rec, pack_diff(&diff), 0); talloc_free(mem); @@ -345,20 +349,19 @@ static TDB_DATA fetch_record(struct check_ctx* ctx, TALLOC_CTX* mem_ctx, TDB_DATA key) { TDB_DATA tmp; + NTSTATUS status; - if (ctx->diff->fetch(ctx->diff, mem_ctx, key, &tmp) == -1) { - DEBUG(0, ("Out of memory!\n")); - return tdb_null; - } - if (tmp.dptr != NULL) { + status = dbwrap_fetch(ctx->diff, mem_ctx, key, &tmp); + + if (NT_STATUS_IS_OK(status)) { TDB_DATA_diff diff = unpack_diff(tmp); TDB_DATA ret = talloc_copy(mem_ctx, diff.nval); talloc_free(tmp.dptr); return ret; } - if (ctx->db->fetch(ctx->db, mem_ctx, key, &tmp) == -1) { - DEBUG(0, ("Out of memory!\n")); + status = dbwrap_fetch(ctx->db, mem_ctx, key, &tmp); + if (!NT_STATUS_IS_OK(status)) { return tdb_null; } @@ -387,10 +390,12 @@ static void edit_record(struct record* r) { static bool check_version(struct check_ctx* ctx) { static const char* key = "IDMAP_VERSION"; uint32_t version; - bool no_version = !dbwrap_fetch_uint32(ctx->db, key, &version); + NTSTATUS status; char action = 's'; struct check_actions* act = &ctx->action; - if (no_version) { + + status = dbwrap_fetch_uint32_bystring(ctx->db, key, &version); + if (!NT_STATUS_IS_OK(status)) { d_printf("No version number, assume 2\n"); action = get_action(&act->no_version, NULL, NULL); } else if (version != 2) { @@ -416,9 +421,11 @@ static bool check_version(struct check_ctx* ctx) { static void check_hwm(struct check_ctx* ctx, const char* key, uint32_t target) { uint32_t hwm; char action = 's'; - bool found = dbwrap_fetch_uint32(ctx->db, key, &hwm); + NTSTATUS status; struct check_actions* act = &ctx->action; - if (!found) { + + status = dbwrap_fetch_uint32_bystring(ctx->db, key, &hwm); + if (!NT_STATUS_IS_OK(status)) { d_printf("No %s should be %d\n", key, target); action = get_action(&act->invalid_hwm, NULL, NULL); } else if (target < hwm) { @@ -436,9 +443,16 @@ int traverse_check(struct db_record *rec, void* data) { struct check_ctx* ctx = (struct check_ctx*)data; struct check_actions* act = &ctx->action; TALLOC_CTX* mem = talloc_new(ctx->diff); - struct record* r = parse_record(mem, rec->key, rec->value); + TDB_DATA key; + TDB_DATA value; + struct record *r; char action = 's'; + key = dbwrap_record_get_key(rec); + value = dbwrap_record_get_value(rec); + + r = parse_record(mem, key, value); + if (is_invalid(r)) { action = get_action(&act->invalid_record, r, NULL); ctx->n_invalid_record++; @@ -470,10 +484,10 @@ int traverse_check(struct db_record *rec, void* data) { case 's': /* skip */ break; case 'd': /* delete */ - del_record(ctx, rec->key); + del_record(ctx, key); break; case 'f': /* add reverse mapping */ - add_record(ctx, rec->value, rec->key); + add_record(ctx, value, key); break; case 'e': /* edit */ edit_record(r); @@ -482,9 +496,9 @@ int traverse_check(struct db_record *rec, void* data) { action = get_action(&act->invalid_edit, r,NULL); continue; } - if (!tdb_data_equal(rec->key, r->key)) { + if (!tdb_data_equal(key, r->key)) { TDB_DATA oval = fetch_record(ctx, mem, r->key); - if (!is_empty(oval) && + if (!tdb_data_is_empty(oval) && !tdb_data_equal(oval, r->val)) { action = get_action(&act->record_exists, @@ -496,7 +510,7 @@ int traverse_check(struct db_record *rec, void* data) { } if (is_map(r)) { TDB_DATA okey = fetch_record(ctx, mem, r->val); - if (!is_empty(okey) && + if (!tdb_data_is_empty(okey) && !tdb_data_equal(okey, r->key)) { action = get_action(&act->record_exists, @@ -507,8 +521,8 @@ int traverse_check(struct db_record *rec, void* data) { continue; case 'o': /* overwrite */ adjust_hwm(ctx, r); - if (!tdb_data_equal(rec->key, r->key)) { - del_record(ctx, rec->key); + if (!tdb_data_equal(key, r->key)) { + del_record(ctx, key); } add_record(ctx, r->key, r->val); if (is_map(r)) { @@ -549,7 +563,7 @@ TDB_DATA talloc_copy(TALLOC_CTX* mem_ctx, TDB_DATA data) { } static bool is_cstr(TDB_DATA str) { - return !is_empty(str) && str.dptr[str.dsize-1] == '\0'; + return !tdb_data_is_empty(str) && str.dptr[str.dsize-1] == '\0'; } static bool parse_sid (TDB_DATA str, enum DT* type, struct dom_sid* sid) { @@ -646,35 +660,10 @@ struct record* reverse_record(struct record* in) /******************************************************************************/ -int interact_prompt(const char* msg, const char* acc, char def) { - struct termios old_tio, new_tio; - int c; - - tcgetattr(STDIN_FILENO, &old_tio); - new_tio=old_tio; - new_tio.c_lflag &=(~ICANON & ~ECHO); - tcsetattr(STDIN_FILENO, TCSANOW, &new_tio); - - do { - d_printf("%s? [%c]\n", msg, def); - fflush(stdout); - c = getchar(); - if (c == '\n') { - c = def; - break; - } - else if (strchr(acc, tolower(c)) != NULL) { - break; - } - d_printf("Invalid input '%c'\n", c); - } while(c != EOF); - tcsetattr(STDIN_FILENO, TCSANOW, &old_tio); - return c; -} char* print_data(TALLOC_CTX* mem_ctx, TDB_DATA d) { - if (!is_empty(d)) { + if (!tdb_data_is_empty(d)) { char* ret = NULL; cbuf* ost = cbuf_new(mem_ctx); int len = cbuf_print_quoted(ost, (const char*)d.dptr, d.dsize); @@ -701,76 +690,17 @@ TDB_DATA parse_data(TALLOC_CTX* mem_ctx, const char** ptr) { return ret; } -static const char* get_editor(void) { - static const char* editor = NULL; - if (editor == NULL) { - editor = getenv("VISUAL"); - if (editor == NULL) { - editor = getenv("EDITOR"); - } - if (editor == NULL) { - editor = "vi"; - } - } - return editor; -} - -char* interact_edit(TALLOC_CTX* mem_ctx, const char* str) { - char fname[] = "/tmp/net_idmap_check.XXXXXX"; - char buf[128]; - char* ret = NULL; - FILE* file; - - int fd = mkstemp(fname); - if (fd == -1) { - DEBUG(0, ("failed to mkstemp %s: %s\n", fname, - strerror(errno))); - return NULL; - } - - file = fdopen(fd, "w"); - if (!file) { - DEBUG(0, ("failed to open %s for writing: %s\n", fname, - strerror(errno))); - close(fd); - unlink(fname); - return NULL; - } - - fprintf(file, "%s", str); - fclose(file); - - snprintf(buf, sizeof(buf), "%s %s\n", get_editor(), fname); - if (system(buf) != 0) { - DEBUG(0, ("failed to start editor %s: %s\n", buf, - strerror(errno))); - unlink(fname); - return NULL; - } - - file = fopen(fname, "r"); - if (!file) { - DEBUG(0, ("failed to open %s for reading: %s\n", fname, - strerror(errno))); - unlink(fname); - return NULL; - } - while ( fgets(buf, sizeof(buf), file) ) { - ret = talloc_strdup_append(ret, buf); - } - fclose(file); - unlink(fname); - - return talloc_steal(mem_ctx, ret); -} - - static int traverse_print_diff(struct db_record *rec, void* data) { struct check_ctx* ctx = (struct check_ctx*)data; - TDB_DATA key = rec->key; - TDB_DATA_diff diff = unpack_diff(rec->value); + TDB_DATA key; + TDB_DATA value; + TDB_DATA_diff diff; TALLOC_CTX* mem = talloc_new(ctx->diff); + key = dbwrap_record_get_key(rec); + value = dbwrap_record_get_value(rec); + diff = unpack_diff(value); + DEBUG_DIFF(0, mem, "DIFF", key, diff.oval, diff.nval); talloc_free(mem); @@ -780,25 +710,34 @@ static int traverse_print_diff(struct db_record *rec, void* data) { static int traverse_commit(struct db_record *diff_rec, void* data) { struct check_ctx* ctx = (struct check_ctx*)data; - TDB_DATA_diff diff = unpack_diff(diff_rec->value); - TDB_DATA key = diff_rec->key; + TDB_DATA key; + TDB_DATA diff_value; + TDB_DATA_diff diff; + TDB_DATA value; TALLOC_CTX* mem = talloc_new(ctx->diff); int ret = -1; NTSTATUS status; struct check_actions* act = &ctx->action; + struct db_record* rec; + + key = dbwrap_record_get_key(diff_rec); + diff_value = dbwrap_record_get_value(diff_rec); + diff = unpack_diff(diff_value); - struct db_record* rec = ctx->db->fetch_locked(ctx->db, mem, key); + rec = dbwrap_fetch_locked(ctx->db, mem, key); if (rec == NULL) { goto done; - }; + } + + value = dbwrap_record_get_value(rec); - if (!tdb_data_equal(rec->value, diff.oval)) { + if (!tdb_data_equal(value, diff.oval)) { char action; d_printf("Warning: record has changed: %s\n" "expected: %s got %s\n", print_data(mem, key), print_data(mem, diff.oval), - print_data(mem, rec->value)); + print_data(mem, value)); action = get_action(&act->invalid_diff, NULL, NULL); if (action == 's') { @@ -811,10 +750,10 @@ static int traverse_commit(struct db_record *diff_rec, void* data) { DEBUG_DIFF(0, mem, "Commit", key, diff.oval, diff.nval); - if (is_empty(diff.nval)) { - status = rec->delete_rec(rec); + if (tdb_data_is_empty(diff.nval)) { + status = dbwrap_record_delete(rec); } else { - status = rec->store(rec, diff.nval, 0); + status = dbwrap_record_store(rec, diff.nval, 0); } if (!NT_STATUS_IS_OK(status)) { @@ -865,7 +804,8 @@ static bool check_open_db(struct check_ctx* ctx, const char* name, int oflags) } } - ctx->db = db_open(ctx, name, 0, TDB_DEFAULT, oflags, 0); + ctx->db = db_open(ctx, name, 0, TDB_DEFAULT, oflags, 0, + DBWRAP_LOCK_ORDER_1); if (ctx->db == NULL) { d_fprintf(stderr, _("Could not open idmap db (%s) for writing: %s\n"), @@ -914,15 +854,15 @@ static void check_summary(const struct check_ctx* ctx) } static bool check_transaction_start(struct check_ctx* ctx) { - return (ctx->db->transaction_start(ctx->db) == 0); + return (dbwrap_transaction_start(ctx->db) == 0); } static bool check_transaction_commit(struct check_ctx* ctx) { - return (ctx->db->transaction_commit(ctx->db) == 0); + return (dbwrap_transaction_commit(ctx->db) == 0); } static bool check_transaction_cancel(struct check_ctx* ctx) { - return (ctx->db->transaction_cancel(ctx->db) == 0); + return (dbwrap_transaction_cancel(ctx->db) == 0); } @@ -969,7 +909,7 @@ static bool check_commit(struct check_ctx* ctx) check_transaction_cancel(ctx); return false; } - if (ctx->opts.test) { //get_action? + if (ctx->opts.test) { /*get_action? */ return check_transaction_cancel(ctx); } else { return check_transaction_commit(ctx); |