s4 dns: Add a simple dns lookup helper
[Samba/gebeck_regimport.git] / source4 / ntvfs / posix / xattr_system.c
blobf22c0e9ea4b04d1d6bf3cdc988412bdd44add525
1 /*
2 Unix SMB/CIFS implementation.
4 POSIX NTVFS backend - xattr support using filesystem xattrs
6 Copyright (C) Andrew Tridgell 2004
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.
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.
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/>.
22 #include "includes.h"
23 #include "vfs_posix.h"
24 #include "../lib/util/wrap_xattr.h"
27 pull a xattr as a blob, from either a file or a file descriptor
29 NTSTATUS 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)
37 int ret;
39 *blob = data_blob_talloc(mem_ctx, NULL, estimated_size+16);
40 if (blob->data == NULL) {
41 return NT_STATUS_NO_MEMORY;
44 again:
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);
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;
57 blob->length = estimated_size;
58 goto again;
60 if (ret == -1 && errno == EPERM) {
61 struct stat statbuf;
63 if (fd != -1) {
64 ret = fstat(fd, &statbuf);
65 } else {
66 ret = stat(fname, &statbuf);
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 */
73 data_blob_free(blob);
74 return NT_STATUS_NOT_FOUND;
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;
85 if (ret == -1) {
86 data_blob_free(blob);
87 return pvfs_map_errno(pvfs, errno);
90 blob->length = ret;
92 return NT_STATUS_OK;
96 push a xattr as a blob, from either a file or a file descriptor
98 NTSTATUS 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)
104 int ret;
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);
111 if (ret == -1) {
112 return pvfs_map_errno(pvfs, errno);
115 return NT_STATUS_OK;
120 delete a xattr
122 NTSTATUS delete_xattr_system(struct pvfs_state *pvfs, const char *attr_name,
123 const char *fname, int fd)
125 int ret;
127 if (fd != -1) {
128 ret = wrap_fremovexattr(fd, attr_name);
129 } else {
130 ret = wrap_removexattr(fname, attr_name);
132 if (ret == -1) {
133 return pvfs_map_errno(pvfs, errno);
136 return NT_STATUS_OK;
140 unlink a file - cleanup any xattrs
142 NTSTATUS unlink_xattr_system(struct pvfs_state *pvfs, const char *fname)
144 /* nothing needs to be done for filesystem based xattrs */
145 return NT_STATUS_OK;