2 * Copyright (c) 1983 Regents of the University of California.
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
13 #include <afs/kautils.h> /* for UserAuthGeneral */
14 #include <sys/types.h>
18 #include <sys/ioctl.h>
19 #include <sys/param.h>
20 #include <sys/socket.h>
22 #include <netinet/in.h>
33 #if defined(AFS_AIX_ENV)
34 #include <sys/syslog.h>
39 struct passwd *getpwnam();
40 char *crypt(), *strncat();
41 #if !defined(AFS_AIX_ENV) && !defined(AFS_HPUX_ENV) && !defined(AFS_OSF_ENV) && !defined(AFS_SUN5_ENV)
47 #include "AFS_component_version_number.c"
51 SIAENTITY *entity = NULL;
57 * remote execute server:
68 struct sockaddr_in from;
71 fromlen = sizeof(from);
72 if (getpeername(0, (struct sockaddr *)&from, &fromlen) < 0) {
73 fprintf(stderr, "%s: ", argv[0]);
74 perror("getpeername");
84 char env_user[20] = "USER=";
85 char env_home[64] = "HOME=";
86 char env_shell[64] = "SHELL=";
87 char env_logname[32] = "LOGNAME=";
88 char env_password_expires[64] = "PASSWORD_EXPIRES=";
89 afs_int32 password_expires = -1;
90 char pwd_expires_str[10];
91 /* make sure env_password_expires is always the last item in envinit array */
92 #if defined(AFS_OSF_ENV) || defined(AFS_AIX_ENV)
93 char time_zone[20] = "TZ=";
95 { env_home, env_shell, "PATH=:/usr/ucb:/bin:/usr/bin:/usr/sbin", env_user,
96 time_zone, env_logname, env_password_expires, 0
100 { env_home, env_shell, "PATH=:/usr/ucb:/bin:/usr/bin", env_user,
101 env_logname, env_password_expires, 0
104 #define PATHENV ":/usr/ucb:/bin:/usr/bin:/usr/bin/X11"
105 extern char **environ;
107 struct sockaddr_in asin = { AF_INET };
111 struct sockaddr_in *fromp;
113 char cmdbuf[NCARGS + 1], *cp, *namep;
114 char user[16], pass[16];
121 fd_set ready, readfrom;
122 char buf[BUFSIZ], sig;
129 (void)signal(SIGINT, SIG_DFL);
130 (void)signal(SIGQUIT, SIG_DFL);
131 (void)signal(SIGTERM, SIG_DFL);
134 int t = open("/dev/tty", 2);
136 ioctl(t, TIOCNOTTY, NULL);
148 if (read(f, &c, 1) != 1)
152 port = port * 10 + c - '0';
156 s = socket(AF_INET, SOCK_STREAM, 0);
159 if (bind(s, (struct sockaddr *)&asin, sizeof(asin)) < 0)
162 fromp->sin_port = htons((u_short) port);
163 if (connect(s, (struct sockaddr *)fromp, sizeof(*fromp)) < 0)
167 getstr(user, sizeof(user), "username");
168 getstr(pass, sizeof(pass), "password");
169 getstr(cmdbuf, sizeof(cmdbuf), "command");
171 pwd = getpwnam(user);
173 (void)setspent(); /* Shadow password file */
174 shpwd = getspnam(user);
175 if (pwd == NULL || shpwd == NULL) {
179 error("Login Incorrect..\n");
185 password = shpwd->sp_pwdp;
187 password = pwd->pw_passwd;
189 if (*password != '\0') {
192 setpag(); /* Also set a pag */
194 * If it's called as "root" we don't bother with afs authentication...
196 if (strcmp(user, "root")) {
197 /* changed from ka_UserAuthenticate *
198 * to get password_expires information */
199 if (ka_UserAuthenticateGeneral(KA_USERAUTH_VERSION + KA_USERAUTH_DOSETPAG, user, /* kerberos name */
203 0, /* default lifetime */
204 &password_expires, 0, /* spare 2 */
205 &reason /* error string */
213 * if (strcmp(user, "root") &&
214 * strcmp(password, NO_VICE_AUTH_PWD)) {
215 * rc = U_Authenticate(user, pass, &cToken, &sToken);
219 namep = crypt(pass, password);
220 if (strcmp(namep, password) && !afsauthok) {
221 error("Password Incorrect..\n");
225 if (chdir(pwd->pw_dir) < 0) {
226 error("No remote directory.\n");
229 (void)write(2, "\0", 1);
233 if (pid == (int)-1) {
234 error("Try again.\n");
244 FD_SET(s, &readfrom);
245 FD_SET(pv[0], &readfrom);
246 ioctl(pv[1], FIONBIO, (char *)&one);
247 /* should set s nbio! */
251 if (FD_ISSET(s, &readfrom) && maxfd < s)
253 if (FD_ISSET(pv[0], &readfrom) && maxfd < pv[0])
258 (void)select(maxfd + 1, &ready, (fd_set *) 0, (fd_set *) 0,
260 if (FD_ISSET(s, &ready)) {
261 if (read(s, &sig, 1) <= 0)
262 FD_CLR(s, &readfrom);
266 if (FD_ISSET(pv[0], &ready)) {
267 cc = read(pv[0], buf, sizeof(buf));
270 FD_CLR(pv[0], &readfrom);
272 (void)write(s, buf, cc);
277 setpgid(0, getpid());
282 if (*pwd->pw_shell == '\0')
283 pwd->pw_shell = "/bin/sh";
288 /* For 7403 - try setting ulimit here */
290 * Need to set user's ulimit, else system default
292 if (setpcred(pwd->pw_name, NULL) < 0) {
293 error("Can't set user credentials.\n");
296 #endif /* AFS_AIX_ENV */
299 * For both setgid() and setuid() we should have checked for errors but we ignore them since
300 * they may fail in afs...
302 (void)setgid((gid_t) pwd->pw_gid);
303 initgroups(pwd->pw_name, pwd->pw_gid);
304 (void)setuid((uid_t) pwd->pw_uid);
307 strncat(env_home, pwd->pw_dir, sizeof(env_home) - 6);
308 strncat(env_shell, pwd->pw_shell, sizeof(env_shell) - 7);
309 strncat(env_user, pwd->pw_name, sizeof(env_user) - 6);
310 strncat(env_logname, pwd->pw_name, sizeof(env_logname) - 9);
311 /* Determine if password expiration is used
312 * if not, take out env_password_expires string from envinit */
313 if ((password_expires >= 0) && (password_expires < 255)) {
314 sprintf(env_password_expires, "%s%d", env_password_expires,
317 /* taking out PASSWORD_EXPIRES env var from array */
318 #if defined(AFS_OSF_ENV)
322 #endif /* AFS_OSF_ENV */
325 penvlist = getpenv(PENV_USR);
326 environ = penvlist + 1;
327 addenvvar("HOME", pwd->pw_dir);
328 addenvvar("SHELL", pwd->pw_shell);
329 addenvvar("PATH", PATHENV);
330 addenvvar("LOGNAME", pwd->pw_name);
331 addenvvar("USER", pwd->pw_name);
332 /* Determine if password expiration is used
333 * if not, take out env_password_expires string from envinit */
334 if ((password_expires >= 0) && (password_expires < 255)) {
335 sprintf(pwd_expires_str, "%d", password_expires);
336 addenvvar("PASSWORD_EXPIRES", pwd_expires_str);
339 cp = strrchr(pwd->pw_shell, '/');
344 execl(pwd->pw_shell, cp, "-c", cmdbuf, 0);
345 perror(pwd->pw_shell);
350 addenvvar(tag, value)
354 unsigned int len = strlen(tag) + 1; /* allow for '=' */
358 perror("rexecd, addenvvar");
362 len += strlen(value);
363 penv = malloc(len + 1);
368 if (putenv(penv) < 0) {
369 perror("rexecd, putenv");
378 error(fmt, a1, a2, a3)
385 (void)sprintf(buf + 1, fmt, a1, a2, a3);
386 (void)write(2, buf, strlen(buf));
389 getstr(buf, cnt, err)
397 if (read(0, &c, 1) != 1)
401 error("%s too long\n", (int)err, 0, 0);