Thu Mar 8 20:41:48 2012 UTC ()
- check return value of write(2)
- add acl support


(christos)
diff -r1.3 -r1.4 src/external/gpl2/xcvs/dist/src/server.c

cvs diff -r1.3 -r1.4 src/external/gpl2/xcvs/dist/src/server.c (expand / switch to unified diff)

--- src/external/gpl2/xcvs/dist/src/server.c 2009/04/10 11:20:30 1.3
+++ src/external/gpl2/xcvs/dist/src/server.c 2012/03/08 20:41:48 1.4
@@ -682,27 +682,28 @@ outbuf_memory_error (struct buffer *buf) @@ -682,27 +682,28 @@ outbuf_memory_error (struct buffer *buf)
682{ 682{
683 static const char msg[] = "E Fatal server error\n\ 683 static const char msg[] = "E Fatal server error\n\
684error ENOMEM Virtual memory exhausted.\n"; 684error ENOMEM Virtual memory exhausted.\n";
685 if (command_pid > 0) 685 if (command_pid > 0)
686 kill (command_pid, SIGTERM); 686 kill (command_pid, SIGTERM);
687 687
688 /* 688 /*
689 * We have arranged things so that printing this now either will 689 * We have arranged things so that printing this now either will
690 * be valid, or the "E fatal error" line will get glommed onto the 690 * be valid, or the "E fatal error" line will get glommed onto the
691 * end of an existing "E" or "M" response. 691 * end of an existing "E" or "M" response.
692 */ 692 */
693 693
694 /* If this gives an error, not much we could do. syslog() it? */ 694 /* If this gives an error, not much we could do. syslog() it? */
695 write (STDOUT_FILENO, msg, sizeof (msg) - 1); 695 if (write (STDOUT_FILENO, msg, sizeof (msg) - 1) == -1)
 696 exit(EXIT_FAILURE);
696# ifdef HAVE_SYSLOG_H 697# ifdef HAVE_SYSLOG_H
697 syslog (LOG_DAEMON | LOG_ERR, "virtual memory exhausted"); 698 syslog (LOG_DAEMON | LOG_ERR, "virtual memory exhausted");
698# endif /* HAVE_SYSLOG_H */ 699# endif /* HAVE_SYSLOG_H */
699 exit (EXIT_FAILURE); 700 exit (EXIT_FAILURE);
700} 701}
701 702
702 703
703 704
704static void 705static void
705input_memory_error (struct buffer *buf) 706input_memory_error (struct buffer *buf)
706{ 707{
707 outbuf_memory_error (buf); 708 outbuf_memory_error (buf);
708} 709}
@@ -967,32 +968,36 @@ error ENOMEM Virtual memory exhausted.\n @@ -967,32 +968,36 @@ error ENOMEM Virtual memory exhausted.\n
967 gzip_level = config->MinCompressionLevel; 968 gzip_level = config->MinCompressionLevel;
968 forced = true; 969 forced = true;
969 } 970 }
970 971
971 if (gzip_level > config->MaxCompressionLevel) 972 if (gzip_level > config->MaxCompressionLevel)
972 { 973 {
973 gzip_level = config->MaxCompressionLevel; 974 gzip_level = config->MaxCompressionLevel;
974 forced = true; 975 forced = true;
975 } 976 }
976 977
977 if (forced && !quiet 978 if (forced && !quiet
978 && alloc_pending_warning (120 + strlen (program_name))) 979 && alloc_pending_warning (120 + strlen (program_name)))
979 sprintf (pending_warning_text, 980 sprintf (pending_warning_text,
980"E %s server: Forcing compression level %d (allowed: %d <= z <= %d).", 981"E %s server: Forcing compression level %d (allowed: %zu <= z <= %zu).",
981 program_name, gzip_level, config->MinCompressionLevel, 982 program_name, gzip_level, config->MinCompressionLevel,
982 config->MaxCompressionLevel); 983 config->MaxCompressionLevel);
983 } 984 }
984 985
985 if (!nolock) { 986 /* cvsacl patch */
 987 parse_aclconfig (current_parsed_root->directory);
 988
 989 if (!nolock)
 990 {
986 path = xmalloc (strlen (current_parsed_root->directory) 991 path = xmalloc (strlen (current_parsed_root->directory)
987 + sizeof (CVSROOTADM) 992 + sizeof (CVSROOTADM)
988 + 2); 993 + 2);
989 if (path == NULL) 994 if (path == NULL)
990 { 995 {
991 pending_error = ENOMEM; 996 pending_error = ENOMEM;
992 return; 997 return;
993 } 998 }
994 (void) sprintf (path, "%s/%s", current_parsed_root->directory, CVSROOTADM); 999 (void) sprintf (path, "%s/%s", current_parsed_root->directory, CVSROOTADM);
995 if (!isaccessible (path, R_OK | X_OK)) 1000 if (!isaccessible (path, R_OK | X_OK))
996 { 1001 {
997 int save_errno = errno; 1002 int save_errno = errno;
998 if (alloc_pending (80 + strlen (path))) 1003 if (alloc_pending (80 + strlen (path)))
@@ -4613,27 +4618,40 @@ static void @@ -4613,27 +4618,40 @@ static void
4613serve_ls (char *arg) 4618serve_ls (char *arg)
4614{ 4619{
4615 do_cvs_command ("ls", ls); 4620 do_cvs_command ("ls", ls);
4616} 4621}
4617 4622
4618 4623
4619 4624
4620static void 4625static void
4621serve_rls (char *arg) 4626serve_rls (char *arg)
4622{ 4627{
4623 do_cvs_command ("rls", ls); 4628 do_cvs_command ("rls", ls);
4624} 4629}
4625 4630
4626 4631/* cvsacl patch */
 4632static void
 4633serve_acl (char *arg)
 4634{
 4635 do_cvs_command ("acl", cvsacl);
 4636}
 4637
 4638/* cvsacl patch */
 4639static void
 4640serve_racl (char *arg)
 4641{
 4642 cvs_cmd_name = "racl";
 4643 do_cvs_command ("racl", cvsacl);
 4644}
4627 4645
4628static void 4646static void
4629serve_add (char *arg) 4647serve_add (char *arg)
4630{ 4648{
4631 do_cvs_command ("add", add); 4649 do_cvs_command ("add", add);
4632} 4650}
4633 4651
4634 4652
4635 4653
4636static void 4654static void
4637serve_remove (char *arg) 4655serve_remove (char *arg)
4638{ 4656{
4639 do_cvs_command ("remove", cvsremove); 4657 do_cvs_command ("remove", cvsremove);
@@ -5478,27 +5496,27 @@ serve_gzip_contents (char *arg) @@ -5478,27 +5496,27 @@ serve_gzip_contents (char *arg)
5478 { 5496 {
5479 level = config->MinCompressionLevel; 5497 level = config->MinCompressionLevel;
5480 forced = true; 5498 forced = true;
5481 } 5499 }
5482 if (config && level > config->MaxCompressionLevel) 5500 if (config && level > config->MaxCompressionLevel)
5483 { 5501 {
5484 level = config->MaxCompressionLevel; 5502 level = config->MaxCompressionLevel;
5485 forced = true; 5503 forced = true;
5486 } 5504 }
5487 5505
5488 if (forced && !quiet 5506 if (forced && !quiet
5489 && alloc_pending_warning (120 + strlen (program_name))) 5507 && alloc_pending_warning (120 + strlen (program_name)))
5490 sprintf (pending_warning_text, 5508 sprintf (pending_warning_text,
5491"E %s server: Forcing compression level %d (allowed: %d <= z <= %d).", 5509"E %s server: Forcing compression level %d (allowed: %zu <= z <= %zu).",
5492 program_name, level, config->MinCompressionLevel, 5510 program_name, level, config->MinCompressionLevel,
5493 config->MaxCompressionLevel); 5511 config->MaxCompressionLevel);
5494 5512
5495 gzip_level = file_gzip_level = level; 5513 gzip_level = file_gzip_level = level;
5496} 5514}
5497 5515
5498 5516
5499 5517
5500static void 5518static void
5501serve_gzip_stream (char *arg) 5519serve_gzip_stream (char *arg)
5502{ 5520{
5503 int level; 5521 int level;
5504 bool forced = false; 5522 bool forced = false;
@@ -5509,27 +5527,27 @@ serve_gzip_stream (char *arg) @@ -5509,27 +5527,27 @@ serve_gzip_stream (char *arg)
5509 { 5527 {
5510 level = config->MinCompressionLevel; 5528 level = config->MinCompressionLevel;
5511 forced = true; 5529 forced = true;
5512 } 5530 }
5513 if (config && level > config->MaxCompressionLevel) 5531 if (config && level > config->MaxCompressionLevel)
5514 { 5532 {
5515 level = config->MaxCompressionLevel; 5533 level = config->MaxCompressionLevel;
5516 forced = true; 5534 forced = true;
5517 } 5535 }
5518 5536
5519 if (forced && !quiet 5537 if (forced && !quiet
5520 && alloc_pending_warning (120 + strlen (program_name))) 5538 && alloc_pending_warning (120 + strlen (program_name)))
5521 sprintf (pending_warning_text, 5539 sprintf (pending_warning_text,
5522"E %s server: Forcing compression level %d (allowed: %d <= z <= %d).", 5540"E %s server: Forcing compression level %d (allowed: %zu <= z <= %zu).",
5523 program_name, level, config->MinCompressionLevel, 5541 program_name, level, config->MinCompressionLevel,
5524 config->MaxCompressionLevel); 5542 config->MaxCompressionLevel);
5525  5543
5526 gzip_level = level; 5544 gzip_level = level;
5527 5545
5528 /* All further communication with the client will be compressed. 5546 /* All further communication with the client will be compressed.
5529 * 5547 *
5530 * The deflate buffers need to be initialized even for compression level 5548 * The deflate buffers need to be initialized even for compression level
5531 * 0, or the client will no longer be able to understand us. At 5549 * 0, or the client will no longer be able to understand us. At
5532 * compression level 0, the correct compression headers will be created and 5550 * compression level 0, the correct compression headers will be created and
5533 * sent, but data will thereafter simply be copied to the network buffers. 5551 * sent, but data will thereafter simply be copied to the network buffers.
5534 */ 5552 */
5535 5553
@@ -5926,26 +5944,31 @@ struct request requests[] = @@ -5926,26 +5944,31 @@ struct request requests[] =
5926 REQ_LINE("Gssapi-encrypt", serve_gssapi_encrypt, RQ_ROOTLESS), 5944 REQ_LINE("Gssapi-encrypt", serve_gssapi_encrypt, RQ_ROOTLESS),
5927# endif 5945# endif
5928#endif 5946#endif
5929#ifdef HAVE_GSSAPI 5947#ifdef HAVE_GSSAPI
5930 REQ_LINE("Gssapi-authenticate", serve_gssapi_authenticate, RQ_ROOTLESS), 5948 REQ_LINE("Gssapi-authenticate", serve_gssapi_authenticate, RQ_ROOTLESS),
5931#endif 5949#endif
5932 REQ_LINE("expand-modules", serve_expand_modules, 0), 5950 REQ_LINE("expand-modules", serve_expand_modules, 0),
5933 REQ_LINE("ci", serve_ci, RQ_ESSENTIAL), 5951 REQ_LINE("ci", serve_ci, RQ_ESSENTIAL),
5934 REQ_LINE("co", serve_co, RQ_ESSENTIAL), 5952 REQ_LINE("co", serve_co, RQ_ESSENTIAL),
5935 REQ_LINE("update", serve_update, RQ_ESSENTIAL), 5953 REQ_LINE("update", serve_update, RQ_ESSENTIAL),
5936 REQ_LINE("diff", serve_diff, 0), 5954 REQ_LINE("diff", serve_diff, 0),
5937 REQ_LINE("log", serve_log, 0), 5955 REQ_LINE("log", serve_log, 0),
5938 REQ_LINE("rlog", serve_rlog, 0), 5956 REQ_LINE("rlog", serve_rlog, 0),
 5957
 5958 /* cvsacl patch */
 5959 REQ_LINE("acl", serve_acl, 0),
 5960 REQ_LINE("racl", serve_racl, 0),
 5961
5939 REQ_LINE("list", serve_ls, 0), 5962 REQ_LINE("list", serve_ls, 0),
5940 REQ_LINE("rlist", serve_rls, 0), 5963 REQ_LINE("rlist", serve_rls, 0),
5941 /* This allows us to avoid sending `-q' as a command argument to `cvs ls', 5964 /* This allows us to avoid sending `-q' as a command argument to `cvs ls',
5942 * or more accurately, allows us to send `-q' to backwards CVSNT servers. 5965 * or more accurately, allows us to send `-q' to backwards CVSNT servers.
5943 */ 5966 */
5944 REQ_LINE("global-list-quiet", serve_noop, RQ_ROOTLESS), 5967 REQ_LINE("global-list-quiet", serve_noop, RQ_ROOTLESS),
5945 /* Deprecated synonym for rlist, for compatibility with CVSNT. */ 5968 /* Deprecated synonym for rlist, for compatibility with CVSNT. */
5946 REQ_LINE("ls", serve_rls, 0), 5969 REQ_LINE("ls", serve_rls, 0),
5947 REQ_LINE("add", serve_add, 0), 5970 REQ_LINE("add", serve_add, 0),
5948 REQ_LINE("remove", serve_remove, 0), 5971 REQ_LINE("remove", serve_remove, 0),
5949 REQ_LINE("update-patches", serve_ignore, 0), 5972 REQ_LINE("update-patches", serve_ignore, 0),
5950 REQ_LINE("gzip-file-contents", serve_gzip_contents, RQ_ROOTLESS), 5973 REQ_LINE("gzip-file-contents", serve_gzip_contents, RQ_ROOTLESS),
5951 REQ_LINE("status", serve_status, 0), 5974 REQ_LINE("status", serve_status, 0),
@@ -6222,27 +6245,28 @@ server_cleanup (void) @@ -6222,27 +6245,28 @@ server_cleanup (void)
6222 while (read (i, buf, sizeof (buf)) >= 1) 6245 while (read (i, buf, sizeof (buf)) >= 1)
6223 ; 6246 ;
6224 } 6247 }
6225 break; 6248 break;
6226 default: 6249 default:
6227 abort (); 6250 abort ();
6228 } 6251 }
6229 } 6252 }
6230 } 6253 }
6231#endif /* SUNOS_KLUDGE */ 6254#endif /* SUNOS_KLUDGE */
6232 6255
6233 /* Make sure our working directory isn't inside the tree we're 6256 /* Make sure our working directory isn't inside the tree we're
6234 going to delete. */ 6257 going to delete. */
6235 CVS_CHDIR (get_cvs_tmp_dir ()); 6258 if (CVS_CHDIR (get_cvs_tmp_dir ()) == -1)
 6259 error (0, errno, "Cannot chdir to `%s'", get_cvs_tmp_dir ());
