r4464: added pvfs backend support for the special CREATOR_OWNER and CREATOR_GROUP...
[samba.git] / source4 / ntvfs / posix / xattr_system.c
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 2 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, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #include "includes.h"
24 #include "system/filesys.h"
25 #include "vfs_posix.h"
26
27 /*
28   pull a xattr as a blob, from either a file or a file descriptor
29 */
30 NTSTATUS pull_xattr_blob_system(struct pvfs_state *pvfs,
31                                 TALLOC_CTX *mem_ctx,
32                                 const char *attr_name, 
33                                 const char *fname, 
34                                 int fd, 
35                                 size_t estimated_size,
36                                 DATA_BLOB *blob)
37 {
38 #if HAVE_XATTR_SUPPORT
39         int ret;
40
41         *blob = data_blob_talloc(mem_ctx, NULL, estimated_size);
42         if (blob->data == NULL) {
43                 return NT_STATUS_NO_MEMORY;
44         }
45
46 again:
47         if (fd != -1) {
48                 ret = fgetxattr(fd, attr_name, blob->data, estimated_size);
49         } else {
50                 ret = getxattr(fname, attr_name, blob->data, estimated_size);
51         }
52         if (ret == -1 && errno == ERANGE) {
53                 estimated_size *= 2;
54                 blob->data = talloc_realloc(mem_ctx, blob->data, estimated_size);
55                 if (blob->data == NULL) {
56                         return NT_STATUS_NO_MEMORY;
57                 }
58                 blob->length = estimated_size;
59                 goto again;
60         }
61
62         if (ret == -1) {
63                 data_blob_free(blob);
64                 return pvfs_map_errno(pvfs, errno);
65         }
66
67         blob->length = ret;
68
69         return NT_STATUS_OK;
70 #else
71         return NT_STATUS_NOT_SUPPORTED;
72 #endif
73 }
74
75 /*
76   push a xattr as a blob, from either a file or a file descriptor
77 */
78 NTSTATUS push_xattr_blob_system(struct pvfs_state *pvfs,
79                                 const char *attr_name, 
80                                 const char *fname, 
81                                 int fd, 
82                                 const DATA_BLOB *blob)
83 {
84 #if HAVE_XATTR_SUPPORT
85         int ret;
86
87         if (fd != -1) {
88                 ret = fsetxattr(fd, attr_name, blob->data, blob->length, 0);
89         } else {
90                 ret = setxattr(fname, attr_name, blob->data, blob->length, 0);
91         }
92         if (ret == -1) {
93                 return pvfs_map_errno(pvfs, errno);
94         }
95
96         return NT_STATUS_OK;
97 #else
98         return NT_STATUS_NOT_SUPPORTED;
99 #endif
100 }
101
102
103 /*
104   delete a xattr
105 */
106 NTSTATUS delete_xattr_system(struct pvfs_state *pvfs, const char *attr_name, 
107                              const char *fname, int fd)
108 {
109 #if HAVE_XATTR_SUPPORT
110         int ret;
111
112         if (fd != -1) {
113                 ret = fremovexattr(fd, attr_name);
114         } else {
115                 ret = removexattr(fname, attr_name);
116         }
117         if (ret == -1) {
118                 return pvfs_map_errno(pvfs, errno);
119         }
120
121         return NT_STATUS_OK;
122 #else
123         return NT_STATUS_NOT_SUPPORTED;
124 #endif
125 }
126
127 /*
128   unlink a file - cleanup any xattrs
129 */
130 NTSTATUS unlink_xattr_system(struct pvfs_state *pvfs, const char *fname)
131 {
132         /* nothing needs to be done for filesystem based xattrs */
133         return NT_STATUS_OK;
134 }