smbd: Remove unused [push_pull]_file_id_24
[samba.git] / source3 / modules / vfs_tru64acl.c
1 /*
2    Unix SMB/Netbios implementation.
3    VFS module to get and set Tru64 acls
4    Copyright (C) Michael Adam 2006,2008
5
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.
10
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.
15
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/>.
18 */
19
20 #include "includes.h"
21
22 /* prototypes for private functions first - for clarity */
23
24 static struct smb_acl_t *tru64_acl_to_smb_acl(const struct acl *tru64_acl);
25 static bool tru64_ace_to_smb_ace(acl_entry_t tru64_ace, 
26                                 struct smb_acl_entry *smb_ace);
27 static acl_t smb_acl_to_tru64_acl(const SMB_ACL_T smb_acl);
28 static acl_tag_t smb_tag_to_tru64(SMB_ACL_TAG_T smb_tag);
29 static SMB_ACL_TAG_T tru64_tag_to_smb(acl_tag_t tru64_tag);
30 static acl_perm_t smb_permset_to_tru64(SMB_ACL_PERM_T smb_permset);
31 static SMB_ACL_PERM_T tru64_permset_to_smb(const acl_perm_t tru64_permset);
32
33
34 /* public functions - the api */
35
36 SMB_ACL_T tru64acl_sys_acl_get_file(vfs_handle_struct *handle,
37                                     const char *path_p,
38                                     SMB_ACL_TYPE_T type)
39 {
40         struct smb_acl_t *result;
41         acl_type_t the_acl_type;
42         acl_t tru64_acl;
43
44         DEBUG(10, ("Hi! This is tru64acl_sys_acl_get_file.\n"));
45
46         switch(type) {
47         case SMB_ACL_TYPE_ACCESS:
48                 the_acl_type = ACL_TYPE_ACCESS;
49                 break;
50         case SMB_ACL_TYPE_DEFAULT:
51                 the_acl_type = ACL_TYPE_DEFAULT;
52                 break;
53         default:
54                 errno = EINVAL;
55                 return NULL;
56         }
57
58         tru64_acl = acl_get_file((char *)path_p, the_acl_type);
59
60         if (tru64_acl == NULL) {
61                 return NULL;
62         }
63
64         result = tru64_acl_to_smb_acl(tru64_acl);
65         acl_free(tru64_acl);
66         return result;
67 }
68
69 SMB_ACL_T tru64acl_sys_acl_get_fd(vfs_handle_struct *handle,
70                                   files_struct *fsp)
71 {
72         struct smb_acl_t *result;
73         acl_t tru64_acl = acl_get_fd(fsp->fh->fd, ACL_TYPE_ACCESS);
74
75         if (tru64_acl == NULL) {
76                 return NULL;
77         }
78         
79         result = tru64_acl_to_smb_acl(tru64_acl);
80         acl_free(tru64_acl);
81         return result;
82 }
83
84 int tru64acl_sys_acl_set_file(vfs_handle_struct *handle,
85                               const char *name,
86                               SMB_ACL_TYPE_T type,
87                               SMB_ACL_T theacl)
88 {
89         int res;
90         acl_type_t the_acl_type;
91         acl_t tru64_acl;
92
93         DEBUG(10, ("tru64acl_sys_acl_set_file called with name %s, type %d\n", 
94                         name, type));
95
96         switch(type) {
97         case SMB_ACL_TYPE_ACCESS:
98                 DEBUGADD(10, ("got acl type ACL_TYPE_ACCESS\n"));
99                 the_acl_type = ACL_TYPE_ACCESS;
100                 break;
101         case SMB_ACL_TYPE_DEFAULT:
102                 DEBUGADD(10, ("got acl type ACL_TYPE_DEFAULT\n"));
103                 the_acl_type = ACL_TYPE_DEFAULT;
104                 break;
105         default:
106                 DEBUGADD(10, ("invalid acl type\n"));
107                 errno = EINVAL;
108                 goto fail;
109         }
110
111         tru64_acl = smb_acl_to_tru64_acl(theacl);
112         if (tru64_acl == NULL) {
113                 DEBUG(10, ("smb_acl_to_tru64_acl failed!\n"));
114                 goto fail;
115         }
116         DEBUG(10, ("got tru64 acl...\n"));
117         res = acl_set_file((char *)name, the_acl_type, tru64_acl);
118         acl_free(tru64_acl);
119         if (res != 0) {
120                 DEBUG(10, ("acl_set_file failed: %s\n", strerror(errno)));
121                 goto fail;
122         }
123         return res;
124 fail:
125         DEBUG(1, ("tru64acl_sys_acl_set_file failed!\n"));
126         return -1;
127 }
128
129 int tru64acl_sys_acl_set_fd(vfs_handle_struct *handle,
130                             files_struct *fsp,
131                             SMB_ACL_T theacl)
132 {
133         int res;
134         acl_t tru64_acl = smb_acl_to_tru64_acl(theacl);
135         if (tru64_acl == NULL) {
136                 return -1;
137         }
138         res =  acl_set_fd(fsp->fh->fd, ACL_TYPE_ACCESS, tru64_acl);
139         acl_free(tru64_acl);
140         return res;
141
142 }
143
144 int tru64acl_sys_acl_delete_def_file(vfs_handle_struct *handle,
145                                      const char *path)
146 {
147         return acl_delete_def_file((char *)path);
148 }
149
150
151 /* private functions */
152
153 static struct smb_acl_t *tru64_acl_to_smb_acl(const struct acl *tru64_acl) 
154 {
155         struct smb_acl_t *result;
156         acl_entry_t entry;
157
158         DEBUG(10, ("Hi! This is tru64_acl_to_smb_acl.\n"));
159         
160         if ((result = SMB_MALLOC_P(struct smb_acl_t)) == NULL) {
161                 DEBUG(0, ("SMB_MALLOC_P failed in tru64_acl_to_smb_acl\n"));
162                 errno = ENOMEM;
163                 goto fail;
164         }
165         ZERO_STRUCTP(result);
166         if (acl_first_entry((struct acl *)tru64_acl) != 0) {
167                 DEBUG(10, ("acl_first_entry failed: %s\n", strerror(errno)));
168                 goto fail;
169         }
170         while ((entry = acl_get_entry((struct acl *)tru64_acl)) != NULL) {
171                 result = SMB_REALLOC(result, sizeof(struct smb_acl_t) +
172                                         (sizeof(struct smb_acl_entry) * 
173                                          (result->count + 1)));
174                 if (result == NULL) {
175                         DEBUG(0, ("SMB_REALLOC failed in tru64_acl_to_smb_acl\n"));
176                         errno = ENOMEM;
177                         goto fail;
178                 }
179                 /* XYZ */
180                 if (!tru64_ace_to_smb_ace(entry, &result->acl[result->count])) {
181                         SAFE_FREE(result);
182                         goto fail;
183                 }
184                 result->count += 1;
185         }
186         return result;
187
188 fail:
189         if (result != NULL) {
190                 SAFE_FREE(result);
191         }
192         DEBUG(1, ("tru64_acl_to_smb_acl failed!\n"));
193         return NULL;
194 }
195
196 static bool tru64_ace_to_smb_ace(acl_entry_t tru64_ace, 
197                                 struct smb_acl_entry *smb_ace) 
198 {
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;
204
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;
208         }
209         
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;
216         }
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;
221         }
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;
227                 }
228         }
229         if (acl_get_permset(tru64_ace, &permset) != 0) {
230                 DEBUG(3, ("acl_get_permset failed: %s\n", strerror(errno)));
231                 return False;
232         }
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;
237         }
238         return True;
239 }
240
241 static acl_t smb_acl_to_tru64_acl(const SMB_ACL_T smb_acl) 
242 {
243         acl_t result;
244         acl_entry_t tru64_entry;
245         int i;
246         char *acl_text;
247         ssize_t acl_text_len;
248         
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. 
255          *
256          * It should not matter, since acl_create_entry enlarges 
257          * the working storage at need. ... */
258
259         DEBUG(10, ("Hi! This is smb_acl_to_tru64_acl.\n"));
260
261         result = acl_init(1);
262
263         if (result == NULL) {
264                 DEBUG(3, ("acl_init failed!\n"));
265                 goto fail;
266         }
267         
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;
274
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;
279                 }
280
281                 if (tru64_tag == ACL_MASK) {
282                         DEBUGADD(10, (" - acl type ACL_MASK: not implemented on Tru64 ==> skipping\n"));
283                         continue;
284                 }
285                 
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;
291                 }
292
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;
297                 }
298                 
299                 switch (smb_entry->a_type) {
300                 case SMB_ACL_USER:
301                         if (acl_set_qualifier(tru64_entry, 
302                                                 (int *)&smb_entry->uid) != 0) 
303                         {
304                                 DEBUG(3, ("acl_set_qualifier failed: %s\n",
305                                         strerror(errno)));
306                                 goto fail;
307                         }
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)
313                         {
314                                 DEBUG(3, ("acl_set_qualifier failed: %s\n",
315                                         strerror(errno)));
316                                 goto fail;
317                         }
318                         DEBUGADD(10, (" - setting gid to %d\n", smb_entry->gid));
319                         break;
320                 default:
321                         break;
322                 }
323
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;
328                 }
329                 DEBUGADD(10, (" - setting perms to %0d\n", tru64_permset));
330                 if (acl_set_permset(tru64_entry, &tru64_permset) != 0)
331                 {
332                         DEBUG(3, ("acl_set_permset failed: %s\n", strerror(errno)));
333                         goto fail;
334                 }
335         } /* for */
336         DEBUGADD(10, ("done parsing acl entries\n"));
337
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"));
344                 }
345                 goto fail;
346         }
347         DEBUGADD(10, ("acl is valid\n"));
348
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;
353         }
354         DEBUG(1, ("acl_text: %s\n", acl_text));
355         free(acl_text);
356
357         return result;
358
359 fail:
360         if (result != NULL) {
361                 acl_free(result);
362         }
363         DEBUG(1, ("smb_acl_to_tru64_acl failed!\n"));
364         return NULL;
365 }
366
367 static acl_tag_t smb_tag_to_tru64(SMB_ACL_TAG_T smb_tag)
368 {
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;
398         }
399         return result;
400 }
401
402
403 static SMB_ACL_TAG_T tru64_tag_to_smb(acl_tag_t tru64_tag)
404 {
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;
434         }
435         return smb_tag_type;
436 }
437
438 static acl_perm_t smb_permset_to_tru64(SMB_ACL_PERM_T smb_permset)
439 {
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;
448         }
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;
455 }
456
457 static SMB_ACL_PERM_T tru64_permset_to_smb(const acl_perm_t tru64_permset)
458 {
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;
464 }
465
466
467 /* VFS operations structure */
468
469 static struct vfs_fn_pointers tru64acl_fns = {
470         .sys_acl_get_file = tru64acl_sys_acl_get_file,
471         .sys_acl_get_fd = tru64acl_sys_acl_get_fd,
472         .sys_acl_set_file = tru64acl_sys_acl_set_file,
473         .sys_acl_set_fd = tru64acl_sys_acl_set_fd,
474         .sys_acl_delete_def_file = tru64acl_sys_acl_delete_def_file,
475 };
476
477 NTSTATUS vfs_tru64acl_init(void);
478 NTSTATUS vfs_tru64acl_init(void)
479 {
480         return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "tru64acl",
481                                 &tru64acl_fns);
482 }
483
484 /* ENTE */