⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rshd.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
				version);			des_set_key(kdata->session, schedule);		} else#endif			rc = krb_recvauth(authopts, 0, ticket, "rcmd",				instance, &fromaddr,				(struct sockaddr_in *) 0,				kdata, "", (bit_64 *) 0, version);		if (rc != KSUCCESS) {			error("Kerberos authentication failure: %s\n",				  krb_err_txt[rc]);			exit(1);		}	} else#endif		getstr(remuser, sizeof(remuser), "remuser");	getstr(locuser, sizeof(locuser), "locuser");	getstr(cmdbuf, sizeof(cmdbuf), "command");	setpwent();	pwd = getpwnam(locuser);	if (pwd == NULL) {		syslog(LOG_INFO|LOG_AUTH,		    "%s@%s as %s: unknown login. cmd='%.80s'",		    remuser, hostname, locuser, cmdbuf);		if (errorstr == NULL)			errorstr = "Login incorrect.\n";		goto fail;	}	if (chdir(pwd->pw_dir) < 0) {		(void) chdir("/");#ifdef notdef		syslog(LOG_INFO|LOG_AUTH,		    "%s@%s as %s: no home directory. cmd='%.80s'",		    remuser, hostname, locuser, cmdbuf);		error("No remote directory.\n");		exit(1);#endif	}#ifdef	KERBEROS	if (use_kerberos) {		if (pwd->pw_passwd != 0 && *pwd->pw_passwd != '\0') {			if (kuserok(kdata, locuser) != 0) {				syslog(LOG_INFO|LOG_AUTH,				    "Kerberos rsh denied to %s.%s@%s",				    kdata->pname, kdata->pinst, kdata->prealm);				error("Permission denied.\n");				exit(1);			}		}	} else#endif		if (errorstr ||		    pwd->pw_passwd != 0 && *pwd->pw_passwd != '\0' &&		    iruserok(fromp->sin_addr.s_addr, pwd->pw_uid == 0,		    remuser, locuser) < 0) {			if (__rcmd_errstr)				syslog(LOG_INFO|LOG_AUTH,			    "%s@%s as %s: permission denied (%s). cmd='%.80s'",				    remuser, hostname, locuser, __rcmd_errstr,				    cmdbuf);			else				syslog(LOG_INFO|LOG_AUTH,			    "%s@%s as %s: permission denied. cmd='%.80s'",				    remuser, hostname, locuser, cmdbuf);fail:			if (errorstr == NULL)				errorstr = "Permission denied.\n";			error(errorstr, errorhost);			exit(1);		}	if (pwd->pw_uid && !access(_PATH_NOLOGIN, F_OK)) {		error("Logins currently disabled.\n");		exit(1);	}	(void) write(STDERR_FILENO, "\0", 1);	sent_null = 1;	if (port) {		if (pipe(pv) < 0) {			error("Can't make pipe.\n");			exit(1);		}#ifdef CRYPT#ifdef KERBEROS		if (doencrypt) {			if (pipe(pv1) < 0) {				error("Can't make 2nd pipe.\n");				exit(1);			}			if (pipe(pv2) < 0) {				error("Can't make 3rd pipe.\n");				exit(1);			}		}#endif#endif		pid = fork();		if (pid == -1)  {			error("Can't fork; try again.\n");			exit(1);		}		if (pid) {#ifdef CRYPT#ifdef KERBEROS			if (doencrypt) {				static char msg[] = SECURE_MESSAGE;				(void) close(pv1[1]);				(void) close(pv2[1]);				des_write(s, msg, sizeof(msg) - 1);			} else#endif#endif			{				(void) close(0);				(void) close(1);			}			(void) close(2);			(void) close(pv[1]);			FD_ZERO(&readfrom);			FD_SET(s, &readfrom);			FD_SET(pv[0], &readfrom);			if (pv[0] > s)				nfd = pv[0];			else				nfd = s;#ifdef CRYPT#ifdef KERBEROS			if (doencrypt) {				FD_ZERO(&writeto);				FD_SET(pv2[0], &writeto);				FD_SET(pv1[0], &readfrom);				nfd = MAX(nfd, pv2[0]);				nfd = MAX(nfd, pv1[0]);			} else#endif#endif				ioctl(pv[0], FIONBIO, (char *)&one);			/* should set s nbio! */			nfd++;			do {				ready = readfrom;#ifdef CRYPT#ifdef KERBEROS				if (doencrypt) {					wready = writeto;					if (select(nfd, &ready,					    &wready, (fd_set *) 0,					    (struct timeval *) 0) < 0)						break;				} else#endif#endif					if (select(nfd, &ready, (fd_set *)0,					  (fd_set *)0, (struct timeval *)0) < 0)						break;				if (FD_ISSET(s, &ready)) {					int	ret;#ifdef CRYPT#ifdef KERBEROS					if (doencrypt)						ret = des_read(s, &sig, 1);					else#endif#endif						ret = read(s, &sig, 1);					if (ret <= 0)						FD_CLR(s, &readfrom);					else						killpg(pid, sig);				}				if (FD_ISSET(pv[0], &ready)) {					errno = 0;					cc = read(pv[0], buf, sizeof(buf));					if (cc <= 0) {						shutdown(s, 1+1);						FD_CLR(pv[0], &readfrom);					} else {#ifdef CRYPT#ifdef KERBEROS						if (doencrypt)							(void)							  des_write(s, buf, cc);						else#endif#endif							(void)							  write(s, buf, cc);					}				}#ifdef CRYPT#ifdef KERBEROS				if (doencrypt && FD_ISSET(pv1[0], &ready)) {					errno = 0;					cc = read(pv1[0], buf, sizeof(buf));					if (cc <= 0) {						shutdown(pv1[0], 1+1);						FD_CLR(pv1[0], &readfrom);					} else						(void) des_write(STDOUT_FILENO,						    buf, cc);				}				if (doencrypt && FD_ISSET(pv2[0], &wready)) {					errno = 0;					cc = des_read(STDIN_FILENO,					    buf, sizeof(buf));					if (cc <= 0) {						shutdown(pv2[0], 1+1);						FD_CLR(pv2[0], &writeto);					} else						(void) write(pv2[0], buf, cc);				}#endif#endif			} while (FD_ISSET(s, &readfrom) ||#ifdef CRYPT#ifdef KERBEROS			    (doencrypt && FD_ISSET(pv1[0], &readfrom)) ||#endif#endif			    FD_ISSET(pv[0], &readfrom));			exit(0);		}		setpgrp(0, getpid());		(void) close(s);		(void) close(pv[0]);#ifdef CRYPT#ifdef KERBEROS		if (doencrypt) {			close(pv1[0]); close(pv2[0]);			dup2(pv1[1], 1);			dup2(pv2[1], 0);			close(pv1[1]);			close(pv2[1]);		}#endif#endif		dup2(pv[1], 2);		close(pv[1]);	}	if (*pwd->pw_shell == '\0')		pwd->pw_shell = _PATH_BSHELL;#if	BSD > 43	if (setlogin(pwd->pw_name) < 0)		syslog(LOG_ERR, "setlogin() failed: %m");#endif	(void) setgid((gid_t)pwd->pw_gid);	initgroups(pwd->pw_name, pwd->pw_gid);	(void) setuid((uid_t)pwd->pw_uid);	environ = envinit;	strncat(homedir, pwd->pw_dir, sizeof(homedir)-6);	strcat(path, _PATH_DEFPATH);	strncat(shell, pwd->pw_shell, sizeof(shell)-7);	strncat(username, pwd->pw_name, sizeof(username)-6);	cp = strrchr(pwd->pw_shell, '/');	if (cp)		cp++;	else		cp = pwd->pw_shell;	endpwent();	if (log_success || pwd->pw_uid == 0) {#ifdef	KERBEROS		if (use_kerberos)		    syslog(LOG_INFO|LOG_AUTH,			"Kerberos shell from %s.%s@%s on %s as %s, cmd='%.80s'",			kdata->pname, kdata->pinst, kdata->prealm,			hostname, locuser, cmdbuf);		else#endif		    syslog(LOG_INFO|LOG_AUTH, "%s@%s as %s: cmd='%.80s'",			remuser, hostname, locuser, cmdbuf);	}	execl(pwd->pw_shell, cp, "-c", cmdbuf, 0);	perror(pwd->pw_shell);	exit(1);}/* * Report error to client.  Note: can't be used until second socket has * connected to client, or older clients will hang waiting for that * connection first. */#if __STDC__#include <stdarg.h>#else#include <varargs.h>#endifvoid#if __STDC__error(const char *fmt, ...)#elseerror(fmt, va_alist)	char *fmt;        va_dcl#endif{	va_list ap;	int len;	char *bp, buf[BUFSIZ];#if __STDC__	va_start(ap, fmt);#else	va_start(ap);#endif	bp = buf;	if (sent_null == 0) {		*bp++ = 1;		len = 1;	} else		len = 0;	(void)vsnprintf(bp, sizeof(buf) - 1, fmt, ap);	(void)write(STDERR_FILENO, buf, len + strlen(bp));}voidgetstr(buf, cnt, err)	char *buf, *err;	int cnt;{	char c;	do {		if (read(STDIN_FILENO, &c, 1) != 1)			exit(1);		*buf++ = c;		if (--cnt == 0) {			error("%s too long\n", err);			exit(1);		}	} while (c != 0);}/* * Check whether host h is in our local domain, * defined as sharing the last two components of the domain part, * or the entire domain part if the local domain has only one component. * If either name is unqualified (contains no '.'), * assume that the host is local, as it will be * interpreted as such. */intlocal_domain(h)	char *h;{	char localhost[MAXHOSTNAMELEN];	char *p1, *p2;	localhost[0] = 0;	(void) gethostname(localhost, sizeof(localhost));	p1 = topdomain(localhost);	p2 = topdomain(h);	if (p1 == NULL || p2 == NULL || !strcasecmp(p1, p2))		return (1);	return (0);}char *topdomain(h)	char *h;{	char *p, *maybe = NULL;	int dots = 0;	for (p = h + strlen(h); p >= h; p--) {		if (*p == '.') {			if (++dots == 2)				return (p);			maybe = p;		}	}	return (maybe);}voidusage(){	syslog(LOG_ERR, "usage: rshd [-%s]", OPTIONS);	exit(2);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -