Beispiel #1
0
/* returns perfcount path for dbname allocated on talloc_tos */
static char *counters_directory(const char *dbname)
{
	char *dir_path = NULL;
	char *db_subpath = NULL;
	char *ret = NULL;

	dir_path = state_path(PERFCOUNTDIR);
	if (dir_path == NULL) {
		return NULL;
	}

	if (!directory_create_or_exist(dir_path, 0755)) {
		TALLOC_FREE(dir_path);
		return NULL;
	}

	db_subpath = talloc_asprintf(dir_path, "%s/%s", PERFCOUNTDIR, dbname);
	if (db_subpath == NULL) {
		TALLOC_FREE(dir_path);
		return NULL;
	}

	ret = state_path(db_subpath);
	TALLOC_FREE(dir_path);
	return ret;
}
Beispiel #2
0
WERROR regdb_open( void )
{
	WERROR result = WERR_OK;

	if ( regdb ) {
		DEBUG(10, ("regdb_open: incrementing refcount (%d->%d)\n",
			   regdb_refcount, regdb_refcount+1));
		regdb_refcount++;
		return WERR_OK;
	}

	become_root();

	regdb = db_open(NULL, state_path("registry.tdb"), 0,
			REG_TDB_FLAGS, O_RDWR, 0600,
			DBWRAP_LOCK_ORDER_1);
	if ( !regdb ) {
		result = ntstatus_to_werror( map_nt_error_from_unix( errno ) );
		DEBUG(0,("regdb_open: Failed to open %s! (%s)\n",
			state_path("registry.tdb"), strerror(errno) ));
	}

	unbecome_root();

	regdb_refcount = 1;
	DEBUG(10, ("regdb_open: registry db opened. refcount reset (%d)\n",
		   regdb_refcount));

	return result;
}
Beispiel #3
0
static bool do_winbind_online(struct tevent_context *ev_ctx,
			      struct messaging_context *msg_ctx,
			      const struct server_id pid,
			      const int argc, const char **argv)
{
	TDB_CONTEXT *tdb;

	if (argc != 1) {
		fprintf(stderr, "Usage: smbcontrol winbindd online\n");
		return False;
	}

	/* Remove the entry in the winbindd_cache tdb to tell a later
	   starting winbindd that we're online. */

	tdb = tdb_open_log(state_path("winbindd_cache.tdb"), 0, TDB_DEFAULT, O_RDWR, 0600);
	if (!tdb) {
		fprintf(stderr, "Cannot open the tdb %s for writing.\n",
			state_path("winbindd_cache.tdb"));
		return False;
	}

	tdb_delete_bystring(tdb, "WINBINDD_OFFLINE");
	tdb_close(tdb);

	return send_message(msg_ctx, pid, MSG_WINBIND_ONLINE, NULL, 0);
}
Beispiel #4
0
char *elog_tdbname(TALLOC_CTX *ctx, const char *name )
{
	char *path;
	char *file;
	char *tdbname;

	path = talloc_strdup(ctx, state_path("eventlog"));
	if (!path) {
		return NULL;
	}

	file = talloc_asprintf_strlower_m(path, "%s.tdb", name);
	if (!file) {
		talloc_free(path);
		return NULL;
	}

	tdbname = talloc_asprintf(path, "%s/%s", state_path("eventlog"), file);
	if (!tdbname) {
		talloc_free(path);
		return NULL;
	}

	return tdbname;
}
Beispiel #5
0
static bool tdbsam_upgrade_next_rid(struct db_context *db)
{
	TDB_CONTEXT *tdb;
	uint32 rid;
	bool ok = false;

	ok = dbwrap_fetch_uint32(db, NEXT_RID_STRING, &rid);
	if (ok) {
		return true;
	}

	tdb = tdb_open_log(state_path("winbindd_idmap.tdb"), 0,
			   TDB_DEFAULT, O_RDONLY, 0644);

	if (tdb) {
		ok = tdb_fetch_uint32(tdb, "RID_COUNTER", &rid);
		if (!ok) {
			rid = BASE_RID;
		}
		tdb_close(tdb);
	} else {
		rid = BASE_RID;
	}

	if (dbwrap_store_uint32(db, NEXT_RID_STRING, rid) != 0) {
		return false;
	}

	return true;
}
Beispiel #6
0
struct piiptyyt_state *state_read(GError **err_p)
{
	gchar *contents = NULL;
	gsize length = 0;
	GError *err = NULL;
	if(!g_file_get_contents(state_path(), &contents, &length, &err)) {
		if(err->code != ENOENT) {
			g_propagate_error(err_p, err);
			return NULL;
		} else {
			g_error_free(err);
			contents = g_strdup("");
		}
	}

	struct piiptyyt_state *st = NULL;
	GKeyFile *kf = g_key_file_new();
	gboolean ok = g_key_file_load_from_data(kf, contents, length, 0, err_p);
	if(ok) {
		st = g_new(struct piiptyyt_state, 1);
		st->username = g_key_file_get_string(kf, "auth", "username", NULL);
		st->auth_token = g_key_file_get_string(kf, "auth", "auth_token", NULL);
		st->auth_secret = g_key_file_get_string(kf, "auth", "auth_secret", NULL);
		st->userid = g_key_file_get_uint64(kf, "auth", "userid", NULL);
	}
	g_key_file_free(kf);
	g_free(contents);

