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