• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt/router/samba-3.5.8/source3/modules/
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
24static struct smb_acl_t *tru64_acl_to_smb_acl(const struct acl *tru64_acl);
25static bool tru64_ace_to_smb_ace(acl_entry_t tru64_ace,
26				struct smb_acl_entry *smb_ace);
27static acl_t smb_acl_to_tru64_acl(const SMB_ACL_T smb_acl);
28static acl_tag_t smb_tag_to_tru64(SMB_ACL_TAG_T smb_tag);
29static SMB_ACL_TAG_T tru64_tag_to_smb(acl_tag_t tru64_tag);
30static acl_perm_t smb_permset_to_tru64(SMB_ACL_PERM_T smb_permset);
31static SMB_ACL_PERM_T tru64_permset_to_smb(const acl_perm_t tru64_permset);
32
33
34/* public functions - the api */
35
36SMB_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
69SMB_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
84int 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;
124fail:
125	DEBUG(1, ("tru64acl_sys_acl_set_file failed!\n"));
126	return -1;
127}
128
129int 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
144int 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
153static 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
188fail:
189	if (result != NULL) {
190		SAFE_FREE(result);
191	}
192	DEBUG(1, ("tru64_acl_to_smb_acl failed!\n"));
193	return NULL;
194}
195
196static 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
241static 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
359fail:
360	if (result != NULL) {
361		acl_free(result);
362	}
363	DEBUG(1, ("smb_acl_to_tru64_acl failed!\n"));
364	return NULL;
365}
366
367static 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
403static 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
438static 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
457static 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
469static 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
477NTSTATUS vfs_tru64acl_init(void);
478NTSTATUS vfs_tru64acl_init(void)
479{
480	return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "tru64acl",
481				&tru64acl_fns);
482}
483
484/* ENTE */
485