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                goto set_size;
 953        }
 954
 955        /*
 956         * We'll try to keep the mode as requested by the user.
 957         * But in cases where we cannot meaningfully convert that
 958         * into ACL, return back the updated mode, so that it is
 959         * updated in the inode.
 960         */
 961
 962        if (!memcmp(pownersid, pgrpsid, sizeof(struct cifs_sid))) {
 963                /*
 964                 * Case when owner and group SIDs are the same.
 965                 * Set the more restrictive of the two modes.
 966                 */
 967                user_mode = nmode & (nmode << 3) & 0700;
 968                group_mode = nmode & (nmode >> 3) & 0070;
 969        } else {
 970                user_mode = nmode & 0700;
 971                group_mode = nmode & 0070;
 972        }
 973
 974        other_mode = nmode & 0007;
 975
 976        /* We need DENY ACE when the perm is more restrictive than the next sets. */
 977        deny_user_mode = ~(user_mode) & ((group_mode << 3) | (other_mode << 6)) & 0700;
 978        deny_group_mode = ~(group_mode) & (other_mode << 3) & 0070;
 979
 980        *pnmode = user_mode | group_mode | other_mode | (nmode & ~0777);
 981
 982        /* This tells if we should allow delete child for group and everyone. */
 983        if (nmode & 01000)
 984                sticky_set = true;
 985
 986        if (deny_user_mode) {
 987                pnntace = (struct cifs_ace *) (nacl_base + nsize);
 988                nsize += fill_ace_for_sid(pnntace, pownersid, deny_user_mode,
 989                                0700, ACCESS_DENIED, false);
 990                num_aces++;
 991        }
 992
 993        /* Group DENY ACE does not conflict with owner ALLOW ACE. Keep in preferred order*/
 994        if (deny_group_mode && !(deny_group_mode & (user_mode >> 3))) {
 995                pnntace = (struct cifs_ace *) (nacl_base + nsize);
 996                nsize += fill_ace_for_sid(pnntace, pgrpsid, deny_group_mode,
 997                                0070, ACCESS_DENIED, false);
 998                num_aces++;
 999        }
