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#include <config.h> 13#include <stdio.h> 14#include "bashtypes.h" 15#include <pwd.h> 16#include <grp.h> 17#include "bashansi.h" 18 19#ifdef HAVE_LIMITS_H 20# include <limits.h> 21#else 22# include <sys/param.h> 23#endif 24 25#if !defined (HAVE_GETPW_DECLS) 26extern struct passwd *getpwuid (); 27#endif 28extern struct group *getgrgid (); 29 30#include "shell.h" 31#include "builtins.h" 32#include "stdc.h" 33#include "common.h" 34#include "bashgetopt.h" 35 36#define ID_ALLGROUPS 0x001 /* -G */ 37#define ID_GIDONLY 0x002 /* -g */ 38#define ID_USENAME 0x004 /* -n */ 39#define ID_USEREAL 0x008 /* -r */ 40#define ID_USERONLY 0x010 /* -u */ 41 42#define ID_FLAGSET(s) ((id_flags & (s)) != 0) 43 44static int id_flags; 45 46static uid_t ruid, euid; 47static gid_t rgid, egid; 48 49static char *id_user; 50 51static int inituser (); 52 53static int id_pruser (); 54static int id_prgrp (); 55static int id_prgroups (); 56static int id_prall (); 57 58int 59id_builtin (list) 60 WORD_LIST *list; 61{ 62 int opt; 63 char *user; 64 65 id_flags = 0; 66 reset_internal_getopt (); 67 while ((opt = internal_getopt (list, "Ggnru")) != -1) 68 { 69 switch (opt) 70 { 71 case 'G': id_flags |= ID_ALLGROUPS; break; 72 case 'g': id_flags |= ID_GIDONLY; break; 73 case 'n': id_flags |= ID_USENAME; break; 74 case 'r': id_flags |= ID_USEREAL; break; 75 case 'u': id_flags |= ID_USERONLY; break; 76 default: 77 builtin_usage (); 78 return (EX_USAGE); 79 } 80 } 81 list = loptend; 82 83 user = list ? list->word->word : (char *)NULL; 84 85 /* Check for some invalid option combinations */ 86 opt = ID_FLAGSET (ID_ALLGROUPS) + ID_FLAGSET (ID_GIDONLY) + ID_FLAGSET (ID_USERONLY); 87 if (opt > 1 || (opt == 0 && ((id_flags & (ID_USEREAL|ID_USENAME)) != 0))) 88 { 89 builtin_usage (); 90 return (EX_USAGE); 91 } 92 93 if (list && list->next) 94 { 95 builtin_usage (); 96 return (EX_USAGE); 97 } 98 99 if (inituser (user) < 0) 100 return (EXECUTION_FAILURE); 101 102 opt = 0; 103 if (id_flags & ID_USERONLY) 104 opt += id_pruser ((id_flags & ID_USEREAL) ? ruid : euid); 105 else if (id_flags & ID_GIDONLY) 106 opt += id_prgrp ((id_flags & ID_USEREAL) ? rgid : egid); 107 else if (id_flags & ID_ALLGROUPS) 108 opt += id_prgroups (user); 109 else 110 opt += id_prall (user); 111 putchar ('\n'); 112 fflush (stdout); 113 114 return (opt == 0 ? EXECUTION_SUCCESS : EXECUTION_FAILURE); 115} 116 117static int 118inituser (uname) 119 char *uname; 120{ 121 struct passwd *pwd; 122 123 if (uname) 124 { 125 pwd = getpwnam (uname); 126 if (pwd == 0) 127 { 128 builtin_error ("%s: no such user", uname); 129 return -1; 130 } 131 ruid = euid = pwd->pw_uid; 132 rgid = egid = pwd->pw_gid; 133 } 134 else 135 { 136 ruid = current_user.uid; 137 euid = current_user.euid; 138 rgid = current_user.gid; 139 egid = current_user.egid; 140 } 141 return 0; 142} 143 144/* Print the name or value of user ID UID. */ 145static int 146id_pruser (uid) 147 int uid; 148{ 149 struct passwd *pwd = NULL; 150 int r; 151 152 r = 0; 153 if (id_flags & ID_USENAME) 154 { 155 pwd = getpwuid (uid); 156 if (pwd == NULL) 157 r = 1; 158 } 159 if (pwd) 160 printf ("%s", pwd->pw_name); 161 else 162 printf ("%u", (unsigned) uid); 163 164 return r; 165} 166 167/* Print the name or value of group ID GID. */ 168 169static int 170id_prgrp (gid) 171 int gid; 172{ 173 struct group *grp = NULL; 174 int r; 175 176 r = 0; 177 if (id_flags & ID_USENAME) 178 { 179 grp = getgrgid (gid); 180 if (grp == NULL) 181 r = 1; 182 } 183 184 if (grp) 185 printf ("%s", grp->gr_name); 186 else 187 printf ("%u", (unsigned) gid); 188 189 return r; 190} 191 192static int 193id_prgroups (uname) 194 char *uname; 195{ 196 int *glist, ng, i, r; 197 198 r = 0; 199 id_prgrp (rgid); 200 if (egid != rgid) 201 { 202 putchar (' '); 203 id_prgrp (egid); 204 } 205 206 if (uname) 207 { 208 builtin_error ("supplementary groups for other users not yet implemented"); 209 glist = (int *)NULL; 210 ng = 0; 211 r = 1; 212 } 213 else 214 glist = get_group_array (&ng); 215 216 for (i = 0; i < ng; i++) 217 if (glist[i] != rgid && glist[i] != egid) 218 { 219 putchar (' '); 220 id_prgrp (glist[i]); 221 } 222 223 return r; 224} 225 226static int 227id_prall (uname) 228 char *uname; 229{ 230 int r, i, ng, *glist; 231 struct passwd *pwd; 232 struct group *grp; 233 234 r = 0; 235 printf ("uid=%u", (unsigned) ruid); 236 pwd = getpwuid (ruid); 237 if (pwd == NULL) 238 r = 1; 239 else 240 printf ("(%s)", pwd->pw_name); 241 242 printf (" gid=%u", (unsigned) rgid); 243 grp = getgrgid (rgid); 244 if (grp == NULL) 245 r = 1; 246 else 247 printf ("(%s)", grp->gr_name); 248 249 if (euid != ruid) 250 { 251 printf (" euid=%u", (unsigned) euid); 252 pwd = getpwuid (euid); 253 if (pwd == NULL) 254 r = 1; 255 else 256 printf ("(%s)", pwd->pw_name); 257 } 258 259 if (egid != rgid) 260 { 261 printf (" egid=%u", (unsigned) egid); 262 grp = getgrgid (egid); 263 if (grp == NULL) 264 r = 1; 265 else 266 printf ("(%s)", grp->gr_name); 267 } 268 269 if (uname) 270 { 271 builtin_error ("supplementary groups for other users not yet implemented"); 272 glist = (int *)NULL; 273 ng = 0; 274 r = 1; 275 } 276 else 277 glist = get_group_array (&ng); 278 279 if (ng > 0) 280 printf (" groups="); 281 for (i = 0; i < ng; i++) 282 { 283 if (i > 0) 284 printf (", "); 285 printf ("%u", (unsigned) glist[i]); 286 grp = getgrgid (glist[i]); 287 if (grp == NULL) 288 r = 1; 289 else 290 printf ("(%s)", grp->gr_name); 291 } 292 293 return r; 294} 295 296char *id_doc[] = { 297 "return information about user identity", 298 (char *)NULL 299}; 300 301struct builtin id_struct = { 302 "id", 303 id_builtin, 304 BUILTIN_ENABLED, 305 id_doc, 306 "id [user]\n\tid -G [-n] [user]\n\tid -g [-nr] [user]\n\tid -u [-nr] [user]", 307 0 308}; 309