예제 #1
0
파일: locking.c 프로젝트: livebox/livebox2
BOOL set_share_mode(files_struct *fsp, uint16 port, uint16 op_type)
{
	TDB_DATA dbuf;
	struct locking_data *data;
	char *p=NULL;
	int size;
	BOOL ret = True;

	/* read in the existing share modes if any */
	dbuf = tdb_fetch(tdb, locking_key_fsp(fsp));
	if (!dbuf.dptr) {
		size_t offset;
		/* we'll need to create a new record */
		pstring fname;

		pstrcpy(fname, fsp->conn->connectpath);
		pstrcat(fname, "/");
		pstrcat(fname, fsp->fsp_name);

		size = sizeof(*data) + sizeof(share_mode_entry) + strlen(fname) + 1;
		p = (char *)malloc(size);
		if (!p)
			return False;
		data = (struct locking_data *)p;
		data->u.num_share_mode_entries = 1;

		DEBUG(10,("set_share_mode: creating entry for file %s. num_share_modes = 1\n",
			fsp->fsp_name ));

		offset = sizeof(*data) + sizeof(share_mode_entry);
		safe_strcpy(p + offset, fname, size - offset - 1);
		fill_share_mode(p + sizeof(*data), fsp, port, op_type);
		dbuf.dptr = p;
		dbuf.dsize = size;
		if (tdb_store(tdb, locking_key_fsp(fsp), dbuf, TDB_REPLACE) == -1)
			ret = False;

		print_share_mode_table((struct locking_data *)p);

		SAFE_FREE(p);
		return ret;
	}

	/* we're adding to an existing entry - this is a bit fiddly */
	data = (struct locking_data *)dbuf.dptr;

	data->u.num_share_mode_entries++;

	DEBUG(10,("set_share_mode: adding entry for file %s. new num_share_modes = %d\n",
		fsp->fsp_name, data->u.num_share_mode_entries ));

	size = dbuf.dsize + sizeof(share_mode_entry);
	p = malloc(size);
	if (!p)
		return False;
	memcpy(p, dbuf.dptr, sizeof(*data));
	fill_share_mode(p + sizeof(*data), fsp, port, op_type);
	memcpy(p + sizeof(*data) + sizeof(share_mode_entry), dbuf.dptr + sizeof(*data),
	       dbuf.dsize - sizeof(*data));
	SAFE_FREE(dbuf.dptr);
	dbuf.dptr = p;
	dbuf.dsize = size;
	if (tdb_store(tdb, locking_key_fsp(fsp), dbuf, TDB_REPLACE) == -1)
		ret = False;
	print_share_mode_table((struct locking_data *)p);
	SAFE_FREE(p);
	return ret;
}
예제 #2
0
static TDB_DATA unparse_share_modes(struct share_mode_lock *lck)
{
	TDB_DATA result;
	int num_valid = 0;
	int i;
	struct locking_data *data;
	ssize_t offset;
	ssize_t sp_len;
	uint32 delete_token_size;

	result.dptr = NULL;
	result.dsize = 0;

	for (i=0; i<lck->num_share_modes; i++) {
		if (!is_unused_share_mode_entry(&lck->share_modes[i])) {
			num_valid += 1;
		}
	}

	if (num_valid == 0) {
		return result;
	}

	sp_len = strlen(lck->servicepath);
	delete_token_size = (lck->delete_token ?
			(sizeof(uid_t) + sizeof(gid_t) + (lck->delete_token->ngroups*sizeof(gid_t))) : 0);

	result.dsize = sizeof(*data) +
		lck->num_share_modes * sizeof(struct share_mode_entry) +
		delete_token_size +
		sp_len + 1 +
		strlen(lck->filename) + 1;
	result.dptr = talloc_size(lck, result.dsize);

	if (result.dptr == NULL) {
		smb_panic("talloc failed\n");
	}

	data = (struct locking_data *)result.dptr;
	ZERO_STRUCTP(data);
	data->u.s.num_share_mode_entries = lck->num_share_modes;
	data->u.s.delete_on_close = lck->delete_on_close;
	data->u.s.initial_delete_on_close = lck->initial_delete_on_close;
	data->u.s.delete_token_size = delete_token_size;
	DEBUG(10, ("unparse_share_modes: del: %d, initial del %d, tok = %u, num: %d\n",
		data->u.s.delete_on_close,
		data->u.s.initial_delete_on_close,
		(unsigned int)data->u.s.delete_token_size,
		data->u.s.num_share_mode_entries));
	memcpy(result.dptr + sizeof(*data), lck->share_modes,
	       sizeof(struct share_mode_entry)*lck->num_share_modes);
	offset = sizeof(*data) +
		sizeof(struct share_mode_entry)*lck->num_share_modes;

	/* Store any delete on close token. */
	if (lck->delete_token) {
		char *p = result.dptr + offset;

		memcpy(p, &lck->delete_token->uid, sizeof(uid_t));
		p += sizeof(uid_t);

		memcpy(p, &lck->delete_token->gid, sizeof(gid_t));
		p += sizeof(gid_t);

		for (i = 0; i < lck->delete_token->ngroups; i++) {
			memcpy(p, &lck->delete_token->groups[i], sizeof(gid_t));
			p += sizeof(gid_t);
		}
		offset = p - result.dptr;
	}

	safe_strcpy(result.dptr + offset, lck->servicepath,
		    result.dsize - offset - 1);
	offset += sp_len + 1;
	safe_strcpy(result.dptr + offset, lck->filename,
		    result.dsize - offset - 1);

	if (DEBUGLEVEL >= 10) {
		print_share_mode_table(data);
	}

	return result;
}
예제 #3
0
파일: locking.c 프로젝트: livebox/livebox2
ssize_t del_share_entry( SMB_DEV_T dev, SMB_INO_T inode,
			share_mode_entry *entry, share_mode_entry **ppse)
{
	TDB_DATA dbuf;
	struct locking_data *data;
	int i, del_count=0;
	share_mode_entry *shares;
	ssize_t count = 0;

	if (ppse)
		*ppse = NULL;

	/* read in the existing share modes */
	dbuf = tdb_fetch(tdb, locking_key(dev, inode));
	if (!dbuf.dptr)
		return -1;

	data = (struct locking_data *)dbuf.dptr;
	shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data));

	/*
	 * Find any with this pid and delete it
	 * by overwriting with the rest of the data
	 * from the record.
	 */

	DEBUG(10,("del_share_entry: num_share_modes = %d\n", data->u.num_share_mode_entries ));

	for (i=0;i<data->u.num_share_mode_entries;) {
		if (share_modes_identical(&shares[i], entry)) {
			DEBUG(10,("del_share_entry: deleted %s\n",
				share_mode_str(i, &shares[i]) ));
			if (ppse)
				*ppse = memdup(&shares[i], sizeof(*shares));
			data->u.num_share_mode_entries--;
			memmove(&shares[i], &shares[i+1],
				dbuf.dsize - (sizeof(*data) + (i+1)*sizeof(*shares)));
			del_count++;

			DEBUG(10,("del_share_entry: deleting entry %d\n", i ));

		} else {
			i++;
		}
	}

	if (del_count) {
		/* the record may have shrunk a bit */
		dbuf.dsize -= del_count * sizeof(*shares);

		count = (ssize_t)data->u.num_share_mode_entries;

		/* store it back in the database */
		if (data->u.num_share_mode_entries == 0) {
			if (tdb_delete(tdb, locking_key(dev, inode)) == -1)
				count = -1;
		} else {
			if (tdb_store(tdb, locking_key(dev, inode), dbuf, TDB_REPLACE) == -1)
				count = -1;
		}
	}
	DEBUG(10,("del_share_entry: Remaining table.\n"));
	print_share_mode_table((struct locking_data *)dbuf.dptr);
	SAFE_FREE(dbuf.dptr);
	return count;
}