| @@ -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\ |
684 | error ENOMEM Virtual memory exhausted.\n"; | | 684 | error 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 | |
704 | static void | | 705 | static void |
705 | input_memory_error (struct buffer *buf) | | 706 | input_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 |
4613 | serve_ls (char *arg) | | 4618 | serve_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 | |
4620 | static void | | 4625 | static void |
4621 | serve_rls (char *arg) | | 4626 | serve_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 */ |
| | | 4632 | static void |
| | | 4633 | serve_acl (char *arg) |
| | | 4634 | { |
| | | 4635 | do_cvs_command ("acl", cvsacl); |
| | | 4636 | } |
| | | 4637 | |
| | | 4638 | /* cvsacl patch */ |
| | | 4639 | static void |
| | | 4640 | serve_racl (char *arg) |
| | | 4641 | { |
| | | 4642 | cvs_cmd_name = "racl"; |
| | | 4643 | do_cvs_command ("racl", cvsacl); |
| | | 4644 | } |
4627 | | | 4645 | |
4628 | static void | | 4646 | static void |
4629 | serve_add (char *arg) | | 4647 | serve_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 | |
4636 | static void | | 4654 | static void |
4637 | serve_remove (char *arg) | | 4655 | serve_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 | |
5500 | static void | | 5518 | static void |
5501 | serve_gzip_stream (char *arg) | | 5519 | serve_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\ |
6563 | error 0 %s: no such system user\n", username); | | 6591 | error 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); |