NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

bin/48445: mail(1)/mailx(1): put ambigious $USER/-u user/xy handling, um, straight



>Number:         48445
>Category:       bin
>Synopsis:       mail(1)/mailx(1): put ambigious $USER/-u user/xy handling, um, 
>straight
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Dec 12 11:35:00 +0000 2013
>Originator:     Steffen
>Release:        6.99.24
>Organization:
>Environment:
-
>Description:
The manual falsely claims that '-u user' is equivalent to '-f mailbox-of-user'; 
i know this is what POSIX states for mailx(1), but in fact the codebase uses 
the 'myname' variable that gets set for much more than just that.

The patch below changes 'myname' handling to something better (imho) in that it 
always verifies the given user identity (instead), wether it comes from $USER 
or from the -u option (or from wherever else), and, as necessary, compares that 
identity against getuid(2), once only.
>How-To-Repeat:
Use different existing and non-existing users and use them assorted in $USER 
and/or '-u USER' when invoking mail(1).
>Fix:
diff -Napru nmail/Makefile nmail.user/Makefile
--- nmail/Makefile      2013-12-09 13:16:52.000000000 +0100
+++ nmail.user/Makefile 2013-12-09 20:34:20.000000000 +0100
@@ -23,7 +23,7 @@ CPPFLAGS+=    -DBROKEN_MAGIC                  # bad MIME t
 
 PROG=  mail
 SRCS=  version.c support.c cmd1.c cmd2.c cmd3.c cmd4.c cmdtab.c collect.c \
-       dotlock.c edit.c fio.c format.c getname.c head.c v7.local.c lex.c \
+       dotlock.c edit.c fio.c format.c head.c v7.local.c lex.c \
        list.c main.c names.c popen.c quit.c send.c sig.c strings.c temp.c \
        tty.c vars.c
 LINKS= ${BINDIR}/mail ${BINDIR}/Mail ${BINDIR}/mail ${BINDIR}/mailx
diff -Napru nmail/extern.h nmail.user/extern.h
--- nmail/extern.h      2013-12-09 13:16:52.000000000 +0100
+++ nmail.user/extern.h 2013-12-09 20:34:10.000000000 +0100
@@ -169,12 +169,6 @@ FILE *     setinput(const struct message *);
 void   setptr(FILE *, off_t);
 
 /*
- * from getname.c
- */
-const char *getname(uid_t);
-int    getuserid(char []);
-
-/*
  * from head.c
  */
 int    ishead(const char []);
@@ -331,7 +325,6 @@ char *      vcopy(const char []);
  */
 void   demail(void);
 void   findmail(const char *, char *, size_t);
-const char *username(void);
 
 /*
  * from version.c
diff -Napru nmail/getname.c nmail.user/getname.c
--- nmail/getname.c     2013-12-09 13:16:52.000000000 +0100
+++ nmail.user/getname.c        1970-01-01 01:00:00.000000000 +0100
@@ -1,71 +0,0 @@
-/*     $NetBSD: getname.c,v 1.11 2006/11/28 18:45:32 christos Exp $    */
-
-/*
- * Copyright (c) 1980, 1993
- *     The Regents of the University of California.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-#ifndef lint
-#if 0
-static char sccsid[] = "@(#)getname.c  8.1 (Berkeley) 6/6/93";
-#else
-__RCSID("$NetBSD: getname.c,v 1.11 2006/11/28 18:45:32 christos Exp $");
-#endif
-#endif /* not lint */
-
-#include "rcv.h"
-#include "extern.h"
-
-/* Getname / getuserid for those with hashed passwd data base). */
-
-/*
- * Search the passwd file for a uid.  Return name on success, NULL on failure
- */
-PUBLIC const char *
-getname(uid_t uid)
-{
-       struct passwd *pw;
-
-       if ((pw = getpwuid(uid)) == NULL)
-               return NULL;
-       return pw->pw_name;
-}
-
-/*
- * Convert the passed name to a user id and return it.  Return -1
- * on error.
- */
-PUBLIC int
-getuserid(char name[])
-{
-       struct passwd *pw;
-
-       if ((pw = getpwnam(name)) == NULL)
-               return -1;
-       return pw->pw_uid;
-}
diff -Napru nmail/glob.h nmail.user/glob.h
--- nmail/glob.h        2013-12-09 13:16:52.000000000 +0100
+++ nmail.user/glob.h   2013-12-09 20:33:43.000000000 +0100
@@ -64,7 +64,9 @@ EXTERN char   prevfile[PATHSIZE];             /* Name
 EXTERN char    *tmpdir;                        /* Path name of temp directory 
*/
 EXTERN char    *homedir;                       /* Path name of home directory 
*/
 EXTERN char    *origdir;                       /* Path name of directory we 
started in */
-EXTERN char    *myname;                        /* My login name */
+EXTERN char    *myname;                        /* My login/-u user/$USER.. */
+EXTERN unsigned        myuid;                          /* It's UID */
+EXTERN unsigned        theuid;                         /* getuid() */
 EXTERN off_t   mailsize;                       /* Size of system mailbox */
 EXTERN struct  message *dot;                   /* Pointer to current message */
 EXTERN struct  var     *variables[HSHSIZE];    /* Pointer to active var list */
