Commit | Line | Data |
---|---|---|
e2f34481 NJ |
1 | /* SPDX-License-Identifier: LGPL-2.1+ */ |
2 | /* | |
3 | * Copyright (c) International Business Machines Corp., 2007 | |
4 | * Author(s): Steve French (sfrench@us.ibm.com) | |
5 | * Modified by Namjae Jeon (linkinjeon@kernel.org) | |
6 | */ | |
7 | ||
8 | #ifndef _SMBACL_H | |
9 | #define _SMBACL_H | |
10 | ||
11 | #include <linux/fs.h> | |
12 | #include <linux/namei.h> | |
13 | #include <linux/posix_acl.h> | |
a793d79e | 14 | #include <linux/mnt_idmapping.h> |
e2f34481 NJ |
15 | |
16 | #include "mgmt/tree_connect.h" | |
17 | ||
18 | #define NUM_AUTHS (6) /* number of authority fields */ | |
19 | #define SID_MAX_SUB_AUTHORITIES (15) /* max number of sub authority fields */ | |
20 | ||
6128468d NJ |
21 | /* |
22 | * ACE types - see MS-DTYP 2.4.4.1 | |
23 | */ | |
24 | enum { | |
25 | ACCESS_ALLOWED, | |
26 | ACCESS_DENIED, | |
27 | }; | |
e2f34481 | 28 | |
12411ad5 NJ |
29 | /* |
30 | * Security ID types | |
31 | */ | |
32 | enum { | |
33 | SIDOWNER = 1, | |
34 | SIDGROUP, | |
35 | SIDCREATOR_OWNER, | |
36 | SIDCREATOR_GROUP, | |
37 | SIDUNIX_USER, | |
38 | SIDUNIX_GROUP, | |
39 | SIDNFS_USER, | |
40 | SIDNFS_GROUP, | |
41 | SIDNFS_MODE, | |
42 | }; | |
e2f34481 NJ |
43 | |
44 | /* Revision for ACLs */ | |
45 | #define SD_REVISION 1 | |
46 | ||
47 | /* Control flags for Security Descriptor */ | |
48 | #define OWNER_DEFAULTED 0x0001 | |
49 | #define GROUP_DEFAULTED 0x0002 | |
50 | #define DACL_PRESENT 0x0004 | |
51 | #define DACL_DEFAULTED 0x0008 | |
52 | #define SACL_PRESENT 0x0010 | |
53 | #define SACL_DEFAULTED 0x0020 | |
54 | #define DACL_TRUSTED 0x0040 | |
55 | #define SERVER_SECURITY 0x0080 | |
56 | #define DACL_AUTO_INHERIT_REQ 0x0100 | |
57 | #define SACL_AUTO_INHERIT_REQ 0x0200 | |
58 | #define DACL_AUTO_INHERITED 0x0400 | |
59 | #define SACL_AUTO_INHERITED 0x0800 | |
60 | #define DACL_PROTECTED 0x1000 | |
61 | #define SACL_PROTECTED 0x2000 | |
62 | #define RM_CONTROL_VALID 0x4000 | |
63 | #define SELF_RELATIVE 0x8000 | |
64 | ||
65 | /* ACE types - see MS-DTYP 2.4.4.1 */ | |
66 | #define ACCESS_ALLOWED_ACE_TYPE 0x00 | |
67 | #define ACCESS_DENIED_ACE_TYPE 0x01 | |
68 | #define SYSTEM_AUDIT_ACE_TYPE 0x02 | |
69 | #define SYSTEM_ALARM_ACE_TYPE 0x03 | |
70 | #define ACCESS_ALLOWED_COMPOUND_ACE_TYPE 0x04 | |
71 | #define ACCESS_ALLOWED_OBJECT_ACE_TYPE 0x05 | |
72 | #define ACCESS_DENIED_OBJECT_ACE_TYPE 0x06 | |
73 | #define SYSTEM_AUDIT_OBJECT_ACE_TYPE 0x07 | |
74 | #define SYSTEM_ALARM_OBJECT_ACE_TYPE 0x08 | |
75 | #define ACCESS_ALLOWED_CALLBACK_ACE_TYPE 0x09 | |
76 | #define ACCESS_DENIED_CALLBACK_ACE_TYPE 0x0A | |
77 | #define ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE 0x0B | |
78 | #define ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE 0x0C | |
79 | #define SYSTEM_AUDIT_CALLBACK_ACE_TYPE 0x0D | |
80 | #define SYSTEM_ALARM_CALLBACK_ACE_TYPE 0x0E /* Reserved */ | |
81 | #define SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE 0x0F | |
82 | #define SYSTEM_ALARM_CALLBACK_OBJECT_ACE_TYPE 0x10 /* reserved */ | |
83 | #define SYSTEM_MANDATORY_LABEL_ACE_TYPE 0x11 | |
84 | #define SYSTEM_RESOURCE_ATTRIBUTE_ACE_TYPE 0x12 | |
85 | #define SYSTEM_SCOPED_POLICY_ID_ACE_TYPE 0x13 | |
86 | ||
87 | /* ACE flags */ | |
88 | #define OBJECT_INHERIT_ACE 0x01 | |
89 | #define CONTAINER_INHERIT_ACE 0x02 | |
90 | #define NO_PROPAGATE_INHERIT_ACE 0x04 | |
91 | #define INHERIT_ONLY_ACE 0x08 | |
92 | #define INHERITED_ACE 0x10 | |
93 | #define SUCCESSFUL_ACCESS_ACE_FLAG 0x40 | |
94 | #define FAILED_ACCESS_ACE_FLAG 0x80 | |
95 | ||
96 | /* | |
97 | * Maximum size of a string representation of a SID: | |
98 | * | |
99 | * The fields are unsigned values in decimal. So: | |
100 | * | |
101 | * u8: max 3 bytes in decimal | |
102 | * u32: max 10 bytes in decimal | |
103 | * | |
104 | * "S-" + 3 bytes for version field + 15 for authority field + NULL terminator | |
105 | * | |
106 | * For authority field, max is when all 6 values are non-zero and it must be | |
107 | * represented in hex. So "-0x" + 12 hex digits. | |
108 | * | |
109 | * Add 11 bytes for each subauthority field (10 bytes each + 1 for '-') | |
110 | */ | |
111 | #define SID_STRING_BASE_SIZE (2 + 3 + 15 + 1) | |
112 | #define SID_STRING_SUBAUTH_SIZE (11) /* size of a single subauth string */ | |
113 | ||
114 | #define DOMAIN_USER_RID_LE cpu_to_le32(513) | |
115 | ||
116 | struct ksmbd_conn; | |
117 | ||
118 | struct smb_ntsd { | |
119 | __le16 revision; /* revision level */ | |
120 | __le16 type; | |
121 | __le32 osidoffset; | |
122 | __le32 gsidoffset; | |
123 | __le32 sacloffset; | |
124 | __le32 dacloffset; | |
125 | } __packed; | |
126 | ||
127 | struct smb_sid { | |
128 | __u8 revision; /* revision level */ | |
129 | __u8 num_subauth; | |
130 | __u8 authority[NUM_AUTHS]; | |
131 | __le32 sub_auth[SID_MAX_SUB_AUTHORITIES]; /* sub_auth[num_subauth] */ | |
132 | } __packed; | |
133 | ||
134 | /* size of a struct cifs_sid, sans sub_auth array */ | |
135 | #define CIFS_SID_BASE_SIZE (1 + 1 + NUM_AUTHS) | |
136 | ||
137 | struct smb_acl { | |
138 | __le16 revision; /* revision level */ | |
139 | __le16 size; | |
140 | __le32 num_aces; | |
141 | } __packed; | |
142 | ||
143 | struct smb_ace { | |
144 | __u8 type; | |
145 | __u8 flags; | |
146 | __le16 size; | |
147 | __le32 access_req; | |
148 | struct smb_sid sid; /* ie UUID of user or group who gets these perms */ | |
149 | } __packed; | |
150 | ||
151 | struct smb_fattr { | |
152 | kuid_t cf_uid; | |
153 | kgid_t cf_gid; | |
154 | umode_t cf_mode; | |
155 | __le32 daccess; | |
156 | struct posix_acl *cf_acls; | |
157 | struct posix_acl *cf_dacls; | |
158 | }; | |
159 | ||
160 | struct posix_ace_state { | |
161 | u32 allow; | |
162 | u32 deny; | |
163 | }; | |
164 | ||
165 | struct posix_user_ace_state { | |
166 | union { | |
167 | kuid_t uid; | |
168 | kgid_t gid; | |
169 | }; | |
170 | struct posix_ace_state perms; | |
171 | }; | |
172 | ||
173 | struct posix_ace_state_array { | |
174 | int n; | |
175 | struct posix_user_ace_state aces[]; | |
176 | }; | |
177 | ||
178 | /* | |
179 | * while processing the nfsv4 ace, this maintains the partial permissions | |
180 | * calculated so far: | |
181 | */ | |
182 | ||
183 | struct posix_acl_state { | |
184 | struct posix_ace_state owner; | |
185 | struct posix_ace_state group; | |
186 | struct posix_ace_state other; | |
187 | struct posix_ace_state everyone; | |
188 | struct posix_ace_state mask; /* deny unused in this case */ | |
189 | struct posix_ace_state_array *users; | |
190 | struct posix_ace_state_array *groups; | |
191 | }; | |
192 | ||
af34983e HL |
193 | int parse_sec_desc(struct user_namespace *user_ns, struct smb_ntsd *pntsd, |
194 | int acl_len, struct smb_fattr *fattr); | |
195 | int build_sec_desc(struct user_namespace *user_ns, struct smb_ntsd *pntsd, | |
196 | struct smb_ntsd *ppntsd, int addition_info, | |
197 | __u32 *secdesclen, struct smb_fattr *fattr); | |
e2f34481 NJ |
198 | int init_acl_state(struct posix_acl_state *state, int cnt); |
199 | void free_acl_state(struct posix_acl_state *state); | |
200 | void posix_state_to_acl(struct posix_acl_state *state, | |
d7e5852b | 201 | struct posix_acl_entry *pace); |
e2f34481 NJ |
202 | int compare_sids(const struct smb_sid *ctsid, const struct smb_sid *cwsid); |
203 | bool smb_inherit_flags(int flags, bool is_dir); | |
ef24c962 | 204 | int smb_inherit_dacl(struct ksmbd_conn *conn, struct path *path, |
d7e5852b | 205 | unsigned int uid, unsigned int gid); |
ef24c962 | 206 | int smb_check_perm_dacl(struct ksmbd_conn *conn, struct path *path, |
d7e5852b | 207 | __le32 *pdaccess, int uid); |
e2f34481 | 208 | int set_info_sec(struct ksmbd_conn *conn, struct ksmbd_tree_connect *tcon, |
ef24c962 | 209 | struct path *path, struct smb_ntsd *pntsd, int ntsd_len, |
d7e5852b | 210 | bool type_check); |
e2f34481 NJ |
211 | void id_to_sid(unsigned int cid, uint sidtype, struct smb_sid *ssid); |
212 | void ksmbd_init_domain(u32 *sub_auth); | |
0e844efe CB |
213 | |
214 | static inline uid_t posix_acl_uid_translate(struct user_namespace *mnt_userns, | |
215 | struct posix_acl_entry *pace) | |
216 | { | |
217 | kuid_t kuid; | |
218 | ||
219 | /* If this is an idmapped mount, apply the idmapping. */ | |
220 | kuid = kuid_into_mnt(mnt_userns, pace->e_uid); | |
221 | ||
222 | /* Translate the kuid into a userspace id ksmbd would see. */ | |
223 | return from_kuid(&init_user_ns, kuid); | |
224 | } | |
225 | ||
226 | static inline gid_t posix_acl_gid_translate(struct user_namespace *mnt_userns, | |
227 | struct posix_acl_entry *pace) | |
228 | { | |
229 | kgid_t kgid; | |
230 | ||
231 | /* If this is an idmapped mount, apply the idmapping. */ | |
232 | kgid = kgid_into_mnt(mnt_userns, pace->e_gid); | |
233 | ||
234 | /* Translate the kgid into a userspace id ksmbd would see. */ | |
235 | return from_kgid(&init_user_ns, kgid); | |
236 | } | |
237 | ||
e2f34481 | 238 | #endif /* _SMBACL_H */ |