Namjae Jeon | e2f3448 | 2021-03-16 10:49:09 +0900 | [diff] [blame] | 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> |
Christian Brauner | a793d79 | 2021-12-03 12:16:59 +0100 | [diff] [blame] | 14 | #include <linux/mnt_idmapping.h> |
Namjae Jeon | e2f3448 | 2021-03-16 10:49:09 +0900 | [diff] [blame] | 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 | |
Namjae Jeon | 6128468 | 2021-06-30 09:37:43 +0900 | [diff] [blame] | 21 | /* |
| 22 | * ACE types - see MS-DTYP 2.4.4.1 |
| 23 | */ |
| 24 | enum { |
| 25 | ACCESS_ALLOWED, |
| 26 | ACCESS_DENIED, |
| 27 | }; |
Namjae Jeon | e2f3448 | 2021-03-16 10:49:09 +0900 | [diff] [blame] | 28 | |
Namjae Jeon | 12411ad | 2021-06-30 09:38:13 +0900 | [diff] [blame] | 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 | }; |
Namjae Jeon | e2f3448 | 2021-03-16 10:49:09 +0900 | [diff] [blame] | 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 | |
Hyunchul Lee | af34983 | 2021-06-30 18:25:53 +0900 | [diff] [blame] | 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); |
Namjae Jeon | e2f3448 | 2021-03-16 10:49:09 +0900 | [diff] [blame] | 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, |
Hyunchul Lee | d7e5852 | 2021-05-29 09:59:59 +0900 | [diff] [blame] | 201 | struct posix_acl_entry *pace); |
Namjae Jeon | e2f3448 | 2021-03-16 10:49:09 +0900 | [diff] [blame] | 202 | int compare_sids(const struct smb_sid *ctsid, const struct smb_sid *cwsid); |
| 203 | bool smb_inherit_flags(int flags, bool is_dir); |
Hyunchul Lee | ef24c96 | 2021-06-30 18:25:52 +0900 | [diff] [blame] | 204 | int smb_inherit_dacl(struct ksmbd_conn *conn, struct path *path, |
Hyunchul Lee | d7e5852 | 2021-05-29 09:59:59 +0900 | [diff] [blame] | 205 | unsigned int uid, unsigned int gid); |
Hyunchul Lee | ef24c96 | 2021-06-30 18:25:52 +0900 | [diff] [blame] | 206 | int smb_check_perm_dacl(struct ksmbd_conn *conn, struct path *path, |
Hyunchul Lee | d7e5852 | 2021-05-29 09:59:59 +0900 | [diff] [blame] | 207 | __le32 *pdaccess, int uid); |
Namjae Jeon | e2f3448 | 2021-03-16 10:49:09 +0900 | [diff] [blame] | 208 | int set_info_sec(struct ksmbd_conn *conn, struct ksmbd_tree_connect *tcon, |
Hyunchul Lee | ef24c96 | 2021-06-30 18:25:52 +0900 | [diff] [blame] | 209 | struct path *path, struct smb_ntsd *pntsd, int ntsd_len, |
Hyunchul Lee | d7e5852 | 2021-05-29 09:59:59 +0900 | [diff] [blame] | 210 | bool type_check); |
Namjae Jeon | e2f3448 | 2021-03-16 10:49:09 +0900 | [diff] [blame] | 211 | void id_to_sid(unsigned int cid, uint sidtype, struct smb_sid *ssid); |
| 212 | void ksmbd_init_domain(u32 *sub_auth); |
Christian Brauner | 0e844ef | 2021-08-23 17:13:51 +0200 | [diff] [blame] | 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. */ |
Christian Brauner | 4472071 | 2021-12-03 12:17:03 +0100 | [diff] [blame] | 220 | kuid = mapped_kuid_fs(mnt_userns, &init_user_ns, pace->e_uid); |
Christian Brauner | 0e844ef | 2021-08-23 17:13:51 +0200 | [diff] [blame] | 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. */ |
Christian Brauner | 4472071 | 2021-12-03 12:17:03 +0100 | [diff] [blame] | 232 | kgid = mapped_kgid_fs(mnt_userns, &init_user_ns, pace->e_gid); |
Christian Brauner | 0e844ef | 2021-08-23 17:13:51 +0200 | [diff] [blame] | 233 | |
| 234 | /* Translate the kgid into a userspace id ksmbd would see. */ |
| 235 | return from_kgid(&init_user_ns, kgid); |
| 236 | } |
| 237 | |
Namjae Jeon | e2f3448 | 2021-03-16 10:49:09 +0900 | [diff] [blame] | 238 | #endif /* _SMBACL_H */ |