LCOV - code coverage report
Current view: top level - source3/smbd - utmp.c (source / functions) Hit Total Coverage
Test: coverage report for master 6248eab5 Lines: 0 104 0.0 %
Date: 2021-08-25 13:27:56 Functions: 0 8 0.0 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             :    utmp routines
       4             :    Copyright (C) T.D.Lee@durham.ac.uk 1999
       5             :    Heavily modified by Andrew Bartlett and Tridge, April 2001
       6             :    
       7             :    This program is free software; you can redistribute it and/or modify
       8             :    it under the terms of the GNU General Public License as published by
       9             :    the Free Software Foundation; either version 3 of the License, or
      10             :    (at your option) any later version.
      11             :    
      12             :    This program is distributed in the hope that it will be useful,
      13             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :    GNU General Public License for more details.
      16             :    
      17             :    You should have received a copy of the GNU General Public License
      18             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      19             : */
      20             : 
      21             : #include "includes.h"
      22             : #include "system/filesys.h"
      23             : #include "smbd/smbd.h"
      24             : 
      25             : /****************************************************************************
      26             : Reflect connection status in utmp/wtmp files.
      27             :         T.D.Lee@durham.ac.uk  September 1999
      28             : 
      29             :         With grateful thanks since then to many who have helped port it to
      30             :         different operating systems.  The variety of OS quirks thereby
      31             :         uncovered is amazing...
      32             : 
      33             : Hints for porting:
      34             :         o  Always attempt to use programmatic interface (pututline() etc.)
      35             :            Indeed, at present only programmatic use is supported.
      36             :         o  The only currently supported programmatic interface to "wtmp{,x}"
      37             :            is through "updwtmp*()" routines.
      38             :         o  The "x" (utmpx/wtmpx; HAVE_UTMPX_H) seems preferable.
      39             :         o  The HAVE_* items should identify supported features.
      40             :         o  If at all possible, avoid "if defined(MY-OS)" constructions.
      41             : 
      42             : OS observations and status:
      43             :         Almost every OS seems to have its own quirks.
      44             : 
      45             :         Solaris 2.x:
      46             :                 Tested on 2.6 and 2.7; should be OK on other flavours.
      47             :         AIX:
      48             :                 Apparently has utmpx.h but doesn't implement.
      49             :         OSF:
      50             :                 Has utmpx.h, but (e.g.) no "getutmpx()".  (Is this like AIX ?)
      51             :         Redhat 6:
      52             :                 utmpx.h seems not to set default filenames.  non-x better.
      53             :         IRIX 6.5:
      54             :                 Not tested.  Appears to have "x".
      55             :         HP-UX 9.x:
      56             :                 Not tested.  Appears to lack "x".
      57             :         HP-UX 10.x:
      58             :                 Not tested.
      59             :                 "updwtmp*()" routines seem absent, so no current wtmp* support.
      60             :                 Has "ut_addr": probably trivial to implement (although remember
      61             :                 that IPv6 is coming...).
      62             : 
      63             :         FreeBSD:
      64             :                 No "putut*()" type of interface.
      65             :                 No "ut_type" and associated defines. 
      66             :                 Write files directly.  Alternatively use its login(3)/logout(3).
      67             :         SunOS 4:
      68             :                 Not tested.  Resembles FreeBSD, but no login()/logout().
      69             : 
      70             : lastlog:
      71             :         Should "lastlog" files, if any, be updated?
      72             :         BSD systems (SunOS 4, FreeBSD):
      73             :                 o  Prominent mention on man pages.
      74             :         System-V (e.g. Solaris 2):
      75             :                 o  No mention on man pages, even under "man -k".
      76             :                 o  Has a "/var/adm/lastlog" file, but pututxline() etc. seem
      77             :                    not to touch it.
      78             :                 o  Despite downplaying (above), nevertheless has <lastlog.h>.
      79             :         So perhaps UN*X "lastlog" facility is intended for tty/terminal only?
      80             : 
      81             : Notes:
      82             :         Each connection requires a small number (starting at 0, working up)
      83             :         to represent the line.  This must be unique within and across all
      84             :         smbd processes.  It is the 'id_num' from Samba's session.c code.
      85             : 
      86             :         The 4 byte 'ut_id' component is vital to distinguish connections,
      87             :         of which there could be several hundred or even thousand.
      88             :         Entries seem to be printable characters, with optional NULL pads.
      89             : 
      90             :         We need to be distinct from other entries in utmp/wtmp.
      91             : 
      92             :         Observed things: therefore avoid them.  Add to this list please.
      93             :         From Solaris 2.x (because that's what I have):
      94             :                 'sN'    : run-levels; N: [0-9]
      95             :                 'co'    : console
      96             :                 'CC'    : arbitrary things;  C: [a-z]
      97             :                 'rXNN'  : rlogin;  N: [0-9]; X: [0-9a-z]
      98             :                 'tXNN'  : rlogin;  N: [0-9]; X: [0-9a-z]
      99             :                 '/NNN'  : Solaris CDE
     100             :                 'ftpZ'  : ftp (Z is the number 255, aka 0377, aka 0xff)
     101             :         Mostly a record uses the same 'ut_id' in both "utmp" and "wtmp",
     102             :         but differences have been seen.
     103             : 
     104             :         Arbitrarily I have chosen to use a distinctive 'SM' for the
     105             :         first two bytes.
     106             : 
     107             :         The remaining two bytes encode the session 'id_num' (see above).
     108             :         Our caller (session.c) should note our 16-bit limitation.
     109             : 
     110             : ****************************************************************************/
     111             : 
     112             : #ifndef WITH_UTMP
     113             : /*
     114             :  * Not WITH_UTMP?  Simply supply dummy routines.
     115             :  */
     116             : 
     117             : void sys_utmp_claim(const char *username, const char *hostname,
     118             :                     const char *id_str, int id_num)
     119             : {}
     120             : 
     121             : void sys_utmp_yield(const char *username, const char *hostname,
     122             :                     const char *id_str, int id_num)
     123             : {}
     124             : 
     125             : #else /* WITH_UTMP */
     126             : 
     127             : #ifdef HAVE_UTMP_H
     128             : #include <utmp.h>
     129             : #endif
     130             : 
     131             : #ifdef HAVE_UTMPX_H
     132             : #include <utmpx.h>
     133             : #endif
     134             : 
     135             : /* BSD systems: some may need lastlog.h (SunOS 4), some may not (FreeBSD) */
     136             : /* Some System-V systems (e.g. Solaris 2) declare this too. */
     137             : #ifdef HAVE_LASTLOG_H
     138             : #include <lastlog.h>
     139             : #endif
     140             : 
     141             : /****************************************************************************
     142             :  Default paths to various {u,w}tmp{,x} files.
     143             : ****************************************************************************/
     144             : 
     145             : #ifdef  HAVE_UTMPX_H
     146             : 
     147             : static const char * const ux_pathname =
     148             : # if defined (UTMPX_FILE)
     149             :         UTMPX_FILE ;
     150             : # elif defined (_UTMPX_FILE)
     151             :         _UTMPX_FILE ;
     152             : # elif defined (_PATH_UTMPX)
     153             :         _PATH_UTMPX ;
     154             : # else
     155             :         "" ;
     156             : # endif
     157             : 
     158             : static const char * const wx_pathname =
     159             : # if defined (WTMPX_FILE)
     160             :         WTMPX_FILE ;
     161             : # elif defined (_WTMPX_FILE)
     162             :         _WTMPX_FILE ;
     163             : # elif defined (_PATH_WTMPX)
     164             :         _PATH_WTMPX ;
     165             : # else
     166             :         "" ;
     167             : # endif
     168             : 
     169             : #endif  /* HAVE_UTMPX_H */
     170             : 
     171             : static const char * const ut_pathname =
     172             : # if defined (UTMP_FILE)
     173             :         UTMP_FILE ;
     174             : # elif defined (_UTMP_FILE)
     175             :         _UTMP_FILE ;
     176             : # elif defined (_PATH_UTMP)
     177             :         _PATH_UTMP ;
     178             : # else
     179             :         "" ;
     180             : # endif
     181             : 
     182             : static const char * const wt_pathname =
     183             : # if defined (WTMP_FILE)
     184             :         WTMP_FILE ;
     185             : # elif defined (_WTMP_FILE)
     186             :         _WTMP_FILE ;
     187             : # elif defined (_PATH_WTMP)
     188             :         _PATH_WTMP ;
     189             : # else
     190             :         "" ;
     191             : # endif
     192             : 
     193             : /* BSD-like systems might want "lastlog" support. */
     194             : #if 0 /* *** Not yet implemented */
     195             : #ifndef HAVE_PUTUTLINE          /* see "pututline_my()" */
     196             : static const char *ll_pathname =
     197             : # if defined (_PATH_LASTLOG)    /* what other names (if any?) */
     198             :         _PATH_LASTLOG ;
     199             : # else
     200             :         "" ;
     201             : # endif /* _PATH_LASTLOG */
     202             : #endif  /* HAVE_PUTUTLINE */
     203             : #endif
     204             : 
     205             : /*
     206             :  * Get name of {u,w}tmp{,x} file.
     207             :  *      return: fname contains filename
     208             :  *              Possibly empty if this code not yet ported to this system.
     209             :  *
     210             :  * utmp{,x}:  try "utmp dir", then default (a define)
     211             :  * wtmp{,x}:  try "wtmp dir", then "utmp dir", then default (a define)
     212             :  */
     213           0 : static char *uw_pathname(TALLOC_CTX *ctx,
     214             :                 const char *uw_name,
     215             :                 const char *uw_default)
     216             : {
     217           0 :         char *dirname = NULL;
     218             : 
     219             :         /* For w-files, first look for explicit "wtmp dir" */
     220           0 :         if (uw_name[0] == 'w') {
     221           0 :                 dirname = talloc_strdup(ctx, lp_wtmp_directory());
     222           0 :                 if (!dirname) {
     223           0 :                         return NULL;
     224             :                 }
     225           0 :                 trim_char(dirname,'\0','/');
     226             :         }
     227             : 
     228             :         /* For u-files and non-explicit w-dir, look for "utmp dir" */
     229           0 :         if ((dirname == NULL) || (strlen(dirname) == 0)) {
     230           0 :                 dirname = talloc_strdup(ctx, lp_utmp_directory());
     231           0 :                 if (!dirname) {
     232           0 :                         return NULL;
     233             :                 }
     234           0 :                 trim_char(dirname,'\0','/');
     235             :         }
     236             : 
     237             :         /* If explicit directory above, use it */
     238           0 :         if (dirname && strlen(dirname) != 0) {
     239           0 :                 return talloc_asprintf(ctx,
     240             :                                 "%s/%s",
     241             :                                 dirname,
     242             :                                 uw_name);
     243             :         }
     244             : 
     245             :         /* No explicit directory: attempt to use default paths */
     246           0 :         if (strlen(uw_default) == 0) {
     247             :                 /* No explicit setting, no known default.
     248             :                  * Has it yet been ported to this OS?
     249             :                  */
     250           0 :                 DEBUG(2,("uw_pathname: unable to determine pathname\n"));
     251             :         }
     252           0 :         return talloc_strdup(ctx, uw_default);
     253             : }
     254             : 
     255             : #ifndef HAVE_PUTUTLINE
     256             : /****************************************************************************
     257             :  Update utmp file directly.  No subroutine interface: probably a BSD system.
     258             : ****************************************************************************/
     259             : 
     260             : static void pututline_my(const char *uname, struct utmp *u, bool claim)
     261             : {
     262             :         DEBUG(1,("pututline_my: not yet implemented\n"));
     263             :         /* BSD implementor: may want to consider (or not) adjusting "lastlog" */
     264             : }
     265             : #endif /* HAVE_PUTUTLINE */
     266             : 
     267             : #ifndef HAVE_UPDWTMP
     268             : 
     269             : /****************************************************************************
     270             :  Update wtmp file directly.  No subroutine interface: probably a BSD system.
     271             :  Credit: Michail Vidiassov <master@iaas.msu.ru>
     272             : ****************************************************************************/
     273             : 
     274             : static void updwtmp_my(const char *wname, struct utmp *u, bool claim)
     275             : {
     276             :         int fd;
     277             :         struct stat buf;
     278             : 
     279             :         if (! claim) {
     280             :                 /*
     281             :                  * BSD-like systems:
     282             :                  *      may use empty ut_name to distinguish a logout record.
     283             :                  *
     284             :                  * May need "if defined(SUNOS4)" etc. around some of these,
     285             :                  * but try to avoid if possible.
     286             :                  *
     287             :                  * SunOS 4:
     288             :                  *      man page indicates ut_name and ut_host both NULL
     289             :                  * FreeBSD 4.0:
     290             :                  *      man page appears not to specify (hints non-NULL)
     291             :                  *      A correspondent suggest at least ut_name should be NULL
     292             :                  */
     293             : #if defined(HAVE_UT_UT_NAME)
     294             :                 memset((char *)&u->ut_name, '\0', sizeof(u->ut_name));
     295             : #endif
     296             : #if defined(HAVE_UT_UT_HOST)
     297             :                 memset((char *)&u->ut_host, '\0', sizeof(u->ut_host));
     298             : #endif
     299             :         }
     300             :         /* Stolen from logwtmp function in libutil.
     301             :          * May be more locking/blocking is needed?
     302             :          */
     303             :         if ((fd = open(wname, O_WRONLY|O_APPEND, 0)) < 0)
     304             :                 return;
     305             :         if (fstat(fd, &buf) == 0) {
     306             :                 if (write(fd, (char *)u, sizeof(struct utmp)) != sizeof(struct utmp))
     307             :                 (void) ftruncate(fd, buf.st_size);
     308             :         }
     309             :         (void) close(fd);
     310             : }
     311             : #endif /* HAVE_UPDWTMP */
     312             : 
     313             : /****************************************************************************
     314             :  Update via utmp/wtmp (not utmpx/wtmpx).
     315             : ****************************************************************************/
     316             : 
     317           0 : static void utmp_nox_update(struct utmp *u, bool claim)
     318             : {
     319           0 :         char *uname = NULL;
     320           0 :         char *wname = NULL;
     321             : #if defined(PUTUTLINE_RETURNS_UTMP)
     322             :         struct utmp *urc;
     323             : #endif /* PUTUTLINE_RETURNS_UTMP */
     324             : 
     325           0 :         uname = uw_pathname(talloc_tos(), "utmp", ut_pathname);
     326           0 :         if (!uname) {
     327           0 :                 return;
     328             :         }
     329           0 :         DEBUG(2,("utmp_nox_update: uname:%s\n", uname));
     330             : 
     331             : #ifdef HAVE_PUTUTLINE
     332           0 :         if (strlen(uname) != 0) {
     333           0 :                 utmpname(uname);
     334             :         }
     335             : 
     336             : # if defined(PUTUTLINE_RETURNS_UTMP)
     337           0 :         setutent();
     338           0 :         urc = pututline(u);
     339           0 :         endutent();
     340           0 :         if (urc == NULL) {
     341           0 :                 DEBUG(2,("utmp_nox_update: pututline() failed\n"));
     342           0 :                 return;
     343             :         }
     344             : # else  /* PUTUTLINE_RETURNS_UTMP */
     345             :         setutent();
     346             :         pututline(u);
     347             :         endutent();
     348             : # endif /* PUTUTLINE_RETURNS_UTMP */
     349             : 
     350             : #else   /* HAVE_PUTUTLINE */
     351             :         if (strlen(uname) != 0) {
     352             :                 pututline_my(uname, u, claim);
     353             :         }
     354             : #endif /* HAVE_PUTUTLINE */
     355             : 
     356           0 :         wname = uw_pathname(talloc_tos(), "wtmp", wt_pathname);
     357           0 :         if (!wname) {
     358           0 :                 return;
     359             :         }
     360           0 :         DEBUG(2,("utmp_nox_update: wname:%s\n", wname));
     361           0 :         if (strlen(wname) != 0) {
     362             : #ifdef HAVE_UPDWTMP
     363           0 :                 updwtmp(wname, u);
     364             :                 /*
     365             :                  * updwtmp() and the newer updwtmpx() may be unsymmetrical.
     366             :                  * At least one OS, Solaris 2.x declares the former in the
     367             :                  * "utmpx" (latter) file and context.
     368             :                  * In the Solaris case this is irrelevant: it has both and
     369             :                  * we always prefer the "x" case, so doesn't come here.
     370             :                  * But are there other systems, with no "x", which lack
     371             :                  * updwtmp() perhaps?
     372             :                  */
     373             : #else
     374             :                 updwtmp_my(wname, u, claim);
     375             : #endif /* HAVE_UPDWTMP */
     376             :         }
     377             : }
     378             : 
     379             : /****************************************************************************
     380             :  Copy a string in the utmp structure.
     381             : ****************************************************************************/
     382             : 
     383           0 : static void utmp_strcpy(char *dest, const char *src, size_t n)
     384             : {
     385           0 :         size_t len = 0;
     386             : 
     387           0 :         memset(dest, '\0', n);
     388           0 :         if (src)
     389           0 :                 len = strlen(src);
     390           0 :         if (len >= n) {
     391           0 :                 memcpy(dest, src, n);
     392             :         } else {
     393           0 :                 if (len)
     394           0 :                         memcpy(dest, src, len);
     395             :         }
     396           0 : }
     397             : 
     398             : /****************************************************************************
     399             :  Update via utmpx/wtmpx (preferred) or via utmp/wtmp.
     400             : ****************************************************************************/
     401             : 
     402           0 : static void sys_utmp_update(struct utmp *u, const char *hostname, bool claim)
     403             : {
     404             : #if !defined(HAVE_UTMPX_H)
     405             :         /* No utmpx stuff.  Drop to non-x stuff */
     406             :         utmp_nox_update(u, claim);
     407             : #elif !defined(HAVE_PUTUTXLINE)
     408             :         /* Odd.  Have utmpx.h but no "pututxline()".  Drop to non-x stuff */
     409             :         DEBUG(1,("utmp_update: have utmpx.h but no pututxline() function\n"));
     410             :         utmp_nox_update(u, claim);
     411             : #elif !defined(HAVE_GETUTMPX)
     412             :         /* Odd.  Have utmpx.h but no "getutmpx()".  Drop to non-x stuff */
     413             :         DEBUG(1,("utmp_update: have utmpx.h but no getutmpx() function\n"));
     414             :         utmp_nox_update(u, claim);
     415             : #elif !defined(HAVE_UPDWTMPX)
     416             :         /* Have utmpx.h but no "updwtmpx()".  Drop to non-x stuff */
     417             :         DEBUG(1,("utmp_update: have utmpx.h but no updwtmpx() function\n"));
     418             :         utmp_nox_update(u, claim);
     419             : #else
     420           0 :         char *uname = NULL;
     421           0 :         char *wname = NULL;
     422             :         struct utmpx ux, *uxrc;
     423             : 
     424           0 :         getutmpx(u, &ux);
     425             : 
     426             : #if defined(HAVE_UX_UT_SYSLEN)
     427             :         if (hostname)
     428             :                 ux.ut_syslen = strlen(hostname) + 1;    /* include end NULL */
     429             :         else
     430             :                 ux.ut_syslen = 0;
     431             : #endif
     432             : #if defined(HAVE_UX_UT_HOST)
     433           0 :         utmp_strcpy(ux.ut_host, hostname, sizeof(ux.ut_host));
     434             : #endif
     435             : 
     436           0 :         uname = uw_pathname(talloc_tos(), "utmpx", ux_pathname);
     437           0 :         wname = uw_pathname(talloc_tos(), "wtmpx", wx_pathname);
     438           0 :         if (uname && wname) {
     439           0 :                 DEBUG(2,("utmp_update: uname:%s wname:%s\n", uname, wname));
     440             :         }
     441             : 
     442             :         /*
     443             :          * Check for either uname or wname being empty.
     444             :          * Some systems, such as Redhat 6, have a "utmpx.h" which doesn't
     445             :          * define default filenames.
     446             :          * Also, our local installation has not provided an override.
     447             :          * Drop to non-x method.  (E.g. RH6 has good defaults in "utmp.h".)
     448             :          */
     449           0 :         if (!uname || !wname || (strlen(uname) == 0) || (strlen(wname) == 0)) {
     450           0 :                 utmp_nox_update(u, claim);
     451             :         } else {
     452           0 :                 utmpxname(uname);
     453           0 :                 setutxent();
     454           0 :                 uxrc = pututxline(&ux);
     455           0 :                 endutxent();
     456           0 :                 if (uxrc == NULL) {
     457           0 :                         DEBUG(2,("utmp_update: pututxline() failed\n"));
     458           0 :                         return;
     459             :                 }
     460           0 :                 updwtmpx(wname, &ux);
     461             :         }
     462             : #endif /* HAVE_UTMPX_H */
     463             : }
     464             : 
     465             : #if defined(HAVE_UT_UT_ID)
     466             : /****************************************************************************
     467             :  Encode the unique connection number into "ut_id".
     468             : ****************************************************************************/
     469             : 
     470           0 : static int ut_id_encode(int i, char *fourbyte)
     471             : {
     472             :         int nbase;
     473           0 :         const char *ut_id_encstr = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
     474             : 
     475             : /*
     476             :  * 'ut_id_encstr' is the character set on which modulo arithmetic is done.
     477             :  * Example: digits would produce the base-10 numbers from '001'.
     478             :  */
     479           0 :         nbase = strlen(ut_id_encstr);
     480             : 
     481           0 :         fourbyte[0] = ut_id_encstr[i % nbase];
     482           0 :         i /= nbase;
     483           0 :         fourbyte[1] = ut_id_encstr[i % nbase];
     484           0 :         i /= nbase;
     485           0 :         fourbyte[3] = ut_id_encstr[i % nbase];
     486           0 :         i /= nbase;
     487           0 :         fourbyte[2] = ut_id_encstr[i % nbase];
     488           0 :         i /= nbase;
     489             : 
     490             :         /* we do not care about overflows as i is a random number */
     491           0 :         return 0;
     492             : }
     493             : #endif /* defined(HAVE_UT_UT_ID) */
     494             : 
     495             : 
     496             : /*
     497             :   fill a system utmp structure given all the info we can gather
     498             : */
     499           0 : static bool sys_utmp_fill(struct utmp *u,
     500             :                         const char *username, const char *hostname,
     501             :                         const char *id_str, int id_num)
     502             : {
     503             :         struct timeval timeval;
     504             : 
     505             :         /*
     506             :          * ut_name, ut_user:
     507             :          *      Several (all?) systems seems to define one as the other.
     508             :          *      It is easier and clearer simply to let the following take its course,
     509             :          *      rather than to try to detect and optimise.
     510             :          */
     511             : #if defined(HAVE_UT_UT_USER)
     512           0 :         utmp_strcpy(u->ut_user, username, sizeof(u->ut_user));
     513             : #elif defined(HAVE_UT_UT_NAME)
     514             :         utmp_strcpy(u->ut_name, username, sizeof(u->ut_name));
     515             : #endif
     516             : 
     517             :         /*
     518             :          * ut_line:
     519             :          *      If size limit proves troublesome, then perhaps use "ut_id_encode()".
     520             :          */
     521           0 :         utmp_strcpy(u->ut_line, id_str, sizeof(u->ut_line));
     522             : 
     523             : #if defined(HAVE_UT_UT_PID)
     524           0 :         u->ut_pid = getpid();
     525             : #endif
     526             : 
     527             : /*
     528             :  * ut_time, ut_tv:
     529             :  *      Some have one, some the other.  Many have both, but defined (aliased).
     530             :  *      It is easier and clearer simply to let the following take its course.
     531             :  *      But note that we do the more precise ut_tv as the final assignment.
     532             :  */
     533             : #if defined(HAVE_UT_UT_TIME)
     534           0 :         GetTimeOfDay(&timeval);
     535           0 :         u->ut_time = timeval.tv_sec;
     536             : #elif defined(HAVE_UT_UT_TV)
     537             :         GetTimeOfDay(&timeval);
     538             :         u->ut_tv = timeval;
     539             : #else
     540             : #error "with-utmp must have UT_TIME or UT_TV"
     541             : #endif
     542             : 
     543             : #if defined(HAVE_UT_UT_HOST)
     544           0 :         utmp_strcpy(u->ut_host, hostname, sizeof(u->ut_host));
     545             : #endif
     546             : 
     547             : #if defined(HAVE_UT_UT_ID)
     548           0 :         if (ut_id_encode(id_num, u->ut_id) != 0) {
     549           0 :                 DEBUG(1,("utmp_fill: cannot encode id %d\n", id_num));
     550           0 :                 return False;
     551             :         }
     552             : #endif
     553             : 
     554           0 :         return True;
     555             : }
     556             : 
     557             : /****************************************************************************
     558             :  Close a connection.
     559             : ****************************************************************************/
     560             : 
     561           0 : void sys_utmp_yield(const char *username, const char *hostname,
     562             :                     const char *id_str, int id_num)
     563             : {
     564             :         struct utmp u;
     565             : 
     566           0 :         ZERO_STRUCT(u);
     567             : 
     568             : #if defined(HAVE_UT_UT_EXIT)
     569           0 :         u.ut_exit.e_termination = 0;
     570           0 :         u.ut_exit.e_exit = 0;
     571             : #endif
     572             : 
     573             : #if defined(HAVE_UT_UT_TYPE)
     574           0 :         u.ut_type = DEAD_PROCESS;
     575             : #endif
     576             : 
     577           0 :         if (!sys_utmp_fill(&u, username, hostname, id_str, id_num))
     578           0 :                 return;
     579             : 
     580           0 :         sys_utmp_update(&u, NULL, False);
     581             : }
     582             : 
     583             : /****************************************************************************
     584             :  Claim a entry in whatever utmp system the OS uses.
     585             : ****************************************************************************/
     586             : 
     587           0 : void sys_utmp_claim(const char *username, const char *hostname,
     588             :                     const char *id_str, int id_num)
     589             : {
     590             :         struct utmp u;
     591             : 
     592           0 :         ZERO_STRUCT(u);
     593             : 
     594             : #if defined(HAVE_UT_UT_TYPE)
     595           0 :         u.ut_type = USER_PROCESS;
     596             : #endif
     597             : 
     598           0 :         if (!sys_utmp_fill(&u, username, hostname, id_str, id_num))
     599           0 :                 return;
     600             : 
     601           0 :         sys_utmp_update(&u, hostname, True);
     602             : }
     603             : 
     604             : #endif /* WITH_UTMP */

Generated by: LCOV version 1.13