| 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)
|
|---|
| 26 | extern struct passwd *getpwuid ();
|
|---|
| 27 | #endif
|
|---|
| 28 | extern 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 |
|
|---|
| 44 | static int id_flags;
|
|---|
| 45 |
|
|---|
| 46 | static uid_t ruid, euid;
|
|---|
| 47 | static gid_t rgid, egid;
|
|---|
| 48 |
|
|---|
| 49 | static char *id_user;
|
|---|
| 50 |
|
|---|
| 51 | static int inituser ();
|
|---|
| 52 |
|
|---|
| 53 | static int id_pruser ();
|
|---|
| 54 | static int id_prgrp ();
|
|---|
| 55 | static int id_prgroups ();
|
|---|
| 56 | static int id_prall ();
|
|---|
| 57 |
|
|---|
| 58 | int
|
|---|
| 59 | id_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 |
|
|---|
| 117 | static int
|
|---|
| 118 | inituser (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. */
|
|---|
| 145 | static int
|
|---|
| 146 | id_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 |
|
|---|
| 169 | static int
|
|---|
| 170 | id_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 |
|
|---|
| 192 | static int
|
|---|
| 193 | id_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 |
|
|---|
| 226 | static int
|
|---|
| 227 | id_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 |
|
|---|
| 296 | char *id_doc[] = {
|
|---|
| 297 | "return information about user identity",
|
|---|
| 298 | (char *)NULL
|
|---|
| 299 | };
|
|---|
| 300 |
|
|---|
| 301 | struct 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 | };
|
|---|