RIP BOOL. Convert BOOL -> bool. I found a few interesting
[nivanova/samba-autobuild/.git] / source3 / smbd / utmp.c
index 84ec364654940e7d2c471f85fd5e83c9718e8fbd..e36e2aa042be77dd9c5edbb352337405964d0362 100644 (file)
@@ -6,7 +6,7 @@
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
 
-#ifdef WITH_UTMP
-
 /****************************************************************************
 Reflect connection status in utmp/wtmp files.
        T.D.Lee@durham.ac.uk  September 1999
@@ -81,11 +78,11 @@ lastlog:
 
 Notes:
        Each connection requires a small number (starting at 0, working up)
-       to represent the line (unum).  This must be unique within and across
-       all smbd processes.
+       to represent the line.  This must be unique within and across all
+       smbd processes.  It is the 'id_num' from Samba's session.c code.
 
        The 4 byte 'ut_id' component is vital to distinguish connections,
-       of which there could be several hundered or even thousand.
+       of which there could be several hundred or even thousand.
        Entries seem to be printable characters, with optional NULL pads.
 
        We need to be distinct from other entries in utmp/wtmp.
@@ -105,14 +102,28 @@ Notes:
        Arbitrarily I have chosen to use a distinctive 'SM' for the
        first two bytes.
 
-       The remaining two encode the "unum" (see above).
-
-       For "utmp consolidate" the suggestion was made to encode the pid into
-       those remaining two bytes (16 bits).  But recent UNIX (e.g Solaris 8)
-       is migrating to pids > 16 bits, so we ought not to do this.
+       The remaining two bytes encode the session 'id_num' (see above).
+       Our caller (session.c) should note our 16-bit limitation.
 
 ****************************************************************************/
 
+#ifndef WITH_UTMP
+/*
+ * Not WITH_UTMP?  Simply supply dummy routines.
+ */
+
+void sys_utmp_claim(const char *username, const char *hostname,
+                       const char *ip_addr_str,
+                       const char *id_str, int id_num)
+{}
+
+void sys_utmp_yield(const char *username, const char *hostname,
+                       const char *ip_addr_str,
+                       const char *id_str, int id_num)
+{}
+
+#else /* WITH_UTMP */
+
 #include <utmp.h>
 
 #ifdef HAVE_UTMPX_H
@@ -125,33 +136,6 @@ Notes:
 #include <lastlog.h>
 #endif
 
-/****************************************************************************
- Obtain/release a small number (0 upwards) unique within and across smbds.
-****************************************************************************/
-/*
- * Need a "small" number to represent this connection, unique within this
- * smbd and across all smbds.
- *
- * claim:
- *     Start at 0, hunt up for free, unique number "unum" by attempting to
- *     store it as a key in a tdb database:
- *             key: unum               data: pid+conn  
- *     Also store its inverse, ready for yield function:
- *             key: pid+conn           data: unum
- *
- * yield:
- *     Find key: pid+conn; data is unum;  delete record
- *     Find key: unum ; delete record.
- *
- * Comment:
- *     The claim algorithm (a "for" loop attempting to store numbers in a tdb
- *     database) will be increasingly inefficient with larger numbers of
- *     connections.  Is it possible to write a suitable primitive within tdb?
- *
- *     However, by also storing the inverse key/data pair, we at least make
- *     the yield algorithm efficient.
- */
-
 /****************************************************************************
  Default paths to various {u,w}tmp{,x} files.
 ****************************************************************************/
