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 #ifndef lint 35 static const char copyright[] = 36 "@(#) 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.2 (Berkeley) 2/16/94"; 43 #endif 44 static const char rcsid[] = 45 "$Id$"; 46 #endif /* not lint */ 47 48 #include <sys/param.h> 49 50 #include <err.h> 51 #include <grp.h> 52 #include <pwd.h> 53 #include <stdio.h> 54 #include <stdlib.h> 55 #include <string.h> 56 #include <unistd.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 u_int 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", pw->pw_name); 178 else 179 (void)printf("euid\t%u", eid); 180 if ((rid = getgid()) != (eid = getegid())) 181 if ((gr = getgrgid(rid))) 182 (void)printf("rgid\t%s\n", gr->gr_name); 183 else 184 (void)printf("rgid\t%u\n", rid); 185 (void)printf("groups\t"); 186 group(NULL, 1); 187 } 188 } 189 190 void 191 current() 192 { 193 struct group *gr; 194 struct passwd *pw; 195 int cnt, id, eid, lastid, ngroups; 196 gid_t groups[NGROUPS]; 197 char *fmt; 198 199 id = getuid(); 200 (void)printf("uid=%u", id); 201 if ((pw = getpwuid(id))) 202 (void)printf("(%s)", pw->pw_name); 203 if ((eid = geteuid()) != id) { 204 (void)printf(" euid=%u", eid); 205 if ((pw = getpwuid(eid))) 206 (void)printf("(%s)", pw->pw_name); 207 } 208 id = getgid(); 209 (void)printf(" gid=%u", id); 210 if ((gr = getgrgid(id))) 211 (void)printf("(%s)", gr->gr_name); 212 if ((eid = getegid()) != id) { 213 (void)printf(" egid=%u", eid); 214 if ((gr = getgrgid(eid))) 215 (void)printf("(%s)", gr->gr_name); 216 } 217 if ((ngroups = getgroups(NGROUPS, groups))) { 218 for (fmt = " groups=%u", lastid = -1, cnt = 0; cnt < ngroups; 219 fmt = ", %u", lastid = id) { 220 id = groups[cnt++]; 221 if (lastid == id) 222 continue; 223 (void)printf(fmt, id); 224 if ((gr = getgrgid(id))) 225 (void)printf("(%s)", gr->gr_name); 226 } 227 } 228 (void)printf("\n"); 229 } 230 231 void 232 user(pw) 233 register struct passwd *pw; 234 { 235 register struct group *gr; 236 register char *fmt; 237 int cnt, gid, lastgid, ngroups, groups[NGROUPS + 1]; 238 239 (void)printf("uid=%u(%s)", pw->pw_uid, pw->pw_name); 240 gid = pw->pw_gid; 241 (void)printf(" gid=%u", gid); 242 if ((gr = getgrgid(gid))) 243 (void)printf("(%s)", gr->gr_name); 244 ngroups = NGROUPS + 1; 245 (void) getgrouplist(pw->pw_name, gid, groups, &ngroups); 246 fmt = " groups=%u"; 247 for (lastgid = -1, cnt = 0; cnt < ngroups; ++cnt) { 248 if (lastgid == (gid = groups[cnt])) 249 continue; 250 (void)printf(fmt, gid); 251 fmt = " %u"; 252 if ((gr = getgrgid(gid))) 253 (void)printf("(%s)", gr->gr_name); 254 lastgid = gid; 255 } 256 (void)printf("\n"); 257 } 258 259 void 260 group(pw, nflag) 261 struct passwd *pw; 262 int nflag; 263 { 264 struct group *gr; 265 int cnt, id, lastid, ngroups; 266 gid_t groups[NGROUPS + 1]; 267 char *fmt; 268 269 if (pw) { 270 ngroups = NGROUPS + 1; 271 (void) getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups); 272 } else { 273 groups[0] = getgid(); 274 ngroups = getgroups(NGROUPS, groups + 1) + 1; 275 } 276 fmt = nflag ? "%s" : "%u"; 277 for (lastid = -1, cnt = 0; cnt < ngroups; ++cnt) { 278 if (lastid == (id = groups[cnt])) 279 continue; 280 if (nflag) { 281 if ((gr = getgrgid(id))) 282 (void)printf(fmt, gr->gr_name); 283 else 284 (void)printf(*fmt == ' ' ? " %u" : "%u", 285 id); 286 fmt = " %s"; 287 } else { 288 (void)printf(fmt, id); 289 fmt = " %u"; 290 } 291 lastid = id; 292 } 293 (void)printf("\n"); 294 } 295 296 struct passwd * 297 who(u) 298 char *u; 299 { 300 struct passwd *pw; 301 long id; 302 char *ep; 303 304 /* 305 * Translate user argument into a pw pointer. First, try to 306 * get it as specified. If that fails, try it as a number. 307 */ 308 if ((pw = getpwnam(u))) 309 return(pw); 310 id = strtol(u, &ep, 10); 311 if (*u && !*ep && (pw = getpwuid(id))) 312 return(pw); 313 errx(1, "%s: no such user", u); 314 /* NOTREACHED */ 315 } 316 317 void 318 usage() 319 { 320 (void)fprintf(stderr, "%s\n%s\n%s\n%s\n", 321 "usage: id [user]", 322 " id -G [-n] [user]", 323 " id -g [-nr] [user]", 324 " id -u [-nr] [user]"); 325 exit(1); 326 } 327