]> andersk Git - openssh.git/blobdiff - loginrec.c
- (djm) utmp direct write & SunOS 4 patch from Charles Levert
[openssh.git] / loginrec.c
index bf106f73ab97dcfb7388f08db0f269dc8651010d..7e7d7dd0c0f1cb831f8ee59344030b9a482cef3c 100644 (file)
 
 #include "includes.h"
 
-#if HAVE_UTMP_H
-# include <utmp.h>
-#endif
-#if HAVE_UTMPX_H
-# include <utmpx.h>
-#endif
-#if HAVE_LASTLOG_H
-# include <lastlog.h>
-#endif
-
 #include "ssh.h"
 #include "xmalloc.h"
 #include "loginrec.h"
@@ -281,17 +271,16 @@ login_get_lastlog_time(const int uid)
 struct logininfo *
 login_get_lastlog(struct logininfo *li, const int uid)
 {
-#ifndef USE_LASTLOG
        struct passwd *pw;
-#endif
 
        memset(li, '\0', sizeof(struct logininfo));
        li->uid = uid;
 
-#ifndef USE_LASTLOG
-       /* If we don't have a 'real' lastlog, we need the username to
+       /* 
+        * If we don't have a 'real' lastlog, we need the username to
         * reliably search wtmp(x) for the last login (see
-        * wtmp_get_entry().) */
+        * wtmp_get_entry().) 
+        */
        pw = getpwuid(uid);
        if (pw == NULL)
                fatal("login_get_lastlog: Cannot find account for uid %i", uid);
@@ -299,7 +288,6 @@ login_get_lastlog(struct logininfo *li, const int uid)
        /* No MIN_SIZEOF here - we absolutely *must not* truncate the
          * username */
        strlcpy(li->username, pw->pw_name, sizeof(li->username));
-#endif
 
        if (getlast_entry(li))
                return li;
