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