6236 6260
6237 /* Temporarily clear noexec, so that we clean up our temp directory 6261 /* Temporarily clear noexec, so that we clean up our temp directory
6238 regardless of it (this could more cleanly be handled by moving 6262 regardless of it (this could more cleanly be handled by moving
6239 the noexec check to all the unlink_file_dir callers from 6263 the noexec check to all the unlink_file_dir callers from
6240 unlink_file_dir itself). */ 6264 unlink_file_dir itself). */
6241 save_noexec = noexec; 6265 save_noexec = noexec;
6242 6266
6243 /* SIG_beginCrSect(); */ 6267 /* SIG_beginCrSect(); */
6244 noexec = 0; 6268 noexec = 0;
6245 unlink_file_dir (orig_server_temp_dir); 6269 unlink_file_dir (orig_server_temp_dir);
6246 noexec = save_noexec; 6270 noexec = save_noexec;
6247 /* SIG_endCrSect(); */ 6271 /* SIG_endCrSect(); */
6248 } /* !dont_delete_temp */ 6272 } /* !dont_delete_temp */
@@ -6543,26 +6567,30 @@ switch_to_user (const char *cvs_username @@ -6543,26 +6567,30 @@ switch_to_user (const char *cvs_username
6543 pam_stage = "get pam user"; 6567 pam_stage = "get pam user";
6544 retval = pam_get_item (pamh, PAM_USER, (const void **)&username); 6568 retval = pam_get_item (pamh, PAM_USER, (const void **)&username);
6545 } 6569 }
6546 6570
6547 if (retval != PAM_SUCCESS) 6571 if (retval != PAM_SUCCESS)
6548 { 6572 {
6549 printf("E PAM %s error: %s\n", pam_stage, 6573 printf("E PAM %s error: %s\n", pam_stage,
6550 pam_strerror (pamh, retval)); 6574 pam_strerror (pamh, retval));
6551 exit (EXIT_FAILURE); 6575 exit (EXIT_FAILURE);
6552 } 6576 }
6553 } 6577 }
6554#endif 6578#endif
6555 6579
 6580 /* cvsacl patch */
 6581 if (use_cvs_acl && cvs_server_run_as)
 6582 username = cvs_server_run_as;
 6583
