*** src/ChangeLog.orig Mon Jun 4 13:40:09 2001 --- src/ChangeLog Mon Jun 4 13:40:53 2001 *************** *** 1,0 **** --- 1,6 ---- + 2001-05-30 Tom Lear + + * server.c (server): recognize -d & -r parameters to "cvs server" + (check_command_legal_p): check for SRVARG_RO global variable + (serve_root): check list SRVARG_Roots and possibly disallow access + *** src/server.c.orig Wed May 30 15:23:43 2001 --- src/server.c Wed May 30 15:14:36 2001 *************** *** 141,146 **** --- 141,159 ---- #endif /* AUTH_SERVER_SUPPORT */ + /* This is for the server parameters -d & -r to select cvs root's allowed, and + possible read-only mode */ + struct SRVARG_Root_Elem + { + char *root; + char ro; + struct SRVARG_Root_Elem *next; + }; + + struct SRVARG_Root_Elem *SRVARG_Roots = NULL; + + char SRVARG_RO = 0; + /* While processing requests, this buffer accumulates data to be sent to the client, and then once we are in do_cvs_command, we use it *************** *** 749,757 **** { char *env; char *path; ! if (error_pending()) return; if (!isabsolute (arg)) { if (alloc_pending (80 + strlen (arg))) --- 762,792 ---- { char *env; char *path; ! struct SRVARG_Root_Elem *root_ptr = SRVARG_Roots; ! char root_allowed = 1; ! if (error_pending()) return; + if (SRVARG_Roots) root_allowed=0; + while(root_ptr) + { + if (strcmp(arg, root_ptr->root) == 0) + { + root_allowed=1; + SRVARG_RO=root_ptr->ro; + root_ptr=NULL; + } else { + root_ptr=root_ptr->next; + } + } + if(!root_allowed) + { + if (alloc_pending (80 + strlen (arg))) + sprintf (pending_error_text, + "E Root %s disallowed by server argument", arg); + return; + } + if (!isabsolute (arg)) { if (alloc_pending (80 + strlen (arg))) *************** *** 2451,2456 **** --- 2486,2498 ---- check_command_legal_p (cmd_name) char *cmd_name; { + /* If this Root is considered read-only we may not want to run the command. + */ + if (SRVARG_RO && + lookup_command_attribute (cmd_name) & CVS_CMD_MODIFIES_REPOSITORY) + { + return 0; + } /* Right now, only pserver notices illegal commands -- namely, * write attempts by a read-only user. Therefore, if CVS_Username * is not set, this just returns 1, because CVS_Username unset *************** *** 4908,4913 **** --- 4950,4958 ---- int argc; char **argv; { + struct SRVARG_Root_Elem *root_ptr; + int c; + if (argc == -1) { static const char *const msg[] = *************** *** 4918,4924 **** }; usage (msg); } ! /* Ignore argc and argv. They might be from .cvsrc. */ buf_to_net = fd_buffer_initialize (STDOUT_FILENO, 0, outbuf_memory_error); --- 4963,4991 ---- }; usage (msg); } ! /* parse args */ ! optind = 0; ! while ((c = getopt (argc, argv, "+d:r")) != -1) ! { ! switch(c) ! { ! case 'd': ! root_ptr=malloc(sizeof(struct SRVARG_Root_Elem)); ! root_ptr->root=optarg; ! root_ptr->ro=0; ! root_ptr->next=SRVARG_Roots; ! SRVARG_Roots=root_ptr; ! break; ! case 'r': ! if (SRVARG_Roots) SRVARG_Roots->ro=1; ! break; ! default: ! error_exit (); ! break; ! } ! } ! argc -= optind; ! argv += optind; buf_to_net = fd_buffer_initialize (STDOUT_FILENO, 0, outbuf_memory_error); *** NEWS.orig Mon Jun 4 13:54:41 2001 --- NEWS Mon Jun 4 13:56:04 2001 *************** *** 1,0 **** --- 1,2 ---- + * Added new "cvs server" arguments -d and -r. +