2 Unix SMB/CIFS implementation.
3 Samba system utilities for ACL support.
4 Copyright (C) Jeremy Allison 2000.
5 Copyright (C) Volker Lendecke 2006
6 Copyright (C) Michael Adam 2006
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 #define DBGC_CLASS DBGC_ACLS
29 * Note that while this code implements sufficient functionality
30 * to support the sys_acl_* interfaces it does not provide all
31 * of the semantics of the POSIX ACL interfaces.
33 * In particular, an ACL entry descriptor (SMB_ACL_ENTRY_T) returned
34 * from a call to sys_acl_get_entry() should not be assumed to be
35 * valid after calling any of the following functions, which may
36 * reorder the entries in the ACL.
43 int sys_acl_get_entry(SMB_ACL_T acl_d, int entry_id, SMB_ACL_ENTRY_T *entry_p)
45 if (entry_id != SMB_ACL_FIRST_ENTRY && entry_id != SMB_ACL_NEXT_ENTRY) {
50 if (entry_p == NULL) {
55 if (entry_id == SMB_ACL_FIRST_ENTRY) {
59 if (acl_d->next < 0) {
64 if (acl_d->next >= acl_d->count) {
68 *entry_p = &acl_d->acl[acl_d->next++];
73 int sys_acl_get_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *type_p)
75 *type_p = entry_d->a_type;
80 int sys_acl_get_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
82 *permset_p = &entry_d->a_perm;
87 void *sys_acl_get_qualifier(SMB_ACL_ENTRY_T entry_d)
89 if (entry_d->a_type == SMB_ACL_USER) {
93 if (entry_d->a_type == SMB_ACL_GROUP) {
101 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset_d)
108 int sys_acl_add_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm)
110 if (perm != SMB_ACL_READ && perm != SMB_ACL_WRITE
111 && perm != SMB_ACL_EXECUTE) {
116 if (permset_d == NULL) {
126 int sys_acl_get_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm)
128 return *permset_d & perm;
131 char *sys_acl_to_text(SMB_ACL_T acl_d, ssize_t *len_p)
138 * use an initial estimate of 20 bytes per ACL entry
139 * when allocating memory for the text representation
143 maxlen = 20 * acl_d->count;
144 if ((text = SMB_MALLOC(maxlen)) == NULL) {
149 for (i = 0; i < acl_d->count; i++) {
150 struct smb_acl_entry *ap = &acl_d->acl[i];
159 switch (ap->a_type) {
161 * for debugging purposes it's probably more
162 * useful to dump unknown tag types rather
163 * than just returning an error
166 slprintf(tagbuf, sizeof(tagbuf)-1, "0x%x",
172 id = uidtoname(ap->uid);
173 case SMB_ACL_USER_OBJ:
178 if ((gr = getgrgid(ap->gid)) == NULL) {
179 slprintf(idbuf, sizeof(idbuf)-1, "%ld",
185 case SMB_ACL_GROUP_OBJ:
199 perms[0] = (ap->a_perm & SMB_ACL_READ) ? 'r' : '-';
200 perms[1] = (ap->a_perm & SMB_ACL_WRITE) ? 'w' : '-';
201 perms[2] = (ap->a_perm & SMB_ACL_EXECUTE) ? 'x' : '-';
204 /* <tag> : <qualifier> : rwx \n \0 */
205 nbytes = strlen(tag) + 1 + strlen(id) + 1 + 3 + 1 + 1;
208 * If this entry would overflow the buffer
209 * allocate enough additional memory for this
210 * entry and an estimate of another 20 bytes
211 * for each entry still to be processed
213 if ((len + nbytes) > maxlen) {
214 maxlen += nbytes + 20 * (acl_d->count - i);
215 if ((text = SMB_REALLOC(text, maxlen)) == NULL) {
221 slprintf(&text[len], nbytes-1, "%s:%s:%s\n", tag, id, perms);
231 SMB_ACL_T sys_acl_init(int count)
241 * note that since the definition of the structure pointed
242 * to by the SMB_ACL_T includes the first element of the
243 * acl[] array, this actually allocates an ACL with room
244 * for (count+1) entries
246 if ((a = SMB_MALLOC(sizeof(struct smb_acl_t) +
247 count * sizeof(struct smb_acl_entry))) == NULL) {
259 int sys_acl_create_entry(SMB_ACL_T *acl_p, SMB_ACL_ENTRY_T *entry_p)
262 SMB_ACL_ENTRY_T entry_d;
264 if (acl_p == NULL || entry_p == NULL || (acl_d = *acl_p) == NULL) {
269 if (acl_d->count >= acl_d->size) {
274 entry_d = &acl_d->acl[acl_d->count++];
284 int sys_acl_set_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T tag_type)
288 case SMB_ACL_USER_OBJ:
290 case SMB_ACL_GROUP_OBJ:
293 entry_d->a_type = tag_type;
303 int sys_acl_set_qualifier(SMB_ACL_ENTRY_T entry_d, void *qual_p)
305 if (entry_d->a_type == SMB_ACL_USER) {
306 entry_d->uid = *((uid_t *)qual_p);
309 if (entry_d->a_type == SMB_ACL_GROUP) {
310 entry_d->gid = *((gid_t *)qual_p);
318 int sys_acl_set_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T permset_d)
320 if (*permset_d & ~(SMB_ACL_READ|SMB_ACL_WRITE|SMB_ACL_EXECUTE)) {
325 entry_d->a_perm = *permset_d;
330 int sys_acl_free_text(char *text)
336 int sys_acl_free_acl(SMB_ACL_T acl_d)
342 int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype)
347 int sys_acl_valid(SMB_ACL_T acl_d)
354 * acl_get_file, acl_get_fd, acl_set_file, acl_set_fd and
355 * sys_acl_delete_def_file are to be redirected to the default
356 * statically-bound acl vfs module, but they are replacable.
359 #if defined(HAVE_POSIX_ACLS)
361 SMB_ACL_T sys_acl_get_file(vfs_handle_struct *handle,
362 const char *path_p, SMB_ACL_TYPE_T type)
364 return posixacl_sys_acl_get_file(handle, path_p, type);
367 SMB_ACL_T sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp, int fd)
369 return posixacl_sys_acl_get_fd(handle, fsp, fd);
372 int sys_acl_set_file(vfs_handle_struct *handle,
373 const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d)
375 return posixacl_sys_acl_set_file(handle, name, type, acl_d);
378 int sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp,
379 int fd, SMB_ACL_T acl_d)
381 return posixacl_sys_acl_set_fd(handle, fsp, fd, acl_d);
384 int sys_acl_delete_def_file(vfs_handle_struct *handle,
387 return posixacl_sys_acl_delete_def_file(handle, path);
390 #elif defined(HAVE_AIX_ACLS)
392 SMB_ACL_T sys_acl_get_file(vfs_handle_struct *handle,
393 const char *path_p, SMB_ACL_TYPE_T type)
395 return aixacl_sys_acl_get_file(handle, path_p, type);
398 SMB_ACL_T sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp, int fd)
400 return aixacl_sys_acl_get_fd(handle, fsp, fd);
403 int sys_acl_set_file(vfs_handle_struct *handle,
404 const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d)
406 return aixacl_sys_acl_set_file(handle, name, type, acl_d);
409 int sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp,
410 int fd, SMB_ACL_T acl_d)
412 return aixacl_sys_acl_set_fd(handle, fsp, fd, acl_d);
415 int sys_acl_delete_def_file(vfs_handle_struct *handle,
418 return aixacl_sys_acl_delete_def_file(handle, path);
421 #elif defined(HAVE_TRU64_ACLS)
423 SMB_ACL_T sys_acl_get_file(vfs_handle_struct *handle,
424 const char *path_p, SMB_ACL_TYPE_T type)
426 return tru64acl_sys_acl_get_file(handle, path_p, type);
429 SMB_ACL_T sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp, int fd)
431 return tru64acl_sys_acl_get_fd(handle, fsp, fd);
434 int sys_acl_set_file(vfs_handle_struct *handle,
435 const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d)
437 return tru64acl_sys_acl_set_file(handle, name, type, acl_d);
440 int sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp,
441 int fd, SMB_ACL_T acl_d)
443 return tru64acl_sys_acl_set_fd(handle, fsp, fd, acl_d);
446 int sys_acl_delete_def_file(vfs_handle_struct *handle,
449 return tru64acl_sys_acl_delete_def_file(handle, path);
452 #elif defined(HAVE_SOLARIS_ACLS) || defined(HAVE_UNIXWARE_ACLS)
454 SMB_ACL_T sys_acl_get_file(vfs_handle_struct *handle,
455 const char *path_p, SMB_ACL_TYPE_T type)
457 return solarisacl_sys_acl_get_file(handle, path_p, type);
460 SMB_ACL_T sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp, int fd)
462 return solarisacl_sys_acl_get_fd(handle, fsp, fd);
465 int sys_acl_set_file(vfs_handle_struct *handle,
466 const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d)
468 return solarisacl_sys_acl_set_file(handle, name, type, acl_d);
471 int sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp,
472 int fd, SMB_ACL_T acl_d)
474 return solarisacl_sys_acl_set_fd(handle, fsp, fd, acl_d);
477 int sys_acl_delete_def_file(vfs_handle_struct *handle,
480 return solarisacl_sys_acl_delete_def_file(handle, path);
483 #elif defined(HAVE_HPUX_ACLS)
485 SMB_ACL_T sys_acl_get_file(vfs_handle_struct *handle,
486 const char *path_p, SMB_ACL_TYPE_T type)
488 return hpuxacl_sys_acl_get_file(handle, path_p, type);
491 SMB_ACL_T sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp, int fd)
493 return hpuxacl_sys_acl_get_fd(handle, fsp, fd);
496 int sys_acl_set_file(vfs_handle_struct *handle,
497 const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d)
499 return hpuxacl_sys_acl_set_file(handle, name, type, acl_d);
502 int sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp,
503 int fd, SMB_ACL_T acl_d)
505 return hpuxacl_sys_acl_set_fd(handle, fsp, fd, acl_d);
508 int sys_acl_delete_def_file(vfs_handle_struct *handle,
511 return hpuxacl_sys_acl_delete_def_file(handle, path);
514 #elif defined(HAVE_IRIX_ACLS)
516 SMB_ACL_T sys_acl_get_file(vfs_handle_struct *handle,
517 const char *path_p, SMB_ACL_TYPE_T type)
519 return irixacl_sys_acl_get_file(handle, path_p, type);
522 SMB_ACL_T sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp, int fd)
524 return irixacl_sys_acl_get_fd(handle, fsp, fd);
527 int sys_acl_set_file(vfs_handle_struct *handle,
528 const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d)
530 return irixacl_sys_acl_set_file(handle, name, type, acl_d);
533 int sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp,
534 int fd, SMB_ACL_T acl_d)
536 return irixacl_sys_acl_set_fd(handle, fsp, fd, acl_d);
539 int sys_acl_delete_def_file(vfs_handle_struct *handle,
542 return irixacl_sys_acl_delete_def_file(handle, path);
547 SMB_ACL_T sys_acl_get_file(vfs_handle_struct *handle,
548 const char *path_p, SMB_ACL_TYPE_T type)
554 SMB_ACL_T sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp, int fd)
560 int sys_acl_set_file(vfs_handle_struct *handle,
561 const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d)
567 int sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp,
568 int fd, SMB_ACL_T acl_d)
574 int sys_acl_delete_def_file(vfs_handle_struct *handle,
583 /************************************************************************
584 Deliberately outside the ACL defines. Return 1 if this is a "no acls"
586 ************************************************************************/
588 int no_acl_syscall_error(int err)
596 if (err == ENOTSUP) {