6556 pw = getpwnam (username); 6584 pw = getpwnam (username);
6557 if (pw == NULL) 6585 if (pw == NULL)
6558 { 6586 {
6559 /* check_password contains a similar check, so this usually won't be 6587 /* check_password contains a similar check, so this usually won't be
6560 reached unless the CVS user is mapped to an invalid system user. */ 6588 reached unless the CVS user is mapped to an invalid system user. */
6561 6589
6562 printf ("E Fatal error, aborting.\n\ 6590 printf ("E Fatal error, aborting.\n\
6563error 0 %s: no such system user\n", username); 6591error 0 %s: no such system user\n", username);
6564 exit (EXIT_FAILURE); 6592 exit (EXIT_FAILURE);
6565 } 6593 }
6566 6594
6567 if (pw->pw_uid == 0) 6595 if (pw->pw_uid == 0)
6568 { 6596 {
@@ -7242,26 +7270,29 @@ pserver_authenticate_connection (void) @@ -7242,26 +7270,29 @@ pserver_authenticate_connection (void)
7242# ifdef HAVE_SYSLOG_H 7270# ifdef HAVE_SYSLOG_H
7243 syslog (LOG_DAEMON | LOG_NOTICE, "login refused for %s", repository); 7271 syslog (LOG_DAEMON | LOG_NOTICE, "login refused for %s", repository);
7244# endif /* HAVE_SYSLOG_H */ 7272# endif /* HAVE_SYSLOG_H */
7245 goto i_hate_you; 7273 goto i_hate_you;
7246 } 7274 }
7247 7275
7248 /* OK, now parse the config file, so we can use it to control how 7276 /* OK, now parse the config file, so we can use it to control how
7249 to check passwords. If there was an error parsing the config 7277 to check passwords. If there was an error parsing the config
7250 file, parse_config already printed an error. We keep going. 7278 file, parse_config already printed an error. We keep going.
7251 Why? Because if we didn't, then there would be no way to check 7279 Why? Because if we didn't, then there would be no way to check
7252 in a new CVSROOT/config file to fix the broken one! */ 7280 in a new CVSROOT/config file to fix the broken one! */
7253 config = get_root_allow_config (repository, gConfigPath); 7281 config = get_root_allow_config (repository, gConfigPath);
7254 7282
 7283 /* cvsacl patch */
 7284 parse_aclconfig (repository);
 7285
