1258945Sroberto/* 2258945Sroberto * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") 3258945Sroberto * Copyright (C) 2000, 2001 Internet Software Consortium. 4258945Sroberto * 5258945Sroberto * Permission to use, copy, modify, and/or distribute this software for any 6258945Sroberto * purpose with or without fee is hereby granted, provided that the above 7258945Sroberto * copyright notice and this permission notice appear in all copies. 8258945Sroberto * 9258945Sroberto * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 10258945Sroberto * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 11258945Sroberto * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 12258945Sroberto * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 13258945Sroberto * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 14258945Sroberto * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15258945Sroberto * PERFORMANCE OF THIS SOFTWARE. 16258945Sroberto */ 17258945Sroberto 18258945Sroberto/* $Id: fsaccess.c,v 1.13 2007/06/19 23:47:18 tbox Exp $ */ 19258945Sroberto 20258945Sroberto#include <config.h> 21258945Sroberto 22258945Sroberto#include <sys/types.h> 23258945Sroberto#include <sys/stat.h> 24258945Sroberto 25258945Sroberto#include <errno.h> 26258945Sroberto 27258945Sroberto#include "errno2result.h" 28258945Sroberto 29258945Sroberto/*! \file 30258945Sroberto * \brief 31258945Sroberto * The OS-independent part of the API is in lib/isc. 32258945Sroberto */ 33258945Sroberto#include "../fsaccess.c" 34258945Sroberto 35258945Srobertoisc_result_t 36258945Srobertoisc_fsaccess_set(const char *path, isc_fsaccess_t access) { 37258945Sroberto struct stat statb; 38258945Sroberto mode_t mode; 39258945Sroberto isc_boolean_t is_dir = ISC_FALSE; 40258945Sroberto isc_fsaccess_t bits; 41258945Sroberto isc_result_t result; 42258945Sroberto 43258945Sroberto if (stat(path, &statb) != 0) 44258945Sroberto return (isc__errno2result(errno)); 45258945Sroberto 46258945Sroberto if ((statb.st_mode & S_IFDIR) != 0) 47258945Sroberto is_dir = ISC_TRUE; 48258945Sroberto else if ((statb.st_mode & S_IFREG) == 0) 49258945Sroberto return (ISC_R_INVALIDFILE); 50258945Sroberto 51258945Sroberto result = check_bad_bits(access, is_dir); 52258945Sroberto if (result != ISC_R_SUCCESS) 53258945Sroberto return (result); 54258945Sroberto 55258945Sroberto /* 56258945Sroberto * Done with checking bad bits. Set mode_t. 57258945Sroberto */ 58258945Sroberto mode = 0; 59258945Sroberto 60258945Sroberto#define SET_AND_CLEAR1(modebit) \ 61258945Sroberto if ((access & bits) != 0) { \ 62258945Sroberto mode |= modebit; \ 63258945Sroberto access &= ~bits; \ 64258945Sroberto } 65258945Sroberto#define SET_AND_CLEAR(user, group, other) \ 66258945Sroberto SET_AND_CLEAR1(user); \ 67258945Sroberto bits <<= STEP; \ 68258945Sroberto SET_AND_CLEAR1(group); \ 69258945Sroberto bits <<= STEP; \ 70258945Sroberto SET_AND_CLEAR1(other); 71258945Sroberto 72258945Sroberto bits = ISC_FSACCESS_READ | ISC_FSACCESS_LISTDIRECTORY; 73258945Sroberto 74258945Sroberto SET_AND_CLEAR(S_IRUSR, S_IRGRP, S_IROTH); 75258945Sroberto 76258945Sroberto bits = ISC_FSACCESS_WRITE | 77258945Sroberto ISC_FSACCESS_CREATECHILD | 78258945Sroberto ISC_FSACCESS_DELETECHILD; 79258945Sroberto 80258945Sroberto SET_AND_CLEAR(S_IWUSR, S_IWGRP, S_IWOTH); 81258945Sroberto 82258945Sroberto bits = ISC_FSACCESS_EXECUTE | 83258945Sroberto ISC_FSACCESS_ACCESSCHILD; 84258945Sroberto 85258945Sroberto SET_AND_CLEAR(S_IXUSR, S_IXGRP, S_IXOTH); 86258945Sroberto 87258945Sroberto INSIST(access == 0); 88258945Sroberto 89258945Sroberto if (chmod(path, mode) < 0) 90258945Sroberto return (isc__errno2result(errno)); 91258945Sroberto 92258945Sroberto return (ISC_R_SUCCESS); 93258945Sroberto} 94