linux/fs/ksmbd/smbacl.c
<<
>>
Prefs
   1// SPDX-License-Identifier: LGPL-2.1+
   2/*
   3 *   Copyright (C) International Business Machines  Corp., 2007,2008
   4 *   Author(s): Steve French (sfrench@us.ibm.com)
   5 *   Copyright (C) 2020 Samsung Electronics Co., Ltd.
   6 *   Author(s): Namjae Jeon <linkinjeon@kernel.org>
   7 */
   8
   9#include <linux/fs.h>
  10#include <linux/slab.h>
  11#include <linux/string.h>
  12
  13#include "smbacl.h"
  14#include "smb_common.h"
  15#include "server.h"
  16#include "misc.h"
  17#include "mgmt/share_config.h"
  18
  19static const struct smb_sid domain = {1, 4, {0, 0, 0, 0, 0, 5},
  20        {cpu_to_le32(21), cpu_to_le32(1), cpu_to_le32(2), cpu_to_le32(3),
  21        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
  22
  23/* security id for everyone/world system group */
  24static const struct smb_sid creator_owner = {
  25        1, 1, {0, 0, 0, 0, 0, 3}, {0} };
  26/* security id for everyone/world system group */
  27static const struct smb_sid creator_group = {
  28        1, 1, {0, 0, 0, 0, 0, 3}, {cpu_to_le32(1)} };
  29
  30/* security id for everyone/world system group */
  31static const struct smb_sid sid_everyone = {
  32        1, 1, {0, 0, 0, 0, 0, 1}, {0} };
  33/* security id for Authenticated Users system group */
  34static const struct smb_sid sid_authusers = {
  35        1, 1, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(11)} };
  36
  37/* S-1-22-1 Unmapped Unix users */
  38static const struct smb_sid sid_unix_users = {1, 1, {0, 0, 0, 0, 0, 22},
  39                {cpu_to_le32(1), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
  40
  41/* S-1-22-2 Unmapped Unix groups */
  42static const struct smb_sid sid_unix_groups = { 1, 1, {0, 0, 0, 0, 0, 22},
  43                {cpu_to_le32(2), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
  44
  45/*
  46 * See http://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx
  47 */
  48
  49/* S-1-5-88 MS NFS and Apple style UID/GID/mode */
  50
  51/* S-1-5-88-1 Unix uid */
  52static const struct smb_sid sid_unix_NFS_users = { 1, 2, {0, 0, 0, 0, 0, 5},
  53        {cpu_to_le32(88),
  54         cpu_to_le32(1), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
  55
  56/* S-1-5-88-2 Unix gid */
  57static const struct smb_sid sid_unix_NFS_groups = { 1, 2, {0, 0, 0, 0, 0, 5},
  58        {cpu_to_le32(88),
  59         cpu_to_le32(2), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
  60
  61/* S-1-5-88-3 Unix mode */
  62static const struct smb_sid sid_unix_NFS_mode = { 1, 2, {0, 0, 0, 0, 0, 5},
  63        {cpu_to_le32(88),
  64         cpu_to_le32(3), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
  65
  66/*
  67 * if the two SIDs (roughly equivalent to a UUID for a user or group) are
  68 * the same returns zero, if they do not match returns non-zero.
  69 */
  70int compare_sids(const struct smb_sid *ctsid, const struct smb_sid *cwsid)
  71{
  72        int i;
  73        int num_subauth, num_sat, num_saw;
  74
  75        if (!ctsid || !cwsid)
  76                return 1;
  77
  78        /* compare the revision */
  79        if (ctsid->revision != cwsid->revision) {
  80                if (ctsid->revision > cwsid->revision)
  81                        return 1;
  82                else
  83                        return -1;
  84        }
  85
  86        /* compare all of the six auth values */
  87        for (i = 0; i < NUM_AUTHS; ++i) {
  88                if (ctsid->authority[i] != cwsid->authority[i]) {
  89                        if (ctsid->authority[i] > cwsid->authority[i])
  90                                return 1;
  91                        else
  92                                return -1;
  93                }
  94        }
  95
  96        /* compare all of the subauth values if any */
  97        num_sat = ctsid->num_subauth;
  98        num_saw = cwsid->num_subauth;
  99        num_subauth = num_sat < num_saw ? num_sat : num_saw;
 100        if (num_subauth) {
 101                for (i = 0; i < num_subauth; ++i) {
 102                        if (ctsid->sub_auth[i] != cwsid->sub_auth[i]) {
 103                                if (le32_to_cpu(ctsid->sub_auth[i]) >
 104                                    le32_to_cpu(cwsid->sub_auth[i]))
 105                                        return 1;
 106                                else
 107                                        return -1;
 108                        }
 109                }
 110        }
 111
 112        return 0; /* sids compare/match */
 113}
 114
 115static void smb_copy_sid(struct smb_sid *dst, const struct smb_sid *src)
 116{
 117        int i;
 118
 119        dst->revision = src->revision;
 120        dst->num_subauth = min_t(u8, src->num_subauth, SID_MAX_SUB_AUTHORITIES);
 121        for (i = 0; i < NUM_AUTHS; ++i)
 122                dst->authority[i] = src->authority[i];
 123        for (i = 0; i < dst->num_subauth; ++i)
 124                dst->sub_auth[i] = src->sub_auth[i];
 125}
 126
 127/*
 128 * change posix mode to reflect permissions
 129 * pmode is the existing mode (we only want to overwrite part of this
 130 * bits to set can be: S_IRWXU, S_IRWXG or S_IRWXO ie 00700 or 00070 or 00007
 131 */
 132static umode_t access_flags_to_mode(struct smb_fattr *fattr, __le32 ace_flags,
 133                                    int type)
 134{
 135        __u32 flags = le32_to_cpu(ace_flags);
 136        umode_t mode = 0;
 137
 138        if (flags & GENERIC_ALL) {
 139                mode = 0777;
 140                ksmbd_debug(SMB, "all perms\n");
 141                return mode;
 142        }
 143
 144        if ((flags & GENERIC_READ) || (flags & FILE_READ_RIGHTS))
 145                mode = 0444;
 146        if ((flags & GENERIC_WRITE) || (flags & FILE_WRITE_RIGHTS)) {
 147                mode |= 0222;
 148                if (S_ISDIR(fattr->cf_mode))
 149                        mode |= 0111;
 150        }
 151        if ((flags & GENERIC_EXECUTE) || (flags & FILE_EXEC_RIGHTS))
 152                mode |= 0111;
 153
 154        if (type == ACCESS_DENIED_ACE_TYPE || type == ACCESS_DENIED_OBJECT_ACE_TYPE)
 155                mode = ~mode;
 156
 157        ksmbd_debug(SMB, "access flags 0x%x mode now %04o\n", flags, mode);
 158
 159        return mode;
 160}
 161
 162/*
 163 * Generate access flags to reflect permissions mode is the existing mode.
 164 * This function is called for every ACE in the DACL whose SID matches
 165 * with either owner or group or everyone.
 166 */
 167static void mode_to_access_flags(umode_t mode, umode_t bits_to_use,
 168                                 __u32 *pace_flags)
 169{
 170        /* reset access mask */
 171        *pace_flags = 0x0;
 172
 173        /* bits to use are either S_IRWXU or S_IRWXG or S_IRWXO */
 174        mode &= bits_to_use;
 175
 176        /*
 177         * check for R/W/X UGO since we do not know whose flags
 178         * is this but we have cleared all the bits sans RWX for
 179         * either user or group or other as per bits_to_use
 180         */
 181        if (mode & 0444)
 182                *pace_flags |= SET_FILE_READ_RIGHTS;
 183        if (mode & 0222)
 184                *pace_flags |= FILE_WRITE_RIGHTS;
 185        if (mode & 0111)
 186                *pace_flags |= SET_FILE_EXEC_RIGHTS;
 187
 188        ksmbd_debug(SMB, "mode: %o, access flags now 0x%x\n",
 189                    mode, *pace_flags);
 190}
 191
 192static __u16 fill_ace_for_sid(struct smb_ace *pntace,
 193                              const struct smb_sid *psid, int type, int flags,
 194                              umode_t mode, umode_t bits)
 195{
 196        int i;
 197        __u16 size = 0;
 198        __u32 access_req = 0;
 199
 200        pntace->type = type;
 201        pntace->flags = flags;
 202        mode_to_access_flags(mode, bits, &access_req);
 203        if (!access_req)
 204                access_req = SET_MINIMUM_RIGHTS;
 205        pntace->access_req = cpu_to_le32(access_req);
 206
 207        pntace->sid.revision = psid->revision;
 208        pntace->sid.num_subauth = psid->num_subauth;
 209        for (i = 0; i < NUM_AUTHS; i++)
 210                pntace->sid.authority[i] = psid->authority[i];
 211        for (i = 0; i < psid->num_subauth; i++)
 212                pntace->sid.sub_auth[i] = psid->sub_auth[i];
 213
 214        size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth * 4);
 215        pntace->size = cpu_to_le16(size);
 216
 217        return size;
 218}
 219
 220void id_to_sid(unsigned int cid, uint sidtype, struct smb_sid *ssid)
 221{
 222        switch (sidtype) {
 223        case SIDOWNER:
 224                smb_copy_sid(ssid, &server_conf.domain_sid);
 225                break;
 226        case SIDUNIX_USER:
 227                smb_copy_sid(ssid, &sid_unix_users);
 228                break;
 229        case SIDUNIX_GROUP:
 230                smb_copy_sid(ssid, &sid_unix_groups);
 231                break;
 232        case SIDCREATOR_OWNER:
 233                smb_copy_sid(ssid, &creator_owner);
 234                return;
 235        case SIDCREATOR_GROUP:
 236                smb_copy_sid(ssid, &creator_group);
 237                return;
 238        case SIDNFS_USER:
 239                smb_copy_sid(ssid, &sid_unix_NFS_users);
 240                break;
 241        case SIDNFS_GROUP:
 242                smb_copy_sid(ssid, &sid_unix_NFS_groups);
 243                break;
 244        case SIDNFS_MODE:
 245                smb_copy_sid(ssid, &sid_unix_NFS_mode);
 246                break;
 247        default:
 248                return;
 249        }
 250
 251        /* RID */
 252        ssid->sub_auth[ssid->num_subauth] = cpu_to_le32(cid);
 253        ssid->num_subauth++;
 254}
 255
 256static int sid_to_id(struct user_namespace *user_ns,
 257                     struct smb_sid *psid, uint sidtype,
 258                     struct smb_fattr *fattr)
 259{
 260        int rc = -EINVAL;
 261
 262        /*
 263         * If we have too many subauthorities, then something is really wrong.
 264         * Just return an error.
 265         */
 266        if (unlikely(psid->num_subauth > SID_MAX_SUB_AUTHORITIES)) {
 267                pr_err("%s: %u subauthorities is too many!\n",
 268                       __func__, psid->num_subauth);
 269                return -EIO;
 270        }
 271
 272        if (sidtype == SIDOWNER) {
 273                kuid_t uid;
 274                uid_t id;
 275
 276                id = le32_to_cpu(psid->sub_auth[psid->num_subauth - 1]);
 277                /*
 278                 * Translate raw sid into kuid in the server's user
 279                 * namespace.
 280                 */
 281                uid = make_kuid(&init_user_ns, id);
 282
 283                /* If this is an idmapped mount, apply the idmapping. */
 284                uid = kuid_from_mnt(user_ns, uid);
 285                if (uid_valid(uid)) {
 286                        fattr->cf_uid = uid;
 287                        rc = 0;
 288                }
 289        } else {
 290                kgid_t gid;
 291                gid_t id;
 292
 293                id = le32_to_cpu(psid->sub_auth[psid->num_subauth - 1]);
 294                /*
 295                 * Translate raw sid into kgid in the server's user
 296                 * namespace.
 297                 */
 298                gid = make_kgid(&init_user_ns, id);
 299
 300                /* If this is an idmapped mount, apply the idmapping. */
 301                gid = kgid_from_mnt(user_ns, gid);
 302                if (gid_valid(gid)) {
 303                        fattr->cf_gid = gid;
 304                        rc = 0;
 305                }
 306        }
 307
 308        return rc;
 309}
 310
 311void posix_state_to_acl(struct posix_acl_state *state,
 312                        struct posix_acl_entry *pace)
 313{
 314        int i;
 315
 316        pace->e_tag = ACL_USER_OBJ;
 317        pace->e_perm = state->owner.allow;
 318        for (i = 0; i < state->users->n; i++) {
 319                pace++;
 320                pace->e_tag = ACL_USER;
 321                pace->e_uid = state->users->aces[i].uid;
 322                pace->e_perm = state->users->aces[i].perms.allow;
 323        }
 324
 325        pace++;
 326        pace->e_tag = ACL_GROUP_OBJ;
 327        pace->e_perm = state->group.allow;
 328
 329        for (i = 0; i < state->groups->n; i++) {
 330                pace++;
 331                pace->e_tag = ACL_GROUP;
 332                pace->e_gid = state->groups->aces[i].gid;
 333                pace->e_perm = state->groups->aces[i].perms.allow;
 334        }
 335
 336        if (state->users->n || state->groups->n) {
 337                pace++;
 338                pace->e_tag = ACL_MASK;
 339                pace->e_perm = state->mask.allow;
 340        }
 341
 342        pace++;
 343        pace->e_tag = ACL_OTHER;
 344        pace->e_perm = state->other.allow;
 345}
 346
 347int init_acl_state(struct posix_acl_state *state, int cnt)
 348{
 349        int alloc;
 350
 351        memset(state, 0, sizeof(struct posix_acl_state));
 352        /*
 353         * In the worst case, each individual acl could be for a distinct
 354         * named user or group, but we don't know which, so we allocate
 355         * enough space for either:
 356         */
 357        alloc = sizeof(struct posix_ace_state_array)
 358                + cnt * sizeof(struct posix_user_ace_state);
 359        state->users = kzalloc(alloc, GFP_KERNEL);
 360        if (!state->users)
 361                return -ENOMEM;
 362        state->groups = kzalloc(alloc, GFP_KERNEL);
 363        if (!state->groups) {
 364                kfree(state->users);
 365                return -ENOMEM;
 366        }
 367        return 0;
 368}
 369
 370void free_acl_state(struct posix_acl_state *state)
 371{
 372        kfree(state->users);
 373        kfree(state->groups);
 374}
 375
 376static void parse_dacl(struct user_namespace *user_ns,
 377                       struct smb_acl *pdacl, char *end_of_acl,
 378                       struct smb_sid *pownersid, struct smb_sid *pgrpsid,
 379                       struct smb_fattr *fattr)
 380{
 381        int i, ret;
 382        int num_aces = 0;
 383        unsigned int acl_size;
 384        char *acl_base;
 385        struct smb_ace **ppace;
 386        struct posix_acl_entry *cf_pace, *cf_pdace;
 387        struct posix_acl_state acl_state, default_acl_state;
 388        umode_t mode = 0, acl_mode;
 389        bool owner_found = false, group_found = false, others_found = false;
 390
 391        if (!pdacl)
 392                return;
 393
 394        /* validate that we do not go past end of acl */
 395        if (end_of_acl < (char *)pdacl + sizeof(struct smb_acl) ||
 396            end_of_acl < (char *)pdacl + le16_to_cpu(pdacl->size)) {
 397                pr_err("ACL too small to parse DACL\n");
 398                return;
 399        }
 400
 401        ksmbd_debug(SMB, "DACL revision %d size %d num aces %d\n",
 402                    le16_to_cpu(pdacl->revision), le16_to_cpu(pdacl->size),
 403                    le32_to_cpu(pdacl->num_aces));
 404
 405        acl_base = (char *)pdacl;
 406        acl_size = sizeof(struct smb_acl);
 407
 408        num_aces = le32_to_cpu(pdacl->num_aces);
 409        if (num_aces <= 0)
 410                return;
 411
 412        if (num_aces > ULONG_MAX / sizeof(struct smb_ace *))
 413                return;
 414
 415        ppace = kmalloc_array(num_aces, sizeof(struct smb_ace *), GFP_KERNEL);
 416        if (!ppace)
 417                return;
 418
 419        ret = init_acl_state(&acl_state, num_aces);
 420        if (ret)
 421                return;
 422        ret = init_acl_state(&default_acl_state, num_aces);
 423        if (ret) {
 424                free_acl_state(&acl_state);
 425                return;
 426        }
 427
 428        /*
 429         * reset rwx permissions for user/group/other.
 430         * Also, if num_aces is 0 i.e. DACL has no ACEs,
 431         * user/group/other have no permissions
 432         */
 433        for (i = 0; i < num_aces; ++i) {
 434                if (end_of_acl - acl_base < acl_size)
 435                        break;
 436
 437                ppace[i] = (struct smb_ace *)(acl_base + acl_size);
 438                acl_base = (char *)ppace[i];
 439                acl_size = offsetof(struct smb_ace, sid) +
 440                        offsetof(struct smb_sid, sub_auth);
 441
 442                if (end_of_acl - acl_base < acl_size ||
 443                    ppace[i]->sid.num_subauth > SID_MAX_SUB_AUTHORITIES ||
 444                    (end_of_acl - acl_base <
 445                     acl_size + sizeof(__le32) * ppace[i]->sid.num_subauth) ||
 446                    (le16_to_cpu(ppace[i]->size) <
 447                     acl_size + sizeof(__le32) * ppace[i]->sid.num_subauth))
 448                        break;
 449
 450                acl_size = le16_to_cpu(ppace[i]->size);
 451                ppace[i]->access_req =
 452                        smb_map_generic_desired_access(ppace[i]->access_req);
 453
 454                if (!(compare_sids(&ppace[i]->sid, &sid_unix_NFS_mode))) {
 455                        fattr->cf_mode =
 456                                le32_to_cpu(ppace[i]->sid.sub_auth[2]);
 457                        break;
 458                } else if (!compare_sids(&ppace[i]->sid, pownersid)) {
 459                        acl_mode = access_flags_to_mode(fattr,
 460                                                        ppace[i]->access_req,
 461                                                        ppace[i]->type);
 462                        acl_mode &= 0700;
 463
 464                        if (!owner_found) {
 465                                mode &= ~(0700);
 466                                mode |= acl_mode;
 467                        }
 468                        owner_found = true;
 469                } else if (!compare_sids(&ppace[i]->sid, pgrpsid) ||
 470                           ppace[i]->sid.sub_auth[ppace[i]->sid.num_subauth - 1] ==
 471                            DOMAIN_USER_RID_LE) {
 472                        acl_mode = access_flags_to_mode(fattr,
 473                                                        ppace[i]->access_req,
 474                                                        ppace[i]->type);
 475                        acl_mode &= 0070;
 476                        if (!group_found) {
 477                                mode &= ~(0070);
 478                                mode |= acl_mode;
 479                        }
 480                        group_found = true;
 481                } else if (!compare_sids(&ppace[i]->sid, &sid_everyone)) {
 482                        acl_mode = access_flags_to_mode(fattr,
 483                                                        ppace[i]->access_req,
 484                                                        ppace[i]->type);
 485                        acl_mode &= 0007;
 486                        if (!others_found) {
 487                                mode &= ~(0007);
 488                                mode |= acl_mode;
 489                        }
 490                        others_found = true;
 491                } else if (!compare_sids(&ppace[i]->sid, &creator_owner)) {
 492                        continue;
 493                } else if (!compare_sids(&ppace[i]->sid, &creator_group)) {
 494                        continue;
 495                } else if (!compare_sids(&ppace[i]->sid, &sid_authusers)) {
 496                        continue;
 497                } else {
 498                        struct smb_fattr temp_fattr;
 499
 500                        acl_mode = access_flags_to_mode(fattr, ppace[i]->access_req,
 501                                                        ppace[i]->type);
 502                        temp_fattr.cf_uid = INVALID_UID;
 503                        ret = sid_to_id(user_ns, &ppace[i]->sid, SIDOWNER, &temp_fattr);
 504                        if (ret || uid_eq(temp_fattr.cf_uid, INVALID_UID)) {
 505                                pr_err("%s: Error %d mapping Owner SID to uid\n",
 506                                       __func__, ret);
 507                                continue;
 508                        }
 509
 510                        acl_state.owner.allow = ((acl_mode & 0700) >> 6) | 0004;
 511                        acl_state.users->aces[acl_state.users->n].uid =
 512                                temp_fattr.cf_uid;
 513                        acl_state.users->aces[acl_state.users->n++].perms.allow =
 514                                ((acl_mode & 0700) >> 6) | 0004;
 515                        default_acl_state.owner.allow = ((acl_mode & 0700) >> 6) | 0004;
 516                        default_acl_state.users->aces[default_acl_state.users->n].uid =
 517                                temp_fattr.cf_uid;
 518                        default_acl_state.users->aces[default_acl_state.users->n++].perms.allow =
 519                                ((acl_mode & 0700) >> 6) | 0004;
 520                }
 521        }
 522        kfree(ppace);
 523
 524        if (owner_found) {
 525                /* The owner must be set to at least read-only. */
 526                acl_state.owner.allow = ((mode & 0700) >> 6) | 0004;
 527                acl_state.users->aces[acl_state.users->n].uid = fattr->cf_uid;
 528                acl_state.users->aces[acl_state.users->n++].perms.allow =
 529                        ((mode & 0700) >> 6) | 0004;
 530                default_acl_state.owner.allow = ((mode & 0700) >> 6) | 0004;
 531                default_acl_state.users->aces[default_acl_state.users->n].uid =
 532                        fattr->cf_uid;
 533                default_acl_state.users->aces[default_acl_state.users->n++].perms.allow =
 534                        ((mode & 0700) >> 6) | 0004;
 535        }
 536
 537        if (group_found) {
 538                acl_state.group.allow = (mode & 0070) >> 3;
 539                acl_state.groups->aces[acl_state.groups->n].gid =
 540                        fattr->cf_gid;
 541                acl_state.groups->aces[acl_state.groups->n++].perms.allow =
 542                        (mode & 0070) >> 3;
 543                default_acl_state.group.allow = (mode & 0070) >> 3;
 544                default_acl_state.groups->aces[default_acl_state.groups->n].gid =
 545                        fattr->cf_gid;
 546                default_acl_state.groups->aces[default_acl_state.groups->n++].perms.allow =
 547                        (mode & 0070) >> 3;
 548        }
 549
 550        if (others_found) {
 551                fattr->cf_mode &= ~(0007);
 552                fattr->cf_mode |= mode & 0007;
 553
 554                acl_state.other.allow = mode & 0007;
 555                default_acl_state.other.allow = mode & 0007;
 556        }
 557
 558        if (acl_state.users->n || acl_state.groups->n) {
 559                acl_state.mask.allow = 0x07;
 560
 561                if (IS_ENABLED(CONFIG_FS_POSIX_ACL)) {
 562                        fattr->cf_acls =
 563                                posix_acl_alloc(acl_state.users->n +
 564                                        acl_state.groups->n + 4, GFP_KERNEL);
 565                        if (fattr->cf_acls) {
 566                                cf_pace = fattr->cf_acls->a_entries;
 567                                posix_state_to_acl(&acl_state, cf_pace);
 568                        }
 569                }
 570        }
 571
 572        if (default_acl_state.users->n || default_acl_state.groups->n) {
 573                default_acl_state.mask.allow = 0x07;
 574
 575                if (IS_ENABLED(CONFIG_FS_POSIX_ACL)) {
 576                        fattr->cf_dacls =
 577                                posix_acl_alloc(default_acl_state.users->n +
 578                                default_acl_state.groups->n + 4, GFP_KERNEL);
 579                        if (fattr->cf_dacls) {
 580                                cf_pdace = fattr->cf_dacls->a_entries;
 581                                posix_state_to_acl(&default_acl_state, cf_pdace);
 582                        }
 583                }
 584        }
 585        free_acl_state(&acl_state);
 586        free_acl_state(&default_acl_state);
 587}
 588
 589static void set_posix_acl_entries_dacl(struct user_namespace *user_ns,
 590                                       struct smb_ace *pndace,
 591                                       struct smb_fattr *fattr, u32 *num_aces,
 592                                       u16 *size, u32 nt_aces_num)
 593{
 594        struct posix_acl_entry *pace;
 595        struct smb_sid *sid;
 596        struct smb_ace *ntace;
 597        int i, j;
 598
 599        if (!fattr->cf_acls)
 600                goto posix_default_acl;
 601
 602        pace = fattr->cf_acls->a_entries;
 603        for (i = 0; i < fattr->cf_acls->a_count; i++, pace++) {
 604                int flags = 0;
 605
 606                sid = kmalloc(sizeof(struct smb_sid), GFP_KERNEL);
 607                if (!sid)
 608                        break;
 609
 610                if (pace->e_tag == ACL_USER) {
 611                        uid_t uid;
 612                        unsigned int sid_type = SIDOWNER;
 613
 614                        uid = posix_acl_uid_translate(user_ns, pace);
 615                        if (!uid)
 616                                sid_type = SIDUNIX_USER;
 617                        id_to_sid(uid, sid_type, sid);
 618                } else if (pace->e_tag == ACL_GROUP) {
 619                        gid_t gid;
 620
 621                        gid = posix_acl_gid_translate(user_ns, pace);
 622                        id_to_sid(gid, SIDUNIX_GROUP, sid);
 623                } else if (pace->e_tag == ACL_OTHER && !nt_aces_num) {
 624                        smb_copy_sid(sid, &sid_everyone);
 625                } else {
 626                        kfree(sid);
 627                        continue;
 628                }
 629                ntace = pndace;
 630                for (j = 0; j < nt_aces_num; j++) {
 631                        if (ntace->sid.sub_auth[ntace->sid.num_subauth - 1] ==
 632                                        sid->sub_auth[sid->num_subauth - 1])
 633                                goto pass_same_sid;
 634                        ntace = (struct smb_ace *)((char *)ntace +
 635                                        le16_to_cpu(ntace->size));
 636                }
 637
 638                if (S_ISDIR(fattr->cf_mode) && pace->e_tag == ACL_OTHER)
 639                        flags = 0x03;
 640
 641                ntace = (struct smb_ace *)((char *)pndace + *size);
 642                *size += fill_ace_for_sid(ntace, sid, ACCESS_ALLOWED, flags,
 643                                pace->e_perm, 0777);
 644                (*num_aces)++;
 645                if (pace->e_tag == ACL_USER)
 646                        ntace->access_req |=
 647                                FILE_DELETE_LE | FILE_DELETE_CHILD_LE;
 648
 649                if (S_ISDIR(fattr->cf_mode) &&
 650                    (pace->e_tag == ACL_USER || pace->e_tag == ACL_GROUP)) {
 651                        ntace = (struct smb_ace *)((char *)pndace + *size);
 652                        *size += fill_ace_for_sid(ntace, sid, ACCESS_ALLOWED,
 653                                        0x03, pace->e_perm, 0777);
 654                        (*num_aces)++;
 655                        if (pace->e_tag == ACL_USER)
 656                                ntace->access_req |=
 657                                        FILE_DELETE_LE | FILE_DELETE_CHILD_LE;
 658                }
 659
 660pass_same_sid:
 661                kfree(sid);
 662        }
 663
 664        if (nt_aces_num)
 665                return;
 666
 667posix_default_acl:
 668        if (!fattr->cf_dacls)
 669                return;
 670
 671        pace = fattr->cf_dacls->a_entries;
 672        for (i = 0; i < fattr->cf_dacls->a_count; i++, pace++) {
 673                sid = kmalloc(sizeof(struct smb_sid), GFP_KERNEL);
 674                if (!sid)
 675                        break;
 676
 677                if (pace->e_tag == ACL_USER) {
 678                        uid_t uid;
 679
 680                        uid = posix_acl_uid_translate(user_ns, pace);
 681                        id_to_sid(uid, SIDCREATOR_OWNER, sid);
 682                } else if (pace->e_tag == ACL_GROUP) {
 683                        gid_t gid;
 684
 685                        gid = posix_acl_gid_translate(user_ns, pace);
 686                        id_to_sid(gid, SIDCREATOR_GROUP, sid);
 687                } else {
 688                        kfree(sid);
 689                        continue;
 690                }
 691
 692                ntace = (struct smb_ace *)((char *)pndace + *size);
 693                *size += fill_ace_for_sid(ntace, sid, ACCESS_ALLOWED, 0x0b,
 694                                pace->e_perm, 0777);
 695                (*num_aces)++;
 696                if (pace->e_tag == ACL_USER)
 697                        ntace->access_req |=
 698                                FILE_DELETE_LE | FILE_DELETE_CHILD_LE;
 699                kfree(sid);
 700        }
 701}
 702
 703static void set_ntacl_dacl(struct user_namespace *user_ns,
 704                           struct smb_acl *pndacl,
 705                           struct smb_acl *nt_dacl,
 706                           const struct smb_sid *pownersid,
 707                           const struct smb_sid *pgrpsid,
 708                           struct smb_fattr *fattr)
 709{
 710        struct smb_ace *ntace, *pndace;
 711        int nt_num_aces = le32_to_cpu(nt_dacl->num_aces), num_aces = 0;
 712        unsigned short size = 0;
 713        int i;
 714
 715        pndace = (struct smb_ace *)((char *)pndacl + sizeof(struct smb_acl));
 716        if (nt_num_aces) {
 717                ntace = (struct smb_ace *)((char *)nt_dacl + sizeof(struct smb_acl));
 718                for (i = 0; i < nt_num_aces; i++) {
 719                        memcpy((char *)pndace + size, ntace, le16_to_cpu(ntace->size));
 720                        size += le16_to_cpu(ntace->size);
 721                        ntace = (struct smb_ace *)((char *)ntace + le16_to_cpu(ntace->size));
 722                        num_aces++;
 723                }
 724        }
 725
 726        set_posix_acl_entries_dacl(user_ns, pndace, fattr,
 727                                   &num_aces, &size, nt_num_aces);
 728        pndacl->num_aces = cpu_to_le32(num_aces);
 729        pndacl->size = cpu_to_le16(le16_to_cpu(pndacl->size) + size);
 730}
 731
 732static void set_mode_dacl(struct user_namespace *user_ns,
 733                          struct smb_acl *pndacl, struct smb_fattr *fattr)
 734{
 735        struct smb_ace *pace, *pndace;
 736        u32 num_aces = 0;
 737        u16 size = 0, ace_size = 0;
 738        uid_t uid;
 739        const struct smb_sid *sid;
 740
 741        pace = pndace = (struct smb_ace *)((char *)pndacl + sizeof(struct smb_acl));
 742
 743        if (fattr->cf_acls) {
 744                set_posix_acl_entries_dacl(user_ns, pndace, fattr,
 745                                           &num_aces, &size, num_aces);
 746                goto out;
 747        }
 748
 749        /* owner RID */
 750        uid = from_kuid(&init_user_ns, fattr->cf_uid);
 751        if (uid)
 752                sid = &server_conf.domain_sid;
 753        else
 754                sid = &sid_unix_users;
 755        ace_size = fill_ace_for_sid(pace, sid, ACCESS_ALLOWED, 0,
 756                                    fattr->cf_mode, 0700);
 757        pace->sid.sub_auth[pace->sid.num_subauth++] = cpu_to_le32(uid);
 758        pace->size = cpu_to_le16(ace_size + 4);
 759        size += le16_to_cpu(pace->size);
 760        pace = (struct smb_ace *)((char *)pndace + size);
 761
 762        /* Group RID */
 763        ace_size = fill_ace_for_sid(pace, &sid_unix_groups,
 764                                    ACCESS_ALLOWED, 0, fattr->cf_mode, 0070);
 765        pace->sid.sub_auth[pace->sid.num_subauth++] =
 766                cpu_to_le32(from_kgid(&init_user_ns, fattr->cf_gid));
 767        pace->size = cpu_to_le16(ace_size + 4);
 768        size += le16_to_cpu(pace->size);
 769        pace = (struct smb_ace *)((char *)pndace + size);
 770        num_aces = 3;
 771
 772        if (S_ISDIR(fattr->cf_mode)) {
 773                pace = (struct smb_ace *)((char *)pndace + size);
 774
 775                /* creator owner */
 776                size += fill_ace_for_sid(pace, &creator_owner, ACCESS_ALLOWED,
 777                                         0x0b, fattr->cf_mode, 0700);
 778                pace = (struct smb_ace *)((char *)pndace + size);
 779
 780                /* creator group */
 781                size += fill_ace_for_sid(pace, &creator_group, ACCESS_ALLOWED,
 782                                         0x0b, fattr->cf_mode, 0070);
 783                pace = (struct smb_ace *)((char *)pndace + size);
 784                num_aces = 5;
 785        }
 786
 787        /* other */
 788        size += fill_ace_for_sid(pace, &sid_everyone, ACCESS_ALLOWED, 0,
 789                                 fattr->cf_mode, 0007);
 790
 791out:
 792        pndacl->num_aces = cpu_to_le32(num_aces);
 793        pndacl->size = cpu_to_le16(le16_to_cpu(pndacl->size) + size);
 794}
 795
 796static int parse_sid(struct smb_sid *psid, char *end_of_acl)
 797{
 798        /*
 799         * validate that we do not go past end of ACL - sid must be at least 8
 800         * bytes long (assuming no sub-auths - e.g. the null SID
 801         */
 802        if (end_of_acl < (char *)psid + 8) {
 803                pr_err("ACL too small to parse SID %p\n", psid);
 804                return -EINVAL;
 805        }
 806
 807        return 0;
 808}
 809
 810/* Convert CIFS ACL to POSIX form */
 811int parse_sec_desc(struct user_namespace *user_ns, struct smb_ntsd *pntsd,
 812                   int acl_len, struct smb_fattr *fattr)
 813{
 814        int rc = 0;
 815        struct smb_sid *owner_sid_ptr, *group_sid_ptr;
 816        struct smb_acl *dacl_ptr; /* no need for SACL ptr */
 817        char *end_of_acl = ((char *)pntsd) + acl_len;
 818        __u32 dacloffset;
 819        int pntsd_type;
 820
 821        if (!pntsd)
 822                return -EIO;
 823
 824        if (acl_len < sizeof(struct smb_ntsd))
 825                return -EINVAL;
 826
 827        owner_sid_ptr = (struct smb_sid *)((char *)pntsd +
 828                        le32_to_cpu(pntsd->osidoffset));
 829        group_sid_ptr = (struct smb_sid *)((char *)pntsd +
 830                        le32_to_cpu(pntsd->gsidoffset));
 831        dacloffset = le32_to_cpu(pntsd->dacloffset);
 832        dacl_ptr = (struct smb_acl *)((char *)pntsd + dacloffset);
 833        ksmbd_debug(SMB,
 834                    "revision %d type 0x%x ooffset 0x%x goffset 0x%x sacloffset 0x%x dacloffset 0x%x\n",
 835                    pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset),
 836                    le32_to_cpu(pntsd->gsidoffset),
 837                    le32_to_cpu(pntsd->sacloffset), dacloffset);
 838
 839        pntsd_type = le16_to_cpu(pntsd->type);
 840        if (!(pntsd_type & DACL_PRESENT)) {
 841                ksmbd_debug(SMB, "DACL_PRESENT in DACL type is not set\n");
 842                return rc;
 843        }
 844
 845        pntsd->type = cpu_to_le16(DACL_PRESENT);
 846
 847        if (pntsd->osidoffset) {
 848                rc = parse_sid(owner_sid_ptr, end_of_acl);
 849                if (rc) {
 850                        pr_err("%s: Error %d parsing Owner SID\n", __func__, rc);
 851                        return rc;
 852                }
 853
 854                rc = sid_to_id(user_ns, owner_sid_ptr, SIDOWNER, fattr);
 855                if (rc) {
 856                        pr_err("%s: Error %d mapping Owner SID to uid\n",
 857                               __func__, rc);
 858                        owner_sid_ptr = NULL;
 859                }
 860        }
 861
 862        if (pntsd->gsidoffset) {
 863                rc = parse_sid(group_sid_ptr, end_of_acl);
 864                if (rc) {
 865                        pr_err("%s: Error %d mapping Owner SID to gid\n",
 866                               __func__, rc);
 867                        return rc;
 868                }
 869                rc = sid_to_id(user_ns, group_sid_ptr, SIDUNIX_GROUP, fattr);
 870                if (rc) {
 871                        pr_err("%s: Error %d mapping Group SID to gid\n",
 872                               __func__, rc);
 873                        group_sid_ptr = NULL;
 874                }
 875        }
 876
 877        if ((pntsd_type & (DACL_AUTO_INHERITED | DACL_AUTO_INHERIT_REQ)) ==
 878            (DACL_AUTO_INHERITED | DACL_AUTO_INHERIT_REQ))
 879                pntsd->type |= cpu_to_le16(DACL_AUTO_INHERITED);
 880        if (pntsd_type & DACL_PROTECTED)
 881                pntsd->type |= cpu_to_le16(DACL_PROTECTED);
 882
 883        if (dacloffset) {
 884                parse_dacl(user_ns, dacl_ptr, end_of_acl,
 885                           owner_sid_ptr, group_sid_ptr, fattr);
 886        }
 887
 888        return 0;
 889}
 890
 891/* Convert permission bits from mode to equivalent CIFS ACL */
 892int build_sec_desc(struct user_namespace *user_ns,
 893                   struct smb_ntsd *pntsd, struct smb_ntsd *ppntsd,
 894                   int addition_info, __u32 *secdesclen,
 895                   struct smb_fattr *fattr)
 896{
 897        int rc = 0;
 898        __u32 offset;
 899        struct smb_sid *owner_sid_ptr, *group_sid_ptr;
 900        struct smb_sid *nowner_sid_ptr, *ngroup_sid_ptr;
 901        struct smb_acl *dacl_ptr = NULL; /* no need for SACL ptr */
 902        uid_t uid;
 903        gid_t gid;
 904        unsigned int sid_type = SIDOWNER;
 905
 906        nowner_sid_ptr = kmalloc(sizeof(struct smb_sid), GFP_KERNEL);
 907        if (!nowner_sid_ptr)
 908                return -ENOMEM;
 909
 910        uid = from_kuid(&init_user_ns, fattr->cf_uid);
 911        if (!uid)
 912                sid_type = SIDUNIX_USER;
 913        id_to_sid(uid, sid_type, nowner_sid_ptr);
 914
 915        ngroup_sid_ptr = kmalloc(sizeof(struct smb_sid), GFP_KERNEL);
 916        if (!ngroup_sid_ptr) {
 917                kfree(nowner_sid_ptr);
 918                return -ENOMEM;
 919        }
 920
 921        gid = from_kgid(&init_user_ns, fattr->cf_gid);
 922        id_to_sid(gid, SIDUNIX_GROUP, ngroup_sid_ptr);
 923
 924        offset = sizeof(struct smb_ntsd);
 925        pntsd->sacloffset = 0;
 926        pntsd->revision = cpu_to_le16(1);
 927        pntsd->type = cpu_to_le16(SELF_RELATIVE);
 928        if (ppntsd)
 929                pntsd->type |= ppntsd->type;
 930
 931        if (addition_info & OWNER_SECINFO) {
 932                pntsd->osidoffset = cpu_to_le32(offset);
 933                owner_sid_ptr = (struct smb_sid *)((char *)pntsd + offset);
 934                smb_copy_sid(owner_sid_ptr, nowner_sid_ptr);
 935                offset += 1 + 1 + 6 + (nowner_sid_ptr->num_subauth * 4);
 936        }
 937
 938        if (addition_info & GROUP_SECINFO) {
 939                pntsd->gsidoffset = cpu_to_le32(offset);
 940                group_sid_ptr = (struct smb_sid *)((char *)pntsd + offset);
 941                smb_copy_sid(group_sid_ptr, ngroup_sid_ptr);
 942                offset += 1 + 1 + 6 + (ngroup_sid_ptr->num_subauth * 4);
 943        }
 944
 945        if (addition_info & DACL_SECINFO) {
 946                pntsd->type |= cpu_to_le16(DACL_PRESENT);
 947                dacl_ptr = (struct smb_acl *)((char *)pntsd + offset);
 948                dacl_ptr->revision = cpu_to_le16(2);
 949                dacl_ptr->size = cpu_to_le16(sizeof(struct smb_acl));
 950                dacl_ptr->num_aces = 0;
 951
 952                if (!ppntsd) {
 953                        set_mode_dacl(user_ns, dacl_ptr, fattr);
 954                } else if (!ppntsd->dacloffset) {
 955                        goto out;
 956                } else {
 957                        struct smb_acl *ppdacl_ptr;
 958
 959                        ppdacl_ptr = (struct smb_acl *)((char *)ppntsd +
 960                                                le32_to_cpu(ppntsd->dacloffset));
 961                        set_ntacl_dacl(user_ns, dacl_ptr, ppdacl_ptr,
 962                                       nowner_sid_ptr, ngroup_sid_ptr, fattr);
 963                }
 964                pntsd->dacloffset = cpu_to_le32(offset);
 965                offset += le16_to_cpu(dacl_ptr->size);
 966        }
 967
 968out:
 969        kfree(nowner_sid_ptr);
 970        kfree(ngroup_sid_ptr);
 971        *secdesclen = offset;
 972        return rc;
 973}
 974
 975static void smb_set_ace(struct smb_ace *ace, const struct smb_sid *sid, u8 type,
 976                        u8 flags, __le32 access_req)
 977{
 978        ace->type = type;
 979        ace->flags = flags;
 980        ace->access_req = access_req;
 981        smb_copy_sid(&ace->sid, sid);
 982        ace->size = cpu_to_le16(1 + 1 + 2 + 4 + 1 + 1 + 6 + (sid->num_subauth * 4));
 983}
 984
 985int smb_inherit_dacl(struct ksmbd_conn *conn,
 986                     struct path *path,
 987                     unsigned int uid, unsigned int gid)
 988{
 989        const struct smb_sid *psid, *creator = NULL;
 990        struct smb_ace *parent_aces, *aces;
 991        struct smb_acl *parent_pdacl;
 992        struct smb_ntsd *parent_pntsd = NULL;
 993        struct smb_sid owner_sid, group_sid;
 994        struct dentry *parent = path->dentry->d_parent;
 995        struct user_namespace *user_ns = mnt_user_ns(path->mnt);
 996        int inherited_flags = 0, flags = 0, i, ace_cnt = 0, nt_size = 0;
 997        int rc = 0, num_aces, dacloffset, pntsd_type, acl_len;
 998        char *aces_base;
 999        bool is_dir = S_ISDIR(d_inode(path->dentry)->i_mode);
1000
1001        acl_len = ksmbd_vfs_get_sd_xattr(conn, user_ns,
1002                                         parent, &parent_pntsd);
1003        if (acl_len <= 0)
1004                return -ENOENT;
1005        dacloffset = le32_to_cpu(parent_pntsd->dacloffset);
1006        if (!dacloffset) {
1007                rc = -EINVAL;
1008                goto free_parent_pntsd;
1009        }
1010
1011        parent_pdacl = (struct smb_acl *)((char *)parent_pntsd + dacloffset);
1012        num_aces = le32_to_cpu(parent_pdacl->num_aces);
1013        pntsd_type = le16_to_cpu(parent_pntsd->type);
1014
1015        aces_base = kmalloc(sizeof(struct smb_ace) * num_aces * 2, GFP_KERNEL);
1016        if (!aces_base) {
1017                rc = -ENOMEM;
1018                goto free_parent_pntsd;
1019        }
1020
1021        aces = (struct smb_ace *)aces_base;
1022        parent_aces = (struct smb_ace *)((char *)parent_pdacl +
1023                        sizeof(struct smb_acl));
1024
1025        if (pntsd_type & DACL_AUTO_INHERITED)
1026                inherited_flags = INHERITED_ACE;
1027
1028        for (i = 0; i < num_aces; i++) {
1029                flags = parent_aces->flags;
1030                if (!smb_inherit_flags(flags, is_dir))
1031                        goto pass;
1032                if (is_dir) {
1033                        flags &= ~(INHERIT_ONLY_ACE | INHERITED_ACE);
1034                        if (!(flags & CONTAINER_INHERIT_ACE))
1035                                flags |= INHERIT_ONLY_ACE;
1036                        if (flags & NO_PROPAGATE_INHERIT_ACE)
1037                                flags = 0;
1038                } else {
1039                        flags = 0;
1040                }
1041
1042                if (!compare_sids(&creator_owner, &parent_aces->sid)) {
1043                        creator = &creator_owner;
1044                        id_to_sid(uid, SIDOWNER, &owner_sid);
1045                        psid = &owner_sid;
1046                } else if (!compare_sids(&creator_group, &parent_aces->sid)) {
1047                        creator = &creator_group;
1048                        id_to_sid(gid, SIDUNIX_GROUP, &group_sid);
1049                        psid = &group_sid;
1050                } else {
1051                        creator = NULL;
1052                        psid = &parent_aces->sid;
1053                }
1054
1055                if (is_dir && creator && flags & CONTAINER_INHERIT_ACE) {
1056                        smb_set_ace(aces, psid, parent_aces->type, inherited_flags,
1057                                    parent_aces->access_req);
1058                        nt_size += le16_to_cpu(aces->size);
1059                        ace_cnt++;
1060                        aces = (struct smb_ace *)((char *)aces + le16_to_cpu(aces->size));
1061                        flags |= INHERIT_ONLY_ACE;
1062                        psid = creator;
1063                } else if (is_dir && !(parent_aces->flags & NO_PROPAGATE_INHERIT_ACE)) {
1064                        psid = &parent_aces->sid;
1065                }
1066
1067                smb_set_ace(aces, psid, parent_aces->type, flags | inherited_flags,
1068                            parent_aces->access_req);
1069                nt_size += le16_to_cpu(aces->size);
1070                aces = (struct smb_ace *)((char *)aces + le16_to_cpu(aces->size));
1071                ace_cnt++;
1072pass:
1073                parent_aces =
1074                        (struct smb_ace *)((char *)parent_aces + le16_to_cpu(parent_aces->size));
1075        }
1076
1077        if (nt_size > 0) {
1078                struct smb_ntsd *pntsd;
1079                struct smb_acl *pdacl;
1080                struct smb_sid *powner_sid = NULL, *pgroup_sid = NULL;
1081                int powner_sid_size = 0, pgroup_sid_size = 0, pntsd_size;
1082
1083                if (parent_pntsd->osidoffset) {
1084                        powner_sid = (struct smb_sid *)((char *)parent_pntsd +
1085                                        le32_to_cpu(parent_pntsd->osidoffset));
1086                        powner_sid_size = 1 + 1 + 6 + (powner_sid->num_subauth * 4);
1087                }
1088                if (parent_pntsd->gsidoffset) {
1089                        pgroup_sid = (struct smb_sid *)((char *)parent_pntsd +
1090                                        le32_to_cpu(parent_pntsd->gsidoffset));
1091                        pgroup_sid_size = 1 + 1 + 6 + (pgroup_sid->num_subauth * 4);
1092                }
1093
1094                pntsd = kzalloc(sizeof(struct smb_ntsd) + powner_sid_size +
1095                                pgroup_sid_size + sizeof(struct smb_acl) +
1096                                nt_size, GFP_KERNEL);
1097                if (!pntsd) {
1098                        rc = -ENOMEM;
1099                        goto free_aces_base;
1100                }
1101
1102                pntsd->revision = cpu_to_le16(1);
1103                pntsd->type = cpu_to_le16(SELF_RELATIVE | DACL_PRESENT);
1104                if (le16_to_cpu(parent_pntsd->type) & DACL_AUTO_INHERITED)
1105                        pntsd->type |= cpu_to_le16(DACL_AUTO_INHERITED);
1106                pntsd_size = sizeof(struct smb_ntsd);
1107                pntsd->osidoffset = parent_pntsd->osidoffset;
1108                pntsd->gsidoffset = parent_pntsd->gsidoffset;
1109                pntsd->dacloffset = parent_pntsd->dacloffset;
1110
1111                if (pntsd->osidoffset) {
1112                        struct smb_sid *owner_sid = (struct smb_sid *)((char *)pntsd +
1113                                        le32_to_cpu(pntsd->osidoffset));
1114                        memcpy(owner_sid, powner_sid, powner_sid_size);
1115                        pntsd_size += powner_sid_size;
1116                }
1117
1118                if (pntsd->gsidoffset) {
1119                        struct smb_sid *group_sid = (struct smb_sid *)((char *)pntsd +
1120                                        le32_to_cpu(pntsd->gsidoffset));
1121                        memcpy(group_sid, pgroup_sid, pgroup_sid_size);
1122                        pntsd_size += pgroup_sid_size;
1123                }
1124
1125                if (pntsd->dacloffset) {
1126                        struct smb_ace *pace;
1127
1128                        pdacl = (struct smb_acl *)((char *)pntsd + le32_to_cpu(pntsd->dacloffset));
1129                        pdacl->revision = cpu_to_le16(2);
1130                        pdacl->size = cpu_to_le16(sizeof(struct smb_acl) + nt_size);
1131                        pdacl->num_aces = cpu_to_le32(ace_cnt);
1132                        pace = (struct smb_ace *)((char *)pdacl + sizeof(struct smb_acl));
1133                        memcpy(pace, aces_base, nt_size);
1134                        pntsd_size += sizeof(struct smb_acl) + nt_size;
1135                }
1136
1137                ksmbd_vfs_set_sd_xattr(conn, user_ns,
1138                                       path->dentry, pntsd, pntsd_size);
1139                kfree(pntsd);
1140        }
1141
1142free_aces_base:
1143        kfree(aces_base);
1144free_parent_pntsd:
1145        kfree(parent_pntsd);
1146        return rc;
1147}
1148
1149bool smb_inherit_flags(int flags, bool is_dir)
1150{
1151        if (!is_dir)
1152                return (flags & OBJECT_INHERIT_ACE) != 0;
1153
1154        if (flags & OBJECT_INHERIT_ACE && !(flags & NO_PROPAGATE_INHERIT_ACE))
1155                return true;
1156
1157        if (flags & CONTAINER_INHERIT_ACE)
1158                return true;
1159        return false;
1160}
1161
1162int smb_check_perm_dacl(struct ksmbd_conn *conn, struct path *path,
1163                        __le32 *pdaccess, int uid)
1164{
1165        struct user_namespace *user_ns = mnt_user_ns(path->mnt);
1166        struct smb_ntsd *pntsd = NULL;
1167        struct smb_acl *pdacl;
1168        struct posix_acl *posix_acls;
1169        int rc = 0, acl_size;
1170        struct smb_sid sid;
1171        int granted = le32_to_cpu(*pdaccess & ~FILE_MAXIMAL_ACCESS_LE);
1172        struct smb_ace *ace;
1173        int i, found = 0;
1174        unsigned int access_bits = 0;
1175        struct smb_ace *others_ace = NULL;
1176        struct posix_acl_entry *pa_entry;
1177        unsigned int sid_type = SIDOWNER;
1178        char *end_of_acl;
1179
1180        ksmbd_debug(SMB, "check permission using windows acl\n");
1181        acl_size = ksmbd_vfs_get_sd_xattr(conn, user_ns,
1182                                          path->dentry, &pntsd);
1183        if (acl_size <= 0 || !pntsd || !pntsd->dacloffset) {
1184                kfree(pntsd);
1185                return 0;
1186        }
1187
1188        pdacl = (struct smb_acl *)((char *)pntsd + le32_to_cpu(pntsd->dacloffset));
1189        end_of_acl = ((char *)pntsd) + acl_size;
1190        if (end_of_acl <= (char *)pdacl) {
1191                kfree(pntsd);
1192                return 0;
1193        }
1194
1195        if (end_of_acl < (char *)pdacl + le16_to_cpu(pdacl->size) ||
1196            le16_to_cpu(pdacl->size) < sizeof(struct smb_acl)) {
1197                kfree(pntsd);
1198                return 0;
1199        }
1200
1201        if (!pdacl->num_aces) {
1202                if (!(le16_to_cpu(pdacl->size) - sizeof(struct smb_acl)) &&
1203                    *pdaccess & ~(FILE_READ_CONTROL_LE | FILE_WRITE_DAC_LE)) {
1204                        rc = -EACCES;
1205                        goto err_out;
1206                }
1207                kfree(pntsd);
1208                return 0;
1209        }
1210
1211        if (*pdaccess & FILE_MAXIMAL_ACCESS_LE) {
1212                granted = READ_CONTROL | WRITE_DAC | FILE_READ_ATTRIBUTES |
1213                        DELETE;
1214
1215                ace = (struct smb_ace *)((char *)pdacl + sizeof(struct smb_acl));
1216                for (i = 0; i < le32_to_cpu(pdacl->num_aces); i++) {
1217                        granted |= le32_to_cpu(ace->access_req);
1218                        ace = (struct smb_ace *)((char *)ace + le16_to_cpu(ace->size));
1219                        if (end_of_acl < (char *)ace)
1220                                goto err_out;
1221                }
1222
1223                if (!pdacl->num_aces)
1224                        granted = GENERIC_ALL_FLAGS;
1225        }
1226
1227        if (!uid)
1228                sid_type = SIDUNIX_USER;
1229        id_to_sid(uid, sid_type, &sid);
1230
1231        ace = (struct smb_ace *)((char *)pdacl + sizeof(struct smb_acl));
1232        for (i = 0; i < le32_to_cpu(pdacl->num_aces); i++) {
1233                if (!compare_sids(&sid, &ace->sid) ||
1234                    !compare_sids(&sid_unix_NFS_mode, &ace->sid)) {
1235                        found = 1;
1236                        break;
1237                }
1238                if (!compare_sids(&sid_everyone, &ace->sid))
1239                        others_ace = ace;
1240
1241                ace = (struct smb_ace *)((char *)ace + le16_to_cpu(ace->size));
1242                if (end_of_acl < (char *)ace)
1243                        goto err_out;
1244        }
1245
1246        if (*pdaccess & FILE_MAXIMAL_ACCESS_LE && found) {
1247                granted = READ_CONTROL | WRITE_DAC | FILE_READ_ATTRIBUTES |
1248                        DELETE;
1249
1250                granted |= le32_to_cpu(ace->access_req);
1251
1252                if (!pdacl->num_aces)
1253                        granted = GENERIC_ALL_FLAGS;
1254        }
1255
1256        if (IS_ENABLED(CONFIG_FS_POSIX_ACL)) {
1257                posix_acls = get_acl(d_inode(path->dentry), ACL_TYPE_ACCESS);
1258                if (posix_acls && !found) {
1259                        unsigned int id = -1;
1260
1261                        pa_entry = posix_acls->a_entries;
1262                        for (i = 0; i < posix_acls->a_count; i++, pa_entry++) {
1263                                if (pa_entry->e_tag == ACL_USER)
1264                                        id = posix_acl_uid_translate(user_ns, pa_entry);
1265                                else if (pa_entry->e_tag == ACL_GROUP)
1266                                        id = posix_acl_gid_translate(user_ns, pa_entry);
1267                                else
1268                                        continue;
1269
1270                                if (id == uid) {
1271                                        mode_to_access_flags(pa_entry->e_perm,
1272                                                             0777,
1273                                                             &access_bits);
1274                                        if (!access_bits)
1275                                                access_bits =
1276                                                        SET_MINIMUM_RIGHTS;
1277                                        goto check_access_bits;
1278                                }
1279                        }
1280                }
1281                if (posix_acls)
1282                        posix_acl_release(posix_acls);
1283        }
1284
1285        if (!found) {
1286                if (others_ace) {
1287                        ace = others_ace;
1288                } else {
1289                        ksmbd_debug(SMB, "Can't find corresponding sid\n");
1290                        rc = -EACCES;
1291                        goto err_out;
1292                }
1293        }
1294
1295        switch (ace->type) {
1296        case ACCESS_ALLOWED_ACE_TYPE:
1297                access_bits = le32_to_cpu(ace->access_req);
1298                break;
1299        case ACCESS_DENIED_ACE_TYPE:
1300        case ACCESS_DENIED_CALLBACK_ACE_TYPE:
1301                access_bits = le32_to_cpu(~ace->access_req);
1302                break;
1303        }
1304
1305check_access_bits:
1306        if (granted &
1307            ~(access_bits | FILE_READ_ATTRIBUTES | READ_CONTROL | WRITE_DAC | DELETE)) {
1308                ksmbd_debug(SMB, "Access denied with winACL, granted : %x, access_req : %x\n",
1309                            granted, le32_to_cpu(ace->access_req));
1310                rc = -EACCES;
1311                goto err_out;
1312        }
1313
1314        *pdaccess = cpu_to_le32(granted);
1315err_out:
1316        kfree(pntsd);
1317        return rc;
1318}
1319
1320int set_info_sec(struct ksmbd_conn *conn, struct ksmbd_tree_connect *tcon,
1321                 struct path *path, struct smb_ntsd *pntsd, int ntsd_len,
1322                 bool type_check)
1323{
1324        int rc;
1325        struct smb_fattr fattr = {{0}};
1326        struct inode *inode = d_inode(path->dentry);
1327        struct user_namespace *user_ns = mnt_user_ns(path->mnt);
1328        struct iattr newattrs;
1329
1330        fattr.cf_uid = INVALID_UID;
1331        fattr.cf_gid = INVALID_GID;
1332        fattr.cf_mode = inode->i_mode;
1333
1334        rc = parse_sec_desc(user_ns, pntsd, ntsd_len, &fattr);
1335        if (rc)
1336                goto out;
1337
1338        newattrs.ia_valid = ATTR_CTIME;
1339        if (!uid_eq(fattr.cf_uid, INVALID_UID)) {
1340                newattrs.ia_valid |= ATTR_UID;
1341                newattrs.ia_uid = fattr.cf_uid;
1342        }
1343        if (!gid_eq(fattr.cf_gid, INVALID_GID)) {
1344                newattrs.ia_valid |= ATTR_GID;
1345                newattrs.ia_gid = fattr.cf_gid;
1346        }
1347        newattrs.ia_valid |= ATTR_MODE;
1348        newattrs.ia_mode = (inode->i_mode & ~0777) | (fattr.cf_mode & 0777);
1349
1350        ksmbd_vfs_remove_acl_xattrs(user_ns, path->dentry);
1351        /* Update posix acls */
1352        if (IS_ENABLED(CONFIG_FS_POSIX_ACL) && fattr.cf_dacls) {
1353                rc = set_posix_acl(user_ns, inode,
1354                                   ACL_TYPE_ACCESS, fattr.cf_acls);
1355                if (rc < 0)
1356                        ksmbd_debug(SMB,
1357                                    "Set posix acl(ACL_TYPE_ACCESS) failed, rc : %d\n",
1358                                    rc);
1359                if (S_ISDIR(inode->i_mode) && fattr.cf_dacls) {
1360                        rc = set_posix_acl(user_ns, inode,
1361                                           ACL_TYPE_DEFAULT, fattr.cf_dacls);
1362                        if (rc)
1363                                ksmbd_debug(SMB,
1364                                            "Set posix acl(ACL_TYPE_DEFAULT) failed, rc : %d\n",
1365                                            rc);
1366                }
1367        }
1368
1369        inode_lock(inode);
1370        rc = notify_change(user_ns, path->dentry, &newattrs, NULL);
1371        inode_unlock(inode);
1372        if (rc)
1373                goto out;
1374
1375        /* Check it only calling from SD BUFFER context */
1376        if (type_check && !(le16_to_cpu(pntsd->type) & DACL_PRESENT))
1377                goto out;
1378
1379        if (test_share_config_flag(tcon->share_conf, KSMBD_SHARE_FLAG_ACL_XATTR)) {
1380                /* Update WinACL in xattr */
1381                ksmbd_vfs_remove_sd_xattrs(user_ns, path->dentry);
1382                ksmbd_vfs_set_sd_xattr(conn, user_ns,
1383                                       path->dentry, pntsd, ntsd_len);
1384        }
1385
1386out:
1387        posix_acl_release(fattr.cf_acls);
1388        posix_acl_release(fattr.cf_dacls);
1389        mark_inode_dirty(inode);
1390        return rc;
1391}
1392
1393void ksmbd_init_domain(u32 *sub_auth)
1394{
1395        int i;
1396
1397        memcpy(&server_conf.domain_sid, &domain, sizeof(struct smb_sid));
1398        for (i = 0; i < 3; ++i)
1399                server_conf.domain_sid.sub_auth[i + 1] = cpu_to_le32(sub_auth[i]);
1400}
1401