static NTSTATUS tdbsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT *user) { NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data; TDB_DATA data, old_key; const char *prefix = USERPREFIX; int prefixlen = strlen (prefix); if (user==NULL) { DEBUG(0,("pdb_get_sampwent: SAM_ACCOUNT is NULL.\n")); return nt_status; } /* skip all non-USER entries (eg. RIDs) */ while ((tdb_state->key.dsize != 0) && (strncmp(tdb_state->key.dptr, prefix, prefixlen))) { old_key = tdb_state->key; /* increment to next in line */ tdb_state->key = tdb_nextkey(tdb_state->passwd_tdb, tdb_state->key); SAFE_FREE(old_key.dptr); } /* do we have an valid iteration pointer? */ if(tdb_state->passwd_tdb == NULL) { DEBUG(0,("pdb_get_sampwent: Bad TDB Context pointer.\n")); return nt_status; } data = tdb_fetch(tdb_state->passwd_tdb, tdb_state->key); if (!data.dptr) { DEBUG(5,("pdb_getsampwent: database entry not found.\n")); return nt_status; } /* unpack the buffer */ if (!init_sam_from_buffer(user, (unsigned char *)data.dptr, data.dsize)) { DEBUG(0,("pdb_getsampwent: Bad SAM_ACCOUNT entry returned from TDB!\n")); SAFE_FREE(data.dptr); return nt_status; } SAFE_FREE(data.dptr); old_key = tdb_state->key; /* increment to next in line */ tdb_state->key = tdb_nextkey(tdb_state->passwd_tdb, tdb_state->key); SAFE_FREE(old_key.dptr); return NT_STATUS_OK; }
pa_datum* pa_database_next(pa_database *db, const pa_datum *key, pa_datum *next, pa_datum *data) { TDB_DATA tdb_key, tdb_data; pa_assert(db); pa_assert(key); tdb_key = tdb_nextkey(MAKE_TDB_CONTEXT(db), *datum_to_tdb(&tdb_key, key)); if (!tdb_key.dptr) return NULL; if (data) { tdb_data = tdb_fetch(MAKE_TDB_CONTEXT(db), tdb_key); if (!tdb_data.dptr) { free(tdb_key.dptr); return NULL; } datum_from_tdb(data, &tdb_data); } datum_from_tdb(next, &tdb_key); return next; }
static PyObject *tdb_iter_next(PyTdbIteratorObject *self) { TDB_DATA current; PyObject *ret; if (self->current.dptr == NULL && self->current.dsize == 0) return NULL; current = self->current; self->current = tdb_nextkey(self->iteratee->ctx, self->current); ret = PyString_FromTDB_DATA(current); return ret; }
static void next_record(TDB_CONTEXT *the_tdb, TDB_DATA *pkey) { TDB_DATA dbuf; *pkey = tdb_nextkey(the_tdb, *pkey); dbuf = tdb_fetch(the_tdb, *pkey); if (!dbuf.dptr) terror("fetch failed"); else print_rec(the_tdb, *pkey, dbuf, NULL); }
static void next_record(TDB_CONTEXT *context, TDB_DATA *pkey) { TDB_DATA dbuf; *pkey = tdb_nextkey(context, *pkey); dbuf = tdb_fetch(context, *pkey); if (!dbuf.dptr) terror("fetch failed"); else /* printf("%s : %*.*s\n", k, (int)dbuf.dsize, (int)dbuf.dsize, dbuf.dptr); */ print_rec(context, *pkey, dbuf, NULL); }
static void next_record(struct tdb_context *the_tdb, TDB_DATA *pkey) { TDB_DATA dbuf; enum TDB_ERROR ecode; ecode = tdb_nextkey(the_tdb, pkey); if (!ecode) ecode = tdb_fetch(the_tdb, *pkey, &dbuf); if (ecode) terror(ecode, "fetch failed"); else print_rec(the_tdb, *pkey, dbuf, NULL); }
/* dump the current config */ static void config_dump(int p) { TDB_DATA data1, data2; /* looping using firstkey/nextkey is a pain ... */ for (data1 = tdb_firstkey(config_db); data1.dptr; data2 = data1, data1 = tdb_nextkey(config_db, data2), free(data2.dptr)) { pprintf(p, "%s = %s\n", data1.dptr, config_get_tmp(data1.dptr)); } }
static PyObject *obj_nextkey(PyTdbObject *self, PyObject *args) { TDB_DATA key; PyObject *py_key; PyErr_TDB_RAISE_IF_CLOSED(self); if (!PyArg_ParseTuple(args, "O", &py_key)) return NULL; key = PyString_AsTDB_DATA(py_key); if (!key.dptr) return NULL; return PyString_FromTDB_DATA(tdb_nextkey(self->ctx, key)); }
static void compare_db(void) { TDB_DATA d, key, nextkey; datum gd, gkey, gnextkey; key = tdb_firstkey(db); while (key.dptr) { d = tdb_fetch(db, key); gkey.dptr = key.dptr; gkey.dsize = key.dsize; gd = gdbm_fetch(gdbm, gkey); if (!gd.dptr) fatal("key not in gdbm"); if (gd.dsize != d.dsize) fatal("data sizes differ"); if (memcmp(gd.dptr, d.dptr, d.dsize)) { fatal("data differs"); } nextkey = tdb_nextkey(db, key); free(key.dptr); free(d.dptr); free(gd.dptr); key = nextkey; } gkey = gdbm_firstkey(gdbm); while (gkey.dptr) { gd = gdbm_fetch(gdbm, gkey); key.dptr = gkey.dptr; key.dsize = gkey.dsize; d = tdb_fetch(db, key); if (!d.dptr) fatal("key not in db"); if (d.dsize != gd.dsize) fatal("data sizes differ"); if (memcmp(d.dptr, gd.dptr, gd.dsize)) { fatal("data differs"); } gnextkey = gdbm_nextkey(gdbm, gkey); free(gkey.dptr); free(gd.dptr); free(d.dptr); gkey = gnextkey; } }
int main(int argc, char *argv[]) { TDB_DATA key; TDB_CONTEXT *tdb; if (argc != 2) barf("Usage: xs_tdb_dump <tdbfile>"); tdb = tdb_open(talloc_strdup(NULL, argv[1]), 0, 0, O_RDONLY, 0); if (!tdb) barf_perror("Could not open %s", argv[1]); key = tdb_firstkey(tdb); while (key.dptr) { TDB_DATA data; struct record_hdr *hdr; data = tdb_fetch(tdb, key); hdr = (void *)data.dptr; if (data.dsize < sizeof(*hdr)) fprintf(stderr, "%.*s: BAD truncated\n", (int)key.dsize, key.dptr); else if (data.dsize != total_size(hdr)) fprintf(stderr, "%.*s: BAD length %i for %i/%i/%i (%i)\n", (int)key.dsize, key.dptr, (int)data.dsize, hdr->num_perms, hdr->datalen, hdr->childlen, total_size(hdr)); else { unsigned int i; char *p; printf("%.*s: ", (int)key.dsize, key.dptr); for (i = 0; i < hdr->num_perms; i++) printf("%s%c%i", i == 0 ? "" : ",", perm_to_char(hdr->perms[i].perms), hdr->perms[i].id); p = (void *)&hdr->perms[hdr->num_perms]; printf(" %.*s\n", hdr->datalen, p); p += hdr->datalen; for (i = 0; i < hdr->childlen; i += strlen(p+i)+1) printf("\t-> %s\n", p+i); } key = tdb_nextkey(tdb, key); } return 0; }
PyObject *py_tdb_hnd_next_key(PyObject *self, PyObject *py_oldkey) { tdb_hnd_object *obj = (tdb_hnd_object *)self; TDB_DATA key, oldkey; if (!obj->tdb) { PyErr_SetString(py_tdb_error, "tdb object has been closed"); return NULL; } if (!PyArg_Parse(py_oldkey, "s#", &oldkey.dptr, &oldkey.dsize)) return NULL; key = tdb_nextkey(obj->tdb, oldkey); return Py_BuildValue("s#", key.dptr, key.dsize); }
static PyObject *pytdb_list_keys(PyTDB *self, PyObject *args, PyObject *kwds) { PyObject *result = PyList_New(0); TDB_DATA first = tdb_firstkey(self->context); TDB_DATA next; PyObject *tmp; while(first.dptr) { tmp = PyString_FromStringAndSize((char *)first.dptr, first.dsize); if(!tmp) return NULL; PyList_Append(result, tmp); Py_DECREF(tmp); next = tdb_nextkey(self->context, first); free(first.dptr); first = next; }; return result; }
/* * A simple interator function */ struct dir_info *e2fsck_dir_info_iter(e2fsck_t ctx, struct dir_info_iter *iter) { TDB_DATA data, key; struct dir_info_db *db = ctx->dir_info; struct dir_info_ent *buf; static struct dir_info ret_dir_info; if (!ctx->dir_info || !iter) return 0; if (db->tdb) { if (iter->tdb_iter.dptr == 0) return 0; key = iter->tdb_iter; data = tdb_fetch(db->tdb, key); if (!data.dptr) { printf("iter fetch failed: %s\n", tdb_errorstr(db->tdb)); return 0; } buf = (struct dir_info_ent *) data.dptr; ret_dir_info.ino = *((ext2_ino_t *) iter->tdb_iter.dptr); ret_dir_info.dotdot = buf->dotdot; ret_dir_info.parent = buf->parent; iter->tdb_iter = tdb_nextkey(db->tdb, key); free(key.dptr); free(data.dptr); return &ret_dir_info; } if (iter->i >= ctx->dir_info->count) return 0; #ifdef DIRINFO_DEBUG printf("iter(%d, %d, %d)...", ctx->dir_info->array[iter->i].ino, ctx->dir_info->array[iter->i].dotdot, ctx->dir_info->array[iter->i].parent); #endif ctx->dir_info->last_lookup = ctx->dir_info->array + iter->i++; return(ctx->dir_info->last_lookup); }
signed pa_database_size(pa_database *db) { TDB_DATA tdb_key; unsigned n = 0; pa_assert(db); /* This sucks */ tdb_key = tdb_firstkey(MAKE_TDB_CONTEXT(db)); while (tdb_key.dptr) { TDB_DATA next; n++; next = tdb_nextkey(MAKE_TDB_CONTEXT(db), tdb_key); free(tdb_key.dptr); tdb_key = next; } return (signed) n; }
/* list the rights for an account. This involves traversing the database */ NTSTATUS privilege_enum_account_rights(DOM_SID *sid, uint32 *count, char ***rights) { TDB_DATA key, nextkey; char *right; if (!tdb) { return NT_STATUS_INTERNAL_ERROR; } *rights = NULL; *count = 0; for (key = tdb_firstkey(tdb); key.dptr; key = nextkey) { nextkey = tdb_nextkey(tdb, key); right = key.dptr; if (privilege_sid_has_right(sid, right)) { (*rights) = (char **)Realloc(*rights,sizeof(char *) * ((*count)+1)); if (! *rights) { safe_free(nextkey.dptr); free(key.dptr); return NT_STATUS_NO_MEMORY; } (*rights)[*count] = strdup(right); (*count)++; } free(key.dptr); } return NT_STATUS_OK; }
/**************************************************************************** Open the group mapping tdb. ****************************************************************************/ NTSTATUS samba3_read_grouptdb(const char *file, TALLOC_CTX *ctx, struct samba3_groupdb *db) { int32_t vers_id; TDB_DATA kbuf, dbuf, newkey; int ret; TDB_CONTEXT *tdb; tdb = tdb_open(file, 0, TDB_DEFAULT, O_RDONLY, 0600); if (!tdb) { DEBUG(0,("Failed to open group mapping database\n")); return NT_STATUS_UNSUCCESSFUL; } /* Cope with byte-reversed older versions of the db. */ vers_id = tdb_fetch_int32(tdb, "INFO/version"); if ((vers_id == DATABASE_VERSION_V1) || (IREV(vers_id) == DATABASE_VERSION_V1)) { /* Written on a bigendian machine with old fetch_int code. Save as le. */ vers_id = DATABASE_VERSION_V2; } if (vers_id != DATABASE_VERSION_V2) { DEBUG(0, ("Group database version mismatch: %d\n", vers_id)); return NT_STATUS_UNSUCCESSFUL; } db->groupmappings = NULL; db->groupmap_count = 0; db->aliases = NULL; db->alias_count = 0; for (kbuf = tdb_firstkey(tdb); kbuf.dptr; newkey = tdb_nextkey(tdb, kbuf), free(kbuf.dptr), kbuf=newkey) { struct samba3_groupmapping map; const char *k = (const char *)kbuf.dptr; if (strncmp(k, GROUP_PREFIX, strlen(GROUP_PREFIX)) == 0) { dbuf = tdb_fetch(tdb, kbuf); if (!dbuf.dptr) continue; ZERO_STRUCT(map); map.sid = dom_sid_parse_talloc(ctx, k+strlen(GROUP_PREFIX)); ret = tdb_unpack(tdb, (char *)dbuf.dptr, dbuf.dsize, "dd", &map.gid, &map.sid_name_use); if ( ret == -1 ) { DEBUG(3,("enum_group_mapping: tdb_unpack failure\n")); continue; } map.nt_name = talloc_strdup(ctx, (const char *)(dbuf.dptr+ret)); map.comment = talloc_strdup(ctx, (const char *)(dbuf.dptr+ret+strlen(map.nt_name))); db->groupmappings = talloc_realloc(ctx, db->groupmappings, struct samba3_groupmapping, db->groupmap_count+1); if (!db->groupmappings) return NT_STATUS_NO_MEMORY; db->groupmappings[db->groupmap_count] = map; db->groupmap_count++; } else if (strncmp(k, MEMBEROF_PREFIX, strlen(MEMBEROF_PREFIX)) == 0)
int main(int argc, char *argv[]) { unsigned int i, j; int num; struct trav_data td; TDB_DATA k; struct tdb_context *tdb; union tdb_attribute seed_attr; enum TDB_ERROR ecode; int flags[] = { TDB_INTERNAL, TDB_DEFAULT, TDB_NOMMAP, TDB_INTERNAL|TDB_CONVERT, TDB_CONVERT, TDB_NOMMAP|TDB_CONVERT }; seed_attr.base.attr = TDB_ATTRIBUTE_SEED; seed_attr.base.next = &tap_log_attr; seed_attr.seed.seed = 6334326220117065685ULL; plan_tests(sizeof(flags) / sizeof(flags[0]) * (NUM_RECORDS*6 + (NUM_RECORDS-1)*3 + 22) + 1); for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) { tdb = tdb_open("run-traverse.tdb", flags[i], O_RDWR|O_CREAT|O_TRUNC, 0600, &seed_attr); ok1(tdb); if (!tdb) continue; ok1(tdb_firstkey(tdb, &k) == TDB_ERR_NOEXIST); /* One entry... */ k.dptr = (unsigned char *)# k.dsize = sizeof(num); num = 0; ok1(tdb_store(tdb, k, k, TDB_INSERT) == 0); ok1(tdb_firstkey(tdb, &k) == TDB_SUCCESS); ok1(k.dsize == sizeof(num)); ok1(memcmp(k.dptr, &num, sizeof(num)) == 0); ok1(tdb_nextkey(tdb, &k) == TDB_ERR_NOEXIST); /* Two entries. */ k.dptr = (unsigned char *)# k.dsize = sizeof(num); num = 1; ok1(tdb_store(tdb, k, k, TDB_INSERT) == 0); ok1(tdb_firstkey(tdb, &k) == TDB_SUCCESS); ok1(k.dsize == sizeof(num)); memcpy(&num, k.dptr, sizeof(num)); ok1(num == 0 || num == 1); ok1(tdb_nextkey(tdb, &k) == TDB_SUCCESS); ok1(k.dsize == sizeof(j)); memcpy(&j, k.dptr, sizeof(j)); ok1(j == 0 || j == 1); ok1(j != num); ok1(tdb_nextkey(tdb, &k) == TDB_ERR_NOEXIST); /* Clean up. */ k.dptr = (unsigned char *)# k.dsize = sizeof(num); num = 0; ok1(tdb_delete(tdb, k) == 0); num = 1; ok1(tdb_delete(tdb, k) == 0); /* Now lots of records. */ ok1(store_records(tdb)); td.calls = 0; num = tdb_traverse(tdb, trav, &td); ok1(num == NUM_RECORDS); ok1(td.calls == NUM_RECORDS); /* Simple loop should match tdb_traverse */ for (j = 0, ecode = tdb_firstkey(tdb, &k); j < td.calls; j++) { int val; ok1(ecode == TDB_SUCCESS); ok1(k.dsize == sizeof(val)); memcpy(&val, k.dptr, k.dsize); ok1(td.records[j] == val); ecode = tdb_nextkey(tdb, &k); } /* But arbitrary orderings should work too. */ for (j = td.calls-1; j > 0; j--) { k.dptr = (unsigned char *)&td.records[j-1]; k.dsize = sizeof(td.records[j-1]); k = dup_key(k); ok1(tdb_nextkey(tdb, &k) == TDB_SUCCESS); ok1(k.dsize == sizeof(td.records[j])); ok1(memcmp(k.dptr, &td.records[j], k.dsize) == 0); free(k.dptr); } /* Even delete should work. */ for (j = 0, ecode = tdb_firstkey(tdb, &k); ecode != TDB_ERR_NOEXIST; j++) { ok1(ecode == TDB_SUCCESS); ok1(k.dsize == 4); ok1(tdb_delete(tdb, k) == 0); ecode = tdb_nextkey(tdb, &k); } diag("delete using first/nextkey gave %u of %u records", j, NUM_RECORDS); ok1(j == NUM_RECORDS); tdb_close(tdb); } ok1(tap_log_messages == 0); return exit_status(); }
static NTSTATUS printing_migrate_internal(struct net_context *c, const struct dom_sid *domain_sid, const char *domain_name, struct cli_state *cli, struct rpc_pipe_client *winreg_pipe, TALLOC_CTX *mem_ctx, int argc, const char **argv) { TALLOC_CTX *tmp_ctx; TDB_CONTEXT *tdb; TDB_DATA kbuf, newkey, dbuf; NTSTATUS status; tmp_ctx = talloc_new(mem_ctx); if (tmp_ctx == NULL) { return NT_STATUS_NO_MEMORY; } tdb = tdb_open_log(argv[0], 0, TDB_DEFAULT, O_RDONLY, 0600); if (tdb == NULL) { d_fprintf(stderr, _("failed to open tdb file: %s\n"), argv[0]); status = NT_STATUS_NO_SUCH_FILE; goto done; } for (kbuf = tdb_firstkey(tdb); kbuf.dptr; newkey = tdb_nextkey(tdb, kbuf), free(kbuf.dptr), kbuf = newkey) { dbuf = tdb_fetch(tdb, kbuf); if (!dbuf.dptr) { continue; } if (strncmp((const char *) kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) == 0) { printing_tdb_migrate_form(tmp_ctx, winreg_pipe, (const char *) kbuf.dptr + strlen(FORMS_PREFIX), dbuf.dptr, dbuf.dsize); SAFE_FREE(dbuf.dptr); continue; } if (strncmp((const char *) kbuf.dptr, DRIVERS_PREFIX, strlen(DRIVERS_PREFIX)) == 0) { printing_tdb_migrate_driver(tmp_ctx, winreg_pipe, (const char *) kbuf.dptr + strlen(DRIVERS_PREFIX), dbuf.dptr, dbuf.dsize); SAFE_FREE(dbuf.dptr); continue; } if (strncmp((const char *) kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) == 0) { printing_tdb_migrate_printer(tmp_ctx, winreg_pipe, (const char *) kbuf.dptr + strlen(PRINTERS_PREFIX), dbuf.dptr, dbuf.dsize); SAFE_FREE(dbuf.dptr); continue; } SAFE_FREE(dbuf.dptr); } for (kbuf = tdb_firstkey(tdb); kbuf.dptr; newkey = tdb_nextkey(tdb, kbuf), free(kbuf.dptr), kbuf = newkey) { dbuf = tdb_fetch(tdb, kbuf); if (!dbuf.dptr) { continue; } if (strncmp((const char *) kbuf.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX)) == 0) { printing_tdb_migrate_secdesc(tmp_ctx, winreg_pipe, (const char *) kbuf.dptr + strlen(SECDESC_PREFIX), dbuf.dptr, dbuf.dsize); SAFE_FREE(dbuf.dptr); continue; } SAFE_FREE(dbuf.dptr); } status = NT_STATUS_OK; done: talloc_free(tmp_ctx); return status; }
static int net_printing_dump(struct net_context *c, int argc, const char **argv) { int ret = -1; TALLOC_CTX *ctx = talloc_stackframe(); TDB_CONTEXT *tdb; TDB_DATA kbuf, newkey, dbuf; if (argc < 1 || c->display_usage) { d_fprintf(stderr, "%s\nnet printing dump <file.tdb>\n", _("Usage:")); goto done; } tdb = tdb_open_log(argv[0], 0, TDB_DEFAULT, O_RDONLY, 0600); if (!tdb) { d_fprintf(stderr, _("failed to open tdb file: %s\n"), argv[0]); goto done; } for (kbuf = tdb_firstkey(tdb); kbuf.dptr; newkey = tdb_nextkey(tdb, kbuf), free(kbuf.dptr), kbuf=newkey) { dbuf = tdb_fetch(tdb, kbuf); if (!dbuf.dptr) { continue; } if (strncmp((const char *)kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) == 0) { dump_form(ctx, (const char *)kbuf.dptr+strlen(FORMS_PREFIX), dbuf.dptr, dbuf.dsize); SAFE_FREE(dbuf.dptr); continue; } if (strncmp((const char *)kbuf.dptr, DRIVERS_PREFIX, strlen(DRIVERS_PREFIX)) == 0) { dump_driver(ctx, (const char *)kbuf.dptr+strlen(DRIVERS_PREFIX), dbuf.dptr, dbuf.dsize); SAFE_FREE(dbuf.dptr); continue; } if (strncmp((const char *)kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) == 0) { dump_printer(ctx, (const char *)kbuf.dptr+strlen(PRINTERS_PREFIX), dbuf.dptr, dbuf.dsize); SAFE_FREE(dbuf.dptr); continue; } if (strncmp((const char *)kbuf.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX)) == 0) { dump_sd(ctx, (const char *)kbuf.dptr+strlen(SECDESC_PREFIX), dbuf.dptr, dbuf.dsize); SAFE_FREE(dbuf.dptr); continue; } } ret = 0; done: talloc_free(ctx); return ret; }
static NTSTATUS migrate_internal(TALLOC_CTX *mem_ctx, const char *tdb_path, struct rpc_pipe_client *winreg_pipe) { const char *backup_suffix = ".bak"; TDB_DATA kbuf, newkey, dbuf; TDB_CONTEXT *tdb; NTSTATUS status; int rc; tdb = tdb_open_log(tdb_path, 0, TDB_DEFAULT, O_RDONLY, 0600); if (tdb == NULL && errno == ENOENT) { /* if we have no printers database then migration is considered successful */ DEBUG(4, ("No printers database to migrate in %s\n", tdb_path)); return NT_STATUS_OK; } if (tdb == NULL) { DEBUG(2, ("Failed to open tdb file: %s\n", tdb_path)); return NT_STATUS_NO_SUCH_FILE; } for (kbuf = tdb_firstkey(tdb); kbuf.dptr; newkey = tdb_nextkey(tdb, kbuf), free(kbuf.dptr), kbuf = newkey) { dbuf = tdb_fetch(tdb, kbuf); if (!dbuf.dptr) { continue; } if (strncmp((const char *) kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) == 0) { status = printing_tdb_migrate_form(mem_ctx, winreg_pipe, (const char *) kbuf.dptr + strlen(FORMS_PREFIX), dbuf.dptr, dbuf.dsize); SAFE_FREE(dbuf.dptr); if (!NT_STATUS_IS_OK(status)) { tdb_close(tdb); return status; } continue; } if (strncmp((const char *) kbuf.dptr, DRIVERS_PREFIX, strlen(DRIVERS_PREFIX)) == 0) { status = printing_tdb_migrate_driver(mem_ctx, winreg_pipe, (const char *) kbuf.dptr + strlen(DRIVERS_PREFIX), dbuf.dptr, dbuf.dsize, false); SAFE_FREE(dbuf.dptr); if (!NT_STATUS_IS_OK(status)) { tdb_close(tdb); return status; } continue; } if (strncmp((const char *) kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) == 0) { const char *printer_name = (const char *)(kbuf.dptr + strlen(PRINTERS_PREFIX)); status = printing_tdb_migrate_printer(mem_ctx, winreg_pipe, printer_name, dbuf.dptr, dbuf.dsize, false); SAFE_FREE(dbuf.dptr); if (!NT_STATUS_IS_OK(status)) { tdb_close(tdb); return status; } continue; } SAFE_FREE(dbuf.dptr); } for (kbuf = tdb_firstkey(tdb); kbuf.dptr; newkey = tdb_nextkey(tdb, kbuf), free(kbuf.dptr), kbuf = newkey) { dbuf = tdb_fetch(tdb, kbuf); if (!dbuf.dptr) { continue; } if (strncmp((const char *) kbuf.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX)) == 0) { const char *secdesc_name = (const char *)(kbuf.dptr + strlen(SECDESC_PREFIX)); status = printing_tdb_migrate_secdesc(mem_ctx, winreg_pipe, secdesc_name, dbuf.dptr, dbuf.dsize); SAFE_FREE(dbuf.dptr); if (NT_STATUS_EQUAL(status, werror_to_ntstatus(WERR_FILE_NOT_FOUND))) { DEBUG(2, ("Skipping secdesc migration for non-existent " "printer: %s\n", secdesc_name)); } else if (!NT_STATUS_IS_OK(status)) { tdb_close(tdb); return status; } continue; } SAFE_FREE(dbuf.dptr); } tdb_close(tdb); rc = rename_file_with_suffix(mem_ctx, tdb_path, backup_suffix); if (rc != 0) { DEBUG(0, ("Error moving tdb to '%s%s'\n", tdb_path, backup_suffix)); } return NT_STATUS_OK; }
static BOOL tdbsam_convert(TDB_CONTEXT *pdb_tdb, tdbsamver_t from) { const char * vstring = TDBSAM_VERSION_STRING; SAM_ACCOUNT *user = NULL; const char *prefix = USERPREFIX; TDB_DATA data, key, old_key; uint8 *buf = NULL; BOOL ret; if (pdb_tdb == NULL) { DEBUG(0,("tdbsam_convert: Bad TDB Context pointer.\n")); return False; } /* handle a Samba upgrade */ tdb_lock_bystring(pdb_tdb, vstring, 0); if (!NT_STATUS_IS_OK(pdb_init_sam(&user))) { DEBUG(0,("tdbsam_convert: cannot initialized a SAM_ACCOUNT.\n")); return False; } /* Enumerate all records and convert them */ key = tdb_firstkey(pdb_tdb); while (key.dptr) { /* skip all non-USER entries (eg. RIDs) */ while ((key.dsize != 0) && (strncmp(key.dptr, prefix, strlen (prefix)))) { old_key = key; /* increment to next in line */ key = tdb_nextkey(pdb_tdb, key); SAFE_FREE(old_key.dptr); } if (key.dptr) { /* read from tdbsam */ data = tdb_fetch(pdb_tdb, key); if (!data.dptr) { DEBUG(0,("tdbsam_convert: database entry not found: %s.\n",key.dptr)); return False; } if (!NT_STATUS_IS_OK(pdb_reset_sam(user))) { DEBUG(0,("tdbsam_convert: cannot reset SAM_ACCOUNT.\n")); SAFE_FREE(data.dptr); return False; } /* unpack the buffer from the former format */ DEBUG(10,("tdbsam_convert: Try unpacking a record with (key:%s) (version:%d)\n", key.dptr, from)); switch (from) { case 0: ret = init_sam_from_buffer_v0(user, (uint8 *)data.dptr, data.dsize); break; case 1: ret = init_sam_from_buffer_v1(user, (uint8 *)data.dptr, data.dsize); break; default: /* unknown tdbsam version */ ret = False; } if (!ret) { DEBUG(0,("tdbsam_convert: Bad SAM_ACCOUNT entry returned from TDB (key:%s) (version:%d)\n", key.dptr, from)); SAFE_FREE(data.dptr); return False; } /* pack from the buffer into the new format */ DEBUG(10,("tdbsam_convert: Try packing a record (key:%s) (version:%d)\n", key.dptr, from)); if ((data.dsize=init_buffer_from_sam (&buf, user, False)) == -1) { DEBUG(0,("tdbsam_convert: cannot pack the SAM_ACCOUNT into the new format\n")); SAFE_FREE(data.dptr); return False; } data.dptr = (char *)buf; /* Store the buffer inside the TDBSAM */ if (tdb_store(pdb_tdb, key, data, TDB_MODIFY) != TDB_SUCCESS) { DEBUG(0,("tdbsam_convert: cannot store the SAM_ACCOUNT (key:%s) in new format\n",key.dptr)); SAFE_FREE(data.dptr); return False; } SAFE_FREE(data.dptr); /* increment to next in line */ old_key = key; key = tdb_nextkey(pdb_tdb, key); SAFE_FREE(old_key.dptr); } } pdb_free_sam(&user); /* upgrade finished */ tdb_store_int32(pdb_tdb, vstring, TDBSAM_VERSION); tdb_unlock_bystring(pdb_tdb, vstring); return(True); }
int main(int argc, char *argv[]) { int c,force = 0; TDB_CONTEXT *tdb; TDB_DATA key, data; io_channel channel; errcode_t retval; int mount_flags; blk64_t blk_num; char *device_name, *tdb_file; io_manager manager = unix_io_manager; #ifdef ENABLE_NLS setlocale(LC_MESSAGES, ""); setlocale(LC_CTYPE, ""); bindtextdomain(NLS_CAT_NAME, LOCALEDIR); textdomain(NLS_CAT_NAME); #endif add_error_table(&et_ext2_error_table); prg_name = argv[0]; while((c = getopt(argc, argv, "f")) != EOF) { switch (c) { case 'f': force = 1; break; default: usage(prg_name); } } if (argc != optind+2) usage(prg_name); tdb_file = argv[optind]; device_name = argv[optind+1]; tdb = tdb_open(tdb_file, 0, 0, O_RDONLY, 0600); if (!tdb) { com_err(prg_name, errno, _("Failed tdb_open %s\n"), tdb_file); exit(1); } retval = ext2fs_check_if_mounted(device_name, &mount_flags); if (retval) { com_err(prg_name, retval, _("Error while determining whether " "%s is mounted.\n"), device_name); exit(1); } if (mount_flags & EXT2_MF_MOUNTED) { com_err(prg_name, retval, _("e2undo should only be run on " "unmounted file system\n")); exit(1); } retval = manager->open(device_name, IO_FLAG_EXCLUSIVE | IO_FLAG_RW, &channel); if (retval) { com_err(prg_name, retval, _("Failed to open %s\n"), device_name); exit(1); } if (!force && check_filesystem(tdb, channel)) { exit(1); } if (set_blk_size(tdb, channel)) { exit(1); } for (key = tdb_firstkey(tdb); key.dptr; key = tdb_nextkey(tdb, key)) { if (!strcmp((char *) key.dptr, (char *) mtime_key) || !strcmp((char *) key.dptr, (char *) uuid_key) || !strcmp((char *) key.dptr, (char *) blksize_key)) { continue; } data = tdb_fetch(tdb, key); if (!data.dptr) { com_err(prg_name, 0, _("Failed tdb_fetch %s\n"), tdb_errorstr(tdb)); exit(1); } blk_num = *(unsigned long *)key.dptr; printf(_("Replayed transaction of size %zd at location %llu\n"), data.dsize, blk_num); retval = io_channel_write_blk64(channel, blk_num, -data.dsize, data.dptr); if (retval == -1) { com_err(prg_name, retval, _("Failed write %s\n"), strerror(errno)); exit(1); } } io_channel_close(channel); tdb_close(tdb); return 0; }
NTSTATUS samba3_read_regdb ( const char *fn, TALLOC_CTX *ctx, struct samba3_regdb *db ) { uint32_t vers_id; TDB_CONTEXT *tdb; TDB_DATA kbuf, vbuf; /* placeholder tdb; reinit upon startup */ if ( !(tdb = tdb_open(fn, 0, TDB_DEFAULT, O_RDONLY, 0600)) ) { DEBUG(0, ("Unable to open registry database %s\n", fn)); return NT_STATUS_UNSUCCESSFUL; } vers_id = tdb_fetch_int32(tdb, "INFO/version"); db->key_count = 0; db->keys = NULL; if (vers_id != -1 && vers_id >= REGVER_V1) { DEBUG(0, ("Registry version mismatch: %d\n", vers_id)); return NT_STATUS_UNSUCCESSFUL; } for (kbuf = tdb_firstkey(tdb); kbuf.dptr; kbuf = tdb_nextkey(tdb, kbuf)) { uint32_t len; int i; struct samba3_regkey key; char *skey; if (strncmp((char *)kbuf.dptr, VALUE_PREFIX, strlen(VALUE_PREFIX)) == 0) continue; vbuf = tdb_fetch(tdb, kbuf); key.name = talloc_strdup(ctx, (char *)kbuf.dptr); len = tdb_unpack(tdb, (char *)vbuf.dptr, vbuf.dsize, "d", &key.subkey_count); key.value_count = 0; key.values = NULL; key.subkeys = talloc_array(ctx, char *, key.subkey_count); for (i = 0; i < key.subkey_count; i++) { fstring tmp; len += tdb_unpack( tdb, (char *)vbuf.dptr+len, vbuf.dsize-len, "f", tmp ); key.subkeys[i] = talloc_strdup(ctx, tmp); } skey = talloc_asprintf(ctx, "%s/%s", VALUE_PREFIX, kbuf.dptr ); vbuf = tdb_fetch_bystring( tdb, skey ); if ( vbuf.dptr ) { regdb_unpack_values( tdb, ctx, &key, vbuf ); } db->keys = talloc_realloc(ctx, db->keys, struct samba3_regkey, db->key_count+1); db->keys[db->key_count] = key; db->key_count++; } tdb_close(tdb); return NT_STATUS_OK; }