/* 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; }
/* 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; struct ldb_dn *dn; NTSTATUS nt_status; state = talloc_zero(NULL, struct dlz_bind9_data); if (state == NULL) { return ISC_R_NOMEMORY; } talloc_set_destructor(state, dlz_state_debug_unregister); /* 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); /* Do not install samba signal handlers */ fault_setup_disable(); /* Start logging (to the bind9 logs) */ debug_set_callback(state, b9_debug); state->ev_ctx = s4_event_context_init(state); if (state->ev_ctx == NULL) { result = ISC_R_NOMEMORY; goto failed; } result = parse_options(state, argc, argv, &state->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 (state->options.debug) { lpcfg_do_global_parameter(state->lp, "log level", state->options.debug); } else { lpcfg_do_global_parameter(state->lp, "log level", "0"); } if (smb_krb5_init_context(state, state->ev_ctx, state->lp, &state->smb_krb5_ctx) != 0) { result = ISC_R_NOMEMORY; goto failed; } nt_status = gensec_init(); if (!NT_STATUS_IS_OK(nt_status)) { result = ISC_R_NOMEMORY; goto failed; } state->auth_context = talloc_zero(state, struct auth4_context); if (state->auth_context == NULL) { result = ISC_R_NOMEMORY; goto failed; } if (state->options.url == NULL) { state->options.url = lpcfg_private_path(state, state->lp, "dns/sam.ldb"); if (state->options.url == NULL) { result = ISC_R_NOMEMORY; goto failed; } } state->samdb = samdb_connect_url(state, state->ev_ctx, state->lp, system_session(state->lp), 0, state->options.url); if (state->samdb == NULL) { state->log(ISC_LOG_ERROR, "samba_dlz: Failed to connect to %s", state->options.url); 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", state->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)); state->auth_context->event_ctx = state->ev_ctx; state->auth_context->lp_ctx = state->lp; state->auth_context->sam_ctx = state->samdb; state->auth_context->generate_session_info_pac = b9_generate_session_info_pac; *dbdata = state; return ISC_R_SUCCESS; failed: talloc_free(state); return result; }