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