s3:locking: add brl_mark_disconnected() and brl_reconnect_disconnected()
[Samba.git] / source3 / modules / vfs_tru64acl.c
blob09f8c3933f6b2d1a5f90a03a35390ec5fe1f134f
1 /*
2 Unix SMB/Netbios implementation.
3 VFS module to get and set Tru64 acls
4 Copyright (C) Michael Adam 2006,2008
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "includes.h"
21 #include "system/filesys.h"
22 #include "smbd/smbd.h"
23 #include "modules/vfs_tru64acl.h"
25 /* prototypes for private functions first - for clarity */
27 static struct smb_acl_t *tru64_acl_to_smb_acl(const struct acl *tru64_acl);
28 static bool tru64_ace_to_smb_ace(acl_entry_t tru64_ace,
29 struct smb_acl_entry *smb_ace);
30 static acl_t smb_acl_to_tru64_acl(const SMB_ACL_T smb_acl);
31 static acl_tag_t smb_tag_to_tru64(SMB_ACL_TAG_T smb_tag);
32 static SMB_ACL_TAG_T tru64_tag_to_smb(acl_tag_t tru64_tag);
33 static acl_perm_t smb_permset_to_tru64(SMB_ACL_PERM_T smb_permset);
34 static SMB_ACL_PERM_T tru64_permset_to_smb(const acl_perm_t tru64_permset);
37 /* public functions - the api */
39 SMB_ACL_T tru64acl_sys_acl_get_file(vfs_handle_struct *handle,
40 const char *path_p,
41 SMB_ACL_TYPE_T type)
43 struct smb_acl_t *result;
44 acl_type_t the_acl_type;
45 acl_t tru64_acl;
47 DEBUG(10, ("Hi! This is tru64acl_sys_acl_get_file.\n"));
49 switch(type) {
50 case SMB_ACL_TYPE_ACCESS:
51 the_acl_type = ACL_TYPE_ACCESS;
52 break;
53 case SMB_ACL_TYPE_DEFAULT:
54 the_acl_type = ACL_TYPE_DEFAULT;
55 break;
56 default:
57 errno = EINVAL;
58 return NULL;
61 tru64_acl = acl_get_file((char *)path_p, the_acl_type);
63 if (tru64_acl == NULL) {
64 return NULL;
67 result = tru64_acl_to_smb_acl(tru64_acl);
68 acl_free(tru64_acl);
69 return result;
72 SMB_ACL_T tru64acl_sys_acl_get_fd(vfs_handle_struct *handle,
73 files_struct *fsp)
75 struct smb_acl_t *result;
76 acl_t tru64_acl = acl_get_fd(fsp->fh->fd, ACL_TYPE_ACCESS);
78 if (tru64_acl == NULL) {
79 return NULL;
82 result = tru64_acl_to_smb_acl(tru64_acl);
83 acl_free(tru64_acl);
84 return result;
87 int tru64acl_sys_acl_set_file(vfs_handle_struct *handle,
88 const char *name,
89 SMB_ACL_TYPE_T type,
90 SMB_ACL_T theacl)
92 int res;
93 acl_type_t the_acl_type;
94 acl_t tru64_acl;
96 DEBUG(10, ("tru64acl_sys_acl_set_file called with name %s, type %d\n",
97 name, type));
99 switch(type) {
100 case SMB_ACL_TYPE_ACCESS:
101 DEBUGADD(10, ("got acl type ACL_TYPE_ACCESS\n"));
102 the_acl_type = ACL_TYPE_ACCESS;
103 break;
104 case SMB_ACL_TYPE_DEFAULT:
105 DEBUGADD(10, ("got acl type ACL_TYPE_DEFAULT\n"));
106 the_acl_type = ACL_TYPE_DEFAULT;
107 break;
108 default:
109 DEBUGADD(10, ("invalid acl type\n"));
110 errno = EINVAL;
111 goto fail;
114 tru64_acl = smb_acl_to_tru64_acl(theacl);
115 if (tru64_acl == NULL) {
116 DEBUG(10, ("smb_acl_to_tru64_acl failed!\n"));
117 goto fail;
119 DEBUG(10, ("got tru64 acl...\n"));
120 res = acl_set_file((char *)name, the_acl_type, tru64_acl);
121 acl_free(tru64_acl);
122 if (res != 0) {
123 DEBUG(10, ("acl_set_file failed: %s\n", strerror(errno)));
124 goto fail;
126 return res;
127 fail:
128 DEBUG(1, ("tru64acl_sys_acl_set_file failed!\n"));
129 return -1;
132 int tru64acl_sys_acl_set_fd(vfs_handle_struct *handle,
133 files_struct *fsp,
134 SMB_ACL_T theacl)
136 int res;
137 acl_t tru64_acl = smb_acl_to_tru64_acl(theacl);
138 if (tru64_acl == NULL) {
139 return -1;
141 res = acl_set_fd(fsp->fh->fd, ACL_TYPE_ACCESS, tru64_acl);
142 acl_free(tru64_acl);
143 return res;
147 int tru64acl_sys_acl_delete_def_file(vfs_handle_struct *handle,
148 const char *path)
150 return acl_delete_def_file((char *)path);
154 /* private functions */
156 static struct smb_acl_t *tru64_acl_to_smb_acl(const struct acl *tru64_acl)
158 struct smb_acl_t *result;
159 acl_entry_t entry;
161 DEBUG(10, ("Hi! This is tru64_acl_to_smb_acl.\n"));
163 if ((result = sys_acl_init(0)) == NULL) {
164 DEBUG(0, ("sys_acl_init() failed in tru64_acl_to_smb_acl\n"));
165 errno = ENOMEM;
166 goto fail;
168 if (acl_first_entry((struct acl *)tru64_acl) != 0) {
169 DEBUG(10, ("acl_first_entry failed: %s\n", strerror(errno)));
170 goto fail;
172 while ((entry = acl_get_entry((struct acl *)tru64_acl)) != NULL) {
173 result->acl = talloc_realloc(result, result->acl, struct smb_acl_entry,
174 result->count + 1);
175 if (result->acl == NULL) {
176 TALLOC_FREE(result);
177 DEBUG(0, ("talloc_realloc failed in tru64_acl_to_smb_acl\n"));
178 errno = ENOMEM;
179 goto fail;
181 /* XYZ */
182 if (!tru64_ace_to_smb_ace(entry, &result->acl[result->count])) {
183 TALLOC_FREE(result);
184 goto fail;
186 result->count += 1;
188 return result;
190 fail:
191 TALLOC_FREE(result);
192 DEBUG(1, ("tru64_acl_to_smb_acl failed!\n"));
193 return NULL;
196 static bool tru64_ace_to_smb_ace(acl_entry_t tru64_ace,
197 struct smb_acl_entry *smb_ace)
199 acl_tag_t tru64_tag;
200 acl_permset_t permset;
201 SMB_ACL_TAG_T smb_tag_type;
202 SMB_ACL_PERM_T smb_permset;
203 void *qualifier;
205 if (acl_get_tag_type(tru64_ace, &tru64_tag) != 0) {
206 DEBUG(0, ("acl_get_tag_type failed: %s\n", strerror(errno)));
207 return False;
210 /* On could set the tag type directly to save a function call,
211 * but I like this better... */
212 smb_tag_type = tru64_tag_to_smb(tru64_tag);
213 if (smb_tag_type == 0) {
214 DEBUG(3, ("invalid tag type given: %d\n", tru64_tag));
215 return False;
217 if (sys_acl_set_tag_type(smb_ace, smb_tag_type) != 0) {
218 DEBUG(3, ("sys_acl_set_tag_type failed: %s\n",
219 strerror(errno)));
220 return False;
222 qualifier = acl_get_qualifier(tru64_ace);
223 if (qualifier != NULL) {
224 if (sys_acl_set_qualifier(smb_ace, qualifier) != 0) {
225 DEBUG(3, ("sys_acl_set_qualifier failed\n"));
226 return False;
229 if (acl_get_permset(tru64_ace, &permset) != 0) {
230 DEBUG(3, ("acl_get_permset failed: %s\n", strerror(errno)));
231 return False;
233 smb_permset = tru64_permset_to_smb(*permset);
234 if (sys_acl_set_permset(smb_ace, &smb_permset) != 0) {
235 DEBUG(3, ("sys_acl_set_permset failed: %s\n", strerror(errno)));
236 return False;
238 return True;
241 static acl_t smb_acl_to_tru64_acl(const SMB_ACL_T smb_acl)
243 acl_t result;
244 acl_entry_t tru64_entry;
245 int i;
246 char *acl_text;
247 ssize_t acl_text_len;
249 /* The tru64 acl_init function takes a size_t value
250 * instead of a count of entries (as with posix).
251 * the size parameter "Specifies the size of the working
252 * storage in bytes" (according to the man page).
253 * But it is unclear to me, how this size is to be
254 * calculated.
256 * It should not matter, since acl_create_entry enlarges
257 * the working storage at need. ... */
259 DEBUG(10, ("Hi! This is smb_acl_to_tru64_acl.\n"));
261 result = acl_init(1);
263 if (result == NULL) {
264 DEBUG(3, ("acl_init failed!\n"));
265 goto fail;
268 DEBUGADD(10, ("parsing acl entries...\n"));
269 for (i = 0; i < smb_acl->count; i++) {
270 /* XYZ - maybe eliminate this direct access? */
271 const struct smb_acl_entry *smb_entry = &smb_acl->acl[i];
272 acl_tag_t tru64_tag;
273 acl_perm_t tru64_permset;
275 tru64_tag = smb_tag_to_tru64(smb_entry->a_type);
276 if (tru64_tag == -1) {
277 DEBUG(3, ("smb_tag_to_tru64 failed!\n"));
278 goto fail;
281 if (tru64_tag == ACL_MASK) {
282 DEBUGADD(10, (" - acl type ACL_MASK: not implemented on Tru64 ==> skipping\n"));
283 continue;
286 tru64_entry = acl_create_entry(&result);
287 if (tru64_entry == NULL) {
288 DEBUG(3, ("acl_create_entry failed: %s\n",
289 strerror(errno)));
290 goto fail;
293 if (acl_set_tag_type(tru64_entry, tru64_tag) != 0) {
294 DEBUG(3, ("acl_set_tag_type(%d) failed: %s\n",
295 strerror(errno)));
296 goto fail;
299 switch (smb_entry->a_type) {
300 case SMB_ACL_USER:
301 if (acl_set_qualifier(tru64_entry,
302 (int *)&smb_entry->uid) != 0)
304 DEBUG(3, ("acl_set_qualifier failed: %s\n",
305 strerror(errno)));
306 goto fail;
308 DEBUGADD(10, (" - setting uid to %d\n", smb_entry->uid));
309 break;
310 case SMB_ACL_GROUP:
311 if (acl_set_qualifier(tru64_entry,
312 (int *)&smb_entry->gid) != 0)
314 DEBUG(3, ("acl_set_qualifier failed: %s\n",
315 strerror(errno)));
316 goto fail;
318 DEBUGADD(10, (" - setting gid to %d\n", smb_entry->gid));
319 break;
320 default:
321 break;
324 tru64_permset = smb_permset_to_tru64(smb_entry->a_perm);
325 if (tru64_permset == -1) {
326 DEBUG(3, ("smb_permset_to_tru64 failed!\n"));
327 goto fail;
329 DEBUGADD(10, (" - setting perms to %0d\n", tru64_permset));
330 if (acl_set_permset(tru64_entry, &tru64_permset) != 0)
332 DEBUG(3, ("acl_set_permset failed: %s\n", strerror(errno)));
333 goto fail;
335 } /* for */
336 DEBUGADD(10, ("done parsing acl entries\n"));
338 tru64_entry = NULL;
339 if (acl_valid(result, &tru64_entry) != 0) {
340 DEBUG(1, ("smb_acl_to_tru64_acl: ACL is invalid (%s)\n",
341 strerror(errno)));
342 if (tru64_entry != NULL) {
343 DEBUGADD(1, ("the acl contains duplicate entries\n"));
345 goto fail;
347 DEBUGADD(10, ("acl is valid\n"));
349 acl_text = acl_to_text(result, &acl_text_len);
350 if (acl_text == NULL) {
351 DEBUG(3, ("acl_to_text failed: %s\n", strerror(errno)));
352 goto fail;
354 DEBUG(1, ("acl_text: %s\n", acl_text));
355 free(acl_text);
357 return result;
359 fail:
360 if (result != NULL) {
361 acl_free(result);
363 DEBUG(1, ("smb_acl_to_tru64_acl failed!\n"));
364 return NULL;
367 static acl_tag_t smb_tag_to_tru64(SMB_ACL_TAG_T smb_tag)
369 acl_tag_t result;
370 switch (smb_tag) {
371 case SMB_ACL_USER:
372 result = ACL_USER;
373 DEBUGADD(10, ("got acl type ACL_USER\n"));
374 break;
375 case SMB_ACL_USER_OBJ:
376 result = ACL_USER_OBJ;
377 DEBUGADD(10, ("got acl type ACL_USER_OBJ\n"));
378 break;
379 case SMB_ACL_GROUP:
380 result = ACL_GROUP;
381 DEBUGADD(10, ("got acl type ACL_GROUP\n"));
382 break;
383 case SMB_ACL_GROUP_OBJ:
384 result = ACL_GROUP_OBJ;
385 DEBUGADD(10, ("got acl type ACL_GROUP_OBJ\n"));
386 break;
387 case SMB_ACL_OTHER:
388 result = ACL_OTHER;
389 DEBUGADD(10, ("got acl type ACL_OTHER\n"));
390 break;
391 case SMB_ACL_MASK:
392 result = ACL_MASK;
393 DEBUGADD(10, ("got acl type ACL_MASK\n"));
394 break;
395 default:
396 DEBUG(1, ("Unknown tag type %d\n", smb_tag));
397 result = -1;
399 return result;
403 static SMB_ACL_TAG_T tru64_tag_to_smb(acl_tag_t tru64_tag)
405 SMB_ACL_TAG_T smb_tag_type;
406 switch(tru64_tag) {
407 case ACL_USER:
408 smb_tag_type = SMB_ACL_USER;
409 DEBUGADD(10, ("got smb acl tag type SMB_ACL_USER\n"));
410 break;
411 case ACL_USER_OBJ:
412 smb_tag_type = SMB_ACL_USER_OBJ;
413 DEBUGADD(10, ("got smb acl tag type SMB_ACL_USER_OBJ\n"));
414 break;
415 case ACL_GROUP:
416 smb_tag_type = SMB_ACL_GROUP;
417 DEBUGADD(10, ("got smb acl tag type SMB_ACL_GROUP\n"));
418 break;
419 case ACL_GROUP_OBJ:
420 smb_tag_type = SMB_ACL_GROUP_OBJ;
421 DEBUGADD(10, ("got smb acl tag type SMB_ACL_GROUP_OBJ\n"));
422 break;
423 case ACL_OTHER:
424 smb_tag_type = SMB_ACL_OTHER;
425 DEBUGADD(10, ("got smb acl tag type SMB_ACL_OTHER\n"));
426 break;
427 case ACL_MASK:
428 smb_tag_type = SMB_ACL_MASK;
429 DEBUGADD(10, ("got smb acl tag type SMB_ACL_MASK\n"));
430 break;
431 default:
432 DEBUG(0, ("Unknown tag type %d\n", (unsigned int)tru64_tag));
433 smb_tag_type = 0;
435 return smb_tag_type;
438 static acl_perm_t smb_permset_to_tru64(SMB_ACL_PERM_T smb_permset)
440 /* originally, I thought that acl_clear_perm was the
441 * proper way to reset the permset to 0. but without
442 * initializing it to 0, acl_clear_perm fails.
443 * so probably, acl_clear_perm is not necessary here... ?! */
444 acl_perm_t tru64_permset = 0;
445 if (acl_clear_perm(&tru64_permset) != 0) {
446 DEBUG(5, ("acl_clear_perm failed: %s\n", strerror(errno)));
447 return -1;
449 /* according to original lib/sysacls.c, acl_add_perm is
450 * broken on tru64 ... */
451 tru64_permset |= ((smb_permset & SMB_ACL_READ) ? ACL_READ : 0);
452 tru64_permset |= ((smb_permset & SMB_ACL_WRITE) ? ACL_WRITE : 0);
453 tru64_permset |= ((smb_permset & SMB_ACL_EXECUTE) ? ACL_EXECUTE : 0);
454 return tru64_permset;
457 static SMB_ACL_PERM_T tru64_permset_to_smb(const acl_perm_t tru64_permset)
459 SMB_ACL_PERM_T smb_permset = 0;
460 smb_permset |= ((tru64_permset & ACL_READ) ? SMB_ACL_READ : 0);
461 smb_permset |= ((tru64_permset & ACL_WRITE) ? SMB_ACL_WRITE : 0);
462 smb_permset |= ((tru64_permset & ACL_EXECUTE) ? SMB_ACL_EXECUTE : 0);
463 return smb_permset;
467 /* VFS operations structure */
469 static struct vfs_fn_pointers tru64acl_fns = {
470 .sys_acl_get_file_fn = tru64acl_sys_acl_get_file,
471 .sys_acl_get_fd_fn = tru64acl_sys_acl_get_fd,
472 .sys_acl_set_file_fn = tru64acl_sys_acl_set_file,
473 .sys_acl_set_fd_fn = tru64acl_sys_acl_set_fd,
474 .sys_acl_delete_def_file_fn = tru64acl_sys_acl_delete_def_file,
477 NTSTATUS vfs_tru64acl_init(void);
478 NTSTATUS vfs_tru64acl_init(void)
480 return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "tru64acl",
481 &tru64acl_fns);
484 /* ENTE */