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,2008
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 3 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, see <http://www.gnu.org/licenses/>.
25
#define DBGC_CLASS DBGC_ACLS
28
* Note that while this code implements sufficient functionality
29
* to support the sys_acl_* interfaces it does not provide all
30
* of the semantics of the POSIX ACL interfaces.
32
* In particular, an ACL entry descriptor (SMB_ACL_ENTRY_T) returned
33
* from a call to sys_acl_get_entry() should not be assumed to be
34
* valid after calling any of the following functions, which may
35
* reorder the entries in the ACL.
42
int sys_acl_get_entry(SMB_ACL_T acl_d, int entry_id, SMB_ACL_ENTRY_T *entry_p)
44
if (entry_id != SMB_ACL_FIRST_ENTRY && entry_id != SMB_ACL_NEXT_ENTRY) {
49
if (entry_p == NULL) {
54
if (entry_id == SMB_ACL_FIRST_ENTRY) {
58
if (acl_d->next < 0) {
63
if (acl_d->next >= acl_d->count) {
67
*entry_p = &acl_d->acl[acl_d->next++];
72
int sys_acl_get_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *type_p)
74
*type_p = entry_d->a_type;
79
int sys_acl_get_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
81
*permset_p = &entry_d->a_perm;
86
void *sys_acl_get_qualifier(SMB_ACL_ENTRY_T entry_d)
88
if (entry_d->a_type == SMB_ACL_USER) {
92
if (entry_d->a_type == SMB_ACL_GROUP) {
100
int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset_d)
107
int sys_acl_add_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm)
109
if (perm != SMB_ACL_READ && perm != SMB_ACL_WRITE
110
&& perm != SMB_ACL_EXECUTE) {
115
if (permset_d == NULL) {
125
int sys_acl_get_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm)
127
return *permset_d & perm;
130
char *sys_acl_to_text(SMB_ACL_T acl_d, ssize_t *len_p)
137
* use an initial estimate of 20 bytes per ACL entry
138
* when allocating memory for the text representation
142
maxlen = 20 * acl_d->count;
143
if ((text = (char *)SMB_MALLOC(maxlen)) == NULL) {
148
for (i = 0; i < acl_d->count; i++) {
149
struct smb_acl_entry *ap = &acl_d->acl[i];
158
switch (ap->a_type) {
160
* for debugging purposes it's probably more
161
* useful to dump unknown tag types rather
162
* than just returning an error
165
slprintf(tagbuf, sizeof(tagbuf)-1, "0x%x",
171
id = uidtoname(ap->uid);
172
case SMB_ACL_USER_OBJ:
177
if ((gr = getgrgid(ap->gid)) == NULL) {
178
slprintf(idbuf, sizeof(idbuf)-1, "%ld",
184
case SMB_ACL_GROUP_OBJ:
198
perms[0] = (ap->a_perm & SMB_ACL_READ) ? 'r' : '-';
199
perms[1] = (ap->a_perm & SMB_ACL_WRITE) ? 'w' : '-';
200
perms[2] = (ap->a_perm & SMB_ACL_EXECUTE) ? 'x' : '-';
203
/* <tag> : <qualifier> : rwx \n \0 */
204
nbytes = strlen(tag) + 1 + strlen(id) + 1 + 3 + 1 + 1;
207
* If this entry would overflow the buffer
208
* allocate enough additional memory for this
209
* entry and an estimate of another 20 bytes
210
* for each entry still to be processed
212
if ((len + nbytes) > maxlen) {
213
maxlen += nbytes + 20 * (acl_d->count - i);
214
if ((text = (char *)SMB_REALLOC(text, maxlen)) == NULL) {
220
slprintf(&text[len], nbytes-1, "%s:%s:%s\n", tag, id, perms);
230
SMB_ACL_T sys_acl_init(int count)
240
* note that since the definition of the structure pointed
241
* to by the SMB_ACL_T includes the first element of the
242
* acl[] array, this actually allocates an ACL with room
243
* for (count+1) entries
245
if ((a = (struct smb_acl_t *)SMB_MALLOC(
246
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++];
275
entry_d->a_type = SMB_ACL_TAG_INVALID;
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)
369
return posixacl_sys_acl_get_fd(handle, fsp);
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,
381
return posixacl_sys_acl_set_fd(handle, fsp, 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)
400
return aixacl_sys_acl_get_fd(handle, fsp);
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,
412
return aixacl_sys_acl_set_fd(handle, fsp, 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)
431
return tru64acl_sys_acl_get_fd(handle, fsp);
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,
443
return tru64acl_sys_acl_set_fd(handle, fsp, 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)
462
return solarisacl_sys_acl_get_fd(handle, fsp);
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,
474
return solarisacl_sys_acl_set_fd(handle, fsp, 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)
493
return hpuxacl_sys_acl_get_fd(handle, fsp);
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,
505
return hpuxacl_sys_acl_set_fd(handle, fsp, 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)
524
return irixacl_sys_acl_get_fd(handle, fsp);
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,
536
return irixacl_sys_acl_set_fd(handle, fsp, 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)
558
SMB_ACL_T sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp)
568
int sys_acl_set_file(vfs_handle_struct *handle,
569
const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d)
579
int sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp,
590
int sys_acl_delete_def_file(vfs_handle_struct *handle,
603
/************************************************************************
604
Deliberately outside the ACL defines. Return 1 if this is a "no acls"
606
************************************************************************/
608
int no_acl_syscall_error(int err)
616
if (err == ENOTSUP) {