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