struct ldb_context *samba_ldb_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct loadparm_context *lp_ctx, struct auth_session_info *session_info, struct cli_credentials *credentials) { struct ldb_context *ldb; int ret; ldb = ldb_init(mem_ctx, ev); if (ldb == NULL) { return NULL; } ldb_set_modules_dir(ldb, modules_path(ldb, "ldb")); ldb_set_debug(ldb, ldb_wrap_debug, NULL); ldb_set_utf8_fns(ldb, NULL, wrap_casefold); if (session_info) { if (ldb_set_opaque(ldb, "sessionInfo", session_info)) { talloc_free(ldb); return NULL; } } if (credentials) { if (ldb_set_opaque(ldb, "credentials", credentials)) { talloc_free(ldb); return NULL; } } if (ldb_set_opaque(ldb, "loadparm", lp_ctx)) { talloc_free(ldb); return NULL; } /* This must be done before we load the schema, as these * handlers for objectSid and objectGUID etc must take * precedence over the 'binary attribute' declaration in the * schema */ ret = ldb_register_samba_handlers(ldb); if (ret != LDB_SUCCESS) { talloc_free(ldb); return NULL; } /* we usually want Samba databases to be private. If we later find we need one public, we will need to add a parameter to ldb_wrap_connect() */ ldb_set_create_perms(ldb, 0600); return ldb; }
/* return the default DN for a ldap server given a connected RPC pipe to the server */ static const char *torture_get_ldap_base_dn(struct torture_context *tctx, struct dcerpc_pipe *p) { const char *hostname = p->binding->host; struct ldb_context *ldb; const char *ldap_url = talloc_asprintf(p, "ldap://%s", hostname); const char *attrs[] = { "defaultNamingContext", NULL }; const char *dnstr; TALLOC_CTX *tmp_ctx = talloc_new(tctx); int ret; struct ldb_result *res; ldb = ldb_init(tmp_ctx, tctx->ev); if (ldb == NULL) { talloc_free(tmp_ctx); return NULL; } if (ldb_set_opaque(ldb, "loadparm", tctx->lp_ctx)) { talloc_free(ldb); return NULL; } ldb_set_modules_dir(ldb, modules_path(ldb, "ldb")); ret = ldb_connect(ldb, ldap_url, 0, NULL); if (ret != LDB_SUCCESS) { torture_comment(tctx, "Failed to make LDB connection to target"); talloc_free(tmp_ctx); return NULL; } ret = dsdb_search_dn(ldb, tmp_ctx, &res, ldb_dn_new(tmp_ctx, ldb, ""), attrs, 0); if (ret != LDB_SUCCESS) { torture_comment(tctx, "Failed to get defaultNamingContext"); talloc_free(tmp_ctx); return NULL; } dnstr = ldb_msg_find_attr_as_string(res->msgs[0], "defaultNamingContext", NULL); dnstr = talloc_strdup(tctx, dnstr); talloc_free(tmp_ctx); return dnstr; }
errno_t sysdb_ldb_connect(TALLOC_CTX *mem_ctx, const char *filename, struct ldb_context **_ldb) { int ret; struct ldb_context *ldb; const char *mod_path; if (_ldb == NULL) { return EINVAL; } ldb = ldb_init(mem_ctx, NULL); if (!ldb) { return EIO; } ret = ldb_set_debug(ldb, ldb_debug_messages, NULL); if (ret != LDB_SUCCESS) { return EIO; } mod_path = getenv(LDB_MODULES_PATH); if (mod_path != NULL) { DEBUG(SSSDBG_TRACE_ALL, "Setting ldb module path to [%s].\n", mod_path); ldb_set_modules_dir(ldb, mod_path); } ret = ldb_connect(ldb, filename, 0, NULL); if (ret != LDB_SUCCESS) { return EIO; } *_ldb = ldb; return EOK; }
/** 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; }
/* wrapped connection to a ldb database to close just talloc_free() the returned ldb_context TODO: We need an error_string parameter */ struct ldb_context *ldb_wrap_connect(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct loadparm_context *lp_ctx, const char *url, struct auth_session_info *session_info, struct cli_credentials *credentials, unsigned int flags) { struct ldb_context *ldb; int ret; char *real_url = NULL; struct ldb_wrap *w; struct ldb_wrap_context c; c.url = url; c.ev = ev; c.lp_ctx = lp_ctx; c.session_info = session_info; c.credentials = credentials; c.flags = flags; /* see if we can re-use an existing ldb */ for (w=ldb_wrap_list; w; w=w->next) { if (ldb_wrap_same_context(&c, &w->context)) { return talloc_reference(mem_ctx, w->ldb); } } /* we want to use the existing event context if possible. This relies on the fact that in smbd, everything is a child of the main event_context */ if (ev == NULL) { return NULL; } ldb = ldb_init(mem_ctx, ev); if (ldb == NULL) { return NULL; } ldb_set_modules_dir(ldb, talloc_asprintf(ldb, "%s/ldb", lp_modulesdir(lp_ctx))); if (ldb_set_opaque(ldb, "sessionInfo", session_info)) { talloc_free(ldb); return NULL; } if (ldb_set_opaque(ldb, "credentials", credentials)) { talloc_free(ldb); return NULL; } if (ldb_set_opaque(ldb, "loadparm", lp_ctx)) { talloc_free(ldb); return NULL; } /* This must be done before we load the schema, as these * handlers for objectSid and objectGUID etc must take * precedence over the 'binary attribute' declaration in the * schema */ ret = ldb_register_samba_handlers(ldb); if (ret == -1) { talloc_free(ldb); return NULL; } if (lp_ctx != NULL && strcmp(lp_sam_url(lp_ctx), url) == 0) { dsdb_set_global_schema(ldb); } ldb_set_debug(ldb, ldb_wrap_debug, NULL); ldb_set_utf8_fns(ldb, NULL, wrap_casefold); real_url = private_path(ldb, lp_ctx, url); if (real_url == NULL) { talloc_free(ldb); return NULL; } /* allow admins to force non-sync ldb for all databases */ if (lp_parm_bool(lp_ctx, NULL, "ldb", "nosync", false)) { flags |= LDB_FLG_NOSYNC; } if (DEBUGLVL(10)) { flags |= LDB_FLG_ENABLE_TRACING; } /* we usually want Samba databases to be private. If we later find we need one public, we will need to add a parameter to ldb_wrap_connect() */ ldb_set_create_perms(ldb, 0600); ret = ldb_connect(ldb, real_url, flags, NULL); if (ret != LDB_SUCCESS) { talloc_free(ldb); return NULL; } /* setup for leak detection */ ldb_set_opaque(ldb, "wrap_url", real_url); /* add to the list of open ldb contexts */ w = talloc(ldb, struct ldb_wrap); if (w == NULL) { talloc_free(ldb); return NULL; } w->context = c; w->context.url = talloc_strdup(w, url); if (w->context.url == NULL) { talloc_free(ldb); return NULL; } w->ldb = ldb; DLIST_ADD(ldb_wrap_list, w); /* make the resulting schema global */ if (lp_ctx != NULL && strcmp(lp_sam_url(lp_ctx), url) == 0) { dsdb_make_schema_global(ldb); } DEBUG(3,("ldb_wrap open of %s\n", url)); talloc_set_destructor(w, ldb_wrap_destructor); return ldb; }
/** process command line options */ struct ldb_cmdline *ldb_cmdline_process(struct ldb_context *ldb, int argc, const char **argv, void (*usage)(void)) { struct ldb_cmdline *ret=NULL; poptContext pc; #if (_SAMBA_BUILD_ >= 4) int r; #endif int num_options = 0; int opt; int flags = 0; #if (_SAMBA_BUILD_ >= 4) r = ldb_register_samba_handlers(ldb); if (r != 0) { goto failed; } #endif /* 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; 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 '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(); 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(); 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 (_SAMBA_BUILD_ >= 4) /* Must be after we have processed command line options */ gensec_init(cmdline_lp_ctx); if (ldb_set_opaque(ldb, "sessionInfo", system_session(cmdline_lp_ctx))) { goto failed; } if (ldb_set_opaque(ldb, "credentials", cmdline_credentials)) { goto failed; } if (ldb_set_opaque(ldb, "loadparm", cmdline_lp_ctx)) { goto failed; } ldb_set_utf8_fns(ldb, NULL, wrap_casefold); #endif if (options.modules_path != NULL) { ldb_set_modules_dir(ldb, options.modules_path); } else if (getenv("LDB_MODULES_PATH") != NULL) { ldb_set_modules_dir(ldb, getenv("LDB_MODULES_PATH")); } /* now connect to the ldb */ if (ldb_connect(ldb, ret->url, flags, ret->options) != 0) { fprintf(stderr, "Failed to connect to %s - %s\n", ret->url, ldb_errstring(ldb)); goto failed; } return ret; failed: talloc_free(ret); exit(1); return NULL; }