diff -Napru nmail/lex.c nmail.user/lex.c
--- nmail/lex.c 2013-12-09 13:16:52.000000000 +0100
+++ nmail.user/lex.c    2013-12-09 20:34:05.000000000 +0100
@@ -206,7 +206,7 @@ setfile(const char *name)
        FILE *ibuf;
        int i, fd;
        struct stat stb;
-       char isedit = *name != '%' || getuserid(myname) != (int)getuid();
+       char isedit = *name != '%' || myuid != theuid;
        const char *who = name[1] ? name + 1 : myname;
        static int shudclob;
        char tempname[PATHSIZE];
diff -Napru nmail/mail.1 nmail.user/mail.1
--- nmail/mail.1        2013-12-09 13:16:52.000000000 +0100
+++ nmail.user/mail.1   2013-12-09 20:21:02.000000000 +0100
@@ -133,7 +133,9 @@ Specify subject on command line
 flag is used as a subject; be careful to quote subjects
 containing spaces.)
 .It Fl u
-Is equivalent to:
+Pretend to be
+.Ar user
+in some aspects and also do the equivalent to:
 .Pp
 .Dl mail -f /var/mail/user
 .It Fl v
diff -Napru nmail/temp.c nmail.user/temp.c
--- nmail/temp.c        2013-12-09 13:16:52.000000000 +0100
+++ nmail.user/temp.c   2013-12-09 20:46:17.000000000 +0100
@@ -54,6 +54,7 @@ tinit(void)
        char pathbuf[MAXPATHLEN];
        const char *cp;
        char *p;
+       struct passwd *pwuid, *pw;
 
        /*
         * It's okay to call savestr in here because main will
@@ -71,18 +72,25 @@ tinit(void)
                p--;
        }
 
-       if (myname != NULL) {
-               if (getuserid(myname) < 0)
-                       errx(EXIT_FAILURE, "`%s' is not a user of this system", 
myname);
-       }
+       cp = (myname == NULL) ? getenv("USER") : myname;
+       myuid = theuid = (unsigned)getuid();
+       if ((pwuid = getpwuid((uid_t)theuid)) == NULL) {
+               (void)printf("Cannot associate a name with uid %u\n", theuid);
+               if (mailmode == mm_receiving)
+                       errx(EXIT_FAILURE, "who am I receiving for?");
+               myname = __UNCONST("nobody");
+       } else if (cp == NULL)
+               myname = pwuid->pw_name;
+       else if ((pw = getpwnam(cp)) == NULL)
+               errx(EXIT_FAILURE, "`%s' is not a user of this system", cp);
        else {
-               if ((cp = username()) == NULL) {
-                       myname = savestr("nobody");
-                       if (mailmode == mm_receiving)
-                               errx(EXIT_FAILURE, "who am I receiving for?");
-               } else
-                       myname = savestr(cp);
+               myname = pw->pw_name;
+               myuid = (unsigned)pw->pw_uid;
+               if (myuid != theuid)
+                       (void)unsetenv("MAIL");
        }
+       myname = savestr(myname);
+
        if ((cp = getenv("HOME")) == NULL)
                cp = ".";
        homedir = savestr(cp);
diff -Napru nmail/v7.local.c nmail.user/v7.local.c
--- nmail/v7.local.c    2013-12-09 13:16:52.000000000 +0100
+++ nmail.user/v7.local.c       2013-12-09 20:21:22.000000000 +0100
@@ -81,20 +81,3 @@ demail(void)
                if ((fd = creat(mailname, 0600)) != -1)
                        (void)close(fd);
 }
-
-/*
- * Discover user login name.
- */
-PUBLIC const char *
-username(void)
-{
-       const char *np;
-       uid_t uid;
-
-       if ((np = getenv("USER")) != NULL)
-               return np;
-       if ((np = getname(uid = getuid())) != NULL)
-               return np;
-       (void)printf("Cannot associate a name with uid %u\n", (unsigned)uid);
-       return NULL;
-}



Home | Main Index | Thread Index | Old Index