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 * Execute command if configured authoriztion checks pass, else deny
47 * The configuration is done either by command-line arguments passed by inetd,
48 * or by the name of the daemon. If command-line arguments are present, they
49 * take priority. The options are:
50 * -k means trust krb4 or krb5
52 * -4 means trust krb4 (using .klogin)
57 * KERBEROS - Define this if application is to be kerberised.
58 * KRB5_KRB4_COMPAT - Define this if v4 rlogin clients are also to be served.
59 * ALWAYS_V5_KUSEROK - Define this if you want .k5login to be
60 * checked even for v4 clients (instead of .klogin).
61 * LOG_ALL_LOGINS - Define this if you want to log all logins.
62 * LOG_OTHER_USERS - Define this if you want to log all principals that do
63 * not map onto the local user.
64 * LOG_REMOTE_REALM - Define this if you want to log all principals from
66 * LOG_CMD - Define this if you want to log not only the user but also the
67 * command executed. This only decides the type of information
68 * logged. Whether or not to log is still decided by the above
70 * Note: Root account access is always logged.
74 #define LOG_REMOTE_REALM
86 #include <sys/unistd.h>
89 #include <sys/types.h>
90 #include <sys/ioctl.h>
91 #include <sys/param.h>
93 /* Ultrix doesn't protect it vs multiple inclusion, and krb.h includes it */
94 #include <sys/socket.h>
102 #ifdef HAVE_SYS_SELECT_H
103 #include <sys/select.h>
106 #include <netinet/in.h>
107 #include <arpa/inet.h>
115 #ifdef HAVE_SYS_LABEL_H
117 #include <sys/label.h>
118 #include <sys/audit.h>
124 /* Ultrix doesn't protect it vs multiple inclusion, and krb.h includes it */
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>
159 #include "loginpaths.h"
160 #ifdef KRB5_KRB4_COMPAT
161 #include <kerberosIV/krb.h>
162 Key_schedule v4_schedule;
165 #define ARGSTR "ek54ciD:S:M:AP:?L:"
172 krb5_context bsd_context;
174 krb5_keytab keytab = NULL;
175 krb5_ccache ccache = NULL;
178 int require_encrypt = 0;
181 char *kprogdir = KPROGDIR;
184 #else /* !KERBEROS */
186 #define ARGSTR "RD:?"
188 #endif /* KERBEROS */
191 #define killpg(pid, sig) kill(-(pid), (sig))
194 /* There are two authentication related masks:
195 * auth_ok and auth_sent.
196 * The auth_ok mask is the oring of authentication systems any one
197 * of which can be used.
198 * The auth_sent mask is the oring of one or more authentication/authorization
199 * systems that succeeded. If the anding
200 * of these two masks is true, then authorization is successful.
202 #define AUTH_KRB4 (0x1)
203 #define AUTH_KRB5 (0x2)
204 int auth_ok = 0, auth_sent = 0;
205 int checksum_required = 0, checksum_ignored = 0;
208 #define MAX_PROG_NAME 10
210 /* Leave room for 4 environment variables to be passed */
212 #define SAVEENVPAD 0,0,0,0 /* padding for envinit slots */
213 char *save_env[MAXENV];
224 void usage(), getstr(), doit();
227 /* sco has getgroups and setgroups but no initgroups */
228 int initgroups(char* name, gid_t basegid) {
229 gid_t others[NGROUPS_MAX+1];
233 ngrps = getgroups(NGROUPS_MAX, others+1);
234 return setgroups(ngrps+1, others);
243 #if defined(BSD) && BSD+0 >= 43
244 struct linger linger;
247 struct sockaddr_in from;
248 extern int opterr, optind;
256 krb5_error_code status;
260 secflag = sysconf(_SC_CRAY_SECURE_SYS);
263 progname = strrchr (*argv, '/');
264 progname = progname ? progname + 1 : *argv;
266 #ifndef LOG_ODELAY /* 4.2 syslog */
267 openlog(progname, LOG_PID);
272 openlog(progname, LOG_PID | LOG_ODELAY, LOG_DAEMON);
273 #endif /* 4.2 syslog */
276 status = krb5_init_context(&bsd_context);
278 syslog(LOG_ERR, "Error initializing krb5: %s",
279 error_message(status));
284 /* Analyze parameters. */
286 while ((ch = getopt(argc, argv, ARGSTR)) != -1)
290 #ifdef KRB5_KRB4_COMPAT
291 auth_ok |= (AUTH_KRB5|AUTH_KRB4);
293 auth_ok |= AUTH_KRB5;
294 #endif /* KRB5_KRB4_COMPAT*/
298 auth_ok |= AUTH_KRB5;
301 checksum_required = 1;
304 checksum_ignored = 1;
307 #ifdef KRB5_KRB4_COMPAT
309 auth_ok |= AUTH_KRB4;
318 if ((status = krb5_kt_resolve(bsd_context, optarg, &keytab))) {
319 com_err(progname, status, "while resolving srvtab file %s",
326 krb5_set_default_realm(bsd_context, optarg);
338 if (num_env < MAXENV) {
339 save_env[num_env] = strdup(optarg);
340 if(!save_env[num_env++]) {
341 com_err(progname, ENOMEM, "in saving environment");
345 fprintf(stderr, "%s: Only %d -L arguments allowed\n",
352 debug_port = atoi(optarg);
369 fromlen = sizeof (from);
373 struct sockaddr_in sin;
375 if ((s = socket(AF_INET, SOCK_STREAM, PF_UNSPEC)) < 0) {
376 fprintf(stderr, "Error in socket: %s\n", strerror(errno));
380 memset((char *) &sin, 0,sizeof(sin));
381 sin.sin_family = AF_INET;
382 sin.sin_port = htons(debug_port);
383 sin.sin_addr.s_addr = INADDR_ANY;
385 (void) setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
386 (char *)&on, sizeof(on));
388 if ((bind(s, (struct sockaddr *) &sin, sizeof(sin))) < 0) {
389 fprintf(stderr, "Error in bind: %s\n", strerror(errno));
393 if ((listen(s, 5)) < 0) {
394 fprintf(stderr, "Error in listen: %s\n", strerror(errno));
398 if ((fd = accept(s, (struct sockaddr *) &from, &fromlen)) < 0) {
399 fprintf(stderr, "Error in accept: %s\n", strerror(errno));
405 if (getpeername(0, (struct sockaddr *)&from, &fromlen) < 0) {
406 fprintf(stderr, "%s: ", progname);
407 perror("getpeername");
414 if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (char *)&on,
416 syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m");
417 #if defined(BSD) && BSD+0 >= 43
419 linger.l_linger = 60; /* XXX */
420 if (setsockopt(fd, SOL_SOCKET, SO_LINGER, (char *)&linger,
421 sizeof (linger)) < 0)
422 syslog(LOG_WARNING , "setsockopt (SO_LINGER): %m");
425 if (checksum_required&&checksum_ignored) {
426 syslog(LOG_CRIT, "Checksums are required and ignored; these options are mutually exclusive--check the documentation.");
427 fatal(fd, "Configuration error: mutually exclusive options specified");
430 doit(dup(fd), &from);
435 char username[32] = "LOGNAME=";
437 char tmpdir[64] = "TMPDIR=";
439 char username[20] = "USER=";
442 char homedir[64] = "HOME=";
443 char shell[64] = "SHELL=";
444 char term[64] = "TERM=network";
445 char path_rest[] = RPATH;
447 char remote_addr[64]; /* = "KRB5REMOTEADDR=" */
448 char remote_port[64]; /* = "KRB5REMOTEPORT=" */
449 char local_addr[64]; /* = "KRB5LOCALADDR=" */
450 char local_port[64]; /* = "KRB5LOCALPORT=" */
451 #define ADDRPAD 0,0,0,0
452 #define KRBPAD 0 /* KRB5CCNAME, optional */
454 /* The following include extra space for TZ and MAXENV pointers... */
455 #define COMMONVARS homedir, shell, 0/*path*/, username, term
458 {COMMONVARS, "TZ=GMT0", tmpdir, SAVEENVPAD, KRBPAD, ADDRPAD, 0};
464 {COMMONVARS, 0/*tz*/, SAVEENVPAD, KRBPAD, ADDRPAD, 0};
467 {COMMONVARS, 0/*tz*/, SAVEENVPAD, ADDRPAD, 0};
468 #endif /* KERBEROS */
474 extern char **environ;
475 char ttyn[12]; /* Line string for wtmp entries */
478 #define SIZEOF_INADDR SIZEOF_in_addr
481 #define SIZEOF_INADDR sizeof(struct in_addr)
485 /* linux doesn't seem to have it... */
492 char locuser[NMAX+1];
493 char remuser[NMAX +1];
494 char cmdbuf[NCARGS+1];
496 krb5_principal client;
497 krb5_authenticator *kdata;
502 int auth_sys = 0; /* Which version of Kerberos used to authenticate */
504 #define KRB5_RECVAUTH_V4 4
505 #define KRB5_RECVAUTH_V5 5
514 (void)sigemptyset(&sa.sa_mask);
516 sa.sa_handler = SIG_IGN;
517 (void)sigaction(SIGINT, &sa, (struct sigaction *)0);
518 (void)sigaction(SIGQUIT, &sa, (struct sigaction *)0);
519 (void)sigaction(SIGTERM, &sa, (struct sigaction *)0);
520 (void)sigaction(SIGPIPE, &sa, (struct sigaction *)0);
521 (void)sigaction(SIGHUP, &sa, (struct sigaction *)0);
523 (void)kill(-pid, SIGTERM);
525 signal(SIGINT, SIG_IGN);
526 signal(SIGQUIT, SIG_IGN);
527 signal(SIGTERM, SIG_IGN);
528 signal(SIGPIPE, SIG_IGN);
529 signal(SIGHUP, SIG_IGN);
531 killpg(pid, SIGTERM);
535 pty_logwtmp(ttyn,"","");
536 syslog(LOG_INFO ,"Daemon terminated via signal %d.", signumber);
538 krb5_cc_destroy(bsd_context, ccache);
545 struct sockaddr_in *fromp;
549 krb5_error_code status;
560 struct udb ue_static;
561 extern struct udb *getudbnam();
563 extern struct passwd *getpwnam(), *getpwuid();
571 char *makejtmp(), *jtmpnam = 0;
572 int packet_level; /* Packet classification level */
573 long packet_compart; /* Packet compartments */
580 int pv[2], pw[2], px[2], cc;
581 fd_set ready, readfrom;
582 char buf[RCMD_BUFSIZ], sig;
583 struct sockaddr_in fromaddr;
584 struct sockaddr_in localaddr;
585 int non_privileged = 0;
591 /* solaris has IP_TOS, but only IPTOS_* values */
592 #ifdef HAVE_GETTOSBYNAME
595 if ((tp = gettosbyname("interactive", "tcp")) &&
596 (setsockopt(f, IPPROTO_IP, IP_TOS, &tp->t_tos, sizeof(int)) < 0))
598 syslog(LOG_NOTICE, "setsockopt (IP_TOS): %m");
600 ; /* silently ignore TOS errors in 6E */
606 int sin_len = sizeof (struct sockaddr_in);
607 if (getsockname(f, &localaddr, &sin_len) < 0) {
608 perror("getsockname");
615 (void)sigemptyset(&sa.sa_mask);
617 sa.sa_handler = SIG_DFL;
618 (void)sigaction(SIGINT, &sa, (struct sigaction *)0);
619 (void)sigaction(SIGQUIT, &sa, (struct sigaction *)0);
620 (void)sigaction(SIGTERM, &sa, (struct sigaction *)0);
622 signal(SIGINT, SIG_DFL);
623 signal(SIGQUIT, SIG_DFL);
624 signal(SIGTERM, SIG_DFL);
627 { int t = open("/dev/tty", 2);
629 ioctl(t, TIOCNOTTY, (char *)0);
634 fromp->sin_port = ntohs((u_short)fromp->sin_port);
635 if (fromp->sin_family != AF_INET) {
636 syslog(LOG_ERR , "malformed from address\n");
641 if ( (fromp->sin_port >= IPPORT_RESERVED ||
642 fromp->sin_port < IPPORT_RESERVED/2))
645 if (fromp->sin_port >= IPPORT_RESERVED ||
646 fromp->sin_port < IPPORT_RESERVED/2) {
647 syslog(LOG_ERR , "connection from bad port\n");
650 #endif /* KERBEROS */
654 /* If this is a secure system then get the packet classification
655 of f. ( Note IP_SECURITY is checked in get_packet_classification:
656 if it's not set then the user's (root) default
657 classification level and compartments are returned. )
658 Then set this process to that level/compart so that the stderr
659 connection will be labeled appropriately.
662 if (get_packet_classification(f,getuid(),
663 &packet_level,&packet_compart) < 0) {
664 syslog(LOG_ERR, "cannot get ip packet level\n");
667 if(secflag == TFM_UDB_5) {
668 if(setucmp(packet_compart, C_PROC) != 0) {
669 error("Unable to setucmp.\n");
672 } else if(secflag == TFM_UDB_6) {
673 if(setulvl(packet_level,C_PROC) != 0) {
674 error("Unable to setulvl.\n");
677 if(setucmp(packet_compart, C_PROC) != 0) {
678 error("Unable to setucmp.\n");
690 if ((cc = read(f, &c, 1)) != 1) {
692 syslog(LOG_NOTICE , "read: %m");
698 port = port * 10 + c - '0';
705 int lport = IPPORT_RESERVED - 1;
706 s = rresvport(&lport);
710 "can't get stderr port: %m");
714 if ( port >= IPPORT_RESERVED)
717 if (port >= IPPORT_RESERVED) {
718 syslog(LOG_ERR , "2nd port not reserved\n");
721 #endif /* KERBEROS */
722 fromp->sin_port = htons((u_short)port);
723 if (connect(s, (struct sockaddr *)fromp, sizeof (*fromp)) < 0) {
725 "connect second port: %m");
732 hp = gethostbyaddr((char *)&fromp->sin_addr, sizeof (struct in_addr),
735 hostname = malloc(strlen(hp->h_name) + 1);
736 strcpy(hostname,hp->h_name);
739 hostname = malloc(strlen((char *)inet_ntoa(fromp->sin_addr)) + 1);
740 strcpy(hostname,(char *)inet_ntoa(fromp->sin_addr));
744 if ((status = recvauth(f, fromaddr,&valid_checksum))) {
745 error("Authentication failed: %s\n", error_message(status));
749 getstr(f, remuser, sizeof(remuser), "remuser");
750 getstr(f, locuser, sizeof(locuser), "locuser");
751 getstr(f, cmdbuf, sizeof(cmdbuf), "command");
752 rcmd_stream_init_normal();
753 #endif /* KERBEROS */
756 paddr = inet_addr(inet_ntoa(fromp->sin_addr));
759 * check network authorization list
761 if (fetchnal(paddr,&nal) < 0) {
763 * NAL file inaccessible, abort connection.
765 error("Permission denied.\n");
771 pwd = getpwnam(locuser);
772 if (pwd == (struct passwd *) 0 ) {
774 "Principal %s (%s@%s) for local user %s has no account.\n",
775 kremuser, remuser, hostname, locuser); /* xxx sprintf buffer in syslog*/
776 error("Login incorrect.\n");
781 /* Setup job entry, and validate udb entry.
782 ( against packet level also ) */
783 if ((jid = setjob(pwd->pw_uid, 0)) < 0) {
784 error("Unable to create new job.\n");
787 if ((jtmpnam = makejtmp(pwd->pw_uid, pwd->pw_gid, jid))) {
788 register int pid, tpid;
790 switch(pid = fork()) {
792 cleanjtmp(locuser, jtmpnam);
793 envinit[TMPDIRENV] = 0;
804 while ((tpid = wait(&status)) != pid) {
808 cleanjtmp(locuser, jtmpnam);
813 envinit[TMPDIRENV] = 0;
818 if ((ue = getudbnam(pwd->pw_name)) == (struct udb *)NULL) {
819 error("Unable to fetch account id.\n");
822 ue_static = *ue; /* save from setlimits call */
825 if(getsysv(&sysv, sizeof(struct sysv)) != 0) {
826 loglogin(hostname, SLG_LLERR, 0, ue);
827 error("Permission denied.\n");
830 if ((packet_level != ue->ue_deflvl) ||
831 ((packet_compart & ue->ue_comparts) != packet_compart )){
832 loglogin(hostname, SLG_LLERR, 0, ue);
833 error("Permission denied.\n");
836 if (ue->ue_disabled != 0) {
837 loglogin(hostname,SLG_LOCK,ue->ue_logfails,ue);
838 error("Permission denied.\n");
841 maxlogs = sysv.sy_maxlogs;
843 if (acctid(getpid(), ue->ue_acids[0]) == -1) {
844 error("Unable to set account id.\n");
847 if (setshares(pwd->pw_uid, acctid(0, -1), error, 1, 0)) {
848 error("Unable to set shares.\n");
851 if (setlimits(pwd->pw_name, C_PROC, getpid(), UDBRC_INTER)) {
852 error("Unable to set limits.\n");
855 if (setlimits(pwd->pw_name, C_JOB, jid, UDBRC_INTER)) {
856 error("Unable to set limits.\n");
859 ue = &ue_static; /* restore after setlimits call */
860 endudb(); /* setlimits opens udb and leaves it
861 open so close it here. */
865 /* Setup wtmp entry : we do it here so that if this is a CRAY
866 the Process Id is correct and we have not lost our trusted
869 /* Place entry into wtmp */
870 sprintf(ttyn,"krsh%1d",getpid());
871 pty_logwtmp(ttyn,locuser,hostname);
873 /* We are simply execing a program over rshd : log entry into wtmp,
874 as kexe(pid), then finish out the session right after that.
875 Syslog should have the information as to what was exec'd */
877 pty_logwtmp(ttyn,locuser,hostname);
882 /* If we are a secure system then we need to get rid of our
883 trusted facility, so that MAC on the chdir we work. Before we
884 do this make an entry into wtmp, and any other audit recording. */
888 syslog(LOG_ERR,"Cannot getusrv");
889 error("Permission denied.\n");
890 loglogin(hostname, SLG_LVERR, ue->ue_logfails,ue);
894 * 6.0 no longer allows any form ofTRUSTED_PROCESS logins.
896 if((ue->ue_valcat & TFM_TRUSTED) ||
898 ((ue->ue_comparts & TRUSTED_SUBJECT) == TRUSTED_SUBJECT))) {
899 loglogin(hostname, SLG_TRSUB, ue->ue_logfails,ue);
900 error("Permission denied.\n");
904 loglogin(hostname, SLG_OKLOG, ue->ue_logfails,ue);
906 /* Setup usrv structure with user udb info and
907 packet_level and packet_compart. */
908 usrv.sv_actlvl = packet_level;
909 usrv.sv_actcmp = packet_compart; /*Note get_packet_level sets
910 compartment to users default
912 usrv.sv_permit = ue->ue_permits;
913 usrv.sv_intcls = ue->ue_intcls;
914 usrv.sv_maxcls = ue->ue_maxcls;
915 usrv.sv_intcat = ue->ue_intcat;
916 usrv.sv_valcat = ue->ue_valcat;
921 * Set user values to workstation boundaries
930 #define MIN(a,b) ((a) < (b) ? (a) : (b))
931 #define MAX(a,b) ((a) > (b) ? (a) : (b))
936 if ((ue->ue_minlvl > nal.na_smax) ||
937 (ue->ue_maxlvl < nal.na_smin))
940 usrv.sv_minlvl=MAX(ue->ue_minlvl, nal.na_smin);
941 usrv.sv_maxlvl=MIN(ue->ue_maxlvl, nal.na_smax);
945 if (usrv.sv_actlvl < usrv.sv_minlvl)
946 usrv.sv_actlvl = usrv.sv_minlvl;
947 if (usrv.sv_actlvl > usrv.sv_maxlvl)
948 usrv.sv_actlvl = usrv.sv_maxlvl;
950 #else /*IP_SECURITY*/
951 if (usrv.sv_actlvl < usrv.sv_minlvl)
953 if (usrv.sv_actlvl > usrv.sv_maxlvl)
955 if (usrv.sv_actlvl != ue->ue_deflvl)
958 usrv.sv_valcmp = ue->ue_comparts & nal.na_scmp;
959 usrv.sv_actcmp &= nal.na_scmp;
960 #endif /*IP_SECURITY*/
961 usrv.sv_valcmp = ue->ue_comparts & nal.na_scmp;
962 usrv.sv_actcmp = (usrv.sv_valcmp &
967 * If the user's minimum level is greater than
968 * zero, they cannot log on from this (ie. an
969 * unclassified) host.
971 if (ue->ue_minlvl > 0)
974 * Address not in NAL, if EXEMPT_NAL is not
975 * true, then even an unclassified user is
989 loglogin(hostname, SLG_LVERR, ue->ue_logfails,ue);
990 error("Permission denied.\n");
995 /* Before the setusrv is done then do a sethost for paddr */
998 if (setusrv(&usrv) == -1) {
999 loglogin(hostname, SLG_LVERR, ue->ue_logfails,ue);
1000 error("Permission denied.\n");
1001 goto signout_please;
1003 if (getusrv(&usrv) == -1) {
1004 error("Getusrv Permission denied.\n");
1005 goto signout_please;
1011 if (chdir(pwd->pw_dir) < 0) {
1012 if(chdir("/") < 0) {
1013 error("No remote directory.\n");
1014 goto signout_please;
1021 #if defined(KRB5_KRB4_COMPAT) && !defined(ALWAYS_V5_KUSEROK)
1022 if (auth_sys == KRB5_RECVAUTH_V4) {
1023 /* kuserok returns 0 if OK */
1024 if (kuserok(v4_kdata, locuser)){
1026 "Principal %s (%s@%s) for local user %s failed kuserok.\n",
1027 kremuser, remuser, hostname, locuser);
1029 else auth_sent |= AUTH_KRB4;
1033 /* krb5_kuserok returns 1 if OK */
1034 if (!krb5_kuserok(bsd_context, client, locuser)){
1036 "Principal %s (%s@%s) for local user %s failed krb5_kuserok.\n",
1037 kremuser, remuser, hostname, locuser);
1041 ((auth_sys == KRB5_RECVAUTH_V4) ? AUTH_KRB4 : AUTH_KRB5);
1046 if (pwd->pw_passwd != 0 && *pwd->pw_passwd != '\0' &&
1047 ruserok(hostname, pwd->pw_uid == 0, remuser, locuser) < 0) {
1048 error("Permission denied.\n");
1049 goto signout_please;
1051 #endif /* KERBEROS */
1054 if (checksum_required && !valid_checksum) {
1055 if (auth_sent & AUTH_KRB5) {
1056 syslog(LOG_WARNING, "Client did not supply required checksum--connection rejected.");
1057 error( "You are using an old Kerberos5 client without checksum support; only newer clients are authorized.\n");
1058 goto signout_please;
1061 "Configuration error: Requiring checksums with -c is inconsistent with allowing Kerberos V4 connections.");
1064 if (require_encrypt&&(!do_encrypt)) {
1065 error("You must use encryption.\n");
1066 goto signout_please;
1068 if (!(auth_ok&auth_sent)) {
1070 error("Another authentication mechanism must be used to access this host.\n");
1072 error("Permission denied.\n");
1073 goto signout_please;
1076 if (pwd->pw_uid && !access("/etc/nologin", F_OK)) {
1077 error("Logins currently disabled.\n");
1078 goto signout_please;
1081 /* Log access to account */
1082 pwd = (struct passwd *) getpwnam(locuser);
1083 if (pwd && (pwd->pw_uid == 0)) {
1085 syslog(LOG_NOTICE, "Executing %s for principal %s (%s@%s) as ROOT",
1086 cmdbuf, kremuser, remuser, hostname);
1088 syslog(LOG_NOTICE ,"Access as ROOT by principal %s (%s@%s)",
1089 kremuser, remuser, hostname);
1092 #if defined(KERBEROS) && defined(LOG_REMOTE_REALM) && !defined(LOG_OTHER_USERS) && !defined(LOG_ALL_LOGINS)
1093 /* Log if principal is from a remote realm */
1094 else if (client && !default_realm(client))
1097 #if defined(KERBEROS) && defined(LOG_OTHER_USERS) && !defined(LOG_ALL_LOGINS)
1098 /* Log if principal name does not map to local username */
1099 else if (client && !princ_maps_to_lname(client, locuser))
1100 #endif /* LOG_OTHER_USERS */
1102 #ifdef LOG_ALL_LOGINS /* Log everything */
1106 #if defined(LOG_REMOTE_REALM) || defined(LOG_OTHER_USERS) || defined(LOG_ALL_LOGINS)
1109 syslog(LOG_NOTICE, "Executing %s for principal %s (%s@%s) as local user %s",
1110 cmdbuf, kremuser, remuser, hostname, locuser);
1112 syslog(LOG_NOTICE ,"Access as %s by principal %s (%s@%s)",
1113 locuser, kremuser, remuser, hostname);
1118 (void) write(2, "", 1);
1120 if (port||do_encrypt) {
1121 if (port&&(pipe(pv) < 0)) {
1122 error("Can't make pipe.\n");
1123 goto signout_please;
1126 error("Can't make pipe 2.\n");
1127 goto signout_please;
1130 error("Can't make pipe 3.\n");
1131 goto signout_please;
1135 error("Fork failed.\n");
1136 goto signout_please;
1139 #ifdef POSIX_SIGNALS
1140 sa.sa_handler = cleanup;
1141 (void)sigaction(SIGINT, &sa, (struct sigaction *)0);
1142 (void)sigaction(SIGQUIT, &sa, (struct sigaction *)0);
1143 (void)sigaction(SIGTERM, &sa, (struct sigaction *)0);
1144 (void)sigaction(SIGHUP, &sa, (struct sigaction *)0);
1146 sa.sa_handler = SIG_IGN;
1147 /* SIGPIPE is a crutch that we don't need if we check
1148 the exit status of write. */
1149 (void)sigaction(SIGPIPE, &sa, (struct sigaction *)0);
1150 (void)sigaction(SIGCHLD, &sa, (struct sigaction *)0);
1152 signal(SIGINT, cleanup);
1153 signal(SIGQUIT, cleanup);
1154 signal(SIGTERM, cleanup);
1155 signal(SIGHUP, cleanup);
1156 /* SIGPIPE is a crutch that we don't need if we check
1157 the exit status of write. */
1158 signal(SIGPIPE, SIG_IGN);
1159 signal(SIGCHLD,SIG_IGN);
1162 (void) close(0); (void) close(1); (void) close(2);
1164 (void) close(pv[1]);
1165 (void) close(pw[1]);
1166 (void) close(px[0]);
1171 FD_SET(f, &readfrom);
1173 FD_SET(s, &readfrom);
1175 FD_SET(pv[0], &readfrom);
1176 FD_SET(pw[0], &readfrom);
1178 /* read from f, write to px[1] -- child stdin */
1179 /* read from s, signal child */
1180 /* read from pv[0], write to s -- child stderr */
1181 /* read from pw[0], write to f -- child stdout */
1185 if (select(8*sizeof(ready), &ready, (fd_set *)0,
1186 (fd_set *)0, (struct timeval *)0) < 0) {
1187 if (errno == EINTR) {
1194 if (port&&FD_ISSET(pv[0], &ready)) {
1195 /* read from the child stderr, write to the net */
1197 cc = read(pv[0], buf, sizeof (buf));
1200 FD_CLR(pv[0], &readfrom);
1202 (void) rcmd_stream_write(s, buf, cc);
1205 if (FD_ISSET(pw[0], &ready)) {
1206 /* read from the child stdout, write to the net */
1208 cc = read(pw[0], buf, sizeof (buf));
1211 FD_CLR(pw[0], &readfrom);
1213 (void) rcmd_stream_write(f, buf, cc);
1216 if (port&&FD_ISSET(s, &ready)) {
1217 /* read from the alternate channel, signal the child */
1218 if (rcmd_stream_read(s, &sig, 1) <= 0) {
1219 FD_CLR(s, &readfrom);
1221 #ifdef POSIX_SIGNALS
1222 sa.sa_handler = cleanup;
1223 (void)sigaction(sig, &sa, (struct sigaction *)0);
1226 signal(sig, cleanup);
1231 if (FD_ISSET(f, &ready)) {
1232 /* read from the net, write to child stdin */
1234 cc = rcmd_stream_read(f, buf, sizeof(buf));
1236 (void) close(px[1]);
1237 FD_CLR(f, &readfrom);
1240 wcc = write(px[1], buf, cc);
1242 /* pipe closed, don't read any more */
1243 /* might check for EPIPE */
1244 (void) close(px[1]);
1245 FD_CLR(f, &readfrom);
1246 } else if (wcc != cc) {
1247 syslog(LOG_INFO, "only wrote %d/%d to child",
1252 } while ((port&&FD_ISSET(s, &readfrom)) ||
1253 FD_ISSET(f, &readfrom) ||
1254 (port&&FD_ISSET(pv[0], &readfrom) )||
1255 FD_ISSET(pw[0], &readfrom));
1258 "Shell process completed.");
1260 /* Finish session in wmtp */
1261 pty_logwtmp(ttyn,"","");
1263 krb5_cc_destroy(bsd_context, ccache);
1266 #if defined(HAVE_SETSID)&&(!defined(ULTRIX))
1269 #ifdef SETPGRP_TWOARG
1270 setpgrp(0, getpid());
1273 #endif /*setpgrp_twoarg*/
1274 #endif /*HAVE_SETSID*/
1277 (void) close(pw[0]);
1279 (void) close(pv[0]);
1280 (void) close(px[1]);
1282 (void) dup2(px[0], 0);
1283 (void) dup2(pw[1], 1);
1285 (void) dup2(pv[1], 2);
1286 else dup2(pw[1], 2);
1288 (void) close(px[0]);
1289 (void) close(pw[1]);
1291 (void) close(pv[1]);
1294 /* We are simply execing a program over rshd : log entry into wtmp,
1295 as kexe(pid), then finish out the session right after that.
1296 Syslog should have the information as to what was exec'd */
1298 pty_logwtmp(ttyn,"","");
1301 if (*pwd->pw_shell == '\0')
1302 pwd->pw_shell = "/bin/sh";
1304 (void) setgid((gid_t)pwd->pw_gid);
1306 if (getuid() == 0 || getuid() != pwd->pw_uid) {
1307 /* For testing purposes, we don't call initgroups if we
1308 already have the right uid, and it is not root. This is
1309 because on some systems initgroups outputs an error message
1310 if not called by root. */
1311 initgroups(pwd->pw_name, pwd->pw_gid);
1316 * If we're on a system which keeps track of login uids, then
1317 * set the login uid.
1319 setluid((uid_t) pwd->pw_uid);
1320 #endif /* HAVE_SETLUID */
1321 (void) setuid((uid_t)pwd->pw_uid);
1322 /* if TZ is set in the parent, drag it in */
1324 char **findtz = environ;
1326 if(!strncmp(*findtz,"TZ=",3)) {
1327 envinit[TZENV] = *findtz;
1333 strncat(homedir, pwd->pw_dir, sizeof(homedir)-6);
1334 strncat(shell, pwd->pw_shell, sizeof(shell)-7);
1335 strncat(username, pwd->pw_name, sizeof(username)-6);
1336 path = (char *) malloc(strlen(kprogdir) + strlen(path_rest) + 7);
1341 sprintf(path, "PATH=%s:%s", kprogdir, path_rest);
1342 envinit[PATHENV] = path;
1344 /* If we have KRB5CCNAME set, then copy into the
1345 * child's environment. This can't really have
1346 * a fixed position because tz may or may not be set.
1348 if (getenv("KRB5CCNAME")) {
1350 char *buf = (char *)malloc(strlen(getenv("KRB5CCNAME"))
1351 +strlen("KRB5CCNAME=")+1);
1353 sprintf(buf, "KRB5CCNAME=%s",getenv("KRB5CCNAME"));
1355 for (i = 0; envinit[i]; i++);
1362 /* these four are covered by ADDRPAD */
1363 sprintf(local_addr, "KRB5LOCALADDR=%s", inet_ntoa(localaddr.sin_addr));
1364 for (i = 0; envinit[i]; i++);
1365 envinit[i] =local_addr;
1367 sprintf(local_port, "KRB5LOCALPORT=%d", ntohs(localaddr.sin_port));
1368 for (; envinit[i]; i++);
1369 envinit[i] =local_port;
1371 sprintf(remote_addr, "KRB5REMOTEADDR=%s", inet_ntoa(fromp->sin_addr));
1372 for (; envinit[i]; i++);
1373 envinit[i] =remote_addr;
1375 sprintf(remote_port, "KRB5REMOTEPORT=%d", ntohs(fromp->sin_port));
1376 for (; envinit[i]; i++);
1377 envinit[i] =remote_port;
1380 /* If we do anything else, make sure there is space in the array. */
1382 for(cnt=0; cnt < num_env; cnt++) {
1386 if(getenv(save_env[cnt])) {
1387 buf = (char *)malloc(strlen(getenv(save_env[cnt]))
1388 +strlen(save_env[cnt]+2));
1390 sprintf(buf, "%s=%s", save_env[cnt],
1391 getenv(save_env[cnt]));
1392 for (i = 0; envinit[i]; i++);
1398 /* XXX - If we do anything else, make sure there is space in the array. */
1403 /* To make Kerberos rcp work correctly, we must ensure that we
1404 invoke Kerberos rcp on this end, not normal rcp, even if the
1405 shell startup files change PATH. */
1406 if (!strncmp(cmdbuf, "rcp ", 4) ||
1407 (do_encrypt && !strncmp(cmdbuf, "-x rcp ", 7))) {
1412 copy = malloc(strlen(cmdbuf) + 1);
1417 strcpy(copy, cmdbuf);
1418 if (do_encrypt && !strncmp(cmdbuf, "-x ", 3)) {
1422 strcpy((char *) cmdbuf + offst, kprogdir);
1423 cp = copy + 3 + offst;
1425 if (auth_sys == KRB5_RECVAUTH_V4) {
1426 strcat(cmdbuf, "/v4rcp");
1428 strcat(cmdbuf, "/rcp");
1430 if (stat((char *)cmdbuf + offst, &s) >= 0)
1433 strcpy(cmdbuf, copy);
1438 cp = strrchr(pwd->pw_shell, '/');
1444 if (do_encrypt && !strncmp(cmdbuf, "-x ", 3)) {
1445 execl(pwd->pw_shell, cp, "-c", (char *)cmdbuf + 3, 0);
1448 execl(pwd->pw_shell, cp, "-c", cmdbuf, 0);
1450 perror(pwd->pw_shell);
1456 krb5_cc_destroy(bsd_context, ccache);
1458 pty_logwtmp(ttyn,"","");
1465 void error(fmt, a1, a2, a3)
1469 char buf[RCMD_BUFSIZ];
1472 (void) sprintf(buf+1, "%s: ", progname);
1473 (void) sprintf(buf+strlen(buf), fmt, a1, a2, a3);
1474 (void) write(2, buf, strlen(buf));
1475 syslog(LOG_ERR ,"%s",buf+1);
1479 void getstr(fd, buf, cnt, err)
1488 if (read(fd, &c, 1) != 1)
1492 error("%s too long\n", err);
1499 char *makejtmp(uid, gid, jid)
1500 register int uid, gid, jid;
1502 register char *endc, *tdp = &tmpdir[strlen(tmpdir)];
1505 sprintf(tdp, "%s/jtmp.%06d", JTMPDIR, jid);
1506 endc = &tmpdir[strlen(tmpdir)];
1509 for (i = 0; i < 26; i++) {
1511 if (mkdir(tdp, JTMPMODE) != -1) {
1512 chown(tdp, uid, gid);
1514 } else if (errno != EEXIST)
1522 cleanjtmp(user, tpath)
1523 register char *user, *tpath;
1530 execl("/bin/rm", "rm", "-rf", tpath, 0);
1531 error("exec of %s failed; errno = %d\n",
1534 execl(CLEANTMPCMD, CLEANTMPCMD, user, tpath, 0);
1535 error("exec of %s failed; errno = %d\n",
1536 CLEANTMPCMD, errno);
1542 * Just forget about the child, let init will pick it
1551 /***get_packet_classification
1554 * int get_packet_classification():
1555 * Obtain packet level and compartments from passed fd...
1558 * -1: If could not get user defaults.
1562 static int get_packet_classification(fd,useruid,level,comp)
1568 struct socket_security pkt_sec;
1575 udb = getudbuid ((int) useruid);
1577 if (udb == (struct udb *) 0) return(-1);
1578 /* Get packet IP packet label */
1579 sockoptlen = SIZEOF_sec;
1580 if ( getsockopt(fd,SOL_SOCKET,SO_SECURITY,
1581 (char *) &pkt_sec,&sockoptlen)){ /* Failed */
1584 *level = pkt_sec.sec_level;
1585 *comp = udb->ue_defcomps;
1589 #else /* If no IP_SECURITY set level to users default */
1591 static int get_packet_classification(fd,useruid,level,comp)
1599 udb = getudbuid ((int) useruid);
1601 if (udb == (struct udb *) 0) return(-1);
1602 *level = udb->ue_deflvl;
1603 *comp = udb->ue_defcomps;
1607 #endif /* IP_SECURITY */
1612 * Make a security log entry for the login attempt.
1613 * host = pointer to host id
1614 * flag = status of login
1615 * failures = current losing streak in login attempts
1617 /* Make a security log entry for the login attempt.
1618 * host = pointer to host id
1619 * flag = status of login
1620 * failures = current losing streak in login attempts
1623 loglogin(host, flag, failures, ue)
1629 char urec[sizeof(struct slghdr) + sizeof(struct slglogin)];
1630 struct slghdr *uhdr = (struct slghdr *)urec;
1631 struct slglogin *ulogin=(struct slglogin *)&urec[sizeof(struct slghdr)];
1633 strncpy(ulogin->sl_line, ttyn, sizeof(ulogin->sl_line));
1634 strncpy(ulogin->sl_host, host, sizeof(ulogin->sl_host));
1635 ulogin->sl_failures = failures;
1636 if ( maxlogs && (failures >= maxlogs))
1638 ulogin->sl_result = flag;
1639 uhdr->sl_uid = ue->ue_uid;
1640 uhdr->sl_ruid = ue->ue_uid;
1641 uhdr->sl_juid = ue->ue_uid;
1642 uhdr->sl_gid = ue->ue_gids[0];
1643 uhdr->sl_rgid = ue->ue_gids[0];
1644 uhdr->sl_slvl = ue->ue_deflvl;
1645 /* uhdr->sl_scls = ue->ue_defcls; enable for integrity policy */
1647 uhdr->sl_len = sizeof(urec);
1650 slgentry(SLG_LOGN, (word *)urec);
1652 slgentry(SLG_LOGN, (waddr_t)urec);
1664 syslog(LOG_ERR, "usage: kshd [-54ecikK] ");
1666 syslog(LOG_ERR, "usage: rshd");
1672 int princ_maps_to_lname(principal, luser)
1673 krb5_principal principal;
1677 if (!(krb5_aname_to_localname(bsd_context, principal,
1678 sizeof(kuser), kuser))
1679 && (strcmp(kuser, luser) == 0)) {
1686 int default_realm(principal)
1687 krb5_principal principal;
1693 realm_length = krb5_princ_realm(bsd_context, principal)->length;
1695 if ((retval = krb5_get_default_realm(bsd_context, &def_realm))) {
1699 if ((realm_length != strlen(def_realm)) ||
1700 (memcmp(def_realm, krb5_princ_realm(bsd_context, principal)->data,
1711 #ifndef KRB_SENDAUTH_VLEN
1712 #define KRB_SENDAUTH_VLEN 8 /* length for version strings */
1715 #define KRB_SENDAUTH_VERS "AUTHV0.1" /* MUST be KRB_SENDAUTH_VLEN
1719 recvauth(netf, peersin, valid_checksum)
1721 struct sockaddr_in peersin;
1722 int *valid_checksum;
1724 krb5_auth_context auth_context = NULL;
1725 krb5_error_code status;
1726 struct sockaddr_in laddr;
1727 char krb_vers[KRB_SENDAUTH_VLEN + 1];
1730 char v4_instance[INST_SZ]; /* V4 Instance */
1732 krb5_authenticator *authenticator;
1733 krb5_ticket *ticket;
1739 *valid_checksum = 0;
1740 len = sizeof(laddr);
1741 if (getsockname(netf, (struct sockaddr *)&laddr, &len)) {
1746 #define SIZEOF_INADDR SIZEOF_in_addr
1748 #define SIZEOF_INADDR sizeof(struct in_addr)
1751 strcpy(v4_instance, "*");
1753 if (status = krb5_auth_con_init(bsd_context, &auth_context))
1756 if (status = krb5_auth_con_genaddrs(bsd_context, auth_context, netf,
1757 KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR))
1760 status = krb5_auth_con_getrcache(bsd_context, auth_context, &rcache);
1761 if (status) return status;
1764 krb5_principal server;
1766 status = krb5_sname_to_principal(bsd_context, 0, 0,
1767 KRB5_NT_SRV_HST, &server);
1768 if (status) return status;
1770 status = krb5_get_server_rcache(bsd_context,
1771 krb5_princ_component(bsd_context, server, 0),
1773 krb5_free_principal(bsd_context, server);
1774 if (status) return status;
1776 status = krb5_auth_con_setrcache(bsd_context, auth_context, rcache);
1777 if (status) return status;
1780 status = krb5_compat_recvauth(bsd_context, &auth_context, &netf,
1782 NULL, /* Specify daemon principal */
1784 keytab, /* normally NULL to use v5srvtab */
1786 "rcmd", /* v4_service */
1787 v4_instance, /* v4_instance */
1788 &peersin, /* foreign address */
1789 &laddr, /* our local address */
1790 "", /* use default srvtab */
1792 &ticket, /* return ticket */
1793 &auth_sys, /* which authentication system*/
1794 &v4_kdata, 0, v4_version);
1797 if (auth_sys == KRB5_RECVAUTH_V5) {
1799 * clean up before exiting
1801 getstr(netf, locuser, sizeof(locuser), "locuser");
1802 getstr(netf, cmdbuf, sizeof(cmdbuf), "command");
1803 getstr(netf, remuser, sizeof(locuser), "remuser");
1808 getstr(netf, locuser, sizeof(locuser), "locuser");
1809 getstr(netf, cmdbuf, sizeof(cmdbuf), "command");
1811 if (auth_sys == KRB5_RECVAUTH_V4) {
1812 rcmd_stream_init_normal();
1814 /* We do not really know the remote user's login name.
1815 * Assume it to be the same as the first component of the
1818 strcpy(remuser, v4_kdata->pname);
1820 status = krb5_425_conv_principal(bsd_context, v4_kdata->pname,
1821 v4_kdata->pinst, v4_kdata->prealm,
1823 if (status) return status;
1825 status = krb5_unparse_name(bsd_context, client, &kremuser);
1832 getstr(netf, remuser, sizeof(locuser), "remuser");
1834 if ((status = krb5_unparse_name(bsd_context, ticket->enc_part2->client,
1838 if ((status = krb5_copy_principal(bsd_context, ticket->enc_part2->client,
1841 if ((status = krb5_auth_con_getauthenticator(bsd_context, auth_context,
1845 if (authenticator->checksum && !checksum_ignored) {
1846 struct sockaddr_in adr;
1847 int adr_length = sizeof(adr);
1848 char * chksumbuf = (char *) malloc(strlen(cmdbuf)+strlen(locuser)+32);
1852 if (getsockname(netf, (struct sockaddr *) &adr, &adr_length) != 0)
1855 sprintf(chksumbuf,"%u:", ntohs(adr.sin_port));
1856 strcat(chksumbuf,cmdbuf);
1857 strcat(chksumbuf,locuser);
1859 status = krb5_verify_checksum(bsd_context,
1860 authenticator->checksum->checksum_type,
1861 authenticator->checksum,
1862 chksumbuf, strlen(chksumbuf),
1863 ticket->enc_part2->session->contents,
1864 ticket->enc_part2->session->length);
1870 krb5_free_authenticator(bsd_context, authenticator);
1873 *valid_checksum = 1;
1875 krb5_free_authenticator(bsd_context, authenticator);
1878 if (!strncmp(cmdbuf, "-x ", 3))
1880 rcmd_stream_init_krb5(ticket->enc_part2->session, do_encrypt, 0);
1882 /* Null out the "session" because kcmd.c references the session
1883 * key here, and we do not want krb5_free_ticket() to destroy it. */
1884 ticket->enc_part2->session = 0;
1886 if ((status = krb5_read_message(bsd_context, (krb5_pointer)&netf,
1888 error("Error reading message: %s\n", error_message(status));
1892 if (inbuf.length) { /* Forwarding being done, read creds */
1893 pwd = getpwnam(locuser);
1895 error("Login incorrect.\n");
1900 if ((status = rd_and_store_for_creds(bsd_context, auth_context, &inbuf,
1901 ticket, &ccache))) {
1902 error("Can't get forwarded credentials: %s\n",
1903 error_message(status));
1906 if (chown(krb5_cc_get_name(bsd_context, ccache), uid, gid) == -1) {
1907 error("Can't chown forwarded credentials: %s\n",
1908 error_message(errno));
1912 krb5_free_ticket(bsd_context, ticket);
1915 #endif /* KERBEROS */
1924 #ifndef POSIX_TERMIOS
1925 int out = 1 ; /* Output queue of f */
1928 buf[0] = '\01'; /* error indicator */
1929 (void) sprintf(buf + 1, "%s: %s.\r\n",progname, msg);
1930 if ((f == netf) && (pid > 0))
1931 (void) rcmd_stream_write(f, buf, strlen(buf));
1933 (void) write(f, buf, strlen(buf));
1934 syslog(LOG_ERR,"%s\n",msg);
1936 signal(SIGCHLD,SIG_IGN);
1938 #ifdef POSIX_TERMIOS
1939 (void) tcflush(1, TCOFLUSH);
1941 (void) ioctl(f, TIOCFLUSH, (char *)&out);