groupaccess.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. /* $OpenBSD: groupaccess.c,v 1.17 2019/03/06 22:14:23 dtucker Exp $ */
  2. /*
  3. * Copyright (c) 2001 Kevin Steves. All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. *
  14. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  15. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  16. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  17. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  18. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  19. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  20. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  21. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  22. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  23. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24. */
  25. #include "includes.h"
  26. #include <sys/types.h>
  27. #include <grp.h>
  28. #include <unistd.h>
  29. #include <stdarg.h>
  30. #include <stdlib.h>
  31. #include <string.h>
  32. #include <limits.h>
  33. #include "xmalloc.h"
  34. #include "groupaccess.h"
  35. #include "match.h"
  36. #include "log.h"
  37. static int ngroups;
  38. static char **groups_byname;
  39. /*
  40. * Initialize group access list for user with primary (base) and
  41. * supplementary groups. Return the number of groups in the list.
  42. */
  43. int
  44. ga_init(const char *user, gid_t base)
  45. {
  46. gid_t *groups_bygid;
  47. int i, j, retry = 0;
  48. struct group *gr;
  49. if (ngroups > 0)
  50. ga_free();
  51. ngroups = NGROUPS_MAX;
  52. #if defined(HAVE_SYSCONF) && defined(_SC_NGROUPS_MAX)
  53. ngroups = MAX(NGROUPS_MAX, sysconf(_SC_NGROUPS_MAX));
  54. #endif
  55. groups_bygid = xcalloc(ngroups, sizeof(*groups_bygid));
  56. while (getgrouplist(user, base, groups_bygid, &ngroups) == -1) {
  57. if (retry++ > 0)
  58. fatal("getgrouplist: groups list too small");
  59. groups_bygid = xreallocarray(groups_bygid, ngroups,
  60. sizeof(*groups_bygid));
  61. }
  62. groups_byname = xcalloc(ngroups, sizeof(*groups_byname));
  63. for (i = 0, j = 0; i < ngroups; i++)
  64. if ((gr = getgrgid(groups_bygid[i])) != NULL)
  65. groups_byname[j++] = xstrdup(gr->gr_name);
  66. free(groups_bygid);
  67. return (ngroups = j);
  68. }
  69. /*
  70. * Return 1 if one of user's groups is contained in groups.
  71. * Return 0 otherwise. Use match_pattern() for string comparison.
  72. */
  73. int
  74. ga_match(char * const *groups, int n)
  75. {
  76. int i, j;
  77. for (i = 0; i < ngroups; i++)
  78. for (j = 0; j < n; j++)
  79. if (match_pattern(groups_byname[i], groups[j]))
  80. return 1;
  81. return 0;
  82. }
  83. /*
  84. * Return 1 if one of user's groups matches group_pattern list.
  85. * Return 0 on negated or no match.
  86. */
  87. int
  88. ga_match_pattern_list(const char *group_pattern)
  89. {
  90. int i, found = 0;
  91. for (i = 0; i < ngroups; i++) {
  92. switch (match_usergroup_pattern_list(groups_byname[i],
  93. group_pattern)) {
  94. case -1:
  95. return 0; /* Negated match wins */
  96. case 0:
  97. continue;
  98. case 1:
  99. found = 1;
  100. }
  101. }
  102. return found;
  103. }
  104. /*
  105. * Free memory allocated for group access list.
  106. */
  107. void
  108. ga_free(void)
  109. {
  110. int i;
  111. if (ngroups > 0) {
  112. for (i = 0; i < ngroups; i++)
  113. free(groups_byname[i]);
  114. ngroups = 0;
  115. free(groups_byname);
  116. groups_byname = NULL;
  117. }
  118. }