NetBSD Problem Report #48445
From www@NetBSD.org Thu Dec 12 11:34:11 2013
Return-Path: <www@NetBSD.org>
Received: from mail.netbsd.org (mail.netbsd.org [149.20.53.66])
(using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits))
(Client CN "mail.NetBSD.org", Issuer "Postmaster NetBSD.org" (verified OK))
by mollari.NetBSD.org (Postfix) with ESMTPS id CCF0DA63C4
for <gnats-bugs@gnats.NetBSD.org>; Thu, 12 Dec 2013 11:34:11 +0000 (UTC)
Message-Id: <20131212113409.D8CF5A642D@mollari.NetBSD.org>
Date: Thu, 12 Dec 2013 11:34:09 +0000 (UTC)
From: sdaoden@gmail.com
Reply-To: sdaoden@gmail.com
To: gnats-bugs@NetBSD.org
Subject: mail(1)/mailx(1): put ambigious $USER/-u user/xy handling, um, straight
X-Send-Pr-Version: www-1.0
>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;
-}
(Contact us)
$NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2007
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.