--- source3/smbd/utmp.c.orig 2019-01-15 10:07:00 UTC +++ source3/smbd/utmp.c @@ -257,7 +257,7 @@ static char *uw_pathname(TALLOC_CTX *ctx Update utmp file directly. No subroutine interface: probably a BSD system. ****************************************************************************/ -static void pututline_my(const char *uname, struct utmp *u, bool claim) +static void pututline_my(const char *uname, STRUCT_UTMP *u, bool claim) { DEBUG(1,("pututline_my: not yet implemented\n")); /* BSD implementor: may want to consider (or not) adjusting "lastlog" */ @@ -271,7 +271,7 @@ static void pututline_my(const char *una Credit: Michail Vidiassov ****************************************************************************/ -static void updwtmp_my(const char *wname, struct utmp *u, bool claim) +static void updwtmp_my(const char *wname, STRUCT_UTMP *u, bool claim) { int fd; struct stat buf; @@ -303,7 +303,7 @@ static void updwtmp_my(const char *wname if ((fd = open(wname, O_WRONLY|O_APPEND, 0)) < 0) return; if (fstat(fd, &buf) == 0) { - if (write(fd, (char *)u, sizeof(struct utmp)) != sizeof(struct utmp)) + if (write(fd, (char *)u, sizeof(STRUCT_UTMP)) != sizeof(STRUCT_UTMP)) (void) ftruncate(fd, buf.st_size); } (void) close(fd); @@ -314,12 +314,12 @@ static void updwtmp_my(const char *wname 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) { char *uname = NULL; char *wname = NULL; #if defined(PUTUTLINE_RETURNS_UTMP) - struct utmp *urc; + STRUCT_UTMP *urc; #endif /* PUTUTLINE_RETURNS_UTMP */ uname = uw_pathname(talloc_tos(), "utmp", ut_pathname); @@ -376,127 +376,52 @@ static void utmp_nox_update(struct utmp } } -/**************************************************************************** - Copy a string in the utmp structure. -****************************************************************************/ -static void utmp_strcpy(char *dest, const char *src, size_t n) -{ - size_t len = 0; - memset(dest, '\0', n); - if (src) - len = strlen(src); - if (len >= n) { - memcpy(dest, src, n); - } else { - if (len) - memcpy(dest, src, len); - } -} + /**************************************************************************** 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 */ - utmp_nox_update(u, claim); -#elif !defined(HAVE_PUTUTXLINE) - /* Odd. Have utmpx.h but no "pututxline()". Drop to non-x stuff */ - DEBUG(1,("utmp_update: have utmpx.h but no pututxline() function\n")); - utmp_nox_update(u, claim); -#elif !defined(HAVE_GETUTMPX) - /* Odd. Have utmpx.h but no "getutmpx()". Drop to non-x stuff */ - DEBUG(1,("utmp_update: have utmpx.h but no getutmpx() function\n")); - utmp_nox_update(u, claim); -#elif !defined(HAVE_UPDWTMPX) - /* Have utmpx.h but no "updwtmpx()". Drop to non-x stuff */ - DEBUG(1,("utmp_update: have utmpx.h but no updwtmpx() function\n")); - utmp_nox_update(u, claim); -#else - char *uname = NULL; - char *wname = NULL; - struct utmpx ux, *uxrc; - - getutmpx(u, &ux); - -#if defined(HAVE_UX_UT_SYSLEN) - if (hostname) - ux.ut_syslen = strlen(hostname) + 1; /* include end NULL */ - else - ux.ut_syslen = 0; -#endif -#if defined(HAVE_UX_UT_HOST) - utmp_strcpy(ux.ut_host, hostname, sizeof(ux.ut_host)); -#endif - - uname = uw_pathname(talloc_tos(), "utmpx", ux_pathname); - wname = uw_pathname(talloc_tos(), "wtmpx", wx_pathname); - if (uname && wname) { - DEBUG(2,("utmp_update: uname:%s wname:%s\n", uname, wname)); - } + STRUCT_UTMP *urc; - /* - * Check for either uname or wname being empty. - * Some systems, such as Redhat 6, have a "utmpx.h" which doesn't - * define default filenames. - * Also, our local installation has not provided an override. - * Drop to non-x method. (E.g. RH6 has good defaults in "utmp.h".) - */ - if (!uname || !wname || (strlen(uname) == 0) || (strlen(wname) == 0)) { - utmp_nox_update(u, claim); - } else { - utmpxname(uname); - setutxent(); - uxrc = pututxline(&ux); - endutxent(); - if (uxrc == NULL) { - DEBUG(2,("utmp_update: pututxline() failed\n")); - return; - } - updwtmpx(wname, &ux); + setutxent(); + urc = pututxline(u); + endutxent(); + if (urc == NULL) { + DEBUG(2,("utmp_update: pututxline() failed\n")); + return; } -#endif /* HAVE_UTMPX_H */ } #if defined(HAVE_UT_UT_ID) /**************************************************************************** Encode the unique connection number into "ut_id". ****************************************************************************/ - -static int ut_id_encode(int i, char *fourbyte) +static void ut_id_encode(char *buf, int id, size_t buf_size) { - int nbase; - const char *ut_id_encstr = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; - -/* - * 'ut_id_encstr' is the character set on which modulo arithmetic is done. - * Example: digits would produce the base-10 numbers from '001'. - */ - nbase = strlen(ut_id_encstr); + const char ut_id_encstr[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; - fourbyte[0] = ut_id_encstr[i % nbase]; - i /= nbase; - fourbyte[1] = ut_id_encstr[i % nbase]; - i /= nbase; - fourbyte[3] = ut_id_encstr[i % nbase]; - i /= nbase; - fourbyte[2] = ut_id_encstr[i % nbase]; - i /= nbase; + int nbase = sizeof(ut_id_encstr) - 1; + /* + * 'ut_id_encstr' is the character set on which modulo arithmetic is done. + * Example: digits would produce the base-10 numbers from '001'. + */ - /* we do not care about overflows as i is a random number */ - return 0; + for(int i = 0; i < buf_size; i++) { + buf[i] = ut_id_encstr[id % nbase]; + id /= nbase; + } } #endif /* defined(HAVE_UT_UT_ID) */ - /* fill a system utmp structure given all the info we can gather */ -static bool sys_utmp_fill(struct utmp *u, +static bool sys_utmp_fill(STRUCT_UTMP *u, const char *username, const char *hostname, const char *id_str, int id_num) { @@ -509,16 +434,16 @@ static bool sys_utmp_fill(struct utmp *u * rather than to try to detect and optimise. */ #if defined(HAVE_UT_UT_USER) - utmp_strcpy(u->ut_user, username, sizeof(u->ut_user)); + strncpy(u->ut_user, username, sizeof(u->ut_user)); #elif defined(HAVE_UT_UT_NAME) - utmp_strcpy(u->ut_name, username, sizeof(u->ut_name)); + strncpy(u->ut_name, username, sizeof(u->ut_name)); #endif /* * ut_line: * If size limit proves troublesome, then perhaps use "ut_id_encode()". */ - utmp_strcpy(u->ut_line, id_str, sizeof(u->ut_line)); + strncpy(u->ut_line, id_str, sizeof(u->ut_line)); #if defined(HAVE_UT_UT_PID) u->ut_pid = getpid(); @@ -535,20 +460,23 @@ static bool sys_utmp_fill(struct utmp *u u->ut_time = timeval.tv_sec; #elif defined(HAVE_UT_UT_TV) GetTimeOfDay(&timeval); - u->ut_tv = timeval; + u->ut_tv.tv_sec = timeval.tv_sec; + u->ut_tv.tv_usec = timeval.tv_usec; #else #error "with-utmp must have UT_TIME or UT_TV" #endif #if defined(HAVE_UT_UT_HOST) - utmp_strcpy(u->ut_host, hostname, sizeof(u->ut_host)); + if(hostname != NULL) { + strncpy(u->ut_host, hostname, sizeof(u->ut_host)); +#if defined(HAVE_UT_UT_SYSLEN) + u->ut_syslen = strlen(hostname) + 1; /* include trailing NULL */ +#endif + } #endif #if defined(HAVE_UT_UT_ID) - if (ut_id_encode(id_num, u->ut_id) != 0) { - DEBUG(1,("utmp_fill: cannot encode id %d\n", id_num)); - return False; - } + ut_id_encode(u->ut_id, id_num, sizeof(u->ut_id)); #endif return True; @@ -561,7 +489,7 @@ static bool sys_utmp_fill(struct utmp *u void sys_utmp_yield(const char *username, const char *hostname, const char *id_str, int id_num) { - struct utmp u; + STRUCT_UTMP u; ZERO_STRUCT(u); @@ -587,7 +515,7 @@ void sys_utmp_yield(const char *username void sys_utmp_claim(const char *username, const char *hostname, const char *id_str, int id_num) { - struct utmp u; + STRUCT_UTMP u; ZERO_STRUCT(u);