* @brief Get host for the current session
*
* @param[out] out Host name
+ * @param[in] main_pid the PID of the main process (the parent PID if
+ * the process forked itself)
*
* @return 0 or a positive integer if the host was obtained properly,
* another value on error.
*/
-extern int get_session_host (char **out);
+extern int get_session_host (char **out, pid_t main_pid);
#ifndef ENABLE_LOGIND
/**
* @brief Update or create an utmp entry in utmp, wtmp, utmpw, or wtmpx
* @param[in] user username
* @param[in] tty tty
* @param[in] host hostname
+ * @param[in] main_pid the PID of the main process (the parent PID if
+ * the process forked itself)
*
* @return 0 if utmp was updated properly,
* 1 on error.
*/
extern int update_utmp (const char *user,
const char *tty,
- const char *host);
+ const char *host,
+ pid_t main_pid);
/**
* @brief Update the cumulative failure log
*
* @param[in] failent_user username
* @param[in] tty tty
* @param[in] host hostname
+ * @param[in] main_pid the PID of the main process (the parent PID if
+ * the process forked itself)
*
*/
extern void record_failure(const char *failent_user,
const char *tty,
- const char *hostname);
+ const char *hostname,
+ pid_t main_pid);
#endif /* ENABLE_LOGIND */
/**
* Return NULL if no entries exist in utmp for the current process.
*/
static /*@null@*/ /*@only@*/struct utmpx *
-get_current_utmp(void)
+get_current_utmp(pid_t main_pid)
{
struct utmpx *ut;
&& (USER_PROCESS != ut->ut_type))
continue;
- if ( ( (ut->ut_pid == getpid ())
- || (ut->ut_pid == getppid ()))
+ if ( (main_pid == ut->ut_pid)
&& ('\0' != ut->ut_id[0])
/* A process may have failed to close an entry
* Check if this entry refers to the current tty */
int
-get_session_host(char **out)
+get_session_host(char **out, pid_t main_pid)
{
int ret = 0;
struct utmpx *ut;
- ut = get_current_utmp();
+ ut = get_current_utmp(main_pid);
#if defined(HAVE_STRUCT_UTMPX_UT_HOST)
if ((ut != NULL) && (ut->ut_host[0] != '\0')) {
*/
static /*@only@*/struct utmpx *
prepare_utmp(const char *name, const char *line, const char *host,
- /*@null@*/const struct utmpx *ut)
+ /*@null@*/const struct utmpx *ut, pid_t main_pid)
{
char *hostname = NULL;
struct utmpx *utent;
utent->ut_type = USER_PROCESS;
- utent->ut_pid = getpid ();
+ utent->ut_pid = main_pid;
STRNCPY(utent->ut_line, line);
if (NULL != ut) {
STRNCPY(utent->ut_id, ut->ut_id);
int
-update_utmp(const char *user, const char *tty, const char *host)
+update_utmp(const char *user, const char *tty, const char *host,
+ pid_t main_pid)
{
struct utmpx *utent, *ut;
- utent = get_current_utmp ();
- ut = prepare_utmp (user, tty, host, utent);
+ utent = get_current_utmp(main_pid);
+ ut = prepare_utmp(user, tty, host, utent, main_pid);
(void) setutmp (ut); /* make entry in the utmp & wtmp files */
void
-record_failure(const char *failent_user, const char *tty, const char *hostname)
+record_failure(const char *failent_user, const char *tty, const char *hostname,
+ pid_t main_pid)
{
struct utmpx *utent, *failent;
if (getdef_str ("FTMP_FILE") != NULL) {
- utent = get_current_utmp ();
- failent = prepare_utmp (failent_user, tty, hostname, utent);
+ utent = get_current_utmp(main_pid);
+ failent = prepare_utmp(failent_user, tty, hostname, utent,
+ main_pid);
failtmp (failent_user, failent);
free (utent);
free (failent);
char *host = NULL;
char tty[BUFSIZ];
char fromhost[512];
+ pid_t initial_pid; /* the "session leader" PID */
const char *failent_user;
const char *tmptty;
const char *cp;
exit (1); /* must be a terminal */
}
- err = get_session_host(&host);
+ initial_pid = getpid();
+ err = get_session_host(&host, initial_pid);
/*
* Be picky if run by normal users (possible if installed setuid
* root), but not if run by root.
failure (pwd->pw_uid, tty, &faillog);
}
#ifndef ENABLE_LOGIND
- record_failure(failent_user, tty, hostname);
+ record_failure(failent_user, tty, hostname, initial_pid);
#endif /* ENABLE_LOGIND */
retries--;
* The utmp entry needs to be updated to indicate the new status
* of the session, the new PID and SID.
*/
- err = update_utmp (username, tty, hostname);
+ err = update_utmp(username, tty, hostname, initial_pid);
if (err != 0) {
SYSLOG ((LOG_WARN, "Unable to update utmp entry for %s", username));
}