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