Пример #1
0
void msg_close_file(struct messaging_context *msg_ctx,
			void *private_data,
			uint32_t msg_type,
			struct server_id server_id,
			DATA_BLOB *data)
{
	files_struct *fsp = NULL;
	struct share_mode_entry e;
	struct smbd_server_connection *sconn =
		talloc_get_type_abort(private_data,
		struct smbd_server_connection);

	message_to_share_mode_entry(&e, (char *)data->data);

	if(DEBUGLVL(10)) {
		char *sm_str = share_mode_str(NULL, 0, &e);
		if (!sm_str) {
			smb_panic("talloc failed");
		}
		DEBUG(10,("msg_close_file: got request to close share mode "
			"entry %s\n", sm_str));
		TALLOC_FREE(sm_str);
	}

	fsp = file_find_dif(sconn, e.id, e.share_file_id);
	if (!fsp) {
		DEBUG(10,("msg_close_file: failed to find file.\n"));
		return;
	}
	close_file(NULL, fsp, NORMAL_CLOSE);
}
Пример #2
0
static void print_share_mode_table(struct locking_data *data)
{
	int num_share_modes = data->u.num_share_mode_entries;
	share_mode_entry *shares = (share_mode_entry *)(data + 1);
	int i;

	for (i = 0; i < num_share_modes; i++) {
		share_mode_entry *entry_p = &shares[i];
		DEBUG(10,("print_share_mode_table: %s\n", share_mode_str(i, entry_p) ));
	}
}
Пример #3
0
static void print_share_mode_table(struct locking_data *data)
{
	int num_share_modes = data->u.s.num_share_mode_entries;
	struct share_mode_entry *shares =
		(struct share_mode_entry *)(data + 1);
	int i;

	for (i = 0; i < num_share_modes; i++) {
		struct share_mode_entry entry;

		memcpy(&entry, &shares[i], sizeof(struct share_mode_entry));
		DEBUG(10,("print_share_mode_table: %s\n",
			  share_mode_str(i, &entry)));
	}
}
Пример #4
0
static BOOL parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck)
{
	struct locking_data *data;
	int i;

	if (dbuf.dsize < sizeof(struct locking_data)) {
		smb_panic("PANIC: parse_share_modes: buffer too short.\n");
	}

	data = (struct locking_data *)dbuf.dptr;

	lck->delete_on_close = data->u.s.delete_on_close;
	lck->initial_delete_on_close = data->u.s.initial_delete_on_close;
	lck->num_share_modes = data->u.s.num_share_mode_entries;

	DEBUG(10, ("parse_share_modes: delete_on_close: %d, "
		   "initial_delete_on_close: %d, "
		   "num_share_modes: %d\n",
		lck->delete_on_close,
		lck->initial_delete_on_close,
		lck->num_share_modes));

	if ((lck->num_share_modes < 0) || (lck->num_share_modes > 1000000)) {
		DEBUG(0, ("invalid number of share modes: %d\n",
			  lck->num_share_modes));
		smb_panic("PANIC: invalid number of share modes");
	}

	lck->share_modes = NULL;
	
	if (lck->num_share_modes != 0) {

		if (dbuf.dsize < (sizeof(struct locking_data) +
				  (lck->num_share_modes *
				   sizeof(struct share_mode_entry)))) {
			smb_panic("PANIC: parse_share_modes: buffer too short.\n");
		}
				  
		lck->share_modes = talloc_memdup(lck, dbuf.dptr+sizeof(*data),
						 lck->num_share_modes *
						 sizeof(struct share_mode_entry));

		if (lck->share_modes == NULL) {
			smb_panic("talloc failed\n");
		}
	}

	/* Get any delete token. */
	if (data->u.s.delete_token_size) {
		char *p = dbuf.dptr + sizeof(*data) +
				(lck->num_share_modes *
				sizeof(struct share_mode_entry));

		if ((data->u.s.delete_token_size < sizeof(uid_t) + sizeof(gid_t)) ||
				((data->u.s.delete_token_size - sizeof(uid_t)) % sizeof(gid_t)) != 0) {
			DEBUG(0, ("parse_share_modes: invalid token size %d\n",
				data->u.s.delete_token_size));
			smb_panic("parse_share_modes: invalid token size\n");
		}

		lck->delete_token = TALLOC_P(lck, UNIX_USER_TOKEN);
		if (!lck->delete_token) {
			smb_panic("talloc failed\n");
		}

		/* Copy out the uid and gid. */
		memcpy(&lck->delete_token->uid, p, sizeof(uid_t));
		p += sizeof(uid_t);
		memcpy(&lck->delete_token->gid, p, sizeof(gid_t));
		p += sizeof(gid_t);

		/* Any supplementary groups ? */
		lck->delete_token->ngroups = (data->u.s.delete_token_size > (sizeof(uid_t) + sizeof(gid_t))) ?
					((data->u.s.delete_token_size -
						(sizeof(uid_t) + sizeof(gid_t)))/sizeof(gid_t)) : 0;

		if (lck->delete_token->ngroups) {
			/* Make this a talloc child of lck->delete_token. */
			lck->delete_token->groups = TALLOC_ARRAY(lck->delete_token, gid_t,
							lck->delete_token->ngroups);
			if (!lck->delete_token) {
				smb_panic("talloc failed\n");
			}

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

	} else {
		lck->delete_token = NULL;
	}

	/* Save off the associated service path and filename. */
	lck->servicepath = talloc_strdup(lck, dbuf.dptr + sizeof(*data) +
					(lck->num_share_modes *
					sizeof(struct share_mode_entry)) +
					data->u.s.delete_token_size );

	lck->filename = talloc_strdup(lck, dbuf.dptr + sizeof(*data) +
					(lck->num_share_modes *
					sizeof(struct share_mode_entry)) +
					data->u.s.delete_token_size +
					strlen(lck->servicepath) + 1 );

	/*
	 * Ensure that each entry has a real process attached.
	 */

	for (i = 0; i < lck->num_share_modes; i++) {
		struct share_mode_entry *entry_p = &lck->share_modes[i];
		DEBUG(10,("parse_share_modes: %s\n",
			  share_mode_str(i, entry_p) ));
		if (!process_exists(entry_p->pid)) {
			DEBUG(10,("parse_share_modes: deleted %s\n",
				  share_mode_str(i, entry_p) ));
			entry_p->op_type = UNUSED_SHARE_MODE_ENTRY;
			lck->modified = True;
		}
	}

	return True;
}
Пример #5
0
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;
}
Пример #6
0
int get_share_modes(connection_struct *conn,
		    SMB_DEV_T dev, SMB_INO_T inode,
		    share_mode_entry **pp_shares)
{
	TDB_DATA dbuf;
	struct locking_data *data;
	int num_share_modes;
	share_mode_entry *shares = NULL;

	*pp_shares = NULL;

	dbuf = tdb_fetch(tdb, locking_key(dev, inode));
	if (!dbuf.dptr)
		return 0;

	data = (struct locking_data *)dbuf.dptr;
	num_share_modes = data->u.num_share_mode_entries;
	if(num_share_modes) {
		int i;
		int del_count = 0;

		shares = (share_mode_entry *)memdup(dbuf.dptr + sizeof(*data),
						num_share_modes * sizeof(share_mode_entry));

		if (!shares) {
			SAFE_FREE(dbuf.dptr);
			return 0;
		}

		/*
		 * Ensure that each entry has a real process attached.
		 */

		for (i = 0; i < num_share_modes; ) {
			share_mode_entry *entry_p = &shares[i];
			if (process_exists(entry_p->pid)) {
				DEBUG(10,("get_share_modes: %s\n", share_mode_str(i, entry_p) ));
				i++;
			} else {
				DEBUG(10,("get_share_modes: deleted %s\n", share_mode_str(i, entry_p) ));
				memcpy( &shares[i], &shares[i+1],
					sizeof(share_mode_entry) * (num_share_modes - i - 1));
				num_share_modes--;
				del_count++;
			}
		}

		/* Did we delete any ? If so, re-store in tdb. */
		if (del_count) {
			data->u.num_share_mode_entries = num_share_modes;

			if (num_share_modes)
				memcpy(dbuf.dptr + sizeof(*data), shares,
						num_share_modes * sizeof(share_mode_entry));

			/* The record has shrunk a bit */
			dbuf.dsize -= del_count * sizeof(share_mode_entry);

			if (tdb_store(tdb, locking_key(dev, inode), dbuf, TDB_REPLACE) == -1) {
				SAFE_FREE(shares);
				SAFE_FREE(dbuf.dptr);
				return 0;
			}
		}
	}

	SAFE_FREE(dbuf.dptr);
	*pp_shares = shares;
	return num_share_modes;
}