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