Bug 16081

Summary: [PATCH] utmp, wtmp, lastlog support for gnome-terminal
Product: Ports & Packages Reporter: ajk <ajk>
Component: Individual Port(s)Assignee: Ade Lovett <ade>
Status: Closed FIXED    
Severity: Affects Only Me CC: jirka
Priority: Normal    
Version: Latest   
Hardware: Any   
OS: Any   
Attachments:
Description Flags
file.diff none

Description ajk 2000-01-12 17:00:01 UTC
The utmp and wtmp support gnome-terminal is broken, and lastlog
support is nonexistent.  The gnome-pty-helper program uses seteuid()
to give up root privileges but tries to use setuid() to get them
back.  The patches below fix that problem and add lastlog support.

Fix: Apply the following patches to the gnomelibs and gnomecore
distributions and reinstall gnome-pty-helper and gnome-terminal.
Note that gnome-pty-helper also needs to be setuid-root, not the
default, for these features to work.

------- begin gnomelibs patch

------- end gnomelibs patch

------- begin gnomecore patch



------- end gnomecore patch--KUWqNa0ZjONstMYmXg99dxeMN0jNUcdrpMOSF3Itq5cYyZ6s
Content-Type: text/plain; name="file.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="file.diff"

--- zvt/gnome-pty-helper.c.orig	Fri Jan  7 12:42:13 2000
+++ zvt/gnome-pty-helper.c	Wed Jan 12 10:25:16 2000
@@ -319,7 +319,7 @@
 }
 
 static int
