1135446Strhodes/*
2193149Sdougb * Copyright (C) 2004-2007  Internet Systems Consortium, Inc. ("ISC")
3135446Strhodes * Copyright (C) 2000, 2001  Internet Software Consortium.
4135446Strhodes *
5193149Sdougb * Permission to use, copy, modify, and/or distribute this software for any
6135446Strhodes * purpose with or without fee is hereby granted, provided that the above
7135446Strhodes * copyright notice and this permission notice appear in all copies.
8135446Strhodes *
9135446Strhodes * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10135446Strhodes * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11135446Strhodes * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12135446Strhodes * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13135446Strhodes * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14135446Strhodes * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15135446Strhodes * PERFORMANCE OF THIS SOFTWARE.
16135446Strhodes */
17135446Strhodes
18234010Sdougb/* $Id: fsaccess.c,v 1.13 2007/06/19 23:47:18 tbox Exp $ */
19135446Strhodes
20165071Sdougb#include <config.h>
21165071Sdougb
22135446Strhodes#include <sys/types.h>
23135446Strhodes#include <sys/stat.h>
24135446Strhodes
25135446Strhodes#include <errno.h>
26135446Strhodes
27135446Strhodes#include "errno2result.h"
28135446Strhodes
29170222Sdougb/*! \file
30170222Sdougb * \brief
31135446Strhodes * The OS-independent part of the API is in lib/isc.
32135446Strhodes */
33135446Strhodes#include "../fsaccess.c"
34135446Strhodes
35135446Strhodesisc_result_t
36135446Strhodesisc_fsaccess_set(const char *path, isc_fsaccess_t access) {
37135446Strhodes	struct stat statb;
38135446Strhodes	mode_t mode;
39135446Strhodes	isc_boolean_t is_dir = ISC_FALSE;
40135446Strhodes	isc_fsaccess_t bits;
41135446Strhodes	isc_result_t result;
42135446Strhodes
43135446Strhodes	if (stat(path, &statb) != 0)
44135446Strhodes		return (isc__errno2result(errno));
45135446Strhodes
46135446Strhodes	if ((statb.st_mode & S_IFDIR) != 0)
47135446Strhodes		is_dir = ISC_TRUE;
48135446Strhodes	else if ((statb.st_mode & S_IFREG) == 0)
49135446Strhodes		return (ISC_R_INVALIDFILE);
50135446Strhodes
51135446Strhodes	result = check_bad_bits(access, is_dir);
52135446Strhodes	if (result != ISC_R_SUCCESS)
53135446Strhodes		return (result);
54135446Strhodes
55135446Strhodes	/*
56135446Strhodes	 * Done with checking bad bits.  Set mode_t.
57135446Strhodes	 */
58135446Strhodes	mode = 0;
59135446Strhodes
60135446Strhodes#define SET_AND_CLEAR1(modebit) \
61135446Strhodes	if ((access & bits) != 0) { \
62135446Strhodes		mode |= modebit; \
63135446Strhodes		access &= ~bits; \
64135446Strhodes	}
65135446Strhodes#define SET_AND_CLEAR(user, group, other) \
66135446Strhodes	SET_AND_CLEAR1(user); \
67135446Strhodes	bits <<= STEP; \
68135446Strhodes	SET_AND_CLEAR1(group); \
69135446Strhodes	bits <<= STEP; \
70135446Strhodes	SET_AND_CLEAR1(other);
71135446Strhodes
72135446Strhodes	bits = ISC_FSACCESS_READ | ISC_FSACCESS_LISTDIRECTORY;
73135446Strhodes
74135446Strhodes	SET_AND_CLEAR(S_IRUSR, S_IRGRP, S_IROTH);
75135446Strhodes
76135446Strhodes	bits = ISC_FSACCESS_WRITE |
77135446Strhodes	       ISC_FSACCESS_CREATECHILD |
78135446Strhodes	       ISC_FSACCESS_DELETECHILD;
79135446Strhodes
80135446Strhodes	SET_AND_CLEAR(S_IWUSR, S_IWGRP, S_IWOTH);
81135446Strhodes
82135446Strhodes	bits = ISC_FSACCESS_EXECUTE |
83135446Strhodes	       ISC_FSACCESS_ACCESSCHILD;
84135446Strhodes
85135446Strhodes	SET_AND_CLEAR(S_IXUSR, S_IXGRP, S_IXOTH);
86135446Strhodes
87135446Strhodes	INSIST(access == 0);
88135446Strhodes
89135446Strhodes	if (chmod(path, mode) < 0)
90135446Strhodes		return (isc__errno2result(errno));
91135446Strhodes
92135446Strhodes	return (ISC_R_SUCCESS);
93135446Strhodes}
94