^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * fs/cifs/cifsacl.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) International Business Machines Corp., 2007,2008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Author(s): Steve French (sfrench@us.ibm.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Contains the routines for mapping CIFS/NTFS ACLs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * This library is free software; you can redistribute it and/or modify
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * it under the terms of the GNU Lesser General Public License as published
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * by the Free Software Foundation; either version 2.1 of the License, or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * (at your option) any later version.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * This library is distributed in the hope that it will be useful,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * but WITHOUT ANY WARRANTY; without even the implied warranty of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * the GNU Lesser General Public License for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * You should have received a copy of the GNU Lesser General Public License
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * along with this library; if not, write to the Free Software
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/keyctl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/key-type.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <keys/user-type.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include "cifspdu.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include "cifsglob.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include "cifsacl.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include "cifsproto.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include "cifs_debug.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) /* security id for everyone/world system group */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) static const struct cifs_sid sid_everyone = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) 1, 1, {0, 0, 0, 0, 0, 1}, {0} };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) /* security id for Authenticated Users system group */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) static const struct cifs_sid sid_authusers = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) 1, 1, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(11)} };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) /* S-1-22-1 Unmapped Unix users */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) static const struct cifs_sid sid_unix_users = {1, 1, {0, 0, 0, 0, 0, 22},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) {cpu_to_le32(1), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) /* S-1-22-2 Unmapped Unix groups */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) static const struct cifs_sid sid_unix_groups = { 1, 1, {0, 0, 0, 0, 0, 22},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) {cpu_to_le32(2), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * See https://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) /* S-1-5-88 MS NFS and Apple style UID/GID/mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) /* S-1-5-88-1 Unix uid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) static const struct cifs_sid sid_unix_NFS_users = { 1, 2, {0, 0, 0, 0, 0, 5},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) {cpu_to_le32(88),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) cpu_to_le32(1), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) /* S-1-5-88-2 Unix gid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) static const struct cifs_sid sid_unix_NFS_groups = { 1, 2, {0, 0, 0, 0, 0, 5},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) {cpu_to_le32(88),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) cpu_to_le32(2), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) /* S-1-5-88-3 Unix mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) static const struct cifs_sid sid_unix_NFS_mode = { 1, 2, {0, 0, 0, 0, 0, 5},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) {cpu_to_le32(88),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) cpu_to_le32(3), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) static const struct cred *root_cred;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) cifs_idmap_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) char *payload;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * If the payload is less than or equal to the size of a pointer, then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * an allocation here is wasteful. Just copy the data directly to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * payload.value union member instead.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * With this however, you must check the datalen before trying to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * dereference payload.data!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) if (prep->datalen <= sizeof(key->payload)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) key->payload.data[0] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) memcpy(&key->payload, prep->data, prep->datalen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) payload = kmemdup(prep->data, prep->datalen, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) if (!payload)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) key->payload.data[0] = payload;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) key->datalen = prep->datalen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) cifs_idmap_key_destroy(struct key *key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) if (key->datalen > sizeof(key->payload))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) kfree(key->payload.data[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) static struct key_type cifs_idmap_key_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) .name = "cifs.idmap",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) .instantiate = cifs_idmap_key_instantiate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) .destroy = cifs_idmap_key_destroy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) .describe = user_describe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) static char *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) sid_to_key_str(struct cifs_sid *sidptr, unsigned int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) int i, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) unsigned int saval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) char *sidstr, *strptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) unsigned long long id_auth_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) /* 3 bytes for prefix */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) sidstr = kmalloc(3 + SID_STRING_BASE_SIZE +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) (SID_STRING_SUBAUTH_SIZE * sidptr->num_subauth),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) if (!sidstr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) return sidstr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) strptr = sidstr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) len = sprintf(strptr, "%cs:S-%hhu", type == SIDOWNER ? 'o' : 'g',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) sidptr->revision);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) strptr += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) /* The authority field is a single 48-bit number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) id_auth_val = (unsigned long long)sidptr->authority[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) id_auth_val |= (unsigned long long)sidptr->authority[4] << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) id_auth_val |= (unsigned long long)sidptr->authority[3] << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) id_auth_val |= (unsigned long long)sidptr->authority[2] << 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) id_auth_val |= (unsigned long long)sidptr->authority[1] << 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) id_auth_val |= (unsigned long long)sidptr->authority[0] << 48;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) * MS-DTYP states that if the authority is >= 2^32, then it should be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * expressed as a hex value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) if (id_auth_val <= UINT_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) len = sprintf(strptr, "-%llu", id_auth_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) len = sprintf(strptr, "-0x%llx", id_auth_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) strptr += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) for (i = 0; i < sidptr->num_subauth; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) saval = le32_to_cpu(sidptr->sub_auth[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) len = sprintf(strptr, "-%u", saval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) strptr += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) return sidstr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) * if the two SIDs (roughly equivalent to a UUID for a user or group) are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) * the same returns zero, if they do not match returns non-zero.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) int num_subauth, num_sat, num_saw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) if ((!ctsid) || (!cwsid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) /* compare the revision */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) if (ctsid->revision != cwsid->revision) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) if (ctsid->revision > cwsid->revision)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) /* compare all of the six auth values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) for (i = 0; i < NUM_AUTHS; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) if (ctsid->authority[i] != cwsid->authority[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) if (ctsid->authority[i] > cwsid->authority[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) /* compare all of the subauth values if any */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) num_sat = ctsid->num_subauth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) num_saw = cwsid->num_subauth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) num_subauth = num_sat < num_saw ? num_sat : num_saw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) if (num_subauth) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) for (i = 0; i < num_subauth; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) if (ctsid->sub_auth[i] != cwsid->sub_auth[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) if (le32_to_cpu(ctsid->sub_auth[i]) >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) le32_to_cpu(cwsid->sub_auth[i]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) return 0; /* sids compare/match */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) static bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) is_well_known_sid(const struct cifs_sid *psid, uint32_t *puid, bool is_group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) int num_subauth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) const struct cifs_sid *pwell_known_sid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) if (!psid || (puid == NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) num_subauth = psid->num_subauth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) /* check if Mac (or Windows NFS) vs. Samba format for Unix owner SID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) if (num_subauth == 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) if (is_group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) pwell_known_sid = &sid_unix_groups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) pwell_known_sid = &sid_unix_users;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) } else if (num_subauth == 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) if (is_group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) pwell_known_sid = &sid_unix_NFS_groups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) pwell_known_sid = &sid_unix_NFS_users;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) /* compare the revision */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) if (psid->revision != pwell_known_sid->revision)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) /* compare all of the six auth values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) for (i = 0; i < NUM_AUTHS; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) if (psid->authority[i] != pwell_known_sid->authority[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) cifs_dbg(FYI, "auth %d did not match\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) if (num_subauth == 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) if (psid->sub_auth[0] != pwell_known_sid->sub_auth[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) *puid = le32_to_cpu(psid->sub_auth[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) } else /* 3 subauths, ie Windows/Mac style */ {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) *puid = le32_to_cpu(psid->sub_auth[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) if ((psid->sub_auth[0] != pwell_known_sid->sub_auth[0]) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) (psid->sub_auth[1] != pwell_known_sid->sub_auth[1]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) *puid = le32_to_cpu(psid->sub_auth[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) cifs_dbg(FYI, "Unix UID %d returned from SID\n", *puid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) return true; /* well known sid found, uid returned */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) cifs_copy_sid(struct cifs_sid *dst, const struct cifs_sid *src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) dst->revision = src->revision;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) dst->num_subauth = min_t(u8, src->num_subauth, SID_MAX_SUB_AUTHORITIES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) for (i = 0; i < NUM_AUTHS; ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) dst->authority[i] = src->authority[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) for (i = 0; i < dst->num_subauth; ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) dst->sub_auth[i] = src->sub_auth[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) id_to_sid(unsigned int cid, uint sidtype, struct cifs_sid *ssid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) struct key *sidkey;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) struct cifs_sid *ksid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) unsigned int ksid_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) char desc[3 + 10 + 1]; /* 3 byte prefix + 10 bytes for value + NULL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) const struct cred *saved_cred;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) rc = snprintf(desc, sizeof(desc), "%ci:%u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) sidtype == SIDOWNER ? 'o' : 'g', cid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) if (rc >= sizeof(desc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) saved_cred = override_creds(root_cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) sidkey = request_key(&cifs_idmap_key_type, desc, "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) if (IS_ERR(sidkey)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) cifs_dbg(FYI, "%s: Can't map %cid %u to a SID\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) __func__, sidtype == SIDOWNER ? 'u' : 'g', cid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) goto out_revert_creds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) } else if (sidkey->datalen < CIFS_SID_BASE_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) __func__, sidkey->datalen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) goto invalidate_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) * A sid is usually too large to be embedded in payload.value, but if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) * there are no subauthorities and the host has 8-byte pointers, then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) * it could be.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) ksid = sidkey->datalen <= sizeof(sidkey->payload) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) (struct cifs_sid *)&sidkey->payload :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) (struct cifs_sid *)sidkey->payload.data[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) ksid_size = CIFS_SID_BASE_SIZE + (ksid->num_subauth * sizeof(__le32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) if (ksid_size > sidkey->datalen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu, ksid_size=%u)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) __func__, sidkey->datalen, ksid_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) goto invalidate_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) cifs_copy_sid(ssid, ksid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) out_key_put:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) key_put(sidkey);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) out_revert_creds:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) revert_creds(saved_cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) invalidate_key:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) key_invalidate(sidkey);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) goto out_key_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) sid_to_id(struct cifs_sb_info *cifs_sb, struct cifs_sid *psid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) struct cifs_fattr *fattr, uint sidtype)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) struct key *sidkey;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) char *sidstr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) const struct cred *saved_cred;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) kuid_t fuid = cifs_sb->mnt_uid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) kgid_t fgid = cifs_sb->mnt_gid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) * If we have too many subauthorities, then something is really wrong.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) * Just return an error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) if (unlikely(psid->num_subauth > SID_MAX_SUB_AUTHORITIES)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) cifs_dbg(FYI, "%s: %u subauthorities is too many!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) __func__, psid->num_subauth);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UID_FROM_ACL) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) (cifs_sb_master_tcon(cifs_sb)->posix_extensions)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) uint32_t unix_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) bool is_group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) if (sidtype != SIDOWNER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) is_group = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) is_group = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) if (is_well_known_sid(psid, &unix_id, is_group) == false)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) goto try_upcall_to_get_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) if (is_group) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) kgid_t gid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) gid_t id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) id = (gid_t)unix_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) gid = make_kgid(&init_user_ns, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) if (gid_valid(gid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) fgid = gid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) goto got_valid_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) kuid_t uid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) uid_t id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) id = (uid_t)unix_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) uid = make_kuid(&init_user_ns, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) if (uid_valid(uid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) fuid = uid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) goto got_valid_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) /* If unable to find uid/gid easily from SID try via upcall */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) try_upcall_to_get_id:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) sidstr = sid_to_key_str(psid, sidtype);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) if (!sidstr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) saved_cred = override_creds(root_cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) sidkey = request_key(&cifs_idmap_key_type, sidstr, "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) if (IS_ERR(sidkey)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) cifs_dbg(FYI, "%s: Can't map SID %s to a %cid\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) __func__, sidstr, sidtype == SIDOWNER ? 'u' : 'g');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) goto out_revert_creds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) * FIXME: Here we assume that uid_t and gid_t are same size. It's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) * probably a safe assumption but might be better to check based on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) * sidtype.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) BUILD_BUG_ON(sizeof(uid_t) != sizeof(gid_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if (sidkey->datalen != sizeof(uid_t)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) __func__, sidkey->datalen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) key_invalidate(sidkey);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) goto out_key_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) if (sidtype == SIDOWNER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) kuid_t uid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) uid_t id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) memcpy(&id, &sidkey->payload.data[0], sizeof(uid_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) uid = make_kuid(&init_user_ns, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) if (uid_valid(uid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) fuid = uid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) kgid_t gid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) gid_t id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) memcpy(&id, &sidkey->payload.data[0], sizeof(gid_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) gid = make_kgid(&init_user_ns, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) if (gid_valid(gid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) fgid = gid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) out_key_put:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) key_put(sidkey);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) out_revert_creds:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) revert_creds(saved_cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) kfree(sidstr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) * Note that we return 0 here unconditionally. If the mapping
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) * fails then we just fall back to using the mnt_uid/mnt_gid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) got_valid_id:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) if (sidtype == SIDOWNER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) fattr->cf_uid = fuid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) fattr->cf_gid = fgid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) init_cifs_idmap(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) struct cred *cred;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) struct key *keyring;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) cifs_dbg(FYI, "Registering the %s key type\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) cifs_idmap_key_type.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) /* create an override credential set with a special thread keyring in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) * which requests are cached
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) * this is used to prevent malicious redirections from being installed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) * with add_key().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) cred = prepare_kernel_cred(NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) if (!cred)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) keyring = keyring_alloc(".cifs_idmap",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) (KEY_POS_ALL & ~KEY_POS_SETATTR) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) KEY_USR_VIEW | KEY_USR_READ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) if (IS_ERR(keyring)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) ret = PTR_ERR(keyring);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) goto failed_put_cred;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) ret = register_key_type(&cifs_idmap_key_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) goto failed_put_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) /* instruct request_key() to use this special keyring as a cache for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) * the results it looks up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) cred->thread_keyring = keyring;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) root_cred = cred;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) cifs_dbg(FYI, "cifs idmap keyring: %d\n", key_serial(keyring));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) failed_put_key:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) key_put(keyring);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) failed_put_cred:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) put_cred(cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) exit_cifs_idmap(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) key_revoke(root_cred->thread_keyring);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) unregister_key_type(&cifs_idmap_key_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) put_cred(root_cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) cifs_dbg(FYI, "Unregistered %s key type\n", cifs_idmap_key_type.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) /* copy ntsd, owner sid, and group sid from a security descriptor to another */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) static void copy_sec_desc(const struct cifs_ntsd *pntsd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) struct cifs_ntsd *pnntsd, __u32 sidsoffset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) /* copy security descriptor control portion */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) pnntsd->revision = pntsd->revision;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) pnntsd->type = pntsd->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) pnntsd->dacloffset = cpu_to_le32(sizeof(struct cifs_ntsd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) pnntsd->sacloffset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) pnntsd->osidoffset = cpu_to_le32(sidsoffset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) pnntsd->gsidoffset = cpu_to_le32(sidsoffset + sizeof(struct cifs_sid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) /* copy owner sid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) le32_to_cpu(pntsd->osidoffset));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) nowner_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) cifs_copy_sid(nowner_sid_ptr, owner_sid_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) /* copy group sid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) le32_to_cpu(pntsd->gsidoffset));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) ngroup_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) sizeof(struct cifs_sid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) cifs_copy_sid(ngroup_sid_ptr, group_sid_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) change posix mode to reflect permissions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) pmode is the existing mode (we only want to overwrite part of this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) bits to set can be: S_IRWXU, S_IRWXG or S_IRWXO ie 00700 or 00070 or 00007
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) static void access_flags_to_mode(__le32 ace_flags, int type, umode_t *pmode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) umode_t *pbits_to_set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) __u32 flags = le32_to_cpu(ace_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) /* the order of ACEs is important. The canonical order is to begin with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) DENY entries followed by ALLOW, otherwise an allow entry could be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) encountered first, making the subsequent deny entry like "dead code"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) which would be superflous since Windows stops when a match is made
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) for the operation you are trying to perform for your user */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) /* For deny ACEs we change the mask so that subsequent allow access
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) control entries do not turn on the bits we are denying */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) if (type == ACCESS_DENIED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) if (flags & GENERIC_ALL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) *pbits_to_set &= ~S_IRWXUGO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) if ((flags & GENERIC_WRITE) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) ((flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) *pbits_to_set &= ~S_IWUGO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) if ((flags & GENERIC_READ) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) ((flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) *pbits_to_set &= ~S_IRUGO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) if ((flags & GENERIC_EXECUTE) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) ((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) *pbits_to_set &= ~S_IXUGO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) } else if (type != ACCESS_ALLOWED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) cifs_dbg(VFS, "unknown access control type %d\n", type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) /* else ACCESS_ALLOWED type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) if (flags & GENERIC_ALL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) *pmode |= (S_IRWXUGO & (*pbits_to_set));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) cifs_dbg(NOISY, "all perms\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) if ((flags & GENERIC_WRITE) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) ((flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) *pmode |= (S_IWUGO & (*pbits_to_set));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) if ((flags & GENERIC_READ) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) ((flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) *pmode |= (S_IRUGO & (*pbits_to_set));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) if ((flags & GENERIC_EXECUTE) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) ((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) *pmode |= (S_IXUGO & (*pbits_to_set));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) cifs_dbg(NOISY, "access flags 0x%x mode now %04o\n", flags, *pmode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) Generate access flags to reflect permissions mode is the existing mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) This function is called for every ACE in the DACL whose SID matches
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) with either owner or group or everyone.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) static void mode_to_access_flags(umode_t mode, umode_t bits_to_use,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) __u32 *pace_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) /* reset access mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) *pace_flags = 0x0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) /* bits to use are either S_IRWXU or S_IRWXG or S_IRWXO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) mode &= bits_to_use;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) /* check for R/W/X UGO since we do not know whose flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) is this but we have cleared all the bits sans RWX for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) either user or group or other as per bits_to_use */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) if (mode & S_IRUGO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) *pace_flags |= SET_FILE_READ_RIGHTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) if (mode & S_IWUGO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) *pace_flags |= SET_FILE_WRITE_RIGHTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) if (mode & S_IXUGO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) *pace_flags |= SET_FILE_EXEC_RIGHTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) cifs_dbg(NOISY, "mode: %04o, access flags now 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) mode, *pace_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) static __u16 fill_ace_for_sid(struct cifs_ace *pntace,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) const struct cifs_sid *psid, __u64 nmode, umode_t bits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) __u16 size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) __u32 access_req = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) pntace->type = ACCESS_ALLOWED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) pntace->flags = 0x0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) mode_to_access_flags(nmode, bits, &access_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) if (!access_req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) access_req = SET_MINIMUM_RIGHTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) pntace->access_req = cpu_to_le32(access_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) pntace->sid.revision = psid->revision;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) pntace->sid.num_subauth = psid->num_subauth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) for (i = 0; i < NUM_AUTHS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) pntace->sid.authority[i] = psid->authority[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) for (i = 0; i < psid->num_subauth; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) pntace->sid.sub_auth[i] = psid->sub_auth[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth * 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) pntace->size = cpu_to_le16(size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) return size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) #ifdef CONFIG_CIFS_DEBUG2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) static void dump_ace(struct cifs_ace *pace, char *end_of_acl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) int num_subauth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) /* validate that we do not go past end of acl */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) if (le16_to_cpu(pace->size) < 16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) cifs_dbg(VFS, "ACE too small %d\n", le16_to_cpu(pace->size));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) if (end_of_acl < (char *)pace + le16_to_cpu(pace->size)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) cifs_dbg(VFS, "ACL too small to parse ACE\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) num_subauth = pace->sid.num_subauth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) if (num_subauth) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) cifs_dbg(FYI, "ACE revision %d num_auth %d type %d flags %d size %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) pace->sid.revision, pace->sid.num_subauth, pace->type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) pace->flags, le16_to_cpu(pace->size));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) for (i = 0; i < num_subauth; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) cifs_dbg(FYI, "ACE sub_auth[%d]: 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) i, le32_to_cpu(pace->sid.sub_auth[i]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) /* BB add length check to make sure that we do not have huge
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) num auths and therefore go off the end */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) struct cifs_sid *pownersid, struct cifs_sid *pgrpsid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) struct cifs_fattr *fattr, bool mode_from_special_sid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) int num_aces = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) int acl_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) char *acl_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) struct cifs_ace **ppace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) /* BB need to add parm so we can store the SID BB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) if (!pdacl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) /* no DACL in the security descriptor, set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) all the permissions for user/group/other */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) fattr->cf_mode |= S_IRWXUGO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) /* validate that we do not go past end of acl */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) if (end_of_acl < (char *)pdacl + le16_to_cpu(pdacl->size)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) cifs_dbg(VFS, "ACL too small to parse DACL\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) cifs_dbg(NOISY, "DACL revision %d size %d num aces %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) le16_to_cpu(pdacl->revision), le16_to_cpu(pdacl->size),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) le32_to_cpu(pdacl->num_aces));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) /* reset rwx permissions for user/group/other.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) Also, if num_aces is 0 i.e. DACL has no ACEs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) user/group/other have no permissions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) fattr->cf_mode &= ~(S_IRWXUGO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) acl_base = (char *)pdacl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) acl_size = sizeof(struct cifs_acl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) num_aces = le32_to_cpu(pdacl->num_aces);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) if (num_aces > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) umode_t user_mask = S_IRWXU;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) umode_t group_mask = S_IRWXG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) umode_t other_mask = S_IRWXU | S_IRWXG | S_IRWXO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) if (num_aces > ULONG_MAX / sizeof(struct cifs_ace *))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) ppace = kmalloc_array(num_aces, sizeof(struct cifs_ace *),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) if (!ppace)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) for (i = 0; i < num_aces; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) ppace[i] = (struct cifs_ace *) (acl_base + acl_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) #ifdef CONFIG_CIFS_DEBUG2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) dump_ace(ppace[i], end_of_acl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) if (mode_from_special_sid &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) (compare_sids(&(ppace[i]->sid),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) &sid_unix_NFS_mode) == 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) * Full permissions are:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) * 07777 = S_ISUID | S_ISGID | S_ISVTX |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) * S_IRWXU | S_IRWXG | S_IRWXO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) fattr->cf_mode &= ~07777;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) fattr->cf_mode |=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) le32_to_cpu(ppace[i]->sid.sub_auth[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) } else if (compare_sids(&(ppace[i]->sid), pownersid) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) access_flags_to_mode(ppace[i]->access_req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) ppace[i]->type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) &fattr->cf_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) &user_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) else if (compare_sids(&(ppace[i]->sid), pgrpsid) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) access_flags_to_mode(ppace[i]->access_req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) ppace[i]->type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) &fattr->cf_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) &group_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) else if (compare_sids(&(ppace[i]->sid), &sid_everyone) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) access_flags_to_mode(ppace[i]->access_req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) ppace[i]->type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) &fattr->cf_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) &other_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) else if (compare_sids(&(ppace[i]->sid), &sid_authusers) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) access_flags_to_mode(ppace[i]->access_req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) ppace[i]->type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) &fattr->cf_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) &other_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) /* memcpy((void *)(&(cifscred->aces[i])),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) (void *)ppace[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) sizeof(struct cifs_ace)); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) acl_base = (char *)ppace[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) acl_size = le16_to_cpu(ppace[i]->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) kfree(ppace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) unsigned int setup_authusers_ACE(struct cifs_ace *pntace)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) unsigned int ace_size = 20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) pntace->type = ACCESS_ALLOWED_ACE_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) pntace->flags = 0x0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) pntace->access_req = cpu_to_le32(GENERIC_ALL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) pntace->sid.num_subauth = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) pntace->sid.revision = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) for (i = 0; i < NUM_AUTHS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) pntace->sid.authority[i] = sid_authusers.authority[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) pntace->sid.sub_auth[0] = sid_authusers.sub_auth[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) /* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth*4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) pntace->size = cpu_to_le16(ace_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) return ace_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) * Fill in the special SID based on the mode. See
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) * https://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) unsigned int setup_special_mode_ACE(struct cifs_ace *pntace, __u64 nmode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) unsigned int ace_size = 28;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) pntace->type = ACCESS_DENIED_ACE_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) pntace->flags = 0x0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) pntace->access_req = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) pntace->sid.num_subauth = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) pntace->sid.revision = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) for (i = 0; i < NUM_AUTHS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) pntace->sid.authority[i] = sid_unix_NFS_mode.authority[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) pntace->sid.sub_auth[0] = sid_unix_NFS_mode.sub_auth[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) pntace->sid.sub_auth[1] = sid_unix_NFS_mode.sub_auth[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) pntace->sid.sub_auth[2] = cpu_to_le32(nmode & 07777);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) /* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth*4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) pntace->size = cpu_to_le16(ace_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) return ace_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) unsigned int setup_special_user_owner_ACE(struct cifs_ace *pntace)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) unsigned int ace_size = 28;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) pntace->type = ACCESS_ALLOWED_ACE_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) pntace->flags = 0x0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) pntace->access_req = cpu_to_le32(GENERIC_ALL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) pntace->sid.num_subauth = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) pntace->sid.revision = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) for (i = 0; i < NUM_AUTHS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) pntace->sid.authority[i] = sid_unix_NFS_users.authority[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) pntace->sid.sub_auth[0] = sid_unix_NFS_users.sub_auth[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) pntace->sid.sub_auth[1] = sid_unix_NFS_users.sub_auth[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) pntace->sid.sub_auth[2] = cpu_to_le32(current_fsgid().val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) /* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth*4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) pntace->size = cpu_to_le16(ace_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) return ace_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) static int set_chmod_dacl(struct cifs_acl *pndacl, struct cifs_sid *pownersid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) struct cifs_sid *pgrpsid, __u64 nmode, bool modefromsid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) u16 size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) u32 num_aces = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) struct cifs_acl *pnndacl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) pnndacl = (struct cifs_acl *)((char *)pndacl + sizeof(struct cifs_acl));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) if (modefromsid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) struct cifs_ace *pntace =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) (struct cifs_ace *)((char *)pnndacl + size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) size += setup_special_mode_ACE(pntace, nmode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) num_aces++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) size += fill_ace_for_sid((struct cifs_ace *) ((char *)pnndacl + size),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) pownersid, nmode, S_IRWXU);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) num_aces++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) size += fill_ace_for_sid((struct cifs_ace *)((char *)pnndacl + size),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) pgrpsid, nmode, S_IRWXG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) num_aces++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) size += fill_ace_for_sid((struct cifs_ace *)((char *)pnndacl + size),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) &sid_everyone, nmode, S_IRWXO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) num_aces++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) pndacl->num_aces = cpu_to_le32(num_aces);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) pndacl->size = cpu_to_le16(size + sizeof(struct cifs_acl));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) static int parse_sid(struct cifs_sid *psid, char *end_of_acl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) /* BB need to add parm so we can store the SID BB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) /* validate that we do not go past end of ACL - sid must be at least 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) bytes long (assuming no sub-auths - e.g. the null SID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) if (end_of_acl < (char *)psid + 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) cifs_dbg(VFS, "ACL too small to parse SID %p\n", psid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) #ifdef CONFIG_CIFS_DEBUG2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) if (psid->num_subauth) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) cifs_dbg(FYI, "SID revision %d num_auth %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) psid->revision, psid->num_subauth);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) for (i = 0; i < psid->num_subauth; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) cifs_dbg(FYI, "SID sub_auth[%d]: 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) i, le32_to_cpu(psid->sub_auth[i]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) /* BB add length check to make sure that we do not have huge
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) num auths and therefore go off the end */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) cifs_dbg(FYI, "RID 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) le32_to_cpu(psid->sub_auth[psid->num_subauth-1]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) /* Convert CIFS ACL to POSIX form */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) static int parse_sec_desc(struct cifs_sb_info *cifs_sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) struct cifs_ntsd *pntsd, int acl_len, struct cifs_fattr *fattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) bool get_mode_from_special_sid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) struct cifs_acl *dacl_ptr; /* no need for SACL ptr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) char *end_of_acl = ((char *)pntsd) + acl_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) __u32 dacloffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) if (pntsd == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) le32_to_cpu(pntsd->osidoffset));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) le32_to_cpu(pntsd->gsidoffset));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) dacloffset = le32_to_cpu(pntsd->dacloffset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) cifs_dbg(NOISY, "revision %d type 0x%x ooffset 0x%x goffset 0x%x sacloffset 0x%x dacloffset 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) le32_to_cpu(pntsd->gsidoffset),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) le32_to_cpu(pntsd->sacloffset), dacloffset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) /* cifs_dump_mem("owner_sid: ", owner_sid_ptr, 64); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) rc = parse_sid(owner_sid_ptr, end_of_acl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) cifs_dbg(FYI, "%s: Error %d parsing Owner SID\n", __func__, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) rc = sid_to_id(cifs_sb, owner_sid_ptr, fattr, SIDOWNER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) cifs_dbg(FYI, "%s: Error %d mapping Owner SID to uid\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) __func__, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) rc = parse_sid(group_sid_ptr, end_of_acl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) cifs_dbg(FYI, "%s: Error %d mapping Owner SID to gid\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) __func__, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) rc = sid_to_id(cifs_sb, group_sid_ptr, fattr, SIDGROUP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) cifs_dbg(FYI, "%s: Error %d mapping Group SID to gid\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) __func__, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) if (dacloffset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) group_sid_ptr, fattr, get_mode_from_special_sid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) cifs_dbg(FYI, "no ACL\n"); /* BB grant all or default perms? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) /* Convert permission bits from mode to equivalent CIFS ACL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) __u32 secdesclen, __u64 nmode, kuid_t uid, kgid_t gid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) bool mode_from_sid, bool id_from_sid, int *aclflag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) __u32 dacloffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) __u32 ndacloffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) __u32 sidsoffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) struct cifs_acl *dacl_ptr = NULL; /* no need for SACL ptr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) struct cifs_acl *ndacl_ptr = NULL; /* no need for SACL ptr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) if (nmode != NO_CHANGE_64) { /* chmod */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) le32_to_cpu(pntsd->osidoffset));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) le32_to_cpu(pntsd->gsidoffset));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) dacloffset = le32_to_cpu(pntsd->dacloffset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) ndacloffset = sizeof(struct cifs_ntsd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) ndacl_ptr = (struct cifs_acl *)((char *)pnntsd + ndacloffset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) ndacl_ptr->revision = dacl_ptr->revision;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) ndacl_ptr->size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) ndacl_ptr->num_aces = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) rc = set_chmod_dacl(ndacl_ptr, owner_sid_ptr, group_sid_ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) nmode, mode_from_sid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) sidsoffset = ndacloffset + le16_to_cpu(ndacl_ptr->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) /* copy sec desc control portion & owner and group sids */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) copy_sec_desc(pntsd, pnntsd, sidsoffset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) *aclflag = CIFS_ACL_DACL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) memcpy(pnntsd, pntsd, secdesclen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) if (uid_valid(uid)) { /* chown */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) uid_t id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) owner_sid_ptr = (struct cifs_sid *)((char *)pnntsd +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) le32_to_cpu(pnntsd->osidoffset));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) nowner_sid_ptr = kmalloc(sizeof(struct cifs_sid),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) if (!nowner_sid_ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) id = from_kuid(&init_user_ns, uid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) if (id_from_sid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) struct owner_sid *osid = (struct owner_sid *)nowner_sid_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) /* Populate the user ownership fields S-1-5-88-1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) osid->Revision = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) osid->NumAuth = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) osid->Authority[5] = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) osid->SubAuthorities[0] = cpu_to_le32(88);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) osid->SubAuthorities[1] = cpu_to_le32(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) osid->SubAuthorities[2] = cpu_to_le32(id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) } else { /* lookup sid with upcall */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) rc = id_to_sid(id, SIDOWNER, nowner_sid_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) cifs_dbg(FYI, "%s: Mapping error %d for owner id %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) __func__, rc, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) kfree(nowner_sid_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) cifs_copy_sid(owner_sid_ptr, nowner_sid_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) kfree(nowner_sid_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) *aclflag = CIFS_ACL_OWNER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) if (gid_valid(gid)) { /* chgrp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) gid_t id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) group_sid_ptr = (struct cifs_sid *)((char *)pnntsd +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) le32_to_cpu(pnntsd->gsidoffset));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) ngroup_sid_ptr = kmalloc(sizeof(struct cifs_sid),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) if (!ngroup_sid_ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) id = from_kgid(&init_user_ns, gid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) if (id_from_sid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) struct owner_sid *gsid = (struct owner_sid *)ngroup_sid_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) /* Populate the group ownership fields S-1-5-88-2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) gsid->Revision = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) gsid->NumAuth = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) gsid->Authority[5] = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) gsid->SubAuthorities[0] = cpu_to_le32(88);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) gsid->SubAuthorities[1] = cpu_to_le32(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) gsid->SubAuthorities[2] = cpu_to_le32(id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) } else { /* lookup sid with upcall */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) rc = id_to_sid(id, SIDGROUP, ngroup_sid_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) cifs_dbg(FYI, "%s: Mapping error %d for group id %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) __func__, rc, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) kfree(ngroup_sid_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) cifs_copy_sid(group_sid_ptr, ngroup_sid_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) kfree(ngroup_sid_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) *aclflag = CIFS_ACL_GROUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) const struct cifs_fid *cifsfid, u32 *pacllen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) struct cifs_ntsd *pntsd = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) unsigned int xid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) if (IS_ERR(tlink))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) return ERR_CAST(tlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) xid = get_xid();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) rc = CIFSSMBGetCIFSACL(xid, tlink_tcon(tlink), cifsfid->netfid, &pntsd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) pacllen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) free_xid(xid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) cifs_put_tlink(tlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) cifs_dbg(FYI, "%s: rc = %d ACL len %d\n", __func__, rc, *pacllen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) return ERR_PTR(rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) return pntsd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) const char *path, u32 *pacllen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) struct cifs_ntsd *pntsd = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) int oplock = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) unsigned int xid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) struct cifs_tcon *tcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) struct cifs_fid fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) struct cifs_open_parms oparms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) if (IS_ERR(tlink))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) return ERR_CAST(tlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) tcon = tlink_tcon(tlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) xid = get_xid();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) oparms.tcon = tcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) oparms.cifs_sb = cifs_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) oparms.desired_access = READ_CONTROL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) oparms.create_options = cifs_create_options(cifs_sb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) oparms.disposition = FILE_OPEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) oparms.path = path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) oparms.fid = &fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) oparms.reconnect = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) rc = CIFS_open(xid, &oparms, &oplock, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) if (!rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) rc = CIFSSMBGetCIFSACL(xid, tcon, fid.netfid, &pntsd, pacllen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) CIFSSMBClose(xid, tcon, fid.netfid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) cifs_put_tlink(tlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) free_xid(xid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) cifs_dbg(FYI, "%s: rc = %d ACL len %d\n", __func__, rc, *pacllen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) return ERR_PTR(rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) return pntsd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) /* Retrieve an ACL from the server */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) struct inode *inode, const char *path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) u32 *pacllen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) struct cifs_ntsd *pntsd = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) struct cifsFileInfo *open_file = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) if (inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) open_file = find_readable_file(CIFS_I(inode), true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) if (!open_file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) return get_cifs_acl_by_path(cifs_sb, path, pacllen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) pntsd = get_cifs_acl_by_fid(cifs_sb, &open_file->fid, pacllen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) cifsFileInfo_put(open_file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) return pntsd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) /* Set an ACL on the server */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) struct inode *inode, const char *path, int aclflag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) int oplock = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) unsigned int xid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) int rc, access_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) struct cifs_tcon *tcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) struct cifs_fid fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) struct cifs_open_parms oparms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) if (IS_ERR(tlink))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) return PTR_ERR(tlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) tcon = tlink_tcon(tlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) xid = get_xid();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) if (aclflag == CIFS_ACL_OWNER || aclflag == CIFS_ACL_GROUP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) access_flags = WRITE_OWNER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) access_flags = WRITE_DAC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) oparms.tcon = tcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) oparms.cifs_sb = cifs_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) oparms.desired_access = access_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) oparms.create_options = cifs_create_options(cifs_sb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) oparms.disposition = FILE_OPEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) oparms.path = path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) oparms.fid = &fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) oparms.reconnect = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) rc = CIFS_open(xid, &oparms, &oplock, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) cifs_dbg(VFS, "Unable to open file to set ACL\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) rc = CIFSSMBSetCIFSACL(xid, tcon, fid.netfid, pnntsd, acllen, aclflag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) cifs_dbg(NOISY, "SetCIFSACL rc = %d\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) CIFSSMBClose(xid, tcon, fid.netfid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) free_xid(xid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) cifs_put_tlink(tlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) /* Translate the CIFS ACL (similar to NTFS ACL) for a file into mode bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) struct inode *inode, bool mode_from_special_sid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) const char *path, const struct cifs_fid *pfid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) struct cifs_ntsd *pntsd = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) u32 acllen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) struct smb_version_operations *ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) cifs_dbg(NOISY, "converting ACL to mode for %s\n", path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) if (IS_ERR(tlink))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) return PTR_ERR(tlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) ops = tlink_tcon(tlink)->ses->server->ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) if (pfid && (ops->get_acl_by_fid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) pntsd = ops->get_acl_by_fid(cifs_sb, pfid, &acllen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) else if (ops->get_acl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) pntsd = ops->get_acl(cifs_sb, inode, path, &acllen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) cifs_put_tlink(tlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) /* if we can retrieve the ACL, now parse Access Control Entries, ACEs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) if (IS_ERR(pntsd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) rc = PTR_ERR(pntsd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) } else if (mode_from_special_sid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) kfree(pntsd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) /* get approximated mode from ACL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) kfree(pntsd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) cifs_dbg(VFS, "parse sec desc failed rc = %d\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) cifs_put_tlink(tlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) /* Convert mode bits to an ACL so we can update the ACL on the server */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) kuid_t uid, kgid_t gid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) int aclflag = CIFS_ACL_DACL; /* default flag to set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) __u32 secdesclen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) struct cifs_ntsd *pntsd = NULL; /* acl obtained from server */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) struct cifs_ntsd *pnntsd = NULL; /* modified acl to be sent to server */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) struct smb_version_operations *ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) bool mode_from_sid, id_from_sid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) if (IS_ERR(tlink))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) return PTR_ERR(tlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) ops = tlink_tcon(tlink)->ses->server->ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) cifs_dbg(NOISY, "set ACL from mode for %s\n", path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) /* Get the security descriptor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) if (ops->get_acl == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) cifs_put_tlink(tlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) pntsd = ops->get_acl(cifs_sb, inode, path, &secdesclen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) if (IS_ERR(pntsd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) rc = PTR_ERR(pntsd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) cifs_put_tlink(tlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) * Add three ACEs for owner, group, everyone getting rid of other ACEs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) * as chmod disables ACEs and set the security descriptor. Allocate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) * memory for the smb header, set security descriptor request security
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) * descriptor parameters, and secuirty descriptor itself
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) secdesclen = max_t(u32, secdesclen, DEFAULT_SEC_DESC_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) pnntsd = kmalloc(secdesclen, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) if (!pnntsd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) kfree(pntsd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) cifs_put_tlink(tlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) mode_from_sid = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) mode_from_sid = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UID_FROM_ACL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) id_from_sid = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) id_from_sid = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) rc = build_sec_desc(pntsd, pnntsd, secdesclen, nmode, uid, gid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) mode_from_sid, id_from_sid, &aclflag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) cifs_dbg(NOISY, "build_sec_desc rc: %d\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) if (ops->set_acl == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) rc = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) if (!rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) /* Set the security descriptor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) rc = ops->set_acl(pnntsd, secdesclen, inode, path, aclflag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) cifs_dbg(NOISY, "set_cifs_acl rc: %d\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) cifs_put_tlink(tlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) kfree(pnntsd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) kfree(pntsd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) }