-open_ptys (int utmp, int wtmp)
+open_ptys (int utmp, int wtmp, int lastlog)
 {
 	char *term_name;
 	int status, master_pty, slave_pty;
@@ -486,8 +486,13 @@
 #endif
 
 	status = openpty (&master_pty, &slave_pty, term_name, &term, NULL);
+#ifdef HAVE_SETEUID
+	seteuid(savedUid);
+	setegid(savedGid);
+#else
 	setuid(savedUid);
 	setgid(savedGid);
+#endif
 
 	if (status == -1){
 		result = 0;
@@ -509,8 +514,8 @@
 		exit (0);
 	}
 
-	if (utmp || wtmp){
-		p->data = update_dbs (utmp, wtmp, login_name, display_name, term_name);
+	if (utmp || wtmp || lastlog){
+		p->data = update_dbs (utmp, wtmp, lastlog, login_name, display_name, term_name);
 	}
 	
 	return 1;
@@ -664,19 +669,35 @@
 
 		switch (op){
 		case GNOME_PTY_OPEN_PTY_UTMP:
-			open_ptys (1, 0);
+			open_ptys (1, 0, 0);
 			break;
 			
 		case GNOME_PTY_OPEN_PTY_UWTMP:
-			open_ptys (1, 1);
+			open_ptys (1, 1, 0);
 			break;
 			
 		case GNOME_PTY_OPEN_PTY_WTMP:
-			open_ptys (0, 1);
+			open_ptys (0, 1, 0);
 			break;
 			
+		case GNOME_PTY_OPEN_PTY_LASTLOG:
+			open_ptys (0, 0, 1);
+			break;
+
+		case GNOME_PTY_OPEN_PTY_LASTLOGUTMP:
+			open_ptys (1, 0, 1);
+			break;
+
+		case GNOME_PTY_OPEN_PTY_LASTLOGUWTMP:
+			open_ptys (1, 1, 1);
+			break;
+
+		case GNOME_PTY_OPEN_PTY_LASTLOGWTMP:
+			open_ptys (0, 1, 1);
+			break;
+
 		case GNOME_PTY_OPEN_NO_DB_UPDATE:
-			open_ptys (0, 0);
+			open_ptys (0, 0, 0);
 			break;
 			
 		case GNOME_PTY_CLOSE_PTY:
--- zvt/gnome-pty.h.orig	Wed Jan 12 10:22:01 2000
+++ zvt/gnome-pty.h	Wed Jan 12 10:35:06 2000
@@ -5,12 +5,16 @@
 	GNOME_PTY_OPEN_PTY_UTMP = 1,
 	GNOME_PTY_OPEN_PTY_UWTMP,
 	GNOME_PTY_OPEN_PTY_WTMP,
+	GNOME_PTY_OPEN_PTY_LASTLOG,
+	GNOME_PTY_OPEN_PTY_LASTLOGUTMP,
+	GNOME_PTY_OPEN_PTY_LASTLOGUWTMP,
+	GNOME_PTY_OPEN_PTY_LASTLOGWTMP,
 	GNOME_PTY_OPEN_NO_DB_UPDATE,
 	GNOME_PTY_CLOSE_PTY
 } GnomePtyOps;
 
-void *update_dbs         (int utmp, int wtmp, char *login_name, char *display_name, char *term_name);
-void *write_login_record (char *login_name, char *display_name, char *term_name, int utmp, int wtmp);
+void *update_dbs         (int utmp, int wtmp, int lastlog, char *login_name, char *display_name, char *term_name);
+void *write_login_record (char *login_name, char *display_name, char *term_name, int utmp, int wtmp, int lastlog);
 void write_logout_record (void *data, int utmp, int wtmp);
 
 #endif
--- zvt/gnome-utmp.c.orig	Wed Jan 12 07:44:41 2000
+++ zvt/gnome-utmp.c	Wed Jan 12 11:24:30 2000
@@ -31,6 +31,11 @@
 #    include <paths.h>
 #endif
 
+#ifdef _PATH_LASTLOG
+#include <sys/types.h>
+#include <sys/uio.h>
+#endif /* _PATH_LASTLOG */
+
 #if defined(HAVE_UTMPX_H)
 #    include <utmpx.h>
 #endif
@@ -165,6 +170,30 @@
 }
 #endif
 
+#ifdef _PATH_LASTLOG
+static void
+update_lastlog(UTMP *ut)
+{
+	int		 fd;
+	struct iovec	*p;
+	struct iovec	 iov[3];
+
+	p = iov;
+	p->iov_base = (char *)&ut->ut_time;
+	p->iov_len = sizeof ut->ut_time;
+	(++p)->iov_base = ut->ut_line;
+	p->iov_len = sizeof ut->ut_line;
+	(++p)->iov_base = ut->ut_host;
+	p->iov_len = sizeof ut->ut_host;
+	if ((fd = open(_PATH_LASTLOG, O_WRONLY, 0)) >= 0) {
+		(void) lseek(fd, getuid() * sizeof (struct lastlog),
+		    SEEK_SET);
+		(void) writev(fd, iov, sizeof iov / sizeof (struct iovec));
+		(void) close(fd);
+	}
+}
+#endif /* _PATH_LASTLOG */
+
 void 
 write_logout_record (void *data, int utmp, int wtmp)
 {
@@ -197,7 +226,7 @@
 }
 
 void *
-write_login_record (char *login_name, char *display_name, char *term_name, int utmp, int wtmp)
+write_login_record (char *login_name, char *display_name, char *term_name, int utmp, int wtmp, int lastlog)
 {
 	UTMP *ut;
 	char *pty = term_name;
@@ -263,6 +292,11 @@
 #    endif
 #endif
 
+#ifdef _PATH_LASTLOG
+	if (lastlog)
+		update_lastlog(ut);
+#endif /* _PATH_LASTLOG */
+
 	if (utmp)
 		update_utmp (ut);
 
@@ -273,7 +307,7 @@
 }
 
 void *
-update_dbs (int utmp, int wtmp, char *login_name, char *display_name, char *term_name)
+update_dbs (int utmp, int wtmp, int lastlog, char *login_name, char *display_name, char *term_name)
 {
-	return write_login_record (login_name, display_name, term_name, utmp, wtmp);
+	return write_login_record (login_name, display_name, term_name, utmp, wtmp, lastlog);
 }
--- zvt/subshell.c.orig	Wed Jan 12 10:25:30 2000
+++ zvt/subshell.c	Wed Jan 12 11:23:49 2000
@@ -25,6 +25,7 @@
 #include "subshell-includes.h"
 #define ZVT_TERM_DO_UTMP_LOG 1
 #define ZVT_TERM_DO_WTMP_LOG 2
+#define ZVT_TERM_DO_LASTLOG  4
 
 /* Pid of the helper SUID process */
 static pid_t helper_pid;
@@ -260,14 +261,22 @@
 	op = GNOME_PTY_OPEN_NO_DB_UPDATE;
 	
 	if (update_wutmp & ZVT_TERM_DO_UTMP_LOG){
-		if (update_wutmp & ZVT_TERM_DO_WTMP_LOG)
+		if (update_wutmp & (ZVT_TERM_DO_WTMP_LOG | ZVT_TERM_DO_LASTLOG))
+			op = GNOME_PTY_OPEN_PTY_LASTLOGUWTMP;
+		else if (update_wutmp & ZVT_TERM_DO_WTMP_LOG)
 			op = GNOME_PTY_OPEN_PTY_UWTMP;
+		else if (update_wutmp & ZVT_TERM_DO_LASTLOG)
+			op = GNOME_PTY_OPEN_PTY_LASTLOGUTMP;
 		else
 			op = GNOME_PTY_OPEN_PTY_UTMP;
-	} else {
-		if (update_wutmp & ZVT_TERM_DO_WTMP_LOG)
+	} else if (update_wutmp & ZVT_TERM_DO_WTMP_LOG) {
+		if (update_wutmp & (ZVT_TERM_DO_WTMP_LOG | ZVT_TERM_DO_LASTLOG))
+			op = GNOME_PTY_OPEN_PTY_LASTLOGWTMP;
+		else if (update_wutmp & ZVT_TERM_DO_WTMP_LOG)
 			op = GNOME_PTY_OPEN_PTY_WTMP;
-	}
+	} else
+		if (update_wutmp & ZVT_TERM_DO_LASTLOG)
+			op = GNOME_PTY_OPEN_PTY_LASTLOG;
 	
 	if (write (helper_socket_protocol [0], &op, sizeof (op)) < 0)
 		return NULL;
