1 /*- 2 * Copyright (c) 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 #include <sys/cdefs.h> 35 #ifndef lint 36 __COPYRIGHT("@(#) Copyright (c) 1991, 1993\n\ 37 The Regents of the University of California. All rights reserved.\n"); 38 #endif /* not lint */ 39 40 #ifndef lint 41 #if 0 42 static char sccsid[] = "@(#)id.c 8.3 (Berkeley) 4/28/95"; 43 #else 44 __RCSID("$NetBSD: id.c,v 1.17 2001/01/05 03:08:23 itohy Exp $"); 45 #endif 46 #endif /* not lint */ 47 48 #include <sys/param.h> 49 50 #include <err.h> 51 #include <errno.h> 52 #include <grp.h> 53 #include <pwd.h> 54 #include <stdio.h> 55 #include <stdlib.h> 56 #include <string.h> 57 #include <unistd.h> 58 59 int main __P((int, char **)); 60 61 static void current __P((void)); 62 static void pretty __P((struct passwd *)); 63 static void group __P((struct passwd *, int)); 64 static void usage __P((void)); 65 static void user __P((struct passwd *)); 66 static struct passwd *who __P((char *)); 67 68 static int maxgroups; 69 static gid_t *groups; 70 71 int 72 main(argc, argv) 73 int argc; 74 char *argv[]; 75 { 76 struct group *gr; 77 struct passwd *pw; 78 int ch, id; 79 int Gflag, gflag, nflag, pflag, rflag, uflag; 80 extern const char *__progname; 81 82 Gflag = gflag = nflag = pflag = rflag = uflag = 0; 83 84 if (!strcmp(__progname, "groups")) { 85 Gflag = 1; 86 nflag = 1; 87 } else if (!strcmp(__progname, "whoami")) { 88 uflag = 1; 89 nflag = 1; 90 } 91 92 while ((ch = getopt(argc, argv, "Ggnpru")) != -1) 93 switch(ch) { 94 case 'G': 95 Gflag = 1; 96 break; 97 case 'g': 98 gflag = 1; 99 break; 100 case 'n': 101 nflag = 1; 102 break; 103 case 'p': 104 pflag = 1; 105 break; 106 case 'r': 107 rflag = 1; 108 break; 109 case 'u': 110 uflag = 1; 111 break; 112 case '?': 113 default: 114 usage(); 115 } 116 argc -= optind; 117 argv += optind; 118 119 switch(Gflag + gflag + pflag + uflag) { 120 case 1: 121 break; 122 case 0: 123 if (!nflag && !rflag) 124 break; 125 /* FALLTHROUGH */ 126 default: 127 usage(); 128 } 129 130 pw = *argv ? who(*argv) : NULL; 131 132 maxgroups = sysconf(_SC_NGROUPS_MAX); 133 if ((groups = malloc((maxgroups + 1) * sizeof(gid_t))) == NULL) 134 err(1, NULL); 135 136 if (gflag) { 137 id = pw ? pw->pw_gid : rflag ? getgid() : getegid(); 138 if (nflag && (gr = getgrgid(id))) 139 (void)printf("%s\n", gr->gr_name); 140 else 141 (void)printf("%u\n", id); 142 goto done; 143 } 144 145 if (uflag) { 146 id = pw ? pw->pw_uid : rflag ? getuid() : geteuid(); 147 if (nflag && (pw = getpwuid(id))) 148 (void)printf("%s\n", pw->pw_name); 149 else 150 (void)printf("%u\n", id); 151 goto done; 152 } 153 154 if (Gflag) { 155 group(pw, nflag); 156 goto done; 157 } 158 159 if (pflag) { 160 pretty(pw); 161 goto done; 162 } 163 164 if (pw) 165 user(pw); 166 else 167 current(); 168 done: 169 free(groups); 170 return(0); 171 } 172 173 static void 174 pretty(pw) 175 struct passwd *pw; 176 { 177 struct group *gr; 178 u_int eid, rid; 179 char *login; 180 181 if (pw) { 182 (void)printf("uid\t%s\n", pw->pw_name); 183 (void)printf("groups\t"); 184 group(pw, 1); 185 } else { 186 if ((login = getlogin()) == NULL) 187 err(1, "getlogin"); 188 189 pw = getpwuid(rid = getuid()); 190 if (pw == NULL || strcmp(login, pw->pw_name)) 191 (void)printf("login\t%s\n", login); 192 if (pw) 193 (void)printf("uid\t%s\n", pw->pw_name); 194 else 195 (void)printf("uid\t%u\n", rid); 196 197 if ((eid = geteuid()) != rid) { 198 if ((pw = getpwuid(eid)) != NULL) 199 (void)printf("euid\t%s\n", pw->pw_name); 200 else 201 (void)printf("euid\t%u\n", eid); 202 } 203 if ((rid = getgid()) != (eid = getegid())) { 204 if ((gr = getgrgid(rid)) != NULL) 205 (void)printf("rgid\t%s\n", gr->gr_name); 206 else 207 (void)printf("rgid\t%u\n", rid); 208 } 209 (void)printf("groups\t"); 210 group(NULL, 1); 211 } 212 } 213 214 static void 215 current() 216 { 217 struct group *gr; 218 struct passwd *pw; 219 int cnt, id, eid, lastid, ngroups; 220 char *fmt; 221 222 id = getuid(); 223 (void)printf("uid=%u", id); 224 if ((pw = getpwuid(id)) != NULL) 225 (void)printf("(%s)", pw->pw_name); 226 if ((eid = geteuid()) != id) { 227 (void)printf(" euid=%u", eid); 228 if ((pw = getpwuid(eid)) != NULL) 229 (void)printf("(%s)", pw->pw_name); 230 } 231 id = getgid(); 232 (void)printf(" gid=%u", id); 233 if ((gr = getgrgid(id)) != NULL) 234 (void)printf("(%s)", gr->gr_name); 235 if ((eid = getegid()) != id) { 236 (void)printf(" egid=%u", eid); 237 if ((gr = getgrgid(eid)) != NULL) 238 (void)printf("(%s)", gr->gr_name); 239 } 240 if ((ngroups = getgroups(maxgroups, groups)) != NULL) { 241 for (fmt = " groups=%u", lastid = -1, cnt = 0; cnt < ngroups; 242 fmt = ",%u", lastid = id, cnt++) { 243 id = groups[cnt]; 244 if (lastid == id) 245 continue; 246 (void)printf(fmt, id); 247 if ((gr = getgrgid(id)) != NULL) 248 (void)printf("(%s)", gr->gr_name); 249 } 250 } 251 (void)printf("\n"); 252 } 253 254 static void 255 user(pw) 256 struct passwd *pw; 257 { 258 struct group *gr; 259 char *fmt; 260 int cnt, id, lastid, ngroups; 261 262 id = pw->pw_uid; 263 (void)printf("uid=%u(%s)", id, pw->pw_name); 264 (void)printf(" gid=%lu", (u_long)pw->pw_gid); 265 if ((gr = getgrgid(pw->pw_gid)) != NULL) 266 (void)printf("(%s)", gr->gr_name); 267 ngroups = maxgroups + 1; 268 (void) getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups); 269 for (fmt = " groups=%u", lastid = -1, cnt = 0; cnt < ngroups; 270 fmt=",%u", lastid = id, cnt++) { 271 id = groups[cnt]; 272 if (lastid == id) 273 continue; 274 (void)printf(fmt, id); 275 if ((gr = getgrgid(id)) != NULL) 276 (void)printf("(%s)", gr->gr_name); 277 } 278 (void)printf("\n"); 279 } 280 281 static void 282 group(pw, nflag) 283 struct passwd *pw; 284 int nflag; 285 { 286 struct group *gr; 287 int cnt, id, lastid, ngroups; 288 char *fmt; 289 290 if (pw) { 291 ngroups = maxgroups; 292 (void) getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups); 293 } else { 294 groups[0] = getgid(); 295 ngroups = getgroups(maxgroups, groups + 1) + 1; 296 } 297 fmt = nflag ? "%s" : "%u"; 298 for (lastid = -1, cnt = 0; cnt < ngroups; ++cnt) { 299 if (lastid == (id = groups[cnt])) 300 continue; 301 if (nflag) { 302 if ((gr = getgrgid(id)) != NULL) 303 (void)printf(fmt, gr->gr_name); 304 else 305 (void)printf(*fmt == ' ' ? " %u" : "%u", 306 id); 307 fmt = " %s"; 308 } else { 309 (void)printf(fmt, id); 310 fmt = " %u"; 311 } 312 lastid = id; 313 } 314 (void)printf("\n"); 315 } 316 317 struct passwd * 318 who(u) 319 char *u; 320 { 321 struct passwd *pw; 322 long id; 323 char *ep; 324 325 /* 326 * Translate user argument into a pw pointer. First, try to 327 * get it as specified. If that fails, try it as a number. 328 */ 329 if ((pw = getpwnam(u)) != NULL) 330 return(pw); 331 id = strtol(u, &ep, 10); 332 if (*u && !*ep && (pw = getpwuid(id))) 333 return(pw); 334 errx(1, "%s: No such user", u); 335 /* NOTREACHED */ 336 return (NULL); 337 } 338 339 void 340 usage() 341 { 342 (void)fprintf(stderr, "usage: id [user]\n"); 343 (void)fprintf(stderr, " id -G [-n] [user]\n"); 344 (void)fprintf(stderr, " id -g [-nr] [user]\n"); 345 (void)fprintf(stderr, " id -p\n"); 346 (void)fprintf(stderr, " id -u [-nr] [user]\n"); 347 exit(1); 348 } 349