Module Name:    src
Committed By:   christos
Date:           Thu Mar  8 20:34:35 UTC 2012

Modified Files:
        src/external/gpl2/xcvs/dist/src: tag.c

Log Message:
- restrict tag command to non-destructive operations for non-admins.
  [deletion, moving is dissallowed]
- add history for tag commands
- cvs acl support


To generate a diff of this commit:
cvs rdiff -u -r1.2 -r1.3 src/external/gpl2/xcvs/dist/src/tag.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/external/gpl2/xcvs/dist/src/tag.c
diff -u src/external/gpl2/xcvs/dist/src/tag.c:1.2 src/external/gpl2/xcvs/dist/src/tag.c:1.3
--- src/external/gpl2/xcvs/dist/src/tag.c:1.2	Fri Apr 10 07:20:30 2009
+++ src/external/gpl2/xcvs/dist/src/tag.c	Thu Mar  8 15:34:35 2012
@@ -18,6 +18,7 @@
  */
 
 #include "cvs.h"
+#include <grp.h>
 #include "save-cwd.h"
 
 static int rtag_proc (int argc, char **argv, char *xwhere,
@@ -106,15 +107,17 @@ static const char *const tag_usage[] =
     NULL
 };
 
-
+char *UserTagOptions = "bcflRrD";
 
 int
 cvstag (int argc, char **argv)
 {
+    struct group *grp;
     bool local = false;			/* recursive by default */
     int c;
     int err = 0;
     bool run_module_prog = true;
+    int only_allowed_options;
 
     is_rtag = (strcmp (cvs_cmd_name, "rtag") == 0);
 
@@ -122,8 +125,11 @@ cvstag (int argc, char **argv)
 	usage (is_rtag ? rtag_usage : tag_usage);
 
     getoptreset ();
+    only_allowed_options = 1;
     while ((c = getopt (argc, argv, is_rtag ? rtag_opts : tag_opts)) != -1)
     {
+	if (!strchr(UserTagOptions, c))
+	    only_allowed_options = 0;
 	switch (c)
 	{
 	    case 'a':
@@ -193,6 +199,42 @@ cvstag (int argc, char **argv)
 	error (0, 0, "warning: -b ignored with -d options");
     RCS_check_tag (symtag);
 
+#ifdef CVS_ADMIN_GROUP
+    if (!only_allowed_options && 
+	(grp = getgrnam(CVS_ADMIN_GROUP)) != NULL)
+    {
+#ifdef HAVE_GETGROUPS
+	gid_t *grps;
+	int i, n;
+
+	/* get number of auxiliary groups */
+	n = getgroups (0, NULL);
+	if (n < 0)
+	    error (1, errno, "unable to get number of auxiliary groups");
+	grps = (gid_t *) xmalloc((n + 1) * sizeof *grps);
+	n = getgroups (n, grps);
+	if (n < 0)
+	    error (1, errno, "unable to get list of auxiliary groups");
+	grps[n] = getgid();
+	for (i = 0; i <= n; i++)
+	    if (grps[i] == grp->gr_gid) break;
+	free (grps);
+	if (i > n)
+	    error (1, 0, "usage is restricted to members of the group %s",
+		   CVS_ADMIN_GROUP);
+#else
+	char *me = getcaller();
+	char **grnam;
+	
+	for (grnam = grp->gr_mem; *grnam; grnam++)
+	    if (strcmp (*grnam, me) == 0) break;
+	if (!*grnam && getgid() != grp->gr_gid)
+	    error (1, 0, "usage is restricted to members of the group %s",
+		   CVS_ADMIN_GROUP);
+#endif
+    }
+#endif /* defined CVS_ADMIN_GROUP */
+
 #ifdef CLIENT_SUPPORT
     if (current_parsed_root->isremote)
     {
@@ -271,6 +313,13 @@ cvstag (int argc, char **argv)
     }
     else
     {
+	int i;
+	for (i = 0; i < argc; i++)
+	{
+	    /* XXX last arg should be repository, but doesn't make sense here */
+	    history_write ('T', (delete_flag ? "D" : (numtag ? numtag :
+			   (date ? date : "A"))), symtag, argv[i], "");
+	}
 	err = rtag_proc (argc + 1, argv - 1, NULL, NULL, NULL, 0, local, NULL,
 			 NULL);
     }
@@ -948,6 +997,25 @@ rtag_fileproc (void *callerdat, struct f
      * correctly without breaking your link!
      */
 
+/* cvsacl patch */
+#ifdef SERVER_SUPPORT
+    if (use_cvs_acl /* && server_active */)
+    {
+	if (!access_allowed (finfo->file, finfo->repository, numtag, 4,
+	    NULL, NULL, 1))
+	{
+	    if (stop_at_first_permission_denied)
+		error (1, 0, "permission denied for %s",
+		       Short_Repository (finfo->repository));
+	    else
+		error (0, 0, "permission denied for %s/%s",
+		       Short_Repository (finfo->repository), finfo->file);
+
+	    return (0);
+	}
+    }
+#endif
+
     if (delete_flag)
     {
 	retval = rtag_delete (rcsfile);
@@ -1167,6 +1235,21 @@ tag_fileproc (void *callerdat, struct fi
         if (!nversion)
 	    goto free_vars_and_return;
     }
+
+/* cvsacl patch */
+#ifdef SERVER_SUPPORT
+	if (use_cvs_acl /* && server_active */)
+	{
+	if (!access_allowed (finfo->file, finfo->repository, vers->tag, 4,
+			     NULL, NULL, 1))
+	{
+	    error (0, 0, "permission denied for %s/%s",
+		   Short_Repository (finfo->repository), finfo->file);
+	    return (0);
+	}
+    }
+#endif
+
     if (delete_flag)
     {
 

Reply via email to