~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to source3/modules/vfs_tru64acl.c

  • Committer: Chuck Short
  • Date: 2010-09-28 20:38:39 UTC
  • Revision ID: zulcss@ubuntu.com-20100928203839-pgjulytsi9ue63x1
Initial version

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 vfs_op_tuple tru64acl_op_tuples[] = {
 
470
        /* Disk operations */
 
471
  {SMB_VFS_OP(tru64acl_sys_acl_get_file),
 
472
   SMB_VFS_OP_SYS_ACL_GET_FILE,
 
473
   SMB_VFS_LAYER_TRANSPARENT},
 
474
 
 
475
  {SMB_VFS_OP(tru64acl_sys_acl_get_fd),
 
476
   SMB_VFS_OP_SYS_ACL_GET_FD,
 
477
   SMB_VFS_LAYER_TRANSPARENT},
 
478
 
 
479
  {SMB_VFS_OP(tru64acl_sys_acl_set_file),
 
480
   SMB_VFS_OP_SYS_ACL_SET_FILE,
 
481
   SMB_VFS_LAYER_TRANSPARENT},
 
482
 
 
483
  {SMB_VFS_OP(tru64acl_sys_acl_set_fd),
 
484
   SMB_VFS_OP_SYS_ACL_SET_FD,
 
485
   SMB_VFS_LAYER_TRANSPARENT},
 
486
 
 
487
  {SMB_VFS_OP(tru64acl_sys_acl_delete_def_file),
 
488
   SMB_VFS_OP_SYS_ACL_DELETE_DEF_FILE,
 
489
   SMB_VFS_LAYER_TRANSPARENT},
 
490
 
 
491
  {SMB_VFS_OP(NULL),
 
492
   SMB_VFS_OP_NOOP,
 
493
   SMB_VFS_LAYER_NOOP}
 
494
};
 
495
 
 
496
NTSTATUS vfs_tru64acl_init(void);
 
497
NTSTATUS vfs_tru64acl_init(void)
 
498
{
 
499
        return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "tru64acl",
 
500
                                tru64acl_op_tuples);
 
501
}
 
502
 
 
503
/* ENTE */