/contrib/bind9/lib/isc/unix/fsaccess.c

https://bitbucket.org/freebsd/freebsd-head/ · C · 93 lines · 48 code · 21 blank · 24 comment · 13 complexity · 7f7dc987ad964814fed8d0da279d0b07 MD5 · raw file

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