/* parse options */ static isc_result_t parse_options(struct dlz_bind9_data *state, unsigned int argc, char *argv[], struct b9_options *options) { int opt; poptContext pc; struct poptOption long_options[] = { { "url", 'H', POPT_ARG_STRING, &options->url, 0, "database URL", "URL" }, { NULL } }; struct poptOption **popt_options; int ret; fault_setup_disable(); popt_options = ldb_module_popt_options(state->samdb); (*popt_options) = long_options; ret = ldb_modules_hook(state->samdb, LDB_MODULE_HOOK_CMDLINE_OPTIONS); if (ret != LDB_SUCCESS) { state->log(ISC_LOG_ERROR, "dlz samba: failed cmdline hook"); return ISC_R_FAILURE; } pc = poptGetContext("dlz_bind9", argc, (const char **)argv, *popt_options, POPT_CONTEXT_KEEP_FIRST); while ((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { default: state->log(ISC_LOG_ERROR, "dlz samba: Invalid option %s: %s", poptBadOption(pc, 0), poptStrerror(opt)); return ISC_R_FAILURE; } } ret = ldb_modules_hook(state->samdb, LDB_MODULE_HOOK_CMDLINE_PRECONNECT); if (ret != LDB_SUCCESS) { state->log(ISC_LOG_ERROR, "dlz samba: failed cmdline preconnect"); return ISC_R_FAILURE; } return ISC_R_SUCCESS; }
int main(int argc, char *argv[]) { bool emergency = false; int c, rc; char *fname; struct ldb_dn *dn = NULL; ldb = ldb_init(NULL, NULL); if (ldb == NULL) { fprintf(stderr, "ldb: ldb_init failed()"); exit(1); } rc = ldb_modules_hook(ldb, LDB_MODULE_HOOK_CMDLINE_PRECONNECT); if (rc != LDB_SUCCESS) { fprintf(stderr, "ldb: failed to run preconnect hooks (needed to get Samba LDIF handlers): %s\n", ldb_strerror(rc)); exit(1); } if (argc < 2) { printf("Usage: ldbdump <fname>\n"); exit(1); } while ((c = getopt( argc, argv, "hd:ec")) != -1) { switch (c) { case 'h': usage(); exit( 0); case 'd': dn = ldb_dn_new(ldb, ldb, optarg); if (!dn) { fprintf(stderr, "ldb failed to parse %s as a DN\n", optarg); exit(1); } break; case 'e': emergency = true; break; case 'i': show_index = true; break; case 'c': validate_contents = true; break; default: usage(); exit( 1); } } fname = argv[optind]; return dump_tdb(fname, dn, emergency); }
/* called to initialise the driver */ _PUBLIC_ isc_result_t dlz_create(const char *dlzname, unsigned int argc, char *argv[], void **dbdata, ...) { struct dlz_bind9_data *state; const char *helper_name; va_list ap; isc_result_t result; TALLOC_CTX *tmp_ctx; int ret; struct ldb_dn *dn; struct b9_options options; ZERO_STRUCT(options); state = talloc_zero(NULL, struct dlz_bind9_data); if (state == NULL) { return ISC_R_NOMEMORY; } tmp_ctx = talloc_new(state); /* fill in the helper functions */ va_start(ap, dbdata); while ((helper_name = va_arg(ap, const char *)) != NULL) { b9_add_helper(state, helper_name, va_arg(ap, void*)); } va_end(ap); state->ev_ctx = s4_event_context_init(state); if (state->ev_ctx == NULL) { result = ISC_R_NOMEMORY; goto failed; } state->samdb = ldb_init(state, state->ev_ctx); if (state->samdb == NULL) { state->log(ISC_LOG_ERROR, "samba_dlz: Failed to create ldb"); result = ISC_R_FAILURE; goto failed; } result = parse_options(state, argc, argv, &options); if (result != ISC_R_SUCCESS) { goto failed; } state->lp = loadparm_init_global(true); if (state->lp == NULL) { result = ISC_R_NOMEMORY; goto failed; } if (options.url == NULL) { options.url = talloc_asprintf(tmp_ctx, "ldapi://%s", lpcfg_private_path(tmp_ctx, state->lp, "ldap_priv/ldapi")); if (options.url == NULL) { result = ISC_R_NOMEMORY; goto failed; } } ret = ldb_connect(state->samdb, options.url, 0, NULL); if (ret != LDB_SUCCESS) { state->log(ISC_LOG_ERROR, "samba_dlz: Failed to connect to %s - %s", options.url, ldb_errstring(state->samdb)); result = ISC_R_FAILURE; goto failed; } ret = ldb_modules_hook(state->samdb, LDB_MODULE_HOOK_CMDLINE_POSTCONNECT); if (ret != LDB_SUCCESS) { state->log(ISC_LOG_ERROR, "samba_dlz: Failed postconnect for %s - %s", options.url, ldb_errstring(state->samdb)); result = ISC_R_FAILURE; goto failed; } dn = ldb_get_default_basedn(state->samdb); if (dn == NULL) { state->log(ISC_LOG_ERROR, "samba_dlz: Unable to get basedn for %s - %s", options.url, ldb_errstring(state->samdb)); result = ISC_R_FAILURE; goto failed; } state->log(ISC_LOG_INFO, "samba_dlz: started for DN %s", ldb_dn_get_linearized(dn)); *dbdata = state; talloc_free(tmp_ctx); return ISC_R_SUCCESS; failed: talloc_free(state); return result; }
/** process command line options */ struct ldb_cmdline *ldb_cmdline_process(struct ldb_context *ldb, int argc, const char **argv, void (*usage)(struct ldb_context *)) { struct ldb_cmdline *ret=NULL; poptContext pc; int num_options = 0; int opt; unsigned int flags = 0; int rc; struct poptOption **popt_options; /* make the ldb utilities line buffered */ setlinebuf(stdout); ret = talloc_zero(ldb, struct ldb_cmdline); if (ret == NULL) { fprintf(stderr, "Out of memory!\n"); goto failed; } options = *ret; /* pull in URL */ options.url = getenv("LDB_URL"); /* and editor (used by ldbedit) */ options.editor = getenv("VISUAL"); if (!options.editor) { options.editor = getenv("EDITOR"); } if (!options.editor) { options.editor = "vi"; } options.scope = LDB_SCOPE_DEFAULT; popt_options = ldb_module_popt_options(ldb); (*popt_options) = builtin_popt_options; rc = ldb_modules_hook(ldb, LDB_MODULE_HOOK_CMDLINE_OPTIONS); if (rc != LDB_SUCCESS) { fprintf(stderr, "ldb: failed to run command line hooks : %s\n", ldb_strerror(rc)); goto failed; } pc = poptGetContext(argv[0], argc, argv, *popt_options, POPT_CONTEXT_KEEP_FIRST); while((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { case 's': { const char *arg = poptGetOptArg(pc); if (strcmp(arg, "base") == 0) { options.scope = LDB_SCOPE_BASE; } else if (strcmp(arg, "sub") == 0) { options.scope = LDB_SCOPE_SUBTREE; } else if (strcmp(arg, "one") == 0) { options.scope = LDB_SCOPE_ONELEVEL; } else { fprintf(stderr, "Invalid scope '%s'\n", arg); goto failed; } break; } case 'v': options.verbose++; break; case 'o': options.options = talloc_realloc(ret, options.options, const char *, num_options+3); if (options.options == NULL) { fprintf(stderr, "Out of memory!\n"); goto failed; } options.options[num_options] = poptGetOptArg(pc); options.options[num_options+1] = NULL; num_options++; break; case 'c': { const char *cs = poptGetOptArg(pc); const char *p; for (p = cs; p != NULL; ) { const char *t, *c; t = strchr(p, ','); if (t == NULL) { c = talloc_strdup(options.controls, p); p = NULL; } else { c = talloc_strndup(options.controls, p, t-p); p = t + 1; } if (c == NULL || !add_control(ret, c)) { fprintf(stderr, __location__ ": out of memory\n"); goto failed; } } break; } case 'P': if (!add_control(ret, "paged_results:1:1024")) { fprintf(stderr, __location__ ": out of memory\n"); goto failed; } break; case 'D': if (!add_control(ret, "show_deleted:1")) { fprintf(stderr, __location__ ": out of memory\n"); goto failed; } break; case 'R': if (!add_control(ret, "show_recycled:0")) { fprintf(stderr, __location__ ": out of memory\n"); goto failed; } break; case 'd': if (!add_control(ret, "show_deactivated_link:0")) { fprintf(stderr, __location__ ": out of memory\n"); goto failed; } break; case 'r': if (!add_control(ret, "reveal_internals:0")) { fprintf(stderr, __location__ ": out of memory\n"); goto failed; } break; case CMDLINE_RELAX: if (!add_control(ret, "relax:0")) { fprintf(stderr, __location__ ": out of memory\n"); goto failed; } break; case 'N': if (!add_control(ret, "search_options:1:2")) { fprintf(stderr, __location__ ": out of memory\n"); goto failed; } break; case 'E': if (!add_control(ret, "extended_dn:1:1")) { fprintf(stderr, __location__ ": out of memory\n"); goto failed; } break; default: fprintf(stderr, "Invalid option %s: %s\n", poptBadOption(pc, 0), poptStrerror(opt)); if (usage) usage(ldb); goto failed; } } /* setup the remaining options for the main program to use */ options.argv = poptGetArgs(pc); if (options.argv) { options.argv++; while (options.argv[options.argc]) options.argc++; } *ret = options; /* all utils need some option */ if (ret->url == NULL) { fprintf(stderr, "You must supply a url with -H or with $LDB_URL\n"); if (usage) usage(ldb); goto failed; } if (strcmp(ret->url, "NONE") == 0) { return ret; } if (options.nosync) { flags |= LDB_FLG_NOSYNC; } if (options.show_binary) { flags |= LDB_FLG_SHOW_BINARY; } if (options.tracing) { flags |= LDB_FLG_ENABLE_TRACING; } if (options.modules_path != NULL) { ldb_set_modules_dir(ldb, options.modules_path); } rc = ldb_modules_hook(ldb, LDB_MODULE_HOOK_CMDLINE_PRECONNECT); if (rc != LDB_SUCCESS) { fprintf(stderr, "ldb: failed to run preconnect hooks : %s\n", ldb_strerror(rc)); goto failed; } /* now connect to the ldb */ if (ldb_connect(ldb, ret->url, flags, ret->options) != LDB_SUCCESS) { fprintf(stderr, "Failed to connect to %s - %s\n", ret->url, ldb_errstring(ldb)); goto failed; } rc = ldb_modules_hook(ldb, LDB_MODULE_HOOK_CMDLINE_POSTCONNECT); if (rc != LDB_SUCCESS) { fprintf(stderr, "ldb: failed to run post connect hooks : %s\n", ldb_strerror(rc)); goto failed; } return ret; failed: talloc_free(ret); exit(LDB_ERR_OPERATIONS_ERROR); return NULL; }
static int dump_lmdb(const char *fname, struct ldb_dn *dn, bool emergency) { int ret; struct MDB_env *env = NULL; struct MDB_txn *txn = NULL; MDB_dbi dbi; struct MDB_cursor *cursor = NULL; struct MDB_val key; struct MDB_val data; ret = mdb_env_create(&env); if (ret != 0) { fprintf(stderr, "Could not create MDB environment: (%d) %s\n", ret, mdb_strerror(ret)); goto close_env; } ret = mdb_env_open(env, fname, MDB_NOSUBDIR|MDB_NOTLS|MDB_RDONLY, 0600); if (ret != 0) { fprintf(stderr, "Could not open environment for %s: (%d) %s\n", fname, ret, mdb_strerror(ret)); goto close_env; } ret = mdb_txn_begin(env, NULL, MDB_RDONLY, &txn); if (ret != 0) { fprintf(stderr, "Could not start transaction: (%d) %s\n", ret, mdb_strerror(ret)); goto close_env; } ret = mdb_dbi_open(txn, NULL, 0, &dbi); if (ret != 0) { fprintf(stderr, "Could not open database: (%d) %s\n", ret, mdb_strerror(ret)); goto close_txn; } ret = mdb_cursor_open(txn, dbi, &cursor); if (ret != 0) { fprintf(stderr, "Could not open cursor: (%d) %s\n", ret, mdb_strerror(ret)); goto close_txn; } ret = mdb_cursor_get(cursor, &key, &data, MDB_FIRST); if (ret != 0 && ret != MDB_NOTFOUND) { fprintf(stderr, "Could not find first record: (%d) %s\n", ret, mdb_strerror(ret)); goto close_cursor; } while (ret != MDB_NOTFOUND) { struct TDB_DATA tkey = { .dptr = key.mv_data, .dsize = key.mv_size }; struct TDB_DATA tdata = { .dptr = data.mv_data, .dsize = data.mv_size }; traverse_fn(NULL, tkey, tdata, dn); ret = mdb_cursor_get(cursor, &key, &data, MDB_NEXT); if (ret != 0 && ret != MDB_NOTFOUND) { fprintf(stderr, "Could not read next record: (%d) %s\n", ret, mdb_strerror(ret)); goto close_cursor; } } ret = 0; close_cursor: mdb_cursor_close(cursor); close_txn: mdb_txn_commit(txn); close_env: mdb_env_close(env); if (ret != 0) { return 1; } return 0; } #else static int dump_lmdb(const char *fname, struct ldb_dn *dn, bool emergency) { /* not built with lmdb support */ return 1; } #endif /* #ifdef HAVE_LMDB */ static void usage( void) { printf( "Usage: ldbdump [options] <filename>\n\n"); printf( " -h this help message\n"); printf( " -d DN dumps DN only\n"); printf( " -e emergency dump, for corrupt databases\n"); printf( " -i include index and @BASEINFO records in dump\n"); printf( " -c validate contents of the records\n"); } int main(int argc, char *argv[]) { bool emergency = false; int c, rc; char *fname; struct ldb_dn *dn = NULL; ldb = ldb_init(NULL, NULL); if (ldb == NULL) { fprintf(stderr, "ldb: ldb_init failed()"); exit(1); } rc = ldb_modules_hook(ldb, LDB_MODULE_HOOK_CMDLINE_PRECONNECT); if (rc != LDB_SUCCESS) { fprintf(stderr, "ldb: failed to run preconnect hooks (needed to get Samba LDIF handlers): %s\n", ldb_strerror(rc)); exit(1); } if (argc < 2) { printf("Usage: ldbdump <fname>\n"); exit(1); } while ((c = getopt( argc, argv, "hd:eic")) != -1) { switch (c) { case 'h': usage(); exit( 0); case 'd': dn = ldb_dn_new(ldb, ldb, optarg); if (!dn) { fprintf(stderr, "ldb failed to parse %s as a DN\n", optarg); exit(1); } break; case 'e': emergency = true; break; case 'i': show_index = true; break; case 'c': validate_contents = true; break; default: usage(); exit( 1); } } fname = argv[optind]; rc = dump_lmdb(fname, dn, emergency); if (rc != 0) { rc = dump_tdb(fname, dn, emergency); if (rc != 0) { fprintf(stderr, "Failed to open %s\n", fname); return 1; } } return 0; }