generic ACL interface (RFC)

Cole, Timothy D. timothy_d_cole at md.northgrum.com
Tue Jul 27 20:31:26 GMT 1999


Here's a very early shot at a header file for a generic internal ACL
interface for SAMBA.  I _think_ the representation is general enough to
cover all of the major Unix ACL schemes without losing information (well, at
least POSIX/Solaris, HP-UX and AFS [I think]).

--- snip ---

typedef enum acl_entry_type {
	ACL_ENTRY_OTHER=0, /* "World" or "Everyone" */
	ACL_ENTRY_USER=1,
	ACL_ENTRY_GROUP=2,
	ACL_ENTRY_USER_AND_GROUP=(ACL_ENTRY_USER|ACL_ENTRY_GROUP),
	ACL_ENTRY_MASK=4
} ACL_ENTRY_TYPE;

enum acl_entry_flags {
	ACL_ENTRY_IS_OWNER=1,
	ACL_ENTRY_IS_OWNING_GROUP=2,
	ACL_ENTRY_HAS_VALID_USER_ID=4,
	ACL_ENTRY_HAS_VALID_GROUP_ID=8,
	ACL_ENTRY_HAS_VALID_USER_SID=16,
	ACL_ENTRY_HAS_VALID_GROUP_SID=32,
	ACL_ENTRY_IS_DEFAULT=64,
	ACL_ENTRY_UNSUPPORTED=128 /* unsupported by client */
};

enum acl_entry_permissions {
	ACL_PERM_EXECUTE=1,
	ACL_PERM_SEARCH=1,
	ACL_PERM_WRITE=2,
	ACL_PERM_INSERT=2,
	ACL_PERM_READ=4,
	ACL_PERM_CONTROL=8,
	ACL_PERM_DELETE=16,
	ACL_PERM_REMOVE=16,
	ACL_PERM_LOCK=32
};

typedef struct acl_entry_info {
	ACL_ENTRY_TYPE type;
	int32 flags;
	uid_t user_id;
	DOM_SID user_sid;
	gid_t group_id;
	DOM_SID group_sid;
	struct {
		int32 allow;
		int32 deny;
	} perms;
} ACL_ENTRY;

/* what should the return values mean here? */
extern int get_acl(files_struct *fsp, ACL_ENTRY **entries, int *n_entries);
extern int set_acl(files_struct *fsp, const ACL_ENTRY *entries, int
n_entries);
extern void free_acl(files_struct *fsp, ACL_ENTRY *entries);

/* these would be used internally; it may not be worthwhile to expose them:
*/
extern BOOL client_supports_acl_entry(connection_struct *conn, const
ACL_ENTRY *entry);
extern BOOL implementation_supports_acl_entry(connection_struct *conn, const
ACL_ENTRY *entry);

--- snip ---

Hrm; this almost seems kind of overengineered to me, but I do want to be
able to express as much information as possible before translating it to the
client's native format (i.e. in smbd/nttrans.c).  I didn't want to use the
rpc_secdes.h representations since that would mean a lot more special-case
code for each underlying ACL implementation.

Some notes on semantics:

get_acl() allocates its own ACL_ENTRY array, returning a pointer to it in
*entries, and placing a count in *n_entries.  (the array can be subsequently
freed with free_acl())  ACL entries that the client (as determined by the
files_struct's associated connection_struct) does not support will be marked
with ACL_ENTRY_UNSUPPORTED.

set_acl() will usually imply a call to get_acl() to compare the existing
permissions against the desired ones.

 Entries in the "desired" ACL that do not exist in the "current" ACL will be
added.

 Entries in the "current" ACL that do not exist in the "desired" ACL will be
removed, UNLESS they are marked as ACL_ENTRY_UNSUPPORTED, in which case they
will be left alone.

 Entries in the "current" ACL that have corresponding entries in the
"desired" ACL will be modified to match the permissions expressed in the
"desired" ACL.

ACL_ENTRY_UNSUPPORTED entries won't get presented to the client, which might
be a bad thing -- they don't see the entire ACL.  "A little knowledge is a
dangerous thing", and that applies especially to security.  OTOH, there is
no possible way to represent all ACL entries on some systems to some clients
-- should we not bother with ACLs at all in such cases?

I dunno.  What do you folks think?



More information about the samba-technical mailing list