1 /*- 2 * Copyright (c) 1991 The Regents of the University of California. 3 * 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 char copyright[] = 36 "@(#) Copyright (c) 1991 The Regents of the University of California.\n\ 37 All rights reserved.\n"; 38 #endif /* not lint */ 39 40 #ifndef lint 41 /*static char sccsid[] = "from: @(#)id.c 5.1 (Berkeley) 6/29/91";*/ 42 static char rcsid[] = "$Id: id.c,v 1.2 1993/08/01 18:14:41 mycroft Exp $"; 43 #endif /* not lint */ 44 45 #include <sys/param.h> 46 #include <pwd.h> 47 #include <grp.h> 48 #include <errno.h> 49 #include <unistd.h> 50 #include <stdlib.h> 51 #include <stdio.h> 52 #include <string.h> 53 54 typedef struct passwd PW; 55 typedef struct group GR; 56 57 void current __P((void)); 58 void err __P((const char *, ...)); 59 int gcmp __P((const void *, const void *)); 60 void sgroup __P((PW *)); 61 void ugroup __P((PW *)); 62 void usage __P((void)); 63 void user __P((PW *)); 64 PW *who __P((char *)); 65 66 int Gflag, gflag, nflag, rflag, uflag; 67 68 main(argc, argv) 69 int argc; 70 char *argv[]; 71 { 72 GR *gr; 73 PW *pw; 74 int ch, id; 75 76 while ((ch = getopt(argc, argv, "Ggnru")) != EOF) 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 'r': 88 rflag = 1; 89 break; 90 case 'u': 91 uflag = 1; 92 break; 93 case '?': 94 default: 95 usage(); 96 } 97 argc -= optind; 98 argv += optind; 99 100 pw = *argv ? who(*argv) : NULL; 101 102 if (Gflag + gflag + uflag > 1) 103 usage(); 104 105 if (Gflag) { 106 if (nflag) 107 sgroup(pw); 108 else 109 ugroup(pw); 110 exit(0); 111 } 112 113 if (gflag) { 114 id = pw ? pw->pw_gid : rflag ? getgid() : getegid(); 115 if (nflag && (gr = getgrgid(id))) { 116 (void)printf("%s\n", gr->gr_name); 117 exit(0); 118 } 119 (void)printf("%u\n", id); 120 exit(0); 121 } 122 123 if (uflag) { 124 id = pw ? pw->pw_uid : rflag ? getuid() : geteuid(); 125 if (nflag && (pw = getpwuid(id))) { 126 (void)printf("%s\n", pw->pw_name); 127 exit(0); 128 } 129 (void)printf("%u\n", id); 130 exit(0); 131 } 132 133 if (pw) 134 user(pw); 135 else 136 current(); 137 exit(0); 138 } 139 140 void 141 sgroup(pw) 142 PW *pw; 143 { 144 register int id, lastid; 145 char *fmt; 146 147 if (pw) { 148 register GR *gr; 149 register char *name, **p; 150 151 name = pw->pw_name; 152 for (fmt = "%s", lastid = -1; gr = getgrent(); lastid = id) { 153 for (p = gr->gr_mem; p && *p; p++) 154 if (!strcmp(*p, name)) { 155 (void)printf(fmt, gr->gr_name); 156 fmt = " %s"; 157 break; 158 } 159 } 160 } else { 161 GR *gr; 162 register int ngroups; 163 int groups[NGROUPS + 1]; 164 165 groups[0] = getgid(); 166 ngroups = getgroups(NGROUPS, groups + 1) + 1; 167 heapsort(groups, ngroups, sizeof(groups[0]), gcmp); 168 for (fmt = "%s", lastid = -1; --ngroups >= 0;) { 169 if (lastid == (id = groups[ngroups])) 170 continue; 171 if (gr = getgrgid(id)) 172 (void)printf(fmt, gr->gr_name); 173 else 174 (void)printf(*fmt == ' ' ? " %u" : "%u", id); 175 fmt = " %s"; 176 lastid = id; 177 } 178 } 179 (void)printf("\n"); 180 } 181 182 void 183 ugroup(pw) 184 PW *pw; 185 { 186 register int id, lastid; 187 register char *fmt; 188 189 if (pw) { 190 register GR *gr; 191 register char *name, **p; 192 193 name = pw->pw_name; 194 for (fmt = "%u", lastid = -1; gr = getgrent(); lastid = id) { 195 for (p = gr->gr_mem; p && *p; p++) 196 if (!strcmp(*p, name)) { 197 (void)printf(fmt, gr->gr_gid); 198 fmt = " %u"; 199 break; 200 } 201 } 202 } else { 203 register int ngroups; 204 int groups[NGROUPS + 1]; 205 206 groups[0] = getgid(); 207 ngroups = getgroups(NGROUPS, groups + 1) + 1; 208 heapsort(groups, ngroups, sizeof(groups[0]), gcmp); 209 for (fmt = "%u", lastid = -1; --ngroups >= 0;) { 210 if (lastid == (id = groups[ngroups])) 211 continue; 212 (void)printf(fmt, id); 213 fmt = " %u"; 214 lastid = id; 215 } 216 } 217 (void)printf("\n"); 218 } 219 220 void 221 current() 222 { 223 GR *gr; 224 PW *pw; 225 int id, eid, lastid, ngroups, groups[NGROUPS]; 226 char *fmt; 227 228 id = getuid(); 229 (void)printf("uid=%u", id); 230 if (pw = getpwuid(id)) 231 (void)printf("(%s)", pw->pw_name); 232 if ((eid = geteuid()) != id) { 233 (void)printf(" euid=%u", eid); 234 if (pw = getpwuid(eid)) 235 (void)printf("(%s)", pw->pw_name); 236 } 237 id = getgid(); 238 (void)printf(" gid=%u", id); 239 if (gr = getgrgid(id)) 240 (void)printf("(%s)", gr->gr_name); 241 if ((eid = getegid()) != id) { 242 (void)printf(" egid=%u", eid); 243 if (gr = getgrgid(eid)) 244 (void)printf("(%s)", gr->gr_name); 245 } 246 if (ngroups = getgroups(NGROUPS, groups)) { 247 heapsort(groups, ngroups, sizeof(groups[0]), gcmp); 248 for (fmt = " groups=%u", lastid = -1; --ngroups >= 0; 249 fmt = ", %u", lastid = id) { 250 id = groups[ngroups]; 251 if (lastid == id) 252 continue; 253 (void)printf(fmt, id); 254 if (gr = getgrgid(id)) 255 (void)printf("(%s)", gr->gr_name); 256 } 257 } 258 (void)printf("\n"); 259 } 260 261 void 262 user(pw) 263 register PW *pw; 264 { 265 register GR *gr; 266 register int id, lastid; 267 register char *fmt, **p; 268 269 id = pw->pw_uid; 270 (void)printf("uid=%u(%s)", id, pw->pw_name); 271 (void)printf(" gid=%u", pw->pw_gid); 272 if (gr = getgrgid(id)) 273 (void)printf("(%s)", gr->gr_name); 274 for (fmt = " groups=%u(%s)", lastid = -1; gr = getgrent(); 275 lastid = id) { 276 if (pw->pw_gid == gr->gr_gid) 277 continue; 278 for (p = gr->gr_mem; p && *p; p++) 279 if (!strcmp(*p, pw->pw_name)) { 280 (void)printf(fmt, gr->gr_gid, gr->gr_name); 281 fmt = ", %u(%s)"; 282 break; 283 } 284 } 285 (void)printf("\n"); 286 } 287 288 PW * 289 who(u) 290 char *u; 291 { 292 PW *pw; 293 long 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 = strtol(u, &ep, 10); 303 if (*u && !*ep && (pw = getpwuid(id))) 304 return(pw); 305 err("%s: No such user", u); 306 /* NOTREACHED */ 307 } 308 309 gcmp(a, b) 310 const void *a, *b; 311 { 312 return(*(int *)b - *(int *)a); 313 } 314 315 #if __STDC__ 316 #include <stdarg.h> 317 #else 318 #include <varargs.h> 319 #endif 320 321 void 322 #if __STDC__ 323 err(const char *fmt, ...) 324 #else 325 err(fmt, va_alist) 326 char *fmt; 327 va_dcl 328 #endif 329 { 330 va_list ap; 331 #if __STDC__ 332 va_start(ap, fmt); 333 #else 334 va_start(ap); 335 #endif 336 (void)fprintf(stderr, "id: "); 337 (void)vfprintf(stderr, fmt, ap); 338 va_end(ap); 339 (void)fprintf(stderr, "\n"); 340 exit(1); 341 /* NOTREACHED */ 342 } 343 344 void 345 usage() 346 { 347 (void)fprintf(stderr, "usage: id [user]\n"); 348 (void)fprintf(stderr, " id -G [-n] [user]\n"); 349 (void)fprintf(stderr, " id -g [-nr] [user]\n"); 350 (void)fprintf(stderr, " id -u [-nr] [user]\n"); 351 exit(1); 352 } 353