static PyObject *py_wrap_setxattr(PyObject *self, PyObject *args) { char *filename, *attribute, *tdbname; DATA_BLOB blob; int blobsize; NTSTATUS status; TALLOC_CTX *mem_ctx; struct tdb_wrap *eadb; if (!PyArg_ParseTuple(args, "ssss#", &tdbname, &filename, &attribute, &blob.data, &blobsize)) return NULL; blob.length = blobsize; mem_ctx = talloc_new(NULL); eadb = tdb_wrap_open(mem_ctx, tdbname, 50000, TDB_DEFAULT, O_RDWR|O_CREAT, 0600); if (eadb == NULL) { PyErr_SetFromErrno(PyExc_IOError); talloc_free(mem_ctx); return NULL; } status = push_xattr_blob_tdb_raw(eadb, mem_ctx, attribute, filename, -1, &blob); if (!NT_STATUS_IS_OK(status)) { PyErr_FromNTSTATUS(status); talloc_free(mem_ctx); return NULL; } talloc_free(mem_ctx); Py_RETURN_NONE; }
bool notify_internal_parent_init(TALLOC_CTX *mem_ctx) { struct tdb_wrap *db1, *db2; struct loadparm_context *lp_ctx; if (lp_clustering()) { return true; } lp_ctx = loadparm_init_s3(mem_ctx, loadparm_s3_context()); if (lp_ctx == NULL) { DEBUG(0, ("loadparm_init_s3 failed\n")); return false; } /* * Open the tdbs in the parent process (smbd) so that our * CLEAR_IF_FIRST optimization in tdb_reopen_all can properly * work. */ db1 = tdb_wrap_open(mem_ctx, lock_path("notify.tdb"), 0, TDB_SEQNUM|TDB_CLEAR_IF_FIRST|TDB_INCOMPATIBLE_HASH, O_RDWR|O_CREAT, 0644, lp_ctx); if (db1 == NULL) { talloc_unlink(mem_ctx, lp_ctx); DEBUG(1, ("could not open notify.tdb: %s\n", strerror(errno))); return false; } db2 = tdb_wrap_open(mem_ctx, lock_path("notify_onelevel.tdb"), 0, TDB_CLEAR_IF_FIRST|TDB_INCOMPATIBLE_HASH, O_RDWR|O_CREAT, 0644, lp_ctx); talloc_unlink(mem_ctx, lp_ctx); if (db2 == NULL) { DEBUG(1, ("could not open notify_onelevel.tdb: %s\n", strerror(errno))); TALLOC_FREE(db1); return false; } return true; }
struct db_context *db_open_tdb(TALLOC_CTX *mem_ctx, const char *name, int hash_size, int tdb_flags, int open_flags, mode_t mode) { struct db_context *result = NULL; struct db_tdb_ctx *db_tdb; struct loadparm_context *lp_ctx; result = talloc_zero(mem_ctx, struct db_context); if (result == NULL) { DEBUG(0, ("talloc failed\n")); goto fail; } lp_ctx = loadparm_init_s3(result, loadparm_s3_context()); result->private_data = db_tdb = talloc(result, struct db_tdb_ctx); if (db_tdb == NULL) { DEBUG(0, ("talloc failed\n")); goto fail; } db_tdb->wtdb = tdb_wrap_open(db_tdb, name, hash_size, tdb_flags, open_flags, mode, lp_ctx); talloc_unlink(result, lp_ctx); if (db_tdb->wtdb == NULL) { DEBUG(3, ("Could not open tdb: %s\n", strerror(errno))); goto fail; } result->fetch_locked = db_tdb_fetch_locked; result->traverse = db_tdb_traverse; result->traverse_read = db_tdb_traverse_read; result->parse_record = db_tdb_parse; result->get_seqnum = db_tdb_get_seqnum; result->get_flags = db_tdb_get_flags; result->persistent = ((tdb_flags & TDB_CLEAR_IF_FIRST) == 0); result->transaction_start = db_tdb_transaction_start; result->transaction_commit = db_tdb_transaction_commit; result->transaction_cancel = db_tdb_transaction_cancel; result->exists = db_tdb_exists; result->wipe = db_tdb_wipe; return result; fail: if (result != NULL) { TALLOC_FREE(result); } return NULL; }
struct tdb_wrap *open_schannel_session_store(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx) { struct tdb_wrap *tdb_sc = NULL; char *fname = lpcfg_private_path(mem_ctx, lp_ctx, "schannel_store.tdb"); if (!fname) { return NULL; } tdb_sc = tdb_wrap_open(mem_ctx, fname, 0, TDB_CLEAR_IF_FIRST|TDB_NOSYNC, O_RDWR|O_CREAT, 0600, lp_ctx); if (!tdb_sc) { DEBUG(0,("open_schannel_session_store: Failed to open %s - %s\n", fname, strerror(errno))); TALLOC_FREE(fname); return NULL; } TALLOC_FREE(fname); return tdb_sc; }
struct tdb_wrap *open_schannel_session_store(TALLOC_CTX *mem_ctx, const char *private_dir) { struct tdb_wrap *tdb_sc = NULL; char *fname = talloc_asprintf(mem_ctx, "%s/schannel_store.tdb", private_dir); if (!fname) { return NULL; } tdb_sc = tdb_wrap_open(mem_ctx, fname, 0, TDB_CLEAR_IF_FIRST|TDB_NOSYNC, O_RDWR|O_CREAT, 0600); if (!tdb_sc) { DEBUG(0,("open_schannel_session_store: Failed to open %s - %s\n", fname, strerror(errno))); TALLOC_FREE(fname); return NULL; } TALLOC_FREE(fname); return tdb_sc; }
struct named_mutex *grab_named_mutex(TALLOC_CTX *mem_ctx, const char *name, int timeout) { struct named_mutex *result; result = talloc(mem_ctx, struct named_mutex); if (result == NULL) { DEBUG(0, ("talloc failed\n")); return NULL; } result->name = talloc_strdup(result, name); if (result->name == NULL) { DEBUG(0, ("talloc failed\n")); TALLOC_FREE(result); return NULL; } result->tdb = tdb_wrap_open(result, lock_path("mutex.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600); if (result->tdb == NULL) { DEBUG(1, ("Could not open mutex.tdb: %s\n", strerror(errno))); TALLOC_FREE(result); return NULL; } if (tdb_lock_bystring_with_timeout(result->tdb->tdb, name, timeout) == -1) { DEBUG(1, ("Could not get the lock for %s\n", name)); TALLOC_FREE(result); return NULL; } talloc_set_destructor(result, unlock_named_mutex); return result; }
/******************************************************************* open the profiling shared memory area ******************************************************************/ bool profile_setup(struct messaging_context *msg_ctx, bool rdonly) { unsigned char tmp[16] = {}; MD5_CTX md5; char *db_name; if (smbprofile_state.internal.db != NULL) { return true; } db_name = cache_path("smbprofile.tdb"); if (db_name == NULL) { return false; } smbprofile_state.internal.db = tdb_wrap_open( NULL, db_name, 0, rdonly ? 0 : TDB_CLEAR_IF_FIRST|TDB_MUTEX_LOCKING, O_CREAT | (rdonly ? O_RDONLY : O_RDWR), 0644); if (smbprofile_state.internal.db == NULL) { return false; } if (msg_ctx != NULL) { messaging_register(msg_ctx, NULL, MSG_PROFILE, profile_message); messaging_register(msg_ctx, NULL, MSG_REQ_PROFILELEVEL, reqprofile_message); } MD5Init(&md5); MD5Update(&md5, (const uint8_t *)&smbprofile_state.stats.global, sizeof(smbprofile_state.stats.global)); #define __UPDATE(str) do { \ MD5Update(&md5, (const uint8_t *)str, strlen(str)); \ } while(0) #define SMBPROFILE_STATS_START #define SMBPROFILE_STATS_SECTION_START(name, display) do { \ __UPDATE(#name "+" #display); \ } while(0); #define SMBPROFILE_STATS_COUNT(name) do { \ __UPDATE(#name "+count"); \ } while(0); #define SMBPROFILE_STATS_TIME(name) do { \ __UPDATE(#name "+time"); \ } while(0); #define SMBPROFILE_STATS_BASIC(name) do { \ __UPDATE(#name "+count"); \ __UPDATE(#name "+time"); \ } while(0); #define SMBPROFILE_STATS_BYTES(name) do { \ __UPDATE(#name "+count"); \ __UPDATE(#name "+time"); \ __UPDATE(#name "+idle"); \ __UPDATE(#name "+bytes"); \ } while(0); #define SMBPROFILE_STATS_IOBYTES(name) do { \ __UPDATE(#name "+count"); \ __UPDATE(#name "+time"); \ __UPDATE(#name "+idle"); \ __UPDATE(#name "+inbytes"); \ __UPDATE(#name "+outbytes"); \ } while(0); #define SMBPROFILE_STATS_SECTION_END #define SMBPROFILE_STATS_END SMBPROFILE_STATS_ALL_SECTIONS #undef __UPDATE #undef SMBPROFILE_STATS_START #undef SMBPROFILE_STATS_SECTION_START #undef SMBPROFILE_STATS_COUNT #undef SMBPROFILE_STATS_TIME #undef SMBPROFILE_STATS_BASIC #undef SMBPROFILE_STATS_BYTES #undef SMBPROFILE_STATS_IOBYTES #undef SMBPROFILE_STATS_SECTION_END #undef SMBPROFILE_STATS_END MD5Final(tmp, &md5); profile_p = &smbprofile_state.stats.global; profile_p->magic = BVAL(tmp, 0); if (profile_p->magic == 0) { profile_p->magic = BVAL(tmp, 8); } return True; }
/* setup config options for a posix share */ static void pvfs_setup_options(struct pvfs_state *pvfs) { struct share_config *scfg = pvfs->ntvfs->ctx->config; const char *eadb; bool def_perm_override = false; if (share_bool_option(scfg, SHARE_MAP_HIDDEN, SHARE_MAP_HIDDEN_DEFAULT)) pvfs->flags |= PVFS_FLAG_MAP_HIDDEN; if (share_bool_option(scfg, SHARE_MAP_ARCHIVE, SHARE_MAP_ARCHIVE_DEFAULT)) pvfs->flags |= PVFS_FLAG_MAP_ARCHIVE; if (share_bool_option(scfg, SHARE_MAP_SYSTEM, SHARE_MAP_SYSTEM_DEFAULT)) pvfs->flags |= PVFS_FLAG_MAP_SYSTEM; if (share_bool_option(scfg, SHARE_READONLY, SHARE_READONLY_DEFAULT)) pvfs->flags |= PVFS_FLAG_READONLY; if (share_bool_option(scfg, SHARE_STRICT_SYNC, SHARE_STRICT_SYNC_DEFAULT)) pvfs->flags |= PVFS_FLAG_STRICT_SYNC; if (share_bool_option(scfg, SHARE_STRICT_LOCKING, SHARE_STRICT_LOCKING_DEFAULT)) pvfs->flags |= PVFS_FLAG_STRICT_LOCKING; if (share_bool_option(scfg, SHARE_CI_FILESYSTEM, SHARE_CI_FILESYSTEM_DEFAULT)) pvfs->flags |= PVFS_FLAG_CI_FILESYSTEM; if (share_bool_option(scfg, PVFS_FAKE_OPLOCKS, PVFS_FAKE_OPLOCKS_DEFAULT)) pvfs->flags |= PVFS_FLAG_FAKE_OPLOCKS; if (share_bool_option(scfg, PVFS_AIO, false)) pvfs->flags |= PVFS_FLAG_LINUX_AIO; #if defined(O_DIRECTORY) && defined(O_NOFOLLOW) /* set PVFS_PERM_OVERRIDE by default only if the system * supports the necessary capabilities to make it secure */ def_perm_override = true; #endif if (share_bool_option(scfg, PVFS_PERM_OVERRIDE, def_perm_override)) pvfs->flags |= PVFS_FLAG_PERM_OVERRIDE; /* file perm options */ pvfs->options.create_mask = share_int_option(scfg, SHARE_CREATE_MASK, SHARE_CREATE_MASK_DEFAULT); pvfs->options.dir_mask = share_int_option(scfg, SHARE_DIR_MASK, SHARE_DIR_MASK_DEFAULT); pvfs->options.force_dir_mode = share_int_option(scfg, SHARE_FORCE_DIR_MODE, SHARE_FORCE_DIR_MODE_DEFAULT); pvfs->options.force_create_mode = share_int_option(scfg, SHARE_FORCE_CREATE_MODE, SHARE_FORCE_CREATE_MODE_DEFAULT); /* this must be a power of 2 */ pvfs->alloc_size_rounding = share_int_option(scfg, PVFS_ALLOCATION_ROUNDING, PVFS_ALLOCATION_ROUNDING_DEFAULT); pvfs->search.inactivity_time = share_int_option(scfg, PVFS_SEARCH_INACTIVITY, PVFS_SEARCH_INACTIVITY_DEFAULT); #if HAVE_XATTR_SUPPORT if (share_bool_option(scfg, PVFS_XATTR, PVFS_XATTR_DEFAULT)) pvfs->flags |= PVFS_FLAG_XATTR_ENABLE; #endif pvfs->sharing_violation_delay = share_int_option(scfg, PVFS_SHARE_DELAY, PVFS_SHARE_DELAY_DEFAULT); pvfs->oplock_break_timeout = share_int_option(scfg, PVFS_OPLOCK_TIMEOUT, PVFS_OPLOCK_TIMEOUT_DEFAULT); pvfs->writetime_delay = share_int_option(scfg, PVFS_WRITETIME_DELAY, PVFS_WRITETIME_DELAY_DEFAULT); pvfs->share_name = talloc_strdup(pvfs, scfg->name); pvfs->fs_attribs = FS_ATTR_CASE_SENSITIVE_SEARCH | FS_ATTR_CASE_PRESERVED_NAMES | FS_ATTR_UNICODE_ON_DISK | FS_ATTR_SPARSE_FILES; /* allow xattrs to be stored in a external tdb */ eadb = share_string_option(scfg, PVFS_EADB, NULL); if (eadb != NULL) { pvfs->ea_db = tdb_wrap_open(pvfs, eadb, 50000, TDB_DEFAULT, O_RDWR|O_CREAT, 0600, pvfs->ntvfs->ctx->lp_ctx); if (pvfs->ea_db != NULL) { pvfs->flags |= PVFS_FLAG_XATTR_ENABLE; } else { DEBUG(0,("Failed to open eadb '%s' - %s\n", eadb, strerror(errno))); pvfs->flags &= ~PVFS_FLAG_XATTR_ENABLE; } } if (pvfs->flags & PVFS_FLAG_XATTR_ENABLE) { pvfs->fs_attribs |= FS_ATTR_NAMED_STREAMS; } if (pvfs->flags & PVFS_FLAG_XATTR_ENABLE) { pvfs->fs_attribs |= FS_ATTR_PERSISTANT_ACLS; } pvfs->sid_cache.creator_owner = dom_sid_parse_talloc(pvfs, SID_CREATOR_OWNER); pvfs->sid_cache.creator_group = dom_sid_parse_talloc(pvfs, SID_CREATOR_GROUP); /* check if the system really supports xattrs */ if (pvfs->flags & PVFS_FLAG_XATTR_ENABLE) { pvfs_xattr_probe(pvfs); } /* enable an ACL backend */ pvfs->acl_ops = pvfs_acl_backend_byname(share_string_option(scfg, PVFS_ACL, "xattr")); }
/* test tdb speed */ static bool test_tdb_speed(struct torture_context *torture, const void *_data) { struct timeval tv; struct tdb_wrap *tdbw; int timelimit = torture_setting_int(torture, "timelimit", 10); int i, count; TALLOC_CTX *tmp_ctx = talloc_new(torture); unlink("test.tdb"); torture_comment(torture, "Testing tdb speed for sidmap\n"); tdbw = tdb_wrap_open(tmp_ctx, "test.tdb", 10000, 0, O_RDWR|O_CREAT|O_TRUNC, 0600); if (!tdbw) { unlink("test.tdb"); talloc_free(tmp_ctx); torture_fail(torture, "Failed to open test.tdb"); } torture_comment(torture, "Adding %d SID records\n", torture_entries); for (i=0;i<torture_entries;i++) { if (!tdb_add_record(tdbw, "S-1-5-21-53173311-3623041448-2049097239-%u", "UID %u", i)) { torture_result(torture, TORTURE_FAIL, "Failed to add SID %d\n", i); goto failed; } if (!tdb_add_record(tdbw, "UID %u", "S-1-5-21-53173311-3623041448-2049097239-%u", i)) { torture_result(torture, TORTURE_FAIL, "Failed to add UID %d\n", i); goto failed; } } torture_comment(torture, "Testing for %d seconds\n", timelimit); tv = timeval_current(); for (count=0;timeval_elapsed(&tv) < timelimit;count++) { TDB_DATA key, data; i = random() % torture_entries; key.dptr = (uint8_t *)talloc_asprintf(tmp_ctx, "S-1-5-21-53173311-3623041448-2049097239-%u", i); key.dsize = strlen((char *)key.dptr)+1; data = tdb_fetch(tdbw->tdb, key); talloc_free(key.dptr); if (data.dptr == NULL) { torture_result(torture, TORTURE_FAIL, "Failed to fetch SID %d\n", i); goto failed; } free(data.dptr); key.dptr = (uint8_t *)talloc_asprintf(tmp_ctx, "UID %u", i); key.dsize = strlen((char *)key.dptr)+1; data = tdb_fetch(tdbw->tdb, key); talloc_free(key.dptr); if (data.dptr == NULL) { torture_result(torture, TORTURE_FAIL, "Failed to fetch UID %d\n", i); goto failed; } free(data.dptr); } tdb_speed = count/timeval_elapsed(&tv); torture_comment(torture, "tdb speed %.2f ops/sec\n", tdb_speed); unlink("test.tdb"); talloc_free(tmp_ctx); return true; failed: unlink("test.tdb"); talloc_free(tmp_ctx); return false; }
/* setup config options for a posix share */ static void pvfs_setup_options(struct pvfs_state *pvfs) { struct share_config *scfg = pvfs->ntvfs->ctx->config; const char *eadb; if (share_bool_option(scfg, SHARE_MAP_HIDDEN, SHARE_MAP_HIDDEN_DEFAULT)) pvfs->flags |= PVFS_FLAG_MAP_HIDDEN; if (share_bool_option(scfg, SHARE_MAP_ARCHIVE, SHARE_MAP_ARCHIVE_DEFAULT)) pvfs->flags |= PVFS_FLAG_MAP_ARCHIVE; if (share_bool_option(scfg, SHARE_MAP_SYSTEM, SHARE_MAP_SYSTEM_DEFAULT)) pvfs->flags |= PVFS_FLAG_MAP_SYSTEM; if (share_bool_option(scfg, SHARE_READONLY, SHARE_READONLY_DEFAULT)) pvfs->flags |= PVFS_FLAG_READONLY; if (share_bool_option(scfg, SHARE_STRICT_SYNC, SHARE_STRICT_SYNC_DEFAULT)) pvfs->flags |= PVFS_FLAG_STRICT_SYNC; if (share_bool_option(scfg, SHARE_STRICT_LOCKING, SHARE_STRICT_LOCKING_DEFAULT)) pvfs->flags |= PVFS_FLAG_STRICT_LOCKING; if (share_bool_option(scfg, SHARE_CI_FILESYSTEM, SHARE_CI_FILESYSTEM_DEFAULT)) pvfs->flags |= PVFS_FLAG_CI_FILESYSTEM; if (share_bool_option(scfg, PVFS_FAKE_OPLOCKS, PVFS_FAKE_OPLOCKS_DEFAULT)) { pvfs->flags |= PVFS_FLAG_FAKE_OPLOCKS; } /* this must be a power of 2 */ pvfs->alloc_size_rounding = share_int_option(scfg, PVFS_ALLOCATION_ROUNDING, PVFS_ALLOCATION_ROUNDING_DEFAULT); pvfs->search.inactivity_time = share_int_option(scfg, PVFS_SEARCH_INACTIVITY, PVFS_SEARCH_INACTIVITY_DEFAULT); #if HAVE_XATTR_SUPPORT if (share_bool_option(scfg, PVFS_XATTR, PVFS_XATTR_DEFAULT)) pvfs->flags |= PVFS_FLAG_XATTR_ENABLE; #endif pvfs->sharing_violation_delay = share_int_option(scfg, PVFS_SHARE_DELAY, PVFS_SHARE_DELAY_DEFAULT); pvfs->share_name = talloc_strdup(pvfs, scfg->name); pvfs->fs_attribs = FS_ATTR_CASE_SENSITIVE_SEARCH | FS_ATTR_CASE_PRESERVED_NAMES | FS_ATTR_UNICODE_ON_DISK | FS_ATTR_SPARSE_FILES; /* allow xattrs to be stored in a external tdb */ eadb = share_string_option(scfg, PVFS_EADB, NULL); if (eadb != NULL) { pvfs->ea_db = tdb_wrap_open(pvfs, eadb, 50000, TDB_DEFAULT, O_RDWR|O_CREAT, 0600); if (pvfs->ea_db != NULL) { pvfs->flags |= PVFS_FLAG_XATTR_ENABLE; } else { DEBUG(0,("Failed to open eadb '%s' - %s\n", eadb, strerror(errno))); pvfs->flags &= ~PVFS_FLAG_XATTR_ENABLE; } } if (pvfs->flags & PVFS_FLAG_XATTR_ENABLE) { pvfs->fs_attribs |= FS_ATTR_NAMED_STREAMS; } if (pvfs->flags & PVFS_FLAG_XATTR_ENABLE) { pvfs->fs_attribs |= FS_ATTR_PERSISTANT_ACLS; } pvfs->sid_cache.creator_owner = dom_sid_parse_talloc(pvfs, SID_CREATOR_OWNER); pvfs->sid_cache.creator_group = dom_sid_parse_talloc(pvfs, SID_CREATOR_GROUP); /* check if the system really supports xattrs */ if (pvfs->flags & PVFS_FLAG_XATTR_ENABLE) { pvfs_xattr_probe(pvfs); } /* enable an ACL backend */ pvfs->acl_ops = pvfs_acl_backend_byname(share_string_option(scfg, PVFS_ACL, "xattr")); }
struct db_context *db_open_tdb(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx, const char *name, int hash_size, int tdb_flags, int open_flags, mode_t mode, enum dbwrap_lock_order lock_order, uint64_t dbrwap_flags) { struct db_context *result = NULL; struct db_tdb_ctx *db_tdb; struct stat st; result = talloc_zero(mem_ctx, struct db_context); if (result == NULL) { DEBUG(0, ("talloc failed\n")); goto fail; } result->private_data = db_tdb = talloc(result, struct db_tdb_ctx); if (db_tdb == NULL) { DEBUG(0, ("talloc failed\n")); goto fail; } result->lock_order = lock_order; if (hash_size == 0) { hash_size = lpcfg_tdb_hash_size(lp_ctx, name); } db_tdb->wtdb = tdb_wrap_open(db_tdb, name, hash_size, lpcfg_tdb_flags(lp_ctx, tdb_flags), open_flags, mode); if (db_tdb->wtdb == NULL) { DEBUG(3, ("Could not open tdb: %s\n", strerror(errno))); goto fail; } ZERO_STRUCT(db_tdb->id); if (fstat(tdb_fd(db_tdb->wtdb->tdb), &st) == -1) { DEBUG(3, ("fstat failed: %s\n", strerror(errno))); goto fail; } db_tdb->id.dev = st.st_dev; db_tdb->id.ino = st.st_ino; result->fetch_locked = db_tdb_fetch_locked; result->try_fetch_locked = db_tdb_try_fetch_locked; result->traverse = db_tdb_traverse; result->traverse_read = db_tdb_traverse_read; result->parse_record = db_tdb_parse; result->get_seqnum = db_tdb_get_seqnum; result->persistent = ((tdb_flags & TDB_CLEAR_IF_FIRST) == 0); result->transaction_start = db_tdb_transaction_start; result->transaction_start_nonblock = db_tdb_transaction_start_nonblock; result->transaction_commit = db_tdb_transaction_commit; result->transaction_cancel = db_tdb_transaction_cancel; result->exists = db_tdb_exists; result->wipe = db_tdb_wipe; result->id = db_tdb_id; result->check = db_tdb_check; result->name = tdb_name(db_tdb->wtdb->tdb); result->hash_size = hash_size; return result; fail: TALLOC_FREE(result); return NULL; }
/* * Open sam.ldb.d/metadata.tdb. */ static int partition_metadata_open(struct ldb_module *module, bool create) { struct ldb_context *ldb = ldb_module_get_ctx(module); TALLOC_CTX *tmp_ctx; struct partition_private_data *data; struct loadparm_context *lp_ctx; const char *sam_name; char *filename, *dirname; int open_flags; struct stat statbuf; data = talloc_get_type_abort(ldb_module_get_private(module), struct partition_private_data); if (!data || !data->metadata) { return ldb_module_error(module, LDB_ERR_OPERATIONS_ERROR, "partition_metadata: metadata not initialized"); } tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ldb_module_oom(module); } sam_name = (const char *)ldb_get_opaque(ldb, "ldb_url"); if (!sam_name) { talloc_free(tmp_ctx); return ldb_operr(ldb); } if (strncmp("tdb://", sam_name, 6) == 0) { sam_name += 6; } filename = talloc_asprintf(tmp_ctx, "%s.d/metadata.tdb", sam_name); if (!filename) { talloc_free(tmp_ctx); return ldb_oom(ldb); } open_flags = O_RDWR; if (create) { open_flags |= O_CREAT; /* While provisioning, sam.ldb.d directory may not exist, * so create it. Ignore errors, if it already exists. */ dirname = talloc_asprintf(tmp_ctx, "%s.d", sam_name); if (!dirname) { talloc_free(tmp_ctx); return ldb_oom(ldb); } mkdir(dirname, 0700); talloc_free(dirname); } else { if (stat(filename, &statbuf) != 0) { talloc_free(tmp_ctx); return LDB_ERR_OPERATIONS_ERROR; } } lp_ctx = talloc_get_type_abort(ldb_get_opaque(ldb, "loadparm"), struct loadparm_context); data->metadata->db = tdb_wrap_open( data->metadata, filename, 10, lpcfg_tdb_flags(lp_ctx, TDB_DEFAULT), open_flags, 0660); if (data->metadata->db == NULL) { talloc_free(tmp_ctx); if (create) { ldb_asprintf_errstring(ldb, "partition_metadata: Unable to create %s: %s", filename, strerror(errno)); } else { ldb_asprintf_errstring(ldb, "partition_metadata: Unable to open %s: %s", filename, strerror(errno)); } if (errno == EACCES || errno == EPERM) { return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS; } return LDB_ERR_OPERATIONS_ERROR; } talloc_free(tmp_ctx); return LDB_SUCCESS; }