Changed the new "plussed_user" option to mts.conf's "masquerade:" to
[mmh] / zotnet / mts / mts.c
index 61a604c..9194404 100644 (file)
@@ -60,9 +60,11 @@ char *mmdlm2 = "\001\001\001\001\n";
 static char username[BUFSIZ];
 static char fullname[BUFSIZ];
 
-/* variables for username masquerading */
-static int MMailids = 0;
-static char *mmailid = "0";
+/* Variables for username masquerading: */
+       boolean  draft_from_masquerading = FALSE;  /* also used from post.c */
+static boolean  mmailid_masquerading = FALSE;
+static boolean  username_extension_masquerading = FALSE;
+static char*    masquerade = "";
 
 
 /*
@@ -128,7 +130,7 @@ static struct bind binds[] = {
     { "uucplfil", &uucplfil },
     { "mmdelim1", &mmdlm1 },
     { "mmdelim2", &mmdlm2 },
-    { "mmailid", &mmailid },
+    { "masquerade", &masquerade },
 
 #if defined(SENDMTS) || defined(SMTPMTS)
     { "hostable", &hostable },
@@ -196,8 +198,17 @@ mts_init (char *name)
     }
 
     fclose (fp);
-    MMailids = atoi (mmailid);
+
     Everyone = atoi (everyone);
+
+    if (strstr(masquerade, "draft_from") != NULL)
+       draft_from_masquerading = TRUE;
+
+    if (strstr(masquerade, "mmailid") != NULL)
+       mmailid_masquerading = TRUE;
+
+    if (strstr(masquerade, "username_extension") != NULL)
+       username_extension_masquerading = TRUE;
 }
 
 
@@ -375,7 +386,8 @@ getfullname (void)
 
 /*
  * Find the user's username and full name, and cache them.
- * It also handles mmailid processing (username masquerading)
+ * Also, handle "mmailid" username masquerading controlled from the GECOS field
+ * of the passwd file. 
  */
 
 static void
@@ -399,7 +411,6 @@ getuserinfo (void)
            || pw->pw_name == NULL
            || *pw->pw_name == '\0') {
 #endif /* KPOP */
-
        strncpy (username, "unknown", sizeof(username));
        snprintf (fullname, sizeof(fullname), "The Unknown User-ID (%d)",
                (int) getuid ());
@@ -408,38 +419,97 @@ getuserinfo (void)
 
     np = pw->pw_gecos;
 
-    /*
-     * Do mmailid (username masquerading) processing.  The GECOS
-     * field should have the form "Full Name <fakeusername>".
-     */
-#ifndef        GCOS_HACK
-    for (cp = fullname; *np && *np != (MMailids ? '<' : ','); *cp++ = *np++)
-       continue;
-#else
-    for (cp = fullname; *np && *np != (MMailids ? '<' : ','); ) {
-       if (*np == '&') {       /* blech! */
-           strcpy (cp, pw->pw_name);
-           *cp = toupper(*cp);
-           while (*cp)
-               cp++;
-           np++;
-       } else {
-           *cp++ = *np++;
+    /* Get the user's real name from the GECOS field.  Stop once we hit a ',',
+       which some OSes use to separate other 'finger' information in the GECOS
+       field, like phone number.  Also, if mmailid masquerading is turned on due
+       to "mmailid" appearing on the "masquerade:" line of mts.conf, stop if we
+       hit a '<' (which should precede any ','s). */
+#ifndef BSD42
+    if (mmailid_masquerading)
+       /* Stop at ',' or '<'. */
+       for (cp = fullname; *np != '\0' && *np != ',' && *np != '<';
+            *cp++ = *np++)
+           continue;
+    else
+       /* Allow '<' as a legal character of the user's name.  This code is
+          basically a duplicate of the code above the "else" -- we don't
+          collapse it down to one copy and put the mmailid_masquerading check
+          inside the loop with "(x ? y : z)" because that's inefficient and the
+          value'll never change while it's in there. */
+       for (cp = fullname; *np != '\0' && *np != ',';
+            *cp++ = *np++)
+           continue;
+#else /* BSD42 */
+    /* On BSD(-derived) systems, the system utilities that deal with the GECOS
+       field (finger, mail, sendmail, etc.) translate any '&' character in it to
+       the login name, with the first letter capitalized.  So, for instance,
+       fingering a user "bob" with the GECOS field "& Jones" would reveal him to
+       be "In real life: Bob Jones".  Surprisingly, though, the OS doesn't do
+       the translation for you, so we have to do it manually here. */
+    if (mmailid_masquerading)
+       /* Stop at ',' or '<'. */
+       for (cp = fullname;
+            *np != '\0' && *np != ',' && *np != '<';) {
+           if (*np == '&')     {       /* blech! */
+               strcpy (cp, pw->pw_name);
+               *cp = toupper(*cp);
+               while (*cp)
+                   cp++;
+               np++;
+           } else {
+               *cp++ = *np++;
+           }
        }
-    }
-#endif
-
+    else
+       /* Allow '<' as a legal character of the user's name.  This code is
+          basically a duplicate of the code above the "else" -- we don't
+          collapse it down to one copy and put the mmailid_masquerading check
+          inside the loop with "(x ? y : z)" because that's inefficient and the
+          value'll never change while it's in there. */
+       for (cp = fullname;
+            *np != '\0' && *np != ',';) {
+           if (*np == '&')     {       /* blech! */
+               strcpy (cp, pw->pw_name);
+               *cp = toupper(*cp);
+               while (*cp)
+                   cp++;
+               np++;
+           } else {
+               *cp++ = *np++;
+           }
+       }
+#endif /* BSD42 */
     *cp = '\0';
-    if (MMailids) {
+
+    if (mmailid_masquerading) {
+       /* Do mmailid processing.  The GECOS field should have the form
+          "Full Name <fakeusername>".  For instance,
+          "Dan Harkless <Dan.Harkless>".  Naturally, you'll want your MTA to
+          have an alias (e.g. in /etc/aliases) from "fakeusername" to your
+          account name.  */ 
        if (*np)
            np++;
        for (cp = username; *np && *np != '>'; *cp++ = *np++)
            continue;
        *cp = '\0';
     }
-    if (MMailids == 0 || *np == '\0')
+    if (!mmailid_masquerading || *np == '\0')
        strncpy (username, pw->pw_name, sizeof(username));
 
+    if (username_extension_masquerading) {
+       char*  username_extension = getenv("USERNAME_EXTENSION");
+
+       if (username_extension != NULL && *username_extension != '\0')
+           /* $USERNAME_EXTENSION environment variable has been set, so tack on
+              its value to the actual username.  This is meant to interact with
+              qmail's "user-extension" feature and sendmail's "plussed user"
+              feature. */
+           snprintf(username, sizeof(username), "%s%s",
+                    username, username_extension);
+    }
+
+    /* The $SIGNATURE environment variable overrides the GECOS field's idea of
+       your real name. */
     if ((cp = getenv ("SIGNATURE")) && *cp)
        strncpy (fullname, cp, sizeof(fullname));