]> arthur.barton.de Git - netatalk.git/blob - libatalk/vfs/acl.c
call readt with ONE_DELAY = 5 s
[netatalk.git] / libatalk / vfs / acl.c
1 /*
2   Copyright (c) 2009 Frank Lahm <franklahm@gmail.com>
3
4   This program is free software; you can redistribute it and/or modify
5   it under the terms of the GNU General Public License as published by
6   the Free Software Foundation; either version 2 of the License, or
7   (at your option) any later version.
8
9   This program is distributed in the hope that it will be useful,
10   but WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12   GNU General Public License for more details.
13 */
14
15 #ifdef HAVE_CONFIG_H
16 #include "config.h"
17 #endif /* HAVE_CONFIG_H */
18
19 #include <unistd.h>
20 #include <sys/types.h>
21 #include <sys/stat.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <errno.h>
25 #include <sys/acl.h>
26
27 #include <atalk/afp.h>
28 #include <atalk/util.h>
29 #include <atalk/logger.h>
30
31 /* Removes all non-trivial ACLs from object. Returns full AFPERR code. */
32 int remove_acl(const char *name)
33 {
34     int ret,i, ace_count, trivial_aces, new_aces_count;
35     ace_t *old_aces = NULL;
36     ace_t *new_aces = NULL;
37
38     LOG(log_debug9, logtype_afpd, "remove_acl: BEGIN");
39
40     /* Get existing ACL and count trivial ACEs */
41     if ((ace_count = get_nfsv4_acl(name, &old_aces)) == -1)
42         return AFPERR_MISC;
43     trivial_aces = 0;
44     for ( i=0; i < ace_count; i++) {
45         if (old_aces[i].a_flags & (ACE_OWNER | ACE_GROUP | ACE_EVERYONE))
46             trivial_aces++;
47     }
48
49     /* malloc buffer for new ACL */
50     if ((new_aces = malloc(trivial_aces * sizeof(ace_t))) == NULL) {
51         LOG(log_error, logtype_afpd, "remove_acl: malloc %s", strerror(errno));
52         ret = AFPERR_MISC;
53         goto exit;
54     }
55
56     /* Now copy the trivial ACEs */
57     new_aces_count = 0;
58     for (i=0; i < ace_count; i++) {
59         if (old_aces[i].a_flags  & (ACE_OWNER | ACE_GROUP | ACE_EVERYONE)) {
60             memcpy(&new_aces[new_aces_count], &old_aces[i], sizeof(ace_t));
61             new_aces_count++;
62         }
63     }
64
65     if ( (acl(name, ACE_SETACL, trivial_aces, new_aces)) == 0)
66         ret = AFP_OK;
67     else {
68         LOG(log_error, logtype_afpd, "set_acl: error setting acl: %s", strerror(errno));
69         if (errno == (EACCES | EPERM))
70             ret = AFPERR_ACCESS;
71         else if (errno == ENOENT)
72             ret = AFPERR_NOITEM;
73         else
74             ret = AFPERR_MISC;
75     }
76
77 exit:
78     free(old_aces);
79     free(new_aces);
80
81     LOG(log_debug9, logtype_afpd, "remove_acl: END");
82     return ret;
83 }