0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/fs.h>
0010 #include <linux/slab.h>
0011 #include <linux/string.h>
0012 #include <linux/mnt_idmapping.h>
0013
0014 #include "smbacl.h"
0015 #include "smb_common.h"
0016 #include "server.h"
0017 #include "misc.h"
0018 #include "mgmt/share_config.h"
0019
0020 static const struct smb_sid domain = {1, 4, {0, 0, 0, 0, 0, 5},
0021 {cpu_to_le32(21), cpu_to_le32(1), cpu_to_le32(2), cpu_to_le32(3),
0022 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
0023
0024
0025 static const struct smb_sid creator_owner = {
0026 1, 1, {0, 0, 0, 0, 0, 3}, {0} };
0027
0028 static const struct smb_sid creator_group = {
0029 1, 1, {0, 0, 0, 0, 0, 3}, {cpu_to_le32(1)} };
0030
0031
0032 static const struct smb_sid sid_everyone = {
0033 1, 1, {0, 0, 0, 0, 0, 1}, {0} };
0034
0035 static const struct smb_sid sid_authusers = {
0036 1, 1, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(11)} };
0037
0038
0039 static const struct smb_sid sid_unix_users = {1, 1, {0, 0, 0, 0, 0, 22},
0040 {cpu_to_le32(1), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
0041
0042
0043 static const struct smb_sid sid_unix_groups = { 1, 1, {0, 0, 0, 0, 0, 22},
0044 {cpu_to_le32(2), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
0045
0046
0047
0048
0049
0050
0051
0052
0053 static const struct smb_sid sid_unix_NFS_users = { 1, 2, {0, 0, 0, 0, 0, 5},
0054 {cpu_to_le32(88),
0055 cpu_to_le32(1), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
0056
0057
0058 static const struct smb_sid sid_unix_NFS_groups = { 1, 2, {0, 0, 0, 0, 0, 5},
0059 {cpu_to_le32(88),
0060 cpu_to_le32(2), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
0061
0062
0063 static const struct smb_sid sid_unix_NFS_mode = { 1, 2, {0, 0, 0, 0, 0, 5},
0064 {cpu_to_le32(88),
0065 cpu_to_le32(3), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
0066
0067
0068
0069
0070
0071 int compare_sids(const struct smb_sid *ctsid, const struct smb_sid *cwsid)
0072 {
0073 int i;
0074 int num_subauth, num_sat, num_saw;
0075
0076 if (!ctsid || !cwsid)
0077 return 1;
0078
0079
0080 if (ctsid->revision != cwsid->revision) {
0081 if (ctsid->revision > cwsid->revision)
0082 return 1;
0083 else
0084 return -1;
0085 }
0086
0087
0088 for (i = 0; i < NUM_AUTHS; ++i) {
0089 if (ctsid->authority[i] != cwsid->authority[i]) {
0090 if (ctsid->authority[i] > cwsid->authority[i])
0091 return 1;
0092 else
0093 return -1;
0094 }
0095 }
0096
0097
0098 num_sat = ctsid->num_subauth;
0099 num_saw = cwsid->num_subauth;
0100 num_subauth = num_sat < num_saw ? num_sat : num_saw;
0101 if (num_subauth) {
0102 for (i = 0; i < num_subauth; ++i) {
0103 if (ctsid->sub_auth[i] != cwsid->sub_auth[i]) {
0104 if (le32_to_cpu(ctsid->sub_auth[i]) >
0105 le32_to_cpu(cwsid->sub_auth[i]))
0106 return 1;
0107 else
0108 return -1;
0109 }
0110 }
0111 }
0112
0113 return 0;
0114 }
0115
0116 static void smb_copy_sid(struct smb_sid *dst, const struct smb_sid *src)
0117 {
0118 int i;
0119
0120 dst->revision = src->revision;
0121 dst->num_subauth = min_t(u8, src->num_subauth, SID_MAX_SUB_AUTHORITIES);
0122 for (i = 0; i < NUM_AUTHS; ++i)
0123 dst->authority[i] = src->authority[i];
0124 for (i = 0; i < dst->num_subauth; ++i)
0125 dst->sub_auth[i] = src->sub_auth[i];
0126 }
0127
0128
0129
0130
0131
0132
0133 static umode_t access_flags_to_mode(struct smb_fattr *fattr, __le32 ace_flags,
0134 int type)
0135 {
0136 __u32 flags = le32_to_cpu(ace_flags);
0137 umode_t mode = 0;
0138
0139 if (flags & GENERIC_ALL) {
0140 mode = 0777;
0141 ksmbd_debug(SMB, "all perms\n");
0142 return mode;
0143 }
0144
0145 if ((flags & GENERIC_READ) || (flags & FILE_READ_RIGHTS))
0146 mode = 0444;
0147 if ((flags & GENERIC_WRITE) || (flags & FILE_WRITE_RIGHTS)) {
0148 mode |= 0222;
0149 if (S_ISDIR(fattr->cf_mode))
0150 mode |= 0111;
0151 }
0152 if ((flags & GENERIC_EXECUTE) || (flags & FILE_EXEC_RIGHTS))
0153 mode |= 0111;
0154
0155 if (type == ACCESS_DENIED_ACE_TYPE || type == ACCESS_DENIED_OBJECT_ACE_TYPE)
0156 mode = ~mode;
0157
0158 ksmbd_debug(SMB, "access flags 0x%x mode now %04o\n", flags, mode);
0159
0160 return mode;
0161 }
0162
0163
0164
0165
0166
0167
0168 static void mode_to_access_flags(umode_t mode, umode_t bits_to_use,
0169 __u32 *pace_flags)
0170 {
0171
0172 *pace_flags = 0x0;
0173
0174
0175 mode &= bits_to_use;
0176
0177
0178
0179
0180
0181
0182 if (mode & 0444)
0183 *pace_flags |= SET_FILE_READ_RIGHTS;
0184 if (mode & 0222)
0185 *pace_flags |= FILE_WRITE_RIGHTS;
0186 if (mode & 0111)
0187 *pace_flags |= SET_FILE_EXEC_RIGHTS;
0188
0189 ksmbd_debug(SMB, "mode: %o, access flags now 0x%x\n",
0190 mode, *pace_flags);
0191 }
0192
0193 static __u16 fill_ace_for_sid(struct smb_ace *pntace,
0194 const struct smb_sid *psid, int type, int flags,
0195 umode_t mode, umode_t bits)
0196 {
0197 int i;
0198 __u16 size = 0;
0199 __u32 access_req = 0;
0200
0201 pntace->type = type;
0202 pntace->flags = flags;
0203 mode_to_access_flags(mode, bits, &access_req);
0204 if (!access_req)
0205 access_req = SET_MINIMUM_RIGHTS;
0206 pntace->access_req = cpu_to_le32(access_req);
0207
0208 pntace->sid.revision = psid->revision;
0209 pntace->sid.num_subauth = psid->num_subauth;
0210 for (i = 0; i < NUM_AUTHS; i++)
0211 pntace->sid.authority[i] = psid->authority[i];
0212 for (i = 0; i < psid->num_subauth; i++)
0213 pntace->sid.sub_auth[i] = psid->sub_auth[i];
0214
0215 size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth * 4);
0216 pntace->size = cpu_to_le16(size);
0217
0218 return size;
0219 }
0220
0221 void id_to_sid(unsigned int cid, uint sidtype, struct smb_sid *ssid)
0222 {
0223 switch (sidtype) {
0224 case SIDOWNER:
0225 smb_copy_sid(ssid, &server_conf.domain_sid);
0226 break;
0227 case SIDUNIX_USER:
0228 smb_copy_sid(ssid, &sid_unix_users);
0229 break;
0230 case SIDUNIX_GROUP:
0231 smb_copy_sid(ssid, &sid_unix_groups);
0232 break;
0233 case SIDCREATOR_OWNER:
0234 smb_copy_sid(ssid, &creator_owner);
0235 return;
0236 case SIDCREATOR_GROUP:
0237 smb_copy_sid(ssid, &creator_group);
0238 return;
0239 case SIDNFS_USER:
0240 smb_copy_sid(ssid, &sid_unix_NFS_users);
0241 break;
0242 case SIDNFS_GROUP:
0243 smb_copy_sid(ssid, &sid_unix_NFS_groups);
0244 break;
0245 case SIDNFS_MODE:
0246 smb_copy_sid(ssid, &sid_unix_NFS_mode);
0247 break;
0248 default:
0249 return;
0250 }
0251
0252
0253 ssid->sub_auth[ssid->num_subauth] = cpu_to_le32(cid);
0254 ssid->num_subauth++;
0255 }
0256
0257 static int sid_to_id(struct user_namespace *user_ns,
0258 struct smb_sid *psid, uint sidtype,
0259 struct smb_fattr *fattr)
0260 {
0261 int rc = -EINVAL;
0262
0263
0264
0265
0266
0267 if (unlikely(psid->num_subauth > SID_MAX_SUB_AUTHORITIES)) {
0268 pr_err("%s: %u subauthorities is too many!\n",
0269 __func__, psid->num_subauth);
0270 return -EIO;
0271 }
0272
0273 if (sidtype == SIDOWNER) {
0274 kuid_t uid;
0275 uid_t id;
0276
0277 id = le32_to_cpu(psid->sub_auth[psid->num_subauth - 1]);
0278 uid = mapped_kuid_user(user_ns, &init_user_ns, KUIDT_INIT(id));
0279 if (uid_valid(uid)) {
0280 fattr->cf_uid = uid;
0281 rc = 0;
0282 }
0283 } else {
0284 kgid_t gid;
0285 gid_t id;
0286
0287 id = le32_to_cpu(psid->sub_auth[psid->num_subauth - 1]);
0288 gid = mapped_kgid_user(user_ns, &init_user_ns, KGIDT_INIT(id));
0289 if (gid_valid(gid)) {
0290 fattr->cf_gid = gid;
0291 rc = 0;
0292 }
0293 }
0294
0295 return rc;
0296 }
0297
0298 void posix_state_to_acl(struct posix_acl_state *state,
0299 struct posix_acl_entry *pace)
0300 {
0301 int i;
0302
0303 pace->e_tag = ACL_USER_OBJ;
0304 pace->e_perm = state->owner.allow;
0305 for (i = 0; i < state->users->n; i++) {
0306 pace++;
0307 pace->e_tag = ACL_USER;
0308 pace->e_uid = state->users->aces[i].uid;
0309 pace->e_perm = state->users->aces[i].perms.allow;
0310 }
0311
0312 pace++;
0313 pace->e_tag = ACL_GROUP_OBJ;
0314 pace->e_perm = state->group.allow;
0315
0316 for (i = 0; i < state->groups->n; i++) {
0317 pace++;
0318 pace->e_tag = ACL_GROUP;
0319 pace->e_gid = state->groups->aces[i].gid;
0320 pace->e_perm = state->groups->aces[i].perms.allow;
0321 }
0322
0323 if (state->users->n || state->groups->n) {
0324 pace++;
0325 pace->e_tag = ACL_MASK;
0326 pace->e_perm = state->mask.allow;
0327 }
0328
0329 pace++;
0330 pace->e_tag = ACL_OTHER;
0331 pace->e_perm = state->other.allow;
0332 }
0333
0334 int init_acl_state(struct posix_acl_state *state, int cnt)
0335 {
0336 int alloc;
0337
0338 memset(state, 0, sizeof(struct posix_acl_state));
0339
0340
0341
0342
0343
0344 alloc = sizeof(struct posix_ace_state_array)
0345 + cnt * sizeof(struct posix_user_ace_state);
0346 state->users = kzalloc(alloc, GFP_KERNEL);
0347 if (!state->users)
0348 return -ENOMEM;
0349 state->groups = kzalloc(alloc, GFP_KERNEL);
0350 if (!state->groups) {
0351 kfree(state->users);
0352 return -ENOMEM;
0353 }
0354 return 0;
0355 }
0356
0357 void free_acl_state(struct posix_acl_state *state)
0358 {
0359 kfree(state->users);
0360 kfree(state->groups);
0361 }
0362
0363 static void parse_dacl(struct user_namespace *user_ns,
0364 struct smb_acl *pdacl, char *end_of_acl,
0365 struct smb_sid *pownersid, struct smb_sid *pgrpsid,
0366 struct smb_fattr *fattr)
0367 {
0368 int i, ret;
0369 int num_aces = 0;
0370 unsigned int acl_size;
0371 char *acl_base;
0372 struct smb_ace **ppace;
0373 struct posix_acl_entry *cf_pace, *cf_pdace;
0374 struct posix_acl_state acl_state, default_acl_state;
0375 umode_t mode = 0, acl_mode;
0376 bool owner_found = false, group_found = false, others_found = false;
0377
0378 if (!pdacl)
0379 return;
0380
0381
0382 if (end_of_acl < (char *)pdacl + sizeof(struct smb_acl) ||
0383 end_of_acl < (char *)pdacl + le16_to_cpu(pdacl->size)) {
0384 pr_err("ACL too small to parse DACL\n");
0385 return;
0386 }
0387
0388 ksmbd_debug(SMB, "DACL revision %d size %d num aces %d\n",
0389 le16_to_cpu(pdacl->revision), le16_to_cpu(pdacl->size),
0390 le32_to_cpu(pdacl->num_aces));
0391
0392 acl_base = (char *)pdacl;
0393 acl_size = sizeof(struct smb_acl);
0394
0395 num_aces = le32_to_cpu(pdacl->num_aces);
0396 if (num_aces <= 0)
0397 return;
0398
0399 if (num_aces > ULONG_MAX / sizeof(struct smb_ace *))
0400 return;
0401
0402 ppace = kmalloc_array(num_aces, sizeof(struct smb_ace *), GFP_KERNEL);
0403 if (!ppace)
0404 return;
0405
0406 ret = init_acl_state(&acl_state, num_aces);
0407 if (ret)
0408 return;
0409 ret = init_acl_state(&default_acl_state, num_aces);
0410 if (ret) {
0411 free_acl_state(&acl_state);
0412 return;
0413 }
0414
0415
0416
0417
0418
0419
0420 for (i = 0; i < num_aces; ++i) {
0421 if (end_of_acl - acl_base < acl_size)
0422 break;
0423
0424 ppace[i] = (struct smb_ace *)(acl_base + acl_size);
0425 acl_base = (char *)ppace[i];
0426 acl_size = offsetof(struct smb_ace, sid) +
0427 offsetof(struct smb_sid, sub_auth);
0428
0429 if (end_of_acl - acl_base < acl_size ||
0430 ppace[i]->sid.num_subauth > SID_MAX_SUB_AUTHORITIES ||
0431 (end_of_acl - acl_base <
0432 acl_size + sizeof(__le32) * ppace[i]->sid.num_subauth) ||
0433 (le16_to_cpu(ppace[i]->size) <
0434 acl_size + sizeof(__le32) * ppace[i]->sid.num_subauth))
0435 break;
0436
0437 acl_size = le16_to_cpu(ppace[i]->size);
0438 ppace[i]->access_req =
0439 smb_map_generic_desired_access(ppace[i]->access_req);
0440
0441 if (!(compare_sids(&ppace[i]->sid, &sid_unix_NFS_mode))) {
0442 fattr->cf_mode =
0443 le32_to_cpu(ppace[i]->sid.sub_auth[2]);
0444 break;
0445 } else if (!compare_sids(&ppace[i]->sid, pownersid)) {
0446 acl_mode = access_flags_to_mode(fattr,
0447 ppace[i]->access_req,
0448 ppace[i]->type);
0449 acl_mode &= 0700;
0450
0451 if (!owner_found) {
0452 mode &= ~(0700);
0453 mode |= acl_mode;
0454 }
0455 owner_found = true;
0456 } else if (!compare_sids(&ppace[i]->sid, pgrpsid) ||
0457 ppace[i]->sid.sub_auth[ppace[i]->sid.num_subauth - 1] ==
0458 DOMAIN_USER_RID_LE) {
0459 acl_mode = access_flags_to_mode(fattr,
0460 ppace[i]->access_req,
0461 ppace[i]->type);
0462 acl_mode &= 0070;
0463 if (!group_found) {
0464 mode &= ~(0070);
0465 mode |= acl_mode;
0466 }
0467 group_found = true;
0468 } else if (!compare_sids(&ppace[i]->sid, &sid_everyone)) {
0469 acl_mode = access_flags_to_mode(fattr,
0470 ppace[i]->access_req,
0471 ppace[i]->type);
0472 acl_mode &= 0007;
0473 if (!others_found) {
0474 mode &= ~(0007);
0475 mode |= acl_mode;
0476 }
0477 others_found = true;
0478 } else if (!compare_sids(&ppace[i]->sid, &creator_owner)) {
0479 continue;
0480 } else if (!compare_sids(&ppace[i]->sid, &creator_group)) {
0481 continue;
0482 } else if (!compare_sids(&ppace[i]->sid, &sid_authusers)) {
0483 continue;
0484 } else {
0485 struct smb_fattr temp_fattr;
0486
0487 acl_mode = access_flags_to_mode(fattr, ppace[i]->access_req,
0488 ppace[i]->type);
0489 temp_fattr.cf_uid = INVALID_UID;
0490 ret = sid_to_id(user_ns, &ppace[i]->sid, SIDOWNER, &temp_fattr);
0491 if (ret || uid_eq(temp_fattr.cf_uid, INVALID_UID)) {
0492 pr_err("%s: Error %d mapping Owner SID to uid\n",
0493 __func__, ret);
0494 continue;
0495 }
0496
0497 acl_state.owner.allow = ((acl_mode & 0700) >> 6) | 0004;
0498 acl_state.users->aces[acl_state.users->n].uid =
0499 temp_fattr.cf_uid;
0500 acl_state.users->aces[acl_state.users->n++].perms.allow =
0501 ((acl_mode & 0700) >> 6) | 0004;
0502 default_acl_state.owner.allow = ((acl_mode & 0700) >> 6) | 0004;
0503 default_acl_state.users->aces[default_acl_state.users->n].uid =
0504 temp_fattr.cf_uid;
0505 default_acl_state.users->aces[default_acl_state.users->n++].perms.allow =
0506 ((acl_mode & 0700) >> 6) | 0004;
0507 }
0508 }
0509 kfree(ppace);
0510
0511 if (owner_found) {
0512
0513 acl_state.owner.allow = ((mode & 0700) >> 6) | 0004;
0514 acl_state.users->aces[acl_state.users->n].uid = fattr->cf_uid;
0515 acl_state.users->aces[acl_state.users->n++].perms.allow =
0516 ((mode & 0700) >> 6) | 0004;
0517 default_acl_state.owner.allow = ((mode & 0700) >> 6) | 0004;
0518 default_acl_state.users->aces[default_acl_state.users->n].uid =
0519 fattr->cf_uid;
0520 default_acl_state.users->aces[default_acl_state.users->n++].perms.allow =
0521 ((mode & 0700) >> 6) | 0004;
0522 }
0523
0524 if (group_found) {
0525 acl_state.group.allow = (mode & 0070) >> 3;
0526 acl_state.groups->aces[acl_state.groups->n].gid =
0527 fattr->cf_gid;
0528 acl_state.groups->aces[acl_state.groups->n++].perms.allow =
0529 (mode & 0070) >> 3;
0530 default_acl_state.group.allow = (mode & 0070) >> 3;
0531 default_acl_state.groups->aces[default_acl_state.groups->n].gid =
0532 fattr->cf_gid;
0533 default_acl_state.groups->aces[default_acl_state.groups->n++].perms.allow =
0534 (mode & 0070) >> 3;
0535 }
0536
0537 if (others_found) {
0538 fattr->cf_mode &= ~(0007);
0539 fattr->cf_mode |= mode & 0007;
0540
0541 acl_state.other.allow = mode & 0007;
0542 default_acl_state.other.allow = mode & 0007;
0543 }
0544
0545 if (acl_state.users->n || acl_state.groups->n) {
0546 acl_state.mask.allow = 0x07;
0547
0548 if (IS_ENABLED(CONFIG_FS_POSIX_ACL)) {
0549 fattr->cf_acls =
0550 posix_acl_alloc(acl_state.users->n +
0551 acl_state.groups->n + 4, GFP_KERNEL);
0552 if (fattr->cf_acls) {
0553 cf_pace = fattr->cf_acls->a_entries;
0554 posix_state_to_acl(&acl_state, cf_pace);
0555 }
0556 }
0557 }
0558
0559 if (default_acl_state.users->n || default_acl_state.groups->n) {
0560 default_acl_state.mask.allow = 0x07;
0561
0562 if (IS_ENABLED(CONFIG_FS_POSIX_ACL)) {
0563 fattr->cf_dacls =
0564 posix_acl_alloc(default_acl_state.users->n +
0565 default_acl_state.groups->n + 4, GFP_KERNEL);
0566 if (fattr->cf_dacls) {
0567 cf_pdace = fattr->cf_dacls->a_entries;
0568 posix_state_to_acl(&default_acl_state, cf_pdace);
0569 }
0570 }
0571 }
0572 free_acl_state(&acl_state);
0573 free_acl_state(&default_acl_state);
0574 }
0575
0576 static void set_posix_acl_entries_dacl(struct user_namespace *user_ns,
0577 struct smb_ace *pndace,
0578 struct smb_fattr *fattr, u32 *num_aces,
0579 u16 *size, u32 nt_aces_num)
0580 {
0581 struct posix_acl_entry *pace;
0582 struct smb_sid *sid;
0583 struct smb_ace *ntace;
0584 int i, j;
0585
0586 if (!fattr->cf_acls)
0587 goto posix_default_acl;
0588
0589 pace = fattr->cf_acls->a_entries;
0590 for (i = 0; i < fattr->cf_acls->a_count; i++, pace++) {
0591 int flags = 0;
0592
0593 sid = kmalloc(sizeof(struct smb_sid), GFP_KERNEL);
0594 if (!sid)
0595 break;
0596
0597 if (pace->e_tag == ACL_USER) {
0598 uid_t uid;
0599 unsigned int sid_type = SIDOWNER;
0600
0601 uid = posix_acl_uid_translate(user_ns, pace);
0602 if (!uid)
0603 sid_type = SIDUNIX_USER;
0604 id_to_sid(uid, sid_type, sid);
0605 } else if (pace->e_tag == ACL_GROUP) {
0606 gid_t gid;
0607
0608 gid = posix_acl_gid_translate(user_ns, pace);
0609 id_to_sid(gid, SIDUNIX_GROUP, sid);
0610 } else if (pace->e_tag == ACL_OTHER && !nt_aces_num) {
0611 smb_copy_sid(sid, &sid_everyone);
0612 } else {
0613 kfree(sid);
0614 continue;
0615 }
0616 ntace = pndace;
0617 for (j = 0; j < nt_aces_num; j++) {
0618 if (ntace->sid.sub_auth[ntace->sid.num_subauth - 1] ==
0619 sid->sub_auth[sid->num_subauth - 1])
0620 goto pass_same_sid;
0621 ntace = (struct smb_ace *)((char *)ntace +
0622 le16_to_cpu(ntace->size));
0623 }
0624
0625 if (S_ISDIR(fattr->cf_mode) && pace->e_tag == ACL_OTHER)
0626 flags = 0x03;
0627
0628 ntace = (struct smb_ace *)((char *)pndace + *size);
0629 *size += fill_ace_for_sid(ntace, sid, ACCESS_ALLOWED, flags,
0630 pace->e_perm, 0777);
0631 (*num_aces)++;
0632 if (pace->e_tag == ACL_USER)
0633 ntace->access_req |=
0634 FILE_DELETE_LE | FILE_DELETE_CHILD_LE;
0635
0636 if (S_ISDIR(fattr->cf_mode) &&
0637 (pace->e_tag == ACL_USER || pace->e_tag == ACL_GROUP)) {
0638 ntace = (struct smb_ace *)((char *)pndace + *size);
0639 *size += fill_ace_for_sid(ntace, sid, ACCESS_ALLOWED,
0640 0x03, pace->e_perm, 0777);
0641 (*num_aces)++;
0642 if (pace->e_tag == ACL_USER)
0643 ntace->access_req |=
0644 FILE_DELETE_LE | FILE_DELETE_CHILD_LE;
0645 }
0646
0647 pass_same_sid:
0648 kfree(sid);
0649 }
0650
0651 if (nt_aces_num)
0652 return;
0653
0654 posix_default_acl:
0655 if (!fattr->cf_dacls)
0656 return;
0657
0658 pace = fattr->cf_dacls->a_entries;
0659 for (i = 0; i < fattr->cf_dacls->a_count; i++, pace++) {
0660 sid = kmalloc(sizeof(struct smb_sid), GFP_KERNEL);
0661 if (!sid)
0662 break;
0663
0664 if (pace->e_tag == ACL_USER) {
0665 uid_t uid;
0666
0667 uid = posix_acl_uid_translate(user_ns, pace);
0668 id_to_sid(uid, SIDCREATOR_OWNER, sid);
0669 } else if (pace->e_tag == ACL_GROUP) {
0670 gid_t gid;
0671
0672 gid = posix_acl_gid_translate(user_ns, pace);
0673 id_to_sid(gid, SIDCREATOR_GROUP, sid);
0674 } else {
0675 kfree(sid);
0676 continue;
0677 }
0678
0679 ntace = (struct smb_ace *)((char *)pndace + *size);
0680 *size += fill_ace_for_sid(ntace, sid, ACCESS_ALLOWED, 0x0b,
0681 pace->e_perm, 0777);
0682 (*num_aces)++;
0683 if (pace->e_tag == ACL_USER)
0684 ntace->access_req |=
0685 FILE_DELETE_LE | FILE_DELETE_CHILD_LE;
0686 kfree(sid);
0687 }
0688 }
0689
0690 static void set_ntacl_dacl(struct user_namespace *user_ns,
0691 struct smb_acl *pndacl,
0692 struct smb_acl *nt_dacl,
0693 unsigned int aces_size,
0694 const struct smb_sid *pownersid,
0695 const struct smb_sid *pgrpsid,
0696 struct smb_fattr *fattr)
0697 {
0698 struct smb_ace *ntace, *pndace;
0699 int nt_num_aces = le32_to_cpu(nt_dacl->num_aces), num_aces = 0;
0700 unsigned short size = 0;
0701 int i;
0702
0703 pndace = (struct smb_ace *)((char *)pndacl + sizeof(struct smb_acl));
0704 if (nt_num_aces) {
0705 ntace = (struct smb_ace *)((char *)nt_dacl + sizeof(struct smb_acl));
0706 for (i = 0; i < nt_num_aces; i++) {
0707 unsigned short nt_ace_size;
0708
0709 if (offsetof(struct smb_ace, access_req) > aces_size)
0710 break;
0711
0712 nt_ace_size = le16_to_cpu(ntace->size);
0713 if (nt_ace_size > aces_size)
0714 break;
0715
0716 memcpy((char *)pndace + size, ntace, nt_ace_size);
0717 size += nt_ace_size;
0718 aces_size -= nt_ace_size;
0719 ntace = (struct smb_ace *)((char *)ntace + nt_ace_size);
0720 num_aces++;
0721 }
0722 }
0723
0724 set_posix_acl_entries_dacl(user_ns, pndace, fattr,
0725 &num_aces, &size, nt_num_aces);
0726 pndacl->num_aces = cpu_to_le32(num_aces);
0727 pndacl->size = cpu_to_le16(le16_to_cpu(pndacl->size) + size);
0728 }
0729
0730 static void set_mode_dacl(struct user_namespace *user_ns,
0731 struct smb_acl *pndacl, struct smb_fattr *fattr)
0732 {
0733 struct smb_ace *pace, *pndace;
0734 u32 num_aces = 0;
0735 u16 size = 0, ace_size = 0;
0736 uid_t uid;
0737 const struct smb_sid *sid;
0738
0739 pace = pndace = (struct smb_ace *)((char *)pndacl + sizeof(struct smb_acl));
0740
0741 if (fattr->cf_acls) {
0742 set_posix_acl_entries_dacl(user_ns, pndace, fattr,
0743 &num_aces, &size, num_aces);
0744 goto out;
0745 }
0746
0747
0748 uid = from_kuid(&init_user_ns, fattr->cf_uid);
0749 if (uid)
0750 sid = &server_conf.domain_sid;
0751 else
0752 sid = &sid_unix_users;
0753 ace_size = fill_ace_for_sid(pace, sid, ACCESS_ALLOWED, 0,
0754 fattr->cf_mode, 0700);
0755 pace->sid.sub_auth[pace->sid.num_subauth++] = cpu_to_le32(uid);
0756 pace->size = cpu_to_le16(ace_size + 4);
0757 size += le16_to_cpu(pace->size);
0758 pace = (struct smb_ace *)((char *)pndace + size);
0759
0760
0761 ace_size = fill_ace_for_sid(pace, &sid_unix_groups,
0762 ACCESS_ALLOWED, 0, fattr->cf_mode, 0070);
0763 pace->sid.sub_auth[pace->sid.num_subauth++] =
0764 cpu_to_le32(from_kgid(&init_user_ns, fattr->cf_gid));
0765 pace->size = cpu_to_le16(ace_size + 4);
0766 size += le16_to_cpu(pace->size);
0767 pace = (struct smb_ace *)((char *)pndace + size);
0768 num_aces = 3;
0769
0770 if (S_ISDIR(fattr->cf_mode)) {
0771 pace = (struct smb_ace *)((char *)pndace + size);
0772
0773
0774 size += fill_ace_for_sid(pace, &creator_owner, ACCESS_ALLOWED,
0775 0x0b, fattr->cf_mode, 0700);
0776 pace = (struct smb_ace *)((char *)pndace + size);
0777
0778
0779 size += fill_ace_for_sid(pace, &creator_group, ACCESS_ALLOWED,
0780 0x0b, fattr->cf_mode, 0070);
0781 pace = (struct smb_ace *)((char *)pndace + size);
0782 num_aces = 5;
0783 }
0784
0785
0786 size += fill_ace_for_sid(pace, &sid_everyone, ACCESS_ALLOWED, 0,
0787 fattr->cf_mode, 0007);
0788
0789 out:
0790 pndacl->num_aces = cpu_to_le32(num_aces);
0791 pndacl->size = cpu_to_le16(le16_to_cpu(pndacl->size) + size);
0792 }
0793
0794 static int parse_sid(struct smb_sid *psid, char *end_of_acl)
0795 {
0796
0797
0798
0799
0800 if (end_of_acl < (char *)psid + 8) {
0801 pr_err("ACL too small to parse SID %p\n", psid);
0802 return -EINVAL;
0803 }
0804
0805 return 0;
0806 }
0807
0808
0809 int parse_sec_desc(struct user_namespace *user_ns, struct smb_ntsd *pntsd,
0810 int acl_len, struct smb_fattr *fattr)
0811 {
0812 int rc = 0;
0813 struct smb_sid *owner_sid_ptr, *group_sid_ptr;
0814 struct smb_acl *dacl_ptr;
0815 char *end_of_acl = ((char *)pntsd) + acl_len;
0816 __u32 dacloffset;
0817 int pntsd_type;
0818
0819 if (!pntsd)
0820 return -EIO;
0821
0822 if (acl_len < sizeof(struct smb_ntsd))
0823 return -EINVAL;
0824
0825 owner_sid_ptr = (struct smb_sid *)((char *)pntsd +
0826 le32_to_cpu(pntsd->osidoffset));
0827 group_sid_ptr = (struct smb_sid *)((char *)pntsd +
0828 le32_to_cpu(pntsd->gsidoffset));
0829 dacloffset = le32_to_cpu(pntsd->dacloffset);
0830 dacl_ptr = (struct smb_acl *)((char *)pntsd + dacloffset);
0831 ksmbd_debug(SMB,
0832 "revision %d type 0x%x ooffset 0x%x goffset 0x%x sacloffset 0x%x dacloffset 0x%x\n",
0833 pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset),
0834 le32_to_cpu(pntsd->gsidoffset),
0835 le32_to_cpu(pntsd->sacloffset), dacloffset);
0836
0837 pntsd_type = le16_to_cpu(pntsd->type);
0838 if (!(pntsd_type & DACL_PRESENT)) {
0839 ksmbd_debug(SMB, "DACL_PRESENT in DACL type is not set\n");
0840 return rc;
0841 }
0842
0843 pntsd->type = cpu_to_le16(DACL_PRESENT);
0844
0845 if (pntsd->osidoffset) {
0846 rc = parse_sid(owner_sid_ptr, end_of_acl);
0847 if (rc) {
0848 pr_err("%s: Error %d parsing Owner SID\n", __func__, rc);
0849 return rc;
0850 }
0851
0852 rc = sid_to_id(user_ns, owner_sid_ptr, SIDOWNER, fattr);
0853 if (rc) {
0854 pr_err("%s: Error %d mapping Owner SID to uid\n",
0855 __func__, rc);
0856 owner_sid_ptr = NULL;
0857 }
0858 }
0859
0860 if (pntsd->gsidoffset) {
0861 rc = parse_sid(group_sid_ptr, end_of_acl);
0862 if (rc) {
0863 pr_err("%s: Error %d mapping Owner SID to gid\n",
0864 __func__, rc);
0865 return rc;
0866 }
0867 rc = sid_to_id(user_ns, group_sid_ptr, SIDUNIX_GROUP, fattr);
0868 if (rc) {
0869 pr_err("%s: Error %d mapping Group SID to gid\n",
0870 __func__, rc);
0871 group_sid_ptr = NULL;
0872 }
0873 }
0874
0875 if ((pntsd_type & (DACL_AUTO_INHERITED | DACL_AUTO_INHERIT_REQ)) ==
0876 (DACL_AUTO_INHERITED | DACL_AUTO_INHERIT_REQ))
0877 pntsd->type |= cpu_to_le16(DACL_AUTO_INHERITED);
0878 if (pntsd_type & DACL_PROTECTED)
0879 pntsd->type |= cpu_to_le16(DACL_PROTECTED);
0880
0881 if (dacloffset) {
0882 parse_dacl(user_ns, dacl_ptr, end_of_acl,
0883 owner_sid_ptr, group_sid_ptr, fattr);
0884 }
0885
0886 return 0;
0887 }
0888
0889
0890 int build_sec_desc(struct user_namespace *user_ns,
0891 struct smb_ntsd *pntsd, struct smb_ntsd *ppntsd,
0892 int ppntsd_size, int addition_info, __u32 *secdesclen,
0893 struct smb_fattr *fattr)
0894 {
0895 int rc = 0;
0896 __u32 offset;
0897 struct smb_sid *owner_sid_ptr, *group_sid_ptr;
0898 struct smb_sid *nowner_sid_ptr, *ngroup_sid_ptr;
0899 struct smb_acl *dacl_ptr = NULL;
0900 uid_t uid;
0901 gid_t gid;
0902 unsigned int sid_type = SIDOWNER;
0903
0904 nowner_sid_ptr = kmalloc(sizeof(struct smb_sid), GFP_KERNEL);
0905 if (!nowner_sid_ptr)
0906 return -ENOMEM;
0907
0908 uid = from_kuid(&init_user_ns, fattr->cf_uid);
0909 if (!uid)
0910 sid_type = SIDUNIX_USER;
0911 id_to_sid(uid, sid_type, nowner_sid_ptr);
0912
0913 ngroup_sid_ptr = kmalloc(sizeof(struct smb_sid), GFP_KERNEL);
0914 if (!ngroup_sid_ptr) {
0915 kfree(nowner_sid_ptr);
0916 return -ENOMEM;
0917 }
0918
0919 gid = from_kgid(&init_user_ns, fattr->cf_gid);
0920 id_to_sid(gid, SIDUNIX_GROUP, ngroup_sid_ptr);
0921
0922 offset = sizeof(struct smb_ntsd);
0923 pntsd->sacloffset = 0;
0924 pntsd->revision = cpu_to_le16(1);
0925 pntsd->type = cpu_to_le16(SELF_RELATIVE);
0926 if (ppntsd)
0927 pntsd->type |= ppntsd->type;
0928
0929 if (addition_info & OWNER_SECINFO) {
0930 pntsd->osidoffset = cpu_to_le32(offset);
0931 owner_sid_ptr = (struct smb_sid *)((char *)pntsd + offset);
0932 smb_copy_sid(owner_sid_ptr, nowner_sid_ptr);
0933 offset += 1 + 1 + 6 + (nowner_sid_ptr->num_subauth * 4);
0934 }
0935
0936 if (addition_info & GROUP_SECINFO) {
0937 pntsd->gsidoffset = cpu_to_le32(offset);
0938 group_sid_ptr = (struct smb_sid *)((char *)pntsd + offset);
0939 smb_copy_sid(group_sid_ptr, ngroup_sid_ptr);
0940 offset += 1 + 1 + 6 + (ngroup_sid_ptr->num_subauth * 4);
0941 }
0942
0943 if (addition_info & DACL_SECINFO) {
0944 pntsd->type |= cpu_to_le16(DACL_PRESENT);
0945 dacl_ptr = (struct smb_acl *)((char *)pntsd + offset);
0946 dacl_ptr->revision = cpu_to_le16(2);
0947 dacl_ptr->size = cpu_to_le16(sizeof(struct smb_acl));
0948 dacl_ptr->num_aces = 0;
0949
0950 if (!ppntsd) {
0951 set_mode_dacl(user_ns, dacl_ptr, fattr);
0952 } else {
0953 struct smb_acl *ppdacl_ptr;
0954 unsigned int dacl_offset = le32_to_cpu(ppntsd->dacloffset);
0955 int ppdacl_size, ntacl_size = ppntsd_size - dacl_offset;
0956
0957 if (!dacl_offset ||
0958 (dacl_offset + sizeof(struct smb_acl) > ppntsd_size))
0959 goto out;
0960
0961 ppdacl_ptr = (struct smb_acl *)((char *)ppntsd + dacl_offset);
0962 ppdacl_size = le16_to_cpu(ppdacl_ptr->size);
0963 if (ppdacl_size > ntacl_size ||
0964 ppdacl_size < sizeof(struct smb_acl))
0965 goto out;
0966
0967 set_ntacl_dacl(user_ns, dacl_ptr, ppdacl_ptr,
0968 ntacl_size - sizeof(struct smb_acl),
0969 nowner_sid_ptr, ngroup_sid_ptr,
0970 fattr);
0971 }
0972 pntsd->dacloffset = cpu_to_le32(offset);
0973 offset += le16_to_cpu(dacl_ptr->size);
0974 }
0975
0976 out:
0977 kfree(nowner_sid_ptr);
0978 kfree(ngroup_sid_ptr);
0979 *secdesclen = offset;
0980 return rc;
0981 }
0982
0983 static void smb_set_ace(struct smb_ace *ace, const struct smb_sid *sid, u8 type,
0984 u8 flags, __le32 access_req)
0985 {
0986 ace->type = type;
0987 ace->flags = flags;
0988 ace->access_req = access_req;
0989 smb_copy_sid(&ace->sid, sid);
0990 ace->size = cpu_to_le16(1 + 1 + 2 + 4 + 1 + 1 + 6 + (sid->num_subauth * 4));
0991 }
0992
0993 int smb_inherit_dacl(struct ksmbd_conn *conn,
0994 struct path *path,
0995 unsigned int uid, unsigned int gid)
0996 {
0997 const struct smb_sid *psid, *creator = NULL;
0998 struct smb_ace *parent_aces, *aces;
0999 struct smb_acl *parent_pdacl;
1000 struct smb_ntsd *parent_pntsd = NULL;
1001 struct smb_sid owner_sid, group_sid;
1002 struct dentry *parent = path->dentry->d_parent;
1003 struct user_namespace *user_ns = mnt_user_ns(path->mnt);
1004 int inherited_flags = 0, flags = 0, i, ace_cnt = 0, nt_size = 0, pdacl_size;
1005 int rc = 0, num_aces, dacloffset, pntsd_type, pntsd_size, acl_len, aces_size;
1006 char *aces_base;
1007 bool is_dir = S_ISDIR(d_inode(path->dentry)->i_mode);
1008
1009 pntsd_size = ksmbd_vfs_get_sd_xattr(conn, user_ns,
1010 parent, &parent_pntsd);
1011 if (pntsd_size <= 0)
1012 return -ENOENT;
1013 dacloffset = le32_to_cpu(parent_pntsd->dacloffset);
1014 if (!dacloffset || (dacloffset + sizeof(struct smb_acl) > pntsd_size)) {
1015 rc = -EINVAL;
1016 goto free_parent_pntsd;
1017 }
1018
1019 parent_pdacl = (struct smb_acl *)((char *)parent_pntsd + dacloffset);
1020 acl_len = pntsd_size - dacloffset;
1021 num_aces = le32_to_cpu(parent_pdacl->num_aces);
1022 pntsd_type = le16_to_cpu(parent_pntsd->type);
1023 pdacl_size = le16_to_cpu(parent_pdacl->size);
1024
1025 if (pdacl_size > acl_len || pdacl_size < sizeof(struct smb_acl)) {
1026 rc = -EINVAL;
1027 goto free_parent_pntsd;
1028 }
1029
1030 aces_base = kmalloc(sizeof(struct smb_ace) * num_aces * 2, GFP_KERNEL);
1031 if (!aces_base) {
1032 rc = -ENOMEM;
1033 goto free_parent_pntsd;
1034 }
1035
1036 aces = (struct smb_ace *)aces_base;
1037 parent_aces = (struct smb_ace *)((char *)parent_pdacl +
1038 sizeof(struct smb_acl));
1039 aces_size = acl_len - sizeof(struct smb_acl);
1040
1041 if (pntsd_type & DACL_AUTO_INHERITED)
1042 inherited_flags = INHERITED_ACE;
1043
1044 for (i = 0; i < num_aces; i++) {
1045 int pace_size;
1046
1047 if (offsetof(struct smb_ace, access_req) > aces_size)
1048 break;
1049
1050 pace_size = le16_to_cpu(parent_aces->size);
1051 if (pace_size > aces_size)
1052 break;
1053
1054 aces_size -= pace_size;
1055
1056 flags = parent_aces->flags;
1057 if (!smb_inherit_flags(flags, is_dir))
1058 goto pass;
1059 if (is_dir) {
1060 flags &= ~(INHERIT_ONLY_ACE | INHERITED_ACE);
1061 if (!(flags & CONTAINER_INHERIT_ACE))
1062 flags |= INHERIT_ONLY_ACE;
1063 if (flags & NO_PROPAGATE_INHERIT_ACE)
1064 flags = 0;
1065 } else {
1066 flags = 0;
1067 }
1068
1069 if (!compare_sids(&creator_owner, &parent_aces->sid)) {
1070 creator = &creator_owner;
1071 id_to_sid(uid, SIDOWNER, &owner_sid);
1072 psid = &owner_sid;
1073 } else if (!compare_sids(&creator_group, &parent_aces->sid)) {
1074 creator = &creator_group;
1075 id_to_sid(gid, SIDUNIX_GROUP, &group_sid);
1076 psid = &group_sid;
1077 } else {
1078 creator = NULL;
1079 psid = &parent_aces->sid;
1080 }
1081
1082 if (is_dir && creator && flags & CONTAINER_INHERIT_ACE) {
1083 smb_set_ace(aces, psid, parent_aces->type, inherited_flags,
1084 parent_aces->access_req);
1085 nt_size += le16_to_cpu(aces->size);
1086 ace_cnt++;
1087 aces = (struct smb_ace *)((char *)aces + le16_to_cpu(aces->size));
1088 flags |= INHERIT_ONLY_ACE;
1089 psid = creator;
1090 } else if (is_dir && !(parent_aces->flags & NO_PROPAGATE_INHERIT_ACE)) {
1091 psid = &parent_aces->sid;
1092 }
1093
1094 smb_set_ace(aces, psid, parent_aces->type, flags | inherited_flags,
1095 parent_aces->access_req);
1096 nt_size += le16_to_cpu(aces->size);
1097 aces = (struct smb_ace *)((char *)aces + le16_to_cpu(aces->size));
1098 ace_cnt++;
1099 pass:
1100 parent_aces = (struct smb_ace *)((char *)parent_aces + pace_size);
1101 }
1102
1103 if (nt_size > 0) {
1104 struct smb_ntsd *pntsd;
1105 struct smb_acl *pdacl;
1106 struct smb_sid *powner_sid = NULL, *pgroup_sid = NULL;
1107 int powner_sid_size = 0, pgroup_sid_size = 0, pntsd_size;
1108
1109 if (parent_pntsd->osidoffset) {
1110 powner_sid = (struct smb_sid *)((char *)parent_pntsd +
1111 le32_to_cpu(parent_pntsd->osidoffset));
1112 powner_sid_size = 1 + 1 + 6 + (powner_sid->num_subauth * 4);
1113 }
1114 if (parent_pntsd->gsidoffset) {
1115 pgroup_sid = (struct smb_sid *)((char *)parent_pntsd +
1116 le32_to_cpu(parent_pntsd->gsidoffset));
1117 pgroup_sid_size = 1 + 1 + 6 + (pgroup_sid->num_subauth * 4);
1118 }
1119
1120 pntsd = kzalloc(sizeof(struct smb_ntsd) + powner_sid_size +
1121 pgroup_sid_size + sizeof(struct smb_acl) +
1122 nt_size, GFP_KERNEL);
1123 if (!pntsd) {
1124 rc = -ENOMEM;
1125 goto free_aces_base;
1126 }
1127
1128 pntsd->revision = cpu_to_le16(1);
1129 pntsd->type = cpu_to_le16(SELF_RELATIVE | DACL_PRESENT);
1130 if (le16_to_cpu(parent_pntsd->type) & DACL_AUTO_INHERITED)
1131 pntsd->type |= cpu_to_le16(DACL_AUTO_INHERITED);
1132 pntsd_size = sizeof(struct smb_ntsd);
1133 pntsd->osidoffset = parent_pntsd->osidoffset;
1134 pntsd->gsidoffset = parent_pntsd->gsidoffset;
1135 pntsd->dacloffset = parent_pntsd->dacloffset;
1136
1137 if (pntsd->osidoffset) {
1138 struct smb_sid *owner_sid = (struct smb_sid *)((char *)pntsd +
1139 le32_to_cpu(pntsd->osidoffset));
1140 memcpy(owner_sid, powner_sid, powner_sid_size);
1141 pntsd_size += powner_sid_size;
1142 }
1143
1144 if (pntsd->gsidoffset) {
1145 struct smb_sid *group_sid = (struct smb_sid *)((char *)pntsd +
1146 le32_to_cpu(pntsd->gsidoffset));
1147 memcpy(group_sid, pgroup_sid, pgroup_sid_size);
1148 pntsd_size += pgroup_sid_size;
1149 }
1150
1151 if (pntsd->dacloffset) {
1152 struct smb_ace *pace;
1153
1154 pdacl = (struct smb_acl *)((char *)pntsd + le32_to_cpu(pntsd->dacloffset));
1155 pdacl->revision = cpu_to_le16(2);
1156 pdacl->size = cpu_to_le16(sizeof(struct smb_acl) + nt_size);
1157 pdacl->num_aces = cpu_to_le32(ace_cnt);
1158 pace = (struct smb_ace *)((char *)pdacl + sizeof(struct smb_acl));
1159 memcpy(pace, aces_base, nt_size);
1160 pntsd_size += sizeof(struct smb_acl) + nt_size;
1161 }
1162
1163 ksmbd_vfs_set_sd_xattr(conn, user_ns,
1164 path->dentry, pntsd, pntsd_size);
1165 kfree(pntsd);
1166 }
1167
1168 free_aces_base:
1169 kfree(aces_base);
1170 free_parent_pntsd:
1171 kfree(parent_pntsd);
1172 return rc;
1173 }
1174
1175 bool smb_inherit_flags(int flags, bool is_dir)
1176 {
1177 if (!is_dir)
1178 return (flags & OBJECT_INHERIT_ACE) != 0;
1179
1180 if (flags & OBJECT_INHERIT_ACE && !(flags & NO_PROPAGATE_INHERIT_ACE))
1181 return true;
1182
1183 if (flags & CONTAINER_INHERIT_ACE)
1184 return true;
1185 return false;
1186 }
1187
1188 int smb_check_perm_dacl(struct ksmbd_conn *conn, struct path *path,
1189 __le32 *pdaccess, int uid)
1190 {
1191 struct user_namespace *user_ns = mnt_user_ns(path->mnt);
1192 struct smb_ntsd *pntsd = NULL;
1193 struct smb_acl *pdacl;
1194 struct posix_acl *posix_acls;
1195 int rc = 0, pntsd_size, acl_size, aces_size, pdacl_size, dacl_offset;
1196 struct smb_sid sid;
1197 int granted = le32_to_cpu(*pdaccess & ~FILE_MAXIMAL_ACCESS_LE);
1198 struct smb_ace *ace;
1199 int i, found = 0;
1200 unsigned int access_bits = 0;
1201 struct smb_ace *others_ace = NULL;
1202 struct posix_acl_entry *pa_entry;
1203 unsigned int sid_type = SIDOWNER;
1204 unsigned short ace_size;
1205
1206 ksmbd_debug(SMB, "check permission using windows acl\n");
1207 pntsd_size = ksmbd_vfs_get_sd_xattr(conn, user_ns,
1208 path->dentry, &pntsd);
1209 if (pntsd_size <= 0 || !pntsd)
1210 goto err_out;
1211
1212 dacl_offset = le32_to_cpu(pntsd->dacloffset);
1213 if (!dacl_offset ||
1214 (dacl_offset + sizeof(struct smb_acl) > pntsd_size))
1215 goto err_out;
1216
1217 pdacl = (struct smb_acl *)((char *)pntsd + le32_to_cpu(pntsd->dacloffset));
1218 acl_size = pntsd_size - dacl_offset;
1219 pdacl_size = le16_to_cpu(pdacl->size);
1220
1221 if (pdacl_size > acl_size || pdacl_size < sizeof(struct smb_acl))
1222 goto err_out;
1223
1224 if (!pdacl->num_aces) {
1225 if (!(pdacl_size - sizeof(struct smb_acl)) &&
1226 *pdaccess & ~(FILE_READ_CONTROL_LE | FILE_WRITE_DAC_LE)) {
1227 rc = -EACCES;
1228 goto err_out;
1229 }
1230 goto err_out;
1231 }
1232
1233 if (*pdaccess & FILE_MAXIMAL_ACCESS_LE) {
1234 granted = READ_CONTROL | WRITE_DAC | FILE_READ_ATTRIBUTES |
1235 DELETE;
1236
1237 ace = (struct smb_ace *)((char *)pdacl + sizeof(struct smb_acl));
1238 aces_size = acl_size - sizeof(struct smb_acl);
1239 for (i = 0; i < le32_to_cpu(pdacl->num_aces); i++) {
1240 if (offsetof(struct smb_ace, access_req) > aces_size)
1241 break;
1242 ace_size = le16_to_cpu(ace->size);
1243 if (ace_size > aces_size)
1244 break;
1245 aces_size -= ace_size;
1246 granted |= le32_to_cpu(ace->access_req);
1247 ace = (struct smb_ace *)((char *)ace + le16_to_cpu(ace->size));
1248 }
1249
1250 if (!pdacl->num_aces)
1251 granted = GENERIC_ALL_FLAGS;
1252 }
1253
1254 if (!uid)
1255 sid_type = SIDUNIX_USER;
1256 id_to_sid(uid, sid_type, &sid);
1257
1258 ace = (struct smb_ace *)((char *)pdacl + sizeof(struct smb_acl));
1259 aces_size = acl_size - sizeof(struct smb_acl);
1260 for (i = 0; i < le32_to_cpu(pdacl->num_aces); i++) {
1261 if (offsetof(struct smb_ace, access_req) > aces_size)
1262 break;
1263 ace_size = le16_to_cpu(ace->size);
1264 if (ace_size > aces_size)
1265 break;
1266 aces_size -= ace_size;
1267
1268 if (!compare_sids(&sid, &ace->sid) ||
1269 !compare_sids(&sid_unix_NFS_mode, &ace->sid)) {
1270 found = 1;
1271 break;
1272 }
1273 if (!compare_sids(&sid_everyone, &ace->sid))
1274 others_ace = ace;
1275
1276 ace = (struct smb_ace *)((char *)ace + le16_to_cpu(ace->size));
1277 }
1278
1279 if (*pdaccess & FILE_MAXIMAL_ACCESS_LE && found) {
1280 granted = READ_CONTROL | WRITE_DAC | FILE_READ_ATTRIBUTES |
1281 DELETE;
1282
1283 granted |= le32_to_cpu(ace->access_req);
1284
1285 if (!pdacl->num_aces)
1286 granted = GENERIC_ALL_FLAGS;
1287 }
1288
1289 if (IS_ENABLED(CONFIG_FS_POSIX_ACL)) {
1290 posix_acls = get_acl(d_inode(path->dentry), ACL_TYPE_ACCESS);
1291 if (posix_acls && !found) {
1292 unsigned int id = -1;
1293
1294 pa_entry = posix_acls->a_entries;
1295 for (i = 0; i < posix_acls->a_count; i++, pa_entry++) {
1296 if (pa_entry->e_tag == ACL_USER)
1297 id = posix_acl_uid_translate(user_ns, pa_entry);
1298 else if (pa_entry->e_tag == ACL_GROUP)
1299 id = posix_acl_gid_translate(user_ns, pa_entry);
1300 else
1301 continue;
1302
1303 if (id == uid) {
1304 mode_to_access_flags(pa_entry->e_perm,
1305 0777,
1306 &access_bits);
1307 if (!access_bits)
1308 access_bits =
1309 SET_MINIMUM_RIGHTS;
1310 posix_acl_release(posix_acls);
1311 goto check_access_bits;
1312 }
1313 }
1314 }
1315 if (posix_acls)
1316 posix_acl_release(posix_acls);
1317 }
1318
1319 if (!found) {
1320 if (others_ace) {
1321 ace = others_ace;
1322 } else {
1323 ksmbd_debug(SMB, "Can't find corresponding sid\n");
1324 rc = -EACCES;
1325 goto err_out;
1326 }
1327 }
1328
1329 switch (ace->type) {
1330 case ACCESS_ALLOWED_ACE_TYPE:
1331 access_bits = le32_to_cpu(ace->access_req);
1332 break;
1333 case ACCESS_DENIED_ACE_TYPE:
1334 case ACCESS_DENIED_CALLBACK_ACE_TYPE:
1335 access_bits = le32_to_cpu(~ace->access_req);
1336 break;
1337 }
1338
1339 check_access_bits:
1340 if (granted &
1341 ~(access_bits | FILE_READ_ATTRIBUTES | READ_CONTROL | WRITE_DAC | DELETE)) {
1342 ksmbd_debug(SMB, "Access denied with winACL, granted : %x, access_req : %x\n",
1343 granted, le32_to_cpu(ace->access_req));
1344 rc = -EACCES;
1345 goto err_out;
1346 }
1347
1348 *pdaccess = cpu_to_le32(granted);
1349 err_out:
1350 kfree(pntsd);
1351 return rc;
1352 }
1353
1354 int set_info_sec(struct ksmbd_conn *conn, struct ksmbd_tree_connect *tcon,
1355 struct path *path, struct smb_ntsd *pntsd, int ntsd_len,
1356 bool type_check)
1357 {
1358 int rc;
1359 struct smb_fattr fattr = {{0}};
1360 struct inode *inode = d_inode(path->dentry);
1361 struct user_namespace *user_ns = mnt_user_ns(path->mnt);
1362 struct iattr newattrs;
1363
1364 fattr.cf_uid = INVALID_UID;
1365 fattr.cf_gid = INVALID_GID;
1366 fattr.cf_mode = inode->i_mode;
1367
1368 rc = parse_sec_desc(user_ns, pntsd, ntsd_len, &fattr);
1369 if (rc)
1370 goto out;
1371
1372 newattrs.ia_valid = ATTR_CTIME;
1373 if (!uid_eq(fattr.cf_uid, INVALID_UID)) {
1374 newattrs.ia_valid |= ATTR_UID;
1375 newattrs.ia_uid = fattr.cf_uid;
1376 }
1377 if (!gid_eq(fattr.cf_gid, INVALID_GID)) {
1378 newattrs.ia_valid |= ATTR_GID;
1379 newattrs.ia_gid = fattr.cf_gid;
1380 }
1381 newattrs.ia_valid |= ATTR_MODE;
1382 newattrs.ia_mode = (inode->i_mode & ~0777) | (fattr.cf_mode & 0777);
1383
1384 ksmbd_vfs_remove_acl_xattrs(user_ns, path->dentry);
1385
1386 if (IS_ENABLED(CONFIG_FS_POSIX_ACL) && fattr.cf_dacls) {
1387 rc = set_posix_acl(user_ns, inode,
1388 ACL_TYPE_ACCESS, fattr.cf_acls);
1389 if (rc < 0)
1390 ksmbd_debug(SMB,
1391 "Set posix acl(ACL_TYPE_ACCESS) failed, rc : %d\n",
1392 rc);
1393 if (S_ISDIR(inode->i_mode) && fattr.cf_dacls) {
1394 rc = set_posix_acl(user_ns, inode,
1395 ACL_TYPE_DEFAULT, fattr.cf_dacls);
1396 if (rc)
1397 ksmbd_debug(SMB,
1398 "Set posix acl(ACL_TYPE_DEFAULT) failed, rc : %d\n",
1399 rc);
1400 }
1401 }
1402
1403 inode_lock(inode);
1404 rc = notify_change(user_ns, path->dentry, &newattrs, NULL);
1405 inode_unlock(inode);
1406 if (rc)
1407 goto out;
1408
1409
1410 if (type_check && !(le16_to_cpu(pntsd->type) & DACL_PRESENT))
1411 goto out;
1412
1413 if (test_share_config_flag(tcon->share_conf, KSMBD_SHARE_FLAG_ACL_XATTR)) {
1414
1415 ksmbd_vfs_remove_sd_xattrs(user_ns, path->dentry);
1416 ksmbd_vfs_set_sd_xattr(conn, user_ns,
1417 path->dentry, pntsd, ntsd_len);
1418 }
1419
1420 out:
1421 posix_acl_release(fattr.cf_acls);
1422 posix_acl_release(fattr.cf_dacls);
1423 mark_inode_dirty(inode);
1424 return rc;
1425 }
1426
1427 void ksmbd_init_domain(u32 *sub_auth)
1428 {
1429 int i;
1430
1431 memcpy(&server_conf.domain_sid, &domain, sizeof(struct smb_sid));
1432 for (i = 0; i < 3; ++i)
1433 server_conf.domain_sid.sub_auth[i + 1] = cpu_to_le32(sub_auth[i]);
1434 }