6 * Copyright (c) 1983 The Regents of the University of California.
9 * Redistribution and use in source and binary forms are permitted
10 * provided that the above copyright notice and this paragraph are
11 * duplicated in all such forms and that any documentation,
12 * advertising materials, and other materials related to such
13 * distribution and use acknowledge that the software was developed
14 * by the University of California, Berkeley. The name of the
15 * University may not be used to endorse or promote products derived
16 * from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
19 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
24 "@(#) Copyright (c) 1983 The Regents of the University of California.\n\
25 All rights reserved.\n";
28 /* based on @(#)rshd.c 5.12 (Berkeley) 9/12/88 */
31 * remote shell server:
39 * This is the rshell daemon. The very basic protocol for checking
40 * authentication and authorization is:
41 * 1) Check authentication.
42 * 2) Check authorization via the access-control files:
43 * ~/.k5login (using krb5_kuserok) and/or
44 * ~/.rhosts (using ruserok).
45 * Execute command if configured authoriztion checks pass, else deny
48 * The configuration is done either by command-line arguments passed by inetd,
49 * or by the name of the daemon. If command-line arguments are present, they
50 * take priority. The options are:
51 * -k and -K means check .k5login (using krb5_kuserok).
52 * -r and -R means check .rhosts (using ruserok).
53 * The difference between upper and lower case is as follows:
54 * If lower case -r or -k, then as long as one of krb5_kuserok or ruserok
55 * passes, allow access. If both fail, no access. The program does not fall
56 * back on password verification.
57 * If uppercase -R or -K, then those checks must be passed, regardless of
58 * other checks, else no access.
60 * If no command-line arguments are present, then the presence of the
61 * letters kKrR in the program-name before "shd" determine the
62 * behaviour of the program exactly as with the command-line arguments.
66 * KERBEROS - Define this if application is to be kerberised.
67 * KRB5_KRB4_COMPAT - Define this if v4 rlogin clients are also to be served.
68 * ALWAYS_V5_KUSEROK - Define this if you want .k5login to be
69 * checked even for v4 clients (instead of .klogin).
70 * LOG_ALL_LOGINS - Define this if you want to log all logins.
71 * LOG_OTHER_USERS - Define this if you want to log all principals that do
72 * not map onto the local user.
73 * LOG_REMOTE_REALM - Define this if you want to log all principals from
75 * LOG_CMD - Define this if you want to log not only the user but also the
76 * command executed. This only decides the type of information
77 * logged. Whether or not to log is still decided by the above
79 * Note: Root account access is always logged.
83 #define LOG_REMOTE_REALM
93 #include <sys/unistd.h>
96 #include <sys/types.h>
97 #include <sys/ioctl.h>
98 #include <sys/param.h>
99 #include <sys/socket.h>
100 #include <sys/file.h>
101 #include <sys/time.h>
105 #ifdef HAVE_SYS_SELECT_H
106 #include <sys/select.h>
109 #include <netinet/in.h>
110 #include <arpa/inet.h>
118 #ifdef HAVE_SYS_LABEL_H
120 #include <sys/label.h>
121 #include <sys/audit.h>
132 #include <sys/category.h>
133 #include <netinet/ip.h>
136 #include <sys/secparm.h>
137 #include <sys/usrv.h>
138 #include <sys/utsname.h>
139 #include <sys/sysv.h>
140 #include <sys/slrec.h>
141 #include <sys/unistd.h>
151 #ifdef HAVE_SYS_FILIO_H
152 /* get FIONBIO from sys/filio.h, so what if it is a compatibility feature */
153 #include <sys/filio.h>
157 #include <krb5/krb5.h>
158 #include <krb5/asn1.h>
159 #include <krb5/crc-32.h>
160 #include <krb5/mit-des.h>
161 #include <krb5/ext-proto.h>
164 #include "loginpaths.h"
166 #define ARGSTR "rRxXeEkKD:?"
168 #define SECURE_MESSAGE "This rsh session is using DES encryption for all data transmissions.\r\n"
177 char des_inbuf[2*BUFSIZ]; /* needs to be > largest read size */
178 krb5_encrypt_block eblock; /* eblock for encrypt/decrypt */
179 char des_outbuf[2*BUFSIZ]; /* needs to be > largest write size */
180 krb5_data desinbuf,desoutbuf;
186 int (*des_read)() = v5_des_read;
187 int (*des_write)() = v5_des_write;
192 #else /* !KERBEROS */
194 #define ARGSTR "rRD:?"
195 #define (*des_read) read
196 #define (*des_write) write
198 #endif /* KERBEROS */
201 #define killpg(pid, sig) kill(-(pid), (sig))
204 int must_pass_rhosts = 0, must_pass_k5 = 0, must_pass_one = 0;
208 #define MAX_PROG_NAME 10
221 /* sco has getgroups and setgroups but no initgroups */
222 int initgroups(char* name, gid_t basegid) {
223 gid_t others[NGROUPS_MAX+1];
227 ngrps = getgroups(NGROUPS_MAX, others+1);
228 return setgroups(ngrps+1, others);
237 #if defined(BSD) && BSD+0 >= 43
238 struct linger linger;
241 struct sockaddr_in from;
242 extern int opterr, optind;
251 secflag = sysconf(_SC_CRAY_SECURE_SYS);
256 #ifndef LOG_ODELAY /* 4.2 syslog */
257 openlog(progname, LOG_PID);
262 openlog(progname, LOG_PID | LOG_ODELAY, LOG_DAEMON);
263 #endif /* 4.2 syslog */
265 if (argc == 1) { /* Get parameters from program name. */
266 if (strlen(progname) > MAX_PROG_NAME) {
270 options = (char *) malloc(MAX_PROG_NAME+1);
272 for (i = 0; (progname[i] != '\0') && (i < MAX_PROG_NAME); i++)
273 if (!strcmp(progname+i, "shd")) {
274 strcpy(options, "-");
275 strncat(options, progname, i);
279 * Since we are just going to break out afterwards, we'll
280 * re-use the variable "i" to move the command line args.
282 for (i=argc-1; i>0; i--) argv[i+1] = argv[i];
291 /* Analyze parameters. */
293 while ((ch = getopt(argc, argv, ARGSTR)) != EOF)
296 must_pass_one = 1; /* If just 'r', any one check must succeed */
298 case 'R': /* If 'R', must pass .rhosts check*/
299 must_pass_rhosts = 1;
305 must_pass_one = 1; /* If just 'k', any one check must succeed */
307 case 'K': /* If 'K', must pass .k5login check*/
321 debug_port = atoi(optarg);
338 fromlen = sizeof (from);
342 struct sockaddr_in sin;
344 if ((s = socket(AF_INET, SOCK_STREAM, PF_UNSPEC)) < 0) {
345 fprintf(stderr, "Error in socket: %s\n", strerror(errno));
349 memset((char *) &sin, 0,sizeof(sin));
350 sin.sin_family = AF_INET;
351 sin.sin_port = htons(debug_port);
352 sin.sin_addr.s_addr = INADDR_ANY;
354 if ((bind(s, (struct sockaddr *) &sin, sizeof(sin))) < 0) {
355 fprintf(stderr, "Error in bind: %s\n", strerror(errno));
359 if ((listen(s, 5)) < 0) {
360 fprintf(stderr, "Error in listen: %s\n", strerror(errno));
364 if ((fd = accept(s, &from, &fromlen)) < 0) {
365 fprintf(stderr, "Error in accept: %s\n", strerror(errno));
371 if (getpeername(0, (struct sockaddr *)&from, &fromlen) < 0) {
372 fprintf(stderr, "%s: ", progname);
373 perror("getpeername");
380 if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (char *)&on,
383 "setsockopt (SO_KEEPALIVE): %m");
384 #if defined(BSD) && BSD+0 >= 43
386 linger.l_linger = 60; /* XXX */
387 if (setsockopt(fd, SOL_SOCKET, SO_LINGER, (char *)&linger,
388 sizeof (linger)) < 0)
389 syslog(LOG_WARNING , "setsockopt (SO_LINGER): %m");
391 doit(dup(fd), &from);
395 char username[32] = "LOGNAME=";
397 char tmpdir[64] = "TMPDIR=";
399 char username[20] = "USER=";
402 char homedir[64] = "HOME=";
403 char shell[64] = "SHELL=";
404 char term[64] = "TERM=network";
405 char path[128] = "PATH=";
406 char path_rest[64] = RPATH;
410 {homedir, shell, path, username, "TZ=GMT0", tmpdir, term, 0};
417 {homedir, shell, path, username, term, 0};
420 {homedir, shell, path, username, term, 0};
421 #endif /* KERBEROS */
424 extern char **environ;
425 char ttyn[12]; /* Line string for wtmp entries */
428 #define SIZEOF_INADDR SIZEOF_in_addr
431 #define SIZEOF_INADDR sizeof(struct in_addr)
435 /* linux doesn't seem to have it... */
442 char locuser[NMAX+1];
443 char remuser[NMAX +1];
444 char cmdbuf[NCARGS+1];
446 krb5_principal client;
447 krb5_authenticator *kdata;
449 #ifdef KRB5_KRB4_COMPAT
450 #include <kerberosIV/krb.h>
455 int auth_sys = 0; /* Which version of Kerberos used to authenticate */
457 #define KRB5_RECVAUTH_V4 4
458 #define KRB5_RECVAUTH_V5 5
462 struct sockaddr_in *fromp;
467 krb5_address peeraddr;
468 krb5_error_code status;
474 char *salt, *ttynm, *tty;
482 struct udb ue_static;
483 extern struct udb *getudbnam();
485 extern struct passwd *getpwnam(), *getpwuid();
493 char *makejtmp(), *jtmpnam = 0;
494 int packet_level; /* Packet classification level */
495 long packet_compart; /* Packet compartments */
502 int pv[2], pw[2], px[2], cc;
503 fd_set ready, readfrom;
504 char buf[BUFSIZ], sig;
506 krb5_sigtype cleanup();
508 struct sockaddr_in fromaddr;
509 int non_privileged = 0;
515 /* solaris has IP_TOS, but only IPTOS_* values */
516 #ifdef HAVE_GETTOSBYNAME
519 if ((tp = gettosbyname("interactive", "tcp")) &&
520 (setsockopt(f, IPPROTO_IP, IP_TOS, &tp->t_tos, sizeof(int)) < 0))
522 syslog(LOG_NOTICE, "setsockopt (IP_TOS): %m");
524 ; /* silently ignore TOS errors in 6E */
532 (void)sigemptyset(&sa.sa_mask);
534 sa.sa_handler = SIG_DFL;
535 (void)sigaction(SIGINT, &sa, (struct sigaction *)0);
536 (void)sigaction(SIGQUIT, &sa, (struct sigaction *)0);
537 (void)sigaction(SIGTERM, &sa, (struct sigaction *)0);
539 signal(SIGINT, SIG_DFL);
540 signal(SIGQUIT, SIG_DFL);
541 signal(SIGTERM, SIG_DFL);
544 { int t = open("/dev/tty", 2);
546 ioctl(t, TIOCNOTTY, (char *)0);
551 fromp->sin_port = ntohs((u_short)fromp->sin_port);
552 if (fromp->sin_family != AF_INET) {
553 syslog(LOG_ERR , "malformed from address\n");
559 desinbuf.data = des_inbuf;
560 desoutbuf.data = des_outbuf;
561 if ((must_pass_rhosts || must_pass_one)
562 && (fromp->sin_port >= IPPORT_RESERVED ||
563 fromp->sin_port < IPPORT_RESERVED/2))
566 if (fromp->sin_port >= IPPORT_RESERVED ||
567 fromp->sin_port < IPPORT_RESERVED/2) {
568 syslog(LOG_ERR , "connection from bad port\n");
571 #endif /* KERBEROS */
575 /* If this is a secure system then get the packet classification
576 of f. ( Note IP_SECURITY is checked in get_packet_classification:
577 if it's not set then the user's (root) default
578 classification level and compartments are returned. )
579 Then set this process to that level/compart so that the stderr
580 connection will be labeled appropriately.
583 if (get_packet_classification(f,getuid(),
584 &packet_level,&packet_compart) < 0) {
585 syslog(LOG_ERR, "cannot get ip packet level\n");
588 if(secflag == TFM_UDB_5) {
589 if(setucmp(packet_compart, C_PROC) != 0) {
590 error("Unable to setucmp.\n");
593 } else if(secflag == TFM_UDB_6) {
594 if(setulvl(packet_level,C_PROC) != 0) {
595 error("Unable to setulvl.\n");
598 if(setucmp(packet_compart, C_PROC) != 0) {
599 error("Unable to setucmp.\n");
611 if ((cc = read(f, &c, 1)) != 1) {
613 syslog(LOG_NOTICE , "read: %m");
619 port = port * 10 + c - '0';
623 int lport = IPPORT_RESERVED - 1;
624 s = rresvport(&lport);
627 "can't get stderr port: %m");
631 if ((must_pass_rhosts || must_pass_one)
632 && port >= IPPORT_RESERVED)
635 if (port >= IPPORT_RESERVED) {
636 syslog(LOG_ERR , "2nd port not reserved\n");
639 #endif /* KERBEROS */
640 fromp->sin_port = htons((u_short)port);
641 if (connect(s, (struct sockaddr *)fromp, sizeof (*fromp)) < 0) {
643 "connect second port: %m");
650 hp = gethostbyaddr((char *)&fromp->sin_addr, sizeof (struct in_addr),
653 hostname = malloc(strlen(hp->h_name) + 1);
654 strcpy(hostname,hp->h_name);
657 hostname = malloc(strlen((char *)inet_ntoa(fromp->sin_addr)) + 1);
658 strcpy(hostname,(char *)inet_ntoa(fromp->sin_addr));
660 peeraddr.addrtype = fromp->sin_family;
661 peeraddr.length = SIZEOF_INADDR;
662 peeraddr.contents = (krb5_octet *)&fromp->sin_addr;
666 if (status = recvauth(f, fromaddr, peeraddr)) {
667 error("Authentication failed: %s\n", error_message(status));
670 if (!strncmp(cmdbuf, "-x ", 3))
673 getstr(f, remuser, sizeof(remuser), "remuser");
674 getstr(f, locuser, sizeof(locuser), "locuser");
675 getstr(f, cmdbuf, sizeof(cmdbuf), "command");
676 #endif /* KERBEROS */
679 paddr = inet_addr(inet_ntoa(fromp->sin_addr));
682 * check network authorization list
684 if (fetchnal(paddr,&nal) < 0) {
686 * NAL file inaccessible, abort connection.
688 error("Permission denied.\n");
694 pwd = getpwnam(locuser);
695 if (pwd == (struct passwd *) 0 ) {
697 "Principal %s (%s@%s) for local user %s has no account.\n",
698 kremuser, remuser, hostname, locuser);
699 error("Login incorrect.\n");
704 /* Setup job entry, and validate udb entry.
705 ( against packet level also ) */
706 if ((jid = setjob(pwd->pw_uid, 0)) < 0) {
707 error("Unable to create new job.\n");
710 if ((jtmpnam = makejtmp(pwd->pw_uid, pwd->pw_gid, jid))) {
711 register int pid, tpid;
713 switch(pid = fork()) {
715 cleanjtmp(locuser, jtmpnam);
716 envinit[TMPDIRENV] = 0;
727 while ((tpid = wait(&status)) != pid) {
731 cleanjtmp(locuser, jtmpnam);
736 envinit[TMPDIRENV] = 0;
741 if ((ue = getudbnam(pwd->pw_name)) == (struct udb *)NULL) {
742 error("Unable to fetch account id.\n");
745 ue_static = *ue; /* save from setlimits call */
748 if(getsysv(&sysv, sizeof(struct sysv)) != 0) {
749 loglogin(hostname, SLG_LLERR, 0, ue);
750 error("Permission denied.\n");
753 if ((packet_level != ue->ue_deflvl) ||
754 ((packet_compart & ue->ue_comparts) != packet_compart )){
755 loglogin(hostname, SLG_LLERR, 0, ue);
756 error("Permission denied.\n");
759 if (ue->ue_disabled != 0) {
760 loglogin(hostname,SLG_LOCK,ue->ue_logfails,ue);
761 error("Permission denied.\n");
764 maxlogs = sysv.sy_maxlogs;
766 if (acctid(getpid(), ue->ue_acids[0]) == -1) {
767 error("Unable to set account id.\n");
770 if (setshares(pwd->pw_uid, acctid(0, -1), error, 1, 0)) {
771 error("Unable to set shares.\n");
774 if (setlimits(pwd->pw_name, C_PROC, getpid(), UDBRC_INTER)) {
775 error("Unable to set limits.\n");
778 if (setlimits(pwd->pw_name, C_JOB, jid, UDBRC_INTER)) {
779 error("Unable to set limits.\n");
782 ue = &ue_static; /* restore after setlimits call */
783 endudb(); /* setlimits opens udb and leaves it
784 open so close it here. */
788 /* Setup wtmp entry : we do it here so that if this is a CRAY
789 the Process Id is correct and we have not lost our trusted
792 /* Place entry into wtmp */
793 sprintf(ttyn,"krsh%1d",getpid());
794 logwtmp(ttyn,locuser,hostname,1);
796 /* We are simply execing a program over rshd : log entry into wtmp,
797 as kexe(pid), then finish out the session right after that.
798 Syslog should have the information as to what was exec'd */
800 logwtmp(ttyn,locuser,hostname,1);
805 /* If we are a secure system then we need to get rid of our
806 trusted facility, so that MAC on the chdir we work. Before we
807 do this make an entry into wtmp, and any other audit recording. */
811 syslog(LOG_ERR,"Cannot getusrv");
812 error("Permission denied.\n");
813 loglogin(hostname, SLG_LVERR, ue->ue_logfails,ue);
817 * 6.0 no longer allows any form ofTRUSTED_PROCESS logins.
819 if((ue->ue_valcat & TFM_TRUSTED) ||
821 ((ue->ue_comparts & TRUSTED_SUBJECT) == TRUSTED_SUBJECT))) {
822 loglogin(hostname, SLG_TRSUB, ue->ue_logfails,ue);
823 error("Permission denied.\n");
827 loglogin(hostname, SLG_OKLOG, ue->ue_logfails,ue);
829 /* Setup usrv structure with user udb info and
830 packet_level and packet_compart. */
831 usrv.sv_actlvl = packet_level;
832 usrv.sv_actcmp = packet_compart; /*Note get_packet_level sets
833 compartment to users default
835 usrv.sv_permit = ue->ue_permits;
836 usrv.sv_intcls = ue->ue_intcls;
837 usrv.sv_maxcls = ue->ue_maxcls;
838 usrv.sv_intcat = ue->ue_intcat;
839 usrv.sv_valcat = ue->ue_valcat;
844 * Set user values to workstation boundaries
853 #define MIN(a,b) ((a) < (b) ? (a) : (b))
854 #define MAX(a,b) ((a) > (b) ? (a) : (b))
859 if ((ue->ue_minlvl > nal.na_smax) ||
860 (ue->ue_maxlvl < nal.na_smin))
863 usrv.sv_minlvl=MAX(ue->ue_minlvl, nal.na_smin);
864 usrv.sv_maxlvl=MIN(ue->ue_maxlvl, nal.na_smax);
868 if (usrv.sv_actlvl < usrv.sv_minlvl)
869 usrv.sv_actlvl = usrv.sv_minlvl;
870 if (usrv.sv_actlvl > usrv.sv_maxlvl)
871 usrv.sv_actlvl = usrv.sv_maxlvl;
873 #else /*IP_SECURITY*/
874 if (usrv.sv_actlvl < usrv.sv_minlvl)
876 if (usrv.sv_actlvl > usrv.sv_maxlvl)
878 if (usrv.sv_actlvl != ue->ue_deflvl)
881 usrv.sv_valcmp = ue->ue_comparts & nal.na_scmp;
882 usrv.sv_actcmp &= nal.na_scmp;
883 #endif /*IP_SECURITY*/
884 usrv.sv_valcmp = ue->ue_comparts & nal.na_scmp;
885 usrv.sv_actcmp = (usrv.sv_valcmp &
890 * If the user's minimum level is greater than
891 * zero, they cannot log on from this (ie. an
892 * unclassified) host.
894 if (ue->ue_minlvl > 0)
898 * Address not in NAL, if EXEMPT_NAL is not
899 * true, then even an unclassified user is
913 loglogin(hostname, SLG_LVERR, ue->ue_logfails,ue);
914 error("Permission denied.\n");
919 /* Before the setusrv is done then do a sethost for paddr */
922 if (setusrv(&usrv) == -1) {
923 loglogin(hostname, SLG_LVERR, ue->ue_logfails,ue);
924 error("Permission denied.\n");
927 if (getusrv(&usrv) == -1) {
928 error("Getusrv Permission denied.\n");
935 if (chdir(pwd->pw_dir) < 0) {
937 "Principal %s (%s@%s) for local user %s has no home directory.\n",
938 kremuser, remuser, hostname, locuser);
939 error("No remote directory.\n");
944 if (must_pass_k5 || must_pass_one) {
945 #if defined(KRB5_KRB4_COMPAT) && !defined(ALWAYS_V5_KUSEROK)
946 if (auth_sys == KRB5_RECVAUTH_V4) {
947 /* kuserok returns 0 if OK */
948 if (kuserok(v4_kdata, locuser)){
950 "Principal %s (%s@%s) for local user %s failed kuserok.\n",
951 kremuser, remuser, hostname, locuser);
953 error("Permission denied.\n");
961 /* krb5_kuserok returns 1 if OK */
962 if (!krb5_kuserok(client, locuser)){
964 "Principal %s (%s@%s) for local user %s failed krb5_kuserok.\n",
965 kremuser, remuser, hostname, locuser);
967 error("Permission denied.\n");
975 if (must_pass_rhosts || (failed_k5 && must_pass_one)) {
976 /* Cannot check .rhosts unless connection from privileged port */
977 if (non_privileged) {
978 syslog(LOG_ERR , "connection from bad port\n");
982 if (ruserok(hostname, pwd->pw_uid == 0,
983 remuser, locuser) < 0) {
985 "Principal %s (%s@%s) for local user %s failed ruserok.\n",
986 kremuser, remuser, hostname, locuser);
987 error("Permission denied.\n");
992 if (pwd->pw_passwd != 0 && *pwd->pw_passwd != '\0' &&
993 ruserok(hostname, pwd->pw_uid == 0, remuser, locuser) < 0) {
994 error("Permission denied.\n");
997 #endif /* KERBEROS */
999 if (pwd->pw_uid && !access("/etc/nologin", F_OK)) {
1000 error("Logins currently disabled.\n");
1001 goto signout_please;
1004 /* Log access to account */
1005 pwd = (struct passwd *) getpwnam(locuser);
1006 if (pwd && (pwd->pw_uid == 0)) {
1008 syslog(LOG_NOTICE, "Executing %s for principal %s (%s@%s) as ROOT",
1009 cmdbuf, kremuser, remuser, hostname);
1011 syslog(LOG_NOTICE ,"Access as ROOT by principal %s (%s@%s)",
1012 kremuser, remuser, hostname);
1015 #if defined(KERBEROS) && defined(LOG_REMOTE_REALM) && !defined(LOG_OTHER_USERS) && !defined(LOG_ALL_LOGINS)
1016 /* Log if principal is from a remote realm */
1017 else if (client && !default_realm(client))
1020 #if defined(KERBEROS) && defined(LOG_OTHER_USERS) && !defined(LOG_ALL_LOGINS)
1021 /* Log if principal name does not map to local username */
1022 else if (client && !princ_maps_to_lname(client, locuser))
1023 #endif /* LOG_OTHER_USERS */
1025 #ifdef LOG_ALL_LOGINS /* Log everything */
1029 #if defined(LOG_REMOTE_REALM) || defined(LOG_OTHER_USERS) || defined(LOG_ALL_LOGINS)
1032 syslog(LOG_NOTICE, "Executing %s for principal %s (%s@%s) as local user %s",
1033 cmdbuf, kremuser, remuser, hostname, locuser);
1035 syslog(LOG_NOTICE ,"Access as %s by principal %s (%s@%s)",
1036 locuser, kremuser, remuser, hostname);
1041 (void) write(2, "", 1);
1045 error("Can't make pipe.\n");
1046 goto signout_please;
1049 error("Can't make pipe 2.\n");
1050 goto signout_please;
1053 error("Can't make pipe 3.\n");
1054 goto signout_please;
1058 error("Fork failed.\n");
1059 goto signout_please;
1062 #ifdef POSIX_SIGNALS
1063 sa.sa_handler = cleanup;
1064 (void)sigaction(SIGINT, &sa, (struct sigaction *)0);
1065 (void)sigaction(SIGQUIT, &sa, (struct sigaction *)0);
1066 (void)sigaction(SIGTERM, &sa, (struct sigaction *)0);
1067 (void)sigaction(SIGPIPE, &sa, (struct sigaction *)0);
1068 (void)sigaction(SIGHUP, &sa, (struct sigaction *)0);
1070 sa.sa_handler = SIG_IGN;
1071 (void)sigaction(SIGCHLD, &sa, (struct sigaction *)0);
1073 signal(SIGINT, cleanup);
1074 signal(SIGQUIT, cleanup);
1075 signal(SIGTERM, cleanup);
1076 signal(SIGPIPE, cleanup);
1077 signal(SIGHUP, cleanup);
1078 signal(SIGCHLD,SIG_IGN);
1081 (void) close(0); (void) close(1); (void) close(2);
1082 (void) close(pv[1]);
1083 (void) close(pw[1]);
1084 (void) close(px[0]);
1086 ioctl(pv[0], FIONBIO, (char *)&one);
1087 ioctl(pw[0], FIONBIO, (char *)&one);
1088 /* should set s nbio! */
1091 if (((*des_write)(s, SECURE_MESSAGE, sizeof(SECURE_MESSAGE))) < 0)
1092 fatal(pw[0], "Cannot encrypt-write network.");
1095 FD_SET(f, &readfrom);
1096 FD_SET(s, &readfrom);
1097 FD_SET(pv[0], &readfrom);
1098 FD_SET(pw[0], &readfrom);
1102 if (select(8*sizeof(ready), &ready, (fd_set *)0,
1103 (fd_set *)0, (struct timeval *)0) < 0)
1105 if (FD_ISSET(s, &ready)) {
1106 if ((*des_read)(s, &sig, 1) <= 0)
1107 FD_CLR(s, &readfrom);
1109 #ifdef POSIX_SIGNALS
1110 sa.sa_handler = cleanup;
1111 (void)sigaction(sig, &sa, (struct sigaction *)0);
1114 signal(sig, cleanup);
1119 if (FD_ISSET(f, &ready)) {
1121 cc = (*des_read)(f, buf, sizeof(buf));
1123 (void) close(px[1]);
1124 FD_CLR(f, &readfrom);
1126 (void) write(px[1], buf, cc);
1128 if (FD_ISSET(pv[0], &ready)) {
1130 cc = read(pv[0], buf, sizeof (buf));
1133 FD_CLR(pv[0], &readfrom);
1135 (void) (*des_write)(s, buf, cc);
1137 if (FD_ISSET(pw[0], &ready)) {
1139 cc = read(pw[0], buf, sizeof (buf));
1142 FD_CLR(pw[0], &readfrom);
1144 (void) (*des_write)(f, buf, cc);
1146 } while (FD_ISSET(s, &readfrom) ||
1147 FD_ISSET(f, &readfrom) ||
1148 FD_ISSET(pv[0], &readfrom) ||
1149 FD_ISSET(pw[0], &readfrom));
1152 "Shell process completed.");
1154 /* Finish session in wmtp */
1155 logwtmp(ttyn,"","",0);
1158 #ifdef SETPGRP_TWOARG
1159 setpgrp(0, getpid());
1165 (void) close(pw[0]);
1166 (void) close(pv[0]);
1167 (void) close(px[1]);
1169 (void) dup2(px[0], 0);
1170 (void) dup2(pw[1], 1);
1171 (void) dup2(pv[1], 2);
1173 (void) close(px[0]);
1174 (void) close(pw[1]);
1175 (void) close(pv[1]);
1178 /* We are simply execing a program over rshd : log entry into wtmp,
1179 as kexe(pid), then finish out the session right after that.
1180 Syslog should have the information as to what was exec'd */
1182 logwtmp(ttyn,"","",0);
1185 if (*pwd->pw_shell == '\0')
1186 pwd->pw_shell = "/bin/sh";
1188 (void) setgid((gid_t)pwd->pw_gid);
1190 initgroups(pwd->pw_name, pwd->pw_gid);
1192 (void) setuid((uid_t)pwd->pw_uid);
1194 strncat(homedir, pwd->pw_dir, sizeof(homedir)-6);
1195 strncat(shell, pwd->pw_shell, sizeof(shell)-7);
1196 strncat(username, pwd->pw_name, sizeof(username)-6);
1197 strcat(path, KPROGDIR);
1199 strcat(path, path_rest);
1200 cp = strrchr(pwd->pw_shell, '/');
1206 if (do_encrypt && !strncmp(cmdbuf, "-x ", 3)) {
1207 execl(pwd->pw_shell, cp, "-c", (char *)cmdbuf + 3, 0);
1210 execl(pwd->pw_shell, cp, "-c", cmdbuf, 0);
1212 perror(pwd->pw_shell);
1217 logwtmp(ttyn,"","",0);
1224 error(fmt, a1, a2, a3)
1231 (void) sprintf(buf+1, "%s: ", progname);
1232 (void) sprintf(buf+strlen(buf), fmt, a1, a2, a3);
1233 (void) write(2, buf, strlen(buf));
1234 syslog(LOG_ERR ,"%s",buf+1);
1239 getstr(fd, buf, cnt, err)
1247 if (read(fd, &c, 1) != 1)
1251 error("%s too long\n", err);
1262 #ifdef POSIX_SIGNALS
1263 struct sigaction sa;
1265 (void)sigemptyset(&sa.sa_mask);
1267 sa.sa_handler = SIG_IGN;
1268 (void)sigaction(SIGINT, &sa, (struct sigaction *)0);
1269 (void)sigaction(SIGQUIT, &sa, (struct sigaction *)0);
1270 (void)sigaction(SIGTERM, &sa, (struct sigaction *)0);
1271 (void)sigaction(SIGPIPE, &sa, (struct sigaction *)0);
1272 (void)sigaction(SIGHUP, &sa, (struct sigaction *)0);
1274 (void)kill(-pid, SIGTERM);
1276 signal(SIGINT, SIG_IGN);
1277 signal(SIGQUIT, SIG_IGN);
1278 signal(SIGTERM, SIG_IGN);
1279 signal(SIGPIPE, SIG_IGN);
1280 signal(SIGHUP, SIG_IGN);
1282 killpg(pid, SIGTERM);
1286 logwtmp(ttyn,"","",0);
1287 syslog(LOG_INFO ,"Shell process completed.");
1294 char *makejtmp(uid, gid, jid)
1295 register int uid, gid, jid;
1299 register char *endc, *tdp = &tmpdir[strlen(tmpdir)];
1302 sprintf(tdp, "%s/jtmp.%06d", JTMPDIR, jid);
1303 endc = &tmpdir[strlen(tmpdir)];
1306 for (i = 0; i < 26; i++) {
1308 if (mkdir(tdp, JTMPMODE) != -1) {
1309 chown(tdp, uid, gid);
1311 } else if (errno != EEXIST)
1319 cleanjtmp(user, tpath)
1320 register char *user, *tpath;
1327 execl("/bin/rm", "rm", "-rf", tpath, 0);
1328 error("exec of %s failed; errno = %d\n",
1331 execl(CLEANTMPCMD, CLEANTMPCMD, user, tpath, 0);
1332 error("exec of %s failed; errno = %d\n",
1333 CLEANTMPCMD, errno);
1339 * Just forget about the child, let init will pick it
1348 /***get_packet_classification
1351 * int get_packet_classification():
1352 * Obtain packet level and compartments from passed fd...
1355 * -1: If could not get user defaults.
1359 static int get_packet_classification(fd,useruid,level,comp)
1365 struct socket_security pkt_sec;
1372 udb = getudbuid ((int) useruid);
1374 if (udb == (struct udb *) 0) return(-1);
1375 /* Get packet IP packet label */
1376 sockoptlen = SIZEOF_sec;
1377 if ( getsockopt(fd,SOL_SOCKET,SO_SECURITY,
1378 (char *) &pkt_sec,&sockoptlen)){ /* Failed */
1381 *level = pkt_sec.sec_level;
1382 *comp = udb->ue_defcomps;
1386 #else /* If no IP_SECURITY set level to users default */
1388 static int get_packet_classification(fd,useruid,level,comp)
1396 udb = getudbuid ((int) useruid);
1398 if (udb == (struct udb *) 0) return(-1);
1399 *level = udb->ue_deflvl;
1400 *comp = udb->ue_defcomps;
1404 #endif /* IP_SECURITY */
1409 * Make a security log entry for the login attempt.
1410 * host = pointer to host id
1411 * flag = status of login
1412 * failures = current losing streak in login attempts
1414 /* Make a security log entry for the login attempt.
1415 * host = pointer to host id
1416 * flag = status of login
1417 * failures = current losing streak in login attempts
1420 loglogin(host, flag, failures, ue)
1426 char urec[sizeof(struct slghdr) + sizeof(struct slglogin)];
1427 struct slghdr *uhdr = (struct slghdr *)urec;
1428 struct slglogin *ulogin=(struct slglogin *)&urec[sizeof(struct slghdr)];
1430 strncpy(ulogin->sl_line, ttyn, sizeof(ulogin->sl_line));
1431 strncpy(ulogin->sl_host, host, sizeof(ulogin->sl_host));
1432 ulogin->sl_failures = failures;
1433 if ( maxlogs && (failures >= maxlogs))
1435 ulogin->sl_result = flag;
1436 uhdr->sl_uid = ue->ue_uid;
1437 uhdr->sl_ruid = ue->ue_uid;
1438 uhdr->sl_juid = ue->ue_uid;
1439 uhdr->sl_gid = ue->ue_gids[0];
1440 uhdr->sl_rgid = ue->ue_gids[0];
1441 uhdr->sl_slvl = ue->ue_deflvl;
1442 /* uhdr->sl_scls = ue->ue_defcls; enable for integrity policy */
1444 uhdr->sl_len = sizeof(urec);
1447 slgentry(SLG_LOGN, (word *)urec);
1449 slgentry(SLG_LOGN, (waddr_t)urec);
1461 syslog(LOG_ERR, "usage: kshd [-rRkK] or [r/R][k/K]shd");
1463 syslog(LOG_ERR, "usage: rshd");
1469 int princ_maps_to_lname(principal, luser)
1470 krb5_principal principal;
1474 if (!(krb5_aname_to_localname(principal,
1475 sizeof(kuser), kuser))
1476 && (strcmp(kuser, luser) == 0)) {
1483 int default_realm(principal)
1484 krb5_principal principal;
1490 realm_length = krb5_princ_realm(principal)->length;
1492 if (retval = krb5_get_default_realm(&def_realm)) {
1496 if ((realm_length != strlen(def_realm)) ||
1497 (memcmp(def_realm, krb5_princ_realm(principal)->data, realm_length))) {
1507 #ifndef KRB_SENDAUTH_VLEN
1508 #define KRB_SENDAUTH_VLEN 8 /* length for version strings */
1511 #define KRB_SENDAUTH_VERS "AUTHV0.1" /* MUST be KRB_SENDAUTH_VLEN
1515 recvauth(netf, peersin, peeraddr)
1517 struct sockaddr_in peersin;
1518 krb5_address peeraddr;
1520 krb5_error_code status;
1521 struct sockaddr_in laddr;
1522 char krb_vers[KRB_SENDAUTH_VLEN + 1];
1524 krb5_principal server;
1526 char v4_instance[INST_SZ]; /* V4 Instance */
1528 krb5_ticket *ticket;
1530 len = sizeof(laddr);
1531 if (getsockname(netf, (struct sockaddr *)&laddr, &len)) {
1536 #define SIZEOF_INADDR SIZEOF_in_addr
1538 #define SIZEOF_INADDR sizeof(struct in_addr)
1541 if (status = krb5_sname_to_principal(NULL, "host", KRB5_NT_SRV_HST,
1543 syslog(LOG_ERR, "parse server name %s: %s", "host",
1544 error_message(status));
1548 strcpy(v4_instance, "*");
1550 status = krb5_compat_recvauth(&netf,
1552 server, /* Specify daemon principal */
1553 &peeraddr, /* We do want to match */
1554 /* this against caddrs in */
1556 0, /* use v5srvtab */
1558 0, /* no keyprocarg */
1559 0, /* default rc_type */
1563 "rcmd", /* v4_service */
1564 v4_instance, /* v4_instance */
1565 &peersin, /* foriegn address */
1566 &laddr, /* our local address */
1567 "", /* use default srvtab */
1569 &auth_sys, /* which authentication system */
1570 0, /* no seq number */
1571 &client, /* return client */
1572 &ticket, /* return ticket */
1573 &kdata, /* return authenticator */
1575 &v4_kdata, 0, v4_version);
1578 if (auth_sys == KRB5_RECVAUTH_V5) {
1580 * clean up before exiting
1582 getstr(netf, locuser, sizeof(locuser), "locuser");
1583 getstr(netf, cmdbuf, sizeof(cmdbuf), "command");
1584 getstr(netf, remuser, sizeof(locuser), "remuser");
1589 getstr(netf, locuser, sizeof(locuser), "locuser");
1590 getstr(netf, cmdbuf, sizeof(cmdbuf), "command");
1592 if (auth_sys == KRB5_RECVAUTH_V4) {
1593 /* We do not really know the remote user's login name.
1594 * Assume it to be the same as the first component of the
1597 strcpy(remuser, v4_kdata->pname);
1598 kremuser = (char *) malloc(strlen(v4_kdata->pname) + 1 +
1599 strlen(v4_kdata->pinst) + 1 +
1600 strlen(v4_kdata->prealm) + 1);
1601 sprintf(kremuser, "%s/%s@%s", v4_kdata->pname,
1602 v4_kdata->pinst, v4_kdata->prealm);
1604 if (status = krb5_parse_name(kremuser, &client))
1611 getstr(netf, remuser, sizeof(locuser), "remuser");
1613 if (status = krb5_unparse_name(client, &kremuser))
1616 /* Setup eblock for encrypted sessions. */
1617 krb5_use_keytype(&eblock, ticket->enc_part2->session->keytype);
1618 if (status = krb5_process_key(&eblock, ticket->enc_part2->session))
1619 fatal(netf, "Permission denied");
1621 /* Null out the "session" because eblock.key references the session
1622 * key here, and we do not want krb5_free_ticket() to destroy it. */
1623 ticket->enc_part2->session = 0;
1625 if (status = krb5_read_message((krb5_pointer)&netf, &inbuf)) {
1626 error("Error reading message: %s\n", error_message(status));
1630 if (inbuf.length) { /* Forwarding being done, read creds */
1631 if (status = rd_and_store_for_creds(&inbuf, ticket, locuser)) {
1632 error("Can't get forwarded credentials: %s\n",
1633 error_message(status));
1637 krb5_free_ticket(ticket);
1642 char storage[2*BUFSIZ]; /* storage for the decryption */
1644 char *store_ptr = storage;
1647 v5_des_read(fd, buf, len)
1653 krb5_ui_4 net_len,rd_len;
1655 unsigned char len_buf[4];
1658 return(read(fd, buf, len));
1660 if (nstored >= len) {
1661 memcpy(buf, store_ptr, len);
1665 } else if (nstored) {
1666 memcpy(buf, store_ptr, nstored);
1667 nreturned += nstored;
1673 if ((cc = krb5_net_read(fd, (char *)len_buf, 4)) != 4) {
1674 if ((cc < 0) && ((errno == EWOULDBLOCK) || (errno == EAGAIN)))
1676 /* XXX can't read enough, pipe must have closed */
1684 net_len = krb5_encrypt_size(rd_len, eblock.crypto_entry);
1685 if (net_len < 0 || net_len > sizeof(des_inbuf)) {
1686 /* XXX preposterous length, probably out of sync.
1687 act as if pipe closed */
1688 syslog(LOG_ERR,"Read size problem (rd_len=%d, net_len=%d)",
1694 if ((cc = krb5_net_read(fd, desinbuf.data, net_len)) != net_len) {
1695 /* XXX can't read enough, pipe must have closed */
1696 if ((cc < 0) && ((errno == EWOULDBLOCK) || (errno == EAGAIN))) {
1698 if (retry > MAXRETRIES){
1699 syslog(LOG_ERR, "des_read retry count exceeded %d\n", retry);
1706 "Read data received %d != expected %d.",
1712 if (krb5_decrypt(desinbuf.data, (krb5_pointer) storage, net_len,
1714 syslog(LOG_ERR,"Read decrypt problem.");
1718 store_ptr = storage;
1720 if (nstored > len) {
1721 memcpy(buf, store_ptr, len);
1726 memcpy(buf, store_ptr, nstored);
1727 nreturned += nstored;
1735 v5_des_write(fd, buf, len)
1740 unsigned char len_buf[4];
1743 return(write(fd, buf, len));
1745 desoutbuf.length = krb5_encrypt_size(len, eblock.crypto_entry);
1746 if (desoutbuf.length > sizeof(des_outbuf)){
1747 syslog(LOG_ERR,"Write size problem (%d > %d)",
1748 desoutbuf.length, sizeof(des_outbuf));
1752 if (krb5_encrypt((krb5_pointer)buf, desoutbuf.data, len, &eblock, 0)) {
1753 syslog(LOG_ERR,"Write encrypt problem.");
1757 len_buf[0] = (len & 0xff000000) >> 24;
1758 len_buf[1] = (len & 0xff0000) >> 16;
1759 len_buf[2] = (len & 0xff00) >> 8;
1760 len_buf[3] = (len & 0xff);
1761 (void) write(fd, len_buf, 4);
1763 if (write(fd, desoutbuf.data, desoutbuf.length) != desoutbuf.length){
1764 syslog(LOG_ERR,"Could not write out all data.");
1776 int out = 1 ; /* Output queue of f */
1778 buf[0] = '\01'; /* error indicator */
1779 (void) sprintf(buf + 1, "%s: %s.\r\n",progname, msg);
1780 if ((f == netf) && (pid > 0))
1781 (void) (*des_write)(f, buf, strlen(buf));
1783 (void) write(f, buf, strlen(buf));
1784 syslog(LOG_ERR,"%s\n",msg);
1786 signal(SIGCHLD,SIG_IGN);
1788 #ifdef POSIX_TERMIOS
1789 (void) tcflush(1, TCOFLUSH);
1791 (void) ioctl(f, TIOCFLUSH, (char *)&out);
1797 #endif /* KERBEROS */