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

📄 loginrec.c

📁 OpenSSL Source code for SFTP, SSH, and many others
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * 'line' string utility functions * * These functions process the 'line' string into one of three forms: * * 1. The full filename (including '/dev') * 2. The stripped name (excluding '/dev') * 3. The abbreviated name (e.g. /dev/ttyp00 -> yp00 *                               /dev/pts/1  -> ts/1 ) * * Form 3 is used on some systems to identify a .tmp.? entry when * attempting to remove it. Typically both addition and removal is * performed by one application - say, sshd - so as long as the choice * uniquely identifies a terminal it's ok. *//* line_fullname(): add the leading '/dev/' if it doesn't exist make * sure dst has enough space, if not just copy src (ugh) */char *line_fullname(char *dst, const char *src, int dstsize){	memset(dst, '\0', dstsize);	if ((strncmp(src, "/dev/", 5) == 0) || (dstsize < (strlen(src) + 5))) {		strlcpy(dst, src, dstsize);	} else {		strlcpy(dst, "/dev/", dstsize);		strlcat(dst, src, dstsize);	}	return dst;}/* line_stripname(): strip the leading '/dev' if it exists, return dst */char *line_stripname(char *dst, const char *src, int dstsize){	memset(dst, '\0', dstsize);	if (strncmp(src, "/dev/", 5) == 0)		strlcpy(dst, src + 5, dstsize);	else		strlcpy(dst, src, dstsize);	return dst;}/* line_abbrevname(): Return the abbreviated (usually four-character) * form of the line (Just use the last <dstsize> characters of the * full name.) * * NOTE: use strncpy because we do NOT necessarily want zero * termination */char *line_abbrevname(char *dst, const char *src, int dstsize){	size_t len;	memset(dst, '\0', dstsize);	/* Always skip prefix if present */	if (strncmp(src, "/dev/", 5) == 0)		src += 5;#ifdef WITH_ABBREV_NO_TTY	if (strncmp(src, "tty", 3) == 0)		src += 3;#endif	len = strlen(src);	if (len > 0) {		if (((int)len - dstsize) > 0)			src +=  ((int)len - dstsize);		/* note: _don't_ change this to strlcpy */		strncpy(dst, src, (size_t)dstsize);	}	return dst;}/** ** utmp utility functions ** ** These functions manipulate struct utmp, taking system differences ** into account. **/#if defined(USE_UTMP) || defined (USE_WTMP) || defined (USE_LOGIN)/* build the utmp structure */voidset_utmp_time(struct logininfo *li, struct utmp *ut){# ifdef HAVE_TV_IN_UTMP	ut->ut_tv.tv_sec = li->tv_sec;	ut->ut_tv.tv_usec = li->tv_usec;# else#  ifdef HAVE_TIME_IN_UTMP	ut->ut_time = li->tv_sec;#  endif# endif}voidconstruct_utmp(struct logininfo *li,		    struct utmp *ut){	memset(ut, '\0', sizeof(*ut));	/* First fill out fields used for both logins and logouts */# ifdef HAVE_ID_IN_UTMP	line_abbrevname(ut->ut_id, li->line, sizeof(ut->ut_id));# endif# ifdef HAVE_TYPE_IN_UTMP	/* This is done here to keep utmp constants out of struct logininfo */	switch (li->type) {	case LTYPE_LOGIN:		ut->ut_type = USER_PROCESS;#ifdef _CRAY		cray_set_tmpdir(ut);#endif		break;	case LTYPE_LOGOUT:		ut->ut_type = DEAD_PROCESS;#ifdef _CRAY		cray_retain_utmp(ut, li->pid);#endif		break;	}# endif	set_utmp_time(li, ut);	line_stripname(ut->ut_line, li->line, sizeof(ut->ut_line));# ifdef HAVE_PID_IN_UTMP	ut->ut_pid = li->pid;# endif	/* If we're logging out, leave all other fields blank */	if (li->type == LTYPE_LOGOUT)	  return;	/*	 * These fields are only used when logging in, and are blank	 * for logouts.	 */	/* Use strncpy because we don't necessarily want null termination */	strncpy(ut->ut_name, li->username, MIN_SIZEOF(ut->ut_name, li->username));# ifdef HAVE_HOST_IN_UTMP	strncpy(ut->ut_host, li->hostname, MIN_SIZEOF(ut->ut_host, li->hostname));# endif# ifdef HAVE_ADDR_IN_UTMP	/* this is just a 32-bit IP address */	if (li->hostaddr.sa.sa_family == AF_INET)		ut->ut_addr = li->hostaddr.sa_in.sin_addr.s_addr;# endif}#endif /* USE_UTMP || USE_WTMP || USE_LOGIN *//** ** utmpx utility functions ** ** These functions manipulate struct utmpx, accounting for system ** variations. **/#if defined(USE_UTMPX) || defined (USE_WTMPX)/* build the utmpx structure */voidset_utmpx_time(struct logininfo *li, struct utmpx *utx){# ifdef HAVE_TV_IN_UTMPX	utx->ut_tv.tv_sec = li->tv_sec;	utx->ut_tv.tv_usec = li->tv_usec;# else /* HAVE_TV_IN_UTMPX */#  ifdef HAVE_TIME_IN_UTMPX	utx->ut_time = li->tv_sec;#  endif /* HAVE_TIME_IN_UTMPX */# endif /* HAVE_TV_IN_UTMPX */}voidconstruct_utmpx(struct logininfo *li, struct utmpx *utx){	memset(utx, '\0', sizeof(*utx));# ifdef HAVE_ID_IN_UTMPX	line_abbrevname(utx->ut_id, li->line, sizeof(utx->ut_id));# endif	/* this is done here to keep utmp constants out of loginrec.h */	switch (li->type) {	case LTYPE_LOGIN:		utx->ut_type = USER_PROCESS;		break;	case LTYPE_LOGOUT:		utx->ut_type = DEAD_PROCESS;		break;	}	line_stripname(utx->ut_line, li->line, sizeof(utx->ut_line));	set_utmpx_time(li, utx);	utx->ut_pid = li->pid;	/* strncpy(): Don't necessarily want null termination */	strncpy(utx->ut_name, li->username, MIN_SIZEOF(utx->ut_name, li->username));	if (li->type == LTYPE_LOGOUT)		return;	/*	 * These fields are only used when logging in, and are blank	 * for logouts.	 */# ifdef HAVE_HOST_IN_UTMPX	strncpy(utx->ut_host, li->hostname, MIN_SIZEOF(utx->ut_host, li->hostname));# endif# ifdef HAVE_ADDR_IN_UTMPX	/* this is just a 32-bit IP address */	if (li->hostaddr.sa.sa_family == AF_INET)		utx->ut_addr = li->hostaddr.sa_in.sin_addr.s_addr;# endif# ifdef HAVE_SYSLEN_IN_UTMPX	/* ut_syslen is the length of the utx_host string */	utx->ut_syslen = MIN(strlen(li->hostname), sizeof(utx->ut_host));# endif}#endif /* USE_UTMPX || USE_WTMPX *//** ** Low-level utmp functions **//* FIXME: (ATL) utmp_write_direct needs testing */#ifdef USE_UTMP/* if we can, use pututline() etc. */# if !defined(DISABLE_PUTUTLINE) && defined(HAVE_SETUTENT) && \	defined(HAVE_PUTUTLINE)#  define UTMP_USE_LIBRARY# endif/* write a utmp entry with the system's help (pututline() and pals) */# ifdef UTMP_USE_LIBRARYstatic intutmp_write_library(struct logininfo *li, struct utmp *ut){	setutent();	pututline(ut);#  ifdef HAVE_ENDUTENT	endutent();#  endif	return 1;}# else /* UTMP_USE_LIBRARY *//* write a utmp entry direct to the file *//* This is a slightly modification of code in OpenBSD's login.c */static intutmp_write_direct(struct logininfo *li, struct utmp *ut){	struct utmp old_ut;	register int fd;	int tty;	/* FIXME: (ATL) ttyslot() needs local implementation */#if defined(HAVE_GETTTYENT)	register struct ttyent *ty;	tty=0;	setttyent();	while ((struct ttyent *)0 != (ty = getttyent())) {		tty++;		if (!strncmp(ty->ty_name, ut->ut_line, sizeof(ut->ut_line)))			break;	}	endttyent();	if((struct ttyent *)0 == ty) {		log("utmp_write_entry: tty not found");		return(1);	}#else /* FIXME */	tty = ttyslot(); /* seems only to work for /dev/ttyp? style names */#endif /* HAVE_GETTTYENT */	if (tty > 0 && (fd = open(UTMP_FILE, O_RDWR|O_CREAT, 0644)) >= 0) {		(void)lseek(fd, (off_t)(tty * sizeof(struct utmp)), SEEK_SET);		/*		 * Prevent luser from zero'ing out ut_host.		 * If the new ut_line is empty but the old one is not		 * and ut_line and ut_name match, preserve the old ut_line.		 */		if (atomicio(read, fd, &old_ut, sizeof(old_ut)) == sizeof(old_ut) &&			(ut->ut_host[0] == '\0') && (old_ut.ut_host[0] != '\0') &&			(strncmp(old_ut.ut_line, ut->ut_line, sizeof(ut->ut_line)) == 0) &&			(strncmp(old_ut.ut_name, ut->ut_name, sizeof(ut->ut_name)) == 0)) {			(void)memcpy(ut->ut_host, old_ut.ut_host, sizeof(ut->ut_host));		}		(void)lseek(fd, (off_t)(tty * sizeof(struct utmp)), SEEK_SET);		if (atomicio(write, fd, ut, sizeof(*ut)) != sizeof(*ut))			log("utmp_write_direct: error writing %s: %s",			    UTMP_FILE, strerror(errno));		(void)close(fd);		return 1;	} else {		return 0;	}}# endif /* UTMP_USE_LIBRARY */static intutmp_perform_login(struct logininfo *li){	struct utmp ut;	construct_utmp(li, &ut);# ifdef UTMP_USE_LIBRARY	if (!utmp_write_library(li, &ut)) {		log("utmp_perform_login: utmp_write_library() failed");		return 0;	}# else	if (!utmp_write_direct(li, &ut)) {		log("utmp_perform_login: utmp_write_direct() failed");		return 0;	}# endif	return 1;}static intutmp_perform_logout(struct logininfo *li){	struct utmp ut;	construct_utmp(li, &ut);# ifdef UTMP_USE_LIBRARY	if (!utmp_write_library(li, &ut)) {		log("utmp_perform_logout: utmp_write_library() failed");		return 0;	}# else	if (!utmp_write_direct(li, &ut)) {		log("utmp_perform_logout: utmp_write_direct() failed");		return 0;	}# endif	return 1;}intutmp_write_entry(struct logininfo *li){	switch(li->type) {	case LTYPE_LOGIN:		return utmp_perform_login(li);	case LTYPE_LOGOUT:		return utmp_perform_logout(li);	default:		log("utmp_write_entry: invalid type field");		return 0;	}}#endif /* USE_UTMP *//** ** Low-level utmpx functions **//* not much point if we don't want utmpx entries */#ifdef USE_UTMPX/* if we have the wherewithall, use pututxline etc. */# if !defined(DISABLE_PUTUTXLINE) && defined(HAVE_SETUTXENT) && \	defined(HAVE_PUTUTXLINE)#  define UTMPX_USE_LIBRARY# endif/* write a utmpx entry with the system's help (pututxline() and pals) */# ifdef UTMPX_USE_LIBRARYstatic intutmpx_write_library(struct logininfo *li, struct utmpx *utx){	setutxent();	pututxline(utx);#  ifdef HAVE_ENDUTXENT	endutxent();#  endif	return 1;}# else /* UTMPX_USE_LIBRARY *//* write a utmp entry direct to the file */static intutmpx_write_direct(struct logininfo *li, struct utmpx *utx){	log("utmpx_write_direct: not implemented!");	return 0;}# endif /* UTMPX_USE_LIBRARY */static intutmpx_perform_login(struct logininfo *li){	struct utmpx utx;	construct_utmpx(li, &utx);# ifdef UTMPX_USE_LIBRARY	if (!utmpx_write_library(li, &utx)) {		log("utmpx_perform_login: utmp_write_library() failed");		return 0;	}# else	if (!utmpx_write_direct(li, &ut)) {		log("utmpx_perform_login: utmp_write_direct() failed");		return 0;	}# endif	return 1;}static intutmpx_perform_logout(struct logininfo *li){	struct utmpx utx;	construct_utmpx(li, &utx);# ifdef HAVE_ID_IN_UTMPX	line_abbrevname(utx.ut_id, li->line, sizeof(utx.ut_id));# endif# ifdef HAVE_TYPE_IN_UTMPX	utx.ut_type = DEAD_PROCESS;# endif# ifdef UTMPX_USE_LIBRARY	utmpx_write_library(li, &utx);# else	utmpx_write_direct(li, &utx);# endif	return 1;}intutmpx_write_entry(struct logininfo *li){	switch(li->type) {	case LTYPE_LOGIN:		return utmpx_perform_login(li);	case LTYPE_LOGOUT:		return utmpx_perform_logout(li);	default:		log("utmpx_write_entry: invalid type field");		return 0;	}}#endif /* USE_UTMPX *//** ** Low-level wtmp functions **/#ifdef USE_WTMP/* write a wtmp entry direct to the end of the file *//* This is a slight modification of code in OpenBSD's logwtmp.c */static intwtmp_write(struct logininfo *li, struct utmp *ut){	struct stat buf;	int fd, ret = 1;	if ((fd = open(WTMP_FILE, O_WRONLY|O_APPEND, 0)) < 0) {		log("wtmp_write: problem writing %s: %s",		    WTMP_FILE, strerror(errno));		return 0;	}	if (fstat(fd, &buf) == 0)		if (atomicio(write, fd, ut, sizeof(*ut)) != sizeof(*ut)) {			ftruncate(fd, buf.st_size);			log("wtmp_write: problem writing %s: %s",			    WTMP_FILE, strerror(errno));			ret = 0;		}	(void)close(fd);

⌨️ 快捷键说明

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