--- zvt/test-utmp.c.orig	Wed Jan 12 10:22:06 2000
+++ zvt/test-utmp.c	Wed Jan 12 10:24:21 2000
@@ -8,7 +8,7 @@
 main ()
 {
 void *utmp;
-	utmp = update_dbs (1, 1, "testlogin", ":0", "/dev/ttyp9");
+	utmp = update_dbs (1, 1, 1, "testlogin", ":0", "/dev/ttyp9");
 	sleep (120);
 	write_logout_record (utmp, 1, 1);
 	return 0;
--- zvt/zterm.c.orig	Wed Jan 12 10:55:55 2000
+++ zvt/zterm.c	Wed Jan 12 10:56:13 2000
@@ -264,7 +264,7 @@
   gtk_widget_show (window);
 
   /* fork the shell/program */
-  switch (zvt_term_forkpty(ZVT_TERM (term), ZVT_TERM_DO_UTMP_LOG | ZVT_TERM_DO_WTMP_LOG)) {
+  switch (zvt_term_forkpty(ZVT_TERM (term), ZVT_TERM_DO_UTMP_LOG | ZVT_TERM_DO_WTMP_LOG | ZVT_TERM_DO_LASTLOG)) {
   case -1:
     perror("ERROR: unable to fork:");
     exit(1);
--- zvt/zvtterm.h.orig	Wed Jan 12 10:36:48 2000
+++ zvt/zvtterm.h	Wed Jan 12 10:37:21 2000
@@ -177,6 +177,7 @@
 /* options for fork */
 #define ZVT_TERM_DO_UTMP_LOG 1
 #define ZVT_TERM_DO_WTMP_LOG 2
+#define ZVT_TERM_DO_LASTLOG  4
 
 /* background flag options */
 #define ZVT_BACKGROUND_SHADED 0x01 /* shade background image.  This must be left as 1 for api compat! */
How-To-Repeat: 
Run gnome-terminal.
Comment 1 Ade Lovett freebsd_committer freebsd_triage 2000-01-13 19:16:51 UTC
Responsible Changed
From-To: freebsd-ports->ade

I'll deal with this on the next GNOME update 


Date: Thu, 13 Jan 2000 09:34:20 -0600
Comment 2 Ade Lovett freebsd_committer freebsd_triage 2000-01-14 20:56:51 UTC
State Changed
From-To: open->closed

Fix committed, thanks!        
(please also file a report at bugs.gnome.org)