laccess.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. /*
  2. * CDE - Common Desktop Environment
  3. *
  4. * Copyright (c) 1993-2012, The Open Group. All rights reserved.
  5. *
  6. * These libraries and programs are free software; you can
  7. * redistribute them and/or modify them under the terms of the GNU
  8. * Lesser General Public License as published by the Free Software
  9. * Foundation; either version 2 of the License, or (at your option)
  10. * any later version.
  11. *
  12. * These libraries and programs are distributed in the hope that
  13. * they will be useful, but WITHOUT ANY WARRANTY; without even the
  14. * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  15. * PURPOSE. See the GNU Lesser General Public License for more
  16. * details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with these libraries and programs; if not, write
  20. * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
  21. * Floor, Boston, MA 02110-1301 USA
  22. */
  23. /* $XConsortium: laccess.c /main/1 1996/04/21 19:23:33 drk $ */
  24. /*
  25. * (c) Copyright 1993, 1994 Hewlett-Packard Company
  26. * (c) Copyright 1993, 1994 International Business Machines Corp.
  27. * (c) Copyright 1993, 1994 Novell, Inc.
  28. * (c) Copyright 1993, 1994 Sun Microsystems, Inc.
  29. */
  30. #include <EUSCompat.h>
  31. #include <stdio.h>
  32. #include <stdlib.h>
  33. #include <string.h>
  34. #include "laccess.h"
  35. #include "lutil.h"
  36. /******************************************************************************
  37. * forward declaration of static functions used within the file
  38. ******************************************************************************/
  39. static void get_component(char **str, char *comp, char token);
  40. static void get_last_component(char *head, char **tail, char *comp, char token);
  41. static boolean_t match_forward(char *str1, char *str2);
  42. static boolean_t match_backward(char *str1, char *str2);
  43. /*****************************************************************************
  44. * extern functions used in the library
  45. *****************************************************************************/
  46. /*
  47. * Correct format assumed, i.e. str = label1[.label2 ...]
  48. * Compare str2 against str1 which should be more fully qualified than str2
  49. */
  50. extern boolean_t
  51. _DtCmIsSamePath(char *str1, char *str2)
  52. {
  53. if (str1 == NULL || str2 == NULL)
  54. return(B_FALSE);
  55. /* check format */
  56. if (*str1 == '.' || *str2 == '.')
  57. return (B_FALSE); /* bad format */
  58. if (match_forward(str1, str2) == B_TRUE)
  59. return (B_TRUE);
  60. else
  61. return (match_backward(str1, str2));
  62. }
  63. /*
  64. * compare user1 and user2
  65. * user1 = user@host[.domain]
  66. * user2 = any format in (user, user@host[.domain], user@domain)
  67. */
  68. extern boolean_t
  69. _DtCmIsSameUser(char *user1, char *user2)
  70. {
  71. char *str1, *str2;
  72. char buf[BUFSIZ], *domain;
  73. if (user1 == NULL || user2 == NULL)
  74. return (B_FALSE);
  75. /* compare user name */
  76. str1 = _DtCmGetPrefix(user1, '@');
  77. str2 = _DtCmGetPrefix(user2, '@');
  78. if (str1 == NULL || str2 == NULL) {
  79. free(str1);
  80. free(str2);
  81. return (B_FALSE);
  82. }
  83. if (strcmp(str1, str2)) {
  84. free(str1);
  85. free(str2);
  86. return (B_FALSE);
  87. }
  88. free(str1);
  89. free(str2);
  90. /* if only user name is specified, don't need to check domain */
  91. str2 = strchr(user2, '@');
  92. if (str2 == NULL)
  93. return (B_TRUE);
  94. domain = _DtCmGetLocalDomain(NULL);
  95. /* first assume user2=user@domain */
  96. str1 = strchr(user1, '.');
  97. if (str1 == NULL) {
  98. if (_DtCmIsSamePath(domain, ++str2)) {
  99. free(domain);
  100. return (B_TRUE);
  101. }
  102. } else {
  103. if (_DtCmIsSamePath(++str1, ++str2)) {
  104. return (B_TRUE);
  105. }
  106. }
  107. /* assume user2=user@host[.domain] */
  108. if (str1 == NULL) {
  109. str1 = strchr(user1, '@');
  110. snprintf(buf, sizeof buf, "%s.%s", ++str1, domain);
  111. str1 = buf;
  112. } else {
  113. str1 = strchr(user1, '@');
  114. str1++;
  115. }
  116. if (_DtCmIsSamePath(str1, str2))
  117. return (B_TRUE);
  118. else
  119. return (B_FALSE);
  120. }
  121. /*****************************************************************************
  122. * static functions used within the file
  123. *****************************************************************************/
  124. /*
  125. * str consists of components separated by token
  126. * get and copy the first component into comp and
  127. * strip it out of str, so str would point to the first
  128. * token or the null terminator.
  129. */
  130. static void
  131. get_component(char **str, char *comp, char token)
  132. {
  133. char *ptr;
  134. *comp = 0;
  135. if (str == NULL)
  136. return;
  137. else
  138. ptr = *str;
  139. while (ptr && *ptr != 0 && *ptr != token)
  140. *comp++ = *ptr++;
  141. *str = ptr;
  142. *comp = 0;
  143. }
  144. /*
  145. * head and tail points to the first and last character
  146. * of a string which consists of components separated by token.
  147. * get and copy the last component into comp and
  148. * strip it out of the string, so tail would point to the last
  149. * token or the head of the string.
  150. */
  151. static void
  152. get_last_component(char *head, char **tail, char *comp, char token)
  153. {
  154. char *ptr, *cptr;
  155. *comp = 0;
  156. if (tail == NULL)
  157. return;
  158. else
  159. cptr = *tail;
  160. while (cptr != head && *cptr != token)
  161. cptr--;
  162. if (*cptr == token)
  163. ptr = cptr + 1;
  164. else
  165. ptr = cptr;
  166. while (ptr != (*tail + 1))
  167. *comp++ = *ptr++;
  168. *tail = cptr;
  169. *comp = 0;
  170. }
  171. static boolean_t
  172. match_forward(char *str1, char *str2)
  173. {
  174. char com1[BUFSIZ], com2[BUFSIZ];
  175. if (str1 == NULL || str2 == NULL)
  176. return (B_FALSE);
  177. while (B_TRUE) {
  178. get_component(&str1, com1, '.');
  179. get_component(&str2, com2, '.');
  180. if (*com1) {
  181. if (*com2 == '\0')
  182. return (B_TRUE);
  183. } else {
  184. if (*com2 == '\0')
  185. return (B_TRUE);
  186. else
  187. return (B_FALSE);
  188. }
  189. if (strcasecmp(com1, com2) != 0)
  190. return (B_FALSE);
  191. /* take care of case: a.b a. */
  192. if (strcmp(str2, ".") == 0
  193. && (strcmp(str1, ".") != 0 || *str1 != '\0'))
  194. return (B_FALSE);
  195. /* skip "." */
  196. if (*str1 == '.') {
  197. if (*str2 == '\0')
  198. return (B_TRUE);
  199. else {
  200. str1++;
  201. str2++;
  202. }
  203. } else if (strcmp(str2, ".") == 0 || *str2 == '\0')
  204. return (B_TRUE);
  205. else
  206. return (B_FALSE);
  207. }
  208. }
  209. static boolean_t
  210. match_backward(char *str1, char *str2)
  211. {
  212. int len1, len2;
  213. char *ptr1, *ptr2;
  214. char com1[BUFSIZ], com2[BUFSIZ];
  215. if (str1 == NULL || str2 == NULL)
  216. return (B_FALSE);
  217. len1 = strlen(str1);
  218. len2 = strlen(str2);
  219. if (len2 > len1)
  220. return (B_FALSE);
  221. else if (len2 == 0)
  222. return (B_TRUE);
  223. ptr1 = (len1 ? (str1 + len1 - 1) : str1);
  224. ptr2 = (len2 ? (str2 + len2 - 1) : str2);
  225. if (*ptr1 == '.' && ptr1 != str1)
  226. ptr1--;
  227. if (*ptr2 == '.' && ptr2 != str2)
  228. ptr2--;
  229. while (B_TRUE) {
  230. get_last_component(str1, &ptr1, com1, '.');
  231. get_last_component(str2, &ptr2, com2, '.');
  232. if (*com1) {
  233. if (*com2 == '\0')
  234. return (B_TRUE);
  235. } else {
  236. if (*com2 == '\0')
  237. return (B_TRUE);
  238. else
  239. return (B_FALSE);
  240. }
  241. if (strcasecmp(com1, com2) != 0)
  242. return (B_FALSE);
  243. /* skip "." */
  244. if (*ptr1 == '.') {
  245. if (ptr1 != str1)
  246. ptr1--;
  247. else
  248. return (B_FALSE); /* bad format */
  249. } else
  250. return (B_TRUE); /* done */
  251. if (*ptr2 == '.') {
  252. if (ptr2 != str2)
  253. ptr2--;
  254. else
  255. return (B_FALSE); /* bad format */
  256. } else
  257. return (B_TRUE); /* done */
  258. }
  259. }