1/* 2 Unix SMB/CIFS implementation. 3 4 POSIX NTVFS backend - xattr support using filesystem xattrs 5 6 Copyright (C) Andrew Tridgell 2004 7 8 This program is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 3 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program. If not, see <http://www.gnu.org/licenses/>. 20*/ 21 22#include "includes.h" 23#include "vfs_posix.h" 24#include "../lib/util/wrap_xattr.h" 25 26/* 27 pull a xattr as a blob, from either a file or a file descriptor 28*/ 29NTSTATUS pull_xattr_blob_system(struct pvfs_state *pvfs, 30 TALLOC_CTX *mem_ctx, 31 const char *attr_name, 32 const char *fname, 33 int fd, 34 size_t estimated_size, 35 DATA_BLOB *blob) 36{ 37 int ret; 38 39 *blob = data_blob_talloc(mem_ctx, NULL, estimated_size+16); 40 if (blob->data == NULL) { 41 return NT_STATUS_NO_MEMORY; 42 } 43 44again: 45 if (fd != -1) { 46 ret = wrap_fgetxattr(fd, attr_name, blob->data, estimated_size); 47 } else { 48 ret = wrap_getxattr(fname, attr_name, blob->data, estimated_size); 49 } 50 if (ret == -1 && errno == ERANGE) { 51 estimated_size *= 2; 52 blob->data = talloc_realloc(mem_ctx, blob->data, 53 uint8_t, estimated_size); 54 if (blob->data == NULL) { 55 return NT_STATUS_NO_MEMORY; 56 } 57 blob->length = estimated_size; 58 goto again; 59 } 60 if (ret == -1 && errno == EPERM) { 61 struct stat statbuf; 62 63 if (fd != -1) { 64 ret = fstat(fd, &statbuf); 65 } else { 66 ret = stat(fname, &statbuf); 67 } 68 if (ret == 0) { 69 /* check if this is a directory and the sticky bit is set */ 70 if (S_ISDIR(statbuf.st_mode) && (statbuf.st_mode & S_ISVTX)) { 71 /* pretend we could not find the xattr */ 72 73 data_blob_free(blob); 74 return NT_STATUS_NOT_FOUND; 75 76 } else { 77 /* if not this was probably a legitimate error 78 * reset ret and errno to the correct values */ 79 errno = EPERM; 80 ret = -1; 81 } 82 } 83 } 84 85 if (ret == -1) { 86 data_blob_free(blob); 87 return pvfs_map_errno(pvfs, errno); 88 } 89 90 blob->length = ret; 91 92 return NT_STATUS_OK; 93} 94 95/* 96 push a xattr as a blob, from either a file or a file descriptor 97*/ 98NTSTATUS push_xattr_blob_system(struct pvfs_state *pvfs, 99 const char *attr_name, 100 const char *fname, 101 int fd, 102 const DATA_BLOB *blob) 103{ 104 int ret; 105 106 if (fd != -1) { 107 ret = wrap_fsetxattr(fd, attr_name, blob->data, blob->length, 0); 108 } else { 109 ret = wrap_setxattr(fname, attr_name, blob->data, blob->length, 0); 110 } 111 if (ret == -1) { 112 return pvfs_map_errno(pvfs, errno); 113 } 114 115 return NT_STATUS_OK; 116} 117 118 119/* 120 delete a xattr 121*/ 122NTSTATUS delete_xattr_system(struct pvfs_state *pvfs, const char *attr_name, 123 const char *fname, int fd) 124{ 125 int ret; 126 127 if (fd != -1) { 128 ret = wrap_fremovexattr(fd, attr_name); 129 } else { 130 ret = wrap_removexattr(fname, attr_name); 131 } 132 if (ret == -1) { 133 return pvfs_map_errno(pvfs, errno); 134 } 135 136 return NT_STATUS_OK; 137} 138 139/* 140 unlink a file - cleanup any xattrs 141*/ 142NTSTATUS unlink_xattr_system(struct pvfs_state *pvfs, const char *fname) 143{ 144 /* nothing needs to be done for filesystem based xattrs */ 145 return NT_STATUS_OK; 146} 147