	return st;
}
Beispiel #7
0
static bool acl_tdb_init(struct db_context **pp_db)
{
    char *dbname;

    if (acl_db) {
        *pp_db = acl_db;
        ref_count++;
        return true;
    }

    dbname = state_path("file_ntacls.tdb");

    if (dbname == NULL) {
        errno = ENOSYS;
        return false;
    }

    become_root();
    *pp_db = db_open(NULL, dbname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
    unbecome_root();

    if (*pp_db == NULL) {
#if defined(ENOTSUP)
        errno = ENOTSUP;
#else
        errno = ENOSYS;
#endif
        TALLOC_FREE(dbname);
        return false;
    }

    ref_count++;
    TALLOC_FREE(dbname);
    return true;
}
Beispiel #8
0
static bool acl_tdb_init(void)
{
	char *dbname;

	if (acl_db) {
		ref_count++;
		return true;
	}

	dbname = state_path("file_ntacls.tdb");

	if (dbname == NULL) {
		errno = ENOSYS;
		return false;
	}

	become_root();
	acl_db = db_open(NULL, dbname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600,
			 DBWRAP_LOCK_ORDER_1, DBWRAP_FLAG_NONE);
	unbecome_root();

	if (acl_db == NULL) {
#if defined(ENOTSUP)
		errno = ENOTSUP;
#else
		errno = ENOSYS;
#endif
		TALLOC_FREE(dbname);
		return false;
	}

	ref_count++;
	TALLOC_FREE(dbname);
	return true;
}
Beispiel #9
0
bool state_write(const struct piiptyyt_state *st, GError **err_p)
{
	const char *path = state_path();
	int fd = open(path, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
	if(fd == -1) {
		g_set_error(err_p, 0, errno, "open(2) failed: %s",
			g_strerror(errno));
		return false;
	}
	int n = fchmod(fd, 0600);
	if(n == -1) {
		g_set_error(err_p, 0, errno, "fchmod(2) failed: %s",
			g_strerror(errno));
		close(fd);
		return false;
	}

	GKeyFile *kf = g_key_file_new();
	g_key_file_set_string(kf, "auth", "username", st->username);
	g_key_file_set_string(kf, "auth", "auth_token", st->auth_token);
	g_key_file_set_string(kf, "auth", "auth_secret", st->auth_secret);
	g_key_file_set_uint64(kf, "auth", "userid", st->userid);

	gsize length = 0;
	gchar *contents = g_key_file_to_data(kf, &length, err_p);
	g_key_file_free(kf);

	/* FIXME: this should be re-engineered to write into a temporary file in
	 * the same directory with the appropriate mode, and then rename that file
	 * on top of the old file when the initial write has succeeded.
	 *
	 * i.e. this bit should be a function of its own.
	 */
	bool ret = false;
	if(contents != NULL) {
		off_t nn = lseek(fd, 0, SEEK_SET);
		if(nn == (off_t)-1) {
			/* FIXME: handle */
		}
		n = ftruncate(fd, length);
		if(n == -1) {
			/* FIXME: handle */
		}
		ssize_t n_wr = write(fd, contents, length);
		if(n_wr == -1) {
			/* FIXME: handle */
		} else if(n_wr != length) {
			/* FIXME: handle */
		} else {
			ret = true;
		}
		g_free(contents);
	}

	close(fd);
	return ret;
}
Beispiel #10
0
static char *counters_directory(const char *dbname)
{
	char *path = NULL;
	char *ret = NULL;
	TALLOC_CTX *ctx = talloc_tos();

	path = state_path(PERFCOUNTDIR);
	if (!directory_exist(path)) {
		mkdir(path, 0755);
	}

	path = talloc_asprintf(ctx, "%s/%s", PERFCOUNTDIR, dbname);
	if (!path) {
		return NULL;
	}

	ret = talloc_strdup(ctx, state_path(path));
	TALLOC_FREE(path);
	return ret;
}
Beispiel #11
0
char *elog_tdbname(TALLOC_CTX *ctx, const char *name )
{
	char *path = talloc_asprintf(ctx, "%s/%s.tdb",
			state_path("eventlog"),
			name);
	if (!path) {
		return NULL;
	}
	strlower_m(path);
	return path;
}
Beispiel #12
0
/*
  upgrade from a old style tdb
*/
static bool mapping_upgrade(const char *tdb_path)
{
	static TDB_CONTEXT *tdb;
	int ret, status=0;

	tdb = tdb_open_log(tdb_path, 0, TDB_DEFAULT, O_RDWR, 0600);
	if (tdb == NULL) goto failed;

	/* we have to do the map records first, as alias records may
	   reference them */
	ret = tdb_traverse(tdb, upgrade_map_record, &status);
	if (ret == -1 || status == -1) goto failed;

	ret = tdb_traverse(tdb, upgrade_alias_record, &status);
	if (ret == -1 || status == -1) goto failed;

	if (tdb) {
		tdb_close(tdb);
		tdb = NULL;
	}

	{
		const char *old_path = tdb_path;
		char *new_path = state_path("group_mapping.tdb.upgraded");

		if (!new_path) {
			goto failed;
		}
		if (rename(old_path, new_path) != 0) {
			DEBUG(0,("Failed to rename old group mapping database\n"));
			goto failed;
		}
	}
	return True;

failed:
	DEBUG(0,("Failed to upgrade group mapping database\n"));
	if (tdb) tdb_close(tdb);
	return False;
}
Beispiel #13
0
static bool tdbsam_upgrade_next_rid(struct db_context *db)
{
	TDB_CONTEXT *tdb;
	uint32_t rid;
	bool ok = false;
	NTSTATUS status;
	char *db_path;

	status = dbwrap_fetch_uint32_bystring(db, NEXT_RID_STRING, &rid);
	if (NT_STATUS_IS_OK(status)) {
		return true;
	}

	db_path = state_path("winbindd_idmap.tdb");
	if (db_path == NULL) {
		return false;
	}

	tdb = tdb_open_log(db_path, 0,
			   TDB_DEFAULT, O_RDONLY, 0644);
	TALLOC_FREE(db_path);
	if (tdb) {
		ok = tdb_fetch_uint32(tdb, "RID_COUNTER", &rid);
		if (!ok) {
			rid = BASE_RID;
		}
		tdb_close(tdb);
	} else {
		rid = BASE_RID;
	}

	status = dbwrap_store_uint32_bystring(db, NEXT_RID_STRING, rid);
	if (!NT_STATUS_IS_OK(status)) {
		return false;
	}

	return true;
}
Beispiel #14
0
ELOG_TDB *elog_open_tdb( const char *logname, bool force_clear, bool read_only )
{
	TDB_CONTEXT *tdb = NULL;
	uint32_t vers_id;
	ELOG_TDB *ptr;
	char *tdbpath = NULL;
	ELOG_TDB *tdb_node = NULL;
	char *eventlogdir;
	TALLOC_CTX *ctx = talloc_tos();

	/* check for invalid options */

	if (force_clear && read_only) {
		DEBUG(1,("elog_open_tdb: Invalid flags\n"));
		return NULL;
	}

	/* first see if we have an open context */

	for ( ptr=open_elog_list; ptr; ptr=ptr->next ) {
		if ( strequal( ptr->name, logname ) ) {
			ptr->ref_count++;

			/* trick to alow clearing of the eventlog tdb.
			   The force_clear flag should imply that someone
			   has done a force close.  So make sure the tdb
			   is NULL.  If this is a normal open, then just
			   return the existing reference */

			if ( force_clear ) {
				SMB_ASSERT( ptr->tdb == NULL );
				break;
			}
			else
				return ptr;
		}
	}

	/* make sure that the eventlog dir exists */

	eventlogdir = state_path( "eventlog" );
	if ( !directory_exist( eventlogdir ) )
		mkdir( eventlogdir, 0755 );

	/* get the path on disk */

	tdbpath = elog_tdbname(ctx, logname);
	if (!tdbpath) {
		return NULL;
	}

	DEBUG(7,("elog_open_tdb: Opening %s...(force_clear == %s)\n",
		tdbpath, force_clear?"True":"False" ));

	/* the tdb wasn't already open or this is a forced clear open */

	if ( !force_clear ) {

		tdb = tdb_open_log( tdbpath, 0, TDB_DEFAULT, read_only ? O_RDONLY : O_RDWR , 0 );
		if ( tdb ) {
			vers_id = tdb_fetch_int32( tdb, EVT_VERSION );

			if ( vers_id != EVENTLOG_DATABASE_VERSION_V1 ) {
				DEBUG(1,("elog_open_tdb: Invalid version [%d] on file [%s].\n",
					vers_id, tdbpath));
				tdb_close( tdb );
				tdb = elog_init_tdb( tdbpath );
			}
		}
	}

	if ( !tdb )
		tdb = elog_init_tdb( tdbpath );

	/* if we got a valid context, then add it to the list */

	if ( tdb ) {
		/* on a forced clear, just reset the tdb context if we already
		   have an open entry in the list */

		if ( ptr ) {
			ptr->tdb = tdb;
			return ptr;
		}

		if ( !(tdb_node = TALLOC_ZERO_P( NULL, ELOG_TDB)) ) {
			DEBUG(0,("elog_open_tdb: talloc() failure!\n"));
			tdb_close( tdb );
			return NULL;
		}

		tdb_node->name = talloc_strdup( tdb_node, logname );
		tdb_node->tdb = tdb;
		tdb_node->ref_count = 1;

		DLIST_ADD( open_elog_list, tdb_node );
	}

	return tdb_node;
}
Beispiel #15
0
static bool do_winbind_offline(struct tevent_context *ev_ctx,
			       struct messaging_context *msg_ctx,
			       const struct server_id pid,
			       const int argc, const char **argv)
{
	TDB_CONTEXT *tdb;
	bool ret = False;
	int retry = 0;

	if (argc != 1) {
		fprintf(stderr, "Usage: smbcontrol winbindd offline\n");
		return False;
	}

	/* Create an entry in the winbindd_cache tdb to tell a later
	   starting winbindd that we're offline. We may actually create
	   it here... */

	tdb = tdb_open_log(state_path("winbindd_cache.tdb"),
				WINBINDD_CACHE_TDB_DEFAULT_HASH_SIZE,
				TDB_DEFAULT|TDB_INCOMPATIBLE_HASH /* TDB_CLEAR_IF_FIRST */,
				O_RDWR|O_CREAT, 0600);

	if (!tdb) {
		fprintf(stderr, "Cannot open the tdb %s for writing.\n",
			state_path("winbindd_cache.tdb"));
		return False;
	}

	/* There's a potential race condition that if a child
	   winbindd detects a domain is online at the same time
	   we're trying to tell it to go offline that it might 
	   delete the record we add between us adding it and
	   sending the message. Minimize this by retrying up to
	   5 times. */

	for (retry = 0; retry < 5; retry++) {
		TDB_DATA d;
		uint8 buf[4];

		ZERO_STRUCT(d);

		SIVAL(buf, 0, time(NULL));
		d.dptr = buf;
		d.dsize = 4;

		tdb_store_bystring(tdb, "WINBINDD_OFFLINE", d, TDB_INSERT);

		ret = send_message(msg_ctx, pid, MSG_WINBIND_OFFLINE,
				   NULL, 0);

		/* Check that the entry "WINBINDD_OFFLINE" still exists. */
		d = tdb_fetch_bystring( tdb, "WINBINDD_OFFLINE" );

		if (!d.dptr || d.dsize != 4) {
			SAFE_FREE(d.dptr);
			DEBUG(10,("do_winbind_offline: offline state not set - retrying.\n"));
		} else {
			SAFE_FREE(d.dptr);
			break;
		}
	}

	tdb_close(tdb);
	return ret;
}
Beispiel #16
0
static bool do_winbind_offline(struct tevent_context *ev_ctx,
			       struct messaging_context *msg_ctx,
			       const struct server_id pid,
			       const int argc, const char **argv)
{
	TDB_CONTEXT *tdb;
	bool ret = False;
	int retry = 0;
	char *db_path;

	if (argc != 1) {
		fprintf(stderr, "Usage: smbcontrol winbindd offline\n");
		return False;
	}

	db_path = state_path("winbindd_cache.tdb");
	if (db_path == NULL) {
		return false;
	}

	/* Create an entry in the winbindd_cache tdb to tell a later
	   starting winbindd that we're offline. We may actually create
	   it here... */

	tdb = tdb_open_log(db_path,
				WINBINDD_CACHE_TDB_DEFAULT_HASH_SIZE,
				TDB_DEFAULT|TDB_INCOMPATIBLE_HASH /* TDB_CLEAR_IF_FIRST */,
				O_RDWR|O_CREAT, 0600);

	if (!tdb) {
		fprintf(stderr, "Cannot open the tdb %s for writing.\n",
			db_path);
		TALLOC_FREE(db_path);
		return False;
	}
	TALLOC_FREE(db_path);

	/* There's a potential race condition that if a child
	   winbindd detects a domain is online at the same time
	   we're trying to tell it to go offline that it might 
	   delete the record we add between us adding it and
	   sending the message. Minimize this by retrying up to
	   5 times. */

	for (retry = 0; retry < 5; retry++) {
		uint8_t buf[4];
		TDB_DATA d = { .dptr = buf, .dsize = sizeof(buf) };

		SIVAL(buf, 0, time(NULL));

		tdb_store_bystring(tdb, "WINBINDD_OFFLINE", d, TDB_INSERT);

		ret = send_message(msg_ctx, pid, MSG_WINBIND_OFFLINE,
				   NULL, 0);

		/* Check that the entry "WINBINDD_OFFLINE" still exists. */
		d = tdb_fetch_bystring( tdb, "WINBINDD_OFFLINE" );

		if (!d.dptr || d.dsize != 4) {
			SAFE_FREE(d.dptr);
			DEBUG(10,("do_winbind_offline: offline state not set - retrying.\n"));
		} else {
			SAFE_FREE(d.dptr);
			break;
		}
	}

	tdb_close(tdb);
	return ret;
}

static bool do_winbind_onlinestatus(struct tevent_context *ev_ctx,
				    struct messaging_context *msg_ctx,
				    const struct server_id pid,
				    const int argc, const char **argv)
{
	struct server_id myid;

	myid = messaging_server_id(msg_ctx);

	if (argc != 1) {
		fprintf(stderr, "Usage: smbcontrol winbindd onlinestatus\n");
		return False;
	}

	messaging_register(msg_ctx, NULL, MSG_WINBIND_ONLINESTATUS,
			   print_pid_string_cb);

	if (!send_message(msg_ctx, pid, MSG_WINBIND_ONLINESTATUS, &myid,
			  sizeof(myid)))
		return False;

	wait_replies(ev_ctx, msg_ctx, procid_to_pid(&pid) == 0);

	/* No replies were received within the timeout period */

	if (num_replies == 0)
		printf("No replies received\n");

	messaging_deregister(msg_ctx, MSG_WINBIND_ONLINESTATUS, NULL);

	return num_replies;
}

static bool do_dump_event_list(struct tevent_context *ev_ctx,
			       struct messaging_context *msg_ctx,
			       const struct server_id pid,
			       const int argc, const char **argv)
{
	if (argc != 1) {
		fprintf(stderr, "Usage: smbcontrol <dest> dump-event-list\n");
		return False;
	}

	return send_message(msg_ctx, pid, MSG_DUMP_EVENT_LIST, NULL, 0);
}

static bool do_winbind_dump_domain_list(struct tevent_context *ev_ctx,
					struct messaging_context *msg_ctx,
					const struct server_id pid,
					const int argc, const char **argv)
{
	const char *domain = NULL;
	int domain_len = 0;
	struct server_id myid;
	uint8_t *buf = NULL;
	int buf_len = 0;

	myid = messaging_server_id(msg_ctx);

	if (argc < 1 || argc > 2) {
		fprintf(stderr, "Usage: smbcontrol <dest> dump-domain-list "
			"<domain>\n");
		return false;
	}

	if (argc == 2) {
		domain = argv[1];
		domain_len = strlen(argv[1]) + 1;
	}

	messaging_register(msg_ctx, NULL, MSG_WINBIND_DUMP_DOMAIN_LIST,
			   print_pid_string_cb);

	buf_len = sizeof(myid)+domain_len;
	buf = SMB_MALLOC_ARRAY(uint8_t, buf_len);
	if (!buf) {
		return false;
	}

	memcpy(buf, &myid, sizeof(myid));
	memcpy(&buf[sizeof(myid)], domain, domain_len);

	if (!send_message(msg_ctx, pid, MSG_WINBIND_DUMP_DOMAIN_LIST,
			  buf, buf_len))
	{
		SAFE_FREE(buf);
		return false;
	}

	wait_replies(ev_ctx, msg_ctx, procid_to_pid(&pid) == 0);

	/* No replies were received within the timeout period */

	SAFE_FREE(buf);
	if (num_replies == 0) {
		printf("No replies received\n");
	}

	messaging_deregister(msg_ctx, MSG_WINBIND_DUMP_DOMAIN_LIST, NULL);

	return num_replies;
}

static void winbind_validate_cache_cb(struct messaging_context *msg,
				      void *private_data,
				      uint32_t msg_type,
				      struct server_id pid,
				      DATA_BLOB *data)
{
	struct server_id_buf src_string;
	printf("Winbindd cache is %svalid. (answer from pid %s)\n",
	       (*(data->data) == 0 ? "" : "NOT "),
	       server_id_str_buf(pid, &src_string));
	num_replies++;
}

static bool do_winbind_validate_cache(struct tevent_context *ev_ctx,
				      struct messaging_context *msg_ctx,
				      const struct server_id pid,
				      const int argc, const char **argv)
{
	struct server_id myid;

	myid = messaging_server_id(msg_ctx);

	if (argc != 1) {
		fprintf(stderr, "Usage: smbcontrol winbindd validate-cache\n");
		return False;
	}

	messaging_register(msg_ctx, NULL, MSG_WINBIND_VALIDATE_CACHE,
			   winbind_validate_cache_cb);

	if (!send_message(msg_ctx, pid, MSG_WINBIND_VALIDATE_CACHE, &myid,
			  sizeof(myid))) {
		return False;
	}

	wait_replies(ev_ctx, msg_ctx, procid_to_pid(&pid) == 0);

	if (num_replies == 0) {
		printf("No replies received\n");
	}

	messaging_deregister(msg_ctx, MSG_WINBIND_VALIDATE_CACHE, NULL);

	return num_replies;
}

static bool do_reload_config(struct tevent_context *ev_ctx,
			     struct messaging_context *msg_ctx,
			     const struct server_id pid,
			     const int argc, const char **argv)
{
	if (argc != 1) {
		fprintf(stderr, "Usage: smbcontrol <dest> reload-config\n");
		return False;
	}

	return send_message(msg_ctx, pid, MSG_SMB_CONF_UPDATED, NULL, 0);
}

static bool do_reload_printers(struct tevent_context *ev_ctx,
			       struct messaging_context *msg_ctx,
			       const struct server_id pid,
			       const int argc, const char **argv)
{
	if (argc != 1) {
		fprintf(stderr, "Usage: smbcontrol <dest> reload-printers\n");
		return False;
	}

	return send_message(msg_ctx, pid, MSG_PRINTER_PCAP, NULL, 0);
}

static void my_make_nmb_name( struct nmb_name *n, const char *name, int type)
{
	fstring unix_name;
	memset( (char *)n, '\0', sizeof(struct nmb_name) );
	fstrcpy(unix_name, name);
	(void)strupper_m(unix_name);
	push_ascii(n->name, unix_name, sizeof(n->name), STR_TERMINATE);
	n->name_type = (unsigned int)type & 0xFF;
	push_ascii(n->scope,  lp_netbios_scope(), 64, STR_TERMINATE);
}
Beispiel #17
0
static NTSTATUS idmap_tdb_open_db(struct idmap_domain *dom)
{
	NTSTATUS ret;
	TALLOC_CTX *mem_ctx;
	char *tdbfile = NULL;
	struct db_context *db = NULL;
	int32_t version;
	bool config_error = false;
	struct idmap_tdb_context *ctx;

	ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context);

	if (ctx->db) {
		/* it is already open */
		return NT_STATUS_OK;
	}

	/* use our own context here */
	mem_ctx = talloc_stackframe();

	/* use the old database if present */
	tdbfile = state_path("winbindd_idmap.tdb");
	if (!tdbfile) {
		DEBUG(0, ("Out of memory!\n"));
		ret = NT_STATUS_NO_MEMORY;
		goto done;
	}

	DEBUG(10,("Opening tdbfile %s\n", tdbfile ));

	/* Open idmap repository */
	db = db_open(mem_ctx, tdbfile, 0, TDB_DEFAULT, O_RDWR | O_CREAT, 0644);
	if (!db) {
		DEBUG(0, ("Unable to open idmap database\n"));
		ret = NT_STATUS_UNSUCCESSFUL;
		goto done;
	}

	/* check against earlier versions */
	ret = dbwrap_fetch_int32(db, "IDMAP_VERSION", &version);
	if (!NT_STATUS_IS_OK(ret)) {
		version = -1;
	}

	if (version != IDMAP_VERSION) {
		if (config_error) {
			DEBUG(0,("Upgrade of IDMAP_VERSION from %d to %d is not "
				 "possible with incomplete configuration\n",
				 version, IDMAP_VERSION));
			ret = NT_STATUS_UNSUCCESSFUL;
			goto done;
		}
		if (dbwrap_transaction_start(db) != 0) {
			DEBUG(0, ("Unable to start upgrade transaction!\n"));
			ret = NT_STATUS_INTERNAL_DB_ERROR;
			goto done;
		}

		if (!idmap_tdb_upgrade(dom, db)) {
			dbwrap_transaction_cancel(db);
			DEBUG(0, ("Unable to open idmap database, it's in an old format, and upgrade failed!\n"));
			ret = NT_STATUS_INTERNAL_DB_ERROR;
			goto done;
		}

		if (dbwrap_transaction_commit(db) != 0) {
			DEBUG(0, ("Unable to commit upgrade transaction!\n"));
			ret = NT_STATUS_INTERNAL_DB_ERROR;
			goto done;
		}
	}

	ctx->db = talloc_move(ctx, &db);

	ret = idmap_tdb_init_hwm(dom);

done:
	talloc_free(mem_ctx);
	return ret;
}
Beispiel #18
0
/*
  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;
}
Beispiel #19
0
/****************************************************************************
 Open the group mapping tdb.
****************************************************************************/
static bool init_group_mapping(void)
{
	if (db != NULL) {
		return true;
	}

	db = db_open_trans(NULL, state_path("group_mapping.tdb"), 0,
			   TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
	if (db == NULL) {
		DEBUG(0, ("Failed to open group mapping database: %s\n",
			  strerror(errno)));
		return false;
	}

#if 0
	/*
	 * This code was designed to handle a group mapping version
	 * upgrade. mapping_tdb is not active by default anymore, so ignore
	 * this here.
	 */
	{
		const char *vstring = "INFO/version";
		int32 vers_id;
		GROUP_MAP *map_table = NULL;
		size_t num_entries = 0;

		/* handle a Samba upgrade */
		tdb_lock_bystring(tdb, vstring);

		/* Cope with byte-reversed older versions of the db. */
		vers_id = tdb_fetch_int32(tdb, vstring);
		if ((vers_id == DATABASE_VERSION_V1)
		    || (IREV(vers_id) == DATABASE_VERSION_V1)) {
			/*
			 * Written on a bigendian machine with old fetch_int
			 * code. Save as le.
			 */
			tdb_store_int32(tdb, vstring, DATABASE_VERSION_V2);
			vers_id = DATABASE_VERSION_V2;
		}

		/* if its an unknown version we remove everthing in the db */

		if (vers_id != DATABASE_VERSION_V2) {
			tdb_wipe_all(tdb);
			tdb_store_int32(tdb, vstring, DATABASE_VERSION_V2);
		}

		tdb_unlock_bystring(tdb, vstring);

		/* cleanup any map entries with a gid == -1 */

		if ( enum_group_mapping( NULL, SID_NAME_UNKNOWN, &map_table,
					 &num_entries, False ) ) {
			int i;

			for ( i=0; i<num_entries; i++ ) {
				if ( map_table[i].gid == -1 ) {
					group_map_remove( &map_table[i].sid );
				}
			}

			SAFE_FREE( map_table );
		}
	}
#endif

	return true;
}
bool nt_printing_tdb_migrate(struct messaging_context *msg_ctx)
{
	const char *drivers_path;
	const char *printers_path;
	const char *forms_path;
	bool drivers_exists;
	bool printers_exists;
	bool forms_exists;
	struct auth_session_info *session_info;
	struct rpc_pipe_client *winreg_pipe = NULL;
	TALLOC_CTX *tmp_ctx = talloc_stackframe();
	NTSTATUS status;

	/* paths talloced on new stackframe */
	drivers_path = state_path("ntdrivers.tdb");
	printers_path = state_path("ntprinters.tdb");
	forms_path = state_path("ntforms.tdb");
	if ((drivers_path == NULL) || (printers_path == NULL)
						|| (forms_path == NULL)) {
		talloc_free(tmp_ctx);
		return false;
	}
	drivers_exists = file_exist(drivers_path);
	printers_exists = file_exist(printers_path);
	forms_exists = file_exist(forms_path);

	if (!drivers_exists && !printers_exists && !forms_exists) {
		talloc_free(tmp_ctx);
		return true;
	}

	status = make_session_info_system(tmp_ctx, &session_info);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0, ("Couldn't create session_info: %s\n",
			  nt_errstr(status)));
		talloc_free(tmp_ctx);
		return false;
	}

	status = rpc_pipe_open_interface(tmp_ctx,
					&ndr_table_winreg,
					session_info,
					NULL,
					NULL,
					msg_ctx,
					&winreg_pipe);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0, ("Couldn't open internal winreg pipe: %s\n",
			  nt_errstr(status)));
		talloc_free(tmp_ctx);
		return false;
	}

	if (drivers_exists) {
		status = migrate_internal(tmp_ctx, drivers_path, winreg_pipe);
		if (!NT_STATUS_IS_OK(status)) {
			DEBUG(0, ("Couldn't migrate drivers tdb file: %s\n",
			  nt_errstr(status)));
			talloc_free(tmp_ctx);
			return false;
		}
	}

	if (printers_exists) {
		status = migrate_internal(tmp_ctx, printers_path, winreg_pipe);
		if (!NT_STATUS_IS_OK(status)) {
			DEBUG(0, ("Couldn't migrate printers tdb file: %s\n",
				  nt_errstr(status)));
			talloc_free(tmp_ctx);
			return false;
		}
	}

	if (forms_exists) {
		status = migrate_internal(tmp_ctx, forms_path, winreg_pipe);
		if (!NT_STATUS_IS_OK(status)) {
			DEBUG(0, ("Couldn't migrate forms tdb file: %s\n",
				  nt_errstr(status)));
			talloc_free(tmp_ctx);
			return false;
		}
	}

	talloc_free(tmp_ctx);
	return true;
}
Beispiel #21
0
bool share_info_db_init(void)
{
	const char *vstring = "INFO/version";
	int32 vers_id = 0;
	bool upgrade_ok = true;
	NTSTATUS status;

	if (share_db != NULL) {
		return True;
	}

	share_db = db_open(NULL, state_path("share_info.tdb"), 0,
				 TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
	if (share_db == NULL) {
		DEBUG(0,("Failed to open share info database %s (%s)\n",
			state_path("share_info.tdb"), strerror(errno) ));
		return False;
	}

	status = dbwrap_fetch_int32(share_db, vstring, &vers_id);
	if (!NT_STATUS_IS_OK(status)) {
		vers_id = 0;
	}

	if (vers_id == SHARE_DATABASE_VERSION_V3) {
		return true;
	}

	if (dbwrap_transaction_start(share_db) != 0) {
		DEBUG(0, ("transaction_start failed\n"));
		TALLOC_FREE(share_db);
		return false;
	}

	status = dbwrap_fetch_int32(share_db, vstring, &vers_id);
	if (!NT_STATUS_IS_OK(status)) {
		vers_id = 0;
	}

	if (vers_id == SHARE_DATABASE_VERSION_V3) {
		/*
		 * Race condition
		 */
		if (dbwrap_transaction_cancel(share_db)) {
			smb_panic("transaction_cancel failed");
		}
		return true;
	}

	/* Move to at least V2. */

	/* Cope with byte-reversed older versions of the db. */
	if ((vers_id == SHARE_DATABASE_VERSION_V1) || (IREV(vers_id) == SHARE_DATABASE_VERSION_V1)) {
		/* Written on a bigendian machine with old fetch_int code. Save as le. */

		status = dbwrap_store_int32(share_db, vstring,
					    SHARE_DATABASE_VERSION_V2);
		if (!NT_STATUS_IS_OK(status)) {
			DEBUG(0, ("dbwrap_store_int32 failed: %s\n",
				  nt_errstr(status)));
			goto cancel;
		}
		vers_id = SHARE_DATABASE_VERSION_V2;
	}

	if (vers_id != SHARE_DATABASE_VERSION_V2) {
		status = dbwrap_traverse(share_db, delete_fn, NULL, NULL);
		if (!NT_STATUS_IS_OK(status)) {
			DEBUG(0, ("traverse failed\n"));
			goto cancel;
		}
		status = dbwrap_store_int32(share_db, vstring,
					    SHARE_DATABASE_VERSION_V2);
		if (!NT_STATUS_IS_OK(status)) {
			DEBUG(0, ("dbwrap_store_int32 failed: %s\n",
				  nt_errstr(status)));
			goto cancel;
		}
	}

	/* Finally upgrade to version 3, with canonicalized sharenames. */

	status = dbwrap_traverse(share_db, upgrade_v2_to_v3, &upgrade_ok, NULL);
	if (!NT_STATUS_IS_OK(status) || upgrade_ok == false) {
		DEBUG(0, ("traverse failed\n"));
		goto cancel;
	}
	status = dbwrap_store_int32(share_db, vstring,
				    SHARE_DATABASE_VERSION_V3);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0, ("dbwrap_store_int32 failed: %s\n",
			  nt_errstr(status)));
		goto cancel;
	}

	if (dbwrap_transaction_commit(share_db) != 0) {
		DEBUG(0, ("transaction_commit failed\n"));
		return false;
	}

	return true;

 cancel:
	if (dbwrap_transaction_cancel(share_db)) {
		smb_panic("transaction_cancel failed");
	}

	return false;
}
Beispiel #22
0
WERROR regdb_init(void)
{
	int32_t vers_id;
	WERROR werr;
	NTSTATUS status;

	if (regdb) {
		DEBUG(10, ("regdb_init: incrementing refcount (%d->%d)\n",
			   regdb_refcount, regdb_refcount+1));
		regdb_refcount++;
		return WERR_OK;
	}

	regdb = db_open(NULL, state_path("registry.tdb"), 0,
			REG_TDB_FLAGS, O_RDWR, 0600,
			DBWRAP_LOCK_ORDER_1);
	if (!regdb) {
		regdb = db_open(NULL, state_path("registry.tdb"), 0,
				REG_TDB_FLAGS, O_RDWR|O_CREAT, 0600,
				DBWRAP_LOCK_ORDER_1);
		if (!regdb) {
			werr = ntstatus_to_werror(map_nt_error_from_unix(errno));
			DEBUG(1,("regdb_init: Failed to open registry %s (%s)\n",
				state_path("registry.tdb"), strerror(errno) ));
			return werr;
		}

		werr = regdb_store_regdb_version(regdb, REGDB_CODE_VERSION);
		if (!W_ERROR_IS_OK(werr)) {
			DEBUG(1, ("regdb_init: Failed to store version: %s\n",
				  win_errstr(werr)));
			return werr;
		}

		DEBUG(10,("regdb_init: Successfully created registry tdb\n"));
	}

	regdb_refcount = 1;
	DEBUG(10, ("regdb_init: registry db openend. refcount reset (%d)\n",
		   regdb_refcount));

	status = dbwrap_fetch_int32(regdb, REGDB_VERSION_KEYNAME, &vers_id);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(10, ("regdb_init: registry version uninitialized "
			   "(got %d), initializing to version %d\n",
			   vers_id, REGDB_VERSION_V1));

		/*
		 * There was a regdb format version prior to version 1
		 * which did not store a INFO/version key. The format
		 * of this version was identical to version 1 except for
		 * the lack of the sorted subkey cache records.
		 * Since these are disposable, we can safely assume version
		 * 1 if no INFO/version key is found and run the db through
		 * the whole chain of upgrade. If the database was not
		 * initialized, this does not harm. If it was the unversioned
		 * version ("0"), then it do the right thing with the records.
		 */
		werr = regdb_store_regdb_version(regdb, REGDB_VERSION_V1);
		if (!W_ERROR_IS_OK(werr)) {
			return werr;
		}
		vers_id = REGDB_VERSION_V1;
	}

	if (vers_id == REGDB_CODE_VERSION) {
		return WERR_OK;
	}

	if (vers_id > REGDB_CODE_VERSION || vers_id == 0) {
		DEBUG(0, ("regdb_init: unknown registry version %d "
			  "(code version = %d), refusing initialization\n",
			  vers_id, REGDB_CODE_VERSION));
		return WERR_CAN_NOT_COMPLETE;
	}

	if (dbwrap_transaction_start(regdb) != 0) {
		return WERR_REG_IO_FAILURE;
	}

	if (vers_id == REGDB_VERSION_V1) {
		DEBUG(10, ("regdb_init: upgrading registry from version %d "
			   "to %d\n", REGDB_VERSION_V1, REGDB_VERSION_V2));

		werr = regdb_upgrade_v1_to_v2(regdb);
		if (!W_ERROR_IS_OK(werr)) {
			dbwrap_transaction_cancel(regdb);
			return werr;
		}

		vers_id = REGDB_VERSION_V2;
	}

	if (vers_id == REGDB_VERSION_V2) {
		DEBUG(10, ("regdb_init: upgrading registry from version %d "
			   "to %d\n", REGDB_VERSION_V2, REGDB_VERSION_V3));

		werr = regdb_upgrade_v2_to_v3(regdb);
		if (!W_ERROR_IS_OK(werr)) {
			dbwrap_transaction_cancel(regdb);
			return werr;
		}

		vers_id = REGDB_VERSION_V3;
	}

	/* future upgrade code should go here */

	if (dbwrap_transaction_commit(regdb) != 0) {
		return WERR_REG_IO_FAILURE;
	}

	return WERR_OK;
}
/****************************************************************************
 Open the group mapping tdb.
****************************************************************************/
static bool init_group_mapping(void)
{
	const char *ldb_path;

	if (db != NULL) {
		return true;
	}

	db = db_open(NULL, state_path("group_mapping.tdb"), 0,
		     TDB_DEFAULT, O_RDWR|O_CREAT, 0600,
		     DBWRAP_LOCK_ORDER_1);
	if (db == NULL) {
		DEBUG(0, ("Failed to open group mapping database: %s\n",
			  strerror(errno)));
		return false;
	}

	ldb_path = state_path("group_mapping.ldb");
	if (file_exist(ldb_path) && !mapping_switch(ldb_path)) {
		unlink(state_path("group_mapping.tdb"));
		return false;

	} else {
		/* handle upgrade from old versions of the database */
#if 0 /* -- Needs conversion to dbwrap -- */
		const char *vstring = "INFO/version";
		int32 vers_id;
		GROUP_MAP *map_table = NULL;
		size_t num_entries = 0;

		/* handle a Samba upgrade */
		tdb_lock_bystring(tdb, vstring);

		/* Cope with byte-reversed older versions of the db. */
		vers_id = tdb_fetch_int32(tdb, vstring);
		if ((vers_id == DATABASE_VERSION_V1)
		    || (IREV(vers_id) == DATABASE_VERSION_V1)) {
			/*
			 * Written on a bigendian machine with old fetch_int
			 * code. Save as le.
			 */
			tdb_store_int32(tdb, vstring, DATABASE_VERSION_V2);
			vers_id = DATABASE_VERSION_V2;
		}

		/* if its an unknown version we remove everthing in the db */

		if (vers_id != DATABASE_VERSION_V2) {
			tdb_wipe_all(tdb);
			tdb_store_int32(tdb, vstring, DATABASE_VERSION_V2);
		}

		tdb_unlock_bystring(tdb, vstring);

		/* cleanup any map entries with a gid == -1 */

		if ( enum_group_mapping( NULL, SID_NAME_UNKNOWN, &map_table,
					 &num_entries, False ) ) {
			int i;

			for ( i=0; i<num_entries; i++ ) {
				if ( map_table[i].gid == -1 ) {
					group_map_remove( &map_table[i].sid );
				}
			}

			SAFE_FREE( map_table );
		}
#endif
	}
	return true;
}
Beispiel #24
0
WERROR regdb_init(void)
{
	const char *vstring = "INFO/version";
	uint32 vers_id, expected_version;
	WERROR werr;

	if (regdb) {
		DEBUG(10, ("regdb_init: incrementing refcount (%d->%d)\n",
			   regdb_refcount, regdb_refcount+1));
		regdb_refcount++;
		return WERR_OK;
	}

	regdb = db_open(NULL, state_path("registry.tdb"), 0,
			      REG_TDB_FLAGS, O_RDWR, 0600);
	if (!regdb) {
		regdb = db_open(NULL, state_path("registry.tdb"), 0,
				      REG_TDB_FLAGS, O_RDWR|O_CREAT, 0600);
		if (!regdb) {
			werr = ntstatus_to_werror(map_nt_error_from_unix(errno));
			DEBUG(1,("regdb_init: Failed to open registry %s (%s)\n",
				state_path("registry.tdb"), strerror(errno) ));
			return werr;
		}

		DEBUG(10,("regdb_init: Successfully created registry tdb\n"));
	}

	regdb_refcount = 1;
	DEBUG(10, ("regdb_init: registry db openend. refcount reset (%d)\n",
		   regdb_refcount));

	expected_version = REGVER_V2;

	vers_id = dbwrap_fetch_int32(regdb, vstring);
	if (vers_id == -1) {
		DEBUG(10, ("regdb_init: registry version uninitialized "
			   "(got %d), initializing to version %d\n",
			   vers_id, expected_version));

		werr = regdb_store_regdb_version(expected_version);
		return werr;
	}

	if (vers_id > expected_version || vers_id == 0) {
		DEBUG(1, ("regdb_init: unknown registry version %d "
			  "(code version = %d), refusing initialization\n",
			  vers_id, expected_version));
		return WERR_CAN_NOT_COMPLETE;
	}

	if (vers_id == REGVER_V1) {
		DEBUG(10, ("regdb_init: got registry db version %d, upgrading "
			   "to version %d\n", REGVER_V1, REGVER_V2));

		if (regdb->transaction_start(regdb) != 0) {
			return WERR_REG_IO_FAILURE;
		}

		werr = regdb_upgrade_v1_to_v2();
		if (!W_ERROR_IS_OK(werr)) {
			regdb->transaction_cancel(regdb);
			return werr;
		}

		if (regdb->transaction_commit(regdb) != 0) {
			return WERR_REG_IO_FAILURE;
		}

		vers_id = REGVER_V2;
	}

	/* future upgrade code should go here */

	return WERR_OK;
}
Beispiel #25
0
bool share_info_db_init(void)
{
	const char *vstring = "INFO/version";
	int32 vers_id;

	if (share_db != NULL) {
		return True;
	}

	share_db = db_open(NULL, state_path("share_info.tdb"), 0,
				 TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
	if (share_db == NULL) {
		DEBUG(0,("Failed to open share info database %s (%s)\n",
			state_path("share_info.tdb"), strerror(errno) ));
		return False;
	}

	vers_id = dbwrap_fetch_int32(share_db, vstring);
	if (vers_id == SHARE_DATABASE_VERSION_V2) {
		return true;
	}

	if (share_db->transaction_start(share_db) != 0) {
		DEBUG(0, ("transaction_start failed\n"));
		TALLOC_FREE(share_db);
		return false;
	}

	vers_id = dbwrap_fetch_int32(share_db, vstring);
	if (vers_id == SHARE_DATABASE_VERSION_V2) {
		/*
		 * Race condition
		 */
		if (share_db->transaction_cancel(share_db)) {
			smb_panic("transaction_cancel failed");
		}
		return true;
	}

	/* Cope with byte-reversed older versions of the db. */
	if ((vers_id == SHARE_DATABASE_VERSION_V1) || (IREV(vers_id) == SHARE_DATABASE_VERSION_V1)) {
		/* Written on a bigendian machine with old fetch_int code. Save as le. */

		if (dbwrap_store_int32(share_db, vstring,
				       SHARE_DATABASE_VERSION_V2) != 0) {
			DEBUG(0, ("dbwrap_store_int32 failed\n"));
			goto cancel;
		}
		vers_id = SHARE_DATABASE_VERSION_V2;
	}

	if (vers_id != SHARE_DATABASE_VERSION_V2) {
		int ret;
		ret = share_db->traverse(share_db, delete_fn, NULL);
		if (ret < 0) {
			DEBUG(0, ("traverse failed\n"));
			goto cancel;
		}
		if (dbwrap_store_int32(share_db, vstring,
				       SHARE_DATABASE_VERSION_V2) != 0) {
			DEBUG(0, ("dbwrap_store_int32 failed\n"));
			goto cancel;
		}
	}

	if (share_db->transaction_commit(share_db) != 0) {
		DEBUG(0, ("transaction_commit failed\n"));
		return false;
	}

	return true;

 cancel:
	if (share_db->transaction_cancel(share_db)) {
		smb_panic("transaction_cancel failed");
	}

	return false;
}