Apply better logic to guess the username when getlogin(3) is not
available for some reason, e.g. no login session at all, no access
to utmp/wtmp, etc.

--- a/dma.c
+++ b/dma.c
@@ -75,6 +75,8 @@
 struct authusers authusers = LIST_HEAD_INITIALIZER(authusers);
 static int daemonize = 1;
 struct config *config;
+static const char *username;
+static uid_t uid;
 static struct strlist seenmsg[16][16];
 
 static int open_locked(const char *, int);
@@ -118,6 +120,45 @@
 	return name;
 }
 
+static const char *
+check_username(const char *username, uid_t uid)
+{
+	struct passwd *pwd;
+
+	if (username == NULL)
+		return (NULL);
+	pwd = getpwnam(username);
+	if (pwd == NULL || pwd->pw_uid != uid)
+		return (NULL);
+	return (username);
+}
+
+static void
+set_username(void)
+{
+	struct passwd *pwd;
+	char *u;
+
+	uid = getuid();
+	username = check_username(getlogin(), uid);
+	if (username == NULL)
+		username = check_username(getenv("LOGNAME"), uid);
+	if (username == NULL)
+		username = check_username(getenv("USER"), uid);
+	if (username == NULL) {
+		pwd = getpwuid(uid);
+		if (pwd != NULL && pwd->pw_name != NULL &&
+		    pwd->pw_name[0] != '\0')
+			username = check_username(strdup(pwd->pw_name), uid);
+	}
+	if (username == NULL) {
+		asprintf(&u, "%ld", (long)uid);
+		username = u;
+	}
+	if (username == NULL)
+		username = "unknown-or-invalid-username";
+}
+
 static char *
 set_from(const char *osender)
 {
@@ -126,7 +167,7 @@
 
 	if ((config->features & VIRTUAL) != 0) {
 		SLIST_FOREACH(v, &virtusers, next) {
-			if (strcmp(v->login, getlogin()) == 0) {
+			if (strcmp(v->login, username) == 0) {
 				sender = strdup(v->address);
 				if (sender == NULL)
 					return(NULL);
@@ -140,7 +181,7 @@
 		if (sender == NULL)
 			return (NULL);
 	} else {
-		if (asprintf(&sender, "%s@%s", getlogin(), hostname()) <= 0)
+		if (asprintf(&sender, "%s@%s", username, hostname()) <= 0)
 			return (NULL);
 	}
 
@@ -368,7 +409,7 @@
 \tid %"PRIxMAX"\n\
 \tby %s (%s)\n\
 \t%s\n",
-		getlogin(), getuid(),
+		username, uid,
 		sender,
 		queue->id,
 		hostname(), VERSION,
@@ -1182,6 +1223,7 @@
 	opterr = 1;
 
 	openlog(tag, LOG_PID | LOG_PERROR, LOG_MAIL);
+	set_username();
 
 	config = malloc(sizeof(struct config));
 	if (config == NULL)
