xref: /minix/external/bsd/bind/dist/lib/isc/unix/fsaccess.c (revision fb9c64b2)
1 /*	$NetBSD: fsaccess.c,v 1.4 2014/12/10 04:38:01 christos Exp $	*/
2 
3 /*
4  * Copyright (C) 2004-2007  Internet Systems Consortium, Inc. ("ISC")
5  * Copyright (C) 2000, 2001  Internet Software Consortium.
6  *
7  * Permission to use, copy, modify, and/or distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17  * PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 /* Id: fsaccess.c,v 1.13 2007/06/19 23:47:18 tbox Exp  */
21 
22 #include <config.h>
23 
24 #include <sys/types.h>
25 #include <sys/stat.h>
26 
27 #include <errno.h>
28 
29 #include "errno2result.h"
30 
31 /*! \file
32  * \brief
33  * The OS-independent part of the API is in lib/isc.
34  */
35 #include "../fsaccess.c"
36 
37 isc_result_t
38 isc_fsaccess_set(const char *path, isc_fsaccess_t access) {
39 	struct stat statb;
40 	mode_t mode;
41 	isc_boolean_t is_dir = ISC_FALSE;
42 	isc_fsaccess_t bits;
43 	isc_result_t result;
44 
45 	if (stat(path, &statb) != 0)
46 		return (isc__errno2result(errno));
47 
48 	if ((statb.st_mode & S_IFDIR) != 0)
49 		is_dir = ISC_TRUE;
50 	else if ((statb.st_mode & S_IFREG) == 0)
51 		return (ISC_R_INVALIDFILE);
52 
53 	result = check_bad_bits(access, is_dir);
54 	if (result != ISC_R_SUCCESS)
55 		return (result);
56 
57 	/*
58 	 * Done with checking bad bits.  Set mode_t.
59 	 */
60 	mode = 0;
61 
62 #define SET_AND_CLEAR1(modebit) \
63 	if ((access & bits) != 0) { \
64 		mode |= modebit; \
65 		access &= ~bits; \
66 	}
67 #define SET_AND_CLEAR(user, group, other) \
68 	SET_AND_CLEAR1(user); \
69 	bits <<= STEP; \
70 	SET_AND_CLEAR1(group); \
71 	bits <<= STEP; \
72 	SET_AND_CLEAR1(other);
73 
74 	bits = ISC_FSACCESS_READ | ISC_FSACCESS_LISTDIRECTORY;
75 
76 	SET_AND_CLEAR(S_IRUSR, S_IRGRP, S_IROTH);
77 
78 	bits = ISC_FSACCESS_WRITE |
79 	       ISC_FSACCESS_CREATECHILD |
80 	       ISC_FSACCESS_DELETECHILD;
81 
82 	SET_AND_CLEAR(S_IWUSR, S_IWGRP, S_IWOTH);
83 
84 	bits = ISC_FSACCESS_EXECUTE |
85 	       ISC_FSACCESS_ACCESSCHILD;
86 
87 	SET_AND_CLEAR(S_IXUSR, S_IXGRP, S_IXOTH);
88 
89 	INSIST(access == 0);
90 
91 	if (chmod(path, mode) < 0)
92 		return (isc__errno2result(errno));
93 
94 	return (ISC_R_SUCCESS);
95 }
96