Return to BSD News archive
Received: by minnie.vk1xwt.ampr.org with NNTP id AA1678 ; Tue, 23 Feb 93 14:53:10 EST Newsgroups: comp.unix.bsd,comp.os.386bsd.bugs Path: sserve!manuel.anu.edu.au!munnari.oz.au!news.Hawaii.Edu!ames!sun-barr!cs.utexas.edu!uwm.edu!rpi!ghost.dsi.unimi.it!serini From: serini@ghost.dsi.unimi.it (Piero Serini) Subject: id(1) bugs and new source Organization: Computer Science Dep. - Milan University Date: Fri, 19 Feb 1993 13:54:50 GMT Message-ID: <1993Feb19.135450.3052@ghost.dsi.unimi.it> Summary: new id.c Lines: 374 Hi. I found that id(1) doesn't handle properly the "gid" and "groups" entries: 1) "normal" id: $ id uid=100(piero) gid=20(staff) groups=5(opr), 20(staff) redundant ^^^^^^^^ 2) id [user] doesn't work: it uses the uid to seek for group name: $ id giulia uid=500(giulia) gid=100 In /etc/group gid 100 = users, but id looks for 500 and doesn't find it. Another test: $ id piero (myself) uid=100(piero) gid=20(users) groups=5(opr) As you can see in the example at 1), gid 20 = staff, but id looks for 100 which is = users 3) after a setuid() AND a setgid(), "groups" is a mix between the original groups and the new ones. Here follows an id from a "super-shell": uid=0(root) gid=0(root) groups=0(root), 5(opr), 20(staff) uid and gid are right; groups: 0(root) is redundant (root has gid 0 = root) 5(opr) is wrong (piero is in group 5, not root) 20(staff) is right, but we can't tell: both piero and root are in group 20. The new id.c source follows. Bye all -- ------------------------------------------ Piero Serini ------------ Via Giambologna, 1 E-mail: piero@strider.st.dsi.unimi.it 20136 - Milano - ITALY or: serini@ghost.dsi.unimi.it -------- PUBLIC KEY AVAILABLE VIA finger(1) or mail request -------- /*- * Copyright (c) 1991 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. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. 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. */ #ifndef lint char copyright[] = "@(#) Copyright (c) 1991 The Regents of the University of California.\n\ All rights reserved.\n"; #endif /* not lint */ #ifndef lint static char sccsid[] = "@(#)id.c 5.1 (Berkeley) 6/29/91"; #endif /* not lint */ #include <sys/param.h> #include <pwd.h> #include <grp.h> #include <errno.h> #include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <string.h> typedef struct passwd PW; typedef struct group GR; void err __P((const char *, ...)); int gcmp __P((const void *, const void *)); void sgroup __P((PW *)); void ugroup __P((PW *)); void usage __P((void)); void user __P((PW *)); PW *who __P((char *)); int Gflag, gflag, nflag, rflag, uflag; main(argc, argv) int argc; char *argv[]; { GR *gr; PW *pw; int ch, id; while ((ch = getopt(argc, argv, "Ggnru")) != EOF) switch(ch) { case 'G': Gflag = 1; break; case 'g': gflag = 1; break; case 'n': nflag = 1; break; case 'r': rflag = 1; break; case 'u': uflag = 1; break; case '?': default: usage(); } argc -= optind; argv += optind; pw = *argv ? who(*argv) : NULL; if (Gflag + gflag + uflag > 1) usage(); if (Gflag) { if (nflag) sgroup(pw); else ugroup(pw); exit(0); } if (gflag) { id = pw ? pw->pw_gid : rflag ? getgid() : getegid(); if (nflag && (gr = getgrgid(id))) { (void)printf("%s\n", gr->gr_name); exit(0); } (void)printf("%u\n", id); exit(0); } if (uflag) { id = pw ? pw->pw_uid : rflag ? getuid() : geteuid(); if (nflag && (pw = getpwuid(id))) { (void)printf("%s\n", pw->pw_name); exit(0); } (void)printf("%u\n", id); exit(0); } if (!pw) pw = getpwuid(getuid()); user(pw); exit(0); } void sgroup(pw) PW *pw; { register int id, lastid; char *fmt; if (pw) { register GR *gr; register char *name, **p; name = pw->pw_name; for (fmt = "%s", lastid = -1; gr = getgrent(); lastid = id) { for (p = gr->gr_mem; p && *p; p++) if (!strcmp(*p, name)) { (void)printf(fmt, gr->gr_name); fmt = " %s"; break; } } } else { GR *gr; register int ngroups; int groups[NGROUPS + 1]; groups[0] = getgid(); ngroups = getgroups(NGROUPS, groups + 1) + 1; heapsort(groups, ngroups, sizeof(groups[0]), gcmp); for (fmt = "%s", lastid = -1; --ngroups >= 0;) { if (lastid == (id = groups[ngroups])) continue; if (gr = getgrgid(id)) (void)printf(fmt, gr->gr_name); else (void)printf(*fmt == ' ' ? " %u" : "%u", id); fmt = " %s"; lastid = id; } } (void)printf("\n"); } void ugroup(pw) PW *pw; { register int id, lastid; register char *fmt; if (pw) { register GR *gr; register char *name, **p; name = pw->pw_name; for (fmt = "%u", lastid = -1; gr = getgrent(); lastid = id) { for (p = gr->gr_mem; p && *p; p++) if (!strcmp(*p, name)) { (void)printf(fmt, gr->gr_gid); fmt = " %u"; break; } } } else { register int ngroups; int groups[NGROUPS + 1]; groups[0] = getgid(); ngroups = getgroups(NGROUPS, groups + 1) + 1; heapsort(groups, ngroups, sizeof(groups[0]), gcmp); for (fmt = "%u", lastid = -1; --ngroups >= 0;) { if (lastid == (id = groups[ngroups])) continue; (void)printf(fmt, id); fmt = " %u"; lastid = id; } } (void)printf("\n"); } void user(pw) register PW *pw; { register GR *gr; register int id, lastid; int eid, gid, egid; register char *fmt, **p; id = pw->pw_uid; gid = pw->pw_gid; (void)printf("uid=%u(%s)", id, pw->pw_name); if (id == getuid()) if ((eid = geteuid()) != id) { (void)printf(" euid=%u", eid); if (pw = getpwuid(eid)) (void)printf("(%s)", pw->pw_name); } /* endif id == getuid() */ (void)printf(" gid=%u", gid); if (gr = getgrgid(gid)) (void)printf("(%s)", gr->gr_name); if (id == getuid()) if ((egid = getegid()) != gid) { (void)printf(" egid=%u", egid); if (gr = getgrgid(egid)) (void)printf("(%s)", gr->gr_name); } /* endif id == getuid() */ /* now pw points to Euid, so we must reset it */ pw = getpwuid(id); for (fmt = " groups=%u(%s)", lastid = -1; gr = getgrent(); lastid = id) { if (pw->pw_gid == gr->gr_gid) continue; for (p = gr->gr_mem; p && *p; p++) if (!strcmp(*p, pw->pw_name)) { (void)printf(fmt, gr->gr_gid, gr->gr_name); fmt = ", %u(%s)"; break; } } (void)printf("\n"); } PW * who(u) char *u; { PW *pw; long id; char *ep; /* * Translate user argument into a pw pointer. First, try to * get it as specified. If that fails, try it as a number. */ if (pw = getpwnam(u)) return(pw); id = strtol(u, &ep, 10); if (*u && !*ep && (pw = getpwuid(id))) return(pw); err("%s: No such user", u); /* NOTREACHED */ } gcmp(a, b) const void *a, *b; { return(*(int *)b - *(int *)a); } #if __STDC__ #include <stdarg.h> #else #include <varargs.h> #endif void #if __STDC__ err(const char *fmt, ...) #else err(fmt, va_alist) char *fmt; va_dcl #endif { va_list ap; #if __STDC__ va_start(ap, fmt); #else va_start(ap); #endif (void)fprintf(stderr, "id: "); (void)vfprintf(stderr, fmt, ap); va_end(ap); (void)fprintf(stderr, "\n"); exit(1); /* NOTREACHED */ } void usage() { (void)fprintf(stderr, "usage: id [user]\n"); (void)fprintf(stderr, " id -G [-n] [user]\n"); (void)fprintf(stderr, " id -g [-nr] [user]\n"); (void)fprintf(stderr, " id -u [-nr] [user]\n"); exit(1); }