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