7255 /* We need the real cleartext before we hash it. */ 7286 /* We need the real cleartext before we hash it. */
7256 descrambled_password = descramble (password); 7287 descrambled_password = descramble (password);
7257 host_user = check_password (username, descrambled_password, repository); 7288 host_user = check_password (username, descrambled_password, repository);
7258 if (host_user == NULL) 7289 if (host_user == NULL)
7259 { 7290 {
7260# ifdef HAVE_SYSLOG_H 7291# ifdef HAVE_SYSLOG_H
7261 syslog (LOG_DAEMON | LOG_NOTICE, "login failure (for %s)", repository); 7292 syslog (LOG_DAEMON | LOG_NOTICE, "login failure (for %s)", repository);
7262# endif /* HAVE_SYSLOG_H */ 7293# endif /* HAVE_SYSLOG_H */
7263 memset (descrambled_password, 0, strlen (descrambled_password)); 7294 memset (descrambled_password, 0, strlen (descrambled_password));
7264 free (descrambled_password); 7295 free (descrambled_password);
7265 i_hate_you: 7296 i_hate_you:
7266 buf_output0 (buf_to_net, "I HATE YOU\n"); 7297 buf_output0 (buf_to_net, "I HATE YOU\n");
7267 buf_flush (buf_to_net, true); 7298 buf_flush (buf_to_net, true);