Remove advertising header from all userland binaries.
[dragonfly.git] / usr.bin / id / id.c
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  * 4. 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  * @(#) Copyright (c) 1991, 1993 The Regents of the University of California.  All rights reserved.
30  * @(#)id.c     8.2 (Berkeley) 2/16/94
31  * $FreeBSD: src/usr.bin/id/id.c,v 1.12.2.3 2001/12/20 12:09:03 ru Exp $
32  * $DragonFly: src/usr.bin/id/id.c,v 1.6 2004/12/31 20:58:17 cpressey Exp $
33  */
34
35 #include <sys/param.h>
36
37 #include <err.h>
38 #include <grp.h>
39 #include <pwd.h>
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <string.h>
43 #include <unistd.h>
44
45 int             main(int, char *[]);
46 static void     current(void);
47 static void     pline(struct passwd *);
48 static void     pretty(struct passwd *);
49 static void     group(struct passwd *, int);
50 static void     usage(void);
51 static void     user(struct passwd *);
52 static struct passwd *
53                 who(char *);
54
55 int isgroups, iswhoami;
56
57 int
58 main(int argc, char **argv)
59 {
60         struct group *gr;
61         struct passwd *pw;
62         int Gflag, Pflag, ch, gflag, id, nflag, pflag, rflag, uflag;
63         const char *myname;
64
65         Gflag = Pflag = gflag = nflag = pflag = rflag = uflag = 0;
66
67         myname = strrchr(argv[0], '/');
68         myname = (myname != NULL) ? myname + 1 : argv[0];
69         if (strcmp(myname, "groups") == 0) {
70                 isgroups = 1;
71                 Gflag = nflag = 1;
72         }
73         else if (strcmp(myname, "whoami") == 0) {
74                 iswhoami = 1;
75                 uflag = nflag = 1;
76         }
77
78         while ((ch = getopt(argc, argv,
79             (isgroups || iswhoami) ? "" : "PGgnpru")) != -1)
80                 switch(ch) {
81                 case 'G':
82                         Gflag = 1;
83                         break;
84                 case 'P':
85                         Pflag = 1;
86                         break;
87                 case 'g':
88                         gflag = 1;
89                         break;
90                 case 'n':
91                         nflag = 1;
92                         break;
93                 case 'p':
94                         pflag = 1;
95                         break;
96                 case 'r':
97                         rflag = 1;
98                         break;
99                 case 'u':
100                         uflag = 1;
101                         break;
102                 case '?':
103                 default:
104                         usage();
105                 }
106         argc -= optind;
107         argv += optind;
108
109         if (iswhoami && argc > 0)
110                 usage();
111
112         switch(Gflag + Pflag + gflag + pflag + uflag) {
113         case 1:
114                 break;
115         case 0:
116                 if (!nflag && !rflag)
117                         break;
118                 /* FALLTHROUGH */
119         default:
120                 usage();
121         }
122
123         pw = *argv ? who(*argv) : NULL;
124
125         if (gflag) {
126                 id = pw ? pw->pw_gid : rflag ? getgid() : getegid();
127                 if (nflag && (gr = getgrgid(id)))
128                         printf("%s\n", gr->gr_name);
129                 else
130                         printf("%u\n", id);
131                 exit(0);
132         }
133
134         if (uflag) {
135                 id = pw ? pw->pw_uid : rflag ? getuid() : geteuid();
136                 if (nflag && (pw = getpwuid(id)))
137                         printf("%s\n", pw->pw_name);
138                 else
139                         printf("%u\n", id);
140                 exit(0);
141         }
142
143         if (Gflag) {
144                 group(pw, nflag);
145                 exit(0);
146         }
147
148         if (Pflag) {
149                 pline(pw);
150                 exit(0);
151         }
152
153         if (pflag) {
154                 pretty(pw);
155                 exit(0);
156         }
157
158         if (pw)
159                 user(pw);
160         else
161                 current();
162         exit(0);
163 }
164
165 static void
166 pretty(struct passwd *pw)
167 {
168         struct group *gr;
169         u_int eid, rid;
170         char *login;
171
172         if (pw) {
173                 printf("uid\t%s\n", pw->pw_name);
174                 printf("groups\t");
175                 group(pw, 1);
176         } else {
177                 if ((login = getlogin()) == NULL)
178                         err(1, "getlogin");
179
180                 pw = getpwuid(rid = getuid());
181                 if (pw == NULL || strcmp(login, pw->pw_name))
182                         printf("login\t%s\n", login);
183                 if (pw)
184                         printf("uid\t%s\n", pw->pw_name);
185                 else
186                         printf("uid\t%u\n", rid);
187
188                 if ((eid = geteuid()) != rid) {
189                         if ((pw = getpwuid(eid)))
190                                 printf("euid\t%s\n", pw->pw_name);
191                         else
192                                 printf("euid\t%u\n", eid);
193                 }
194                 if ((rid = getgid()) != (eid = getegid())) {
195                         if ((gr = getgrgid(rid)))
196                                 printf("rgid\t%s\n", gr->gr_name);
197                         else
198                                 printf("rgid\t%u\n", rid);
199                 }
200                 printf("groups\t");
201                 group(NULL, 1);
202         }
203 }
204
205 static void
206 current(void)
207 {
208         struct group *gr;
209         struct passwd *pw;
210         int cnt, id, eid, lastid, ngroups;
211         gid_t groups[NGROUPS];
212         const char *fmt;
213
214         id = getuid();
215         printf("uid=%u", id);
216         if ((pw = getpwuid(id)))
217                 printf("(%s)", pw->pw_name);
218         if ((eid = geteuid()) != id) {
219                 printf(" euid=%u", eid);
220                 if ((pw = getpwuid(eid)))
221                         printf("(%s)", pw->pw_name);
222         }
223         id = getgid();
224         printf(" gid=%u", id);
225         if ((gr = getgrgid(id)))
226                 printf("(%s)", gr->gr_name);
227         if ((eid = getegid()) != id) {
228                 printf(" egid=%u", eid);
229                 if ((gr = getgrgid(eid)))
230                         printf("(%s)", gr->gr_name);
231         }
232         if ((ngroups = getgroups(NGROUPS, groups))) {
233                 for (fmt = " groups=%u", lastid = -1, cnt = 0; cnt < ngroups;
234                     fmt = ", %u", lastid = id) {
235                         id = groups[cnt++];
236                         if (lastid == id)
237                                 continue;
238                         printf(fmt, id);
239                         if ((gr = getgrgid(id)))
240                                 printf("(%s)", gr->gr_name);
241                 }
242         }
243         printf("\n");
244 }
245
246 static void
247 user(struct passwd *pw)
248 {
249         struct group *gr;
250         const char *fmt;
251         int cnt, ngroups;
252         gid_t gid, lastgid, groups[NGROUPS + 1];
253
254         printf("uid=%u(%s)", pw->pw_uid, pw->pw_name);
255         gid = pw->pw_gid;
256         printf(" gid=%u", gid);
257         if ((gr = getgrgid(gid)))
258                 printf("(%s)", gr->gr_name);
259         ngroups = NGROUPS + 1;
260         getgrouplist(pw->pw_name, gid, groups, &ngroups);
261         fmt = " groups=%u";
262         for (lastgid = -1, cnt = 0; cnt < ngroups; ++cnt) {
263                 if (lastgid == (gid = groups[cnt]))
264                         continue;
265                 printf(fmt, gid);
266                 fmt = ", %u";
267                 if ((gr = getgrgid(gid)))
268                         printf("(%s)", gr->gr_name);
269                 lastgid = gid;
270         }
271         printf("\n");
272 }
273
274 static void
275 group(struct passwd *pw, int nflag)
276 {
277         struct group *gr;
278         int cnt, id, lastid, ngroups;
279         gid_t groups[NGROUPS + 1];
280         const char *fmt;
281
282         if (pw) {
283                 ngroups = NGROUPS + 1;
284                 getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups);
285         } else {
286                 groups[0] = getgid();
287                 ngroups = getgroups(NGROUPS, groups + 1) + 1;
288         }
289         fmt = nflag ? "%s" : "%u";
290         for (lastid = -1, cnt = 0; cnt < ngroups; ++cnt) {
291                 if (lastid == (id = groups[cnt]))
292                         continue;
293                 if (nflag) {
294                         if ((gr = getgrgid(id)))
295                                 printf(fmt, gr->gr_name);
296                         else
297                                 printf(*fmt == ' ' ? " %u" : "%u",
298                                     id);
299                         fmt = " %s";
300                 } else {
301                         printf(fmt, id);
302                         fmt = " %u";
303                 }
304                 lastid = id;
305         }
306         printf("\n");
307 }
308
309 static struct passwd *
310 who(char *u)
311 {
312         struct passwd *pw;
313         long id;
314         char *ep;
315
316         /*
317          * Translate user argument into a pw pointer.  First, try to
318          * get it as specified.  If that fails, try it as a number.
319          */
320         if ((pw = getpwnam(u)))
321                 return(pw);
322         id = strtol(u, &ep, 10);
323         if (*u && !*ep && (pw = getpwuid(id)))
324                 return(pw);
325         errx(1, "%s: no such user", u);
326         /* NOTREACHED */
327 }
328
329 static void
330 pline(struct passwd *pw)
331 {
332         u_int rid;
333
334         if (!pw) {
335                 if ((pw = getpwuid(rid = getuid())) == NULL)
336                         err(1, "getpwuid");
337         }
338
339         printf("%s:%s:%d:%d:%s:%ld:%ld:%s:%s:%s\n", pw->pw_name,
340                         pw->pw_passwd, pw->pw_uid, pw->pw_gid, pw->pw_class,
341                         (long)pw->pw_change, (long)pw->pw_expire, pw->pw_gecos,
342                         pw->pw_dir, pw->pw_shell);
343 }
344
345
346 static void
347 usage(void)
348 {
349
350         if (isgroups)
351                 fprintf(stderr, "usage: groups [user]\n");
352         else if (iswhoami)
353                 fprintf(stderr, "usage: whoami\n");
354         else
355                 fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n",
356                     "usage: id [user]",
357                     "       id -G [-n] [user]",
358                     "       id -P [user]",
359                     "       id -g [-nr] [user]",
360                     "       id -p [user]",
361                     "       id -u [-nr] [user]");
362         exit(1);
363 }