On Tue, 5 Aug 2003 15:38, Lars Segerlund wrote:
>>[Earlier stuff describing a kernel approach deleted]
>   This might be an approach to implement permissions and services in a
> consistent way, whitout needing to give admin rights to the admin
> account ( per user admin ? ).

I've been thinking this too. The kernel APIs I was suggesting are really just 
a new IPC mechanism that is sort of like shared memory, but with better 
access control facilities and better potential to set up a naming structure 
that cooperating processes can use. It seems to me it would have applications 
beyond just wine. Of course this is without sacrificing the principle that it 
needs to have value in improving the efficiency of wine.

I'm calling this mechanism "lockboxes" for now. Unfortunately I probably won't 
have much time to work on it until late November.

>   Basicly the kernel part could handle the services ( run as user <xxx>
> ), the question is how to handle interaction between users on the same
> machine ? shared folders ? network neighbourhood ?

The principle I'm starting from is to provide mechanisms so that what amount 
to subsystems can be implemented in user mode without compromising security 
or efficiency, and trying to figure out the minimum necessary set of new 
kernel functionality to support this.

I'm attaching the header file that constitutes the current definition of the 
lockbox API.
#ifndef __LOCKBOX_H
#define __LOCKBOX_H
#include <sys/types.h>

typedef int	lockbox_t;

#define	LOCKBOX_ERROR ((lockbox_t) -1)

#define	LKB_READLOCK	0x0001
#define	LKB_WRITELOCK	0x0002
#define	LKB_EXCLUSIVE	0x0004

typedef struct
{
	int			lae_idtype;
	int			lae_id;
	int			lae_access;
	int			lae_reserved;
} lockbox_acl_entry;

typedef struct
{
	int			la_version;
	int			la_n_entries;
	lockbox_acl_entry	la_entries[1];
} lockbox_acl;

#define	LKB_ACL_SIZE(e)	(sizeof(lockbox_acl + \
			 ((e) - 1) * sizeof(lockbox_acl_entry))

#define	LKB_ACL_VERSION		0x0100

#define	LKB_IDTYPE_USER		0
#define LKB_IDTYPE_GROUP	1
#define	LKB_IDTYPE_WORLD	2

#define	LKB_ACCESS_READ		0x0001
#define	LKB_ACCESS_WRITE	0x0002
#define	LKB_ACCESS_LOCK		0x0004
#define	LKB_ACCESS_GETFD	0x0008
#define	LKB_ACCESS_SETFD	0x0010
#define	LKB_ACCESS_SETSTATE	0x0020
#define	LKB_ACCESS_TESTSTATE	0x0040
#define	LKB_ACCESS_GETACL	0x0080
#define	LKB_ACCESS_SETACL	0x0100
#define	LKB_ACCESS_OPEN		0x0200

#define LKB_ACCESS_ALL		0x03ff

#define	LKB_STATE_READY		1
#define	LBK_STATE_NOTREADY	0

/* From the API definition, a process can only access one
 * vault at a time. The file descriptor returned by openvault
 * is primarily for use in a call to select(), where it can
 * be tested for exceptional conditions. This tests for
 * there being a "ready" state on one of the lockboxes which
 * have been added to the process' wait list.
 *
 * The file descriptor is initially set to close on exec.
 */

int		lkb_openvault(	char const *	vaultid);
int		lkb_closevault(	int		fd);
int		lkb_listvaults(	char *		data,
				size_t		bufsize,
				size_t		*sizeneeded);

/* Create, open, close. The name is of the form:
 *
 *	shelf/name
 *
 * The shelf describes the type of content in the lockbox,
 * which is meaningful to processes using the vault. A process
 * can enumerate all lockboxes on a shelf.
 *
 * If "name" is not of the form "shelf/name", the name is
 * taken to be a shelf name only, and the kernel will allocate
 * a lockbox name of the form "shelf/#nnnnnnnn", where 'n' is
 * a hexadecimal digit.
 *
 * Shelves are more efficient if the first character of the
 * shelf name is unique.
 *
 * In lkb_create, the acl can be passed as a null pointer, in
 * which case the permissions will be:
 *
 *	user = LKB_ACCESS_ALL
 *	world = LKB_ACCESS_READ | LKB_ACCESS_OPEN
 */
lockbox_t	lkb_create(	char const *	name,
				void const *	data,
				size_t		size,
				lockbox_acl const *acl);
lockbox_t	lkb_open(	char const *	name);
int		lkb_close(	lockbox_t	id);

/* Lock and unlock a lockbox */
int		lkb_lock(	lockbox_t	id,
				int		flags);
int		lkb_unlock(	lockbox_t	id);

/* Get and set various things about a lockbox */

	/* The name of the lockbox. Primarily useful
	 * when you asked the kernel to assign the
	 * lockbox a name on a shelf (in which case the
	 * required buffer size is predictable).
	 */
int		lkb_getname(	lockbox_t	id,
				char *		name,
				size_t		bufsize,
				size_t		*sizeneeded);

	/* The data in the lockbox. Note that setdata
	 * may increase the size of the lock box, but
	 * not decrease it.
	 */
size_t		lkb_size(	lockbox_t	id);
int		lbk_getdata(	lockbox_t	id,
				void *		buffer,
				size_t		bufsize);
int		lbk_setdata(	lockbox_t	id,
				void const *	buffer,
				size_t		bufsize,
				off_t		offset);

	/* Set the state of a lockbox. This is a single
	 * number that can be used for signalling. Anything
	 * other than zero (LKB_STATE_NONE) is "signalled"
	 */
int		lkb_setstate(	lockbox_t	id,
				int		state);
int		lkb_getstate(	lockbox_t	id);

	/* Gets or sets the file associated with a lockbox.
	 * useful for passing file descriptors across process
	 * boundaries.
	 */
int		lkb_setfile(	lockbox_t	id,
				int		fd);
int		lkb_getfile(	lockbox_t	id);

	/* The Access Control List for the lockbox.
	 */
int		lkb_setacl(	lockbox_t	id,
				lockbox_acl const *acl);
int		lkb_getacl(	lockbox_t	id,
				lockbox_acl	*acl,
				size_t		size,
				size_t		*sizeneeded);

/* Addwaid adds a lockbox to the list of lockboxes tested
 * when the fd is select(2)ed, lkb_dropwait removes one,
 * and lkb_resetwaits empties the list entirely.
 */
int		lkb_addwait(	lockbox_t	id);
int		lkb_dropwait(	lockbox_t	id);
int		lkb_resetwaits(	void);

/* lkb_listboxes returns a list of lockboxes on a shelf,
 * or if shelf is a null pointer, returns a list of
 * shelves in the vault.
 */
int		lkb_listboxes(	char const *	shelf,
				char *		names,
				size_t		bufsize,
				size_t		*sizeneeded);

#endif

Reply via email to