162306a36Sopenharmony_ci/* SPDX-License-Identifier: LGPL-2.1+ */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (c) International Business Machines Corp., 2007 462306a36Sopenharmony_ci * Author(s): Steve French (sfrench@us.ibm.com) 562306a36Sopenharmony_ci * Modified by Namjae Jeon (linkinjeon@kernel.org) 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#ifndef _SMBACL_H 962306a36Sopenharmony_ci#define _SMBACL_H 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci#include <linux/fs.h> 1262306a36Sopenharmony_ci#include <linux/namei.h> 1362306a36Sopenharmony_ci#include <linux/posix_acl.h> 1462306a36Sopenharmony_ci#include <linux/mnt_idmapping.h> 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci#include "mgmt/tree_connect.h" 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci#define NUM_AUTHS (6) /* number of authority fields */ 1962306a36Sopenharmony_ci#define SID_MAX_SUB_AUTHORITIES (15) /* max number of sub authority fields */ 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci/* 2262306a36Sopenharmony_ci * ACE types - see MS-DTYP 2.4.4.1 2362306a36Sopenharmony_ci */ 2462306a36Sopenharmony_cienum { 2562306a36Sopenharmony_ci ACCESS_ALLOWED, 2662306a36Sopenharmony_ci ACCESS_DENIED, 2762306a36Sopenharmony_ci}; 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci/* 3062306a36Sopenharmony_ci * Security ID types 3162306a36Sopenharmony_ci */ 3262306a36Sopenharmony_cienum { 3362306a36Sopenharmony_ci SIDOWNER = 1, 3462306a36Sopenharmony_ci SIDGROUP, 3562306a36Sopenharmony_ci SIDCREATOR_OWNER, 3662306a36Sopenharmony_ci SIDCREATOR_GROUP, 3762306a36Sopenharmony_ci SIDUNIX_USER, 3862306a36Sopenharmony_ci SIDUNIX_GROUP, 3962306a36Sopenharmony_ci SIDNFS_USER, 4062306a36Sopenharmony_ci SIDNFS_GROUP, 4162306a36Sopenharmony_ci SIDNFS_MODE, 4262306a36Sopenharmony_ci}; 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci/* Revision for ACLs */ 4562306a36Sopenharmony_ci#define SD_REVISION 1 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ci/* Control flags for Security Descriptor */ 4862306a36Sopenharmony_ci#define OWNER_DEFAULTED 0x0001 4962306a36Sopenharmony_ci#define GROUP_DEFAULTED 0x0002 5062306a36Sopenharmony_ci#define DACL_PRESENT 0x0004 5162306a36Sopenharmony_ci#define DACL_DEFAULTED 0x0008 5262306a36Sopenharmony_ci#define SACL_PRESENT 0x0010 5362306a36Sopenharmony_ci#define SACL_DEFAULTED 0x0020 5462306a36Sopenharmony_ci#define DACL_TRUSTED 0x0040 5562306a36Sopenharmony_ci#define SERVER_SECURITY 0x0080 5662306a36Sopenharmony_ci#define DACL_AUTO_INHERIT_REQ 0x0100 5762306a36Sopenharmony_ci#define SACL_AUTO_INHERIT_REQ 0x0200 5862306a36Sopenharmony_ci#define DACL_AUTO_INHERITED 0x0400 5962306a36Sopenharmony_ci#define SACL_AUTO_INHERITED 0x0800 6062306a36Sopenharmony_ci#define DACL_PROTECTED 0x1000 6162306a36Sopenharmony_ci#define SACL_PROTECTED 0x2000 6262306a36Sopenharmony_ci#define RM_CONTROL_VALID 0x4000 6362306a36Sopenharmony_ci#define SELF_RELATIVE 0x8000 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci/* ACE types - see MS-DTYP 2.4.4.1 */ 6662306a36Sopenharmony_ci#define ACCESS_ALLOWED_ACE_TYPE 0x00 6762306a36Sopenharmony_ci#define ACCESS_DENIED_ACE_TYPE 0x01 6862306a36Sopenharmony_ci#define SYSTEM_AUDIT_ACE_TYPE 0x02 6962306a36Sopenharmony_ci#define SYSTEM_ALARM_ACE_TYPE 0x03 7062306a36Sopenharmony_ci#define ACCESS_ALLOWED_COMPOUND_ACE_TYPE 0x04 7162306a36Sopenharmony_ci#define ACCESS_ALLOWED_OBJECT_ACE_TYPE 0x05 7262306a36Sopenharmony_ci#define ACCESS_DENIED_OBJECT_ACE_TYPE 0x06 7362306a36Sopenharmony_ci#define SYSTEM_AUDIT_OBJECT_ACE_TYPE 0x07 7462306a36Sopenharmony_ci#define SYSTEM_ALARM_OBJECT_ACE_TYPE 0x08 7562306a36Sopenharmony_ci#define ACCESS_ALLOWED_CALLBACK_ACE_TYPE 0x09 7662306a36Sopenharmony_ci#define ACCESS_DENIED_CALLBACK_ACE_TYPE 0x0A 7762306a36Sopenharmony_ci#define ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE 0x0B 7862306a36Sopenharmony_ci#define ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE 0x0C 7962306a36Sopenharmony_ci#define SYSTEM_AUDIT_CALLBACK_ACE_TYPE 0x0D 8062306a36Sopenharmony_ci#define SYSTEM_ALARM_CALLBACK_ACE_TYPE 0x0E /* Reserved */ 8162306a36Sopenharmony_ci#define SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE 0x0F 8262306a36Sopenharmony_ci#define SYSTEM_ALARM_CALLBACK_OBJECT_ACE_TYPE 0x10 /* reserved */ 8362306a36Sopenharmony_ci#define SYSTEM_MANDATORY_LABEL_ACE_TYPE 0x11 8462306a36Sopenharmony_ci#define SYSTEM_RESOURCE_ATTRIBUTE_ACE_TYPE 0x12 8562306a36Sopenharmony_ci#define SYSTEM_SCOPED_POLICY_ID_ACE_TYPE 0x13 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci/* ACE flags */ 8862306a36Sopenharmony_ci#define OBJECT_INHERIT_ACE 0x01 8962306a36Sopenharmony_ci#define CONTAINER_INHERIT_ACE 0x02 9062306a36Sopenharmony_ci#define NO_PROPAGATE_INHERIT_ACE 0x04 9162306a36Sopenharmony_ci#define INHERIT_ONLY_ACE 0x08 9262306a36Sopenharmony_ci#define INHERITED_ACE 0x10 9362306a36Sopenharmony_ci#define SUCCESSFUL_ACCESS_ACE_FLAG 0x40 9462306a36Sopenharmony_ci#define FAILED_ACCESS_ACE_FLAG 0x80 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ci/* 9762306a36Sopenharmony_ci * Maximum size of a string representation of a SID: 9862306a36Sopenharmony_ci * 9962306a36Sopenharmony_ci * The fields are unsigned values in decimal. So: 10062306a36Sopenharmony_ci * 10162306a36Sopenharmony_ci * u8: max 3 bytes in decimal 10262306a36Sopenharmony_ci * u32: max 10 bytes in decimal 10362306a36Sopenharmony_ci * 10462306a36Sopenharmony_ci * "S-" + 3 bytes for version field + 15 for authority field + NULL terminator 10562306a36Sopenharmony_ci * 10662306a36Sopenharmony_ci * For authority field, max is when all 6 values are non-zero and it must be 10762306a36Sopenharmony_ci * represented in hex. So "-0x" + 12 hex digits. 10862306a36Sopenharmony_ci * 10962306a36Sopenharmony_ci * Add 11 bytes for each subauthority field (10 bytes each + 1 for '-') 11062306a36Sopenharmony_ci */ 11162306a36Sopenharmony_ci#define SID_STRING_BASE_SIZE (2 + 3 + 15 + 1) 11262306a36Sopenharmony_ci#define SID_STRING_SUBAUTH_SIZE (11) /* size of a single subauth string */ 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ci#define DOMAIN_USER_RID_LE cpu_to_le32(513) 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_cistruct ksmbd_conn; 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_cistruct smb_ntsd { 11962306a36Sopenharmony_ci __le16 revision; /* revision level */ 12062306a36Sopenharmony_ci __le16 type; 12162306a36Sopenharmony_ci __le32 osidoffset; 12262306a36Sopenharmony_ci __le32 gsidoffset; 12362306a36Sopenharmony_ci __le32 sacloffset; 12462306a36Sopenharmony_ci __le32 dacloffset; 12562306a36Sopenharmony_ci} __packed; 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_cistruct smb_sid { 12862306a36Sopenharmony_ci __u8 revision; /* revision level */ 12962306a36Sopenharmony_ci __u8 num_subauth; 13062306a36Sopenharmony_ci __u8 authority[NUM_AUTHS]; 13162306a36Sopenharmony_ci __le32 sub_auth[SID_MAX_SUB_AUTHORITIES]; /* sub_auth[num_subauth] */ 13262306a36Sopenharmony_ci} __packed; 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_ci/* size of a struct cifs_sid, sans sub_auth array */ 13562306a36Sopenharmony_ci#define CIFS_SID_BASE_SIZE (1 + 1 + NUM_AUTHS) 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_cistruct smb_acl { 13862306a36Sopenharmony_ci __le16 revision; /* revision level */ 13962306a36Sopenharmony_ci __le16 size; 14062306a36Sopenharmony_ci __le32 num_aces; 14162306a36Sopenharmony_ci} __packed; 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_cistruct smb_ace { 14462306a36Sopenharmony_ci __u8 type; 14562306a36Sopenharmony_ci __u8 flags; 14662306a36Sopenharmony_ci __le16 size; 14762306a36Sopenharmony_ci __le32 access_req; 14862306a36Sopenharmony_ci struct smb_sid sid; /* ie UUID of user or group who gets these perms */ 14962306a36Sopenharmony_ci} __packed; 15062306a36Sopenharmony_ci 15162306a36Sopenharmony_cistruct smb_fattr { 15262306a36Sopenharmony_ci kuid_t cf_uid; 15362306a36Sopenharmony_ci kgid_t cf_gid; 15462306a36Sopenharmony_ci umode_t cf_mode; 15562306a36Sopenharmony_ci __le32 daccess; 15662306a36Sopenharmony_ci struct posix_acl *cf_acls; 15762306a36Sopenharmony_ci struct posix_acl *cf_dacls; 15862306a36Sopenharmony_ci}; 15962306a36Sopenharmony_ci 16062306a36Sopenharmony_cistruct posix_ace_state { 16162306a36Sopenharmony_ci u32 allow; 16262306a36Sopenharmony_ci u32 deny; 16362306a36Sopenharmony_ci}; 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_cistruct posix_user_ace_state { 16662306a36Sopenharmony_ci union { 16762306a36Sopenharmony_ci kuid_t uid; 16862306a36Sopenharmony_ci kgid_t gid; 16962306a36Sopenharmony_ci }; 17062306a36Sopenharmony_ci struct posix_ace_state perms; 17162306a36Sopenharmony_ci}; 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_cistruct posix_ace_state_array { 17462306a36Sopenharmony_ci int n; 17562306a36Sopenharmony_ci struct posix_user_ace_state aces[]; 17662306a36Sopenharmony_ci}; 17762306a36Sopenharmony_ci 17862306a36Sopenharmony_ci/* 17962306a36Sopenharmony_ci * while processing the nfsv4 ace, this maintains the partial permissions 18062306a36Sopenharmony_ci * calculated so far: 18162306a36Sopenharmony_ci */ 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_cistruct posix_acl_state { 18462306a36Sopenharmony_ci struct posix_ace_state owner; 18562306a36Sopenharmony_ci struct posix_ace_state group; 18662306a36Sopenharmony_ci struct posix_ace_state other; 18762306a36Sopenharmony_ci struct posix_ace_state everyone; 18862306a36Sopenharmony_ci struct posix_ace_state mask; /* deny unused in this case */ 18962306a36Sopenharmony_ci struct posix_ace_state_array *users; 19062306a36Sopenharmony_ci struct posix_ace_state_array *groups; 19162306a36Sopenharmony_ci}; 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_ciint parse_sec_desc(struct mnt_idmap *idmap, struct smb_ntsd *pntsd, 19462306a36Sopenharmony_ci int acl_len, struct smb_fattr *fattr); 19562306a36Sopenharmony_ciint build_sec_desc(struct mnt_idmap *idmap, struct smb_ntsd *pntsd, 19662306a36Sopenharmony_ci struct smb_ntsd *ppntsd, int ppntsd_size, int addition_info, 19762306a36Sopenharmony_ci __u32 *secdesclen, struct smb_fattr *fattr); 19862306a36Sopenharmony_ciint init_acl_state(struct posix_acl_state *state, int cnt); 19962306a36Sopenharmony_civoid free_acl_state(struct posix_acl_state *state); 20062306a36Sopenharmony_civoid posix_state_to_acl(struct posix_acl_state *state, 20162306a36Sopenharmony_ci struct posix_acl_entry *pace); 20262306a36Sopenharmony_ciint compare_sids(const struct smb_sid *ctsid, const struct smb_sid *cwsid); 20362306a36Sopenharmony_cibool smb_inherit_flags(int flags, bool is_dir); 20462306a36Sopenharmony_ciint smb_inherit_dacl(struct ksmbd_conn *conn, const struct path *path, 20562306a36Sopenharmony_ci unsigned int uid, unsigned int gid); 20662306a36Sopenharmony_ciint smb_check_perm_dacl(struct ksmbd_conn *conn, const struct path *path, 20762306a36Sopenharmony_ci __le32 *pdaccess, int uid); 20862306a36Sopenharmony_ciint set_info_sec(struct ksmbd_conn *conn, struct ksmbd_tree_connect *tcon, 20962306a36Sopenharmony_ci const struct path *path, struct smb_ntsd *pntsd, int ntsd_len, 21062306a36Sopenharmony_ci bool type_check, bool get_write); 21162306a36Sopenharmony_civoid id_to_sid(unsigned int cid, uint sidtype, struct smb_sid *ssid); 21262306a36Sopenharmony_civoid ksmbd_init_domain(u32 *sub_auth); 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_cistatic inline uid_t posix_acl_uid_translate(struct mnt_idmap *idmap, 21562306a36Sopenharmony_ci struct posix_acl_entry *pace) 21662306a36Sopenharmony_ci{ 21762306a36Sopenharmony_ci vfsuid_t vfsuid; 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_ci /* If this is an idmapped mount, apply the idmapping. */ 22062306a36Sopenharmony_ci vfsuid = make_vfsuid(idmap, &init_user_ns, pace->e_uid); 22162306a36Sopenharmony_ci 22262306a36Sopenharmony_ci /* Translate the kuid into a userspace id ksmbd would see. */ 22362306a36Sopenharmony_ci return from_kuid(&init_user_ns, vfsuid_into_kuid(vfsuid)); 22462306a36Sopenharmony_ci} 22562306a36Sopenharmony_ci 22662306a36Sopenharmony_cistatic inline gid_t posix_acl_gid_translate(struct mnt_idmap *idmap, 22762306a36Sopenharmony_ci struct posix_acl_entry *pace) 22862306a36Sopenharmony_ci{ 22962306a36Sopenharmony_ci vfsgid_t vfsgid; 23062306a36Sopenharmony_ci 23162306a36Sopenharmony_ci /* If this is an idmapped mount, apply the idmapping. */ 23262306a36Sopenharmony_ci vfsgid = make_vfsgid(idmap, &init_user_ns, pace->e_gid); 23362306a36Sopenharmony_ci 23462306a36Sopenharmony_ci /* Translate the kgid into a userspace id ksmbd would see. */ 23562306a36Sopenharmony_ci return from_kgid(&init_user_ns, vfsgid_into_kgid(vfsgid)); 23662306a36Sopenharmony_ci} 23762306a36Sopenharmony_ci 23862306a36Sopenharmony_ci#endif /* _SMBACL_H */ 239