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