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