libDtHelp: Cov 88209
[oweals/cde.git] / cde / lib / csa / laccess.c
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
31 #include <EUSCompat.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include "laccess.h"
36 #include "lutil.h"
37
38 /******************************************************************************
39  * forward declaration of static functions used within the file
40  ******************************************************************************/
41 static void get_component(char **str, char *comp, char token);
42 static void get_last_component(char *head, char **tail, char *comp, char token);
43 static boolean_t match_forward(char *str1, char *str2);
44 static boolean_t match_backward(char *str1, char *str2);
45
46 /*****************************************************************************
47  * extern functions used in the library
48  *****************************************************************************/
49
50 /*
51  * Correct format assumed, i.e. str = label1[.label2 ...]
52  * Compare str2 against str1 which should be more fully qualified than str2
53  */
54 extern boolean_t
55 _DtCmIsSamePath(char *str1, char *str2)
56 {
57         if (str1 == NULL || str2 == NULL)
58                 return(B_FALSE);
59
60         /* check format */
61         if (*str1 == '.' || *str2 == '.')
62                 return (B_FALSE); /* bad format */
63
64         if (match_forward(str1, str2) == B_TRUE)
65                 return (B_TRUE);
66         else
67                 return (match_backward(str1, str2));
68 }
69
70 /*
71  * compare user1 and user2
72  * user1 = user@host[.domain]
73  * user2 = any format in (user, user@host[.domain], user@domain)
74  */
75 extern boolean_t
76 _DtCmIsSameUser(char *user1, char *user2)
77 {
78         char *str1, *str2;
79         char buf[BUFSIZ], *domain;
80
81         if (user1 == NULL || user2 == NULL)
82                 return (B_FALSE);
83
84         /* compare user name */
85         str1 = _DtCmGetPrefix(user1, '@');
86         str2 = _DtCmGetPrefix(user2, '@');
87
88         if (str1 == NULL || str2 == NULL) {
89                 free(str1);
90                 free(str2);
91                 return (B_FALSE);
92         }
93
94         if (strcmp(str1, str2)) {
95                 free(str1);
96                 free(str2);
97                 return (B_FALSE);
98         }
99         free(str1);
100         free(str2);
101
102         /* if only user name is specified, don't need to check domain */
103         str2 = strchr(user2, '@');
104         if (str2 == NULL)
105                 return (B_TRUE);
106                 
107         domain = _DtCmGetLocalDomain(NULL);
108
109         /* first assume user2=user@domain */
110         str1 = strchr(user1, '.');
111         if (str1 == NULL) {
112                 if (_DtCmIsSamePath(domain, ++str2)) {
113                         free(domain);
114                         return (B_TRUE);
115                 }
116         } else {
117                 if (_DtCmIsSamePath(++str1, ++str2)) {
118                         return (B_TRUE);
119                 }
120         }
121
122         /* assume user2=user@host[.domain] */
123         if (str1 == NULL) {
124                 str1 = strchr(user1, '@');
125                 snprintf(buf, sizeof buf, "%s.%s", ++str1, domain);
126                 str1 = buf;
127         } else {
128                 str1 = strchr(user1, '@');
129                 str1++;
130         }
131
132         if (_DtCmIsSamePath(str1, str2))
133                 return (B_TRUE);
134         else
135                 return (B_FALSE);
136 }
137
138 /*****************************************************************************
139  * static functions used within the file
140  *****************************************************************************/
141
142 /*
143  * str consists of components separated by token
144  * get and copy the first component into comp and
145  * strip it out of str, so str would point to the first
146  * token or the null terminator.
147  */
148 static void
149 get_component(char **str, char *comp, char token)
150 {
151         char *ptr;
152
153         *comp = 0;
154
155         if (str == NULL)
156                 return;
157         else
158                 ptr = *str;
159
160         while (ptr && *ptr != 0 && *ptr != token)
161                 *comp++ = *ptr++;
162
163         *str = ptr;
164
165         *comp = 0;
166 }
167
168 /*
169  * head and tail points to the first and last character
170  * of a string which consists of components separated by token.
171  * get and copy the last component into comp and
172  * strip it out of the string, so tail would point to the last
173  * token or the head of the string.
174  */
175 static void
176 get_last_component(char *head, char **tail, char *comp, char token)
177 {
178         char *ptr, *cptr;
179
180         *comp = 0;
181
182         if (tail == NULL)
183                 return;
184         else
185                 cptr = *tail;
186
187         while (cptr != head && *cptr != token)
188                 cptr--;
189
190         if (*cptr == token)
191                 ptr = cptr + 1;
192         else
193                 ptr = cptr;
194
195         while (ptr != (*tail + 1))
196                 *comp++ = *ptr++;
197
198         *tail = cptr;
199
200         *comp = 0;
201 }
202
203 static boolean_t
204 match_forward(char *str1, char *str2)
205 {
206         char com1[BUFSIZ], com2[BUFSIZ];
207
208         if (str1 == NULL || str2 == NULL)
209                 return (B_FALSE);
210
211         while (B_TRUE) {
212                 get_component(&str1, com1, '.');
213                 get_component(&str2, com2, '.');
214
215                 if (*com1) {
216                         if (*com2 == '\0')
217                                 return (B_TRUE);
218                 } else {
219                         if (*com2 == '\0')
220                                 return (B_TRUE);
221                         else
222                                 return (B_FALSE);
223                 }
224
225                 if (strcasecmp(com1, com2) != 0)
226                         return (B_FALSE);
227
228                 /* take care of case: a.b a. */
229                 if (strcmp(str2, ".") == 0
230                     && (strcmp(str1, ".") != 0 || *str1 != '\0'))
231                         return (B_FALSE);
232
233                 /* skip "." */
234                 if (*str1 == '.') {
235                         if (*str2 == '\0')
236                                 return (B_TRUE);
237                         else {
238                                 str1++;
239                                 str2++;
240                         }
241                 } else if (strcmp(str2, ".") == 0 || *str2 == '\0')
242                         return (B_TRUE);
243                 else
244                         return (B_FALSE);
245         }
246 }
247
248 static boolean_t
249 match_backward(char *str1, char *str2)
250 {
251         int len1, len2;
252         char *ptr1, *ptr2;
253         char com1[BUFSIZ], com2[BUFSIZ];
254
255         if (str1 == NULL || str2 == NULL)
256                 return (B_FALSE);
257
258         len1 = strlen(str1);
259         len2 = strlen(str2);
260         if (len2 > len1)
261                 return (B_FALSE);
262         else if (len2 == 0)
263                 return (B_TRUE);
264
265         ptr1 = (len1 ? (str1 + len1 - 1) : str1);
266         ptr2 = (len2 ? (str2 + len2 - 1) : str2);
267
268         if (*ptr1 == '.' && ptr1 != str1)
269                 ptr1--;
270
271         if (*ptr2 == '.' && ptr2 != str2)
272                 ptr2--;
273
274         while (B_TRUE) {
275                 get_last_component(str1, &ptr1, com1, '.');
276                 get_last_component(str2, &ptr2, com2, '.');
277
278                 if (*com1) {
279                         if (*com2 == '\0')
280                                 return (B_TRUE);
281                 } else {
282                         if (*com2 == '\0')
283                                 return (B_TRUE);
284                         else
285                                 return (B_FALSE);
286                 }
287
288                 if (strcasecmp(com1, com2) != 0)
289                         return (B_FALSE);
290
291                 /* skip "." */
292                 if (*ptr1 == '.') {
293                         if (ptr1 != str1)
294                                 ptr1--;
295                         else
296                                 return (B_FALSE); /* bad format */
297                 } else
298                         return (B_TRUE); /* done */
299
300                 if (*ptr2 == '.') {
301                         if (ptr2 != str2)
302                                 ptr2--;
303                         else
304                                 return (B_FALSE); /* bad format */
305                 } else
306                         return (B_TRUE); /* done */
307         }
308 }
309
310