struct ub_result * unbify_resolve(const char *hostname) { /*@only@*/ static struct ub_ctx * u = NULL; struct ub_result * r = NULL; int ub_err; assert(hostname != NULL); if ( u == NULL ) { if ( (u = ub_ctx_create()) == NULL ) { unbify_log_error("ub_ctx_create() error"); return NULL; } if ( (ub_err = ub_ctx_config(u, UNBOUND_CONFIG_FILE)) != 0 ) { /*@-mustfreefresh@*/ unbify_log_error(ub_strerror(ub_err)); /*@=mustfreefresh@*/ ub_ctx_delete(u); u = NULL; return NULL; } } /*@-unrecog@*/ if ( (ub_err = ub_resolve(u, (char*)hostname, LDNS_RR_TYPE_A, LDNS_RR_CLASS_IN, &r)) != 0 ) { /*@=unrecog -mustfreefresh@*/ unbify_log_error(ub_strerror(ub_err)); /*@=mustfreefresh@*/ if (r) { ub_resolve_free(r); return NULL; } } return r; }
static void nss_ubdns_load_cfg(void) { ub_ctx_config(ctx, NSS_UBDNS_LUCONF); }
/** Main routine for checkconf */ int main(int argc, char* argv[]) { int c; char* qclass = NULL; char* qtype = NULL; struct ub_ctx* ctx = NULL; int debuglevel = 0; ctx = ub_ctx_create(); if(!ctx) { fprintf(stderr, "error: out of memory\n"); exit(1); } /* parse the options */ while( (c=getopt(argc, argv, "46F:c:df:hrt:vy:C:")) != -1) { switch(c) { case '4': check_ub_res(ub_ctx_set_option(ctx, "do-ip6:", "no")); break; case '6': check_ub_res(ub_ctx_set_option(ctx, "do-ip4:", "no")); break; case 'c': qclass = optarg; break; case 'C': check_ub_res(ub_ctx_config(ctx, optarg)); break; case 'd': debuglevel++; if(debuglevel < 2) debuglevel = 2; /* at least VERB_DETAIL */ break; case 'r': check_ub_res(ub_ctx_resolvconf(ctx, "/etc/resolv.conf")); break; case 't': qtype = optarg; break; case 'v': verb++; break; case 'y': check_ub_res(ub_ctx_add_ta(ctx, optarg)); break; case 'f': check_ub_res(ub_ctx_add_ta_file(ctx, optarg)); break; case 'F': check_ub_res(ub_ctx_trustedkeys(ctx, optarg)); break; case '?': case 'h': default: usage(); } } if(debuglevel != 0) /* set after possible -C options */ check_ub_res(ub_ctx_debuglevel(ctx, debuglevel)); if(ub_ctx_get_option(ctx, "use-syslog", &optarg) == 0) { if(strcmp(optarg, "yes") == 0) /* disable use-syslog */ check_ub_res(ub_ctx_set_option(ctx, "use-syslog:", "no")); free(optarg); } argc -= optind; argv += optind; if(argc != 1) usage(); #ifdef HAVE_NSS if(NSS_NoDB_Init(".") != SECSuccess) { fprintf(stderr, "could not init NSS\n"); return 1; } #endif lookup(ctx, argv[0], qtype, qclass); return 0; }
static int mod_instantiate(void *instance, CONF_SECTION *conf) { rlm_unbound_t *inst = instance; int res; char *optval; fr_log_dst_t log_dst; int log_level; int log_fd = -1; char k[64]; /* To silence const warns until newer unbound in distros */ /* * @todo - move this to the thread-instantiate function */ inst->el = fr_global_event_list(); inst->log_pipe_stream[0] = NULL; inst->log_pipe_stream[1] = NULL; inst->log_fd = -1; inst->log_pipe_in_use = false; inst->ub = ub_ctx_create(); if (!inst->ub) { cf_log_err(conf, "ub_ctx_create failed"); return -1; } /* * Note unbound threads WILL happen with -s option, if it matters. * We cannot tell from here whether that option is in effect. */ res = ub_ctx_async(inst->ub, 1); if (res) goto error; /* Glean some default settings to match the main server. */ /* TODO: debug_level can be changed at runtime. */ /* TODO: log until fork when stdout or stderr and !rad_debug_lvl. */ log_level = 0; if (rad_debug_lvl > 0) { log_level = rad_debug_lvl; } else if (main_config->debug_level > 0) { log_level = main_config->debug_level; } switch (log_level) { /* TODO: This will need some tweaking */ case 0: case 1: break; case 2: log_level = 1; break; case 3: case 4: log_level = 2; /* mid-to-heavy levels of output */ break; case 5: case 6: case 7: case 8: log_level = 3; /* Pretty crazy amounts of output */ break; default: log_level = 4; /* Insane amounts of output including crypts */ break; } res = ub_ctx_debuglevel(inst->ub, log_level); if (res) goto error; switch (default_log.dst) { case L_DST_STDOUT: if (!rad_debug_lvl) { log_dst = L_DST_NULL; break; } log_dst = L_DST_STDOUT; log_fd = dup(STDOUT_FILENO); break; case L_DST_STDERR: if (!rad_debug_lvl) { log_dst = L_DST_NULL; break; } log_dst = L_DST_STDOUT; log_fd = dup(STDERR_FILENO); break; case L_DST_FILES: if (main_config->log_file) { char *log_file; strcpy(k, "logfile:"); /* 3rd argument isn't const'd in libunbounds API */ memcpy(&log_file, &main_config->log_file, sizeof(log_file)); res = ub_ctx_set_option(inst->ub, k, log_file); if (res) { goto error; } log_dst = L_DST_FILES; break; } /* FALL-THROUGH */ case L_DST_NULL: log_dst = L_DST_NULL; break; default: log_dst = L_DST_SYSLOG; break; } /* Now load the config file, which can override gleaned settings. */ { char *file; memcpy(&file, &inst->filename, sizeof(file)); res = ub_ctx_config(inst->ub, file); if (res) goto error; } /* * Check if the config file tried to use syslog. Unbound * does not share syslog gracefully. */ strcpy(k, "use-syslog"); res = ub_ctx_get_option(inst->ub, k, &optval); if (res || !optval) goto error; if (!strcmp(optval, "yes")) { char v[3]; free(optval); WARN("Overriding syslog settings"); strcpy(k, "use-syslog:"); strcpy(v, "no"); res = ub_ctx_set_option(inst->ub, k, v); if (res) goto error; if (log_dst == L_DST_FILES) { char *log_file; /* Reinstate the log file name JIC */ strcpy(k, "logfile:"); /* 3rd argument isn't const'd in libunbounds API */ memcpy(&log_file, &main_config->log_file, sizeof(log_file)); res = ub_ctx_set_option(inst->ub, k, log_file); if (res) goto error; } } else { if (optval) free(optval); strcpy(k, "logfile"); res = ub_ctx_get_option(inst->ub, k, &optval); if (res) goto error; if (optval && strlen(optval)) { log_dst = L_DST_FILES; /* * We open log_fd early in the process, * so that libunbound doesn't close * stdout / stderr on us (grrr, stupid * software). But if the config say to * use files, we now have to close the * dup'd FD. */ if (log_fd >= 0) { close(log_fd); log_fd = -1; } } else if (!rad_debug_lvl) { log_dst = L_DST_NULL; } if (optval) free(optval); } switch (log_dst) { case L_DST_STDOUT: /* * We have an fd to log to. And we've already attempted to * dup it so libunbound doesn't close it on us. */ if (log_fd == -1) { cf_log_err(conf, "Could not dup fd"); goto error_nores; } inst->log_stream = fdopen(log_fd, "w"); if (!inst->log_stream) { cf_log_err(conf, "error setting up log stream"); goto error_nores; } res = ub_ctx_debugout(inst->ub, inst->log_stream); if (res) goto error; break; case L_DST_FILES: /* We gave libunbound a filename. It is on its own now. */ break; case L_DST_NULL: /* We tell libunbound not to log at all. */ res = ub_ctx_debugout(inst->ub, NULL); if (res) goto error; break; case L_DST_SYSLOG: /* * Currently this wreaks havoc when running threaded, so just * turn logging off until that gets figured out. */ res = ub_ctx_debugout(inst->ub, NULL); if (res) goto error; break; default: break; } /* * Now we need to finalize the context. * * There's no clean API to just finalize the context made public * in libunbound. But we can trick it by trying to delete data * which as it happens fails quickly and quietly even though the * data did not exist. */ strcpy(k, "notar33lsite.foo123.nottld A 127.0.0.1"); ub_ctx_data_remove(inst->ub, k); inst->log_fd = ub_fd(inst->ub); if (inst->log_fd >= 0) { if (fr_event_fd_insert(inst, inst->el, inst->log_fd, ub_fd_handler, NULL, NULL, inst) < 0) { cf_log_err(conf, "could not insert async fd"); inst->log_fd = -1; goto error_nores; } } return 0; error: cf_log_err(conf, "%s", ub_strerror(res)); error_nores: if (log_fd > -1) close(log_fd); return -1; }