1b22328f9Schristos /*
2b22328f9Schristos * Copyright (C) 2006 The Free Software Foundation, Inc.
3b22328f9Schristos *
4b22328f9Schristos * Portions Copyright (C) 2006, Baris Sahin <sbaris at users.sourceforge.net>
5b22328f9Schristos * <http://cvsacl.sourceforge.net>
6b22328f9Schristos *
7b22328f9Schristos *
8b22328f9Schristos * You may distribute under the terms of the GNU General Public License as
9b22328f9Schristos * specified in the README file that comes with the CVS source distribution.
10b22328f9Schristos *
11b22328f9Schristos *
12b22328f9Schristos *
13b22328f9Schristos * CVS ACCESS CONTROL LIST EXTENSION
14b22328f9Schristos *
15b22328f9Schristos * It provides advanced access control definitions per modules,
16b22328f9Schristos * directories, and files on branch/tag for remote cvs repository
17b22328f9Schristos * connections.Execution of all CVS subcommands can be controlled
18b22328f9Schristos * with eight different permissions.
19b22328f9Schristos *
20b22328f9Schristos * Permission Types:
21b22328f9Schristos * - no permission (n) (1)
22b22328f9Schristos * - all permissions (a) (2)
23b22328f9Schristos * - write permission (w) (3)
24b22328f9Schristos * - tag permission (t) (4)
25b22328f9Schristos * - read permission (r) (5)
26b22328f9Schristos * - add permission (c) (6)
27b22328f9Schristos * - remove permission (d) (7)
28b22328f9Schristos * - permission change (p) (8)
29b22328f9Schristos *
30b22328f9Schristos */
31*3cd63638Schristos #include <sys/cdefs.h>
32*3cd63638Schristos __RCSID("$NetBSD: acl.c,v 1.6 2016/05/17 14:00:09 christos Exp $");
33*3cd63638Schristos
34b22328f9Schristos #include "cvs.h"
35b22328f9Schristos #include "getline.h"
36d1f48bffSchristos #include <pwd.h>
37b22328f9Schristos #include <grp.h>
38b22328f9Schristos
39b22328f9Schristos static int acl_fileproc (void *callerdat, struct file_info *finfo);
40b22328f9Schristos
41b22328f9Schristos static Dtype acl_dirproc (void *callerdat, const char *dir, const char *repos,
42b22328f9Schristos const char *update_dir, List *entries);
43b22328f9Schristos
44b22328f9Schristos static int acllist_fileproc (void *callerdat, struct file_info *finfo);
45b22328f9Schristos static Dtype acllist_dirproc (void *callerdat, const char *dir,
46b22328f9Schristos const char *repos, const char *update_dir,
47b22328f9Schristos List *entries);
48b22328f9Schristos
49b22328f9Schristos static void acllist_print (char *line, const char *obj);
50b22328f9Schristos
51b22328f9Schristos static int racl_proc (int argc, char **argv, char *xwhere,
52b22328f9Schristos char *mwhere, char *mfile, int shorten,
53b22328f9Schristos int local_specified, char *mname, char *msg);
54b22328f9Schristos
55b22328f9Schristos static FILE *open_accessfile (char *xmode, const char *repos, char **fname);
56b22328f9Schristos static FILE *open_groupfile (char *xmode);
57b22328f9Schristos
58b22328f9Schristos static char *get_perms (const char *xperms);
59b22328f9Schristos static char *make_perms (char *xperms, char *xfounduserpart, char **xerrmsg);
60b22328f9Schristos
61b22328f9Schristos static char *findusername (const char *string1, const char *string2);
62b22328f9Schristos static char *findgroupname (const char *string1, const char *string2);
63b22328f9Schristos static int valid_tag (const char *part_tag, const char *tag);
64b22328f9Schristos static int valid_perm (const char *part_perms, int perm);
65b22328f9Schristos static int write_perms (const char *user, const char *perms,
66b22328f9Schristos const char *founduserpart, int foundline,
67b22328f9Schristos char *otheruserparts, const char *part_type,
68b22328f9Schristos const char *part_object, const char *part_tag, int pos,
69b22328f9Schristos const char *arepos);
70b22328f9Schristos
71b22328f9Schristos static char *cache_repository;
72b22328f9Schristos static int cache_retval;
73b22328f9Schristos static int founddeniedfile;
74b22328f9Schristos static int cache_perm;
75b22328f9Schristos
76b22328f9Schristos static int is_racl;
77b22328f9Schristos static int debug = 0;
78b22328f9Schristos
79b22328f9Schristos int use_cvs_acl = 0;
80b22328f9Schristos char *cvs_acl_default_permissions;
81b22328f9Schristos int use_cvs_groups = 0;
82b22328f9Schristos int use_system_groups = 0;
83b22328f9Schristos int use_separate_acl_file_for_each_dir = 0;
84b22328f9Schristos char *cvs_acl_file_location = NULL;
85b22328f9Schristos char *cvs_groups_file_location = NULL;
86b22328f9Schristos char *cvs_server_run_as = NULL;
87b22328f9Schristos int stop_at_first_permission_denied = 0;
88b22328f9Schristos
89b22328f9Schristos char *tag = NULL;
90b22328f9Schristos
91b22328f9Schristos char *muser;
92b22328f9Schristos char *mperms;
93b22328f9Schristos static int defaultperms;
94b22328f9Schristos
95b22328f9Schristos static char *default_perms_object;
96b22328f9Schristos char *default_part_perms_accessfile;
97b22328f9Schristos int aclconfig_default_used;
98b22328f9Schristos
99b22328f9Schristos int acldir = 0;
100b22328f9Schristos int aclfile = 0;
101b22328f9Schristos int listacl = 0;
102b22328f9Schristos
103b22328f9Schristos int userfound = 0;
104b22328f9Schristos int groupfound = 0;
105b22328f9Schristos
106b22328f9Schristos /* directory depth ... */
107b22328f9Schristos char *dirs[255];
108b22328f9Schristos
109b22328f9Schristos static const char *const acl_usage[] =
110b22328f9Schristos {
111b22328f9Schristos "Usage: %s %s [user||group:permissions] [-Rl] [-r tag] [directories...] [files...]\n",
112b22328f9Schristos "\t-R\tProcess directories recursively.\n",
113b22328f9Schristos "\t-r rev\tExisting revision/tag.\n",
114b22328f9Schristos "\t-l\tList defined ACLs.\n",
115b22328f9Schristos "(Specify the --help global option for a list of other help options)\n",
116b22328f9Schristos NULL
117b22328f9Schristos };
118b22328f9Schristos
119b22328f9Schristos static const char *const racl_usage[] =
120b22328f9Schristos {
121b22328f9Schristos "Usage: %s %s [user||group:permissions] [-Rl] [-r tag] [directories...]"
122b22328f9Schristos " [files...]\n",
123b22328f9Schristos "\t-R\tProcess directories recursively.\n",
124b22328f9Schristos "\t-r rev\tExisting revision/tag.\n",
125b22328f9Schristos "\t-l\tList defined ACLs.\n",
126b22328f9Schristos "(Specify the --help global option for a list of other help options)\n",
127b22328f9Schristos NULL
128b22328f9Schristos };
129b22328f9Schristos
130b22328f9Schristos
131b22328f9Schristos int
access_allowed(const char * file,const char * repos,const char * tag,int perm,char ** mline,int * mpos,int usecache)132b22328f9Schristos access_allowed (const char *file, const char *repos, const char *tag,
133b22328f9Schristos int perm, char **mline, int *mpos, int usecache)
134b22328f9Schristos {
135b22328f9Schristos int retval = 0;
136b22328f9Schristos int foundline = 0;
137b22328f9Schristos FILE *accessfp;
138b22328f9Schristos
139b22328f9Schristos int flag = 1;
140b22328f9Schristos
141b22328f9Schristos char *iline;
142b22328f9Schristos char *tempv;
143b22328f9Schristos char *tempc;
144b22328f9Schristos size_t tempsize;
145b22328f9Schristos
146b22328f9Schristos int intcount;
147b22328f9Schristos int accessfilecount;
148b22328f9Schristos int signlevel = -1;
149b22328f9Schristos int dadmin = 0;
150b22328f9Schristos
151b22328f9Schristos const char *repository;
152b22328f9Schristos char *filefullname = NULL;
153b22328f9Schristos userfound = 0;
154b22328f9Schristos groupfound = 0;
155b22328f9Schristos
156b22328f9Schristos if (defaultperms)
157b22328f9Schristos {
158b22328f9Schristos repository = xstrdup ("ALL");
159b22328f9Schristos }
160b22328f9Schristos else {
161b22328f9Schristos if (strlen(repository = Short_Repository (repos)) == 0)
162b22328f9Schristos {
163b22328f9Schristos repository = xstrdup (".");
164b22328f9Schristos }
165b22328f9Schristos }
166b22328f9Schristos
167b22328f9Schristos /* cache */
168b22328f9Schristos if (usecache && cache_repository != NULL &&
169b22328f9Schristos strcmp (cache_repository, repository) == 0 && !founddeniedfile
170b22328f9Schristos && perm == cache_perm)
171b22328f9Schristos return (cache_retval);
172b22328f9Schristos else
173b22328f9Schristos {
174b22328f9Schristos free (cache_repository);
175b22328f9Schristos cache_repository = xstrdup (repository);
176b22328f9Schristos cache_perm = perm;
177b22328f9Schristos }
178b22328f9Schristos
179b22328f9Schristos iline = xstrdup(repository);
180b22328f9Schristos
181b22328f9Schristos tempv = strtok(iline, "/\t");
182b22328f9Schristos tempc = xstrdup(tempv);
183b22328f9Schristos tempsize = ( tempc != NULL ) ? strlen(tempc) : 0;
184b22328f9Schristos
185b22328f9Schristos intcount = 0;
186b22328f9Schristos /* store paths from object to cvsroot */
187b22328f9Schristos dirs[intcount] = xstrdup(tempc);
188b22328f9Schristos while ((tempv = strtok(NULL, "/\t")) != NULL)
189b22328f9Schristos {
190b22328f9Schristos intcount++;
191b22328f9Schristos
192b22328f9Schristos xrealloc_and_strcat(&tempc, &tempsize, "/");
193b22328f9Schristos xrealloc_and_strcat(&tempc, &tempsize, tempv);
194b22328f9Schristos
195b22328f9Schristos dirs[intcount] = xstrdup(tempc);
196b22328f9Schristos }
197b22328f9Schristos
198b22328f9Schristos /* free not needed variables here */
199b22328f9Schristos free (tempv);
200b22328f9Schristos free (tempc);
201b22328f9Schristos free (iline);
202b22328f9Schristos
203b22328f9Schristos /* accessfilecount will used
204b22328f9Schristos * if UseSeparateACLFile keyword is set to yes*/
205b22328f9Schristos accessfilecount = intcount;
206b22328f9Schristos
207b22328f9Schristos /* if file is not null add it to dirs array */
208b22328f9Schristos if (file != NULL)
209b22328f9Schristos {
210b22328f9Schristos filefullname = Xasprintf("%s/%s", repository, file);
211b22328f9Schristos intcount++;
212b22328f9Schristos dirs[intcount] = xstrdup(filefullname);
213b22328f9Schristos }
214b22328f9Schristos
215c8891c48Schristos for (; accessfilecount >= 0 && flag; accessfilecount--)
216b22328f9Schristos {
217b22328f9Schristos if (!use_separate_acl_file_for_each_dir) {
218b22328f9Schristos flag = 0;
219b22328f9Schristos accessfp = open_accessfile ("r", repository, NULL);
220b22328f9Schristos }
221b22328f9Schristos else
222b22328f9Schristos {
223b22328f9Schristos flag = 1;
224b22328f9Schristos accessfp = open_accessfile ("r", dirs[accessfilecount], NULL);
225b22328f9Schristos }
226b22328f9Schristos
227b22328f9Schristos if (accessfp != NULL)
228b22328f9Schristos {
229b22328f9Schristos char *line = NULL;
230b22328f9Schristos size_t line_allocated = 0;
231b22328f9Schristos
232b22328f9Schristos char *xline;
233b22328f9Schristos char *part_type = NULL;
234b22328f9Schristos char *part_object = NULL;
235b22328f9Schristos char *part_tag = NULL;
236b22328f9Schristos char *part_perms = NULL;
237b22328f9Schristos
238b22328f9Schristos int x;
239b22328f9Schristos
240b22328f9Schristos while (getline (&line, &line_allocated, accessfp) >= 0)
241b22328f9Schristos {
242b22328f9Schristos
243b22328f9Schristos if (line[0] == '#' || line[0] == '\0' || line[0] == '\n')
244b22328f9Schristos continue;
245b22328f9Schristos
246b22328f9Schristos xline = xstrdup (line);
247b22328f9Schristos part_type = strtok (line, ":\t");
248b22328f9Schristos part_object = strtok (NULL, ":\t");
249b22328f9Schristos part_tag = strtok (NULL, ":\t");
250b22328f9Schristos part_perms = strtok (NULL, ":\t");
251b22328f9Schristos
252b22328f9Schristos if (part_type == NULL || part_object == NULL ||
253b22328f9Schristos part_tag == NULL || part_perms == NULL)
254b22328f9Schristos {
255b22328f9Schristos free (line);
256b22328f9Schristos error(1, 0, "access file is corrupted or has invalid"
257b22328f9Schristos " format");
258b22328f9Schristos }
259b22328f9Schristos
260b22328f9Schristos if (debug) fprintf (stderr, "type %s object %s tag %s perms"
261b22328f9Schristos "%s\n", part_type, part_object, part_tag,
262b22328f9Schristos part_perms);
263b22328f9Schristos for (x = intcount; x >= signlevel && x != -1; x--)
264b22328f9Schristos {
265b22328f9Schristos if (debug) fprintf (stderr, "dirs[%d] = %s, part_object="
266b22328f9Schristos "%s\n", x, dirs[x], part_object);
267b22328f9Schristos if (strcmp (dirs[x], part_object) == 0)
268b22328f9Schristos {
269b22328f9Schristos if (debug) fprintf(stderr, "tag %s \n", tag);
270b22328f9Schristos if (valid_tag (part_tag, tag))
271b22328f9Schristos {
272b22328f9Schristos foundline = 1;
273b22328f9Schristos if (debug) fprintf(stderr, "foundline\n");
274b22328f9Schristos
275b22328f9Schristos if (listacl || ((acldir || aclfile) &&
276b22328f9Schristos x == intcount) &&
277b22328f9Schristos strcmp(part_tag, tag) == 0)
278b22328f9Schristos {
279b22328f9Schristos *mline = xstrdup (xline);
280b22328f9Schristos *mpos = ftell (accessfp);
281b22328f9Schristos }
282b22328f9Schristos
283b22328f9Schristos if (debug) fprintf(stderr, "perm %d\n", perm);
284b22328f9Schristos if (valid_perm (part_perms, perm))
285b22328f9Schristos {
286eedd1cd9Schristos if (debug) fprintf(stderr, "signlevel=%d "
287eedd1cd9Schristos " x=%d, aclconfig_default_used=%d\n",
288eedd1cd9Schristos signlevel, x, aclconfig_default_used);
289b22328f9Schristos if (signlevel == x)
290b22328f9Schristos {
291b22328f9Schristos if (strcmp(part_tag, "ALL") != 0 &&
292eedd1cd9Schristos !aclconfig_default_used) {
293b22328f9Schristos retval = 1;
294eedd1cd9Schristos if (debug) fprintf(stderr,
295eedd1cd9Schristos "%s, %d: %d\n", __FILE__, __LINE__,
296eedd1cd9Schristos retval);
297eedd1cd9Schristos }
298b22328f9Schristos }
299b22328f9Schristos else if (!aclconfig_default_used)
300b22328f9Schristos {
301b22328f9Schristos signlevel = x;
302b22328f9Schristos retval = 1;
303eedd1cd9Schristos if (debug) fprintf(stderr,
304eedd1cd9Schristos "%s, %d: %d\n", __FILE__, __LINE__,
305eedd1cd9Schristos retval);
306b22328f9Schristos }
307b22328f9Schristos else {
308b22328f9Schristos /* nothing... */
309b22328f9Schristos }
310b22328f9Schristos }
311b22328f9Schristos else
312b22328f9Schristos {
313b22328f9Schristos if (signlevel == x)
314b22328f9Schristos {
315b22328f9Schristos if (strcmp(part_tag, "ALL") != 0 &&
316eedd1cd9Schristos !aclconfig_default_used) {
317b22328f9Schristos retval = 0;
318eedd1cd9Schristos if (debug) fprintf(stderr,
319eedd1cd9Schristos "%s, %d: %d\n", __FILE__, __LINE__,
320eedd1cd9Schristos retval);
321eedd1cd9Schristos }
322b22328f9Schristos }
323b22328f9Schristos else if (!aclconfig_default_used)
324b22328f9Schristos {
325b22328f9Schristos signlevel = x;
326b22328f9Schristos retval = 0;
327eedd1cd9Schristos if (debug) fprintf(stderr,
328eedd1cd9Schristos "%s, %d: %d\n", __FILE__, __LINE__,
329eedd1cd9Schristos retval);
330b22328f9Schristos
331b22328f9Schristos if (strncmp (part_type, "f", 1) == 0)
332b22328f9Schristos founddeniedfile = 1;
333b22328f9Schristos }
334b22328f9Schristos else {
335b22328f9Schristos }
336b22328f9Schristos }
337b22328f9Schristos }
338b22328f9Schristos }
339b22328f9Schristos }
340b22328f9Schristos
341b22328f9Schristos if (debug) fprintf (stderr, "xline tag = %s %d %d\n", xline,
342b22328f9Schristos groupfound, userfound);
343b22328f9Schristos if (strncmp (xline, "d:ALL:", 6) == 0 &&
344b22328f9Schristos ((!groupfound && !userfound) || listacl))
345b22328f9Schristos {
346b22328f9Schristos if (debug) fprintf (stderr, "ALL tag = %s\n", tag);
347b22328f9Schristos /* a default found */
348b22328f9Schristos if (valid_tag (part_tag, tag) > 0)
349b22328f9Schristos {
350b22328f9Schristos foundline = 1;
351b22328f9Schristos
352b22328f9Schristos default_part_perms_accessfile = xstrdup (part_perms);
353b22328f9Schristos
354b22328f9Schristos if (debug) fprintf (stderr, "valid perm = %d\n", perm);
355b22328f9Schristos if (valid_perm (part_perms, perm))
356b22328f9Schristos {
357b22328f9Schristos retval = 1;
358eedd1cd9Schristos if (debug) fprintf(stderr,
359eedd1cd9Schristos "%s, %d: %d\n", __FILE__, __LINE__,
360eedd1cd9Schristos retval);
361b22328f9Schristos if (perm == 8)
362b22328f9Schristos dadmin = 1;
363b22328f9Schristos }
364eedd1cd9Schristos else {
365b22328f9Schristos retval = 0;
366eedd1cd9Schristos if (debug) fprintf(stderr,
367eedd1cd9Schristos "%s, %d: %d\n", __FILE__, __LINE__,
368eedd1cd9Schristos retval);
369eedd1cd9Schristos }
370b22328f9Schristos }
371b22328f9Schristos }
372b22328f9Schristos
373b22328f9Schristos }
374b22328f9Schristos
375b22328f9Schristos if (fclose (accessfp) == EOF)
376b22328f9Schristos error (1, errno, "cannot close 'access' file");
377b22328f9Schristos }
378b22328f9Schristos }
379b22328f9Schristos
380b22328f9Schristos if (!foundline)
381b22328f9Schristos {
382b22328f9Schristos if (debug) fprintf(stderr, "not found line\n");
383b22328f9Schristos /* DEFAULT */
384eedd1cd9Schristos if (valid_perm (NULL, perm)) {
385b22328f9Schristos retval = 1;
386eedd1cd9Schristos if (debug) fprintf(stderr,
387eedd1cd9Schristos "%s, %d: %d\n", __FILE__, __LINE__,
388eedd1cd9Schristos retval);
389eedd1cd9Schristos } else {
390b22328f9Schristos retval = 0;
391eedd1cd9Schristos if (debug) fprintf(stderr,
392eedd1cd9Schristos "%s, %d: %d\n", __FILE__, __LINE__,
393eedd1cd9Schristos retval);
394eedd1cd9Schristos }
395b22328f9Schristos }
396b22328f9Schristos
397b22328f9Schristos /* acl admin rigths 'p' */
398b22328f9Schristos if (dadmin)
399b22328f9Schristos {
400b22328f9Schristos retval = dadmin;
401b22328f9Schristos }
402b22328f9Schristos
403b22328f9Schristos cache_retval = retval;
404b22328f9Schristos
405b22328f9Schristos free (filefullname);
406b22328f9Schristos /* free directories array */
407b22328f9Schristos while (intcount >= 0)
408b22328f9Schristos {
409b22328f9Schristos free (dirs[intcount]);
410b22328f9Schristos intcount--;
411b22328f9Schristos }
412b22328f9Schristos
413b22328f9Schristos return retval;
414b22328f9Schristos }
415b22328f9Schristos
416b22328f9Schristos /* Returns 1 if tag is valid, 0 if not */
417b22328f9Schristos static int
valid_tag(const char * part_tag,const char * tag)418b22328f9Schristos valid_tag (const char *part_tag, const char *tag)
419b22328f9Schristos {
420b22328f9Schristos int retval;
421b22328f9Schristos
422b22328f9Schristos if (tag == NULL)
423b22328f9Schristos tag = "HEAD";
424b22328f9Schristos
425b22328f9Schristos if (strcmp (tag, part_tag) == 0 || strcmp (part_tag, "ALL") == 0)
426b22328f9Schristos retval = 1;
427b22328f9Schristos else
428b22328f9Schristos retval = 0;
429b22328f9Schristos
430b22328f9Schristos return retval;
431b22328f9Schristos }
432b22328f9Schristos
433b22328f9Schristos /* Returns 1 if successful, 0 if not. */
434b22328f9Schristos static int
valid_perm(const char * part_perms,int perm)435b22328f9Schristos valid_perm (const char *part_perms, int perm)
436b22328f9Schristos {
437b22328f9Schristos char *perms;
438b22328f9Schristos int retval = 0;
439b22328f9Schristos
440b22328f9Schristos perms = get_perms (part_perms);
441b22328f9Schristos
442b22328f9Schristos /* Allow, if nothing found. */
443b22328f9Schristos if (perms[0] == '\0')
444b22328f9Schristos return (1);
445b22328f9Schristos
446b22328f9Schristos /* no access allowed, exit */
447b22328f9Schristos if (strstr (perms, "n"))
448b22328f9Schristos retval = 0;
449b22328f9Schristos
450b22328f9Schristos if (strstr (perms, "p"))
451b22328f9Schristos /* admin rights */
452b22328f9Schristos retval = 1;
453b22328f9Schristos else if (strstr (perms, "a") && perm != 8)
454b22328f9Schristos /* all access allowed, exit */
455b22328f9Schristos retval = 1;
456b22328f9Schristos else
457b22328f9Schristos switch (perm)
458b22328f9Schristos {
459b22328f9Schristos case 3:/* write permission */
460b22328f9Schristos if (strstr (perms, "w"))
461b22328f9Schristos retval = 1;
462b22328f9Schristos break;
463b22328f9Schristos case 4:/* tag permission */
464b22328f9Schristos if (strstr (perms, "t"))
465b22328f9Schristos retval = 1;
466b22328f9Schristos break;
467b22328f9Schristos case 5:/* read permission */
468b22328f9Schristos if (strstr (perms, "w") || strstr (perms, "t") ||
469b22328f9Schristos strstr (perms, "c") || strstr (perms, "d") ||
470b22328f9Schristos strstr (perms, "r"))
471b22328f9Schristos retval = 1;
472b22328f9Schristos break;
473b22328f9Schristos case 6:/* create permission */
474b22328f9Schristos if (strstr (perms, "c"))
475b22328f9Schristos retval = 1;
476b22328f9Schristos break;
477b22328f9Schristos case 7:/* delete permission */
478b22328f9Schristos if (strstr (perms, "d"))
479b22328f9Schristos retval = 1;
480b22328f9Schristos break;
481b22328f9Schristos case 8:/* permission change */
482b22328f9Schristos if (strstr (perms, "p"))
483b22328f9Schristos retval = 1;
484b22328f9Schristos break;
485b22328f9Schristos default:/* never reached */
486b22328f9Schristos retval = 0;
487b22328f9Schristos break;
488b22328f9Schristos }
489b22328f9Schristos
490b22328f9Schristos free (perms);
491b22328f9Schristos
492b22328f9Schristos return (retval);
493b22328f9Schristos }
494b22328f9Schristos
495b22328f9Schristos /* returns permissions found */
496b22328f9Schristos char *
get_perms(const char * part_perms)497b22328f9Schristos get_perms (const char *part_perms)
498b22328f9Schristos {
499b22328f9Schristos char *username;
500b22328f9Schristos char *xperms;
501b22328f9Schristos size_t xperms_len = 1;
502b22328f9Schristos
503b22328f9Schristos FILE *groupfp;
504b22328f9Schristos
505b22328f9Schristos char *founduser = NULL;
506b22328f9Schristos char *foundall = NULL;
507b22328f9Schristos int default_checked = 0;
508b22328f9Schristos
509b22328f9Schristos if (debug) fprintf (stderr, "get_perms %s...", part_perms);
510b22328f9Schristos aclconfig_default_used = 0;
511b22328f9Schristos
512b22328f9Schristos xperms = xmalloc (xperms_len);
513b22328f9Schristos xperms[0] = '\0';
514b22328f9Schristos
515b22328f9Schristos /* use CVS_Username if set */
516b22328f9Schristos if (CVS_Username == NULL)
517b22328f9Schristos username = getcaller ();
518b22328f9Schristos else
519b22328f9Schristos username = CVS_Username;
520b22328f9Schristos
521b22328f9Schristos /* no defined acl, no default acl in access file,
522b22328f9Schristos * or no access file at all */
523b22328f9Schristos if (part_perms == NULL) {
524b22328f9Schristos if (cvs_acl_default_permissions)
525b22328f9Schristos {
526b22328f9Schristos aclconfig_default_used = 1;
527b22328f9Schristos if (debug) fprintf (stderr, "default %s\n",
528b22328f9Schristos cvs_acl_default_permissions);
529eedd1cd9Schristos return xstrdup(cvs_acl_default_permissions);
530b22328f9Schristos }
531b22328f9Schristos else {
532b22328f9Schristos if (debug) fprintf (stderr, "early %s\n", xperms);
533b22328f9Schristos return xperms;
534b22328f9Schristos }
535b22328f9Schristos }
536b22328f9Schristos
537b22328f9Schristos check_default:
538b22328f9Schristos founduser = findusername (part_perms, username);
539b22328f9Schristos foundall = strstr (part_perms, "ALL!");
540b22328f9Schristos
541b22328f9Schristos if (debug) fprintf (stderr, "founduser=%s foundALL=%s\n",
542b22328f9Schristos founduser, foundall);
543b22328f9Schristos if (founduser)
544b22328f9Schristos {
545b22328f9Schristos char *usr;
546b22328f9Schristos char *per;
547b22328f9Schristos
548b22328f9Schristos usr = strtok (founduser, "!\t");
549b22328f9Schristos per = strtok (NULL, ",\t");
550b22328f9Schristos
551cc7958a0Schristos free(xperms);
552b22328f9Schristos xperms = xstrdup (per);
553b22328f9Schristos xperms_len = strlen (xperms);
554b22328f9Schristos
555b22328f9Schristos userfound = 1;
556cc7958a0Schristos free (founduser);
557b22328f9Schristos }
558b22328f9Schristos else
559b22328f9Schristos {
560b22328f9Schristos if (debug) fprintf (stderr, "usesystemgroups=%d\n", use_system_groups);
561b22328f9Schristos if (use_system_groups) {
562b22328f9Schristos struct group *griter;
563d1f48bffSchristos struct passwd *pwd;
564d1f48bffSchristos gid_t gid = (pwd = getpwnam(username)) != NULL ? pwd->pw_gid : -1;
565b22328f9Schristos setgrent ();
566b22328f9Schristos while (griter = getgrent ())
567b22328f9Schristos {
568d1f48bffSchristos char *userchk;
569d1f48bffSchristos if (gid == griter->gr_gid) {
570d1f48bffSchristos userchk = username;
571d1f48bffSchristos } else {
572b22328f9Schristos char **users = griter->gr_mem;
573b22328f9Schristos int index = 0;
574d1f48bffSchristos userchk = users [index++];
575b22328f9Schristos while(userchk != NULL) {
576b22328f9Schristos if(strcmp (userchk, username) == 0)
577b22328f9Schristos break;
578b22328f9Schristos userchk = users[index++];
579b22328f9Schristos }
580d1f48bffSchristos }
581b22328f9Schristos if (userchk != NULL) {
582b22328f9Schristos char *grp;
583b22328f9Schristos if ((grp = findusername (part_perms, griter->gr_name)))
584b22328f9Schristos {
585b22328f9Schristos char *gperm = strtok (grp, "!\t");
586b22328f9Schristos if (debug) fprintf (stderr, "usercheck=%s, grp=%s\n",
587b22328f9Schristos userchk, grp);
588b22328f9Schristos gperm = strtok (NULL, ",\t");
589b22328f9Schristos xrealloc_and_strcat (&xperms, &xperms_len, gperm);
590b22328f9Schristos
591b22328f9Schristos groupfound = 1;
592cc7958a0Schristos free (grp);
593b22328f9Schristos }
594b22328f9Schristos }
595b22328f9Schristos }
596b22328f9Schristos endgrent ();
597b22328f9Schristos }
598b22328f9Schristos else if (use_cvs_groups) {
599b22328f9Schristos groupfp = open_groupfile ("r");
600b22328f9Schristos if (groupfp != NULL)
601b22328f9Schristos {
602b22328f9Schristos char *line = NULL;
603b22328f9Schristos char *grp;
604b22328f9Schristos char *gperm;
605b22328f9Schristos int read;
606b22328f9Schristos
607b22328f9Schristos size_t line_allocated = 0;
608b22328f9Schristos
609b22328f9Schristos while ((read = getline (&line, &line_allocated, groupfp)) >= 0)
610b22328f9Schristos {
611cc7958a0Schristos char *user;
612b22328f9Schristos if (line[0] == '#' || line[0] == '\0' || line[0] == '\n')
613b22328f9Schristos continue;
614b22328f9Schristos
615b22328f9Schristos if (line[read - 1] == '\n')
616b22328f9Schristos line[--read] = '\0';
617b22328f9Schristos
618cc7958a0Schristos if ((grp = findgroupname (line, username)) &&
619cc7958a0Schristos (user = findusername (part_perms, grp)))
620cc7958a0Schristos
621b22328f9Schristos {
622cc7958a0Schristos gperm = strtok (user, "!\t");
623b22328f9Schristos gperm = strtok (NULL, ",\t");
624b22328f9Schristos xrealloc_and_strcat (&xperms, &xperms_len, gperm);
625b22328f9Schristos groupfound = 1;
626cc7958a0Schristos free (grp);
627cc7958a0Schristos free (user);
628b22328f9Schristos }
629b22328f9Schristos }
630b22328f9Schristos
631b22328f9Schristos free (line);
632b22328f9Schristos
633b22328f9Schristos if (fclose (groupfp) == EOF)
634b22328f9Schristos error (1, errno, "cannot close 'group' file");
635b22328f9Schristos }
636b22328f9Schristos }
637b22328f9Schristos }
638b22328f9Schristos
639b22328f9Schristos if (foundall)
640b22328f9Schristos {
641b22328f9Schristos char *usr;
642b22328f9Schristos char *per;
643b22328f9Schristos
644b22328f9Schristos usr = strtok (strstr (part_perms, "ALL!"), "!\t");
645b22328f9Schristos per = strtok (NULL, ",\t");
646b22328f9Schristos
647b22328f9Schristos if (!default_checked)
648b22328f9Schristos default_perms_object = xstrdup (per);
649b22328f9Schristos
650b22328f9Schristos if (xperms[0] == '\0')
651b22328f9Schristos {
652b22328f9Schristos xperms = xstrdup (per);
653b22328f9Schristos xperms_len = strlen (xperms);
654b22328f9Schristos }
655b22328f9Schristos
656b22328f9Schristos /* You don't free pointers from strtok()! */
657b22328f9Schristos //free(usr);
658b22328f9Schristos //free(per);
659b22328f9Schristos }
660b22328f9Schristos
661b22328f9Schristos if (xperms[0] == '\0' && !default_checked && default_part_perms_accessfile)
662b22328f9Schristos {
663b22328f9Schristos part_perms = xstrdup (default_part_perms_accessfile);
664b22328f9Schristos default_checked = 1;
665b22328f9Schristos
666b22328f9Schristos goto check_default;
667b22328f9Schristos }
668b22328f9Schristos
669b22328f9Schristos if (xperms[0] != '\0' && strcmp (xperms, "x") == 0)
670b22328f9Schristos {
671b22328f9Schristos if (default_perms_object)
672b22328f9Schristos xperms = xstrdup (default_perms_object);
673b22328f9Schristos else if (default_part_perms_accessfile)
674b22328f9Schristos {
675b22328f9Schristos part_perms = default_part_perms_accessfile;
676b22328f9Schristos default_checked = 1;
677b22328f9Schristos goto check_default;
678b22328f9Schristos }
679b22328f9Schristos else if (cvs_acl_default_permissions)
680b22328f9Schristos {
681b22328f9Schristos aclconfig_default_used = 1;
682b22328f9Schristos xperms = xstrdup (cvs_acl_default_permissions);
683b22328f9Schristos }
684b22328f9Schristos }
685b22328f9Schristos
686b22328f9Schristos if (xperms[0] == '\0' && cvs_acl_default_permissions)
687b22328f9Schristos {
688b22328f9Schristos aclconfig_default_used = 1;
689b22328f9Schristos xperms = xstrdup (cvs_acl_default_permissions);
690b22328f9Schristos }
691b22328f9Schristos
692b22328f9Schristos if (debug) fprintf (stderr, "late %s\n", xperms);
693b22328f9Schristos return xperms;
694b22328f9Schristos }
695b22328f9Schristos
696b22328f9Schristos
697b22328f9Schristos int
cvsacl(int argc,char ** argv)698b22328f9Schristos cvsacl (int argc, char **argv)
699b22328f9Schristos {
700b22328f9Schristos char *chdirrepository;
701b22328f9Schristos int c;
702b22328f9Schristos int err = 0;
703b22328f9Schristos int usetag = 0;
704b22328f9Schristos int recursive = 0;
705b22328f9Schristos
706b22328f9Schristos int which;
707b22328f9Schristos char *where;
708b22328f9Schristos
709b22328f9Schristos is_racl = (strcmp (cvs_cmd_name, "racl") == 0);
710b22328f9Schristos
711b22328f9Schristos if (argc == -1)
712b22328f9Schristos usage (is_racl ? racl_usage : acl_usage);
713b22328f9Schristos
714b22328f9Schristos /* parse the args */
715b22328f9Schristos optind = 0;
716b22328f9Schristos
717b22328f9Schristos while ((c = getopt (argc, argv, "dRr:l")) != -1)
718b22328f9Schristos {
719b22328f9Schristos switch (c)
720b22328f9Schristos {
721b22328f9Schristos case 'd':
722b22328f9Schristos debug++;
723b22328f9Schristos break;
724b22328f9Schristos case 'R':
725b22328f9Schristos recursive = 1;
726b22328f9Schristos break;
727b22328f9Schristos case 'r': // baris
728b22328f9Schristos tag = xstrdup (optarg);
729b22328f9Schristos break;
730b22328f9Schristos case 'l':
731b22328f9Schristos listacl = 1;
732b22328f9Schristos break;
733b22328f9Schristos case '?':
734b22328f9Schristos default:
735b22328f9Schristos usage (is_racl ? racl_usage : acl_usage);
736b22328f9Schristos break;
737b22328f9Schristos }
738b22328f9Schristos }
739b22328f9Schristos
740b22328f9Schristos argc -= optind;
741b22328f9Schristos argv += optind;
742b22328f9Schristos
743b22328f9Schristos if (argc < (is_racl ? 1 : 1))
744b22328f9Schristos usage (is_racl ? racl_usage : acl_usage);
745b22328f9Schristos if (listacl) {
746b22328f9Schristos if (strstr (argv[0], ":"))
747b22328f9Schristos usage (is_racl ? racl_usage : acl_usage);
748b22328f9Schristos } else {
749b22328f9Schristos if (!strstr (argv[0], ":"))
750b22328f9Schristos usage (is_racl ? racl_usage : acl_usage);
751b22328f9Schristos }
752b22328f9Schristos
753b22328f9Schristos
754b22328f9Schristos #ifdef CLIENT_SUPPORT
755b22328f9Schristos
756b22328f9Schristos if (current_parsed_root->isremote)
757b22328f9Schristos {
758b22328f9Schristos start_server ();
759b22328f9Schristos ign_setup ();
760b22328f9Schristos
761b22328f9Schristos if(recursive)
762b22328f9Schristos send_arg ("-R");
763b22328f9Schristos
764b22328f9Schristos if (listacl)
765b22328f9Schristos send_arg ("-l");
766b22328f9Schristos
767b22328f9Schristos if(tag)
768b22328f9Schristos {
769b22328f9Schristos option_with_arg ("-r", tag);
770b22328f9Schristos }
771b22328f9Schristos
772b22328f9Schristos send_arg ("--");
773b22328f9Schristos
774b22328f9Schristos if (!listacl)
775b22328f9Schristos {
776b22328f9Schristos send_arg (argv[0]);
777b22328f9Schristos
778b22328f9Schristos argc--;
779b22328f9Schristos argv++;
780b22328f9Schristos }
781b22328f9Schristos
782b22328f9Schristos if (is_racl)
783b22328f9Schristos {
784b22328f9Schristos int i;
785b22328f9Schristos for (i = 0; i < argc; ++i)
786b22328f9Schristos send_arg (argv[i]);
787b22328f9Schristos
788b22328f9Schristos send_to_server ("racl\012",0);
789b22328f9Schristos }
790b22328f9Schristos else
791b22328f9Schristos {
792b22328f9Schristos send_files (argc, argv, recursive, 0, SEND_NO_CONTENTS);
793b22328f9Schristos send_file_names (argc, argv, SEND_EXPAND_WILD);
794b22328f9Schristos send_to_server ("acl\012", 0);
795b22328f9Schristos }
796b22328f9Schristos
797b22328f9Schristos return get_responses_and_close ();
798b22328f9Schristos }
799b22328f9Schristos #endif
800b22328f9Schristos
801b22328f9Schristos #ifdef SERVER_SUPPORT
802b22328f9Schristos
803b22328f9Schristos if (!listacl)
804b22328f9Schristos {
805b22328f9Schristos muser = strtok (argv[0], ":\t");
806b22328f9Schristos mperms = strtok (NULL, ":\t");
807b22328f9Schristos
808b22328f9Schristos /* if set to 'default' */
809b22328f9Schristos if ((strlen (mperms) == 7) && (strncmp (mperms, "default", 7) == 0))
810b22328f9Schristos mperms = xstrdup ("x");
811b22328f9Schristos
812b22328f9Schristos /* Check that the given permissions are valid. */
813b22328f9Schristos if (!given_perms_valid (mperms))
814b22328f9Schristos error (1,0,"Invalid permissions: `%s'", mperms);
815b22328f9Schristos
816b22328f9Schristos argc--;
817b22328f9Schristos argv++;
818b22328f9Schristos }
819b22328f9Schristos
820b22328f9Schristos
821b22328f9Schristos if (!tag)
822b22328f9Schristos tag = xstrdup ("HEAD");
823b22328f9Schristos
824b22328f9Schristos if (!strcasecmp (argv[0], "ALL"))
825b22328f9Schristos {
826b22328f9Schristos argv[0] = xstrdup (".");
827b22328f9Schristos defaultperms = 1;
828b22328f9Schristos if (!use_separate_acl_file_for_each_dir)
829b22328f9Schristos {
830b22328f9Schristos recursive = 0;
831b22328f9Schristos }
832b22328f9Schristos
833b22328f9Schristos }
834b22328f9Schristos
835b22328f9Schristos if (is_racl)
836b22328f9Schristos {
837b22328f9Schristos DBM *db;
838b22328f9Schristos int i;
839b22328f9Schristos db = open_module ();
840b22328f9Schristos for (i = 0; i < argc; i++)
841b22328f9Schristos {
842b22328f9Schristos err += do_module (db, argv[i], MISC, "ACL ing: ",
843b22328f9Schristos racl_proc, NULL, 0, !recursive, 0,
844b22328f9Schristos 0, NULL);
845b22328f9Schristos }
846b22328f9Schristos close_module (db);
847b22328f9Schristos }
848b22328f9Schristos else
849b22328f9Schristos {
850b22328f9Schristos err = racl_proc (argc + 1, argv - 1, NULL, NULL, NULL, 0, !recursive,
851b22328f9Schristos NULL, NULL);
852b22328f9Schristos }
853b22328f9Schristos
854b22328f9Schristos return err;
855b22328f9Schristos
856b22328f9Schristos #endif
857b22328f9Schristos }
858b22328f9Schristos
859b22328f9Schristos static int
racl_proc(int argc,char ** argv,char * xwhere,char * mwhere,char * mfile,int shorten,int local,char * mname,char * msg)860b22328f9Schristos racl_proc (int argc, char **argv, char *xwhere, char *mwhere,
861b22328f9Schristos char *mfile, int shorten, int local, char *mname, char *msg)
862b22328f9Schristos {
863b22328f9Schristos char *myargv[2];
864b22328f9Schristos int err = 0;
865b22328f9Schristos int which;
866cc7958a0Schristos char *repository;
867b22328f9Schristos char *where;
868b22328f9Schristos char *obj;
869b22328f9Schristos size_t objlen = 0;
870b22328f9Schristos
871b22328f9Schristos if (!use_cvs_acl)
872b22328f9Schristos {
873b22328f9Schristos error(1, 0, "CVSACL extension is not enabled, set `UseCVSACL=yes'"
874b22328f9Schristos " in aclconfig file");
875b22328f9Schristos }
876b22328f9Schristos
877b22328f9Schristos if (is_racl)
878b22328f9Schristos {
879cc7958a0Schristos char *v;
880b22328f9Schristos repository = Xasprintf ("%s/%s", current_parsed_root->directory,
881b22328f9Schristos argv[0]);
882cc7958a0Schristos where = xstrdup (argv[0]);
883b22328f9Schristos
884b22328f9Schristos /* if mfile isn't null, we need to set up to do only part of the
885b22328f9Schristos * module */
886b22328f9Schristos if (mfile != NULL)
887b22328f9Schristos {
888b22328f9Schristos char *cp;
889b22328f9Schristos char *path;
890b22328f9Schristos
891b22328f9Schristos /* if the portion of the module is a path, put the dir part on
892b22328f9Schristos * repos */
893b22328f9Schristos if ((cp = strrchr (mfile, '/')) != NULL)
894b22328f9Schristos {
895b22328f9Schristos *cp = '\0';
896cc7958a0Schristos v = Xasprintf ("%s/%s", repository, mfile);
897cc7958a0Schristos free (repository);
898cc7958a0Schristos repository = v;
899cc7958a0Schristos v = Xasprintf ("%s/%s", where, mfile);
900cc7958a0Schristos free(where);
901cc7958a0Schristos where = v;
902b22328f9Schristos mfile = cp + 1;
903b22328f9Schristos }
904b22328f9Schristos
905b22328f9Schristos /* take care of the rest */
906b22328f9Schristos path = Xasprintf ("%s/%s", repository, mfile);
907b22328f9Schristos if (isdir (path))
908b22328f9Schristos {
909b22328f9Schristos /* directory means repository gets the dir tacked on */
910cc7958a0Schristos free(repository);
911cc7958a0Schristos repository = path;
912cc7958a0Schristos v = Xasprintf ("%s/%s", where, mfile);
913cc7958a0Schristos free(where);
914cc7958a0Schristos where = v;
915b22328f9Schristos }
916b22328f9Schristos else
917b22328f9Schristos {
918cc7958a0Schristos free (path);
919b22328f9Schristos myargv[0] = argv[0];
920b22328f9Schristos myargv[1] = mfile;
921b22328f9Schristos argc = 2;
922b22328f9Schristos argv = myargv;
923b22328f9Schristos }
924b22328f9Schristos }
925b22328f9Schristos
926b22328f9Schristos /* cd to the starting repository */
927b22328f9Schristos if ( CVS_CHDIR (repository) < 0)
928b22328f9Schristos {
929b22328f9Schristos error (0, errno, "cannot chdir to %s", repository);
930b22328f9Schristos free (repository);
931b22328f9Schristos free (where);
932b22328f9Schristos return 1;
933b22328f9Schristos }
934b22328f9Schristos
935b22328f9Schristos /* End section which is identical to patch_proc. */
936b22328f9Schristos
937b22328f9Schristos which = W_REPOS | W_ATTIC;
938b22328f9Schristos
939b22328f9Schristos if (argc > 1)
940b22328f9Schristos {
941b22328f9Schristos obj = Xasprintf ("%s/%s", repository, argv[1]);
942b22328f9Schristos }
943b22328f9Schristos else
944b22328f9Schristos {
945b22328f9Schristos obj = xstrdup(repository);
946b22328f9Schristos }
947b22328f9Schristos }
948b22328f9Schristos else
949b22328f9Schristos {
950b22328f9Schristos where = NULL;
951cc7958a0Schristos repository = NULL;
952b22328f9Schristos which = W_LOCAL | W_REPOS | W_ATTIC;
953b22328f9Schristos
954b22328f9Schristos obj = xstrdup (argv[1]);
955b22328f9Schristos }
956b22328f9Schristos
957b22328f9Schristos if (isdir (obj))
958b22328f9Schristos acldir = 1;
959b22328f9Schristos else if (isfile (obj))
960b22328f9Schristos aclfile = 1;
961b22328f9Schristos else
962b22328f9Schristos error(1, 0, "no such file or directory");
963b22328f9Schristos
964b22328f9Schristos free (obj);
965b22328f9Schristos
966b22328f9Schristos if (listacl)
967b22328f9Schristos err = start_recursion (acllist_fileproc, NULL, acllist_dirproc, NULL,
968b22328f9Schristos NULL, argc - 1, argv + 1, local, which, 0, 0,
969cc7958a0Schristos where, 1, repository);
970b22328f9Schristos else
971b22328f9Schristos err = start_recursion (acl_fileproc, NULL, acl_dirproc, NULL, NULL,
972b22328f9Schristos argc - 1, argv + 1, local, which, 0, 0,
973cc7958a0Schristos where, 1, repository);
974b22328f9Schristos
975b22328f9Schristos if (repository != NULL)
976b22328f9Schristos free (repository);
977cc7958a0Schristos if (where != NULL)
978cc7958a0Schristos free (where);
979b22328f9Schristos
980b22328f9Schristos return err;
981b22328f9Schristos }
982b22328f9Schristos
983b22328f9Schristos
984b22328f9Schristos static int
acl_fileproc(void * callerdat,struct file_info * finfo)985b22328f9Schristos acl_fileproc (void *callerdat, struct file_info *finfo)
986b22328f9Schristos {
987b22328f9Schristos char *filefullname;
988b22328f9Schristos char *founduserpart = NULL;
989b22328f9Schristos char *otheruserparts = NULL;
990b22328f9Schristos size_t otherslen = 0;
991b22328f9Schristos
992b22328f9Schristos const char *frepository;
993b22328f9Schristos int foundline = 0;
994b22328f9Schristos
995b22328f9Schristos char *line = NULL;
996b22328f9Schristos size_t line_allocated = 0;
997b22328f9Schristos int linelen;
998b22328f9Schristos
999b22328f9Schristos char *wperms;
1000b22328f9Schristos char *errmsg;
1001b22328f9Schristos
1002b22328f9Schristos int pos;
1003b22328f9Schristos
1004b22328f9Schristos if (!aclfile)
1005b22328f9Schristos return 0;
1006b22328f9Schristos
1007b22328f9Schristos frepository = Short_Repository (finfo->repository);
1008b22328f9Schristos
1009b22328f9Schristos filefullname = Xasprintf("%s/%s", frepository, finfo->file);
1010b22328f9Schristos
1011b22328f9Schristos
1012b22328f9Schristos if (!access_allowed (finfo->file, finfo->repository, tag, 8, &line, &pos,
1013b22328f9Schristos 0))
1014b22328f9Schristos error (1, 0, "You do not have acl admin rights on '%s'", frepository);
1015b22328f9Schristos
1016b22328f9Schristos if (line != NULL)
1017b22328f9Schristos {
1018b22328f9Schristos char *part_type = NULL;
1019b22328f9Schristos char *part_object = NULL;
1020b22328f9Schristos char *part_tag = NULL;
1021b22328f9Schristos char *part_perms = NULL;
1022b22328f9Schristos char *userpart;
1023b22328f9Schristos
1024b22328f9Schristos part_type = strtok (line, ":\t");
1025b22328f9Schristos part_object = strtok (NULL, ":\t");
1026b22328f9Schristos part_tag = strtok (NULL, ":\t");
1027b22328f9Schristos part_perms = strtok (NULL, ":\t");
1028b22328f9Schristos
1029b22328f9Schristos foundline = 1;
1030b22328f9Schristos userpart = strtok (part_perms, ",\t");
1031b22328f9Schristos
1032b22328f9Schristos do
1033b22328f9Schristos {
1034b22328f9Schristos if (strncmp (userpart, muser, strlen (muser)) == 0)
1035b22328f9Schristos founduserpart = xstrdup (userpart);
1036b22328f9Schristos else
1037b22328f9Schristos {
1038b22328f9Schristos if (otheruserparts != NULL)
1039b22328f9Schristos {
1040b22328f9Schristos xrealloc_and_strcat (&otheruserparts, &otherslen, ",");
1041b22328f9Schristos xrealloc_and_strcat (&otheruserparts, &otherslen, userpart);
1042b22328f9Schristos }
1043b22328f9Schristos else
1044b22328f9Schristos {
1045b22328f9Schristos otheruserparts = xstrdup (userpart);
1046b22328f9Schristos otherslen = strlen (otheruserparts);
1047b22328f9Schristos }
1048b22328f9Schristos }
1049b22328f9Schristos } while ((userpart = strtok (NULL, ",\t")) != NULL);
1050b22328f9Schristos
1051b22328f9Schristos free (userpart);
1052b22328f9Schristos }
1053b22328f9Schristos
1054b22328f9Schristos wperms = make_perms (mperms, founduserpart, &errmsg);
1055b22328f9Schristos if (wperms == NULL)
1056b22328f9Schristos {
1057b22328f9Schristos if (errmsg)
1058b22328f9Schristos error (0, 0, "`%s' %s", filefullname, errmsg);
1059b22328f9Schristos }
1060b22328f9Schristos else
1061b22328f9Schristos {
1062b22328f9Schristos cvs_output ("X ", 0);
1063b22328f9Schristos cvs_output (filefullname, 0);
1064b22328f9Schristos cvs_output ("\n", 0);
1065b22328f9Schristos
1066b22328f9Schristos write_perms (muser, wperms, founduserpart, foundline,
1067b22328f9Schristos otheruserparts, "f", filefullname, tag, pos,
1068b22328f9Schristos Short_Repository(finfo->repository));
1069b22328f9Schristos }
1070b22328f9Schristos
1071b22328f9Schristos free (line);
1072b22328f9Schristos free (founduserpart);
1073b22328f9Schristos free (otheruserparts);
1074b22328f9Schristos free (wperms);
1075b22328f9Schristos free (filefullname);
1076b22328f9Schristos
1077b22328f9Schristos return 0;
1078b22328f9Schristos }
1079b22328f9Schristos
1080b22328f9Schristos static Dtype
acl_dirproc(void * callerdat,const char * dir,const char * repos,const char * update_dir,List * entries)1081b22328f9Schristos acl_dirproc (void *callerdat, const char *dir, const char *repos,
1082b22328f9Schristos const char *update_dir, List *entries)
1083b22328f9Schristos {
1084b22328f9Schristos const char *drepository;
1085b22328f9Schristos char *founduserpart = NULL;
1086b22328f9Schristos char *otheruserparts = NULL;
1087b22328f9Schristos size_t otherslen = 0;
1088b22328f9Schristos int foundline = 0;
1089b22328f9Schristos
1090b22328f9Schristos char *line = NULL;
1091b22328f9Schristos size_t line_allocated = 0;
1092b22328f9Schristos int linelen;
1093b22328f9Schristos
1094b22328f9Schristos int pos;
1095b22328f9Schristos
1096b22328f9Schristos char *wperms;
1097b22328f9Schristos char *errmsg;
1098b22328f9Schristos
1099b22328f9Schristos if (!acldir)
1100b22328f9Schristos return 0;
1101b22328f9Schristos
1102b22328f9Schristos if (repos[0] == '\0')
1103b22328f9Schristos repos = Name_Repository (dir, NULL);
1104b22328f9Schristos
1105b22328f9Schristos if (!access_allowed (NULL, repos, tag, 8, &line, &pos, 0))
1106b22328f9Schristos error (1, 0, "You do not have admin rights on '%s'",
1107b22328f9Schristos Short_Repository (repos));
1108b22328f9Schristos
1109b22328f9Schristos drepository = Short_Repository (repos);
1110b22328f9Schristos
1111b22328f9Schristos if (line != NULL)
1112b22328f9Schristos {
1113b22328f9Schristos char *part_type = NULL;
1114b22328f9Schristos char *part_object = NULL;
1115b22328f9Schristos char *part_tag = NULL;
1116b22328f9Schristos char *part_perms = NULL;
1117b22328f9Schristos char *userpart;
1118b22328f9Schristos
1119b22328f9Schristos part_type = strtok (line, ":\t");
1120b22328f9Schristos part_object = strtok (NULL, ":\t");
1121b22328f9Schristos part_tag = strtok (NULL, ":\t");
1122b22328f9Schristos part_perms = strtok (NULL, ":\t");
1123b22328f9Schristos
1124b22328f9Schristos foundline = 1;
1125b22328f9Schristos userpart = strtok (part_perms, ",\t");
1126b22328f9Schristos
1127b22328f9Schristos do
1128b22328f9Schristos {
1129b22328f9Schristos if (strncmp (userpart, muser, strlen (muser)) == 0)
1130b22328f9Schristos founduserpart = xstrdup (userpart);
1131b22328f9Schristos else
1132b22328f9Schristos {
1133b22328f9Schristos if (otheruserparts != NULL)
1134b22328f9Schristos {
1135b22328f9Schristos xrealloc_and_strcat (&otheruserparts, &otherslen, ",");
1136b22328f9Schristos xrealloc_and_strcat (&otheruserparts, &otherslen, userpart);
1137b22328f9Schristos }
1138b22328f9Schristos else
1139b22328f9Schristos {
1140b22328f9Schristos otheruserparts = xstrdup (userpart);
1141b22328f9Schristos otherslen = strlen (otheruserparts);
1142b22328f9Schristos }
1143b22328f9Schristos }
1144b22328f9Schristos } while ((userpart = strtok (NULL, ",\t")) != NULL);
1145b22328f9Schristos }
1146b22328f9Schristos
1147b22328f9Schristos wperms = make_perms (mperms, founduserpart, &errmsg);
1148b22328f9Schristos if (wperms == NULL)
1149b22328f9Schristos {
1150b22328f9Schristos if (errmsg)
1151b22328f9Schristos error (0, 0, "`%s' %s", drepository, errmsg);
1152b22328f9Schristos }
1153b22328f9Schristos else
1154b22328f9Schristos {
1155b22328f9Schristos if (defaultperms)
1156b22328f9Schristos {
1157b22328f9Schristos cvs_output ("X ", 0);
1158b22328f9Schristos cvs_output ("ALL", 0);
1159b22328f9Schristos cvs_output ("\n", 0);
1160b22328f9Schristos write_perms (muser, wperms, founduserpart, foundline,
1161b22328f9Schristos otheruserparts, "d", "ALL", tag, pos, drepository);
1162b22328f9Schristos
1163b22328f9Schristos }
1164b22328f9Schristos else
1165b22328f9Schristos {
1166b22328f9Schristos cvs_output ("X ", 0);
1167b22328f9Schristos cvs_output (drepository, 0);
1168b22328f9Schristos cvs_output ("\n", 0);
1169b22328f9Schristos write_perms (muser, wperms, founduserpart, foundline,
1170b22328f9Schristos otheruserparts, "d", drepository, tag, pos,
1171b22328f9Schristos drepository);
1172b22328f9Schristos }
1173b22328f9Schristos }
1174b22328f9Schristos
1175b22328f9Schristos free (line);
1176b22328f9Schristos free (founduserpart);
1177b22328f9Schristos free (otheruserparts);
1178b22328f9Schristos free (wperms);
1179b22328f9Schristos
1180b22328f9Schristos return 0;
1181b22328f9Schristos }
1182b22328f9Schristos
1183b22328f9Schristos /* Open CVSROOT/access or defined CVSACLFileLocation file
1184b22328f9Schristos * Open access file In each directory if UseSeparateACLFileForEachDir=yes
1185b22328f9Schristos * returns file pointer to access file or NULL if access file not found */
1186b22328f9Schristos FILE *
open_accessfile(char * fmode,const char * adir,char ** fname)1187b22328f9Schristos open_accessfile (char *fmode, const char *adir, char **fname)
1188b22328f9Schristos {
1189b22328f9Schristos char *accessfile = NULL;
1190b22328f9Schristos FILE *accessfp;
1191b22328f9Schristos
1192b22328f9Schristos if (!use_separate_acl_file_for_each_dir)
1193b22328f9Schristos {
1194b22328f9Schristos if (cvs_acl_file_location == NULL)
1195b22328f9Schristos {
1196b22328f9Schristos accessfile = Xasprintf("%s/%s/%s", current_parsed_root->directory,
1197b22328f9Schristos CVSROOTADM, CVSROOTADM_ACCESS);
1198b22328f9Schristos }
1199b22328f9Schristos else
1200b22328f9Schristos {
1201b22328f9Schristos accessfile = xstrdup(cvs_acl_file_location);
1202b22328f9Schristos }
1203b22328f9Schristos }
1204b22328f9Schristos else
1205b22328f9Schristos {
1206b22328f9Schristos size_t accessfilelen = 0;
1207b22328f9Schristos xrealloc_and_strcat (&accessfile, &accessfilelen,
1208b22328f9Schristos current_parsed_root->directory);
1209b22328f9Schristos xrealloc_and_strcat (&accessfile, &accessfilelen, "/");
1210b22328f9Schristos xrealloc_and_strcat (&accessfile, &accessfilelen, adir);
1211b22328f9Schristos xrealloc_and_strcat (&accessfile, &accessfilelen, "/access");
1212b22328f9Schristos }
1213b22328f9Schristos
1214b22328f9Schristos accessfp = CVS_FOPEN (accessfile, fmode);
1215b22328f9Schristos
1216b22328f9Schristos if (fname != NULL)
1217b22328f9Schristos *fname = xstrdup (accessfile);
1218b22328f9Schristos
1219b22328f9Schristos free (accessfile);
1220b22328f9Schristos
1221b22328f9Schristos return accessfp;
1222b22328f9Schristos }
1223b22328f9Schristos
1224b22328f9Schristos /* Open /etc/group file if UseSystemGroups=yes in config file
1225b22328f9Schristos * Open CVSROOT/group file if UseCVSGroups=yes in config file
1226b22328f9Schristos * Open group file if specified in CVSGroupsFileLocation
1227b22328f9Schristos * returns group file pointer if UseSystemGroups=yes
1228b22328f9Schristos * returns NULL if UseSystemGroups=no or group file not found */
1229b22328f9Schristos FILE *
open_groupfile(char * fmode)1230b22328f9Schristos open_groupfile (char *fmode)
1231b22328f9Schristos {
1232b22328f9Schristos char *groupfile;
1233b22328f9Schristos FILE *groupfp;
1234b22328f9Schristos
1235b22328f9Schristos if (use_cvs_groups)
1236b22328f9Schristos {
1237b22328f9Schristos if (cvs_groups_file_location != NULL)
1238b22328f9Schristos {
1239b22328f9Schristos groupfile = xstrdup (cvs_groups_file_location);
1240b22328f9Schristos }
1241b22328f9Schristos else
1242b22328f9Schristos {
1243b22328f9Schristos groupfile = Xasprintf("%s/%s/%s", current_parsed_root->directory,
1244b22328f9Schristos CVSROOTADM, CVSROOTADM_GROUP);
1245b22328f9Schristos }
1246b22328f9Schristos }
1247b22328f9Schristos else
1248b22328f9Schristos {
1249b22328f9Schristos return NULL;
1250b22328f9Schristos }
1251b22328f9Schristos
1252b22328f9Schristos groupfp = CVS_FOPEN (groupfile, "r");
1253b22328f9Schristos
1254b22328f9Schristos if (groupfp == NULL)
1255b22328f9Schristos error (0, 0, "cannot open file: %s", groupfile);
1256b22328f9Schristos
1257b22328f9Schristos free (groupfile);
1258b22328f9Schristos
1259b22328f9Schristos return groupfp;
1260b22328f9Schristos }
1261b22328f9Schristos
1262b22328f9Schristos
1263b22328f9Schristos /* Check whether given permissions are valid or not
1264b22328f9Schristos * Returns 1 if permissions are valid
1265b22328f9Schristos * Returns 0 if permissions are NOT valid */
1266b22328f9Schristos int
given_perms_valid(const char * cperms)1267b22328f9Schristos given_perms_valid (const char *cperms)
1268b22328f9Schristos {
1269b22328f9Schristos int cperms_len;
1270b22328f9Schristos int retval;
1271b22328f9Schristos int index, i;
1272b22328f9Schristos
1273b22328f9Schristos if (cperms[0] == '+' || cperms[0] == '-')
1274b22328f9Schristos index = 1;
1275b22328f9Schristos else
1276b22328f9Schristos index = 0;
1277b22328f9Schristos
1278b22328f9Schristos cperms_len = strlen (cperms);
1279b22328f9Schristos
1280b22328f9Schristos switch (cperms[index])
1281b22328f9Schristos {
1282b22328f9Schristos case 'x':
1283b22328f9Schristos if ((cperms_len - index) == 1 && cperms_len == 1)
1284b22328f9Schristos retval = 1;
1285b22328f9Schristos else
1286b22328f9Schristos retval = 0;
1287b22328f9Schristos break;
1288b22328f9Schristos case 'n':
1289b22328f9Schristos if ((cperms_len - index) == 1 && cperms_len == 1)
1290b22328f9Schristos retval = 1;
1291b22328f9Schristos else
1292b22328f9Schristos retval = 0;
1293b22328f9Schristos break;
1294b22328f9Schristos case 'p':
1295b22328f9Schristos if ((cperms_len - index) == 1)
1296b22328f9Schristos retval = 1;
1297b22328f9Schristos else
1298b22328f9Schristos retval = 0;
1299b22328f9Schristos break;
1300b22328f9Schristos case 'a':
1301b22328f9Schristos if ((cperms_len - index) == 1)
1302b22328f9Schristos retval = 1;
1303b22328f9Schristos else
1304b22328f9Schristos retval = 0;
1305b22328f9Schristos break;
1306b22328f9Schristos case 'r':
1307b22328f9Schristos if ((cperms_len - index) == 1)
1308b22328f9Schristos retval = 1;
1309b22328f9Schristos else
1310b22328f9Schristos retval = 0;
1311b22328f9Schristos break;
1312b22328f9Schristos case 'w':
1313b22328f9Schristos if ((cperms_len - index) == 1)
1314b22328f9Schristos retval = 1;
1315b22328f9Schristos else
1316b22328f9Schristos for (i = index + 1; i < cperms_len; i++)
1317b22328f9Schristos if (cperms[i] == 't' || cperms[i] == 'c' || cperms[i] == 'd')
1318b22328f9Schristos retval = 1;
1319b22328f9Schristos else
1320b22328f9Schristos retval = 0;
1321b22328f9Schristos break;
1322b22328f9Schristos case 't':
1323b22328f9Schristos if ((cperms_len - index) == 1)
1324b22328f9Schristos retval = 1;
1325b22328f9Schristos else
1326b22328f9Schristos for (i = index + 1; i < cperms_len; i++)
1327b22328f9Schristos if (cperms[i] == 'w' || cperms[i] == 'c' || cperms[i] == 'd')
1328b22328f9Schristos retval = 1;
1329b22328f9Schristos else
1330b22328f9Schristos retval = 0;
1331b22328f9Schristos break;
1332b22328f9Schristos case 'c':
1333b22328f9Schristos if ((cperms_len - index) == 1)
1334b22328f9Schristos retval = 1;
1335b22328f9Schristos else
1336b22328f9Schristos for (i = index + 1; i < cperms_len; i++)
1337b22328f9Schristos if (cperms[i] == 't' || cperms[i] == 'w' || cperms[i] == 'd')
1338b22328f9Schristos retval = 1;
1339b22328f9Schristos else
1340b22328f9Schristos retval = 0;
1341b22328f9Schristos break;
1342b22328f9Schristos case 'd':
1343b22328f9Schristos if ((cperms_len - index) == 1)
1344b22328f9Schristos retval = 1;
1345b22328f9Schristos else
1346b22328f9Schristos for (i = index + 1; i < cperms_len; i++)
1347b22328f9Schristos if (cperms[i] == 't' || cperms[i] == 'c' || cperms[i] == 'w')
1348b22328f9Schristos retval = 1;
1349b22328f9Schristos else
1350b22328f9Schristos retval = 0;
1351b22328f9Schristos break;
1352b22328f9Schristos default:
1353b22328f9Schristos retval = 0;
1354b22328f9Schristos break;
1355b22328f9Schristos }
1356b22328f9Schristos
1357b22328f9Schristos return retval;
1358b22328f9Schristos }
1359b22328f9Schristos
1360b22328f9Schristos /* prepare permsissions string to be written to access file
1361b22328f9Schristos * returns permissions or NULL if */
1362b22328f9Schristos char *
make_perms(char * perms,char * founduserpart,char ** xerrmsg)1363b22328f9Schristos make_perms (char *perms, char *founduserpart, char **xerrmsg)
1364b22328f9Schristos {
1365cc7958a0Schristos char *fperms = NULL;
1366b22328f9Schristos size_t perms_len;
1367b22328f9Schristos size_t fperms_len;
1368b22328f9Schristos
1369b22328f9Schristos int i, j;
1370b22328f9Schristos int err = 0;
1371b22328f9Schristos char *errmsg = NULL;
1372b22328f9Schristos
1373b22328f9Schristos char *retperms;
1374cc7958a0Schristos size_t retperms_len;
1375b22328f9Schristos
1376b22328f9Schristos perms_len = strlen (perms);
1377b22328f9Schristos if (perms[0] == '+' || perms[0] == '-')
1378b22328f9Schristos {
1379cc7958a0Schristos retperms = xmalloc (retperms_len);
1380cc7958a0Schristos retperms[0] = '\0';
1381cc7958a0Schristos retperms_len = 1;
1382cc7958a0Schristos
1383b22328f9Schristos if (founduserpart)
1384b22328f9Schristos {
1385b22328f9Schristos char *tempfperms;
1386b22328f9Schristos size_t tempfperms_len;
1387b22328f9Schristos
1388b22328f9Schristos char *temp;
1389b22328f9Schristos int per = 0;
1390b22328f9Schristos temp = strtok (founduserpart, "!\t");
1391b22328f9Schristos fperms = strtok (NULL, "!\t");
1392b22328f9Schristos fperms_len = strlen (fperms);
1393b22328f9Schristos
1394b22328f9Schristos if (strncmp (fperms, "x", 1) == 0)
1395b22328f9Schristos {
1396b22328f9Schristos err = 1;
1397b22328f9Schristos if (perms[0] == '+')
1398b22328f9Schristos *xerrmsg = xstrdup ("cannot add default permission 'x'");
1399b22328f9Schristos else
1400b22328f9Schristos *xerrmsg = xstrdup ("cannot remove default permission 'x'");
1401b22328f9Schristos }
1402b22328f9Schristos
1403b22328f9Schristos /* go through perms */
1404b22328f9Schristos for (i = 1; i < perms_len && !err; i++)
1405b22328f9Schristos {
1406b22328f9Schristos switch (perms[i])
1407b22328f9Schristos {
1408b22328f9Schristos case 'n':
1409b22328f9Schristos err = 1;
1410b22328f9Schristos break;
1411b22328f9Schristos case 'p':
1412b22328f9Schristos if (perms[0] == '+')
1413b22328f9Schristos fperms = xstrdup ("p");
1414b22328f9Schristos else if (perms[0] == '-')
1415b22328f9Schristos {
1416b22328f9Schristos fperms_len = 1;
1417b22328f9Schristos fperms = xmalloc (fperms_len);
1418b22328f9Schristos fperms[0] = '\0';
1419b22328f9Schristos }
1420b22328f9Schristos break;
1421b22328f9Schristos case 'a':
1422b22328f9Schristos for (j = 0; j < fperms_len; j++)
1423b22328f9Schristos {
1424b22328f9Schristos if (fperms[j] == 'p')
1425b22328f9Schristos {
1426b22328f9Schristos err = 1;
1427b22328f9Schristos *xerrmsg = xstrdup ("user have admin rights,"
1428b22328f9Schristos " cannot use +/- permissions");
1429b22328f9Schristos }
1430b22328f9Schristos else if (fperms[j] == 'a' && perms[0] == '+')
1431b22328f9Schristos {
1432b22328f9Schristos err = 1;
1433b22328f9Schristos *xerrmsg = xstrdup ("user already has all ('a')"
1434b22328f9Schristos " permission");
1435b22328f9Schristos }
1436b22328f9Schristos else if (fperms[j] != 'a' && perms[0] == '-')
1437b22328f9Schristos {
1438b22328f9Schristos err = 1;
1439b22328f9Schristos *xerrmsg = xstrdup ("user does not have all "
1440b22328f9Schristos "('a') permission");
1441b22328f9Schristos }
1442b22328f9Schristos }
1443b22328f9Schristos if (perms[0] == '+')
1444b22328f9Schristos {
1445b22328f9Schristos fperms = xstrdup ("a");
1446b22328f9Schristos fperms_len = strlen (fperms);
1447b22328f9Schristos }
1448b22328f9Schristos else if (perms[0] == '-')
1449b22328f9Schristos {
1450b22328f9Schristos fperms_len = 1;
1451b22328f9Schristos fperms = xmalloc (fperms_len);
1452b22328f9Schristos fperms[0] = '\0';
1453b22328f9Schristos }
1454b22328f9Schristos break;
1455b22328f9Schristos case 'r':
1456b22328f9Schristos for (i = 0; i < fperms_len; i++)
1457b22328f9Schristos {
1458b22328f9Schristos if (fperms[i] == 'n' && perms[0] == '+')
1459b22328f9Schristos {
1460b22328f9Schristos fperms = xstrdup ("r");
1461b22328f9Schristos fperms_len = strlen (fperms);
1462b22328f9Schristos }
1463b22328f9Schristos else if (fperms[i] == 'r' && perms[0] == '-')
1464b22328f9Schristos {
1465b22328f9Schristos fperms_len = 1;
1466b22328f9Schristos fperms = xmalloc (fperms_len);
1467b22328f9Schristos fperms[0] = '\0';
1468b22328f9Schristos }
1469b22328f9Schristos else if (perms[0] == '-')
1470b22328f9Schristos {
1471b22328f9Schristos err = 1;
1472b22328f9Schristos *xerrmsg = xstrdup ("user has other permissions,"
1473b22328f9Schristos " cannot remove read ('r')"
1474b22328f9Schristos " permission");
1475b22328f9Schristos }
1476b22328f9Schristos else
1477b22328f9Schristos {
1478b22328f9Schristos err = 1;
1479b22328f9Schristos *xerrmsg = xstrdup ("user has other permissions,"
1480b22328f9Schristos " cannot remove read ('r')"
1481b22328f9Schristos " permission");
1482b22328f9Schristos }
1483b22328f9Schristos }
1484b22328f9Schristos break;
1485b22328f9Schristos case 'w':
1486b22328f9Schristos {
1487b22328f9Schristos tempfperms_len = 1;
1488b22328f9Schristos
1489b22328f9Schristos tempfperms = xmalloc (tempfperms_len);
1490b22328f9Schristos tempfperms[0] = '\0';
1491b22328f9Schristos
1492b22328f9Schristos for (j = 0; j < fperms_len; j++)
1493b22328f9Schristos {
1494b22328f9Schristos if (fperms[j] == 't' || fperms[j] == 'c' ||
1495b22328f9Schristos fperms[j] == 'd')
1496b22328f9Schristos {
1497b22328f9Schristos char *temp;
1498b22328f9Schristos temp = xmalloc (2);
1499b22328f9Schristos temp[0] = fperms[j];
1500b22328f9Schristos temp[1] = '\0';
1501b22328f9Schristos
1502b22328f9Schristos xrealloc_and_strcat (&tempfperms,
1503b22328f9Schristos &tempfperms_len, temp);
1504b22328f9Schristos free (temp);
1505b22328f9Schristos }
1506b22328f9Schristos else if (fperms[j] == 'a' || fperms[j] == 'p')
1507b22328f9Schristos {
1508b22328f9Schristos err = 1;
1509b22328f9Schristos *xerrmsg = xstrdup ("user has higher"
1510b22328f9Schristos " permissions, cannot use"
1511b22328f9Schristos " +/- write permissions");
1512b22328f9Schristos }
1513b22328f9Schristos else if (fperms[j] == 'n' || fperms[j] == 'r')
1514b22328f9Schristos {
1515b22328f9Schristos if (perms[0] == '-')
1516b22328f9Schristos {
1517b22328f9Schristos err = 1;
1518b22328f9Schristos *xerrmsg = xstrdup ("user does not have"
1519b22328f9Schristos " write ('w')"
1520b22328f9Schristos " permission");
1521b22328f9Schristos }
1522b22328f9Schristos }
1523b22328f9Schristos else if (fperms[j] == 'w')
1524b22328f9Schristos {
1525b22328f9Schristos per = 1;
1526b22328f9Schristos if (perms[0] == '+') {
1527b22328f9Schristos err = 1;
1528b22328f9Schristos *xerrmsg = xstrdup ("user already have"
1529b22328f9Schristos " write ('w')"
1530b22328f9Schristos "permission");
1531b22328f9Schristos }
1532b22328f9Schristos }
1533b22328f9Schristos }
1534b22328f9Schristos
1535cc7958a0Schristos fperms = tempfperms;
1536b22328f9Schristos fperms_len = strlen (fperms);
1537b22328f9Schristos
1538b22328f9Schristos if (!per && !err && (perms[0] == '-')) {
1539b22328f9Schristos err = 1;
1540b22328f9Schristos *xerrmsg = xstrdup ("user does not have write"
1541b22328f9Schristos " ('w') permission");
1542b22328f9Schristos }
1543b22328f9Schristos
1544b22328f9Schristos if (perms[0] == '+')
1545b22328f9Schristos {
1546b22328f9Schristos xrealloc_and_strcat (&fperms, &fperms_len, "w");
1547b22328f9Schristos }
1548b22328f9Schristos }
1549b22328f9Schristos break;
1550b22328f9Schristos case 't':
1551b22328f9Schristos {
1552b22328f9Schristos tempfperms_len = 1;
1553b22328f9Schristos
1554b22328f9Schristos tempfperms = xmalloc (tempfperms_len);
1555b22328f9Schristos tempfperms[0] = '\0';
1556b22328f9Schristos
1557b22328f9Schristos for (j = 0; j < fperms_len; j++)
1558b22328f9Schristos {
1559b22328f9Schristos if (fperms[j] == 'w' || fperms[j] == 'c' ||
1560b22328f9Schristos fperms[j] == 'd')
1561b22328f9Schristos {
1562b22328f9Schristos char *temp;
1563b22328f9Schristos temp = xmalloc (2);
1564b22328f9Schristos temp[0] = fperms[j];
1565b22328f9Schristos temp[1] = '\0';
1566b22328f9Schristos
1567b22328f9Schristos xrealloc_and_strcat (&tempfperms,
1568b22328f9Schristos &tempfperms_len, temp);
1569b22328f9Schristos free (temp);
1570b22328f9Schristos }
1571b22328f9Schristos else if (fperms[j] == 'a' || fperms[j] == 'p')
1572b22328f9Schristos {
1573b22328f9Schristos err = 1;
1574b22328f9Schristos *xerrmsg = xstrdup ("user has higher"
1575b22328f9Schristos " permissions, cannot use"
1576b22328f9Schristos " +/- tag permissions");
1577b22328f9Schristos }
1578b22328f9Schristos else if (fperms[j] == 'n' || fperms[i] == 'r')
1579b22328f9Schristos {
1580b22328f9Schristos if (perms[0] == '-')
1581b22328f9Schristos *xerrmsg = xstrdup ("user does not have tag"
1582b22328f9Schristos " ('t') permission");
1583b22328f9Schristos }
1584b22328f9Schristos else if (fperms[j] == 't')
1585b22328f9Schristos {
1586b22328f9Schristos per = 1;
1587b22328f9Schristos if (perms[0] == '+')
1588b22328f9Schristos {
1589b22328f9Schristos err = 1;
1590b22328f9Schristos *xerrmsg = xstrdup ("user already have tag"
1591b22328f9Schristos " ('t') permission");
1592b22328f9Schristos }
1593b22328f9Schristos }
1594b22328f9Schristos }
1595b22328f9Schristos
1596cc7958a0Schristos fperms = tempfperms;
1597b22328f9Schristos fperms_len = strlen (fperms);
1598b22328f9Schristos
1599b22328f9Schristos if (!per && !err && (perms[0] == '-'))
1600b22328f9Schristos {
1601b22328f9Schristos err = 1;
1602b22328f9Schristos *xerrmsg = xstrdup ("user does not have tag ('t')"
1603b22328f9Schristos " permission");
1604b22328f9Schristos }
1605b22328f9Schristos
1606b22328f9Schristos if (perms[0] == '+')
1607b22328f9Schristos {
1608b22328f9Schristos xrealloc_and_strcat (&fperms, &fperms_len, "t");
1609b22328f9Schristos }
1610b22328f9Schristos }
1611b22328f9Schristos break;
1612b22328f9Schristos case 'c':
1613b22328f9Schristos {
1614b22328f9Schristos tempfperms_len = 1;
1615b22328f9Schristos
1616b22328f9Schristos tempfperms = xmalloc (tempfperms_len);
1617b22328f9Schristos tempfperms[0] = '\0';
1618b22328f9Schristos
1619b22328f9Schristos for (j = 0; j < fperms_len; j++)
1620b22328f9Schristos {
1621b22328f9Schristos if (fperms[j] == 'w' || fperms[j] == 't' ||
1622b22328f9Schristos fperms[j] == 'd')
1623b22328f9Schristos {
1624b22328f9Schristos char *temp;
1625b22328f9Schristos temp = xmalloc (2);
1626b22328f9Schristos temp[0] = fperms[j];
1627b22328f9Schristos temp[1] = '\0';
1628b22328f9Schristos
1629b22328f9Schristos xrealloc_and_strcat (&tempfperms,
1630b22328f9Schristos &tempfperms_len, temp);
1631b22328f9Schristos free (temp);
1632b22328f9Schristos }
1633b22328f9Schristos else if (fperms[j] == 'a' || fperms[j] == 'p')
1634b22328f9Schristos {
1635b22328f9Schristos err = 1;
1636b22328f9Schristos *xerrmsg = xstrdup ("user has higher"
1637b22328f9Schristos " permissions, cannot use"
1638b22328f9Schristos " +/- create permissions");
1639b22328f9Schristos }
1640b22328f9Schristos else if (fperms[j] == 'n' || fperms[i] == 'r')
1641b22328f9Schristos {
1642b22328f9Schristos if (perms[0] == '-')
1643b22328f9Schristos err = 1;
1644b22328f9Schristos *xerrmsg = xstrdup ("user does not have create"
1645b22328f9Schristos " ('c') permission");
1646b22328f9Schristos }
1647b22328f9Schristos else if (fperms[j] == 'c')
1648b22328f9Schristos {
1649b22328f9Schristos per = 1;
1650b22328f9Schristos if (perms[0] == '+') {
1651b22328f9Schristos err = 1;
1652b22328f9Schristos *xerrmsg = xstrdup ("user already have"
1653b22328f9Schristos " create ('c')"
1654b22328f9Schristos " permission");
1655b22328f9Schristos }
1656b22328f9Schristos }
1657b22328f9Schristos }
1658b22328f9Schristos
1659cc7958a0Schristos fperms = tempfperms;
1660b22328f9Schristos fperms_len = strlen (fperms);
1661b22328f9Schristos
1662b22328f9Schristos if (!per && !err && (perms[0] == '-')) {
1663b22328f9Schristos err = 1;
1664b22328f9Schristos *xerrmsg = xstrdup ("user does not have create"
1665b22328f9Schristos " ('c') permission");
1666b22328f9Schristos }
1667b22328f9Schristos
1668b22328f9Schristos if (perms[0] == '+')
1669b22328f9Schristos {
1670b22328f9Schristos xrealloc_and_strcat (&fperms, &fperms_len, "c");
1671b22328f9Schristos }
1672b22328f9Schristos }
1673b22328f9Schristos break;
1674b22328f9Schristos case 'd':
1675b22328f9Schristos {
1676b22328f9Schristos tempfperms_len = 1;
1677b22328f9Schristos
1678b22328f9Schristos tempfperms = xmalloc (tempfperms_len);
1679b22328f9Schristos tempfperms[0] = '\0';
1680b22328f9Schristos
1681b22328f9Schristos for (j = 0; j < fperms_len; j++)
1682b22328f9Schristos {
1683b22328f9Schristos if (fperms[j] == 'w' || fperms[j] == 'c' ||
1684b22328f9Schristos fperms[j] == 't')
1685b22328f9Schristos {
1686b22328f9Schristos char *temp;
1687b22328f9Schristos temp = xmalloc (2);
1688b22328f9Schristos temp[0] = fperms[j];
1689b22328f9Schristos temp[1] = '\0';
1690b22328f9Schristos
1691b22328f9Schristos xrealloc_and_strcat (&tempfperms,
1692b22328f9Schristos &tempfperms_len, temp);
1693b22328f9Schristos free (temp);
1694b22328f9Schristos }
1695b22328f9Schristos else if (fperms[j] == 'a' || fperms[j] == 'p')
1696b22328f9Schristos {
1697b22328f9Schristos err = 1;
1698b22328f9Schristos *xerrmsg = xstrdup ("user has higher"
1699b22328f9Schristos " permissions, cannot use"
1700b22328f9Schristos " +/- delete permissions");
1701b22328f9Schristos }
1702b22328f9Schristos else if (fperms[j] == 'n' || fperms[i] == 'r')
1703b22328f9Schristos {
1704b22328f9Schristos if (perms[0] == '-')
1705b22328f9Schristos err = 1;
1706b22328f9Schristos *xerrmsg = xstrdup ("user does not have delete"
1707b22328f9Schristos " ('d') permission");
1708b22328f9Schristos }
1709b22328f9Schristos else if (fperms[j] == 'd')
1710b22328f9Schristos {
1711b22328f9Schristos per = 1;
1712b22328f9Schristos if (perms[0] == '+') {
1713b22328f9Schristos err = 1;
1714b22328f9Schristos *xerrmsg = xstrdup ("user already have"
1715b22328f9Schristos " delete ('d')"
1716b22328f9Schristos " permission");
1717b22328f9Schristos }
1718b22328f9Schristos }
1719b22328f9Schristos }
1720b22328f9Schristos
1721cc7958a0Schristos fperms = tempfperms;
1722b22328f9Schristos fperms_len = strlen (fperms);
1723b22328f9Schristos
1724b22328f9Schristos if (!per && !err && (perms[0] == '-')) {
1725b22328f9Schristos err = 1;
1726b22328f9Schristos *xerrmsg = xstrdup ("user does not have delete"
1727b22328f9Schristos " ('d') permission");
1728b22328f9Schristos }
1729b22328f9Schristos
1730b22328f9Schristos if (perms[0] == '+')
1731b22328f9Schristos {
1732b22328f9Schristos xrealloc_and_strcat (&fperms, &fperms_len, "d");
1733b22328f9Schristos }
1734b22328f9Schristos }
1735b22328f9Schristos break;
1736b22328f9Schristos default:
1737b22328f9Schristos err = 1;
1738b22328f9Schristos *xerrmsg = xstrdup ("error in 'access' file format");
1739b22328f9Schristos break;
1740b22328f9Schristos }
1741b22328f9Schristos
1742b22328f9Schristos if (fperms[0] == '\0')
1743b22328f9Schristos retperms = xstrdup ("none");
1744b22328f9Schristos else
1745b22328f9Schristos retperms = xstrdup (fperms);
1746b22328f9Schristos }
1747b22328f9Schristos }
1748b22328f9Schristos else
1749b22328f9Schristos {
1750b22328f9Schristos err = 1;
1751b22328f9Schristos *xerrmsg = xstrdup("user is not given any permissions to remove/add");
1752b22328f9Schristos }
1753b22328f9Schristos }
1754b22328f9Schristos else
1755b22328f9Schristos {
1756b22328f9Schristos retperms = xstrdup (perms);
1757b22328f9Schristos }
1758cc7958a0Schristos if (fperms)
1759cc7958a0Schristos free (fperms);
1760cc7958a0Schristos if (err && retperms)
1761cc7958a0Schristos free (retperms);
1762b22328f9Schristos
1763b22328f9Schristos return (err ? NULL : retperms);
1764b22328f9Schristos }
1765b22328f9Schristos
1766b22328f9Schristos /* prepare and write resulting permissions to access file */
1767b22328f9Schristos static int
write_perms(const char * user,const char * perms,const char * founduserpart,int foundline,char * otheruserparts,const char * part_type,const char * part_object,const char * part_tag,int pos,const char * arepos)1768b22328f9Schristos write_perms (const char *user, const char *perms, const char *founduserpart,
1769b22328f9Schristos int foundline, char *otheruserparts,
1770b22328f9Schristos const char *part_type, const char *part_object,
1771b22328f9Schristos const char *part_tag, int pos, const char *arepos)
1772b22328f9Schristos {
1773b22328f9Schristos char *accessfile;
1774b22328f9Schristos char *tmpaccessout;
1775b22328f9Schristos FILE *accessfpin;
1776b22328f9Schristos FILE *accessfpout;
1777b22328f9Schristos
1778b22328f9Schristos char *newline = NULL;
1779b22328f9Schristos size_t newlinelen = 1;
1780b22328f9Schristos char *object;
1781b22328f9Schristos
1782b22328f9Schristos char *line = NULL;
1783b22328f9Schristos size_t line_allocated = 0;
1784b22328f9Schristos
1785b22328f9Schristos newline = xmalloc (newlinelen);
1786b22328f9Schristos newline[0] = '\0';
1787b22328f9Schristos
1788b22328f9Schristos if (!strcasecmp (part_tag, "ALL"))
1789b22328f9Schristos part_tag = "ALL";
1790b22328f9Schristos
1791b22328f9Schristos /* strip any trailing slash if found */
1792b22328f9Schristos object = xstrdup (part_object);
1793b22328f9Schristos if (object[strlen (object) - 1] == '/')
1794b22328f9Schristos object[strlen (object) - 1] = '\0';
1795b22328f9Schristos
1796b22328f9Schristos /* first parts, part type, object, and tag */
1797b22328f9Schristos xrealloc_and_strcat (&newline, &newlinelen, part_type);
1798b22328f9Schristos xrealloc_and_strcat (&newline, &newlinelen, ":");
1799b22328f9Schristos xrealloc_and_strcat (&newline, &newlinelen, object);
1800b22328f9Schristos xrealloc_and_strcat (&newline, &newlinelen, ":");
1801b22328f9Schristos xrealloc_and_strcat (&newline, &newlinelen, part_tag);
1802b22328f9Schristos xrealloc_and_strcat (&newline, &newlinelen, ":");
1803b22328f9Schristos
1804b22328f9Schristos if (strncmp (perms, "none", 4) != 0)
1805b22328f9Schristos {
1806b22328f9Schristos xrealloc_and_strcat (&newline, &newlinelen, user);
1807b22328f9Schristos xrealloc_and_strcat (&newline, &newlinelen, "!");
1808b22328f9Schristos xrealloc_and_strcat (&newline, &newlinelen, perms);
1809b22328f9Schristos if (otheruserparts != NULL)
1810b22328f9Schristos xrealloc_and_strcat (&newline, &newlinelen, ",");
1811b22328f9Schristos }
1812b22328f9Schristos
1813b22328f9Schristos if (otheruserparts != NULL)
1814b22328f9Schristos {
1815b22328f9Schristos if (otheruserparts[strlen (otheruserparts) - 1] == '\n')
1816b22328f9Schristos otheruserparts[strlen (otheruserparts) - 1] = '\0';
1817b22328f9Schristos
1818b22328f9Schristos xrealloc_and_strcat (&newline, &newlinelen, otheruserparts);
1819b22328f9Schristos }
1820b22328f9Schristos
1821b22328f9Schristos xrealloc_and_strcat (&newline, &newlinelen, ":");
1822b22328f9Schristos
1823b22328f9Schristos if (foundline)
1824b22328f9Schristos {
1825b22328f9Schristos accessfpout = cvs_temp_file (&tmpaccessout);
1826b22328f9Schristos if (accessfpout == NULL)
1827b22328f9Schristos error (1, errno, "cannot open temporary file: %s", tmpaccessout);
1828b22328f9Schristos
1829b22328f9Schristos accessfpin = open_accessfile ("r", arepos, &accessfile);
1830b22328f9Schristos if (accessfpout == NULL)
1831b22328f9Schristos error (1, errno, "cannot open access file: %s", accessfile);
1832b22328f9Schristos
1833b22328f9Schristos while (getline (&line, &line_allocated, accessfpin) >= 0)
1834b22328f9Schristos {
1835b22328f9Schristos if (pos != ftell (accessfpin))
1836b22328f9Schristos {
1837b22328f9Schristos if (fprintf (accessfpout, "%s", line) < 0)
1838b22328f9Schristos error (1, errno, "writing temporary file: %s", tmpaccessout);
1839b22328f9Schristos }
1840b22328f9Schristos else
1841b22328f9Schristos {
1842b22328f9Schristos if (fprintf (accessfpout, "%s\n", newline) < 0)
1843b22328f9Schristos error (1, errno, "writing temporary file: %s", tmpaccessout);
1844b22328f9Schristos }
1845b22328f9Schristos
1846b22328f9Schristos }
1847b22328f9Schristos if (fclose (accessfpin) == EOF)
1848b22328f9Schristos error (1, errno, "cannot close access file: %s", accessfile);
1849b22328f9Schristos
1850b22328f9Schristos if (fclose (accessfpout) == EOF)
1851b22328f9Schristos error (1, errno, "cannot close temporary file: %s", tmpaccessout);
1852b22328f9Schristos
1853b22328f9Schristos if (CVS_UNLINK (accessfile) < 0)
1854b22328f9Schristos error (0, errno, "cannot remove %s", accessfile);
1855b22328f9Schristos
1856b22328f9Schristos copy_file (tmpaccessout, accessfile);
1857b22328f9Schristos
1858b22328f9Schristos if (CVS_UNLINK (tmpaccessout) < 0)
1859b22328f9Schristos error (0, errno, "cannot remove temporary file: %s", tmpaccessout);
1860b22328f9Schristos }
1861b22328f9Schristos else
1862b22328f9Schristos {
1863b22328f9Schristos accessfpout = open_accessfile ("r+", arepos, &accessfile);
1864b22328f9Schristos
1865b22328f9Schristos if (accessfpout == NULL)
1866b22328f9Schristos {
1867b22328f9Schristos if (existence_error (errno))
1868b22328f9Schristos {
1869b22328f9Schristos accessfpout = open_accessfile ("w+", arepos, &accessfile);
1870b22328f9Schristos }
1871b22328f9Schristos if (accessfpout == NULL)
1872b22328f9Schristos error (1, errno, "cannot open access file: %s", accessfile);
1873b22328f9Schristos }
1874b22328f9Schristos else {
1875b22328f9Schristos if (fseek (accessfpout, 0, 2) != 0)
1876b22328f9Schristos error (1, errno, "cannot fseek access file: %s", accessfile);
1877b22328f9Schristos }
1878b22328f9Schristos
1879b22328f9Schristos if (fprintf (accessfpout, "%s\n", newline) < 0)
1880b22328f9Schristos error (1, errno, "writing access file: %s", accessfile);
1881b22328f9Schristos
1882b22328f9Schristos if (fclose (accessfpout) == EOF)
1883b22328f9Schristos error (1, errno, "cannot close access file: %s", accessfile);
1884b22328f9Schristos }
1885b22328f9Schristos
1886b22328f9Schristos free (line);
1887b22328f9Schristos free (newline);
1888b22328f9Schristos
1889b22328f9Schristos chmod (accessfile, 0644);
1890b22328f9Schristos
1891b22328f9Schristos return 0;
1892b22328f9Schristos }
1893b22328f9Schristos
1894b22328f9Schristos static int
acllist_fileproc(void * callerdat,struct file_info * finfo)1895b22328f9Schristos acllist_fileproc (void *callerdat, struct file_info *finfo)
1896b22328f9Schristos {
1897b22328f9Schristos char *filefullname;
1898b22328f9Schristos const char *frepository;
1899b22328f9Schristos char *line = NULL;
1900b22328f9Schristos int pos;
1901b22328f9Schristos
1902b22328f9Schristos if (!aclfile)
1903b22328f9Schristos return 0;
1904b22328f9Schristos
1905b22328f9Schristos frepository = Short_Repository (finfo->repository);
1906b22328f9Schristos
1907b22328f9Schristos filefullname = Xasprintf("%s/%s", frepository, finfo->file);
1908b22328f9Schristos
1909b22328f9Schristos /* check that user, which run acl/racl command, has admin permisson,
1910b22328f9Schristos * and also return the line with permissions from access file. */
1911b22328f9Schristos if (!access_allowed (finfo->file, finfo->repository, tag, 5, &line, &pos,
1912b22328f9Schristos 0))
1913b22328f9Schristos error (1, 0, "You do not have admin rights on '%s'", frepository);
1914b22328f9Schristos
1915b22328f9Schristos acllist_print (line, filefullname);
1916b22328f9Schristos
1917b22328f9Schristos free (filefullname);
1918b22328f9Schristos
1919b22328f9Schristos return 0;
1920b22328f9Schristos }
1921b22328f9Schristos
1922b22328f9Schristos static Dtype
acllist_dirproc(void * callerdat,const char * dir,const char * repos,const char * update_dir,List * entries)1923b22328f9Schristos acllist_dirproc (void *callerdat, const char *dir, const char *repos,
1924b22328f9Schristos const char *update_dir, List *entries)
1925b22328f9Schristos {
1926b22328f9Schristos char *line = NULL;
1927b22328f9Schristos const char *drepository;
1928b22328f9Schristos int pos;
1929b22328f9Schristos
1930b22328f9Schristos if (repos[0] == '\0')
1931b22328f9Schristos repos = Name_Repository (dir, NULL);
1932b22328f9Schristos
1933b22328f9Schristos if (!acldir)
1934b22328f9Schristos return 0;
1935b22328f9Schristos
1936b22328f9Schristos drepository = Short_Repository (repos);
1937b22328f9Schristos
1938b22328f9Schristos /* check that user, which run acl/racl command, has admin permisson,
1939b22328f9Schristos * and also return the line with permissions from access file. */
1940b22328f9Schristos if (!access_allowed (NULL, repos, tag, 5, &line, &pos, 0))
1941b22328f9Schristos error (1, 0, "You do not have admin rights on '%s'", drepository);
1942b22328f9Schristos
1943b22328f9Schristos acllist_print (line, drepository);
1944b22328f9Schristos
1945b22328f9Schristos return 0;
1946b22328f9Schristos }
1947b22328f9Schristos
1948b22328f9Schristos /* Prints permissions to screen with -l option */
1949b22328f9Schristos void
acllist_print(char * line,const char * obj)1950b22328f9Schristos acllist_print (char *line, const char *obj)
1951b22328f9Schristos {
1952b22328f9Schristos char *temp;
1953b22328f9Schristos int c = 0;
1954b22328f9Schristos int def = 0;
1955b22328f9Schristos
1956b22328f9Schristos char *printedusers[255];
1957b22328f9Schristos printedusers[0] = NULL;
1958b22328f9Schristos
1959b22328f9Schristos if (line != NULL)
1960b22328f9Schristos {
1961b22328f9Schristos temp = strtok (line, ":\t");
1962b22328f9Schristos
1963b22328f9Schristos if (acldir)
1964b22328f9Schristos cvs_output ("d ", 0);
1965b22328f9Schristos else if (aclfile)
1966b22328f9Schristos cvs_output ("f ", 0);
1967b22328f9Schristos
1968b22328f9Schristos temp = strtok (NULL, ":\t");
1969b22328f9Schristos
1970b22328f9Schristos cvs_output(obj, 0);
1971b22328f9Schristos cvs_output (" | ", 0);
1972b22328f9Schristos
1973b22328f9Schristos temp = strtok (NULL, ":\t");
1974b22328f9Schristos cvs_output (temp, 0);
1975b22328f9Schristos cvs_output (" | ", 0);
1976b22328f9Schristos
1977b22328f9Schristos while ((temp = strtok (NULL, "!\t")) != NULL)
1978b22328f9Schristos {
1979b22328f9Schristos if (strncmp (temp, ":", 1) == 0)
1980b22328f9Schristos break;
1981b22328f9Schristos
1982b22328f9Schristos if (strcmp (temp, "ALL") == 0)
1983b22328f9Schristos {
1984b22328f9Schristos temp = strtok (NULL, ",\t");
1985b22328f9Schristos continue;
1986b22328f9Schristos }
1987b22328f9Schristos
1988b22328f9Schristos cvs_output (temp, 0);
1989b22328f9Schristos cvs_output (":", 0);
1990b22328f9Schristos
1991b22328f9Schristos while (printedusers[c] != NULL)
1992b22328f9Schristos c++;
1993b22328f9Schristos
1994b22328f9Schristos printedusers[c] = xstrdup (temp);
1995b22328f9Schristos c++;
1996b22328f9Schristos printedusers[c] = NULL;
1997b22328f9Schristos
1998b22328f9Schristos temp = strtok (NULL, ",\t");
1999b22328f9Schristos
2000b22328f9Schristos if (temp != NULL && temp[strlen (temp) - 2] == ':')
2001b22328f9Schristos temp[strlen (temp) - 2] = '\0';
2002b22328f9Schristos
2003b22328f9Schristos cvs_output (temp, 0);
2004b22328f9Schristos cvs_output (" ", 0);
2005b22328f9Schristos }
2006b22328f9Schristos
2007b22328f9Schristos if (default_perms_object)
2008b22328f9Schristos {
2009b22328f9Schristos cvs_output ("| defaults ", 0);
2010b22328f9Schristos cvs_output ("ALL:", 0);
2011b22328f9Schristos cvs_output (default_perms_object, 0);
2012b22328f9Schristos def = 1;
2013b22328f9Schristos }
2014b22328f9Schristos if (default_part_perms_accessfile)
2015b22328f9Schristos {
2016b22328f9Schristos size_t i;
2017b22328f9Schristos i = strlen (default_part_perms_accessfile);
2018b22328f9Schristos xrealloc_and_strcat (&default_part_perms_accessfile, &i, ",");
2019b22328f9Schristos
2020b22328f9Schristos free (line);
2021b22328f9Schristos line = xstrdup (default_part_perms_accessfile);
2022b22328f9Schristos
2023b22328f9Schristos if (!def)
2024b22328f9Schristos cvs_output ("| defaults ", 0);
2025b22328f9Schristos else
2026b22328f9Schristos cvs_output (" ", 0);
2027b22328f9Schristos
2028b22328f9Schristos temp = strtok (line, "!\t");
2029b22328f9Schristos cvs_output (temp, 0);
2030b22328f9Schristos cvs_output (":", 0);
2031b22328f9Schristos
2032b22328f9Schristos temp = strtok (NULL, ",\t");
2033b22328f9Schristos
2034b22328f9Schristos cvs_output (temp, 0);
2035b22328f9Schristos cvs_output (" ", 0);
2036b22328f9Schristos
2037b22328f9Schristos while ((temp = strtok (NULL, "!\t")) != NULL)
2038b22328f9Schristos {
2039b22328f9Schristos int printed = 0;
2040b22328f9Schristos int c2 = 0;
2041b22328f9Schristos while (printedusers[c2] != NULL && printed == 0)
2042b22328f9Schristos {
2043b22328f9Schristos if (strcmp (printedusers[c2], temp) == 0)
2044b22328f9Schristos {
2045b22328f9Schristos printed = 1;
2046b22328f9Schristos break;
2047b22328f9Schristos }
2048b22328f9Schristos c2++;
2049b22328f9Schristos }
2050b22328f9Schristos
2051b22328f9Schristos if (printed == 0)
2052b22328f9Schristos {
2053b22328f9Schristos cvs_output (temp, 0);
2054b22328f9Schristos cvs_output (":", 0);
2055b22328f9Schristos }
2056b22328f9Schristos
2057b22328f9Schristos temp = strtok (NULL, ",\t");
2058b22328f9Schristos
2059b22328f9Schristos if (temp[strlen (temp) - 2] == ':')
2060b22328f9Schristos temp[strlen (temp) - 2] = '\0';
2061b22328f9Schristos
2062b22328f9Schristos if (printed == 0)
2063b22328f9Schristos {
2064b22328f9Schristos cvs_output (temp, 0);
2065b22328f9Schristos cvs_output (" ", 0);
2066b22328f9Schristos }
2067b22328f9Schristos }
2068b22328f9Schristos def = 1;
2069b22328f9Schristos }
2070b22328f9Schristos else if (cvs_acl_default_permissions)
2071b22328f9Schristos {
2072b22328f9Schristos cvs_output ("| defaults ", 0);
2073b22328f9Schristos cvs_output ("ALL: ", 0);
2074b22328f9Schristos cvs_output (cvs_acl_default_permissions, 0);
2075b22328f9Schristos }
2076b22328f9Schristos }
2077b22328f9Schristos else
2078b22328f9Schristos {
2079b22328f9Schristos if (acldir)
2080b22328f9Schristos cvs_output ("d ", 0);
2081b22328f9Schristos else if (aclfile)
2082b22328f9Schristos cvs_output ("f ", 0);
2083b22328f9Schristos cvs_output (obj, 0);
2084b22328f9Schristos cvs_output (" | ", 0);
2085b22328f9Schristos cvs_output (tag, 0);
2086b22328f9Schristos cvs_output (" | ", 0);
2087b22328f9Schristos
2088b22328f9Schristos if (default_perms_object)
2089b22328f9Schristos {
2090b22328f9Schristos cvs_output ("| defaults ", 0);
2091b22328f9Schristos cvs_output ("ALL:", 0);
2092b22328f9Schristos cvs_output (default_perms_object, 0);
2093b22328f9Schristos def = 1;
2094b22328f9Schristos }
2095b22328f9Schristos if (default_part_perms_accessfile)
2096b22328f9Schristos {
2097b22328f9Schristos free (line);
2098b22328f9Schristos line = xstrdup (default_part_perms_accessfile);
2099b22328f9Schristos
2100b22328f9Schristos if (!def)
2101b22328f9Schristos cvs_output ("| defaults ", 0);
2102b22328f9Schristos else
2103b22328f9Schristos cvs_output (" ", 0);
2104b22328f9Schristos
2105b22328f9Schristos temp = strtok (line, "!\t");
2106b22328f9Schristos cvs_output (temp, 0);
2107b22328f9Schristos cvs_output (":", 0);
2108b22328f9Schristos
2109b22328f9Schristos temp = strtok (NULL, ",\t");
2110b22328f9Schristos
2111b22328f9Schristos if (temp[strlen (temp) - 2] == ':')
2112b22328f9Schristos temp[strlen (temp) - 2] = '\0';
2113b22328f9Schristos
2114b22328f9Schristos cvs_output (temp, 0);
2115b22328f9Schristos cvs_output (" ", 0);
2116b22328f9Schristos
2117b22328f9Schristos while ((temp = strtok (NULL, "!\t")) != NULL)
2118b22328f9Schristos {
2119b22328f9Schristos cvs_output (temp, 0);
2120b22328f9Schristos cvs_output (":", 0);
2121b22328f9Schristos
2122b22328f9Schristos if ((temp = strtok (NULL, ",\t")) != NULL)
2123b22328f9Schristos {
2124b22328f9Schristos if (temp[strlen (temp) - 2] == ':')
2125b22328f9Schristos temp[strlen (temp) - 2] = '\0';
2126b22328f9Schristos
2127b22328f9Schristos cvs_output (temp, 0);
2128b22328f9Schristos cvs_output (" ", 0);
2129b22328f9Schristos }
2130b22328f9Schristos }
2131b22328f9Schristos cvs_output ("\n", 0);
2132b22328f9Schristos }
2133b22328f9Schristos else if (cvs_acl_default_permissions)
2134b22328f9Schristos {
2135b22328f9Schristos cvs_output ("| defaults ", 0);
2136b22328f9Schristos cvs_output ("ALL: ", 0);
2137b22328f9Schristos cvs_output (cvs_acl_default_permissions, 0);
2138b22328f9Schristos }
2139b22328f9Schristos else
2140b22328f9Schristos cvs_output ("default:p (no perms)", 0);
2141b22328f9Schristos }
2142b22328f9Schristos cvs_output ("\n", 0);
2143b22328f9Schristos
2144b22328f9Schristos while (c >= 0) {
2145b22328f9Schristos free (printedusers[c]);
2146b22328f9Schristos c--;
2147b22328f9Schristos }
2148b22328f9Schristos
2149b22328f9Schristos free (line);
2150b22328f9Schristos }
2151b22328f9Schristos
2152b22328f9Schristos /* find username
2153b22328f9Schristos * returns username with its permissions if user found
2154b22328f9Schristos * returns NULL if user not found */
findusername(const char * string1,const char * string2)2155b22328f9Schristos char *findusername (const char *string1, const char *string2)
2156b22328f9Schristos {
2157b22328f9Schristos char *tmp1, *tmp2;
2158b22328f9Schristos
2159b22328f9Schristos if (string1 != NULL && string2 != NULL)
2160b22328f9Schristos {
2161b22328f9Schristos tmp1 = xstrdup (string1);
2162b22328f9Schristos tmp2 = strtok (tmp1, ",\t");
2163b22328f9Schristos
2164b22328f9Schristos do
2165b22328f9Schristos {
2166b22328f9Schristos if (strncmp (tmp2, string2, strlen (string2)) == 0 &&
2167b22328f9Schristos tmp2[strlen (string2)] == '!')
2168b22328f9Schristos {
2169cc7958a0Schristos tmp2 = xstrdup (tmp2);
2170cc7958a0Schristos free (tmp1);
2171b22328f9Schristos return tmp2;
2172b22328f9Schristos }
2173b22328f9Schristos tmp2 = strtok (NULL, ",\t");
2174b22328f9Schristos }
2175b22328f9Schristos while (tmp2 != NULL);
2176b22328f9Schristos
2177b22328f9Schristos free (tmp1);
2178b22328f9Schristos
2179b22328f9Schristos return NULL;
2180b22328f9Schristos }
2181b22328f9Schristos else
2182b22328f9Schristos return NULL;
2183b22328f9Schristos }
2184b22328f9Schristos
2185b22328f9Schristos /* find user name in group file
2186b22328f9Schristos * returns group name if user found
2187b22328f9Schristos * returns NULL if user not found */
findgroupname(const char * string1,const char * string2)2188b22328f9Schristos char *findgroupname (const char *string1, const char *string2)
2189b22328f9Schristos {
2190b22328f9Schristos char *tmp1, *tmp2;
2191b22328f9Schristos char *grpname;
2192b22328f9Schristos
2193b22328f9Schristos if (string1 != NULL && string2 != NULL)
2194b22328f9Schristos {
2195b22328f9Schristos tmp1 = xstrdup (string1);
2196b22328f9Schristos grpname = strtok (tmp1, ":\t");
2197b22328f9Schristos
2198b22328f9Schristos while (tmp2 = strtok(NULL, ",\t"))
2199b22328f9Schristos {
2200b22328f9Schristos if (strcmp (tmp2, string2) == 0)
2201b22328f9Schristos {
2202cc7958a0Schristos grpname = xstrdup (grpname);
2203cc7958a0Schristos free (tmp1);
2204b22328f9Schristos return grpname;
2205b22328f9Schristos }
2206b22328f9Schristos }
2207b22328f9Schristos
2208b22328f9Schristos free (tmp1);
2209b22328f9Schristos
2210b22328f9Schristos return NULL;
2211b22328f9Schristos }
2212b22328f9Schristos else
2213b22328f9Schristos return NULL;
2214b22328f9Schristos }
2215