@@ -232,13 +216,13 @@ static void uw_pathname(pstring fname, const char *uw_name, const char *uw_defau
        /* For w-files, first look for explicit "wtmp dir" */
        if (uw_name[0] == 'w') {
                pstrcpy(dirname,lp_wtmpdir());
-               trim_string(dirname,"","/");
+               trim_char(dirname,'\0','/');
        }
 
        /* For u-files and non-explicit w-dir, look for "utmp dir" */
        if (dirname == 0 || strlen(dirname) == 0) {
                pstrcpy(dirname,lp_utmpdir());
-               trim_string(dirname,"","/");
+               trim_char(dirname,'\0','/');
        }
 
        /* If explicit directory above, use it */
@@ -265,7 +249,7 @@ static void uw_pathname(pstring fname, const char *uw_name, const char *uw_defau
  Update utmp file directly.  No subroutine interface: probably a BSD system.
 ****************************************************************************/
 
-static void pututline_my(pstring uname, struct utmp *u, BOOL claim)
+static void pututline_my(pstring uname, struct utmp *u, bool claim)
 {
        DEBUG(1,("pututline_my: not yet implemented\n"));
        /* BSD implementor: may want to consider (or not) adjusting "lastlog" */
@@ -279,7 +263,7 @@ static void pututline_my(pstring uname, struct utmp *u, BOOL claim)
  Credit: Michail Vidiassov <master@iaas.msu.ru>
 ****************************************************************************/
 
-static void updwtmp_my(pstring wname, struct utmp *u, BOOL claim)
+static void updwtmp_my(pstring wname, struct utmp *u, bool claim)
 {
        int fd;
        struct stat buf;
@@ -298,8 +282,12 @@ static void updwtmp_my(pstring wname, struct utmp *u, BOOL claim)
                 *      man page appears not to specify (hints non-NULL)
                 *      A correspondent suggest at least ut_name should be NULL
                 */
+#if defined(HAVE_UT_UT_NAME)
                memset((char *)&u->ut_name, '\0', sizeof(u->ut_name));
+#endif
+#if defined(HAVE_UT_UT_HOST)
                memset((char *)&u->ut_host, '\0', sizeof(u->ut_host));
+#endif
        }
        /* Stolen from logwtmp function in libutil.
         * May be more locking/blocking is needed?
@@ -318,7 +306,7 @@ static void updwtmp_my(pstring wname, struct utmp *u, BOOL claim)
  Update via utmp/wtmp (not utmpx/wtmpx).
 ****************************************************************************/
 
-static void utmp_nox_update(struct utmp *u, BOOL claim)
+static void utmp_nox_update(struct utmp *u, bool claim)
 {
        pstring uname, wname;
 #if defined(PUTUTLINE_RETURNS_UTMP)
@@ -396,7 +384,7 @@ static void utmp_strcpy(char *dest, const char *src, size_t n)
  Update via utmpx/wtmpx (preferred) or via utmp/wtmp.
 ****************************************************************************/
 
-static void sys_utmp_update(struct utmp *u, const char *hostname, BOOL claim)
+static void sys_utmp_update(struct utmp *u, const char *hostname, bool claim)
 {
 #if !defined(HAVE_UTMPX_H)
        /* No utmpx stuff.  Drop to non-x stuff */
@@ -421,7 +409,9 @@ static void sys_utmp_update(struct utmp *u, const char *hostname, BOOL claim)
        else
                ux.ut_syslen = 0;
 #endif
+#if defined(HAVE_UT_UT_HOST)
        utmp_strcpy(ux.ut_host, hostname, sizeof(ux.ut_host));
+#endif
 
        uw_pathname(uname, "utmpx", ux_pathname);
        uw_pathname(wname, "wtmpx", wx_pathname);
@@ -458,7 +448,7 @@ static int ut_id_encode(int i, char *fourbyte)
 {
        int nbase;
        const char *ut_id_encstr = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
-       
+
        fourbyte[0] = 'S';
        fourbyte[1] = 'M';
 
@@ -480,13 +470,13 @@ static int ut_id_encode(int i, char *fourbyte)
 
 
 /*
-  fill a system utmp structure given all the info we can gather 
+  fill a system utmp structure given all the info we can gather
 */
-static BOOL sys_utmp_fill(struct utmp *u,
-                         const char *username, const char *hostname,
-                         struct in_addr *ipaddr,
-                         const char *id_str, int id_num)
-{                        
+static bool sys_utmp_fill(struct utmp *u,
+                       const char *username, const char *hostname,
+                       const char *ip_addr_str,
+                       const char *id_str, int id_num)
+{
        struct timeval timeval;
 
        /*
@@ -504,14 +494,10 @@ static BOOL sys_utmp_fill(struct utmp *u,
        /*
         * ut_line:
         *      If size limit proves troublesome, then perhaps use "ut_id_encode()".
-        *
-        * Temporary variable "line_tmp" avoids trouble:
-        * o  with unwanted trailing NULL if ut_line full;
-        * o  with overflow if ut_line would be more than full.
         */
        if (strlen(id_str) > sizeof(u->ut_line)) {
-               DEBUG(1,("id_str [%s] is too long for %d char utmp field\n",
-                        id_str, sizeof(u->ut_line)));
+               DEBUG(1,("id_str [%s] is too long for %lu char utmp field\n",
+                        id_str, (unsigned long)sizeof(u->ut_line)));
                return False;
        }
        utmp_strcpy(u->ut_line, id_str, sizeof(u->ut_line));
@@ -521,16 +507,16 @@ static BOOL sys_utmp_fill(struct utmp *u,
 #endif
 
 /*
- * ut_time, ut_tv: 
+ * ut_time, ut_tv:
  *     Some have one, some the other.  Many have both, but defined (aliased).
  *     It is easier and clearer simply to let the following take its course.
  *     But note that we do the more precise ut_tv as the final assignment.
  */
 #if defined(HAVE_UT_UT_TIME)
-       gettimeofday(&timeval, NULL);
+       GetTimeOfDay(&timeval);
        u->ut_time = timeval.tv_sec;
 #elif defined(HAVE_UT_UT_TV)
-       gettimeofday(&timeval, NULL);
+       GetTimeOfDay(&timeval);
        u->ut_tv = timeval;
 #else
 #error "with-utmp must have UT_TIME or UT_TV"
@@ -539,9 +525,22 @@ static BOOL sys_utmp_fill(struct utmp *u,
 #if defined(HAVE_UT_UT_HOST)
        utmp_strcpy(u->ut_host, hostname, sizeof(u->ut_host));
 #endif
-#if defined(HAVE_UT_UT_ADDR)
-       if (ipaddr)
-               u->ut_addr = ipaddr->s_addr;
+#if defined(AF_INET6) && defined(HAVE_UT_UT_ADDR_V6)
+       memset(&u->ut_addr_v6, '\0', sizeof(u->ut_addr_v6));
+       if (ip_addr_str) {
+               struct in6_addr addr;
+               if (inet_pton(AF_INET6, ip_addr_str, &addr) > 0) {
+                       memcpy(&u->ut_addr_v6, &addr, sizeof(addr));
+               }
+       }
+#elif defined(HAVE_UT_UT_ADDR)
+       memset(&u->ut_addr, '\0', sizeof(u->ut_addr));
+       if (ip_addr_str) {
+               struct in_addr addr;
+               if (inet_pton(AF_INET, ip_addr_str, &addr) > 0) {
+                       memcpy(&u->ut_addr, &addr, sizeof(addr));
+               }
+       }
        /*
         * "(unsigned long) ut_addr" apparently exists on at least HP-UX 10.20.
         * Volunteer to implement, please ...
@@ -562,9 +561,9 @@ static BOOL sys_utmp_fill(struct utmp *u,
  Close a connection.
 ****************************************************************************/
 
-void sys_utmp_yield(const char *username, const char *hostname, 
-                   struct in_addr *ipaddr,
-                   const char *id_str, int id_num)
+void sys_utmp_yield(const char *username, const char *hostname,
+                       const char *ip_addr_str,
+                       const char *id_str, int id_num)
 {
        struct utmp u;
 
@@ -579,7 +578,8 @@ void sys_utmp_yield(const char *username, const char *hostname,
        u.ut_type = DEAD_PROCESS;
 #endif
 
-       if (!sys_utmp_fill(&u, username, hostname, ipaddr, id_str, id_num)) return;
+       if (!sys_utmp_fill(&u, username, hostname, ip_addr_str, id_str, id_num))
+               return;
 
        sys_utmp_update(&u, NULL, False);
 }
@@ -588,9 +588,9 @@ void sys_utmp_yield(const char *username, const char *hostname,
  Claim a entry in whatever utmp system the OS uses.
 ****************************************************************************/
 
-void sys_utmp_claim(const char *username, const char *hostname, 
-                   struct in_addr *ipaddr,
-                   const char *id_str, int id_num)
+void sys_utmp_claim(const char *username, const char *hostname,
+                       const char *ip_addr_str,
+                       const char *id_str, int id_num)
 {
        struct utmp u;
 
@@ -600,11 +600,10 @@ void sys_utmp_claim(const char *username, const char *hostname,
        u.ut_type = USER_PROCESS;
 #endif
 
-       if (!sys_utmp_fill(&u, username, hostname, ipaddr, id_str, id_num)) return;
+       if (!sys_utmp_fill(&u, username, hostname, ip_addr_str, id_str, id_num))
+               return;
 
        sys_utmp_update(&u, hostname, True);
 }
 
-#else /* WITH_UTMP */
- void dummy_utmp(void) {}
-#endif
+#endif /* WITH_UTMP */