]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/libc/posix1e/acl_from_mode_np.c
ssh: update to OpenSSH v8.8p1
[FreeBSD/FreeBSD.git] / lib / libc / posix1e / acl_from_mode_np.c
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2021 Robert N M Watson, Gleb Popov
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 /*
29  * acl_from_mode_np: Create an ACL from a mode_t.
30  */
31
32 #include <sys/cdefs.h>
33 __FBSDID("$FreeBSD$");
34
35 #include <sys/types.h>
36 #include <sys/param.h>
37 #include <sys/acl.h>
38 #include <sys/stat.h>
39
40 /*
41  * return an ACL corresponding to the permissions
42  * contained in mode_t
43  */
44 acl_t
45 acl_from_mode_np(const mode_t mode)
46 {
47         acl_t acl;
48         acl_entry_t entry;
49         acl_permset_t perms;
50
51         /* create the ACL */
52         acl = acl_init(3);
53         /* here and below, the only possible reason to fail is ENOMEM, so
54          * no need to set errno again
55          */
56         if (acl == NULL)
57                 return (NULL);
58
59         /* First entry: ACL_USER_OBJ */
60         if (acl_create_entry(&acl, &entry) == -1)
61                 return (NULL);
62         /* TODO: need to handle error there and below? */
63         acl_set_tag_type(entry, ACL_USER_OBJ);
64
65         acl_get_permset(entry, &perms);
66         acl_clear_perms(perms);
67
68         /* calculate user mode */
69         if (mode & S_IRUSR)
70                 acl_add_perm(perms, ACL_READ);
71         if (mode & S_IWUSR)
72                 acl_add_perm(perms, ACL_WRITE);
73         if (mode & S_IXUSR)
74                 acl_add_perm(perms, ACL_EXECUTE);
75
76         acl_set_permset(entry, perms);
77
78         /* Second entry: ACL_GROUP_OBJ */
79         if (acl_create_entry(&acl, &entry) == -1)
80                 return (NULL);
81         acl_set_tag_type(entry, ACL_GROUP_OBJ);
82
83         acl_get_permset(entry, &perms);
84         acl_clear_perms(perms);
85
86         /* calculate group mode */
87         if (mode & S_IRGRP)
88                 acl_add_perm(perms, ACL_READ);
89         if (mode & S_IWGRP)
90                 acl_add_perm(perms, ACL_WRITE);
91         if (mode & S_IXGRP)
92                 acl_add_perm(perms, ACL_EXECUTE);
93
94         acl_set_permset(entry, perms);
95
96         /* Third entry: ACL_OTHER */
97         if (acl_create_entry(&acl, &entry) == -1)
98                 return (NULL);
99         acl_set_tag_type(entry, ACL_OTHER);
100
101         acl_get_permset(entry, &perms);
102         acl_clear_perms(perms);
103
104         /* calculate other mode */
105         if (mode & S_IROTH)
106                 acl_add_perm(perms, ACL_READ);
107         if (mode & S_IWOTH)
108                 acl_add_perm(perms, ACL_WRITE);
109         if (mode & S_IXOTH)
110                 acl_add_perm(perms, ACL_EXECUTE);
111
112         acl_set_permset(entry, perms);
113
114         return (acl);
115 }