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