171SN/A/*
2157SN/A * Copyright (c) 2001-2002 Chris D. Faulhaber
371SN/A * All rights reserved.
471SN/A *
571SN/A * Redistribution and use in source and binary forms, with or without
671SN/A * modification, are permitted provided that the following conditions
7157SN/A * are met:
871SN/A * 1. Redistributions of source code must retain the above copyright
9157SN/A *    notice, this list of conditions and the following disclaimer.
1071SN/A * 2. Redistributions in binary form must reproduce the above copyright
1171SN/A *    notice, this list of conditions and the following disclaimer in the
1271SN/A *    documentation and/or other materials provided with the distribution.
1371SN/A *
1471SN/A * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1571SN/A * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1671SN/A * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1771SN/A * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1871SN/A * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1971SN/A * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2071SN/A * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21157SN/A * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22157SN/A * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23157SN/A * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2471SN/A * SUCH DAMAGE.
2571SN/A */
260SN/A
270SN/A#include <sys/cdefs.h>
2871SN/A__FBSDID("$FreeBSD$");
290SN/A
300SN/A#include <sys/types.h>
310SN/A#include "namespace.h"
3271SN/A#include <sys/acl.h>
330SN/A#include "un-namespace.h"
340SN/A
350SN/A#include <errno.h>
360SN/A#include <stdlib.h>
370SN/A
380SN/A/*
390SN/A * acl_create_entry() (23.4.7): create a new ACL entry in the ACL pointed
400SN/A * to by acl_p.
410SN/A */
420SN/Aint
430SN/Aacl_create_entry(acl_t *acl_p, acl_entry_t *entry_p)
440SN/A{
450SN/A	struct acl *acl_int;
460SN/A
470SN/A	if (acl_p == NULL) {
480SN/A		errno = EINVAL;
490SN/A		return (-1);
500SN/A	}
510SN/A
520SN/A	acl_int = &(*acl_p)->ats_acl;
530SN/A
540SN/A	/*
550SN/A	 * +1, because we are checking if there is space left for one more
560SN/A	 * entry.
570SN/A	 */
580SN/A	if (acl_int->acl_cnt + 1 >= ACL_MAX_ENTRIES) {
590SN/A		errno = EINVAL;
600SN/A		return (-1);
610SN/A	}
620SN/A
630SN/A	*entry_p = &acl_int->acl_entry[acl_int->acl_cnt++];
640SN/A
650SN/A	(**entry_p).ae_tag  = ACL_UNDEFINED_TAG;
660SN/A	(**entry_p).ae_id   = ACL_UNDEFINED_ID;
670SN/A	(**entry_p).ae_perm = ACL_PERM_NONE;
680SN/A	(**entry_p).ae_entry_type = 0;
690SN/A	(**entry_p).ae_flags = 0;
700SN/A
710SN/A	(*acl_p)->ats_cur_entry = 0;
720SN/A
730SN/A	return (0);
740SN/A}
750SN/A
760SN/Aint
770SN/Aacl_create_entry_np(acl_t *acl_p, acl_entry_t *entry_p, int offset)
780SN/A{
790SN/A	int i;
800SN/A	struct acl *acl_int;
810SN/A
820SN/A	if (acl_p == NULL) {
830SN/A		errno = EINVAL;
840SN/A		return (-1);
850SN/A	}
860SN/A
870SN/A	acl_int = &(*acl_p)->ats_acl;
880SN/A
890SN/A	if (acl_int->acl_cnt + 1 >= ACL_MAX_ENTRIES) {
900SN/A		errno = EINVAL;
910SN/A		return (-1);
920SN/A	}
930SN/A
940SN/A	if (offset < 0 || offset >= acl_int->acl_cnt) {
950SN/A		errno = EINVAL;
960SN/A		return (-1);
970SN/A	}
980SN/A
990SN/A	/* Make room for the new entry. */
1000SN/A	for (i = acl_int->acl_cnt; i > offset; i--)
1010SN/A		acl_int->acl_entry[i] = acl_int->acl_entry[i - 1];
1020SN/A
1030SN/A	acl_int->acl_cnt++;
1040SN/A
1050SN/A	*entry_p = &acl_int->acl_entry[offset];
1060SN/A
1070SN/A	(**entry_p).ae_tag  = ACL_UNDEFINED_TAG;
1080SN/A	(**entry_p).ae_id   = ACL_UNDEFINED_ID;
1090SN/A	(**entry_p).ae_perm = ACL_PERM_NONE;
1100SN/A	(**entry_p).ae_entry_type = 0;
1110SN/A	(**entry_p).ae_flags= 0;
1120SN/A
1130SN/A	(*acl_p)->ats_cur_entry = 0;
1140SN/A
1150SN/A	return (0);
1160SN/A}
1170SN/A
1180SN/A/*
1190SN/A * acl_get_entry() (23.4.14): returns an ACL entry from an ACL
1200SN/A * indicated by entry_id.
1210SN/A */
1220SN/Aint
1230SN/Aacl_get_entry(acl_t acl, int entry_id, acl_entry_t *entry_p)
1240SN/A{
12571SN/A	struct acl *acl_int;
1260SN/A
1270SN/A	if (acl == NULL) {
1280SN/A		errno = EINVAL;
1290SN/A		return (-1);
1300SN/A	}
1310SN/A	acl_int = &acl->ats_acl;
1320SN/A
13371SN/A	switch(entry_id) {
13471SN/A	case ACL_FIRST_ENTRY:
13571SN/A		acl->ats_cur_entry = 0;
1360SN/A		/* PASSTHROUGH */
1370SN/A	case ACL_NEXT_ENTRY:
1380SN/A		if (acl->ats_cur_entry >= acl->ats_acl.acl_cnt)
1390SN/A			return 0;
1400SN/A		*entry_p = &acl_int->acl_entry[acl->ats_cur_entry++];
1410SN/A		return (1);
1420SN/A	}
1430SN/A
1440SN/A	errno = EINVAL;
1450SN/A	return (-1);
1460SN/A}
1470SN/A