Upload Tizen:Base source
[external/bash.git] / examples / loadables / id.c
1 /*
2  * id - POSIX.2 user identity
3  *
4  * (INCOMPLETE -- supplementary groups for other users not yet done)
5  *
6  * usage: id [-Ggu] [-nr] [user]
7  *
8  * The default output format looks something like:
9  *      uid=xxx(chet) gid=xx groups=aa(aname), bb(bname), cc(cname)
10  */
11
12 /*
13    Copyright (C) 1999-2009 Free Software Foundation, Inc.
14
15    This file is part of GNU Bash.
16    Bash is free software: you can redistribute it and/or modify
17    it under the terms of the GNU General Public License as published by
18    the Free Software Foundation, either version 3 of the License, or
19    (at your option) any later version.
20
21    Bash is distributed in the hope that it will be useful,
22    but WITHOUT ANY WARRANTY; without even the implied warranty of
23    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24    GNU General Public License for more details.
25
26    You should have received a copy of the GNU General Public License
27    along with Bash.  If not, see <http://www.gnu.org/licenses/>.
28 */
29
30 #include <config.h>
31 #include <stdio.h>
32 #include "bashtypes.h"
33 #include <pwd.h>
34 #include <grp.h>
35 #include "bashansi.h"
36
37 #ifdef HAVE_LIMITS_H
38 #  include <limits.h>
39 #else
40 #  include <sys/param.h>
41 #endif
42
43 #if !defined (HAVE_GETPW_DECLS)
44 extern struct passwd *getpwuid ();
45 #endif
46 extern struct group *getgrgid ();
47
48 #include "shell.h"
49 #include "builtins.h"
50 #include "stdc.h"
51 #include "common.h"
52 #include "bashgetopt.h"
53
54 #define ID_ALLGROUPS    0x001           /* -G */
55 #define ID_GIDONLY      0x002           /* -g */
56 #define ID_USENAME      0x004           /* -n */
57 #define ID_USEREAL      0x008           /* -r */
58 #define ID_USERONLY     0x010           /* -u */
59
60 #define ID_FLAGSET(s)   ((id_flags & (s)) != 0)
61
62 static int id_flags;
63
64 static uid_t ruid, euid;
65 static gid_t rgid, egid;
66
67 static char *id_user;
68
69 static int inituser ();
70
71 static int id_pruser ();
72 static int id_prgrp ();
73 static int id_prgroups ();
74 static int id_prall ();
75
76 int
77 id_builtin (list)
78      WORD_LIST *list;
79 {
80   int opt;
81   char *user;
82
83   id_flags = 0;
84   reset_internal_getopt ();
85   while ((opt = internal_getopt (list, "Ggnru")) != -1)
86     {
87       switch (opt)
88         {
89         case 'G': id_flags |= ID_ALLGROUPS; break;
90         case 'g': id_flags |= ID_GIDONLY; break;
91         case 'n': id_flags |= ID_USENAME; break;
92         case 'r': id_flags |= ID_USEREAL; break;
93         case 'u': id_flags |= ID_USERONLY; break;
94         default:
95           builtin_usage ();
96           return (EX_USAGE);
97         }
98     }
99   list = loptend;
100
101   user = list ? list->word->word : (char *)NULL;
102
103   /* Check for some invalid option combinations */
104   opt = ID_FLAGSET (ID_ALLGROUPS) + ID_FLAGSET (ID_GIDONLY) + ID_FLAGSET (ID_USERONLY);
105   if (opt > 1 || (opt == 0 && ((id_flags & (ID_USEREAL|ID_USENAME)) != 0)))
106     {
107       builtin_usage ();
108       return (EX_USAGE);
109     }
110
111   if (list && list->next)
112     {
113       builtin_usage ();
114       return (EX_USAGE);
115     }
116
117   if (inituser (user) < 0)
118     return (EXECUTION_FAILURE);
119
120   opt = 0;
121   if (id_flags & ID_USERONLY)
122     opt += id_pruser ((id_flags & ID_USEREAL) ? ruid : euid);
123   else if (id_flags & ID_GIDONLY)
124     opt += id_prgrp ((id_flags & ID_USEREAL) ? rgid : egid);
125   else if (id_flags & ID_ALLGROUPS)
126     opt += id_prgroups (user);
127   else
128     opt += id_prall (user);
129   putchar ('\n');
130   fflush (stdout);
131
132   return (opt == 0 ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
133 }
134
135 static int
136 inituser (uname)
137      char *uname;
138 {
139   struct passwd *pwd;
140
141   if (uname)
142     {
143       pwd = getpwnam (uname);
144       if (pwd == 0)
145         {
146           builtin_error ("%s: no such user", uname);
147           return -1;
148         }
149       ruid = euid = pwd->pw_uid;
150       rgid = egid = pwd->pw_gid;
151     }
152   else
153     {
154       ruid = current_user.uid;
155       euid = current_user.euid;
156       rgid = current_user.gid;
157       egid = current_user.egid;
158     }
159   return 0;
160 }
161
162 /* Print the name or value of user ID UID. */
163 static int
164 id_pruser (uid)
165      int uid;
166 {
167   struct passwd *pwd = NULL;
168   int r;
169
170   r = 0;
171   if (id_flags & ID_USENAME)
172     {
173       pwd = getpwuid (uid);
174       if (pwd == NULL)
175         r = 1;
176     }
177   if (pwd)
178     printf ("%s", pwd->pw_name);
179   else
180     printf ("%u", (unsigned) uid);
181       
182   return r;
183 }
184
185 /* Print the name or value of group ID GID. */
186
187 static int
188 id_prgrp (gid)
189      int gid;
190 {
191   struct group *grp = NULL;
192   int r;
193
194   r = 0;
195   if (id_flags & ID_USENAME)
196     {
197       grp = getgrgid (gid);
198       if (grp == NULL)
199         r = 1;
200     }
201
202   if (grp)
203     printf ("%s", grp->gr_name);
204   else
205     printf ("%u", (unsigned) gid);
206
207   return r;
208 }
209
210 static int
211 id_prgroups (uname)
212      char *uname;
213 {
214   int *glist, ng, i, r;
215
216   r = 0;
217   id_prgrp (rgid);
218   if (egid != rgid)
219     {
220       putchar (' ');
221       id_prgrp (egid);
222     }
223
224   if (uname)
225     {
226       builtin_error ("supplementary groups for other users not yet implemented");
227       glist = (int *)NULL;
228       ng = 0;
229       r = 1;
230     }
231   else
232     glist = get_group_array (&ng);
233
234   for (i = 0; i < ng; i++)
235     if (glist[i] != rgid && glist[i] != egid)
236       {
237         putchar (' ');
238         id_prgrp (glist[i]);
239       }
240   
241   return r;
242 }
243
244 static int
245 id_prall (uname)
246      char *uname;
247 {
248   int r, i, ng, *glist;
249   struct passwd *pwd;
250   struct group *grp;
251
252   r = 0;
253   printf ("uid=%u", (unsigned) ruid);
254   pwd = getpwuid (ruid);
255   if (pwd == NULL)
256     r = 1;
257   else
258     printf ("(%s)", pwd->pw_name);
259
260   printf (" gid=%u", (unsigned) rgid);
261   grp = getgrgid (rgid);
262   if (grp == NULL)
263     r = 1;
264   else
265     printf ("(%s)", grp->gr_name);
266
267   if (euid != ruid)
268     { 
269       printf (" euid=%u", (unsigned) euid);
270       pwd = getpwuid (euid);
271       if (pwd == NULL)
272         r = 1;
273       else 
274         printf ("(%s)", pwd->pw_name);
275     }
276
277   if (egid != rgid) 
278     {
279       printf (" egid=%u", (unsigned) egid);
280       grp = getgrgid (egid);
281       if (grp == NULL)
282         r = 1;
283       else
284         printf ("(%s)", grp->gr_name);
285     }
286
287   if (uname)
288     {
289       builtin_error ("supplementary groups for other users not yet implemented");
290       glist = (int *)NULL;
291       ng = 0;
292       r = 1;
293     }
294   else
295     glist = get_group_array (&ng);
296
297   if (ng > 0)
298     printf (" groups=");
299   for (i = 0; i < ng; i++)
300     {
301       if (i > 0)
302         printf (", ");
303       printf ("%u", (unsigned) glist[i]);
304       grp = getgrgid (glist[i]);
305       if (grp == NULL)
306         r = 1;
307       else
308         printf ("(%s)", grp->gr_name);
309     }
310
311   return r;
312 }
313
314 char *id_doc[] = {
315         "Display information about user."
316         "",
317         "Return information about user identity",
318         (char *)NULL
319 };
320
321 struct builtin id_struct = {
322         "id",
323         id_builtin,
324         BUILTIN_ENABLED,
325         id_doc,
326         "id [user]\n\tid -G [-n] [user]\n\tid -g [-nr] [user]\n\tid -u [-nr] [user]",
327         0
328 };