4 * Copyright (c) International Business Machines Corp., 2003
5 * Author(s): Steve French (sfrench@us.ibm.com)
7 * This library is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as published
9 * by the Free Software Foundation; either version 2.1 of the License, or
10 * (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
15 * the GNU Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include <linux/posix_acl_xattr.h>
27 #include "cifsproto.h"
28 #include "cifs_debug.h"
30 #define MAX_EA_VALUE_SIZE 65535
31 #define CIFS_XATTR_DOS_ATTRIB "user.DosAttrib"
32 #define CIFS_XATTR_USER_PREFIX "user."
33 #define CIFS_XATTR_SYSTEM_PREFIX "system."
34 #define CIFS_XATTR_OS2_PREFIX "os2."
35 #define CIFS_XATTR_SECURITY_PREFIX ".security"
36 #define CIFS_XATTR_TRUSTED_PREFIX "trusted."
37 #define XATTR_TRUSTED_PREFIX_LEN 8
38 #define XATTR_SECURITY_PREFIX_LEN 9
39 /* BB need to add server (Samba e.g) support for security and trusted prefix */
43 int cifs_removexattr(struct dentry
* direntry
, const char * ea_name
)
46 #ifdef CONFIG_CIFS_XATTR
48 struct cifs_sb_info
*cifs_sb
;
49 struct cifsTconInfo
*pTcon
;
50 struct super_block
* sb
;
55 if(direntry
->d_inode
== NULL
)
57 sb
= direntry
->d_inode
->i_sb
;
62 cifs_sb
= CIFS_SB(sb
);
63 pTcon
= cifs_sb
->tcon
;
65 full_path
= build_path_from_dentry(direntry
);
66 if(full_path
== NULL
) {
71 cFYI(1,("Null xattr names not supported"));
72 } else if(strncmp(ea_name
,CIFS_XATTR_USER_PREFIX
,5)
73 && (strncmp(ea_name
,CIFS_XATTR_OS2_PREFIX
,4))) {
74 cFYI(1,("illegal xattr namespace %s (only user namespace supported)",ea_name
));
75 /* BB what if no namespace prefix? */
76 /* Should we just pass them to server, except for
77 system and perhaps security prefixes? */
79 if(cifs_sb
->mnt_cifs_flags
& CIFS_MOUNT_NO_XATTR
)
82 ea_name
+=5; /* skip past user. prefix */
83 rc
= CIFSSMBSetEA(xid
,pTcon
,full_path
,ea_name
,NULL
,
84 (__u16
)0, cifs_sb
->local_nls
,
85 cifs_sb
->mnt_cifs_flags
& CIFS_MOUNT_MAP_SPECIAL_CHR
);
94 int cifs_setxattr(struct dentry
* direntry
, const char * ea_name
,
95 const void * ea_value
, size_t value_size
, int flags
)
98 #ifdef CONFIG_CIFS_XATTR
100 struct cifs_sb_info
*cifs_sb
;
101 struct cifsTconInfo
*pTcon
;
102 struct super_block
* sb
;
107 if(direntry
->d_inode
== NULL
)
109 sb
= direntry
->d_inode
->i_sb
;
114 cifs_sb
= CIFS_SB(sb
);
115 pTcon
= cifs_sb
->tcon
;
117 full_path
= build_path_from_dentry(direntry
);
118 if(full_path
== NULL
) {
122 /* return dos attributes as pseudo xattr */
123 /* return alt name if available as pseudo attr */
125 /* if proc/fs/cifs/streamstoxattr is set then
126 search server for EAs or streams to
128 if(value_size
> MAX_EA_VALUE_SIZE
) {
129 cFYI(1,("size of EA value too large"));
135 if(ea_name
== NULL
) {
136 cFYI(1,("Null xattr names not supported"));
137 } else if(strncmp(ea_name
,CIFS_XATTR_USER_PREFIX
,5) == 0) {
138 if(cifs_sb
->mnt_cifs_flags
& CIFS_MOUNT_NO_XATTR
)
140 if(strncmp(ea_name
,CIFS_XATTR_DOS_ATTRIB
,14) == 0) {
141 cFYI(1,("attempt to set cifs inode metadata"));
143 ea_name
+= 5; /* skip past user. prefix */
144 rc
= CIFSSMBSetEA(xid
,pTcon
,full_path
,ea_name
,ea_value
,
145 (__u16
)value_size
, cifs_sb
->local_nls
,
146 cifs_sb
->mnt_cifs_flags
& CIFS_MOUNT_MAP_SPECIAL_CHR
);
147 } else if(strncmp(ea_name
, CIFS_XATTR_OS2_PREFIX
,4) == 0) {
148 if(cifs_sb
->mnt_cifs_flags
& CIFS_MOUNT_NO_XATTR
)
151 ea_name
+= 4; /* skip past os2. prefix */
152 rc
= CIFSSMBSetEA(xid
,pTcon
,full_path
,ea_name
,ea_value
,
153 (__u16
)value_size
, cifs_sb
->local_nls
,
154 cifs_sb
->mnt_cifs_flags
& CIFS_MOUNT_MAP_SPECIAL_CHR
);
157 temp
= strncmp(ea_name
,POSIX_ACL_XATTR_ACCESS
,
158 strlen(POSIX_ACL_XATTR_ACCESS
));
160 #ifdef CONFIG_CIFS_POSIX
161 if(sb
->s_flags
& MS_POSIXACL
)
162 rc
= CIFSSMBSetPosixACL(xid
, pTcon
,full_path
,
163 ea_value
, (const int)value_size
,
164 ACL_TYPE_ACCESS
,cifs_sb
->local_nls
,
165 cifs_sb
->mnt_cifs_flags
&
166 CIFS_MOUNT_MAP_SPECIAL_CHR
);
167 cFYI(1,("set POSIX ACL rc %d",rc
));
169 cFYI(1,("set POSIX ACL not supported"));
171 } else if(strncmp(ea_name
,POSIX_ACL_XATTR_DEFAULT
,strlen(POSIX_ACL_XATTR_DEFAULT
)) == 0) {
172 #ifdef CONFIG_CIFS_POSIX
173 if(sb
->s_flags
& MS_POSIXACL
)
174 rc
= CIFSSMBSetPosixACL(xid
, pTcon
,full_path
,
175 ea_value
, (const int)value_size
,
176 ACL_TYPE_DEFAULT
, cifs_sb
->local_nls
,
177 cifs_sb
->mnt_cifs_flags
&
178 CIFS_MOUNT_MAP_SPECIAL_CHR
);
179 cFYI(1,("set POSIX default ACL rc %d",rc
));
181 cFYI(1,("set default POSIX ACL not supported"));
184 cFYI(1,("illegal xattr request %s (only user namespace supported)",ea_name
));
185 /* BB what if no namespace prefix? */
186 /* Should we just pass them to server, except for
187 system and perhaps security prefixes? */
198 ssize_t
cifs_getxattr(struct dentry
* direntry
, const char * ea_name
,
199 void * ea_value
, size_t buf_size
)
201 ssize_t rc
= -EOPNOTSUPP
;
202 #ifdef CONFIG_CIFS_XATTR
204 struct cifs_sb_info
*cifs_sb
;
205 struct cifsTconInfo
*pTcon
;
206 struct super_block
* sb
;
211 if(direntry
->d_inode
== NULL
)
213 sb
= direntry
->d_inode
->i_sb
;
219 cifs_sb
= CIFS_SB(sb
);
220 pTcon
= cifs_sb
->tcon
;
222 full_path
= build_path_from_dentry(direntry
);
223 if(full_path
== NULL
) {
227 /* return dos attributes as pseudo xattr */
228 /* return alt name if available as pseudo attr */
229 if(ea_name
== NULL
) {
230 cFYI(1,("Null xattr names not supported"));
231 } else if(strncmp(ea_name
,CIFS_XATTR_USER_PREFIX
,5) == 0) {
232 if(cifs_sb
->mnt_cifs_flags
& CIFS_MOUNT_NO_XATTR
)
235 if(strncmp(ea_name
,CIFS_XATTR_DOS_ATTRIB
,14) == 0) {
236 cFYI(1,("attempt to query cifs inode metadata"));
237 /* revalidate/getattr then populate from inode */
238 } /* BB add else when above is implemented */
239 ea_name
+= 5; /* skip past user. prefix */
240 rc
= CIFSSMBQueryEA(xid
,pTcon
,full_path
,ea_name
,ea_value
,
241 buf_size
, cifs_sb
->local_nls
,
242 cifs_sb
->mnt_cifs_flags
& CIFS_MOUNT_MAP_SPECIAL_CHR
);
243 } else if(strncmp(ea_name
, CIFS_XATTR_OS2_PREFIX
,4) == 0) {
244 if(cifs_sb
->mnt_cifs_flags
& CIFS_MOUNT_NO_XATTR
)
247 ea_name
+= 4; /* skip past os2. prefix */
248 rc
= CIFSSMBQueryEA(xid
,pTcon
,full_path
,ea_name
,ea_value
,
249 buf_size
, cifs_sb
->local_nls
,
250 cifs_sb
->mnt_cifs_flags
& CIFS_MOUNT_MAP_SPECIAL_CHR
);
251 } else if(strncmp(ea_name
,POSIX_ACL_XATTR_ACCESS
,
252 strlen(POSIX_ACL_XATTR_ACCESS
)) == 0) {
253 #ifdef CONFIG_CIFS_POSIX
254 if(sb
->s_flags
& MS_POSIXACL
)
255 rc
= CIFSSMBGetPosixACL(xid
, pTcon
, full_path
,
256 ea_value
, buf_size
, ACL_TYPE_ACCESS
,
258 cifs_sb
->mnt_cifs_flags
&
259 CIFS_MOUNT_MAP_SPECIAL_CHR
);
260 /* else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
263 rc = CIFSSMBOpen(xid, pTcon, full_path,
264 FILE_OPEN, GENERIC_READ, 0, &fid,
265 &oplock, NULL, cifs_sb->local_nls,
266 cifs_sb->mnt_cifs_flags &
267 CIFS_MOUNT_MAP_SPECIAL_CHR);
269 rc = CIFSSMBGetCIFSACL(xid, pTcon, fid,
272 CIFSSMBClose(xid, pTcon, fid)
274 } */ /* BB enable after fixing up return data */
277 cFYI(1,("query POSIX ACL not supported yet"));
278 #endif /* CONFIG_CIFS_POSIX */
279 } else if(strncmp(ea_name
,POSIX_ACL_XATTR_DEFAULT
,
280 strlen(POSIX_ACL_XATTR_DEFAULT
)) == 0) {
281 #ifdef CONFIG_CIFS_POSIX
282 if(sb
->s_flags
& MS_POSIXACL
)
283 rc
= CIFSSMBGetPosixACL(xid
, pTcon
, full_path
,
284 ea_value
, buf_size
, ACL_TYPE_DEFAULT
,
286 cifs_sb
->mnt_cifs_flags
&
287 CIFS_MOUNT_MAP_SPECIAL_CHR
);
289 cFYI(1,("query POSIX default ACL not supported yet"));
291 } else if(strncmp(ea_name
,
292 CIFS_XATTR_TRUSTED_PREFIX
,XATTR_TRUSTED_PREFIX_LEN
) == 0) {
293 cFYI(1,("Trusted xattr namespace not supported yet"));
294 } else if(strncmp(ea_name
,
295 CIFS_XATTR_SECURITY_PREFIX
,XATTR_SECURITY_PREFIX_LEN
) == 0) {
296 cFYI(1,("Security xattr namespace not supported yet"));
298 cFYI(1,("illegal xattr name request %s (only user namespace supported)",ea_name
));
301 /* We could add an additional check for streams ie
302 if proc/fs/cifs/streamstoxattr is set then
303 search server for EAs or streams to
316 ssize_t
cifs_listxattr(struct dentry
* direntry
, char * data
, size_t buf_size
)
318 ssize_t rc
= -EOPNOTSUPP
;
319 #ifdef CONFIG_CIFS_XATTR
321 struct cifs_sb_info
*cifs_sb
;
322 struct cifsTconInfo
*pTcon
;
323 struct super_block
* sb
;
328 if(direntry
->d_inode
== NULL
)
330 sb
= direntry
->d_inode
->i_sb
;
335 cifs_sb
= CIFS_SB(sb
);
336 pTcon
= cifs_sb
->tcon
;
338 full_path
= build_path_from_dentry(direntry
);
339 if(full_path
== NULL
) {
343 /* return dos attributes as pseudo xattr */
344 /* return alt name if available as pseudo attr */
346 /* if proc/fs/cifs/streamstoxattr is set then
347 search server for EAs or streams to
349 rc
= CIFSSMBQAllEAs(xid
,pTcon
,full_path
,data
,buf_size
,
351 cifs_sb
->mnt_cifs_flags
&
352 CIFS_MOUNT_MAP_SPECIAL_CHR
);