]> git.pld-linux.org Git - packages/cvs.git/blame - cvs-acl.patch
- ACL patch updated to 1.2.1, release 3
[packages/cvs.git] / cvs-acl.patch
CommitLineData
67ba4c3a 1diff -urN cvs-1.11.17.orig/aclconfig.default cvs-1.11.17/aclconfig.default
2--- cvs-1.11.17.orig/aclconfig.default 1970-01-01 01:00:00.000000000 +0100
3+++ cvs-1.11.17/aclconfig.default 2004-06-17 14:33:44.000000000 +0200
4@@ -0,0 +1,33 @@
5+# Set `UseCVSACL' to yes to use CVS ACL feature.
6+UseCVSACL=yes
7+
8+# Default CVS ACL Permission are to use.
9+#CVSACLDefaultPermissions=a
10+
11+# Default file location for CVS ACL file (access) is CVSROOT/access.
12+# If you want to use a different location, define it below.
13+#CVSACLFileLocation=/path/to/cvs/access
14+
15+# Set `UseSystemGroups' to yes to use system group definitions (/etc/group).
16+UseSystemGroups=yes
17+
18+# Set `UseCVSGroups' to yes to use another group file.
19+#UseCVSGroups=yes
20+
21+# Default file location for CVS groups file is CVSROOT/group.
22+# If you want to use a different location, define it below.
23+#CVSGroupsFileLocation=/path/to/cvs/group
24+
25+# Set UseSeparateACLFileForEachDir to yes in order to use a
26+# separate 'access' file for each directory.
27+# This increased the performance if you have really big repository.
28+#UseSeparateACLFileForEachDir=no
29+
30+# If StopAtFirstPermissionDenied is set to yes
31+# operation will stop at first permission denied message.
32+# Default is no.
33+#StopAtFirstPermissionDenied=no
34+
35+# Set CVSServerRunAsUser to a system user, in order CVS server
36+# to run as.
37+#CVSServerRunAsUser=runascvsuser
c52fdbcd 38diff -urN cvs-1.11.17.orig/INSTALL.cvsacl cvs-1.11.17/INSTALL.cvsacl
39--- cvs-1.11.17.orig/INSTALL.cvsacl 1970-01-01 01:00:00.000000000 +0100
67ba4c3a 40+++ cvs-1.11.17/INSTALL.cvsacl 2004-06-25 07:39:24.000000000 +0200
09f63587 41@@ -0,0 +1,23 @@
42+
43+Installation
44+
45+- copy the file acl.c under src directory of CVS source distribution.
c52fdbcd 46+ "cp acl.c /path/to/cvs-1.11.17/src/"
67ba4c3a 47+- copy the patch file cvsacl-patch-1.2.1 under CVS source distribution
09f63587 48+ directory.
67ba4c3a 49+ "cp cvsacl-patch-1.2.1 /path/to/cvs-1.11.17/"
09f63587 50+- cd to CVS source directory.
c52fdbcd 51+ "cd /path/to/cvs-1.11.17/"
09f63587 52+- apply the patch.
67ba4c3a 53+ "patch -p0 < cvsacl-patch-1.2.1"
09f63587 54+- if you are initializing the repository after applying patch, related
55+ config files will be created with init command.
56+ "cvs -d /path/to/repository init"
57+- if you already have a repository, you have to add the aclconfig file
58+ to your $CVSROOT/CVSROOT/. aclconfig.default is the default configuration
59+ file, you can rename it to aclconfig, and use it .
60+- modify aclconfig file, if you need to change some options.
61+- as the last step, you have to define yourself as acl administrator.
62+ "cvs -d /path/to/repository racl yourname:p -r ALL -d ALL"
63+ this command gives p (acl admin) rights to user (yourname),
64+ on all repository and tags/branches.
c52fdbcd 65diff -urN cvs-1.11.17.orig/README.cvsacl cvs-1.11.17/README.cvsacl
66--- cvs-1.11.17.orig/README.cvsacl 1970-01-01 01:00:00.000000000 +0100
67ba4c3a 67+++ cvs-1.11.17/README.cvsacl 2004-06-25 07:39:30.000000000 +0200
09f63587 68@@ -0,0 +1,282 @@
69+
70+CVS Access Control List Extension Patch
71+
72+http://cvsacl.sourceforge.net/
73+sbaris@users.sourceforge.net
74+
75+CVSACL is a patch for CVS. It adds two new subcommands
76+(acl & racl) to cvs for access control list management. It
77+provides advanced ACL definitions per modules, directories,
78+and files on branch/tag for remote cvs repository connections.
79+Execution of all CVS subcommands can be controlled with eight
80+different permissions.
81+ACL definitions works for only remote connections, local users
82+can access and modify repository, if unix file system permissions
83+allow. If you want all users to make remote connections to
84+repository, and not allow local users to access repository, you
85+have to set CVSServerRunAsUser keyword in aclconfig file
86+(explained below).
87+Still local users can use acl and racl subcommands to set
88+permissions on directories or files if they have acl admin rights (p)
89+on related directories or files.
90+So, in order to control all access to repository with this ACL
91+extension, you should use CVSServerRunAsUser keyword and force all
92+users to make remote connections. CVS repository administrator or
93+project managers have to use acl and racl subcommands to manage
94+permissions. But there is no gui client supporting these subcommands,
95+so you have to use cvs client itself either locally or remotely.
96+
97+
98+
99+
100+Permission Types
101+
102+- no access
103+ Command line character: n
104+ If a user given n permission, it is not allowed for any action on repository.
105+- read
106+ Command line character: r
107+ r permission gives only read access on repository.
108+ With r permission you are allowed to run cvs subcommands: annotate,
109+ checkout, diff, export, log, rannotate, rdiff, rlog, status.
110+- write
111+ Command line character: w
112+ w permission allows only cvs commit/checkin action.
113+ With w permission, you are not allowed to add/remove any file to/from
114+ repository, other permissions should be defines for that.
115+- tag
116+ Command line character: t
117+ t permission allows cvs tag and rtag subcommands to run, so you may
118+ control tagging and untagging operations. t permission includes r
119+ permission, since without reading you can not tag/untag a file.
120+ However t permission does not include write permission, you can not
121+ commit a file with only t permission.
122+- create
123+ Command line character: c
124+ c permission allows cvs add and import subcommands to run. To add or
125+ import a file/directory to repository, you have to given a c
126+ permission. Again, c permission does not include write permission,
127+ thus you may only add or import files, but you can not modify any
128+ existing file. After issuing add subcommand, you have to commit the file
129+ to complete adding. This commit subcommand is allowed because you are
130+ adding file and not modifying existing one.
131+- delete
132+ Command line character: d
133+ d permission allows cvs remove command to run. To remove a file/directory
134+ from repository, d permission have to set. It does not include write
135+ permission, so you can not modify contents of an existing file on repository.
136+- full access except admin rights
137+ Command line character: a
138+ a permission gives all access (above permissions) to repository, but it
139+ can not modify permissions. Only acl admins may modify the acl definitions.
140+- acl admin
141+ Command line character: p
142+ p permission means that user is an acl admin, so it is allowed to make anything on repository.
143+
144+
145+ACL Config Keywords
146+The administrative file aclconfig contains miscellaneous settings which
147+affect the behaviour of ACL extension. Currently defined keywords are:
148+
149+UseCVSACL=value
150+Use ACL definitions if set to yes. If you do not want to use ACLs for
151+some repositories in a patched CVS server, set this keyword to no. The default is no.
152+
153+UseCVSACLDefaultPermissions=value
154+Value can be any combination of valid permission types (w,r,t,c,d,t,a,p).
155+if there is no defined ACL and default permission in access file, or no
156+access file at all, this permissions are used. The default is p (admin rights),
157+if aclconfig file is created with cvs init.
158+
159+UseCVSGroups=value
160+CVS does not have a CVSROOT/passwd file. However it can be created manually
161+(format should be same as /etc/group). If value set to yes, CVS checks for
162+groups in file $CVSROOT/CVSROOT/group The default value is no.
163+
164+UseSystemGroups=value
165+Group memberships for users are checked in file /etc/group, if value is set
166+to yes. The default value is no.
167+
168+CVSACLFileLocation=value
169+Originally access file is put under CVSROOT/CVSROOT, if you want a different
170+location, set value to a valid path. The default value is $CVSROOT/CVSROOT/access.
171+
172+CVSGroupsFileLocation=value
173+IF UseCVSGroups is set to yes, CVS looks for a group file under $CVSROOT/CVSROOT.
174+To use a different location for group file set value to a valid path to group.
175+The default value is $CVSROOT/CVSROOT/group.
176+
c52fdbcd 177+UseSeparateACLFileForEachDir=value
178+If value is set to yes, a separate ACL file (access) is created for each
09f63587 179+directory in repository. If you have a really big repository
180+(directories>10,000 and files>100,000), performance may drop due to a big
181+acl file, access. Setting the value to yes, may increase performance. Normally,
182+you will not need this. The default value is no.
183+
184+StopAtFirstPermissionDenied=value
185+If StopAtFirstPermissionDenied is set to yes
186+operation will stop at first permission denied message.
187+e.g. when you send commit command for a directory, if you dont
188+have write permission for just one file under the directory,
189+by default you will have a warning and commit will continue
190+on the other files. If you set this keyword to 'no', then
191+commit operation will be stopped when inaccassable file found.
192+Default is no.
193+
194+CVSServerRunAsUser=value
195+Set CVSServerRunAsUser keyword to a valid system user.
196+When a user make a remote connection to CVS, after successfull authentication
197+cvs process switch to run as that user, or defined system user in
198+$CVSROOT/CVSROOT/passwd. So, you also have to set unix file permissions accordingly.
199+A better solution:
200+Add a user and group such as both cvsadm.
201+Set CVSServerRunAsUser keyword to cvsadm.
202+Change unix file system permissions for your repository,
203+make cvsadm user and group owner, and read,write,execute permissions and setgid.
204+(chown cvsadm -R /path/to/your/repository)
205+(chgrp cvsadm -R /path/to/your/repository)
206+(chmod 2770 -R /path/to/your/repository)
207+Add yourself to cvsadm group (since you are ACL administrator).
208+Therefore, only users making remote connections will have access to repository
209+if you give rights. Local users can not access to repository via a cvs client or directly.
210+
211+
212+Command Line Usage Information
213+acl command is used on checked out files or directories. racl command is
214+used on repository without a working copy. Usage information can be obtained
215+with standard cvs --help command.
216+Output of cvs --help acl and cvs --help racl:
217+
218+Usage: cvs racl [user||group:permissions] [-Rl] [-r tag]
219+ -d [directory] -f [file]
220+ -R Process directories recursively.
221+ -r rev Existing revision/tag.
222+ -l List defined ACLs.
223+ -d dir Process on given directory.
224+ -f file Process on given file.
225+
226+Usage: cvs acl [user||group:permissions] [-Rl] [-r tag]
227+ -d [directory] -f [file]
228+ -R Process directories recursively.
229+ -r rev Existing revision/tag.
230+ -l List defined ACLs.
231+ -d dir Process on given directory.
232+ -f file Process on given file.
233+
234+You may directly set permissions for a user or group or add/remove
235+permissions with + and - signs to/from existing permissions.
236+If you do not give the branch/tag information, default value of HEAD
237+(main branch) will be used. You have to give branch/tag name with -r option.
238+You may type ALL for branch/tag field.
239+
240+While checking for permissions, it goes thorough the list below. So the highest
241+significant permission is the first item in list.
242+
243+- permissions assigned to username for specific directory or file.
244+- permissions assigned to group name for specific directory or file.
245+- permissions as defaults for specific directory or file.
246+- permissions assigned to parent folders (inherits from the first parent
247+ which permissions are assigned).
248+- permissions as repository defaults.
249+- permissions in aclconfig file.
250+
251+
252+
253+
254+Examples
255+ /cvs/
256+ |
257+ |
258+ +--projectA/
259+ | |
260+ | +---CVSROOT/
261+ | |
262+ | +---lib/
263+ | | |
264+ | | +---gnulib/
265+ | | |
266+ | | +---zlib/
267+ | |
268+ | +---src/
269+ | | |
270+ | | +---main.c
271+ | | |
272+ | | +---server.c
273+ | | |
274+ | | +---client.c
275+ | |
276+ | +---gui/
277+ |
278+ +--projectB/
279+We have above directory structure for a cvs repository, and no defined permissions.
280+
281+Setting main default permissions:
282+
283+$ cvs -d /cvs/projectA racl cvsadmin:p -r ALL -d ALL
284+$ cvs -d /cvs/projectA racl ALL:r -r ALL -d ALL
285+User cvsadmin will be an acl admin, and all other users will have only read
286+rights on all branches/tags in projectA repository. This is the default acl
287+definition and it overwrites default permissions in $CVSROOT/CVSROOT/aclconfig file.
288+
289+$ cvs -d /cvs/projectA racl ALL:r -r ALL -d ALL
290+$ cvs -d /cvs/projectA racl ALL:n -r ALL -d gui
291+After executing these two commands, all users will have read access on all
292+directories and files except gui directory. Everyone will be denied to access to gui
293+directory becase no access, n, permissions is set.
294+
295+Setting permissions directly on a file or directory:
296+
297+$ cvs -d /cvs/projectA racl userX:wcd -d lib
298+$ cvs -d /cvs/projectA racl group1:w -d lib
299+First command will set write, create, and delete permissions for userX on directory
300+lib with branch HEAD (since no branch/tag information given, branch defaults to HEAD).
301+Second command will set only write permission for group1 on directory lib with branch HEAD.
302+Members of group1 will have only commit rights on lib directory, branch HEAD, they can
303+not add or remove any file, just modify existing files.
304+If userX is also a member of group1, userX will have write, create, and delete permissions
305+because it is specifically given these permissions.
306+
307+$ cvs -d /cvs/projectA racl userY:wcd -r develStream -d lib
308+$ cvs -d /cvs/projectA racl userY:r -r integStream -d lib
309+These commands will give wcd permissions to userY on lib directory with tag develstream,
310+and r permissions on lib directory with tag integStream.
311+
312+$ cvs -d /cvs/projectA racl userZ:wcd -d src
313+$ cvs -d /cvs/projectA racl userZ:r -f src/main.c
314+First command will give wcd permissions to userZ on src directory, but only read
315+permission on file main.c in src directory.
316+
317+Using + and - signs to set permissions on a file or directory:
318+
319+$ cvs -d /cvs/projectA racl userZ:+t -d src
320+$ cvs -d /cvs/projectA racl userZ:-cd -d src
321+$ cvs -d /cvs/projectA racl userZ:-wt -d src
322+Before the first command, userZ has wcd permissions on src directory, after issuing
323+command it will have wcdt permissions. Tag permission will be added. UserZ has wcdt
324+permissions, and we execute the second command to remove create and delete permissions.
325+So userZ has wt permissions. In the last command we also remove wt permissions, finally
326+userZ has no defined permissions left, and it will use the default permissions if set.
327+
328+Listing permissions on a file or directory:
329+
330+$ cvs -d /cvs/projectA racl -l -d src
331+$ cvs -d /cvs/projectA racl -l -f src
332+$ cvs -d /cvs/projectA racl -l -f src/main.c
333+
334+First command will list the permissions for src directory.
335+Example output:
336+d src HEAD | userX:wcd group1:r | defaults:r
337+userX and group1 has assigned permissions, all other users will have default
338+permissions, which is only read.
339+
340+Second command will list the permissions for files in src directory.
341+Example output:
342+f src/main.c HEAD | userX:wcd group1:r | defaults:r
343+f src/server.c HEAD | userX:wcd group1:r | defaults:r
344+f src/client.c HEAD | userX:wcd group1:r | defaults:r
345+
346+Third command will list the permissions for main.c file in src directory.
347+Example output:
348+f src/main.c HEAD | userX:wcd group1:r | defaults:r
349+
350+
c52fdbcd 351diff -urN cvs-1.11.17.orig/src/acl.c cvs-1.11.17/src/acl.c
352--- cvs-1.11.17.orig/src/acl.c 1970-01-01 01:00:00.000000000 +0100
67ba4c3a 353+++ cvs-1.11.17/src/acl.c 2004-06-24 10:52:51.000000000 +0200
354@@ -0,0 +1,2028 @@
09f63587 355+/*
356+ *
357+ * CVS ACCESS CONTROL LIST EXTENSION
358+ *
359+ * sbaris@users.sourceforge.net
360+ *
361+ * http://cvsacl.sourceforge.net/
362+ *
c52fdbcd 363+ * CVSACL is a patch for CVS versions
364+ * - cvs-1.11.17
365+ *
09f63587 366+ * It adds two new subcommands (acl & racl) to cvs for access control
367+ * list management.
368+ * It provides advanced ACL definitions per modules, directories,
369+ * and files on branch/tag for remote cvs repository connections.
370+ * Execution of all CVS subcommands can be controlled with eight
371+ * different permissions.
372+ * ACL definitions works for only remote connections, local users can
373+ * access and modify repository, if unix file system permissions allow.
374+ * If you want all users to make remote connections to repository,
375+ * and not allow local users to access repository, you have to set
376+ * CVSServerRunAsUser keyword in aclconfig file (explained below).
377+ * Still local users can use acl and racl subcommands to set permissions
378+ * on directories or files if they have acl admin rights (p) on related
379+ * directories or files.
380+ * So, in order to control all access to repository with this ACL extension,
381+ * you should use CVSServerRunAsUser keyword and force all users to make
382+ * remote connections.
383+ * CVS repository administrator or project managers have to use acl and racl
384+ * subcommands to manage permissions. But there is no gui client supporting
385+ * these subcommands, so you have to use cvs client itself either
386+ * locally or remotely.
387+ *
388+ *
389+ * Permission Types:
390+ * - no permission (n) (1)
391+ * - all permissions (a) (2)
392+ * - write permission (w) (3)
393+ * - tag permission (t) (4)
394+ * - read permission (r) (5)
395+ * - add permission (c) (6)
396+ * - remove permission (d) (7)
397+ * - permission change (p) (8)
398+ *
399+ *
400+ *
401+ *
402+ * ********************************************************************
403+ * This program is free software; you can redistribute it and/or modify
404+ * it under the terms of the GNU General Public License as published by
405+ * the Free Software Foundation; either version 1, or (at your option)
406+ * any later version.
407+ *
408+ * This program is distributed in the hope that it will be useful,
409+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
410+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
411+ * GNU General Public License for more details.
412+ * *******************************************************************
413+ *
414+ */
415+
416+#include "cvs.h"
417+#include "getline.h"
418+#include <grp.h>
419+
420+static int acl_fileproc PROTO ((void *callerdat, struct file_info *finfo));
421+static Dtype acl_dirproc PROTO ((void *callerdat, const char *dir, const char *repos,
422+ const char *update_dir, List *entries));
423+
424+static int acllist_fileproc PROTO ((void *callerdat, struct file_info *finfo));
425+static Dtype acllist_dirproc PROTO ((void *callerdat, const char *dir, const char *repos,
426+ const char *update_dir, List *entries));
427+
428+static void acllist_print PROTO ((char *line, const char *obj));
429+
430+static int racl_proc PROTO((int argc, char **argv, char *xwhere,
431+ char *mwhere, char *mfile, int shorten,
432+ int local_specified, char *mname, char *msg));
433+
67ba4c3a 434+FILE *open_accessfile (char *xmode, const char *repos, char **fname);
09f63587 435+FILE *open_groupfile (char *xmode);
436+
437+char *get_perms (char *xperms);
438+char *make_perms (char *xperms, char *xfounduserpart, char **xerrmsg);
439+
440+static char *cache_repository;
441+static int cache_retval;
442+static int founddeniedfile;
443+static int cache_perm;
444+
445+static int is_racl;
446+
447+int use_cvs_acl = 0;
448+char *cvs_acl_default_permissions;
449+int use_cvs_groups = 0;
450+int use_system_groups = 0;
c52fdbcd 451+int use_separate_acl_file_for_each_dir = 0;
09f63587 452+char *cvs_acl_file_location = NULL;
453+char *cvs_groups_file_location = NULL;
454+char *cvs_server_run_as = NULL;
455+int stop_at_first_permission_denied = 0;
456+
457+char *tag = NULL;
458+
459+char *muser;
460+char *mperms;
461+static int defaultperms;
462+
463+static char *default_perms_object;
464+char *default_part_perms_accessfile;
465+
466+int acldir = 0;
467+int aclfile = 0;
468+int listacl = 0;
469+
470+int userfound;
471+int groupfound;
472+
473+char *dirs[25];
474+
475+int aclconfig_default_used;
476+
477+static const char *const acl_usage[] =
478+ {
479+ "Usage: %s %s [user||group:permissions] [-Rl] [-r tag]\n -d [directory] -f [file]\n",
480+ "\t-R\tProcess directories recursively.\n",
481+ "\t-r rev\tExisting revision/tag.\n",
482+ "\t-l\tList defined ACLs.\n",
483+ "\t-d dir\tProcess on given directory.\n",
484+ "\t-f file\tProcess on given file.\n",
485+ "(Specify the --help global option for a list of other help options)\n",
486+ NULL
487+ };
488+
489+static const char *const racl_usage[] =
490+ {
491+ "Usage: %s %s [user||group:permissions] [-Rl] [-r tag]\n -d [directory] -f [file]\n",
492+ "\t-R\tProcess directories recursively.\n",
493+ "\t-r rev\tExisting revision/tag.\n",
494+ "\t-l\tList defined ACLs.\n",
495+ "\t-d dir\tProcess on given directory.\n",
496+ "\t-f file\tProcess on given file.\n",
497+ "(Specify the --help global option for a list of other help options)\n",
498+ NULL
499+ };
500+
501+
502+int
503+access_allowed (file, repos, tag, perm, mline, mpos, usecache)
504+char *file;
505+char *repos;
506+char *tag;
507+int perm;
508+char **mline;
509+int *mpos;
510+int usecache;
511+{
512+ int retval = 0;
513+ int foundline = 0;
514+ FILE *accessfp;
515+
516+ char *line = NULL;
517+ size_t line_allocated = 0;
518+
519+ char *part_type = NULL;
520+ char *part_object = NULL;
521+ char *part_tag = NULL;
522+ char *part_perms = NULL;
523+ char *xline;
67ba4c3a 524+ int x;
09f63587 525+
526+ char *iline;
527+
528+ char *tempv;
529+ char *tempc;
530+ size_t tempsize;
531+ int intcount;
532+
533+ int oneaccessfile = 0;
534+ int accessfilecount;
535+
67ba4c3a 536+ int signlevel = -1;
09f63587 537+
538+ int dadmin = 0;
539+
540+ const char *repository;
541+ char *filefullname = NULL;
542+
543+
544+ userfound = 0;
545+ groupfound = 0;
546+
547+
548+ if (defaultperms)
549+ {
550+ repository = xstrdup ("ALL");
551+ }
552+ else
553+ repository = Short_Repository (repos);
554+
555+ /* cache */
556+ if (usecache
557+ && cache_repository != NULL
558+ && strcmp (cache_repository, repository) == 0
559+ && !founddeniedfile
560+ && perm == cache_perm)
561+ return (cache_retval);
562+ else
563+ {
564+ free(cache_repository);
565+ cache_repository = xstrdup(repository);
566+ cache_perm = perm;
567+ }
568+
569+ if (file != NULL)
570+ {
571+ filefullname = xmalloc (strlen (repository)
572+ + strlen (file)
573+ + 2);
574+
575+ strcpy (filefullname, repository);
576+ strcat (filefullname, "/");
577+ strcat (filefullname, file);
578+ }
579+
580+
581+ iline = xstrdup(repository);
582+
583+ tempv = strtok(iline, "/\t");
584+ tempc = xstrdup(tempv);
585+ tempsize = strlen(tempc);
586+
587+ intcount = 0;
588+
589+ dirs[intcount] = xstrdup(tempc);
590+
591+ while ((tempv = strtok(NULL, "/\t")) != NULL)
592+ {
593+ intcount++;
594+
595+ xrealloc_and_strcat(&tempc, &tempsize, "/");
596+ xrealloc_and_strcat(&tempc, &tempsize, tempv);
597+
598+ dirs[intcount] = xstrdup(tempc);
599+ }
600+
601+ if (file != NULL)
602+ {
67ba4c3a 603+ accessfilecount = intcount;
09f63587 604+ intcount++;
605+ dirs[intcount] = xstrdup(filefullname);
606+ }
607+
67ba4c3a 608+ for (accessfilecount; accessfilecount >= 0 && !oneaccessfile; accessfilecount--)
09f63587 609+ {
c52fdbcd 610+ if (!use_separate_acl_file_for_each_dir)
09f63587 611+ oneaccessfile = 1;
c52fdbcd 612+ else if (use_separate_acl_file_for_each_dir)
09f63587 613+ oneaccessfile = 0;
614+
67ba4c3a 615+ if (acldir || aclfile)
616+ oneaccessfile = 1;
617+
09f63587 618+ if (oneaccessfile)
67ba4c3a 619+ accessfp = open_accessfile ("r", repository, NULL);
09f63587 620+ else
621+ accessfp = open_accessfile ("r", dirs[accessfilecount], NULL);
622+
623+ if (accessfp != NULL)
624+ {
625+ while (getline (&line, &line_allocated, accessfp) >= 0)
626+ {
67ba4c3a 627+
09f63587 628+ if (line[0] == '#' || line[0] == '\0' || line[0] == '\n')
629+ continue;
630+
631+ xline = xstrdup (line);
632+ part_type = strtok (line, ":\t");
633+ part_object = strtok (NULL, ":\t");
634+ part_tag = strtok (NULL, ":\t");
635+ part_perms = strtok (NULL, ":\t");
636+
67ba4c3a 637+ for (x = intcount; x >= signlevel && x != -1; x--)
09f63587 638+ {
639+ if (strcmp (dirs[x], part_object) == 0)
640+ {
641+ if (valid_tag (part_tag, tag))
642+ {
643+ foundline = 1;
644+
c52fdbcd 645+ if (listacl || acldir || aclfile)
09f63587 646+ {
647+ *mline = xstrdup (xline);
648+ *mpos = ftell (accessfp);
649+ }
650+
651+ if (valid_perm (part_perms, perm))
652+ {
653+ if (signlevel == x)
654+ {
655+ if (strncmp(part_tag, "ALL", 3) != 0 && !aclconfig_default_used)
656+ retval = 1;
657+ }
658+ else if (!aclconfig_default_used)
659+ {
660+ signlevel = x;
661+ retval = 1;
662+ }
67ba4c3a 663+ else {
664+ }
09f63587 665+ }
666+ else
667+ {
668+ if (signlevel == x)
669+ {
670+ if (strncmp(part_tag, "ALL", 3) != 0 && !aclconfig_default_used)
671+ retval = 0;
672+ }
673+ else if (!aclconfig_default_used)
674+ {
675+ signlevel = x;
676+ retval = 0;
677+
678+ if (strncmp (part_type, "f", 1) == 0)
679+ founddeniedfile = 1;
67ba4c3a 680+ }
681+ else {
09f63587 682+ }
683+ }
684+ }
685+ }
686+ }
687+ if (strncmp (xline, "d:ALL", 5) == 0 && (!groupfound && !userfound || listacl))
688+ {
689+ /* a default found */
690+ if (valid_tag (part_tag, tag))
691+ {
692+ foundline = 1;
693+
694+ default_part_perms_accessfile = xstrdup (part_perms);
695+
696+ if (valid_perm (part_perms, perm))
697+ {
698+ retval = 1;
699+
700+ if (perm == 8)
701+ dadmin = 1;
702+ }
703+ else
704+ retval = 0;
705+ }
706+ }
707+
708+ }
709+ if (fclose (accessfp) == EOF)
710+ error (1, errno, "cannot close 'access' file");
711+
712+ }
713+ }
714+
715+ if (!foundline)
716+ {
717+ /* DEFAULT */
718+ if (valid_perm (NULL, perm))
719+ retval = 1;
720+ else
721+ retval = 0;
722+ }
723+
724+ if (dadmin)
725+ {
726+ retval = dadmin;
727+ }
728+
729+ cache_retval = retval;
730+
731+ free (filefullname);
732+
733+ return (retval);
734+}
735+
736+/* Returns 1 if successful, 0 if not. */
737+int
738+valid_tag (part_tag, tag)
739+char *part_tag;
740+char *tag;
741+{
742+ if (tag == NULL)
743+ tag = xstrdup ("HEAD");
744+
745+ if (strcmp (part_tag, "ALL") == 0)
746+ return (1);
747+
748+ if (strcmp (tag, part_tag) == 0)
749+ return (1);
750+ else
751+ return (0);
752+}
753+
754+/* Returns 1 if successful, 0 if not. */
755+int
756+valid_perm (part_perms, perm)
757+char *part_perms;
758+int perm;
759+{
760+ char *perms;
761+ int retval = 0;
762+
763+ perms = get_perms (part_perms);
764+
765+ /* Allow, if nothing found. */
766+ if (perms[0] == '\0')
767+ return (1);
768+
769+
770+ if (strstr (perms, "n"))
771+ retval = 0; /* no access allowed, exit */
772+ if (strstr (perms, "p"))
773+ retval = 1; /* admin rights */
774+ else if (strstr (perms, "a") && perm != 8)
775+ retval = 1; /* all access allowed, exit */
776+ else
777+ switch (perm)
778+ {
779+ case 3: /* write permission */
780+ if (strstr (perms, "w"))
781+ retval = 1;
782+ break;
783+ case 4: /* tag permission */
784+ if (strstr (perms, "t"))
785+ retval = 1;
786+ break;
787+ case 5: /* read permission */
788+ if (strstr (perms, "w") || strstr (perms, "t") || strstr (perms, "c") ||
789+ strstr (perms, "d") || strstr (perms, "r"))
790+ retval = 1;
791+ break;
792+ case 6: /* create permission */
793+ if (strstr (perms, "c"))
794+ retval = 1;
795+ break;
796+ case 7: /* delete permission */
797+ if (strstr (perms, "d"))
798+ retval = 1;
799+ break;
800+ case 8: /* permission change */
801+ if (strstr (perms, "p"))
802+ retval = 1;
803+ break;
804+ default:
805+ retval = 0; /* never reached */
806+ break;
807+ }
808+
809+ return (retval);
810+}
811+
812+char *
813+get_perms (part_perms)
814+char *part_perms;
815+
816+{
817+ char *username;
818+ char *xperms;
819+ size_t xperms_len = 1;
820+
821+ FILE *groupfp;
822+
823+ char *usr;
824+ char *per;
825+ char *founduser = NULL;
826+ char *foundall = NULL;
827+ int default_checked = 0;
828+
829+ aclconfig_default_used = 0;
830+
831+ xperms = xmalloc (xperms_len);
832+ xperms[0] = '\0';
833+
834+ username = getcaller ();
835+
836+ /* no defined acl, no default acl in access file,
837+ or no access file at all */
838+ if (part_perms == NULL)
839+ if (cvs_acl_default_permissions)
840+ {
841+ aclconfig_default_used = 1;
842+ return (cvs_acl_default_permissions);
843+ }
844+ else
845+ return (xperms);
846+
847+check_default:
848+ founduser = strstr (part_perms, username);
849+ foundall = strstr (part_perms, "ALL!");
850+
851+ if (founduser)
852+ {
853+ usr = strtok (founduser, "!\t");
854+ per = strtok (NULL, ",\t");
855+
856+ if (strcmp (usr, username) == 0)
857+ {
858+ xperms = xstrdup (per);
859+ xperms_len = strlen (xperms);
860+
861+ userfound = 1;
862+ }
863+ }
864+ else
865+ {
866+ if (use_system_groups) {
867+ struct group *griter;
868+ setgrent ();
869+ while (griter = getgrent ()) {
870+ char **users=griter->gr_mem;
871+ int index = 0;
872+ char *userchk = users [index++];
873+ while(userchk != NULL) {
874+ if(strcmp (userchk, username) == 0)
875+ break;
876+ userchk = users[index++];
877+ }
878+ if (userchk != NULL) {
879+ char *grp;
880+ if ((grp = strstr (part_perms, griter->gr_name)) && grp[strlen (griter->gr_name)] == '!') {
881+ char *gperm = strtok (grp, "!\t");
882+ gperm = strtok (NULL, ",\t");
883+ xrealloc_and_strcat (&xperms, &xperms_len, gperm);
884+
885+ groupfound = 1;
886+ }
887+ }
888+ }
889+ endgrent ();
890+ }
891+ else if (use_cvs_groups) {
892+ groupfp = open_groupfile ("r");
893+ if (groupfp != NULL)
894+ {
895+ char *line = NULL;
896+ size_t line_allocated = 0;
897+
898+ while (getline (&line, &line_allocated, groupfp) >= 0)
899+ {
900+ if (strstr (line, username))
901+ {
902+ char *temp;
903+ temp = strstr (line, username);
904+
905+ if (temp[strlen (username)] == ','
906+ || temp[strlen (username)] == ' '
907+ || temp[strlen (username)] == '\n')
908+ {
909+ char *tmp;
910+ tmp = strtok (line, ":\t");
911+ if (strcmp (tmp, username) != 0)
912+ {
913+ char *grp;
914+ if ((grp = strstr (part_perms, tmp)))
915+ if (grp[strlen (tmp)] == '!')
916+ {
917+ char *gperm;
918+ gperm = strtok (grp, "!\t");
919+ gperm = strtok (NULL, ",\t");
920+
921+ xrealloc_and_strcat (&xperms, &xperms_len, gperm);
922+
923+ groupfound = 1;
924+ }
925+ }
926+ }
927+ }
928+ }
929+ if (fclose (groupfp) == EOF)
930+ error (1, errno, "cannot close 'group' file");
931+ }
932+ }
933+ }
934+
935+ if (foundall && (!groupfound && !userfound))
936+ {
937+ usr = strtok (strstr (part_perms, "ALL!"), "!\t");
938+ per = strtok (NULL, ",\t");
939+
940+ if (!default_checked)
941+ default_perms_object = xstrdup (per);
942+
943+ if (xperms[0] == '\0')
944+ {
945+ xperms = xstrdup (per);
946+ xperms_len = strlen (xperms);
947+ }
948+ }
949+ else if (xperms[0] == '\0' && !default_checked && default_part_perms_accessfile)
950+ {
951+ part_perms = xstrdup (default_part_perms_accessfile);
952+ default_checked = 1;
953+
954+ goto check_default;
955+ }
956+
957+ if (xperms[0] != '\0' && strcmp (xperms, "x") == 0)
958+ {
959+ if (default_perms_object)
960+ xperms = xstrdup (default_perms_object);
961+ else if (default_part_perms_accessfile)
962+ {
963+ part_perms = default_part_perms_accessfile;
964+ default_checked = 1;
965+ goto check_default;
966+ }
967+ else if (cvs_acl_default_permissions)
968+ {
969+ aclconfig_default_used = 1;
970+ xperms = xstrdup (cvs_acl_default_permissions);
971+ }
972+ }
973+
974+ if (xperms[0] == '\0' && cvs_acl_default_permissions)
975+ {
976+ aclconfig_default_used = 1;
977+ xperms = xstrdup (cvs_acl_default_permissions);
978+ }
979+
980+ return (xperms);
981+}
982+
983+
984+int
985+cvsacl (argc, argv)
986+int argc;
987+char **argv;
988+{
989+ char *chdirrepository;
990+ int c;
991+ int err = 0;
992+ int usetag = 0;
993+ int recursive = 0;
994+
995+ int k;
996+
997+ int which;
998+ char *where;
999+
1000+ is_racl = (strcmp (cvs_cmd_name, "racl") == 0);
1001+
1002+ if (argc == -1)
1003+ usage (is_racl ? racl_usage : acl_usage);
1004+
1005+ /* parse the args */
1006+ optind = 0;
1007+
1008+ while ((c = getopt (argc, argv, "Rr:dfl")) != -1)
1009+ {
1010+ switch (c)
1011+ {
1012+ case 'R':
1013+ recursive = 1;
1014+ break;
1015+ case 'r':
1016+ tag = xstrdup (optarg);
1017+ break;
1018+ case 'd':
1019+ acldir = 1;
1020+ break;
1021+ case 'f':
1022+ aclfile = 1;
1023+ break;
1024+ case 'l':
1025+ listacl = 1;
1026+ break;
1027+ case '?':
1028+ default:
1029+ usage (is_racl ? racl_usage : acl_usage);
1030+ break;
1031+ }
1032+ }
1033+
1034+ argc -= optind;
1035+ argv += optind;
1036+
1037+ if (!acldir && !aclfile)
1038+ usage (is_racl ? racl_usage : acl_usage);
1039+ if (acldir && aclfile)
1040+ usage (is_racl ? racl_usage : acl_usage);
1041+
1042+ if (listacl)
1043+ if (strstr (argv[0], ":"))
1044+ usage (is_racl ? racl_usage : acl_usage);
1045+ if (!listacl)
1046+ if (!strstr (argv[0], ":"))
1047+ usage (is_racl ? racl_usage : acl_usage);
1048+
1049+ if (argc < (is_racl ? 1 : 1))
1050+ usage (is_racl ? racl_usage : acl_usage);
1051+
1052+#ifdef CLIENT_SUPPORT
1053+
1054+ if (current_parsed_root->isremote)
1055+ {
1056+ start_server ();
1057+ ign_setup ();
1058+
1059+ if(recursive)
1060+ send_arg ("-R");
1061+
1062+ if (acldir)
1063+ send_arg ("-d");
1064+
1065+ if (aclfile)
1066+ send_arg ("-f");
1067+
1068+ if (listacl)
1069+ send_arg ("-l");
1070+
1071+ if(tag)
1072+ {
1073+ send_arg ("-r");
1074+ send_arg (tag);
1075+ }
1076+
1077+ send_arg ("--");
1078+
1079+ if (!listacl)
1080+ {
1081+ send_arg (argv[0]);
1082+
1083+ argc--;
1084+ argv++;
1085+ }
1086+
1087+ if (is_racl)
1088+ {
1089+ int i;
1090+ for (i = 0; i < argc; ++i)
1091+ send_arg (argv[i]);
1092+
1093+ send_to_server ("racl\012",0);
1094+ }
1095+ else
1096+ {
1097+ send_files (argc, argv, recursive, 0, SEND_NO_CONTENTS);
1098+ send_file_names (argc, argv, SEND_EXPAND_WILD);
1099+ send_to_server ("acl\012", 0);
1100+ }
1101+
1102+ return get_responses_and_close ();
1103+ }
1104+#endif
1105+
1106+#ifdef SERVER_SUPPORT
1107+
1108+ if (!listacl)
1109+ {
1110+ muser = strtok (argv[0], ":\t");
1111+ mperms = strtok (NULL, ":\t");
1112+
1113+ /* if set to 'default' */
1114+ if ((strlen (mperms) == 7) && (strncmp (mperms, "default", 7) == 0))
1115+ mperms = xstrdup ("x");
1116+
1117+ /* Check that the given permissions are valid. */
1118+ if (!given_perms_valid (mperms))
1119+ error (1,0,"Invalid permissions: '%s'", mperms);
1120+
1121+ argc--;
1122+ argv++;
1123+ }
1124+
1125+
1126+ if (!tag)
1127+ tag = xstrdup ("HEAD");
1128+
1129+ if (!cvs_casecmp (argv[0], "ALL"))
1130+ {
1131+ argv[0] = xstrdup (".");
1132+ defaultperms = 1;
c52fdbcd 1133+ if (!use_separate_acl_file_for_each_dir)
09f63587 1134+ {
1135+ recursive = 0;
1136+ }
1137+
1138+ }
1139+
1140+ if (is_racl)
1141+ {
1142+ DBM *db;
1143+ int i;
1144+ db = open_module ();
1145+ for (i = 0; i < argc; i++)
1146+ {
1147+ err += do_module (db, argv[i], MISC, "ACL ing: ",
1148+ racl_proc, (char *) NULL, 0, !recursive, 0,
1149+ 0, NULL);
1150+ }
1151+ close_module (db);
1152+ }
1153+ else
1154+ {
1155+ err = racl_proc (argc + 1, argv - 1, NULL, NULL, NULL, 0, !recursive, NULL,
1156+ NULL);
1157+ }
1158+ if (err)
1159+ error (1, 0, "an error accured");
1160+
1161+ return (err);
1162+
1163+#endif
1164+}
1165+
1166+static int
1167+racl_proc (argc, argv, xwhere, mwhere, mfile, shorten, local, mname, msg)
1168+int argc;
1169+char **argv;
1170+char *xwhere;
1171+char *mwhere;
1172+char *mfile;
1173+int shorten;
1174+int local;
1175+char *mname;
1176+char *msg;
1177+{
1178+ char *myargv[2];
1179+ int err = 0;
1180+ int which;
1181+ char *repository;
1182+ char *where;
1183+
1184+ if (is_racl)
1185+ {
1186+ repository = xmalloc (strlen (current_parsed_root->directory) + strlen (argv[0])
1187+ + (mfile == NULL ? 0 : strlen (mfile) + 1) + 2);
1188+
1189+ (void) sprintf (repository, "%s/%s", current_parsed_root->directory, argv[0]);
1190+ where = xmalloc (strlen (argv[0]) + (mfile == NULL ? 0 : strlen (mfile) + 1)
1191+ + 1);
1192+ (void) strcpy (where, argv[0]);
1193+
1194+ /* if mfile isn't null, we need to set up to do only part of the module */
1195+ if (mfile != NULL)
1196+ {
1197+ char *cp;
1198+ char *path;
1199+
1200+ /* if the portion of the module is a path, put the dir part on repos */
1201+ if ((cp = strrchr (mfile, '/')) != NULL)
1202+ {
1203+ *cp = '\0';
1204+ (void) strcat (repository, "/");
1205+ (void) strcat (repository, mfile);
1206+ (void) strcat (where, "/");
1207+ (void) strcat (where, mfile);
1208+ mfile = cp + 1;
1209+ }
1210+
1211+ /* take care of the rest */
1212+ path = xmalloc (strlen (repository) + strlen (mfile) + 5);
1213+ (void) sprintf (path, "%s/%s", repository, mfile);
1214+ if (isdir (path))
1215+ {
1216+ /* directory means repository gets the dir tacked on */
1217+ (void) strcpy (repository, path);
1218+ (void) strcat (where, "/");
1219+ (void) strcat (where, mfile);
1220+ }
1221+ else
1222+ {
1223+ myargv[0] = argv[0];
1224+ myargv[1] = mfile;
1225+ argc = 2;
1226+ argv = myargv;
1227+ }
1228+ free (path);
1229+ }
1230+
1231+ /* cd to the starting repository */
1232+ if ( CVS_CHDIR (repository) < 0)
1233+ {
1234+ error (0, errno, "cannot chdir to %s", repository);
1235+ free (repository);
1236+ return (1);
1237+ }
1238+
1239+ /* End section which is identical to patch_proc. */
1240+
1241+ which = W_REPOS | W_ATTIC;
1242+ }
1243+ else
1244+ {
1245+ where = NULL;
1246+ which = W_LOCAL | W_REPOS | W_ATTIC;
1247+ }
1248+ if (listacl)
1249+ err = start_recursion (acllist_fileproc, NULL, acllist_dirproc, NULL, NULL,
1250+ argc - 1, argv + 1, local, which, 0, 0, (char *) where, 1,
1251+ repository);
1252+ else
1253+ err = start_recursion (acl_fileproc, NULL, acl_dirproc, NULL, NULL,
1254+ argc - 1, argv + 1, local, which, 0, 0, (char *) where, 1,
1255+ repository);
1256+
1257+ return (err);
1258+}
1259+
1260+
1261+static int
1262+acl_fileproc (callerdat, finfo)
1263+void *callerdat;
1264+struct file_info *finfo;
1265+{
1266+ Vers_TS *vers;
1267+
1268+ FILE *accessfp;
1269+
1270+ char *filefullname;
1271+
1272+ char *founduserpart = NULL;
1273+ char *newuserpart = NULL;
1274+ char *otheruserparts = NULL;
1275+ size_t otherslen = 0;
1276+
1277+ const char *frepository;
1278+ int foundline = 0;
1279+
1280+ char *line = NULL;
1281+ size_t line_allocated = 0;
1282+ int linelen;
1283+
1284+ char *part_type = NULL;
1285+ char *part_object = NULL;
1286+ char *part_tag = NULL;
1287+ char *part_perms = NULL;
1288+ char *wperms;
1289+ char *userpart;
1290+
1291+ char *errmsg;
1292+
1293+ int pos;
1294+
1295+ if (!aclfile)
1296+ return (0);
1297+
1298+ frepository = Short_Repository (finfo->repository);
1299+
1300+ filefullname = xmalloc (strlen (frepository)
1301+ + strlen (finfo->file)
1302+ + 2);
1303+ strcpy (filefullname, frepository);
1304+ strcat (filefullname, "/");
1305+ strcat (filefullname, finfo->file);
1306+
1307+ if (!access_allowed (finfo->file, finfo->repository, tag, 8, &line, &pos, 0))
1308+ error (1,0,"You do not have acl admin rights on '%s'", frepository);
1309+
1310+ if (line != NULL)
1311+ {
1312+ part_type = strtok (line, ":\t");
1313+ part_object = strtok (NULL, ":\t");
1314+ part_tag = strtok (NULL, ":\t");
1315+ part_perms = strtok (NULL, ":\t");
1316+
1317+ foundline = 1;
1318+ userpart = strtok (part_perms, ",\t");
1319+
1320+ if (strstr (userpart, muser))
1321+ founduserpart = xstrdup (userpart);
1322+ else
1323+ {
1324+ otheruserparts = xstrdup (userpart);
1325+ otherslen = strlen (otheruserparts);
1326+ }
1327+
1328+ while ((userpart = strtok (NULL, ",\t")) != NULL)
1329+ {
1330+ if (strncmp (userpart, muser, strlen (muser)) == 0)
1331+ founduserpart = xstrdup (userpart);
1332+ else
1333+ {
1334+ if (otheruserparts != NULL)
1335+ {
1336+ xrealloc_and_strcat (&otheruserparts, &otherslen, ",");
1337+ xrealloc_and_strcat (&otheruserparts, &otherslen, userpart);
1338+ }
1339+ else
1340+ {
1341+ otheruserparts = xstrdup (userpart);
1342+ otherslen = strlen (otheruserparts);
1343+ }
1344+ }
1345+ }
1346+ }
1347+
1348+ wperms = make_perms (mperms, founduserpart, &errmsg);
1349+ if (wperms == NULL)
1350+ {
1351+ if (errmsg)
1352+ error (0, 0, "%s %s", filefullname, errmsg);
1353+
1354+ return (0);
1355+ }
1356+ else
1357+ {
1358+ cvs_output ("X ", 0);
1359+ cvs_output (filefullname, 0);
1360+ cvs_output ("\n", 0);
1361+
1362+ write_perms (muser, wperms, founduserpart, foundline,
1363+ otheruserparts, "f", filefullname, tag, pos, finfo->repository);
1364+ }
1365+
1366+ return (0);
1367+}
1368+
1369+static Dtype
1370+acl_dirproc (callerdat, dir, repos, update_dir, entries)
1371+void *callerdat;
1372+const char *dir;
1373+const char *repos;
1374+const char *update_dir;
1375+List *entries;
1376+{
1377+ const char *drepository;
1378+ char *founduserpart = NULL;
1379+ char *newuserpart = NULL;
1380+ char *otheruserparts = NULL;
1381+ size_t otherslen = 0;
1382+ int foundline = 0;
1383+
1384+ char *line = NULL;
1385+ size_t line_allocated = 0;
1386+ int linelen;
1387+
1388+ FILE *accessfp;
1389+ char *part_type = NULL;
1390+ char *part_object = NULL;
1391+ char *part_tag = NULL;
1392+ char *part_perms = NULL;
1393+ char *wperms;
1394+ int i = 0;
1395+ char *userpart;
1396+ int pos;
1397+
1398+ char *errmsg;
1399+
1400+ if (repos[0] == '\0')
1401+ repos = Name_Repository (dir, NULL);
1402+
1403+ if (!acldir)
1404+ return (0);
1405+
1406+ if (!access_allowed (NULL, repos, tag, 8, &line, &pos, 0))
1407+ error (1,0,"You do not have admin rights on '%s'", Short_Repository (repos));
1408+
1409+ drepository = Short_Repository (repos);
1410+
1411+ if (line != NULL)
1412+ {
1413+ part_type = strtok (line, ":\t");
1414+ part_object = strtok (NULL, ":\t");
1415+ part_tag = strtok (NULL, ":\t");
1416+ part_perms = strtok (NULL, ":\t");
1417+
1418+ foundline = 1;
1419+ userpart = strtok (part_perms, ",\t");
1420+
1421+ if (strstr (userpart, muser))
1422+ founduserpart = xstrdup (userpart);
1423+ else
1424+ {
1425+ otheruserparts = xstrdup (userpart);
1426+ otherslen = strlen (otheruserparts);
1427+ }
1428+
1429+ while ((userpart = strtok (NULL, ",\t")) != NULL)
1430+ {
1431+ if (strncmp (userpart, muser, strlen (muser)) == 0)
1432+ founduserpart = xstrdup (userpart);
1433+ else
1434+ {
1435+ if (otheruserparts != NULL)
1436+ {
1437+ xrealloc_and_strcat (&otheruserparts, &otherslen, ",");
1438+ xrealloc_and_strcat (&otheruserparts, &otherslen, userpart);
1439+ }
1440+ else
1441+ {
1442+ otheruserparts = xstrdup (userpart);
1443+ otherslen = strlen (otheruserparts);
1444+ }
1445+ }
1446+ }
1447+ }
1448+
1449+ wperms = make_perms (mperms, founduserpart, &errmsg);
1450+ if (wperms == NULL)
1451+ {
1452+ if (errmsg)
1453+ error (0, 0, "%s %s", drepository, errmsg);
1454+
1455+ return (0);
1456+ }
1457+ else
1458+ {
1459+ if (defaultperms)
1460+ {
1461+ cvs_output ("X ", 0);
1462+ cvs_output ("ALL", 0);
1463+ cvs_output ("\n", 0);
1464+ write_perms (muser, wperms, founduserpart, foundline,
67ba4c3a 1465+ otheruserparts, "d", "ALL", tag, pos, drepository);//baris
09f63587 1466+
1467+ }
1468+ else
1469+ {
1470+ cvs_output ("X ", 0);
1471+ cvs_output (drepository, 0);
1472+ cvs_output ("\n", 0);
1473+ write_perms (muser, wperms, founduserpart, foundline,
67ba4c3a 1474+ otheruserparts, "d", drepository, tag, pos, drepository);//baris `repos`
09f63587 1475+ }
1476+ }
1477+
1478+ return (0);
1479+}
1480+
1481+/* Open CVSROOT/access or defined CVSACLFileLocation file. */
1482+FILE *
1483+open_accessfile (fmode, adir, fname)
1484+char *fmode;
67ba4c3a 1485+const char *adir;
09f63587 1486+char **fname;
1487+{
1488+ char *accessfile;
1489+ FILE *accessfp;
1490+
c52fdbcd 1491+ if (!use_separate_acl_file_for_each_dir)
09f63587 1492+ {
1493+ if (cvs_acl_file_location == NULL)
1494+ {
1495+ accessfile = xmalloc (strlen (current_parsed_root->directory)
1496+ + sizeof (CVSROOTADM)
1497+ + sizeof (CVSROOTADM_ACCESS)
1498+ + 3);
1499+
1500+ strcpy (accessfile, current_parsed_root->directory);
1501+ strcat (accessfile, "/");
1502+ strcat (accessfile, CVSROOTADM);
1503+ strcat (accessfile, "/");
1504+ strcat (accessfile, CVSROOTADM_ACCESS);
1505+ }
1506+ else
1507+ {
1508+ accessfile = xmalloc (strlen (cvs_acl_file_location));
1509+ strcpy (accessfile, cvs_acl_file_location);
1510+ }
1511+ }
1512+ else
1513+ {
1514+ accessfile = xmalloc (strlen (current_parsed_root->directory)
1515+ + strlen (adir)
1516+ + strlen ("access")
1517+ + 3);
1518+
1519+ strcpy (accessfile, current_parsed_root->directory);
1520+ strcat (accessfile, "/");
1521+ strcat (accessfile, adir);
1522+ strcat (accessfile, "/");
1523+ strcat (accessfile, "access");
1524+ }
1525+
1526+ accessfp = CVS_FOPEN (accessfile, fmode);
1527+
1528+ if (accessfp == NULL)
1529+ error (0, 0, "cannot open file: %s", accessfile);
1530+
1531+ if (fname != NULL)
1532+ *fname = xstrdup (accessfile);
1533+
1534+ free (accessfile);
1535+
1536+ return (accessfp);
1537+}
1538+
1539+/* Open /etc/group file if UseSystemGroups=yes in config file. */
1540+/* Open CVSROOT/group file if UseCVSGroups=yes in config file. */
1541+FILE *
1542+open_groupfile (fmode)
1543+char *fmode;
1544+{
1545+ char *groupfile;
1546+ FILE *groupfp;
1547+
1548+ if (use_cvs_groups)
1549+ {
1550+ if (cvs_groups_file_location != NULL)
1551+ {
1552+ groupfile = xmalloc (strlen (cvs_groups_file_location));
1553+ strcpy (groupfile, cvs_groups_file_location);
1554+ }
1555+ else
1556+ {
1557+ groupfile = xmalloc (strlen (current_parsed_root->directory)
1558+ + sizeof (CVSROOTADM)
1559+ + sizeof (CVSROOTADM_GROUP)
1560+ + 3);
1561+
1562+ strcpy (groupfile, current_parsed_root->directory);
1563+ strcat (groupfile, "/");
1564+ strcat (groupfile, CVSROOTADM);
1565+ strcat (groupfile, "/");
1566+ strcat (groupfile, CVSROOTADM_GROUP);
1567+ }
1568+ }
1569+
1570+ else
1571+ {
1572+ return (NULL);
1573+ }
1574+
1575+ groupfp = CVS_FOPEN (groupfile, "r");
1576+
1577+ if (groupfp == NULL)
1578+ error (0, 0, "cannot open file: %s", groupfile);
1579+
1580+ free (groupfile);
1581+
1582+ return (groupfp);
1583+}
1584+
1585+
1586+/* Check whether given permissions are valid or not. */
1587+/* Returns 1 if permissions are valid. */
1588+/* Returns 0 if permissions are NOT valid. */
1589+int
1590+given_perms_valid (cperms)
1591+char *cperms;
1592+{
1593+ int cperms_len;
1594+ int retval;
1595+ int index, i;
1596+
1597+ if (cperms[0] == '+' || cperms[0] == '-')
1598+ index = 1;
1599+ else
1600+ index = 0;
1601+
1602+ cperms_len = strlen (cperms);
1603+
1604+ switch (cperms[index])
1605+ {
1606+ case 'x':
1607+ if ((cperms_len - index) == 1 && cperms_len == 1)
1608+ retval = 1;
1609+ else
1610+ retval = 0;
1611+ break;
1612+ case 'n':
1613+ if ((cperms_len - index) == 1 && cperms_len == 1)
1614+ retval = 1;
1615+ else
1616+ retval = 0;
1617+ break;
1618+ case 'p':
1619+ if ((cperms_len - index) == 1)
1620+ retval = 1;
1621+ else
1622+ retval = 0;
1623+ break;
1624+ case 'a':
1625+ if ((cperms_len - index) == 1)
1626+ retval = 1;
1627+ else
1628+ for (i = index + 1; i < cperms_len; i++)
1629+ if (cperms[i] == 'p')
1630+ retval = 1;
1631+ else
1632+ retval = 0;
1633+ break;
1634+ case 'r':
1635+ if ((cperms_len - index) == 1)
1636+ retval = 1;
1637+ else
1638+ for (i = index + 1; i < cperms_len; i++)
1639+ if (cperms[i] == 't' || cperms[i] == 'c' || cperms[i] == 'd')
1640+ retval = 1;
1641+ else
1642+ retval = 0;
1643+ break;
1644+ case 'w':
1645+ if ((cperms_len - index) == 1)
1646+ retval = 1;
1647+ else
1648+ for (i = index + 1; i < cperms_len; i++)
1649+ if (cperms[i] == 't' || cperms[i] == 'c' || cperms[i] == 'd')
1650+ retval = 1;
1651+ else
1652+ retval = 0;
1653+ break;
1654+ case 't':
1655+ if ((cperms_len - index) == 1)
1656+ retval = 1;
1657+ else
1658+ for (i = index + 1; i < cperms_len; i++)
1659+ if (cperms[i] == 'w' || cperms[i] == 'c' || cperms[i] == 'd')
1660+ retval = 1;
1661+ else
1662+ retval = 0;
1663+ break;
1664+ case 'c':
1665+ if ((cperms_len - index) == 1)
1666+ retval = 1;
1667+ else
1668+ for (i = index + 1; i < cperms_len; i++)
1669+ if (cperms[i] == 't' || cperms[i] == 'w' || cperms[i] == 'd')
1670+ retval = 1;
1671+ else
1672+ retval = 0;
1673+ break;
1674+ case 'd':
1675+ if ((cperms_len - index) == 1)
1676+ retval = 1;
1677+ else
1678+ for (i = index + 1; i < cperms_len; i++)
1679+ if (cperms[i] == 't' || cperms[i] == 'c' || cperms[i] == 'w')
1680+ retval = 1;
1681+ else
1682+ retval = 0;
1683+ break;
1684+ default:
1685+ retval = 0;
1686+ break;
1687+ }
1688+ return (retval);
1689+}
1690+
1691+char *
1692+make_perms (perms, founduserpart, xerrmsg)
1693+char *perms;
1694+char *founduserpart;
1695+char **xerrmsg;
1696+{
1697+ char *fperms;
1698+ size_t perms_len;
1699+ size_t fperms_len;
1700+ char *retperms = NULL;
1701+ char *xperms;
1702+ int i, j;
1703+ int err = 0;
1704+ char *errmsg = NULL;
1705+ size_t retperms_len = 1;
1706+
1707+ retperms = xmalloc (retperms_len);
1708+ retperms[0] = '\0';
1709+
1710+ perms_len = strlen (perms);
1711+
1712+ if (perms[0] == '+' || perms[0] == '-')
1713+ {
1714+ if (founduserpart)
1715+ {
1716+ char *temp;
1717+ temp = strtok (founduserpart, "!\t");
1718+ fperms = strtok (NULL, "!\t");
1719+ fperms_len = strlen (fperms);
1720+
1721+ if (strncmp (fperms, "x", 1) == 0)
1722+ {
1723+ err = 1;
1724+ if (perms[0] == '+')
1725+ *xerrmsg = xstrdup ("cannot add default permission 'x'");
1726+ else
1727+ *xerrmsg = xstrdup ("cannot remove default permission 'x'");
1728+ }
1729+
1730+ for (i = 1; i < perms_len && !err; i++)
1731+ {
1732+ switch (perms[i])
1733+ {
1734+ case 'n':
1735+ err = 1;
1736+ break;
1737+ case 'p':
1738+ if (perms[0] == '+')
1739+ fperms = xstrdup ("p");
1740+ else if (perms[0] == '-')
1741+ {
1742+ fperms_len = 1;
1743+ fperms = xmalloc (fperms_len);
1744+ fperms[0] = '\0';
1745+ }
1746+ break;
1747+ case 'a':
1748+ for (j = 0; j < fperms_len; j++)
1749+ {
1750+ if (fperms[j] == 'p')
1751+ {
1752+ err = 1;
1753+ *xerrmsg = xstrdup ("user has admin rights, cannot use +/- permissions");
1754+ }
1755+ else if (fperms[j] == 'a' && perms[0] == '+')
1756+ {
1757+ err = 1;
1758+ *xerrmsg = xstrdup ("user already has all ('a') permission");
1759+ }
1760+ else if (fperms[j] != 'a' && perms[0] == '-')
1761+ {
1762+ err = 1;
1763+ *xerrmsg = xstrdup ("user does not have all ('a') permission");
1764+ }
1765+ }
1766+ if (perms[0] == '+')
1767+ {
1768+ fperms = xstrdup ("a");
1769+ fperms_len = strlen (fperms);
1770+ }
1771+ else if (perms[0] == '-')
1772+ {
1773+ fperms_len = 1;
1774+ fperms = xmalloc (fperms_len);
1775+ fperms[0] = '\0';
1776+ }
1777+
1778+ break;
1779+ case 'r':
1780+ for (i = 0; i < fperms_len; i++)
1781+ {
1782+ if (fperms[i] == 'n' && perms[0] == '+')
1783+ {
1784+ fperms = xstrdup ("r");
1785+ fperms_len = strlen (fperms);
1786+ }
1787+ else if (fperms[i] == 'r' && perms[0] == '-')
1788+ {
1789+ fperms_len = 1;
1790+ fperms = xmalloc (fperms_len);
1791+ fperms[0] = '\0';
1792+ }
1793+ else if (perms[0] == '-')
1794+ {
1795+ err = 1;
1796+ *xerrmsg = xstrdup ("user has other permissions, cannot remove read ('r') permission");
1797+ }
1798+ else
1799+ {
1800+ err = 1;
1801+ *xerrmsg = xstrdup ("user has other permissions, cannot remove read ('r') permission");
1802+ }
1803+ }
1804+ break;
1805+ case 'w':
1806+ {
1807+ char *tempfperms;
1808+ size_t tempfperms_len = 1;
1809+
1810+ tempfperms = xmalloc (tempfperms_len);
1811+ tempfperms[0] = '\0';
1812+
1813+ for (j = 0; j < fperms_len; j++)
1814+ {
1815+ if (fperms[j] == 't' || fperms[j] == 'c' || fperms[j] == 'd')
1816+ {
1817+ char *temp;
1818+ temp = xmalloc (2);
1819+ temp[0] = fperms[j];
1820+ temp[1] = '\0';
1821+
1822+ xrealloc_and_strcat (&tempfperms, &tempfperms_len, temp);
1823+ free (temp);
1824+ }
1825+ else if (fperms[j] == 'a' || fperms[j] == 'p')
1826+ {
1827+ err = 1;
1828+ *xerrmsg = xstrdup ("user has higher permissions, cannot use +/- write permissions");
1829+ }
1830+ else if (fperms[j] == 'n' || fperms[j] == 'r')
1831+ {
1832+ if (perms[0] == '-')
1833+ {
1834+ err = 1;
1835+ *xerrmsg = xstrdup ("user does not have write ('w') permission");
1836+ }
1837+ }
1838+ }
1839+
1840+ fperms = xstrdup (tempfperms);
1841+ fperms_len = strlen (fperms);
1842+ free (tempfperms);
1843+
1844+ if (perms[0] == '+')
1845+ {
1846+ xrealloc_and_strcat (&fperms, &fperms_len, "w");
1847+ }
1848+ }
1849+ break;
1850+ case 't':
1851+ {
1852+ char *tempfperms;
1853+ size_t tempfperms_len = 1;
1854+
1855+ tempfperms = xmalloc (tempfperms_len);
1856+ tempfperms[0] = '\0';
1857+
1858+ for (j = 0; j < fperms_len; j++)
1859+ {
1860+ if (fperms[j] == 'w' || fperms[j] == 'c' || fperms[j] == 'd')
1861+ {
1862+ char *temp;
1863+ temp = xmalloc (2);
1864+ temp[0] = fperms[j];
1865+ temp[1] = '\0';
1866+
1867+ xrealloc_and_strcat (&tempfperms, &tempfperms_len, temp);
1868+ free (temp);
1869+ }
1870+ else if (fperms[j] == 'a' || fperms[j] == 'p')
1871+ {
1872+ err = 1;
1873+ *xerrmsg = xstrdup ("user has higher permissions, cannot use +/- tag permissions");
1874+ }
1875+ else if (fperms[i] == 'n' || fperms[i] == 'r')
1876+ {
1877+ if (perms[0] == '-')
1878+ *xerrmsg = xstrdup ("user does not have tag ('t') permission");
1879+ }
1880+ }
1881+
1882+ fperms = xstrdup (tempfperms);
1883+ fperms_len = strlen (fperms);
1884+ free (tempfperms);
1885+
1886+ if (perms[0] == '+')
1887+ {
1888+ xrealloc_and_strcat (&fperms, &fperms_len, "t");
1889+ }
1890+ }
1891+ break;
1892+ case 'c':
1893+ {
1894+ char *tempfperms;
1895+ size_t tempfperms_len = 1;
1896+
1897+ tempfperms = xmalloc (tempfperms_len);
1898+ tempfperms[0] = '\0';
1899+
1900+ for (j = 0; j < fperms_len; j++)
1901+ {
1902+ if (fperms[j] == 'w' || fperms[j] == 't' || fperms[j] == 'd')
1903+ {
1904+ char *temp;
1905+ temp = xmalloc (2);
1906+ temp[0] = fperms[j];
1907+ temp[1] = '\0';
1908+
1909+ xrealloc_and_strcat (&tempfperms, &tempfperms_len, temp);
1910+ free (temp);
1911+ }
1912+ else if (fperms[j] == 'a' || fperms[j] == 'p')
1913+ {
1914+ err = 1;
1915+ *xerrmsg = xstrdup ("user has higher permissions, cannot use +/- create permissions");
1916+ }
1917+ else if (fperms[i] == 'n' || fperms[i] == 'r')
1918+ {
1919+ if (perms[0] == '-')
1920+ err = 1;
1921+ *xerrmsg = xstrdup ("user does not have create ('c') permission");
1922+ }
1923+
1924+ }
1925+
1926+ fperms = xstrdup (tempfperms);
1927+ fperms_len = strlen (fperms);
1928+ free (tempfperms);
1929+
1930+ if (perms[0] == '+')
1931+ {
1932+ xrealloc_and_strcat (&fperms, &fperms_len, "c");
1933+ }
1934+ }
1935+ break;
1936+ case 'd':
1937+ {
1938+ char *tempfperms;
1939+ size_t tempfperms_len = 1;
1940+
1941+ tempfperms = xmalloc (tempfperms_len);
1942+ tempfperms[0] = '\0';
1943+
1944+ for (j = 0; j < fperms_len; j++)
1945+ {
1946+ if (fperms[j] == 'w' || fperms[j] == 'c' || fperms[j] == 't')
1947+ {
1948+ char *temp;
1949+ temp = xmalloc (2);
1950+ temp[0] = fperms[j];
1951+ temp[1] = '\0';
1952+
1953+ xrealloc_and_strcat (&tempfperms, &tempfperms_len, temp);
1954+ free (temp);
1955+ }
1956+ else if (fperms[j] == 'a' || fperms[j] == 'p')
1957+ {
1958+ err = 1;
1959+ *xerrmsg = xstrdup ("user has higher permissions, cannot use +/- delete permissions");
1960+ }
1961+ else if (fperms[i] == 'n' || fperms[i] == 'r')
1962+ {
1963+ if (perms[0] == '-')
1964+ err = 1;
1965+ *xerrmsg = xstrdup ("user does not have delete ('d') permission");
1966+ }
1967+ }
1968+
1969+ fperms = xstrdup (tempfperms);
1970+ fperms_len = strlen (fperms);
1971+ free (tempfperms);
1972+
1973+ if (perms[0] == '+')
1974+ {
1975+ xrealloc_and_strcat (&fperms, &fperms_len, "d");
1976+ }
1977+ }
1978+ break;
1979+ default:
1980+ err = 1;
1981+ *xerrmsg = xstrdup ("error in 'access' file format");
1982+ break;
1983+ }
1984+ if (fperms[0] == '\0')
1985+ retperms = xstrdup ("none");
1986+ else
1987+ retperms = xstrdup (fperms);
1988+ }
1989+ }
1990+ else
1991+ {
1992+ err = 1;
1993+ *xerrmsg = xstrdup("user is not given any permissions to remove/add");
1994+ }
1995+ }
1996+
1997+ else
1998+ {
1999+ retperms = xstrdup (perms);
2000+ }
2001+
2002+ if (err)
2003+ return (NULL);
2004+ else
2005+ return (retperms);
2006+}
2007+
2008+int
2009+write_perms (user, perms, founduserpart, foundline, otheruserparts,
2010+ part_type, part_object, part_tag, pos, arepos)
2011+char *user;
2012+char *perms;
2013+char *founduserpart;
2014+int foundline;
2015+char *otheruserparts;
2016+char *part_type;
2017+char *part_object;
2018+char *part_tag;
2019+int pos;
2020+char *arepos;
2021+{
09f63587 2022+ char *accessfile;
2023+ char *tmpaccessout;
2024+ FILE *accessfpin;
2025+ FILE *accessfpout;
2026+
2027+ char *newline = NULL;
2028+ size_t newlinelen = 1;
2029+
2030+ char *line = NULL;
2031+ size_t line_allocated = 0;
2032+
2033+ newline = xmalloc (newlinelen);
2034+ newline[0] = '\0';
2035+
2036+ if (!cvs_casecmp (part_tag, "ALL"))
2037+ part_tag = xstrdup ("ALL");
2038+
2039+ xrealloc_and_strcat (&newline, &newlinelen, part_type);
2040+ xrealloc_and_strcat (&newline, &newlinelen, ":");
2041+ xrealloc_and_strcat (&newline, &newlinelen, part_object);
2042+ xrealloc_and_strcat (&newline, &newlinelen, ":");
2043+ xrealloc_and_strcat (&newline, &newlinelen, part_tag);
2044+ xrealloc_and_strcat (&newline, &newlinelen, ":");
2045+
2046+ if (strncmp (perms, "none", 4) != 0)
2047+ {
2048+ xrealloc_and_strcat (&newline, &newlinelen, user);
2049+ xrealloc_and_strcat (&newline, &newlinelen, "!");
2050+ xrealloc_and_strcat (&newline, &newlinelen, perms);
2051+ if (otheruserparts != NULL)
2052+ xrealloc_and_strcat (&newline, &newlinelen, ",");
2053+ }
2054+
2055+ if (otheruserparts != NULL)
2056+ {
2057+ if (otheruserparts[strlen (otheruserparts) - 1] == '\n')
2058+ otheruserparts[strlen (otheruserparts) - 1] = '\0';
2059+
2060+ xrealloc_and_strcat (&newline, &newlinelen, otheruserparts);
2061+ }
2062+
2063+ xrealloc_and_strcat (&newline, &newlinelen, ":");
2064+
2065+ if (foundline)
2066+ {
2067+ accessfpout = cvs_temp_file (&tmpaccessout);
2068+ accessfpin = open_accessfile ("r", arepos, &accessfile);
2069+
2070+ while (getline (&line, &line_allocated, accessfpin) >= 0)
2071+ {
2072+ if (pos != ftell (accessfpin))
2073+ {
2074+ if (fprintf (accessfpout, line) < 0)
2075+ error (1, errno, "writing temporary file: %s", tmpaccessout);
2076+ }
2077+ else
2078+ {
2079+ if (fprintf (accessfpout, "%s\n", newline) < 0)
2080+ error (1, errno, "writing temporary file: %s", tmpaccessout);
2081+ }
2082+
2083+ }
2084+ if (fclose (accessfpin) == EOF)
2085+ error (1, errno, "cannot close access file: %s", accessfile);
2086+
2087+ if (fclose (accessfpout) == EOF)
2088+ error (1, errno, "cannot close temporary file: %s", tmpaccessout);
2089+
2090+ if (CVS_UNLINK (accessfile) < 0)
2091+ error (0, errno, "cannot remove %s", accessfile);
2092+
2093+ copy_file (tmpaccessout, accessfile);
2094+
2095+ if (CVS_UNLINK (tmpaccessout) < 0)
2096+ error (0, errno, "cannot remove temporary file: %s", tmpaccessout);
2097+ }
2098+ else
2099+ {
2100+ accessfpout = open_accessfile ("r+", arepos, &accessfile);
2101+
2102+ if (accessfpout == NULL)
2103+ {
2104+ if (existence_error (errno))
2105+ {
2106+ accessfpout = open_accessfile ("w+", arepos, &accessfile);
2107+ }
2108+ }
67ba4c3a 2109+ else {
2110+ if (fseek (accessfpout, 0, 2) != 0)
2111+ error (1, errno, "cannot fseek access file: %s", accessfile);
2112+ }
09f63587 2113+
2114+ if (fprintf (accessfpout, "%s\n", newline) < 0)
2115+ error (1, errno, "writing access file: %s", accessfile);
2116+
2117+ if (fclose (accessfpout) == EOF)
2118+ error (1, errno, "cannot close access file: %s", accessfile);
2119+ }
2120+
2121+ free (newline);
2122+
2123+ chmod(accessfile, 0644);
2124+
2125+ return (0);
2126+}
2127+
2128+
2129+static int
2130+acllist_fileproc (callerdat, finfo)
2131+void *callerdat;
2132+struct file_info *finfo;
2133+{
2134+
2135+ char *filefullname;
2136+ const char *frepository;
2137+ char *line = NULL;
2138+ int pos;
2139+
2140+ if (!aclfile)
2141+ return (0);
2142+
2143+ frepository = Short_Repository (finfo->repository);
2144+
2145+ filefullname = xmalloc (strlen (frepository)
2146+ + strlen (finfo->file)
2147+ + 2);
2148+ strcpy (filefullname, frepository);
2149+ strcat (filefullname, "/");
2150+ strcat (filefullname, finfo->file);
2151+
2152+ if (!access_allowed (finfo->file, finfo->repository, tag, 5, &line, &pos, 0))
2153+ error (1,0,"You do not have admin rights on '%s'", frepository);
2154+
09f63587 2155+ acllist_print (line, filefullname);
2156+
2157+ return (0);
2158+}
2159+
2160+static Dtype
2161+acllist_dirproc (callerdat, dir, repos, update_dir, entries)
2162+void *callerdat;
2163+const char *dir;
2164+const char *repos;
2165+const char *update_dir;
2166+List *entries;
2167+{
2168+
2169+ char *line = NULL;
2170+ const char *drepository;
2171+ int pos;
2172+
2173+ if (repos[0] == '\0')
2174+ repos = Name_Repository (dir, NULL);
2175+
2176+ if (!acldir)
2177+ return (0);
2178+
2179+ drepository = Short_Repository (repos);
2180+
2181+ if (!access_allowed (NULL, repos, tag, 5, &line, &pos, 0))
2182+ error (1, 0, "You do not have admin rights on '%s'", drepository);
2183+
2184+ acllist_print (line, drepository);
2185+
2186+ return (0);
2187+}
2188+
2189+
2190+void
2191+acllist_print (line, obj)
2192+char *line;
2193+const char *obj;
2194+{
2195+ char *temp;
2196+ char *temp2;
2197+ int x;
2198+ int c = 0;
2199+
2200+ char *printedusers[255];
2201+ printedusers[0] = NULL;
2202+
2203+ if (line != NULL)
2204+ {
2205+ temp = strtok (line, ":\t");
2206+
2207+ if (acldir)
2208+ cvs_output ("d ", 0);
2209+ else if (aclfile)
2210+ cvs_output ("f ", 0);
2211+
2212+ temp = strtok (NULL, ":\t");
2213+
2214+ cvs_output(obj, 0);
2215+ cvs_output (" | ", 0);
2216+
2217+ temp = strtok (NULL, ":\t");
2218+ cvs_output (temp, 0);
2219+ cvs_output (" | ", 0);
2220+
2221+ while ((temp = strtok (NULL, "!\t")) != NULL)
2222+ {
2223+ if (strncmp (temp, ":", 1) == 0)
2224+ break;
2225+
2226+ if (strcmp (temp, "ALL") == 0)
2227+ {
2228+ temp = strtok (NULL, ",\t");
2229+ continue;
2230+ }
2231+
2232+ cvs_output (temp, 0);
2233+ cvs_output (":", 0);
2234+
2235+ while (printedusers[c] != NULL)
2236+ c++;
2237+
2238+ printedusers[c] = xstrdup (temp);
2239+ c++;
2240+ printedusers[c] = NULL;
2241+
2242+ temp = strtok (NULL, ",\t");
2243+
2244+ if (temp != NULL && temp[strlen (temp) - 2] == ':')
2245+ temp[strlen (temp) - 2] = '\0';
2246+
2247+ cvs_output (temp, 0);
2248+ cvs_output (" ", 0);
2249+ }
2250+
2251+ if (default_perms_object)
2252+ {
2253+ cvs_output ("| defaults ", 0);
2254+ cvs_output ("ALL:", 0);
2255+ cvs_output (default_perms_object, 0);
2256+ }
2257+ else if (default_part_perms_accessfile)
2258+ {
2259+ size_t i;
2260+ i = strlen (default_part_perms_accessfile);
2261+ xrealloc_and_strcat (&default_part_perms_accessfile, &i, ",");
2262+
2263+ free(line);
2264+ line = xstrdup(default_part_perms_accessfile);
2265+
2266+ cvs_output ("| defaults ", 0);
2267+
2268+ temp = strtok (line, "!\t");
2269+ cvs_output (temp, 0);
2270+ cvs_output (":", 0);
2271+
2272+ temp = strtok (NULL, ",\t");
2273+
2274+ cvs_output (temp, 0);
2275+ cvs_output (" ", 0);
2276+
2277+ while ((temp = strtok (NULL, "!\t")) != NULL)
2278+ {
2279+ int printed = 0;
2280+ int c2 = 0;
2281+ while (printedusers[c2] != NULL && printed == 0)
2282+ {
2283+ if (strcmp (printedusers[c2], temp) == 0)
2284+ {
2285+ printed = 1;
2286+ break;
2287+ }
2288+ c2++;
2289+ }
2290+
2291+ if (printed == 0)
2292+ {
2293+ cvs_output (temp, 0);
2294+ cvs_output (":", 0);
2295+ }
2296+
2297+ temp = strtok (NULL, ",\t");
2298+
2299+ if (temp[strlen (temp) - 2] == ':')
2300+ temp[strlen (temp) - 2] = '\0';
2301+
2302+ if (printed == 0)
2303+ {
2304+ cvs_output (temp, 0);
2305+ cvs_output (" ", 0);
2306+ }
2307+ }
2308+ }
2309+ else if (cvs_acl_default_permissions)
2310+ {
2311+ cvs_output ("| defaults ", 0);
2312+ cvs_output ("ALL: ", 0);
2313+ cvs_output (cvs_acl_default_permissions, 0);
2314+ }
2315+
2316+ cvs_output ("\n", 0);
2317+
2318+ }
2319+ else
2320+ {
2321+ if (acldir)
2322+ cvs_output ("d ", 0);
2323+ else if (aclfile)
2324+ cvs_output ("f ", 0);
2325+ cvs_output (obj, 0);
2326+ cvs_output (" | ", 0);
2327+ cvs_output (tag, 0);
2328+ cvs_output (" | ", 0);
2329+
2330+ if (default_perms_object)
2331+ {
2332+ cvs_output ("| defaults ", 0);
2333+ cvs_output ("ALL:", 0);
2334+ cvs_output (default_perms_object, 0);
2335+ cvs_output ("\n", 0);
2336+ }
2337+ else if (default_part_perms_accessfile)
2338+ {
2339+ free(line);
2340+ line = xstrdup(default_part_perms_accessfile);
2341+
2342+ cvs_output ("| defaults ", 0);
2343+
2344+ temp = strtok (line, "!\t");
2345+ cvs_output (temp, 0);
2346+ cvs_output (":", 0);
2347+
2348+ temp = strtok (NULL, ",\t");
2349+
2350+ if (temp[strlen (temp) - 2] == ':')
2351+ temp[strlen (temp) - 2] = '\0';
2352+
2353+ cvs_output (temp, 0);
2354+ cvs_output (" ", 0);
2355+
2356+ while ((temp = strtok (NULL, "!\t")) != NULL)
2357+ {
2358+ cvs_output (temp, 0);
2359+ cvs_output (":", 0);
2360+
2361+ temp = strtok (NULL, ",\t");
2362+
2363+ if (temp[strlen (temp) - 2] == ':')
2364+ temp[strlen (temp) - 2] = '\0';
2365+
2366+ cvs_output (temp, 0);
2367+ cvs_output (" ", 0);
2368+ }
2369+ cvs_output ("\n", 0);
2370+ }
2371+ else if (cvs_acl_default_permissions)
2372+ {
2373+ cvs_output ("| defaults ", 0);
2374+ cvs_output ("ALL: ", 0);
2375+ cvs_output (cvs_acl_default_permissions, 0);
2376+ cvs_output ("\n", 0);
2377+ }
2378+ else
2379+ cvs_output ("default:p (no perms)\n", 0);
2380+ }
2381+
2382+}
c52fdbcd 2383diff -urN cvs-1.11.17.orig/src/add.c cvs-1.11.17/src/add.c
2384--- cvs-1.11.17.orig/src/add.c 2004-05-10 16:35:54.000000000 +0200
67ba4c3a 2385+++ cvs-1.11.17/src/add.c 2004-08-04 10:40:18.602728608 +0200
c52fdbcd 2386@@ -400,6 +400,24 @@
09f63587 2387 }
2388 else
2389 {
2390+/* cvsacl patch */
2391+#ifdef SERVER_SUPPORT
2392+ if (use_cvs_acl && server_active)
2393+ {
2394+ if (!access_allowed (finfo.file, repository, vers->tag, 6,
2395+ NULL, NULL, 1))
2396+ {
2397+ if (stop_at_first_permission_denied)
2398+ error (1, 0, "permission denied for %s",
2399+ Short_Repository (finfo.repository));
2400+ else
2401+ error (0, 0, "permission denied for %s/%s",
2402+ Short_Repository (finfo.repository), finfo.file);
2403+
2404+ return (0);
2405+ }
2406+ }
2407+#endif
2408 /* There is a user file, so build the entry for it */
2409 if (build_entry (repository, finfo.file, vers->options,
2410 message, entries, vers->tag) != 0)
c52fdbcd 2411@@ -656,6 +674,26 @@
09f63587 2412 && isdir (finfo.file)
2413 && !wrap_name_has (finfo.file, WRAP_TOCVS))
2414 {
2415+
2416+/* cvsacl patch */
2417+#ifdef SERVER_SUPPORT
2418+ if (use_cvs_acl && server_active)
2419+ {
2420+ if (!access_allowed (NULL, repository, NULL, 6,
2421+ NULL, NULL, 1))
2422+ {
2423+ if (stop_at_first_permission_denied)
2424+ error (1, 0, "permission denied for %s",
2425+ Short_Repository (finfo.repository));
2426+ else
2427+ error (0, 0, "permission denied for %s/%s",
2428+ Short_Repository (finfo.repository), finfo.file);
2429+
2430+ return (0);
2431+ }
2432+ }
2433+#endif
2434+
2435 err += add_directory (&finfo);
2436 }
2437 else
c52fdbcd 2438diff -urN cvs-1.11.17.orig/src/annotate.c cvs-1.11.17/src/annotate.c
2439--- cvs-1.11.17.orig/src/annotate.c 2004-03-22 16:44:27.000000000 +0100
67ba4c3a 2440+++ cvs-1.11.17/src/annotate.c 2004-08-04 10:40:18.603728456 +0200
09f63587 2441@@ -276,6 +276,25 @@
2442 if (version == NULL)
2443 return 0;
2444
2445+/* cvsacl patch */
2446+#ifdef SERVER_SUPPORT
2447+ if (use_cvs_acl && server_active)
2448+ {
2449+ if (!access_allowed (finfo->file, finfo->repository, version, 5,
2450+ NULL, NULL, 1))
2451+ {
2452+ if (stop_at_first_permission_denied)
2453+ error (1, 0, "permission denied for %s",
2454+ Short_Repository (finfo->repository));
2455+ else
2456+ error (0, 0, "permission denied for %s/%s",
2457+ Short_Repository (finfo->repository), finfo->file);
2458+
2459+ return (0);
2460+ }
2461+ }
2462+#endif
2463+
2464 /* Distinguish output for various files if we are processing
2465 several files. */
2466 cvs_outerr ("\nAnnotations for ", 0);
c52fdbcd 2467diff -urN cvs-1.11.17.orig/src/commit.c cvs-1.11.17/src/commit.c
2468--- cvs-1.11.17.orig/src/commit.c 2004-06-09 16:34:54.000000000 +0200
67ba4c3a 2469+++ cvs-1.11.17/src/commit.c 2004-08-04 10:40:18.606728000 +0200
c52fdbcd 2470@@ -1299,6 +1299,34 @@
2471 return 0;
09f63587 2472
2473 ci = p->data;
2474+
2475+/* cvsacl patch */
2476+#ifdef SERVER_SUPPORT
2477+ if (use_cvs_acl && server_active)
2478+ {
2479+ int whichperm;
2480+ if (ci->status == T_MODIFIED)
2481+ whichperm = 3;
2482+ else if (ci->status == T_ADDED)
2483+ whichperm = 6;
2484+ else if (ci->status == T_REMOVED)
2485+ whichperm = 7;
2486+
2487+ if (!access_allowed (finfo->file, finfo->repository, ci->tag, whichperm,
2488+ NULL, NULL, 1))
2489+ {
2490+ if (stop_at_first_permission_denied)
2491+ error (1, 0, "permission denied for %s",
2492+ Short_Repository (finfo->repository));
2493+ else
2494+ error (0, 0, "permission denied for %s/%s",
2495+ Short_Repository (finfo->repository), finfo->file);
2496+
2497+ return (0);
2498+ }
2499+ }
2500+#endif
2501+
2502 if (ci->status == T_MODIFIED)
2503 {
2504 if (finfo->rcs == NULL)
c52fdbcd 2505diff -urN cvs-1.11.17.orig/src/cvs.h cvs-1.11.17/src/cvs.h
67ba4c3a 2506--- cvs-1.11.17.orig/src/cvs.h 2004-08-04 10:31:54.000000000 +0200
2507+++ cvs-1.11.17/src/cvs.h 2004-08-04 10:40:18.609727544 +0200
c52fdbcd 2508@@ -195,6 +195,11 @@
09f63587 2509 #define CVSROOTADM_PASSWD "passwd"
2510 #define CVSROOTADM_CONFIG "config"
2511
2512+/* cvsacl patch */
2513+#define CVSROOTADM_ACLCONFIG "aclconfig"
2514+#define CVSROOTADM_ACCESS "access"
2515+#define CVSROOTADM_GROUP "group"
2516+
2517 #define CVSNULLREPOS "Emptydir" /* an empty directory */
2518
2519 /* Other CVS file names */
67ba4c3a 2520@@ -572,6 +577,18 @@
09f63587 2521 /* LockDir setting from CVSROOT/config. */
2522 extern char *lock_dir;
2523
2524+/* cvsacl patch */
2525+/* ACL Patch settings from CVSROOT/config */
2526+extern int use_cvs_acl;
2527+extern char *cvs_acl_default_permissions;
2528+extern int use_cvs_groups;
2529+extern int use_system_groups;
c52fdbcd 2530+extern int use_separate_acl_file_for_each_dir;
09f63587 2531+extern char *cvs_acl_file_location;
2532+extern char *cvs_groups_file_location;
2533+extern char *cvs_server_run_as;
2534+extern int stop_at_first_permission_denied;
2535+
2536 void Scratch_Entry PROTO((List * list, const char *fname));
2537 void ParseTag PROTO((char **tagp, char **datep, int *nonbranchp));
2538 void WriteTag PROTO ((const char *dir, const char *tag, const char *date,
67ba4c3a 2539@@ -867,6 +884,10 @@
09f63587 2540 int editors PROTO ((int argc, char **argv));
2541 int watchers PROTO ((int argc, char **argv));
2542 extern int annotate PROTO ((int argc, char **argv));
2543+
2544+/* cvsacl patch */
2545+extern int cvsacl PROTO ((int argc, char **argv));
2546+
2547 extern int add PROTO ((int argc, char **argv));
2548 extern int admin PROTO ((int argc, char **argv));
2549 extern int checkout PROTO ((int argc, char **argv));
c52fdbcd 2550diff -urN cvs-1.11.17.orig/src/diff.c cvs-1.11.17/src/diff.c
2551--- cvs-1.11.17.orig/src/diff.c 2004-03-20 03:06:45.000000000 +0100
67ba4c3a 2552+++ cvs-1.11.17/src/diff.c 2004-08-04 10:40:18.611727240 +0200
09f63587 2553@@ -474,6 +474,43 @@
2554 {
2555 /* Skip all the following checks regarding the user file; we're
2556 not using it. */
2557+
2558+/* cvsacl patch */
2559+#ifdef SERVER_SUPPORT
2560+ if (use_cvs_acl && server_active)
2561+ {
2562+ if (diff_rev1)
2563+ {
2564+ if (!access_allowed (NULL, finfo->repository, diff_rev1, 5,
2565+ NULL, NULL, 1))
2566+ {
2567+ if (stop_at_first_permission_denied)
2568+ error (1, 0, "permission denied for %s",
2569+ Short_Repository (finfo->repository));
2570+ else
2571+ error (0, 0, "permission denied for %s/%s",
2572+ Short_Repository (finfo->repository), finfo->file);
2573+
2574+ return (0);
2575+ }
2576+ }
2577+ if (diff_rev2)
2578+ {
2579+ if (!access_allowed (NULL, finfo->repository, diff_rev2, 5))
2580+ {
2581+ if (stop_at_first_permission_denied)
2582+ error (1, 0, "permission denied for %s",
2583+ Short_Repository (finfo->repository));
2584+ else
2585+ error (0, 0, "permission denied for %s/%s",
2586+ Short_Repository (finfo->repository), finfo->file);
2587+
2588+ return (0);
2589+ }
2590+ }
2591+ }
2592+#endif
2593+
2594 }
2595 else if (vers->vn_user == NULL)
2596 {
2597@@ -827,6 +864,42 @@
2598 if (!isdir (dir))
2599 return (R_SKIP_ALL);
2600
2601+/* cvsacl patch */
2602+#ifdef SERVER_SUPPORT
2603+ if (use_cvs_acl && server_active)
2604+ {
2605+ if (diff_rev1)
2606+ {
2607+ if (!access_allowed (NULL, update_dir, diff_rev1, 5,
2608+ NULL, NULL, 1))
2609+ {
2610+ if (stop_at_first_permission_denied)
2611+ error (1, 0, "permission denied for %s",
2612+ Short_Repository (update_dir));
2613+ else
2614+ error (0, 0, "permission denied for %s/%s",
2615+ Short_Repository (update_dir), update_dir);
2616+
2617+ return (0);
2618+ }
2619+ }
2620+ if (diff_rev2)
2621+ {
2622+ if (!access_allowed (NULL, update_dir, diff_rev2, 5))
2623+ {
2624+ if (stop_at_first_permission_denied)
2625+ error (1, 0, "permission denied for %s",
2626+ Short_Repository (update_dir));
2627+ else
2628+ error (0, 0, "permission denied for %s/%s",
2629+ Short_Repository (update_dir), update_dir);
2630+
2631+ return (0);
2632+ }
2633+ }
2634+ }
2635+#endif
2636+
2637 if (!quiet)
2638 error (0, 0, "Diffing %s", update_dir);
2639 return (R_PROCESS);
c52fdbcd 2640diff -urN cvs-1.11.17.orig/src/import.c cvs-1.11.17/src/import.c
2641--- cvs-1.11.17.orig/src/import.c 2004-04-02 20:55:49.000000000 +0200
67ba4c3a 2642+++ cvs-1.11.17/src/import.c 2004-08-04 10:40:18.634723744 +0200
09f63587 2643@@ -304,6 +304,20 @@
2644 error (1, 0, "attempt to import the repository");
2645 }
2646
2647+/* cvsacl patch */
2648+#ifdef SERVER_SUPPORT
2649+ if (use_cvs_acl && server_active)
2650+ {
2651+ if (!access_allowed (NULL, repository, argv[1], 6, NULL, NULL, 1))
2652+ {
2653+ error (stop_at_first_permission_denied, 0, "permission denied for %s",
2654+ Short_Repository (repository));
2655+
2656+ return (0);
2657+ }
2658+ }
2659+#endif
2660+
2661 /*
2662 * Make all newly created directories writable. Should really use a more
2663 * sophisticated security mechanism here.
c52fdbcd 2664diff -urN cvs-1.11.17.orig/src/log.c cvs-1.11.17/src/log.c
2665--- cvs-1.11.17.orig/src/log.c 2004-05-10 15:37:16.000000000 +0200
67ba4c3a 2666+++ cvs-1.11.17/src/log.c 2004-08-04 10:40:18.636723440 +0200
09f63587 2667@@ -837,6 +837,25 @@
2668 return 1;
2669 }
2670
2671+/* cvsacl patch */
2672+#ifdef SERVER_SUPPORT
2673+ if (use_cvs_acl && server_active)
2674+ {
2675+ if (!access_allowed (finfo->file, finfo->repository, NULL, 5,
2676+ NULL, NULL, 1))
2677+ {
2678+ if (stop_at_first_permission_denied)
2679+ error (1, 0, "permission denied for %s",
2680+ Short_Repository (finfo->repository));
2681+ else
2682+ error (0, 0, "permission denied for %s/%s",
2683+ Short_Repository (finfo->repository), finfo->file);
2684+
2685+ return (0);
2686+ }
2687+ }
2688+#endif
2689+
2690 if (log_data->sup_header || !log_data->nameonly)
2691 {
2692
c52fdbcd 2693diff -urN cvs-1.11.17.orig/src/main.c cvs-1.11.17/src/main.c
67ba4c3a 2694--- cvs-1.11.17.orig/src/main.c 2004-08-04 10:31:54.000000000 +0200
2695+++ cvs-1.11.17/src/main.c 2004-08-04 10:40:18.639722984 +0200
2696@@ -106,6 +106,10 @@
09f63587 2697 } cmds[] =
2698
2699 {
2700+ /* cvsacl patch */
2701+ { "acl", NULL, NULL, cvsacl, CVS_CMD_MODIFIES_REPOSITORY | CVS_CMD_USES_WORK_DIR },
2702+ { "racl", NULL, NULL, cvsacl, CVS_CMD_MODIFIES_REPOSITORY | CVS_CMD_USES_WORK_DIR },
2703+
2704 { "add", "ad", "new", add, CVS_CMD_MODIFIES_REPOSITORY | CVS_CMD_USES_WORK_DIR },
2705 { "admin", "adm", "rcs", admin, CVS_CMD_MODIFIES_REPOSITORY | CVS_CMD_USES_WORK_DIR },
2706 { "annotate", "ann", NULL, annotate, CVS_CMD_USES_WORK_DIR },
67ba4c3a 2707@@ -982,6 +986,9 @@
09f63587 2708 if we didn't, then there would be no way to check in a new
2709 CVSROOT/config file to fix the broken one! */
2710 parse_config (current_parsed_root->directory);
2711+
2712+ /* cvsacl patch */
2713+ parse_aclconfig (current_parsed_root->directory);
2714 }
2715
2716 #ifdef CLIENT_SUPPORT
67ba4c3a 2717diff -urN cvs-1.11.17.orig/src/Makefile.am cvs-1.11.17/src/Makefile.am
2718--- cvs-1.11.17.orig/src/Makefile.am 2004-08-04 10:32:06.000000000 +0200
2719+++ cvs-1.11.17/src/Makefile.am 2004-08-04 10:40:18.594729824 +0200
2720@@ -29,6 +29,7 @@
2721
2722 # The cvs executable
2723 cvs_SOURCES = \
2724+ acl.c \
2725 add.c \
2726 admin.c \
2727 annotate.c \
2728diff -urN cvs-1.11.17.orig/src/Makefile.in cvs-1.11.17/src/Makefile.in
2729--- cvs-1.11.17.orig/src/Makefile.in 2004-06-09 16:46:19.000000000 +0200
2730+++ cvs-1.11.17/src/Makefile.in 2004-08-04 10:40:18.600728912 +0200
2731@@ -153,6 +153,7 @@
2732
2733 # The cvs executable
2734 cvs_SOURCES = \
2735+ acl.c \
2736 add.c \
2737 admin.c \
2738 annotate.c \
2739@@ -253,11 +254,11 @@
2740 bin_PROGRAMS = cvs$(EXEEXT)
2741 PROGRAMS = $(bin_PROGRAMS)
2742
2743-am_cvs_OBJECTS = add.$(OBJEXT) admin.$(OBJEXT) annotate.$(OBJEXT) \
2744- buffer.$(OBJEXT) checkin.$(OBJEXT) checkout.$(OBJEXT) \
2745- classify.$(OBJEXT) client.$(OBJEXT) commit.$(OBJEXT) \
2746- create_adm.$(OBJEXT) cvsrc.$(OBJEXT) diff.$(OBJEXT) \
2747- edit.$(OBJEXT) entries.$(OBJEXT) error.$(OBJEXT) \
2748+am_cvs_OBJECTS = acl.$(OBJEXT) add.$(OBJEXT) admin.$(OBJEXT) \
2749+ annotate.$(OBJEXT) buffer.$(OBJEXT) checkin.$(OBJEXT) \
2750+ checkout.$(OBJEXT) classify.$(OBJEXT) client.$(OBJEXT) \
2751+ commit.$(OBJEXT) create_adm.$(OBJEXT) cvsrc.$(OBJEXT) \
2752+ diff.$(OBJEXT) edit.$(OBJEXT) entries.$(OBJEXT) error.$(OBJEXT) \
2753 expand_path.$(OBJEXT) fileattr.$(OBJEXT) filesubr.$(OBJEXT) \
2754 find_names.$(OBJEXT) hardlink.$(OBJEXT) hash.$(OBJEXT) \
2755 history.$(OBJEXT) ignore.$(OBJEXT) import.$(OBJEXT) \
2756@@ -280,34 +281,34 @@
2757 DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
2758 depcomp = $(SHELL) $(top_srcdir)/depcomp
2759 am__depfiles_maybe = depfiles
2760-@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/add.Po ./$(DEPDIR)/admin.Po \
2761-@AMDEP_TRUE@ ./$(DEPDIR)/annotate.Po ./$(DEPDIR)/buffer.Po \
2762-@AMDEP_TRUE@ ./$(DEPDIR)/checkin.Po ./$(DEPDIR)/checkout.Po \
2763-@AMDEP_TRUE@ ./$(DEPDIR)/classify.Po ./$(DEPDIR)/client.Po \
2764-@AMDEP_TRUE@ ./$(DEPDIR)/commit.Po ./$(DEPDIR)/create_adm.Po \
2765-@AMDEP_TRUE@ ./$(DEPDIR)/cvsrc.Po ./$(DEPDIR)/diff.Po \
2766-@AMDEP_TRUE@ ./$(DEPDIR)/edit.Po ./$(DEPDIR)/entries.Po \
2767-@AMDEP_TRUE@ ./$(DEPDIR)/error.Po ./$(DEPDIR)/expand_path.Po \
2768-@AMDEP_TRUE@ ./$(DEPDIR)/fileattr.Po ./$(DEPDIR)/filesubr.Po \
2769-@AMDEP_TRUE@ ./$(DEPDIR)/find_names.Po ./$(DEPDIR)/hardlink.Po \
2770-@AMDEP_TRUE@ ./$(DEPDIR)/hash.Po ./$(DEPDIR)/history.Po \
2771-@AMDEP_TRUE@ ./$(DEPDIR)/ignore.Po ./$(DEPDIR)/import.Po \
2772-@AMDEP_TRUE@ ./$(DEPDIR)/lock.Po ./$(DEPDIR)/log.Po \
2773-@AMDEP_TRUE@ ./$(DEPDIR)/login.Po ./$(DEPDIR)/logmsg.Po \
2774-@AMDEP_TRUE@ ./$(DEPDIR)/main.Po ./$(DEPDIR)/mkmodules.Po \
2775-@AMDEP_TRUE@ ./$(DEPDIR)/modules.Po ./$(DEPDIR)/myndbm.Po \
2776-@AMDEP_TRUE@ ./$(DEPDIR)/no_diff.Po ./$(DEPDIR)/parseinfo.Po \
2777-@AMDEP_TRUE@ ./$(DEPDIR)/patch.Po ./$(DEPDIR)/rcs.Po \
2778-@AMDEP_TRUE@ ./$(DEPDIR)/rcscmds.Po ./$(DEPDIR)/recurse.Po \
2779-@AMDEP_TRUE@ ./$(DEPDIR)/release.Po ./$(DEPDIR)/remove.Po \
2780-@AMDEP_TRUE@ ./$(DEPDIR)/repos.Po ./$(DEPDIR)/root.Po \
2781-@AMDEP_TRUE@ ./$(DEPDIR)/run.Po ./$(DEPDIR)/scramble.Po \
2782-@AMDEP_TRUE@ ./$(DEPDIR)/server.Po ./$(DEPDIR)/stack.Po \
2783-@AMDEP_TRUE@ ./$(DEPDIR)/status.Po ./$(DEPDIR)/subr.Po \
2784-@AMDEP_TRUE@ ./$(DEPDIR)/tag.Po ./$(DEPDIR)/update.Po \
2785-@AMDEP_TRUE@ ./$(DEPDIR)/vers_ts.Po ./$(DEPDIR)/version.Po \
2786-@AMDEP_TRUE@ ./$(DEPDIR)/watch.Po ./$(DEPDIR)/wrapper.Po \
2787-@AMDEP_TRUE@ ./$(DEPDIR)/zlib.Po
2788+@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/acl.Po ./$(DEPDIR)/add.Po \
2789+@AMDEP_TRUE@ ./$(DEPDIR)/admin.Po ./$(DEPDIR)/annotate.Po \
2790+@AMDEP_TRUE@ ./$(DEPDIR)/buffer.Po ./$(DEPDIR)/checkin.Po \
2791+@AMDEP_TRUE@ ./$(DEPDIR)/checkout.Po ./$(DEPDIR)/classify.Po \
2792+@AMDEP_TRUE@ ./$(DEPDIR)/client.Po ./$(DEPDIR)/commit.Po \
2793+@AMDEP_TRUE@ ./$(DEPDIR)/create_adm.Po ./$(DEPDIR)/cvsrc.Po \
2794+@AMDEP_TRUE@ ./$(DEPDIR)/diff.Po ./$(DEPDIR)/edit.Po \
2795+@AMDEP_TRUE@ ./$(DEPDIR)/entries.Po ./$(DEPDIR)/error.Po \
2796+@AMDEP_TRUE@ ./$(DEPDIR)/expand_path.Po ./$(DEPDIR)/fileattr.Po \
2797+@AMDEP_TRUE@ ./$(DEPDIR)/filesubr.Po ./$(DEPDIR)/find_names.Po \
2798+@AMDEP_TRUE@ ./$(DEPDIR)/hardlink.Po ./$(DEPDIR)/hash.Po \
2799+@AMDEP_TRUE@ ./$(DEPDIR)/history.Po ./$(DEPDIR)/ignore.Po \
2800+@AMDEP_TRUE@ ./$(DEPDIR)/import.Po ./$(DEPDIR)/lock.Po \
2801+@AMDEP_TRUE@ ./$(DEPDIR)/log.Po ./$(DEPDIR)/login.Po \
2802+@AMDEP_TRUE@ ./$(DEPDIR)/logmsg.Po ./$(DEPDIR)/main.Po \
2803+@AMDEP_TRUE@ ./$(DEPDIR)/mkmodules.Po ./$(DEPDIR)/modules.Po \
2804+@AMDEP_TRUE@ ./$(DEPDIR)/myndbm.Po ./$(DEPDIR)/no_diff.Po \
2805+@AMDEP_TRUE@ ./$(DEPDIR)/parseinfo.Po ./$(DEPDIR)/patch.Po \
2806+@AMDEP_TRUE@ ./$(DEPDIR)/rcs.Po ./$(DEPDIR)/rcscmds.Po \
2807+@AMDEP_TRUE@ ./$(DEPDIR)/recurse.Po ./$(DEPDIR)/release.Po \
2808+@AMDEP_TRUE@ ./$(DEPDIR)/remove.Po ./$(DEPDIR)/repos.Po \
2809+@AMDEP_TRUE@ ./$(DEPDIR)/root.Po ./$(DEPDIR)/run.Po \
2810+@AMDEP_TRUE@ ./$(DEPDIR)/scramble.Po ./$(DEPDIR)/server.Po \
2811+@AMDEP_TRUE@ ./$(DEPDIR)/stack.Po ./$(DEPDIR)/status.Po \
2812+@AMDEP_TRUE@ ./$(DEPDIR)/subr.Po ./$(DEPDIR)/tag.Po \
2813+@AMDEP_TRUE@ ./$(DEPDIR)/update.Po ./$(DEPDIR)/vers_ts.Po \
2814+@AMDEP_TRUE@ ./$(DEPDIR)/version.Po ./$(DEPDIR)/watch.Po \
2815+@AMDEP_TRUE@ ./$(DEPDIR)/wrapper.Po ./$(DEPDIR)/zlib.Po
2816 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
2817 $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
2818 CCLD = $(CC)
2819@@ -381,6 +382,7 @@
2820 distclean-compile:
2821 -rm -f *.tab.c
2822
2823+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/acl.Po@am__quote@
2824 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/add.Po@am__quote@
2825 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/admin.Po@am__quote@
2826 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/annotate.Po@am__quote@
c52fdbcd 2827diff -urN cvs-1.11.17.orig/src/mkmodules.c cvs-1.11.17/src/mkmodules.c
2828--- cvs-1.11.17.orig/src/mkmodules.c 2004-02-03 15:39:40.000000000 +0100
67ba4c3a 2829+++ cvs-1.11.17/src/mkmodules.c 2004-08-04 10:40:18.641722680 +0200
09f63587 2830@@ -311,6 +311,44 @@
2831 NULL
2832 };
2833
2834+/* cvsacl patch */
2835+static const char *const aclconfig_contents[] = {
2836+ "# Set `UseCVSACL' to yes to use CVSACL feature.\n",
2837+ "UseCVSACL=yes\n",
2838+ "\n",
2839+ "# Default CVSACL Permission to use.\n",
2840+ "#CVSACLDefaultPermissions=p\n",
2841+ "\n",
2842+ "# Default file location for CVS ACL file (access) is CVSROOT/access.\n",
2843+ "# If you want to use a different location, define it below.\n",
2844+ "#CVSACLFileLocation=/path/to/cvs/access\n",
2845+ "\n",
2846+ "# Set `UseSystemGroups' to yes to use system group definitions (/etc/group).\n",
2847+ "UseSystemGroups=yes\n",
2848+ "\n",
2849+ "# Set `UseCVSGroups' to yes to use another group file.\n",
2850+ "#UseCVSGroups=yes\n",
2851+ "\n",
2852+ "# Default file location for CVS groups file is CVSROOT/group.\n",
2853+ "# If you want to use a different location, define it below.\n",
2854+ "#CVSGroupsFileLocation=/path/to/cvs/group\n",
2855+ "\n",
c52fdbcd 2856+ "# Set UseSeparateACLFileForEachDir to yes in order to use a\n",
2857+ "# separate 'access' file for each directory.\n",
09f63587 2858+ "# This increased the performance if you have really big repository.\n",
c52fdbcd 2859+ "#UseSeparateACLFileForEachDir=no\n",
09f63587 2860+ "\n",
2861+ "# If StopAtFirstPermissionDenied is set to yes\n",
2862+ "# operation will stop at first permission denied message.\n",
2863+ "# Default is no.\n",
2864+ "#StopAtFirstPermissionDenied=no\n",
2865+ "\n",
2866+ "# Set CVSServerRunAsUser to a system user, in order CVS server\n",
2867+ "# to run as.\n",
2868+ "#CVSServerRunAsUser=runascvsuser",
2869+ NULL
2870+};
2871+
2872 static const struct admin_file filelist[] = {
2873 {CVSROOTADM_LOGINFO,
2874 "no logging of 'cvs commit' messages is done without a %s file",
2875@@ -373,7 +411,12 @@
2876 {CVSROOTADM_CONFIG,
2877 "a %s file configures various behaviors",
2878 config_contents},
2879- {NULL, NULL, NULL}
2880+
2881+ /* cvsacl patch */
2882+ {CVSROOTADM_ACLCONFIG,
2883+ "a %s file configures Access Control List behaviors",
2884+ aclconfig_contents},
2885+ {NULL, NULL, NULL}
2886 };
2887
2888 /* Rebuild the checked out administrative files in directory DIR. */
2889@@ -957,6 +1000,26 @@
2890 because xchmod() is too shy. */
2891 chmod (info, 0666);
2892 }
2893+
2894+ /* cvsacl patch */
2895+ /* Make an empty 'CVSROOT/access' file */
2896+ strcpy (info, adm);
2897+ strcat (info, "/");
2898+ strcat (info, CVSROOTADM_ACCESS);
2899+ if (!isfile (info))
2900+ {
2901+ FILE *fp;
2902+
2903+ fp = open_file (info, "w");
2904+ if (fputs ("# CVS ACL definitions file. DO NOT EDIT MANUALLY\n",
2905+ fp) < 0)
2906+ error (1, errno, "cannot write %s", info);
2907+
2908+ if (fclose (fp) < 0)
2909+ error (1, errno, "cannot close %s", info);
2910+
2911+ chmod (info, 0644);
2912+ }
2913
2914 /* Make an empty val-tags file to prevent problems creating it later. */
2915 strcpy (info, adm);
c52fdbcd 2916diff -urN cvs-1.11.17.orig/src/parseinfo.c cvs-1.11.17/src/parseinfo.c
2917--- cvs-1.11.17.orig/src/parseinfo.c 2004-03-19 21:36:39.000000000 +0100
67ba4c3a 2918+++ cvs-1.11.17/src/parseinfo.c 2004-08-04 10:40:18.643722376 +0200
09f63587 2919@@ -448,3 +448,192 @@
2920 free (line);
2921 return -1;
2922 }
2923+/* cvsacl patch */
2924+int
2925+parse_aclconfig (cvsroot)
2926+ char *cvsroot;
2927+{
2928+ char *infopath;
2929+ FILE *fp_info;
2930+ char *line = NULL;
2931+ size_t line_allocated = 0;
2932+ size_t len;
2933+ char *p;
2934+ /* FIXME-reentrancy: If we do a multi-threaded server, this would need
2935+ to go to the per-connection data structures. */
2936+ static int parsed = 0;
2937+
2938+ /* Authentication code and serve_root might both want to call us.
2939+ Let this happen smoothly. */
2940+ if (parsed)
2941+ return 0;
2942+ parsed = 1;
2943+
2944+ infopath = xmalloc (strlen (cvsroot)
2945+ + sizeof (CVSROOTADM_ACLCONFIG)
2946+ + sizeof (CVSROOTADM)
2947+ + 10);
2948+ if (infopath == NULL)
2949+ {
2950+ error (0, 0, "out of memory; cannot allocate infopath");
2951+ goto error_return;
2952+ }
2953+
2954+ strcpy (infopath, cvsroot);
2955+ strcat (infopath, "/");
2956+ strcat (infopath, CVSROOTADM);
2957+ strcat (infopath, "/");
2958+ strcat (infopath, CVSROOTADM_ACLCONFIG);
2959+
2960+ fp_info = CVS_FOPEN (infopath, "r");
2961+ if (fp_info == NULL)
2962+ {
2963+ /* If no file, don't do anything special. */
2964+ if (!existence_error (errno))
2965+ {
2966+ /* Just a warning message; doesn't affect return
2967+ value, currently at least. */
2968+ error (0, errno, "cannot open %s", infopath);
2969+ }
2970+ free (infopath);
2971+ return 0;
2972+ }
2973+
2974+ while (getline (&line, &line_allocated, fp_info) >= 0)
2975+ {
2976+ /* Skip comments. */
2977+ if (line[0] == '#')
2978+ continue;
2979+
2980+ len = strlen (line) - 1;
2981+ if (line[len] == '\n')
2982+ line[len] = '\0';
2983+
2984+ /* Skip blank lines. */
2985+ if (line[0] == '\0')
2986+ continue;
2987+
2988+ /* The first '=' separates keyword from value. */
2989+ p = strchr (line, '=');
2990+ if (p == NULL)
2991+ {
2992+ /* Probably should be printing line number. */
2993+ error (0, 0, "syntax error in %s: line '%s' is missing '='",
2994+ infopath, line);
2995+ goto error_return;
2996+ }
2997+
2998+ *p++ = '\0';
2999+
3000+ if (strcmp (line, "UseCVSACL") == 0)
3001+ {
3002+ if (strcmp (p, "no") == 0)
3003+ use_cvs_acl = 0;
3004+ else if (strcmp (p, "yes") == 0)
3005+ use_cvs_acl = 1;
3006+ else
3007+ {
3008+ error (0, 0, "unrecognized value '%s' for UseCVSACL", p);
3009+ goto error_return;
3010+ }
3011+ }
c52fdbcd 3012+ else if (strcmp (line, "UseSeparateACLFileForEachDir") == 0)
09f63587 3013+ {
3014+ if (strcmp (p, "no") == 0)
c52fdbcd 3015+ use_separate_acl_file_for_each_dir = 0;
09f63587 3016+ else if (strcmp (p, "yes") == 0)
c52fdbcd 3017+ use_separate_acl_file_for_each_dir = 1;
09f63587 3018+ else
3019+ {
c52fdbcd 3020+ error (0, 0, "unrecognized value '%s' for UseSeparateACLFileForEachDir", p);
09f63587 3021+ goto error_return;
3022+ }
3023+ }
3024+ else if (strcmp (line, "StopAtFirstPermissionDenied") == 0)
3025+ {
3026+ if (strcmp (p, "no") == 0)
3027+ stop_at_first_permission_denied = 0;
3028+ else if (strcmp (p, "yes") == 0)
3029+ stop_at_first_permission_denied = 1;
3030+ else
3031+ {
3032+ error (0, 0, "unrecognized value '%s' for StopAtFirstPermissionDenied", p);
3033+ goto error_return;
3034+ }
3035+ }
3036+ else if (strcmp (line, "CVSACLDefaultPermissions") == 0)
3037+ {
3038+ if (cvs_acl_default_permissions != NULL)
3039+ free (cvs_acl_default_permissions);
3040+ if (!given_perms_valid (p))
3041+ error (1,0,"Invalid CVS ACL Default Permissions: '%s' in CVSROOT/aclconfig", p);
3042+ cvs_acl_default_permissions = xstrdup (p);
3043+ }
3044+ else if (strcmp (line, "UseCVSGroups") == 0)
3045+ {
3046+ if (strcmp (p, "no") == 0)
3047+ use_cvs_groups = 0;
3048+ else if (strcmp (p, "yes") == 0)
3049+ use_cvs_groups = 1;
3050+ else
3051+ {
3052+ error (0, 0, "unrecognized value '%s' for UseCVSGroups", p);
3053+ goto error_return;
3054+ }
3055+ }
3056+ else if (strcmp (line, "UseSystemGroups") == 0)
3057+ {
3058+ if (strcmp (p, "no") == 0)
3059+ use_system_groups = 0;
3060+ else if (strcmp (p, "yes") == 0)
3061+ use_system_groups = 1;
3062+ else
3063+ {
3064+ error (0, 0, "unrecognized value '%s' for UseSystemGroups", p);
3065+ goto error_return;
3066+ }
3067+ }
3068+ else if (strcmp (line, "CVSACLFileLocation") == 0)
3069+ {
3070+ if (cvs_acl_file_location != NULL)
3071+ free (cvs_acl_file_location);
3072+ cvs_acl_file_location = xstrdup (p);
3073+ }
3074+ else if (strcmp (line, "CVSGroupsFileLocation") == 0)
3075+ {
3076+ if (cvs_groups_file_location != NULL)
3077+ free (cvs_groups_file_location);
3078+ cvs_groups_file_location = xstrdup (p);
3079+ }
3080+ else if (strcmp (line, "CVSServerRunAsUser") == 0)
3081+ {
3082+ if (cvs_server_run_as != NULL)
3083+ free (cvs_server_run_as);
3084+ cvs_server_run_as = xstrdup (p);
3085+ }
3086+
3087+ }
3088+
3089+ if (ferror (fp_info))
3090+ {
3091+ error (0, errno, "cannot read %s", infopath);
3092+ goto error_return;
3093+ }
3094+ if (fclose (fp_info) < 0)
3095+ {
3096+ error (0, errno, "cannot close %s", infopath);
3097+ goto error_return;
3098+ }
3099+ free (infopath);
3100+ if (line != NULL)
3101+ free (line);
3102+ return 0;
3103+
3104+ error_return:
3105+ if (infopath != NULL)
3106+ free (infopath);
3107+ if (line != NULL)
3108+ free (line);
3109+ return -1;
3110+}
3111+
c52fdbcd 3112diff -urN cvs-1.11.17.orig/src/patch.c cvs-1.11.17/src/patch.c
3113--- cvs-1.11.17.orig/src/patch.c 2004-04-02 21:25:32.000000000 +0200
67ba4c3a 3114+++ cvs-1.11.17/src/patch.c 2004-08-04 10:40:18.645722072 +0200
09f63587 3115@@ -498,6 +498,43 @@
3116 goto out2;
3117 }
3118
3119+/* cvsacl patch */
3120+#ifdef SERVER_SUPPORT
3121+ if (use_cvs_acl && server_active)
3122+ {
3123+ if (rev1)
3124+ {
3125+ if (!access_allowed (finfo->file, finfo->repository, rev1, 5,
3126+ NULL, NULL, 1))
3127+ {
3128+ if (stop_at_first_permission_denied)
3129+ error (1, 0, "permission denied for %s",
3130+ Short_Repository (finfo->repository));
3131+ else
3132+ error (0, 0, "permission denied for %s/%s",
3133+ Short_Repository (finfo->repository), finfo->file);
3134+
3135+ return (0);
3136+ }
3137+ }
3138+ if (rev2)
3139+ {
3140+ if (!access_allowed (finfo->file, finfo->repository, rev2, 5,
3141+ NULL, NULL, 1))
3142+ {
3143+ if (stop_at_first_permission_denied)
3144+ error (1, 0, "permission denied for %s",
3145+ Short_Repository (finfo->repository));
3146+ else
3147+ error (0, 0, "permission denied for %s/%s",
3148+ Short_Repository (finfo->repository), finfo->file);
3149+
3150+ return (0);
3151+ }
3152+ }
3153+ }
3154+#endif
3155+
3156 /* Create 3 empty files. I'm not really sure there is any advantage
3157 * to doing so now rather than just waiting until later.
3158 *
c52fdbcd 3159diff -urN cvs-1.11.17.orig/src/remove.c cvs-1.11.17/src/remove.c
3160--- cvs-1.11.17.orig/src/remove.c 2004-03-20 03:34:32.000000000 +0100
67ba4c3a 3161+++ cvs-1.11.17/src/remove.c 2004-08-04 10:40:18.648721616 +0200
09f63587 3162@@ -250,6 +250,25 @@
3163 {
3164 char *fname;
3165
3166+/* cvsacl patch */
3167+#ifdef SERVER_SUPPORT
3168+ if (use_cvs_acl && server_active)
3169+ {
3170+ if (!access_allowed (finfo->file, finfo->repository, vers->tag, 7,
3171+ NULL, NULL, 1))
3172+ {
3173+ if (stop_at_first_permission_denied)
3174+ error (1, 0, "permission denied for %s",
3175+ Short_Repository (finfo->repository));
3176+ else
3177+ error (0, 0, "permission denied for %s/%s",
3178+ Short_Repository (finfo->repository), finfo->file);
3179+
3180+ return (0);
3181+ }
3182+ }
3183+#endif
3184+
3185 /* Re-register it with a negative version number. */
3186 fname = xmalloc (strlen (vers->vn_user) + 5);
3187 (void) strcpy (fname, "-");
c52fdbcd 3188diff -urN cvs-1.11.17.orig/src/server.c cvs-1.11.17/src/server.c
67ba4c3a 3189--- cvs-1.11.17.orig/src/server.c 2004-08-04 10:31:54.000000000 +0200
3190+++ cvs-1.11.17/src/server.c 2004-08-04 10:40:18.656720400 +0200
09f63587 3191@@ -773,6 +773,10 @@
3192 nothing. But for rsh, we need to do it now. */
3193 parse_config (current_parsed_root->directory);
3194
3195+ /* cvsacl patch */
3196+ parse_aclconfig (current_parsed_root->directory);
3197+
3198+
3199 path = xmalloc (strlen (current_parsed_root->directory)
3200 + sizeof (CVSROOTADM)
3201 + 2);
c52fdbcd 3202@@ -3761,6 +3765,23 @@
09f63587 3203 do_cvs_command ("rlog", cvslog);
3204 }
3205
3206+/* cvsacl patch */
3207+static void
3208+serve_acl (arg)
3209+ char *arg;
3210+{
3211+ do_cvs_command ("acl", cvsacl);
3212+}
3213+
3214+/* cvsacl patch */
3215+static void
3216+serve_racl (arg)
3217+ char *arg;
3218+{
c52fdbcd 3219+ cvs_cmd_name = "racl";
09f63587 3220+ do_cvs_command ("racl", cvsacl);
3221+}
3222+
3223 static void
3224 serve_add (arg)
3225 char *arg;
c52fdbcd 3226@@ -4820,6 +4841,11 @@
09f63587 3227 REQ_LINE("diff", serve_diff, 0),
3228 REQ_LINE("log", serve_log, 0),
3229 REQ_LINE("rlog", serve_rlog, 0),
3230+
3231+ /* cvsacl patch */
3232+ REQ_LINE("acl", serve_acl, 0),
3233+ REQ_LINE("racl", serve_racl, 0),
3234+
3235 REQ_LINE("add", serve_add, 0),
3236 REQ_LINE("remove", serve_remove, 0),
3237 REQ_LINE("update-patches", serve_ignore, 0),
c52fdbcd 3238@@ -5293,6 +5319,10 @@
09f63587 3239 {
3240 struct passwd *pw;
3241
3242+ /* cvsacl patch */
3243+ if (use_cvs_acl && cvs_server_run_as)
3244+ username = cvs_server_run_as;
3245+
3246 pw = getpwnam (username);
3247 if (pw == NULL)
3248 {
c52fdbcd 3249@@ -5875,6 +5905,9 @@
09f63587 3250 in a new CVSROOT/config file to fix the broken one! */
3251 parse_config (repository);
3252
3253+ /* cvsacl patch */
3254+ parse_aclconfig (repository);
3255+
3256 /* We need the real cleartext before we hash it. */
3257 descrambled_password = descramble (password);
3258 host_user = check_password (username, descrambled_password, repository);
c52fdbcd 3259diff -urN cvs-1.11.17.orig/src/status.c cvs-1.11.17/src/status.c
3260--- cvs-1.11.17.orig/src/status.c 2004-03-20 02:40:12.000000000 +0100
67ba4c3a 3261+++ cvs-1.11.17/src/status.c 2004-08-04 10:40:18.658720096 +0200
09f63587 3262@@ -128,7 +128,27 @@
3263
3264 status = Classify_File (finfo, (char *) NULL, (char *) NULL, (char *) NULL,
3265 1, 0, &vers, 0);
3266- sstat = "Classify Error";
3267+
3268+/* cvsacl patch */
3269+#ifdef SERVER_SUPPORT
3270+ if (use_cvs_acl && server_active)
3271+ {
3272+ if (!access_allowed (finfo->file, finfo->repository, vers->tag, 5,
3273+ NULL, NULL, 1))
3274+ {
3275+ if (stop_at_first_permission_denied)
3276+ error (1, 0, "permission denied for %s",
3277+ Short_Repository (finfo->repository));
3278+ else
3279+ error (0, 0, "permission denied for %s/%s",
3280+ Short_Repository (finfo->repository), finfo->file);
3281+
3282+ return (0);
3283+ }
3284+ }
3285+#endif
3286+
3287+ sstat = "Classify Error";
3288 switch (status)
3289 {
3290 case T_UNKNOWN:
c52fdbcd 3291diff -urN cvs-1.11.17.orig/src/tag.c cvs-1.11.17/src/tag.c
3292--- cvs-1.11.17.orig/src/tag.c 2004-04-06 20:37:10.000000000 +0200
67ba4c3a 3293+++ cvs-1.11.17/src/tag.c 2004-08-04 10:40:18.661719640 +0200
09f63587 3294@@ -660,6 +660,25 @@
3295 * correctly without breaking your link!
3296 */
3297
3298+/* cvsacl patch */
3299+#ifdef SERVER_SUPPORT
3300+ if (use_cvs_acl && server_active)
3301+ {
3302+ if (!access_allowed (finfo->file, finfo->repository, numtag, 4,
3303+ NULL, NULL, 1))
3304+ {
3305+ if (stop_at_first_permission_denied)
3306+ error (1, 0, "permission denied for %s",
3307+ Short_Repository (finfo->repository));
3308+ else
3309+ error (0, 0, "permission denied for %s/%s",
3310+ Short_Repository (finfo->repository), finfo->file);
3311+
3312+ return (0);
3313+ }
3314+ }
3315+#endif
3316+
3317 if (delete_flag)
3318 return (rtag_delete (rcsfile));
3319
3320@@ -880,6 +899,21 @@
3321 if (nversion == NULL)
3322 goto free_vars_and_return;
3323 }
3324+
3325+/* cvsacl patch */
3326+#ifdef SERVER_SUPPORT
3327+ if (use_cvs_acl && server_active)
3328+ {
3329+ if (!access_allowed (finfo->file, finfo->repository, vers->tag, 4,
3330+ NULL, NULL, 1))
3331+ {
3332+ error (0, 0, "permission denied for %s/%s",
3333+ Short_Repository (finfo->repository), finfo->file);
3334+ return (0);
3335+ }
3336+ }
3337+#endif
3338+
3339 if (delete_flag)
3340 {
3341
c52fdbcd 3342diff -urN cvs-1.11.17.orig/src/update.c cvs-1.11.17/src/update.c
3343--- cvs-1.11.17.orig/src/update.c 2004-05-04 19:25:54.000000000 +0200
67ba4c3a 3344+++ cvs-1.11.17/src/update.c 2004-08-04 10:40:18.664719184 +0200
c52fdbcd 3345@@ -596,6 +596,26 @@
09f63587 3346 status = Classify_File (finfo, tag, date, options, force_tag_match,
3347 aflag, &vers, pipeout);
3348
3349+
3350+/* cvsacl patch */
3351+#ifdef SERVER_SUPPORT
3352+ if (use_cvs_acl && server_active)
3353+ {
3354+ if (!access_allowed (finfo->file, finfo->repository, vers->tag, 5,
3355+ NULL, NULL, 1))
3356+ {
3357+ if (stop_at_first_permission_denied)
3358+ error (1, 0, "permission denied for %s",
3359+ Short_Repository (finfo->repository));
3360+ else
3361+ error (0, 0, "permission denied for %s/%s",
3362+ Short_Repository (finfo->repository), finfo->file);
3363+
3364+ return (0);
3365+ }
3366+ }
3367+#endif
3368+
3369 /* Keep track of whether TAG is a branch tag.
3370 Note that if it is a branch tag in some files and a nonbranch tag
3371 in others, treat it as a nonbranch tag. It is possible that case
c52fdbcd 3372diff -urN cvs-1.11.17.orig/src/version.c cvs-1.11.17/src/version.c
3373--- cvs-1.11.17.orig/src/version.c 2004-02-03 15:37:56.000000000 +0100
67ba4c3a 3374+++ cvs-1.11.17/src/version.c 2004-08-04 10:40:18.669718424 +0200
09f63587 3375@@ -26,7 +26,8 @@
3376 #endif
3377 #endif
3378
3379-
3380+/* cvsacl patch */
67ba4c3a 3381+char *aclpatch_string = "with CVSACL Patch 1.2.1 (cvsacl.sourceforge.net)\n";
09f63587 3382
3383 static const char *const version_usage[] =
3384 {
3385@@ -63,6 +64,8 @@
3386 released. */
3387 (void) fputs (PACKAGE_STRING, stdout);
3388 (void) fputs (config_string, stdout);
3389+ /* cvsacl patch */
3390+ (void) fputs (aclpatch_string, stdout);
3391
3392 #ifdef CLIENT_SUPPORT
3393 if (current_parsed_root && current_parsed_root->isremote)
This page took 0.773863 seconds and 4 git commands to generate.