1000
1001        pnntace = (struct cifs_ace *) (nacl_base + nsize);
1002        nsize += fill_ace_for_sid(pnntace, pownersid, user_mode,
1003                        0700, ACCESS_ALLOWED, true);
1004        num_aces++;
1005
1006        /* Group DENY ACE conflicts with owner ALLOW ACE. So keep it after. */
1007        if (deny_group_mode && (deny_group_mode & (user_mode >> 3))) {
1008                pnntace = (struct cifs_ace *) (nacl_base + nsize);
1009                nsize += fill_ace_for_sid(pnntace, pgrpsid, deny_group_mode,
1010                                0070, ACCESS_DENIED, false);
1011                num_aces++;
1012        }
1013
1014        pnntace = (struct cifs_ace *) (nacl_base + nsize);
1015        nsize += fill_ace_for_sid(pnntace, pgrpsid, group_mode,
1016                        0070, ACCESS_ALLOWED, !sticky_set);
1017        num_aces++;
1018
1019        pnntace = (struct cifs_ace *) (nacl_base + nsize);
1020        nsize += fill_ace_for_sid(pnntace, &sid_everyone, other_mode,
1021                        0007, ACCESS_ALLOWED, !sticky_set);
1022        num_aces++;
1023
1024set_size:
1025        *pnum_aces = num_aces;
1026        *pnsize = nsize;
1027}
1028
1029static __u16 replace_sids_and_copy_aces(struct cifs_acl *pdacl, struct cifs_acl *pndacl,
1030                struct cifs_sid *pownersid, struct cifs_sid *pgrpsid,
1031                struct cifs_sid *pnownersid, struct cifs_sid *pngrpsid)
1032{
1033        int i;
1034        u16 size = 0;
1035        struct cifs_ace *pntace = NULL;
1036        char *acl_base = NULL;
1037        u32 src_num_aces = 0;
1038        u16 nsize = 0;
1039        struct cifs_ace *pnntace = NULL;
1040        char *nacl_base = NULL;
1041        u16 ace_size = 0;
1042
1043        acl_base = (char *)pdacl;
1044        size = sizeof(struct cifs_acl);
1045        src_num_aces = le32_to_cpu(pdacl->num_aces);
1046
1047        nacl_base = (char *)pndacl;
1048        nsize = sizeof(struct cifs_acl);
1049
1050        /* Go through all the ACEs */
1051        for (i = 0; i < src_num_aces; ++i) {
1052                pntace = (struct cifs_ace *) (acl_base + size);
1053                pnntace = (struct cifs_ace *) (nacl_base + nsize);
1054
1055                if (pnownersid && compare_sids(&pntace->sid, pownersid) == 0)
1056                        ace_size = cifs_copy_ace(pnntace, pntace, pnownersid);
1057                else if (pngrpsid && compare_sids(&pntace->sid, pgrpsid) == 0)
1058                        ace_size = cifs_copy_ace(pnntace, pntace, pngrpsid);
1059                else
1060                        ace_size = cifs_copy_ace(pnntace, pntace, NULL);
1061
1062                size += le16_to_cpu(pntace->size);
1063                nsize += ace_size;
1064        }
1065
1066        return nsize;
1067}
1068
1069static int set_chmod_dacl(struct cifs_acl *pdacl, struct cifs_acl *pndacl,
1070                struct cifs_sid *pownersid,     struct cifs_sid *pgrpsid,
1071                __u64 *pnmode, bool mode_from_sid)
1072{
1073        int i;
1074        u16 size = 0;
1075        struct cifs_ace *pntace = NULL;
1076        char *acl_base = NULL;
1077        u32 src_num_aces = 0;
1078        u16 nsize = 0;
1079        struct cifs_ace *pnntace = NULL;
1080        char *nacl_base = NULL;
1081        u32 num_aces = 0;
1082        bool new_aces_set = false;
1083
1084        /* Assuming that pndacl and pnmode are never NULL */
1085        nacl_base = (char *)pndacl;
1086        nsize = sizeof(struct cifs_acl);
1087
1088        /* If pdacl is NULL, we don't have a src. Simply populate new ACL. */
1089        if (!pdacl) {
1090                populate_new_aces(nacl_base,
1091                                pownersid, pgrpsid,
1092                                pnmode, &num_aces, &nsize,
1093                                mode_from_sid);
1094                goto finalize_dacl;
1095        }
1096
1097        acl_base = (char *)pdacl;
1098        size = sizeof(struct cifs_acl);
1099        src_num_aces = le32_to_cpu(pdacl->num_aces);
1100
1101        /* Retain old ACEs which we can retain */
1102        for (i = 0; i < src_num_aces; ++i) {
1103                pntace = (struct cifs_ace *) (acl_base + size);
1104
1105                if (!new_aces_set && (pntace->flags & INHERITED_ACE)) {
1106                        /* Place the new ACEs in between existing explicit and inherited */
1107                        populate_new_aces(nacl_base,
1108                                        pownersid, pgrpsid,
1109                                        pnmode, &num_aces, &nsize,
1110                                        mode_from_sid);
1111
1112                        new_aces_set = true;
1113                }
1114
1115                /* If it's any one of the ACE we're replacing, skip! */
1116                if (((compare_sids(&pntace->sid, &sid_unix_NFS_mode) == 0) ||
1117                                (compare_sids(&pntace->sid, pownersid) == 0) ||
1118                                (compare_sids(&pntace->sid, pgrpsid) == 0) ||
1119                                (compare_sids(&pntace->sid, &sid_everyone) == 0) ||
1120                                (compare_sids(&pntace->sid, &sid_authusers) == 0))) {
1121                        goto next_ace;
1122                }
1123
1124                /* update the pointer to the next ACE to populate*/
1125                pnntace = (struct cifs_ace *) (nacl_base + nsize);
1126
1127                nsize += cifs_copy_ace(pnntace, pntace, NULL);
1128                num_aces++;
1129
1130next_ace:
1131                size += le16_to_cpu(pntace->size);
1132        }
1133
1134        /* If inherited ACEs are not present, place the new ones at the tail */
1135        if (!new_aces_set) {
1136                populate_new_aces(nacl_base,
1137                                pownersid, pgrpsid,
1138                                pnmode, &num_aces, &nsize,
1139                                mode_from_sid);
1140
1141                new_aces_set = true;
1142        }
1143
1144finalize_dacl:
1145        pndacl->num_aces = cpu_to_le32(num_aces);
1146        pndacl->size = cpu_to_le16(nsize);
1147
1148        return 0;
1149}
1150
1151static int parse_sid(struct cifs_sid *psid, char *end_of_acl)
1152{
1153        /* BB need to add parm so we can store the SID BB */
1154
1155        /* validate that we do not go past end of ACL - sid must be at least 8
1156           bytes long (assuming no sub-auths - e.g. the null SID */
1157        if (end_of_acl < (char *)psid + 8) {
1158                cifs_dbg(VFS, "ACL too small to parse SID %p\n", psid);
1159                return -EINVAL;
1160        }
1161
1162#ifdef CONFIG_CIFS_DEBUG2
1163        if (psid->num_subauth) {
1164                int i;
1165                cifs_dbg(FYI, "SID revision %d num_auth %d\n",
1166                         psid->revision, psid->num_subauth);
1167
1168                for (i = 0; i < psid->num_subauth; i++) {
1169                        cifs_dbg(FYI, "SID sub_auth[%d]: 0x%x\n",
1170                                 i, le32_to_cpu(psid->sub_auth[i]));
1171                }
1172
1173                /* BB add length check to make sure that we do not have huge
1174                        num auths and therefore go off the end */
1175                cifs_dbg(FYI, "RID 0x%x\n",
1176                         le32_to_cpu(psid->sub_auth[psid->num_subauth-1]));
1177        }
1178#endif
1179
1180        return 0;
1181}
1182
1183
1184/* Convert CIFS ACL to POSIX form */
1185static int parse_sec_desc(struct cifs_sb_info *cifs_sb,
1186                struct cifs_ntsd *pntsd, int acl_len, struct cifs_fattr *fattr,
1187                bool get_mode_from_special_sid)
1188{
1189        int rc = 0;
1190        struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
1191        struct cifs_acl *dacl_ptr; /* no need for SACL ptr */
1192        char *end_of_acl = ((char *)pntsd) + acl_len;
1193        __u32 dacloffset;
1194
1195        if (pntsd == NULL)
1196                return -EIO;
1197
1198        owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
1199                                le32_to_cpu(pntsd->osidoffset));
1200        group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
1201                                le32_to_cpu(pntsd->gsidoffset));
1202        dacloffset = le32_to_cpu(pntsd->dacloffset);
1203        dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
1204        cifs_dbg(NOISY, "revision %d type 0x%x ooffset 0x%x goffset 0x%x sacloffset 0x%x dacloffset 0x%x\n",
1205                 pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset),
1206                 le32_to_cpu(pntsd->gsidoffset),
1207                 le32_to_cpu(pntsd->sacloffset), dacloffset);
1208/*      cifs_dump_mem("owner_sid: ", owner_sid_ptr, 64); */
1209        rc = parse_sid(owner_sid_ptr, end_of_acl);
1210        if (rc) {
1211                cifs_dbg(FYI, "%s: Error %d parsing Owner SID\n", __func__, rc);
1212                return rc;
1213        }
1214        rc = sid_to_id(cifs_sb, owner_sid_ptr, fattr, SIDOWNER);
1215        if (rc) {
1216                cifs_dbg(FYI, "%s: Error %d mapping Owner SID to uid\n",
1217                         __func__, rc);
1218                return rc;
1219        }
1220
1221        rc = parse_sid(group_sid_ptr, end_of_acl);
1222        if (rc) {
1223                cifs_dbg(FYI, "%s: Error %d mapping Owner SID to gid\n",
1224                         __func__, rc);
1225                return rc;
1226        }
1227        rc = sid_to_id(cifs_sb, group_sid_ptr, fattr, SIDGROUP);
1228        if (rc) {
1229                cifs_dbg(FYI, "%s: Error %d mapping Group SID to gid\n",
1230                         __func__, rc);
1231                return rc;
1232        }
1233
1234        if (dacloffset)
1235                parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr,
1236                           group_sid_ptr, fattr, get_mode_from_special_sid);
1237        else
1238                cifs_dbg(FYI, "no ACL\n"); /* BB grant all or default perms? */
1239
1240        return rc;
1241}
1242
1243/* Convert permission bits from mode to equivalent CIFS ACL */
1244static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
1245        __u32 secdesclen, __u32 *pnsecdesclen, __u64 *pnmode, kuid_t uid, kgid_t gid,
1246        bool mode_from_sid, bool id_from_sid, int *aclflag)
1247{
1248        int rc = 0;
1249        __u32 dacloffset;
1250        __u32 ndacloffset;
1251        __u32 sidsoffset;
1252        struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
1253        struct cifs_sid *nowner_sid_ptr = NULL, *ngroup_sid_ptr = NULL;
1254        struct cifs_acl *dacl_ptr = NULL;  /* no need for SACL ptr */
1255        struct cifs_acl *ndacl_ptr = NULL; /* no need for SACL ptr */
1256        char *end_of_acl = ((char *)pntsd) + secdesclen;
1257        u16 size = 0;
1258
1259        dacloffset = le32_to_cpu(pntsd->dacloffset);
1260        if (dacloffset) {
1261                dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
1262                if (end_of_acl < (char *)dacl_ptr + le16_to_cpu(dacl_ptr->size)) {
1263                        cifs_dbg(VFS, "Server returned illegal ACL size\n");
1264                        return -EINVAL;
1265                }
1266        }
1267
1268        owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
1269                        le32_to_cpu(pntsd->osidoffset));
1270        group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
1271                        le32_to_cpu(pntsd->gsidoffset));
1272
1273        if (pnmode && *pnmode != NO_CHANGE_64) { /* chmod */
1274                ndacloffset = sizeof(struct cifs_ntsd);
1275                ndacl_ptr = (struct cifs_acl *)((char *)pnntsd + ndacloffset);
1276                ndacl_ptr->revision =
1277                        dacloffset ? dacl_ptr->revision : cpu_to_le16(ACL_REVISION);
1278
1279                ndacl_ptr->size = cpu_to_le16(0);
1280                ndacl_ptr->num_aces = cpu_to_le32(0);
1281
1282                rc = set_chmod_dacl(dacl_ptr, ndacl_ptr, owner_sid_ptr, group_sid_ptr,
1283                                    pnmode, mode_from_sid);
1284
1285                sidsoffset = ndacloffset + le16_to_cpu(ndacl_ptr->size);
1286                /* copy the non-dacl portion of secdesc */
1287                *pnsecdesclen = copy_sec_desc(pntsd, pnntsd, sidsoffset,
1288                                NULL, NULL);
1289
1290                *aclflag |= CIFS_ACL_DACL;
1291        } else {
1292                ndacloffset = sizeof(struct cifs_ntsd);
1293                ndacl_ptr = (struct cifs_acl *)((char *)pnntsd + ndacloffset);
1294                ndacl_ptr->revision =
1295                        dacloffset ? dacl_ptr->revision : cpu_to_le16(ACL_REVISION);
1296                ndacl_ptr->num_aces = dacl_ptr ? dacl_ptr->num_aces : 0;
1297
1298                if (uid_valid(uid)) { /* chown */
1299                        uid_t id;
1300                        nowner_sid_ptr = kmalloc(sizeof(struct cifs_sid),
1301                                                                GFP_KERNEL);
1302                        if (!nowner_sid_ptr) {
1303                                rc = -ENOMEM;
1304                                goto chown_chgrp_exit;
1305                        }
1306                        id = from_kuid(&init_user_ns, uid);
1307                        if (id_from_sid) {
1308                                struct owner_sid *osid = (struct owner_sid *)nowner_sid_ptr;
1309                                /* Populate the user ownership fields S-1-5-88-1 */
1310                                osid->Revision = 1;
1311                                osid->NumAuth = 3;
1312                                osid->Authority[5] = 5;
1313                                osid->SubAuthorities[0] = cpu_to_le32(88);
1314                                osid->SubAuthorities[1] = cpu_to_le32(1);
1315                                osid->SubAuthorities[2] = cpu_to_le32(id);
1316
1317                        } else { /* lookup sid with upcall */
1318                                rc = id_to_sid(id, SIDOWNER, nowner_sid_ptr);
1319                                if (rc) {
1320                                        cifs_dbg(FYI, "%s: Mapping error %d for owner id %d\n",
1321                                                 __func__, rc, id);
1322                                        goto chown_chgrp_exit;
1323                                }
1324                        }
1325                        *aclflag |= CIFS_ACL_OWNER;
1326                }
1327                if (gid_valid(gid)) { /* chgrp */
1328                        gid_t id;
1329                        ngroup_sid_ptr = kmalloc(sizeof(struct cifs_sid),
1330                                                                GFP_KERNEL);
1331                        if (!ngroup_sid_ptr) {
1332                                rc = -ENOMEM;
1333                                goto chown_chgrp_exit;
1334                        }
1335                        id = from_kgid(&init_user_ns, gid);
1336                        if (id_from_sid) {
1337                                struct owner_sid *gsid = (struct owner_sid *)ngroup_sid_ptr;
1338                                /* Populate the group ownership fields S-1-5-88-2 */
1339                                gsid->Revision = 1;
1340                                gsid->NumAuth = 3;
1341                                gsid->Authority[5] = 5;
1342                                gsid->SubAuthorities[0] = cpu_to_le32(88);
1343                                gsid->SubAuthorities[1] = cpu_to_le32(2);
1344                                gsid->SubAuthorities[2] = cpu_to_le32(id);
1345
1346                        } else { /* lookup sid with upcall */
1347                                rc = id_to_sid(id, SIDGROUP, ngroup_sid_ptr);
1348                                if (rc) {
1349                                        cifs_dbg(FYI, "%s: Mapping error %d for group id %d\n",
1350                                                 __func__, rc, id);
1351                                        goto chown_chgrp_exit;
1352                                }
1353                        }
1354                        *aclflag |= CIFS_ACL_GROUP;
1355                }
1356
1357                if (dacloffset) {
1358                        /* Replace ACEs for old owner with new one */
1359                        size = replace_sids_and_copy_aces(dacl_ptr, ndacl_ptr,
1360                                        owner_sid_ptr, group_sid_ptr,
1361                                        nowner_sid_ptr, ngroup_sid_ptr);
1362                        ndacl_ptr->size = cpu_to_le16(size);
1363                }
1364
1365                sidsoffset = ndacloffset + le16_to_cpu(ndacl_ptr->size);
1366                /* copy the non-dacl portion of secdesc */
1367                *pnsecdesclen = copy_sec_desc(pntsd, pnntsd, sidsoffset,
1368                                nowner_sid_ptr, ngroup_sid_ptr);
1369
1370chown_chgrp_exit:
1371                /* errors could jump here. So make sure we return soon after this */
1372                kfree(nowner_sid_ptr);
1373                kfree(ngroup_sid_ptr);
1374        }
1375
1376        return rc;
1377}
1378
1379struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
1380                                      const struct cifs_fid *cifsfid, u32 *pacllen,
1381                                      u32 __maybe_unused unused)
1382{
1383        struct cifs_ntsd *pntsd = NULL;
1384        unsigned int xid;
1385        int rc;
1386        struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1387
1388        if (IS_ERR(tlink))
1389                return ERR_CAST(tlink);
1390
1391        xid = get_xid();
1392        rc = CIFSSMBGetCIFSACL(xid, tlink_tcon(tlink), cifsfid->netfid, &pntsd,
1393                                pacllen);
1394        free_xid(xid);
1395
1396        cifs_put_tlink(tlink);
1397
1398        cifs_dbg(FYI, "%s: rc = %d ACL len %d\n", __func__, rc, *pacllen);
1399        if (rc)
1400                return ERR_PTR(rc);
1401        return pntsd;
1402}
1403
1404static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
1405                const char *path, u32 *pacllen)
1406{
1407        struct cifs_ntsd *pntsd = NULL;
1408        int oplock = 0;
1409        unsigned int xid;
1410        int rc;
1411        struct cifs_tcon *tcon;
1412        struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1413        struct cifs_fid fid;
1414        struct cifs_open_parms oparms;
1415
1416        if (IS_ERR(tlink))
1417                return ERR_CAST(tlink);
1418
1419        tcon = tlink_tcon(tlink);
1420        xid = get_xid();
1421
1422        oparms.tcon = tcon;
1423        oparms.cifs_sb = cifs_sb;
1424        oparms.desired_access = READ_CONTROL;
1425        oparms.create_options = cifs_create_options(cifs_sb, 0);
1426        oparms.disposition = FILE_OPEN;
1427        oparms.path = path;
1428        oparms.fid = &fid;
1429        oparms.reconnect = false;
1430
1431        rc = CIFS_open(xid, &oparms, &oplock, NULL);
1432        if (!rc) {
1433                rc = CIFSSMBGetCIFSACL(xid, tcon, fid.netfid, &pntsd, pacllen);
1434                CIFSSMBClose(xid, tcon, fid.netfid);
1435        }
1436
1437        cifs_put_tlink(tlink);
1438        free_xid(xid);
1439
1440        cifs_dbg(FYI, "%s: rc = %d ACL len %d\n", __func__, rc, *pacllen);
1441        if (rc)
1442                return ERR_PTR(rc);
1443        return pntsd;
1444}
1445
1446/* Retrieve an ACL from the server */
1447struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb,
1448                                      struct inode *inode, const char *path,
1449                               u32 *pacllen, u32 info)
1450{
1451        struct cifs_ntsd *pntsd = NULL;
1452        struct cifsFileInfo *open_file = NULL;
1453
1454        if (inode)
1455                open_file = find_readable_file(CIFS_I(inode), true);
1456        if (!open_file)
1457                return get_cifs_acl_by_path(cifs_sb, path, pacllen);
1458
1459        pntsd = get_cifs_acl_by_fid(cifs_sb, &open_file->fid, pacllen, info);
1460        cifsFileInfo_put(open_file);
1461        return pntsd;
1462}
1463
1464 /* Set an ACL on the server */
1465int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
1466                        struct inode *inode, const char *path, int aclflag)
1467{
1468        int oplock = 0;
1469        unsigned int xid;
1470        int rc, access_flags;
1471        struct cifs_tcon *tcon;
1472        struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1473        struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1474        struct cifs_fid fid;
1475        struct cifs_open_parms oparms;
1476
1477        if (IS_ERR(tlink))
1478                return PTR_ERR(tlink);
1479
1480        tcon = tlink_tcon(tlink);
1481        xid = get_xid();
1482
1483        if (aclflag == CIFS_ACL_OWNER || aclflag == CIFS_ACL_GROUP)
1484                access_flags = WRITE_OWNER;
1485        else
1486                access_flags = WRITE_DAC;
1487
1488        oparms.tcon = tcon;
1489        oparms.cifs_sb = cifs_sb;
1490        oparms.desired_access = access_flags;
1491        oparms.create_options = cifs_create_options(cifs_sb, 0);
1492        oparms.disposition = FILE_OPEN;
1493        oparms.path = path;
1494        oparms.fid = &fid;
1495        oparms.reconnect = false;
1496
1497        rc = CIFS_open(xid, &oparms, &oplock, NULL);
1498        if (rc) {
1499                cifs_dbg(VFS, "Unable to open file to set ACL\n");
1500                goto out;
1501        }
1502
1503        rc = CIFSSMBSetCIFSACL(xid, tcon, fid.netfid, pnntsd, acllen, aclflag);
1504        cifs_dbg(NOISY, "SetCIFSACL rc = %d\n", rc);
1505
1506        CIFSSMBClose(xid, tcon, fid.netfid);
1507out:
1508        free_xid(xid);
1509        cifs_put_tlink(tlink);
1510        return rc;
1511}
1512
1513/* Translate the CIFS ACL (similar to NTFS ACL) for a file into mode bits */
1514int
1515cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
1516                  struct inode *inode, bool mode_from_special_sid,
1517                  const char *path, const struct cifs_fid *pfid)
1518{
1519        struct cifs_ntsd *pntsd = NULL;
1520        u32 acllen = 0;
1521        int rc = 0;
1522        struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1523        struct smb_version_operations *ops;
1524        const u32 info = 0;
1525
1526        cifs_dbg(NOISY, "converting ACL to mode for %s\n", path);
1527
1528        if (IS_ERR(tlink))
1529                return PTR_ERR(tlink);
1530
1531        ops = tlink_tcon(tlink)->ses->server->ops;
1532
1533        if (pfid && (ops->get_acl_by_fid))
1534                pntsd = ops->get_acl_by_fid(cifs_sb, pfid, &acllen, info);
1535        else if (ops->get_acl)
1536                pntsd = ops->get_acl(cifs_sb, inode, path, &acllen, info);
1537        else {
1538                cifs_put_tlink(tlink);
1539                return -EOPNOTSUPP;
1540        }
1541        /* if we can retrieve the ACL, now parse Access Control Entries, ACEs */
1542        if (IS_ERR(pntsd)) {
1543                rc = PTR_ERR(pntsd);
1544                cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc);
1545        } else if (mode_from_special_sid) {
1546                rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr, true);
1547                kfree(pntsd);
1548        } else {
1549                /* get approximated mode from ACL */
1550                rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr, false);
1551                kfree(pntsd);
1552                if (rc)
1553                        cifs_dbg(VFS, "parse sec desc failed rc = %d\n", rc);
1554        }
1555
1556        cifs_put_tlink(tlink);
1557
1558        return rc;
1559}
1560
1561/* Convert mode bits to an ACL so we can update the ACL on the server */
1562int
1563id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode,
1564                        kuid_t uid, kgid_t gid)
1565{
1566        int rc = 0;
1567        int aclflag = CIFS_ACL_DACL; /* default flag to set */
1568        __u32 secdesclen = 0;
1569        __u32 nsecdesclen = 0;
1570        __u32 dacloffset = 0;
1571        struct cifs_acl *dacl_ptr = NULL;
1572        struct cifs_ntsd *pntsd = NULL; /* acl obtained from server */
1573        struct cifs_ntsd *pnntsd = NULL; /* modified acl to be sent to server */
1574        struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1575        struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1576        struct smb_version_operations *ops;
1577        bool mode_from_sid, id_from_sid;
1578        const u32 info = 0;
1579
1580        if (IS_ERR(tlink))
1581                return PTR_ERR(tlink);
1582
1583        ops = tlink_tcon(tlink)->ses->server->ops;
1584
1585        cifs_dbg(NOISY, "set ACL from mode for %s\n", path);
1586
1587        /* Get the security descriptor */
1588
1589        if (ops->get_acl == NULL) {
1590                cifs_put_tlink(tlink);
1591                return -EOPNOTSUPP;
1592        }
1593
1594        pntsd = ops->get_acl(cifs_sb, inode, path, &secdesclen, info);
1595        if (IS_ERR(pntsd)) {
1596                rc = PTR_ERR(pntsd);
1597                cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc);
1598                cifs_put_tlink(tlink);
1599                return rc;
1600        }
1601
1602        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID)
1603                mode_from_sid = true;
1604        else
1605                mode_from_sid = false;
1606
1607        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UID_FROM_ACL)
1608                id_from_sid = true;
1609        else
1610                id_from_sid = false;
1611
1612        /* Potentially, five new ACEs can be added to the ACL for U,G,O mapping */
1613        nsecdesclen = secdesclen;
1614        if (pnmode && *pnmode != NO_CHANGE_64) { /* chmod */
1615                if (mode_from_sid)
1616                        nsecdesclen += sizeof(struct cifs_ace);
1617                else /* cifsacl */
1618                        nsecdesclen += 5 * sizeof(struct cifs_ace);
1619        } else { /* chown */
1620                /* When ownership changes, changes new owner sid length could be different */
1621                nsecdesclen = sizeof(struct cifs_ntsd) + (sizeof(struct cifs_sid) * 2);
1622                dacloffset = le32_to_cpu(pntsd->dacloffset);
1623                if (dacloffset) {
1624                        dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
1625                        if (mode_from_sid)
1626                                nsecdesclen +=
1627                                        le32_to_cpu(dacl_ptr->num_aces) * sizeof(struct cifs_ace);
1628                        else /* cifsacl */
1629                                nsecdesclen += le16_to_cpu(dacl_ptr->size);
1630                }
1631        }
1632
1633        /*
1634         * Add three ACEs for owner, group, everyone getting rid of other ACEs
1635         * as chmod disables ACEs and set the security descriptor. Allocate
1636         * memory for the smb header, set security descriptor request security
1637         * descriptor parameters, and security descriptor itself
1638         */
1639        nsecdesclen = max_t(u32, nsecdesclen, DEFAULT_SEC_DESC_LEN);
1640        pnntsd = kmalloc(nsecdesclen, GFP_KERNEL);
1641        if (!pnntsd) {
1642                kfree(pntsd);
1643                cifs_put_tlink(tlink);
1644                return -ENOMEM;
1645        }
1646
1647        rc = build_sec_desc(pntsd, pnntsd, secdesclen, &nsecdesclen, pnmode, uid, gid,
1648                            mode_from_sid, id_from_sid, &aclflag);
1649
1650        cifs_dbg(NOISY, "build_sec_desc rc: %d\n", rc);
1651
1652        if (ops->set_acl == NULL)
1653                rc = -EOPNOTSUPP;
1654
1655        if (!rc) {
1656                /* Set the security descriptor */
1657                rc = ops->set_acl(pnntsd, nsecdesclen, inode, path, aclflag);
1658                cifs_dbg(NOISY, "set_cifs_acl rc: %d\n", rc);
1659        }
1660        cifs_put_tlink(tlink);
1661
1662        kfree(pnntsd);
1663        kfree(pntsd);
1664        return rc;
1665}
1666