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; }
/* 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; }
/* connect to the group mapping ldb */ static bool init_group_mapping(void) { bool existed; const char *init_ldif[] = { "dn: @ATTRIBUTES\n" \ "ntName: CASE_INSENSITIVE\n" \ "\n", "dn: @INDEXLIST\n" \ "@IDXATTR: gidNumber\n" \ "@IDXATTR: ntName\n" \ "@IDXATTR: member\n" }; const char *db_path, *tdb_path; int ret; int flags = 0; if (ldb != NULL) { return True; } /* this is needed as Samba3 doesn't have this globally yet */ ldb_global_init(); db_path = state_path("group_mapping.ldb"); ldb = ldb_init(NULL); if (ldb == NULL) goto failed; /* Ensure this db is created read/write for root only. */ ldb_set_create_perms(ldb, 0600); existed = file_exist(db_path, NULL); if (lp_parm_bool(-1, "groupmap", "nosync", False)) { flags |= LDB_FLG_NOSYNC; } if (!lp_use_mmap()) { flags |= LDB_FLG_NOMMAP; } ret = ldb_connect(ldb, db_path, flags, NULL); if (ret != LDB_SUCCESS) { goto failed; } /* force the permissions on the ldb to 0600 - this will fix existing databases as well as new ones */ if (chmod(db_path, 0600) != 0) { goto failed; } if (!existed) { /* initialise the ldb with an index */ struct ldb_ldif *ldif; int i; for (i=0;i<ARRAY_SIZE(init_ldif);i++) { ldif = ldb_ldif_read_string(ldb, &init_ldif[i]); if (ldif == NULL) goto failed; ret = ldb_add(ldb, ldif->msg); talloc_free(ldif); if (ret == -1) goto failed; } } /* possibly upgrade */ tdb_path = state_path("group_mapping.tdb"); if (file_exist(tdb_path, NULL) && !mapping_upgrade(tdb_path)) { unlink(state_path("group_mapping.ldb")); goto failed; } return True; failed: DEBUG(0,("Failed to open group mapping ldb '%s' - '%s'\n", db_path, ldb?ldb_errstring(ldb):strerror(errno))); talloc_free(ldb); ldb = NULL; return False; }