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) {