@@ -452,10 +440,7 @@ int
 getlast_entry(struct logininfo *li)
 {
 #ifdef USE_LASTLOG
-       if (lastlog_get_entry(li))
-               return 1;
-       else
-               return 0;
+       return(lastlog_get_entry(li));
 #else /* !USE_LASTLOG */
 
 #ifdef DISABLE_LASTLOG
@@ -540,11 +525,18 @@ line_abbrevname(char *dst, const char *src, int dstsize)
        
        memset(dst, '\0', dstsize);
        
+       /* Always skip prefix if present */
+       if (strncmp(src, "/dev/", 5) == 0)
+               src += 5;
+               
        len = strlen(src);
 
-       if (len <= 0) {
-               src += (len - dstsize);
-               strncpy(dst, src, dstsize); /* note: _don't_ change this to strlcpy */
+       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;
@@ -614,7 +606,7 @@ construct_utmp(struct logininfo *li,
         */
 
        /* Use strncpy because we don't necessarily want null termination */
-       strncpy(ut->ut_user, li->username, MIN_SIZEOF(ut->ut_user, li->username));
+       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
@@ -652,7 +644,9 @@ void
 construct_utmpx(struct logininfo *li, struct utmpx *utx)
 {
        memset(utx, '\0', sizeof(struct utmpx));
+# 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) {
@@ -738,22 +732,23 @@ utmp_write_direct(struct logininfo *li, struct utmp *ut)
                 * 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 (   read(fd, &old_ut, sizeof(struct utmp)) == sizeof(struct utmp)
-                      && 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  )
+               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 (write(fd, ut, sizeof(struct utmp))==-1)
+               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
+       } else {
                return 0;
+       }
 }
 # endif /* UTMP_USE_LIBRARY */
 
@@ -936,8 +931,7 @@ wtmp_write(struct logininfo *li, struct utmp *ut)
                return 0;
        }
        if (fstat(fd, &buf) == 0) 
-               if (write(fd, (char *)ut, sizeof(struct utmp)) != 
-                   sizeof(struct utmp)) {
+               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));
@@ -1002,8 +996,8 @@ wtmp_write_entry(struct logininfo *li)
 static int
 wtmp_islogin(struct logininfo *li, struct utmp *ut)
 {
-       if (strncmp(li->username, ut->ut_user
-               MIN_SIZEOF(li->username, ut->ut_user)) == 0) {
+       if (strncmp(li->username, ut->ut_name
+               MIN_SIZEOF(li->username, ut->ut_name)) == 0) {
 # ifdef HAVE_TYPE_IN_UTMP
                if (ut->ut_type & USER_PROCESS)
                        return 1;
@@ -1044,7 +1038,7 @@ wtmp_get_entry(struct logininfo *li)
        }
 
        while (!found) {
-               if (read(fd, &ut, sizeof(ut)) != sizeof(ut)) {
+               if (atomicio(read, fd, &ut, sizeof(ut)) != sizeof(ut)) {
                        log("wtmp_get_entry: read of %s failed: %s",
                            WTMP_FILE, strerror(errno));
                        close (fd);
@@ -1104,8 +1098,7 @@ wtmpx_write(struct logininfo *li, struct utmpx *utx)
        }
 
        if (fstat(fd, &buf) == 0) 
-               if (write(fd, (char *)utx, sizeof(struct utmpx)) != 
-                   sizeof(struct utmpx)) {
+               if (atomicio(write, fd, utx, sizeof(*utx)) != sizeof(*utx)) {
                        ftruncate(fd, buf.st_size);
                        log("wtmpx_write: problem writing %s: %s",
                            WTMPX_FILE, strerror(errno));
@@ -1158,8 +1151,8 @@ wtmpx_write_entry(struct logininfo *li)
 static int
 wtmpx_islogin(struct logininfo *li, struct utmpx *utx)
 {
-       if ( strncmp(li->username, utx->ut_user,
-               MIN_SIZEOF(li->username, utx->ut_user)) == 0 ) {
+       if ( strncmp(li->username, utx->ut_name,
+               MIN_SIZEOF(li->username, utx->ut_name)) == 0 ) {
 # ifdef HAVE_TYPE_IN_UTMPX
                if (utx->ut_type == USER_PROCESS)
                        return 1;
@@ -1201,7 +1194,7 @@ wtmpx_get_entry(struct logininfo *li)
        }
 
        while (!found) {
-               if (read(fd, &utx, sizeof(utx)) != sizeof(utx)) {
+               if (atomicio(read, fd, &utx, sizeof(utx)) != sizeof(utx)) {
                        log("wtmpx_get_entry: read of %s failed: %s",
                            WTMPX_FILE, strerror(errno));
                        close (fd);
@@ -1268,8 +1261,8 @@ syslogin_perform_logout(struct logininfo *li)
 #  ifdef HAVE_LOGWTMP
        } else {
                logwtmp(line, "", "");
-       }
 #  endif
+       }
        /* FIXME: (ATL - if the need arises) What to do if we have
         * login, but no logout?  what if logout but no logwtmp? All
         * routines are in libutil so they should all be there,
@@ -1360,7 +1353,7 @@ lastlog_openseek(struct logininfo *li, int *fd, int filemode)
 
        *fd = open(lastlog_file, filemode);
        if ( *fd < 0) {
-               log("lastlog_openseek: Couldn't open %s: %s",
+               debug("lastlog_openseek: Couldn't open %s: %s",
                    lastlog_file, strerror(errno));
                return 0;
        }
@@ -1386,9 +1379,8 @@ lastlog_perform_login(struct logininfo *li)
        lastlog_construct(li, &last);
 
        /* write the entry */
-       if (lastlog_openseek(li, &fd, O_RDWR)) {
-               if (write(fd, &last, sizeof(struct lastlog)) != 
-                       sizeof(struct lastlog)) {
+       if (lastlog_openseek(li, &fd, O_RDWR|O_CREAT)) {
+               if (atomicio(write, fd, &last, sizeof(last)) != sizeof(last)) {
                        log("lastlog_write_filemode: Error writing to %s: %s",
                            LASTLOG_FILE, strerror(errno));
                        return 0;
@@ -1427,9 +1419,8 @@ lastlog_get_entry(struct logininfo *li)
        int fd;
 
        if (lastlog_openseek(li, &fd, O_RDONLY)) {
-               if ( read(fd, &last, sizeof(struct lastlog)) != 
-                       sizeof(struct lastlog) ) {
-                       log("lastlog_write_filemode: Error reading from %s: %s",
+               if (atomicio(read, fd, &last, sizeof(last)) != sizeof(last)) {
+                       log("lastlog_get_entry: Error reading from %s: %s",
                            LASTLOG_FILE, strerror(errno));
                        return 0;
                } else {
This page took 0.051749 seconds and 4 git commands to generate.