1 // SPDX-License-Identifier: LGPL-2.1 2 /* 3 * 4 * Copyright (c) International Business Machines Corp., 2003, 2007 5 * Author(s): Steve French (sfrench@us.ibm.com) 6 * 7 */ 8 9 #include <linux/fs.h> 10 #include <linux/posix_acl_xattr.h> 11 #include <linux/slab.h> 12 #include <linux/xattr.h> 13 #include "cifsfs.h" 14 #include "cifsglob.h" 15 #include "cifsproto.h" 16 #include "cifs_debug.h" 17 #include "cifs_fs_sb.h" 18 #include "cifs_unicode.h" 19 #include "cifs_ioctl.h" 20 21 #define MAX_EA_VALUE_SIZE CIFSMaxBufSize 22 #define CIFS_XATTR_CIFS_ACL "system.cifs_acl" /* DACL only */ 23 #define CIFS_XATTR_CIFS_NTSD "system.cifs_ntsd" /* owner plus DACL */ 24 #define CIFS_XATTR_CIFS_NTSD_FULL "system.cifs_ntsd_full" /* owner/DACL/SACL */ 25 #define CIFS_XATTR_ATTRIB "cifs.dosattrib" /* full name: user.cifs.dosattrib */ 26 #define CIFS_XATTR_CREATETIME "cifs.creationtime" /* user.cifs.creationtime */ 27 /* 28 * Although these three are just aliases for the above, need to move away from 29 * confusing users and using the 20+ year old term 'cifs' when it is no longer 30 * secure, replaced by SMB2 (then even more highly secure SMB3) many years ago 31 */ 32 #define SMB3_XATTR_CIFS_ACL "system.smb3_acl" /* DACL only */ 33 #define SMB3_XATTR_CIFS_NTSD_SACL "system.smb3_ntsd_sacl" /* SACL only */ 34 #define SMB3_XATTR_CIFS_NTSD_OWNER "system.smb3_ntsd_owner" /* owner only */ 35 #define SMB3_XATTR_CIFS_NTSD "system.smb3_ntsd" /* owner plus DACL */ 36 #define SMB3_XATTR_CIFS_NTSD_FULL "system.smb3_ntsd_full" /* owner/DACL/SACL */ 37 #define SMB3_XATTR_ATTRIB "smb3.dosattrib" /* full name: user.smb3.dosattrib */ 38 #define SMB3_XATTR_CREATETIME "smb3.creationtime" /* user.smb3.creationtime */ 39 /* BB need to add server (Samba e.g) support for security and trusted prefix */ 40 41 enum { XATTR_USER, XATTR_CIFS_ACL, XATTR_ACL_ACCESS, XATTR_ACL_DEFAULT, 42 XATTR_CIFS_NTSD_SACL, XATTR_CIFS_NTSD_OWNER, 43 XATTR_CIFS_NTSD, XATTR_CIFS_NTSD_FULL }; 44 45 static int cifs_attrib_set(unsigned int xid, struct cifs_tcon *pTcon, 46 struct inode *inode, const char *full_path, 47 const void *value, size_t size) 48 { 49 ssize_t rc = -EOPNOTSUPP; 50 __u32 *pattrib = (__u32 *)value; 51 __u32 attrib; 52 FILE_BASIC_INFO info_buf; 53 54 if ((value == NULL) || (size != sizeof(__u32))) 55 return -ERANGE; 56 57 memset(&info_buf, 0, sizeof(info_buf)); 58 attrib = *pattrib; 59 info_buf.Attributes = cpu_to_le32(attrib); 60 if (pTcon->ses->server->ops->set_file_info) 61 rc = pTcon->ses->server->ops->set_file_info(inode, full_path, 62 &info_buf, xid); 63 if (rc == 0) 64 CIFS_I(inode)->cifsAttrs = attrib; 65 66 return rc; 67 } 68 69 static int cifs_creation_time_set(unsigned int xid, struct cifs_tcon *pTcon, 70 struct inode *inode, const char *full_path, 71 const void *value, size_t size) 72 { 73 ssize_t rc = -EOPNOTSUPP; 74 __u64 *pcreation_time = (__u64 *)value; 75 __u64 creation_time; 76 FILE_BASIC_INFO info_buf; 77 78 if ((value == NULL) || (size != sizeof(__u64))) 79 return -ERANGE; 80 81 memset(&info_buf, 0, sizeof(info_buf)); 82 creation_time = *pcreation_time; 83 info_buf.CreationTime = cpu_to_le64(creation_time); 84 if (pTcon->ses->server->ops->set_file_info) 85 rc = pTcon->ses->server->ops->set_file_info(inode, full_path, 86 &info_buf, xid); 87 if (rc == 0) 88 CIFS_I(inode)->createtime = creation_time; 89 90 return rc; 91 } 92 93 static int cifs_xattr_set(const struct xattr_handler *handler, 94 struct mnt_idmap *idmap, 95 struct dentry *dentry, struct inode *inode, 96 const char *name, const void *value, 97 size_t size, int flags) 98 { 99 int rc = -EOPNOTSUPP; 100 unsigned int xid; 101 struct super_block *sb = dentry->d_sb; 102 struct cifs_sb_info *cifs_sb = CIFS_SB(sb); 103 struct tcon_link *tlink; 104 struct cifs_tcon *pTcon; 105 const char *full_path; 106 void *page; 107 108 tlink = cifs_sb_tlink(cifs_sb); 109 if (IS_ERR(tlink)) 110 return PTR_ERR(tlink); 111 pTcon = tlink_tcon(tlink); 112 113 xid = get_xid(); 114 page = alloc_dentry_path(); 115 116 full_path = build_path_from_dentry(dentry, page); 117 if (IS_ERR(full_path)) { 118 rc = PTR_ERR(full_path); 119 goto out; 120 } 121 /* return dos attributes as pseudo xattr */ 122 /* return alt name if available as pseudo attr */ 123 124 /* if proc/fs/cifs/streamstoxattr is set then 125 search server for EAs or streams to 126 returns as xattrs */ 127 if (size > MAX_EA_VALUE_SIZE) { 128 cifs_dbg(FYI, "size of EA value too large\n"); 129 rc = -EOPNOTSUPP; 130 goto out; 131 } 132 133 switch (handler->flags) { 134 case XATTR_USER: 135 cifs_dbg(FYI, "%s:setting user xattr %s\n", __func__, name); 136 if ((strcmp(name, CIFS_XATTR_ATTRIB) == 0) || 137 (strcmp(name, SMB3_XATTR_ATTRIB) == 0)) { 138 rc = cifs_attrib_set(xid, pTcon, inode, full_path, 139 value, size); 140 if (rc == 0) /* force revalidate of the inode */ 141 CIFS_I(inode)->time = 0; 142 break; 143 } else if ((strcmp(name, CIFS_XATTR_CREATETIME) == 0) || 144 (strcmp(name, SMB3_XATTR_CREATETIME) == 0)) { 145 rc = cifs_creation_time_set(xid, pTcon, inode, 146 full_path, value, size); 147 if (rc == 0) /* force revalidate of the inode */ 148 CIFS_I(inode)->time = 0; 149 break; 150 } 151 152 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) 153 goto out; 154 155 if (pTcon->ses->server->ops->set_EA) { 156 rc = pTcon->ses->server->ops->set_EA(xid, pTcon, 157 full_path, name, value, (__u16)size, 158 cifs_sb->local_nls, cifs_sb); 159 if (rc == 0) 160 inode_set_ctime_current(inode); 161 } 162 break; 163 164 case XATTR_CIFS_ACL: 165 case XATTR_CIFS_NTSD_SACL: 166 case XATTR_CIFS_NTSD_OWNER: 167 case XATTR_CIFS_NTSD: 168 case XATTR_CIFS_NTSD_FULL: { 169 struct smb_ntsd *pacl; 170 171 if (!value) 172 goto out; 173 pacl = kmalloc(size, GFP_KERNEL); 174 if (!pacl) { 175 rc = -ENOMEM; 176 } else { 177 memcpy(pacl, value, size); 178 if (pTcon->ses->server->ops->set_acl) { 179 int aclflags = 0; 180 181 switch (handler->flags) { 182 case XATTR_CIFS_NTSD_FULL: 183 aclflags = (CIFS_ACL_OWNER | 184 CIFS_ACL_GROUP | 185 CIFS_ACL_DACL | 186 CIFS_ACL_SACL); 187 break; 188 case XATTR_CIFS_NTSD: 189 aclflags = (CIFS_ACL_OWNER | 190 CIFS_ACL_GROUP | 191 CIFS_ACL_DACL); 192 break; 193 case XATTR_CIFS_NTSD_OWNER: 194 aclflags = (CIFS_ACL_OWNER | 195 CIFS_ACL_GROUP); 196 break; 197 case XATTR_CIFS_NTSD_SACL: 198 aclflags = CIFS_ACL_SACL; 199 break; 200 case XATTR_CIFS_ACL: 201 default: 202 aclflags = CIFS_ACL_DACL; 203 } 204 205 rc = pTcon->ses->server->ops->set_acl(pacl, 206 size, inode, full_path, aclflags); 207 } else { 208 rc = -EOPNOTSUPP; 209 } 210 if (rc == 0) /* force revalidate of the inode */ 211 CIFS_I(inode)->time = 0; 212 kfree(pacl); 213 } 214 break; 215 } 216 } 217 218 out: 219 free_dentry_path(page); 220 free_xid(xid); 221 cifs_put_tlink(tlink); 222 return rc; 223 } 224 225 static int cifs_attrib_get(struct dentry *dentry, 226 struct inode *inode, void *value, 227 size_t size) 228 { 229 ssize_t rc; 230 __u32 *pattribute; 231 232 rc = cifs_revalidate_dentry_attr(dentry); 233 234 if (rc) 235 return rc; 236 237 if ((value == NULL) || (size == 0)) 238 return sizeof(__u32); 239 else if (size < sizeof(__u32)) 240 return -ERANGE; 241 242 /* return dos attributes as pseudo xattr */ 243 pattribute = (__u32 *)value; 244 *pattribute = CIFS_I(inode)->cifsAttrs; 245 246 return sizeof(__u32); 247 } 248 249 static int cifs_creation_time_get(struct dentry *dentry, struct inode *inode, 250 void *value, size_t size) 251 { 252 ssize_t rc; 253 __u64 *pcreatetime; 254 255 rc = cifs_revalidate_dentry_attr(dentry); 256 if (rc) 257 return rc; 258 259 if ((value == NULL) || (size == 0)) 260 return sizeof(__u64); 261 else if (size < sizeof(__u64)) 262 return -ERANGE; 263 264 /* return dos attributes as pseudo xattr */ 265 pcreatetime = (__u64 *)value; 266 *pcreatetime = CIFS_I(inode)->createtime; 267 return sizeof(__u64); 268 } 269 270 271 static int cifs_xattr_get(const struct xattr_handler *handler, 272 struct dentry *dentry, struct inode *inode, 273 const char *name, void *value, size_t size) 274 { 275 ssize_t rc = -EOPNOTSUPP; 276 unsigned int xid; 277 struct super_block *sb = dentry->d_sb; 278 struct cifs_sb_info *cifs_sb = CIFS_SB(sb); 279 struct tcon_link *tlink; 280 struct cifs_tcon *pTcon; 281 const char *full_path; 282 void *page; 283 284 tlink = cifs_sb_tlink(cifs_sb); 285 if (IS_ERR(tlink)) 286 return PTR_ERR(tlink); 287 pTcon = tlink_tcon(tlink); 288 289 xid = get_xid(); 290 page = alloc_dentry_path(); 291 292 full_path = build_path_from_dentry(dentry, page); 293 if (IS_ERR(full_path)) { 294 rc = PTR_ERR(full_path); 295 goto out; 296 } 297 298 /* return alt name if available as pseudo attr */ 299 switch (handler->flags) { 300 case XATTR_USER: 301 cifs_dbg(FYI, "%s:querying user xattr %s\n", __func__, name); 302 if ((strcmp(name, CIFS_XATTR_ATTRIB) == 0) || 303 (strcmp(name, SMB3_XATTR_ATTRIB) == 0)) { 304 rc = cifs_attrib_get(dentry, inode, value, size); 305 break; 306 } else if ((strcmp(name, CIFS_XATTR_CREATETIME) == 0) || 307 (strcmp(name, SMB3_XATTR_CREATETIME) == 0)) { 308 rc = cifs_creation_time_get(dentry, inode, value, size); 309 break; 310 } 311 312 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) 313 goto out; 314 315 if (pTcon->ses->server->ops->query_all_EAs) 316 rc = pTcon->ses->server->ops->query_all_EAs(xid, pTcon, 317 full_path, name, value, size, cifs_sb); 318 break; 319 320 case XATTR_CIFS_ACL: 321 case XATTR_CIFS_NTSD_SACL: 322 case XATTR_CIFS_NTSD_OWNER: 323 case XATTR_CIFS_NTSD: 324 case XATTR_CIFS_NTSD_FULL: { 325 /* 326 * fetch owner, DACL, and SACL if asked for full descriptor, 327 * fetch owner and DACL otherwise 328 */ 329 u32 acllen, extra_info; 330 struct smb_ntsd *pacl; 331 332 if (pTcon->ses->server->ops->get_acl == NULL) 333 goto out; /* rc already EOPNOTSUPP */ 334 335 switch (handler->flags) { 336 case XATTR_CIFS_NTSD_FULL: 337 extra_info = OWNER_SECINFO | GROUP_SECINFO | DACL_SECINFO | SACL_SECINFO; 338 break; 339 case XATTR_CIFS_NTSD: 340 extra_info = OWNER_SECINFO | GROUP_SECINFO | DACL_SECINFO; 341 break; 342 case XATTR_CIFS_NTSD_OWNER: 343 extra_info = OWNER_SECINFO | GROUP_SECINFO; 344 break; 345 case XATTR_CIFS_NTSD_SACL: 346 extra_info = SACL_SECINFO; 347 break; 348 case XATTR_CIFS_ACL: 349 default: 350 extra_info = DACL_SECINFO; 351 break; 352 } 353 pacl = pTcon->ses->server->ops->get_acl(cifs_sb, 354 inode, full_path, &acllen, extra_info); 355 if (IS_ERR(pacl)) { 356 rc = PTR_ERR(pacl); 357 cifs_dbg(VFS, "%s: error %zd getting sec desc\n", 358 __func__, rc); 359 } else { 360 if (value) { 361 if (acllen > size) 362 acllen = -ERANGE; 363 else 364 memcpy(value, pacl, acllen); 365 } 366 rc = acllen; 367 kfree(pacl); 368 } 369 break; 370 } 371 } 372 373 /* We could add an additional check for streams ie 374 if proc/fs/cifs/streamstoxattr is set then 375 search server for EAs or streams to 376 returns as xattrs */ 377 378 if (rc == -EINVAL) 379 rc = -EOPNOTSUPP; 380 381 out: 382 free_dentry_path(page); 383 free_xid(xid); 384 cifs_put_tlink(tlink); 385 return rc; 386 } 387 388 ssize_t cifs_listxattr(struct dentry *direntry, char *data, size_t buf_size) 389 { 390 ssize_t rc = -EOPNOTSUPP; 391 unsigned int xid; 392 struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb); 393 struct tcon_link *tlink; 394 struct cifs_tcon *pTcon; 395 const char *full_path; 396 void *page; 397 398 if (unlikely(cifs_forced_shutdown(cifs_sb))) 399 return smb_EIO(smb_eio_trace_forced_shutdown); 400 401 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) 402 return -EOPNOTSUPP; 403 404 tlink = cifs_sb_tlink(cifs_sb); 405 if (IS_ERR(tlink)) 406 return PTR_ERR(tlink); 407 pTcon = tlink_tcon(tlink); 408 409 xid = get_xid(); 410 page = alloc_dentry_path(); 411 412 full_path = build_path_from_dentry(direntry, page); 413 if (IS_ERR(full_path)) { 414 rc = PTR_ERR(full_path); 415 goto list_ea_exit; 416 } 417 /* return dos attributes as pseudo xattr */ 418 /* return alt name if available as pseudo attr */ 419 420 /* if proc/fs/cifs/streamstoxattr is set then 421 search server for EAs or streams to 422 returns as xattrs */ 423 424 if (pTcon->ses->server->ops->query_all_EAs) 425 rc = pTcon->ses->server->ops->query_all_EAs(xid, pTcon, 426 full_path, NULL, data, buf_size, cifs_sb); 427 list_ea_exit: 428 free_dentry_path(page); 429 free_xid(xid); 430 cifs_put_tlink(tlink); 431 return rc; 432 } 433 434 static const struct xattr_handler cifs_user_xattr_handler = { 435 .prefix = XATTR_USER_PREFIX, 436 .flags = XATTR_USER, 437 .get = cifs_xattr_get, 438 .set = cifs_xattr_set, 439 }; 440 441 /* os2.* attributes are treated like user.* attributes */ 442 static const struct xattr_handler cifs_os2_xattr_handler = { 443 .prefix = XATTR_OS2_PREFIX, 444 .flags = XATTR_USER, 445 .get = cifs_xattr_get, 446 .set = cifs_xattr_set, 447 }; 448 449 static const struct xattr_handler cifs_cifs_acl_xattr_handler = { 450 .name = CIFS_XATTR_CIFS_ACL, 451 .flags = XATTR_CIFS_ACL, 452 .get = cifs_xattr_get, 453 .set = cifs_xattr_set, 454 }; 455 456 /* 457 * Although this is just an alias for the above, need to move away from 458 * confusing users and using the 20 year old term 'cifs' when it is no 459 * longer secure and was replaced by SMB2/SMB3 a long time ago, and 460 * SMB3 and later are highly secure. 461 */ 462 static const struct xattr_handler smb3_acl_xattr_handler = { 463 .name = SMB3_XATTR_CIFS_ACL, 464 .flags = XATTR_CIFS_ACL, 465 .get = cifs_xattr_get, 466 .set = cifs_xattr_set, 467 }; 468 469 static const struct xattr_handler smb3_ntsd_sacl_xattr_handler = { 470 .name = SMB3_XATTR_CIFS_NTSD_SACL, 471 .flags = XATTR_CIFS_NTSD_SACL, 472 .get = cifs_xattr_get, 473 .set = cifs_xattr_set, 474 }; 475 476 static const struct xattr_handler smb3_ntsd_owner_xattr_handler = { 477 .name = SMB3_XATTR_CIFS_NTSD_OWNER, 478 .flags = XATTR_CIFS_NTSD_OWNER, 479 .get = cifs_xattr_get, 480 .set = cifs_xattr_set, 481 }; 482 483 static const struct xattr_handler cifs_cifs_ntsd_xattr_handler = { 484 .name = CIFS_XATTR_CIFS_NTSD, 485 .flags = XATTR_CIFS_NTSD, 486 .get = cifs_xattr_get, 487 .set = cifs_xattr_set, 488 }; 489 490 /* 491 * Although this is just an alias for the above, need to move away from 492 * confusing users and using the 20 year old term 'cifs' when it is no 493 * longer secure and was replaced by SMB2/SMB3 a long time ago, and 494 * SMB3 and later are highly secure. 495 */ 496 static const struct xattr_handler smb3_ntsd_xattr_handler = { 497 .name = SMB3_XATTR_CIFS_NTSD, 498 .flags = XATTR_CIFS_NTSD, 499 .get = cifs_xattr_get, 500 .set = cifs_xattr_set, 501 }; 502 503 static const struct xattr_handler cifs_cifs_ntsd_full_xattr_handler = { 504 .name = CIFS_XATTR_CIFS_NTSD_FULL, 505 .flags = XATTR_CIFS_NTSD_FULL, 506 .get = cifs_xattr_get, 507 .set = cifs_xattr_set, 508 }; 509 510 /* 511 * Although this is just an alias for the above, need to move away from 512 * confusing users and using the 20 year old term 'cifs' when it is no 513 * longer secure and was replaced by SMB2/SMB3 a long time ago, and 514 * SMB3 and later are highly secure. 515 */ 516 static const struct xattr_handler smb3_ntsd_full_xattr_handler = { 517 .name = SMB3_XATTR_CIFS_NTSD_FULL, 518 .flags = XATTR_CIFS_NTSD_FULL, 519 .get = cifs_xattr_get, 520 .set = cifs_xattr_set, 521 }; 522 523 const struct xattr_handler * const cifs_xattr_handlers[] = { 524 &cifs_user_xattr_handler, 525 &cifs_os2_xattr_handler, 526 &cifs_cifs_acl_xattr_handler, 527 &smb3_acl_xattr_handler, /* alias for above since avoiding "cifs" */ 528 &smb3_ntsd_sacl_xattr_handler, 529 &smb3_ntsd_owner_xattr_handler, 530 &cifs_cifs_ntsd_xattr_handler, 531 &smb3_ntsd_xattr_handler, /* alias for above since avoiding "cifs" */ 532 &cifs_cifs_ntsd_full_xattr_handler, 533 &smb3_ntsd_full_xattr_handler, /* alias for above since avoiding "cifs" */ 534 NULL 535 }; 536