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