aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--networking/inetd.c288
1 files changed, 146 insertions, 142 deletions
diff --git a/networking/inetd.c b/networking/inetd.c
index 84d15438f..6980a9003 100644
--- a/networking/inetd.c
+++ b/networking/inetd.c
@@ -830,160 +830,164 @@ extern int inetd_main(int argc, char *argv[])
830 } 830 }
831 831
832 for (;;) { 832 for (;;) {
833 int n, ctrl; 833 fd_set readable;
834 fd_set readable; 834 int ctrl;
835 835 int n;
836 if (nsock == 0) { 836
837 sigprocmask(SIG_BLOCK, &blockmask, NULL); 837 if (nsock == 0) {
838 while (nsock == 0) 838 sigprocmask(SIG_BLOCK, &blockmask, NULL);
839 sigsuspend(&emptymask); 839 while (nsock == 0) {
840 sigprocmask(SIG_SETMASK, &emptymask, NULL); 840 sigsuspend(&emptymask);
841 }
842 readable = allsock;
843 if ((n = select(maxsock + 1, &readable, (fd_set *)0,
844 (fd_set *)0, (struct timeval *)0)) <= 0) {
845 if (n < 0 && errno != EINTR)
846 syslog(LOG_WARNING, "select: %m");
847 sleep(1);
848 continue;
849 }
850 for (sep = servtab; n && sep; sep = sep->se_next)
851 if (sep->se_fd != -1 && FD_ISSET(sep->se_fd, &readable)) {
852 n--;
853 if (!sep->se_wait && sep->se_socktype == SOCK_STREAM) {
854 /* Fixed AGC */
855 fcntl(sep->se_fd, F_SETFL, O_NDELAY);
856 /* --------- */
857 ctrl = accept(sep->se_fd, NULL, NULL);
858 fcntl(sep->se_fd, F_SETFL, 0);
859 if (ctrl < 0) {
860 if (errno == EINTR || errno == EWOULDBLOCK)
861 continue;
862 syslog(LOG_WARNING, "accept (for %s): %m",
863 sep->se_service);
864 continue;
865 } 841 }
866 } else 842 sigprocmask(SIG_SETMASK, &emptymask, NULL);
867 ctrl = sep->se_fd; 843 }
868 sigprocmask(SIG_BLOCK, &blockmask, NULL); 844 readable = allsock;
869 pid = 0; 845 n = select(maxsock + 1, &readable, (fd_set *)0, (fd_set *)0, (struct timeval *)0);
846 if (n <= 0) {
847 if (n < 0 && errno != EINTR) {
848 syslog(LOG_WARNING, "select: %m");
849 }
850 sleep(1);
851 continue;
852 }
853 for (sep = servtab; n && sep; sep = sep->se_next) {
854 if (sep->se_fd != -1 && FD_ISSET(sep->se_fd, &readable)) {
855 n--;
856 if (!sep->se_wait && sep->se_socktype == SOCK_STREAM) {
857 /* Fixed AGC */
858 fcntl(sep->se_fd, F_SETFL, O_NDELAY);
859 /* --------- */
860 ctrl = accept(sep->se_fd, NULL, NULL);
861 fcntl(sep->se_fd, F_SETFL, 0);
862 if (ctrl < 0) {
863 if (errno == EINTR || errno == EWOULDBLOCK) {
864 continue;
865 }
866 syslog(LOG_WARNING, "accept (for %s): %m",
867 sep->se_service);
868 continue;
869 }
870 } else {
871 ctrl = sep->se_fd;
872 }
873 sigprocmask(SIG_BLOCK, &blockmask, NULL);
874 pid = 0;
870#ifdef INETD_FEATURE_ENABLED 875#ifdef INETD_FEATURE_ENABLED
871 if (sep->se_bi == 0 || sep->se_bi->bi_fork) 876 if (sep->se_bi == 0 || sep->se_bi->bi_fork)
872#endif 877#endif
873 { 878 {
874 if (sep->se_count++ == 0) 879 if (sep->se_count++ == 0) {
875 (void)gettimeofday(&sep->se_time, (struct timezone *)0); 880 gettimeofday(&sep->se_time, (struct timezone *)0);
876 else if (sep->se_count >= sep->se_max) { 881 }
877 struct timeval now; 882 else if (sep->se_count >= sep->se_max) {
878 883 struct timeval now;
879 (void)gettimeofday(&now, (struct timezone *)0); 884
880 if (now.tv_sec - sep->se_time.tv_sec > 885 gettimeofday(&now, (struct timezone *)0);
881 CNT_INTVL) { 886 if (now.tv_sec - sep->se_time.tv_sec > CNT_INTVL) {
882 sep->se_time = now; 887 sep->se_time = now;
883 sep->se_count = 1; 888 sep->se_count = 1;
884 } else { 889 } else {
885 syslog(LOG_ERR, 890 syslog(LOG_ERR,
886 "%s/%s server failing (looping), service terminated", 891 "%s/%s server failing (looping), service terminated",
887 sep->se_service, sep->se_proto); 892 sep->se_service, sep->se_proto);
888 FD_CLR(sep->se_fd, &allsock); 893 FD_CLR(sep->se_fd, &allsock);
889 (void) close(sep->se_fd); 894 close(sep->se_fd);
890 sep->se_fd = -1; 895 sep->se_fd = -1;
891 sep->se_count = 0; 896 sep->se_count = 0;
892 nsock--; 897 nsock--;
893 sigprocmask(SIG_SETMASK, &emptymask, 898 sigprocmask(SIG_SETMASK, &emptymask, NULL);
894 NULL); 899 if (!timingout) {
895 if (!timingout) { 900 timingout = 1;
896 timingout = 1; 901 alarm(RETRYTIME);
897 alarm(RETRYTIME); 902 }
903 continue;
904 }
905 }
906 pid = fork();
907 if (pid < 0) {
908 syslog(LOG_ERR, "fork: %m");
909 if (sep->se_socktype == SOCK_STREAM) {
910 close(ctrl);
911 }
912 sigprocmask(SIG_SETMASK, &emptymask, NULL);
913 sleep(1);
914 continue;
915 }
916 if (pid && sep->se_wait) {
917 sep->se_wait = pid;
918 FD_CLR(sep->se_fd, &allsock);
919 nsock--;
898 } 920 }
899 continue;
900 } 921 }
901 }
902 pid = fork();
903 if (pid < 0) {
904 syslog(LOG_ERR, "fork: %m");
905 if (sep->se_socktype == SOCK_STREAM)
906 close(ctrl);
907 sigprocmask(SIG_SETMASK, &emptymask, NULL); 922 sigprocmask(SIG_SETMASK, &emptymask, NULL);
908 sleep(1); 923 if (pid == 0) {
909 continue;
910 }
911 if (pid && sep->se_wait) {
912 sep->se_wait = pid;
913 FD_CLR(sep->se_fd, &allsock);
914 nsock--;
915 }
916 }
917 sigprocmask(SIG_SETMASK, &emptymask, NULL);
918 if (pid == 0) {
919#ifdef INETD_FEATURE_ENABLED 924#ifdef INETD_FEATURE_ENABLED
920 if (sep->se_bi) 925 if (sep->se_bi) {
921 (*sep->se_bi->bi_fn)(ctrl, sep); 926 (*sep->se_bi->bi_fn)(ctrl, sep);
922 else 927 } else
923#endif 928#endif
924 { 929 {
925 struct passwd *pwd = getpwnam(sep->se_user); 930 struct passwd *pwd = getpwnam(sep->se_user);
926 if (pwd == NULL) { 931 if (pwd == NULL) {
927 syslog_err_and_discard_dg( 932 syslog_err_and_discard_dg(
928 sep->se_socktype, 933 sep->se_socktype,
929 "getpwnam: %s: No such user", 934 "getpwnam: %s: No such user",
930 sep->se_user); 935 sep->se_user);
931 } 936 }
932 if (sep->se_group && 937 if (sep->se_group && (grp = getgrnam(sep->se_group)) == NULL) {
933 (grp = getgrnam(sep->se_group)) == NULL) { 938 syslog_err_and_discard_dg(sep->se_socktype,
934 syslog_err_and_discard_dg( 939 "getgrnam: %s: No such group", sep->se_group);
935 sep->se_socktype, 940 }
936 "getgrnam: %s: No such group", 941 /*
937 sep->se_group); 942 * Ok. There are four cases here:
938 } 943 * 1. nonroot user, no group specified
939 /* 944 * 2. nonroot user, some group specified
940 * Ok. There are four cases here: 945 * 3. root user, no group specified
941 * 1. nonroot user, no group specified 946 * 4. root user, some group specified
942 * 2. nonroot user, some group specified 947 * In cases 2 and 4 we setgid to the specified
943 * 3. root user, no group specified 948 * group. In cases 1 and 2 we run initgroups
944 * 4. root user, some group specified 949 * to run with the groups of the given user.
945 * In cases 2 and 4 we setgid to the specified 950 * In case 4 we do setgroups to run with the
946 * group. In cases 1 and 2 we run initgroups 951 * given group. In case 3 we do nothing.
947 * to run with the groups of the given user. 952 */
948 * In case 4 we do setgroups to run with the 953 if (pwd->pw_uid) {
949 * given group. In case 3 we do nothing. 954 if (sep->se_group) {
950 */ 955 pwd->pw_gid = grp->gr_gid;
951 if (pwd->pw_uid) { 956 }
952 if (sep->se_group) 957 setgid((gid_t)pwd->pw_gid);
953 pwd->pw_gid = grp->gr_gid; 958 initgroups(pwd->pw_name, pwd->pw_gid);
954 setgid((gid_t)pwd->pw_gid); 959 setuid((uid_t)pwd->pw_uid);
955 initgroups(pwd->pw_name, pwd->pw_gid); 960 } else if (sep->se_group) {
956 setuid((uid_t)pwd->pw_uid); 961 setgid((gid_t)grp->gr_gid);
957 } else if (sep->se_group) { 962 setgroups(1, &grp->gr_gid);
958 setgid((gid_t)grp->gr_gid); 963 }
959 setgroups(1, &grp->gr_gid); 964 dup2(ctrl, 0);
960 } 965 close(ctrl);
961 dup2(ctrl, 0); 966 dup2(0, 1);
962 close(ctrl); 967 dup2(0, 2);
963 dup2(0, 1);
964 dup2(0, 2);
965#ifdef RLIMIT_NOFILE 968#ifdef RLIMIT_NOFILE
966 if (rlim_ofile.rlim_cur != rlim_ofile_cur) { 969 if (rlim_ofile.rlim_cur != rlim_ofile_cur) {
967 if (setrlimit(RLIMIT_NOFILE, 970 if (setrlimit(RLIMIT_NOFILE, &rlim_ofile) < 0) {
968 &rlim_ofile) < 0) 971 syslog(LOG_ERR,"setrlimit: %m");
969 syslog(LOG_ERR,"setrlimit: %m"); 972 }
970 } 973 }
971#endif 974#endif
972 for (ctrl = rlim_ofile_cur-1; --ctrl > 2; ) 975 for (ctrl = rlim_ofile_cur-1; --ctrl > 2; ) {
973 (void)close(ctrl); 976 (void)close(ctrl);
974 977 }
975 memset(&sa, 0, sizeof(sa)); 978 memset(&sa, 0, sizeof(sa));
976 sa.sa_handler = SIG_DFL; 979 sa.sa_handler = SIG_DFL;
977 sigaction(SIGPIPE, &sa, NULL); 980 sigaction(SIGPIPE, &sa, NULL);
978 981
979 execv(sep->se_server, sep->se_argv); 982 execv(sep->se_server, sep->se_argv);
980 syslog_err_and_discard_dg(sep->se_socktype, 983 syslog_err_and_discard_dg(sep->se_socktype, "execv %s: %m", sep->se_server);
981 "execv %s: %m", sep->se_server); 984 }
985 }
986 if (!sep->se_wait && sep->se_socktype == SOCK_STREAM) {
987 close(ctrl);
988 }
982 } 989 }
983 } 990 }
984 if (!sep->se_wait && sep->se_socktype == SOCK_STREAM)
985 close(ctrl);
986 }
987 } 991 }
988} 992}
989 993