328 lines
		
	
	
	
		
			6.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			328 lines
		
	
	
	
		
			6.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * id - POSIX.2 user identity
 | |
|  *
 | |
|  * (INCOMPLETE -- supplementary groups for other users not yet done)
 | |
|  *
 | |
|  * usage: id [-Ggu] [-nr] [user]
 | |
|  *
 | |
|  * The default output format looks something like:
 | |
|  *	uid=xxx(chet) gid=xx groups=aa(aname), bb(bname), cc(cname)
 | |
|  */
 | |
| 
 | |
| /*
 | |
|    Copyright (C) 1999-2009 Free Software Foundation, Inc.
 | |
| 
 | |
|    This file is part of GNU Bash.
 | |
|    Bash is free software: you can redistribute it and/or modify
 | |
|    it under the terms of the GNU General Public License as published by
 | |
|    the Free Software Foundation, either version 3 of the License, or
 | |
|    (at your option) any later version.
 | |
| 
 | |
|    Bash is distributed in the hope that it will be useful,
 | |
|    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
|    GNU General Public License for more details.
 | |
| 
 | |
|    You should have received a copy of the GNU General Public License
 | |
|    along with Bash.  If not, see <http://www.gnu.org/licenses/>.
 | |
| */
 | |
| 
 | |
| #include <config.h>
 | |
| #include <stdio.h>
 | |
| #include "bashtypes.h"
 | |
| #include <pwd.h>
 | |
| #include <grp.h>
 | |
| #include "bashansi.h"
 | |
| 
 | |
| #ifdef HAVE_LIMITS_H
 | |
| #  include <limits.h>
 | |
| #else
 | |
| #  include <sys/param.h>
 | |
| #endif
 | |
| 
 | |
| #if !defined (HAVE_GETPW_DECLS)
 | |
| extern struct passwd *getpwuid ();
 | |
| #endif
 | |
| extern struct group *getgrgid ();
 | |
| 
 | |
| #include "shell.h"
 | |
| #include "builtins.h"
 | |
| #include "stdc.h"
 | |
| #include "common.h"
 | |
| #include "bashgetopt.h"
 | |
| 
 | |
| #define ID_ALLGROUPS	0x001		/* -G */
 | |
| #define ID_GIDONLY	0x002		/* -g */
 | |
| #define ID_USENAME	0x004		/* -n */
 | |
| #define ID_USEREAL	0x008		/* -r */
 | |
| #define ID_USERONLY	0x010		/* -u */
 | |
| 
 | |
| #define ID_FLAGSET(s)	((id_flags & (s)) != 0)
 | |
| 
 | |
| static int id_flags;
 | |
| 
 | |
| static uid_t ruid, euid;
 | |
| static gid_t rgid, egid;
 | |
| 
 | |
| static char *id_user;
 | |
| 
 | |
| static int inituser ();
 | |
| 
 | |
| static int id_pruser ();
 | |
| static int id_prgrp ();
 | |
| static int id_prgroups ();
 | |
| static int id_prall ();
 | |
| 
 | |
| int
 | |
| id_builtin (list)
 | |
|      WORD_LIST *list;
 | |
| {
 | |
|   int opt;
 | |
|   char *user;
 | |
| 
 | |
|   id_flags = 0;
 | |
|   reset_internal_getopt ();
 | |
|   while ((opt = internal_getopt (list, "Ggnru")) != -1)
 | |
|     {
 | |
|       switch (opt)
 | |
| 	{
 | |
| 	case 'G': id_flags |= ID_ALLGROUPS; break;
 | |
| 	case 'g': id_flags |= ID_GIDONLY; break;
 | |
| 	case 'n': id_flags |= ID_USENAME; break;
 | |
| 	case 'r': id_flags |= ID_USEREAL; break;
 | |
| 	case 'u': id_flags |= ID_USERONLY; break;
 | |
| 	default:
 | |
| 	  builtin_usage ();
 | |
| 	  return (EX_USAGE);
 | |
| 	}
 | |
|     }
 | |
|   list = loptend;
 | |
| 
 | |
|   user = list ? list->word->word : (char *)NULL;
 | |
| 
 | |
|   /* Check for some invalid option combinations */
 | |
|   opt = ID_FLAGSET (ID_ALLGROUPS) + ID_FLAGSET (ID_GIDONLY) + ID_FLAGSET (ID_USERONLY);
 | |
|   if (opt > 1 || (opt == 0 && ((id_flags & (ID_USEREAL|ID_USENAME)) != 0)))
 | |
|     {
 | |
|       builtin_usage ();
 | |
|       return (EX_USAGE);
 | |
|     }
 | |
| 
 | |
|   if (list && list->next)
 | |
|     {
 | |
|       builtin_usage ();
 | |
|       return (EX_USAGE);
 | |
|     }
 | |
| 
 | |
|   if (inituser (user) < 0)
 | |
|     return (EXECUTION_FAILURE);
 | |
| 
 | |
|   opt = 0;
 | |
|   if (id_flags & ID_USERONLY)
 | |
|     opt += id_pruser ((id_flags & ID_USEREAL) ? ruid : euid);
 | |
|   else if (id_flags & ID_GIDONLY)
 | |
|     opt += id_prgrp ((id_flags & ID_USEREAL) ? rgid : egid);
 | |
|   else if (id_flags & ID_ALLGROUPS)
 | |
|     opt += id_prgroups (user);
 | |
|   else
 | |
|     opt += id_prall (user);
 | |
|   putchar ('\n');
 | |
|   fflush (stdout);
 | |
| 
 | |
|   return (opt == 0 ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
 | |
| }
 | |
| 
 | |
| static int
 | |
| inituser (uname)
 | |
|      char *uname;
 | |
| {
 | |
|   struct passwd *pwd;
 | |
| 
 | |
|   if (uname)
 | |
|     {
 | |
|       pwd = getpwnam (uname);
 | |
|       if (pwd == 0)
 | |
| 	{
 | |
| 	  builtin_error ("%s: no such user", uname);
 | |
| 	  return -1;
 | |
| 	}
 | |
|       ruid = euid = pwd->pw_uid;
 | |
|       rgid = egid = pwd->pw_gid;
 | |
|     }
 | |
|   else
 | |
|     {
 | |
|       ruid = current_user.uid;
 | |
|       euid = current_user.euid;
 | |
|       rgid = current_user.gid;
 | |
|       egid = current_user.egid;
 | |
|     }
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| /* Print the name or value of user ID UID. */
 | |
| static int
 | |
| id_pruser (uid)
 | |
|      int uid;
 | |
| {
 | |
|   struct passwd *pwd = NULL;
 | |
|   int r;
 | |
| 
 | |
|   r = 0;
 | |
|   if (id_flags & ID_USENAME)
 | |
|     {
 | |
|       pwd = getpwuid (uid);
 | |
|       if (pwd == NULL)
 | |
|         r = 1;
 | |
|     }
 | |
|   if (pwd)
 | |
|     printf ("%s", pwd->pw_name);
 | |
|   else
 | |
|     printf ("%u", (unsigned) uid);
 | |
|       
 | |
|   return r;
 | |
| }
 | |
| 
 | |
| /* Print the name or value of group ID GID. */
 | |
| 
 | |
| static int
 | |
| id_prgrp (gid)
 | |
|      int gid;
 | |
| {
 | |
|   struct group *grp = NULL;
 | |
|   int r;
 | |
| 
 | |
|   r = 0;
 | |
|   if (id_flags & ID_USENAME)
 | |
|     {
 | |
|       grp = getgrgid (gid);
 | |
|       if (grp == NULL)
 | |
| 	r = 1;
 | |
|     }
 | |
| 
 | |
|   if (grp)
 | |
|     printf ("%s", grp->gr_name);
 | |
|   else
 | |
|     printf ("%u", (unsigned) gid);
 | |
| 
 | |
|   return r;
 | |
| }
 | |
| 
 | |
| static int
 | |
| id_prgroups (uname)
 | |
|      char *uname;
 | |
| {
 | |
|   int *glist, ng, i, r;
 | |
| 
 | |
|   r = 0;
 | |
|   id_prgrp (rgid);
 | |
|   if (egid != rgid)
 | |
|     {
 | |
|       putchar (' ');
 | |
|       id_prgrp (egid);
 | |
|     }
 | |
| 
 | |
|   if (uname)
 | |
|     {
 | |
|       builtin_error ("supplementary groups for other users not yet implemented");
 | |
|       glist = (int *)NULL;
 | |
|       ng = 0;
 | |
|       r = 1;
 | |
|     }
 | |
|   else
 | |
|     glist = get_group_array (&ng);
 | |
| 
 | |
|   for (i = 0; i < ng; i++)
 | |
|     if (glist[i] != rgid && glist[i] != egid)
 | |
|       {
 | |
| 	putchar (' ');
 | |
| 	id_prgrp (glist[i]);
 | |
|       }
 | |
|   
 | |
|   return r;
 | |
| }
 | |
| 
 | |
| static int
 | |
| id_prall (uname)
 | |
|      char *uname;
 | |
| {
 | |
|   int r, i, ng, *glist;
 | |
|   struct passwd *pwd;
 | |
|   struct group *grp;
 | |
| 
 | |
|   r = 0;
 | |
|   printf ("uid=%u", (unsigned) ruid);
 | |
|   pwd = getpwuid (ruid);
 | |
|   if (pwd == NULL)
 | |
|     r = 1;
 | |
|   else
 | |
|     printf ("(%s)", pwd->pw_name);
 | |
| 
 | |
|   printf (" gid=%u", (unsigned) rgid);
 | |
|   grp = getgrgid (rgid);
 | |
|   if (grp == NULL)
 | |
|     r = 1;
 | |
|   else
 | |
|     printf ("(%s)", grp->gr_name);
 | |
| 
 | |
|   if (euid != ruid)
 | |
|     { 
 | |
|       printf (" euid=%u", (unsigned) euid);
 | |
|       pwd = getpwuid (euid);
 | |
|       if (pwd == NULL)
 | |
| 	r = 1;
 | |
|       else 
 | |
| 	printf ("(%s)", pwd->pw_name);
 | |
|     }
 | |
| 
 | |
|   if (egid != rgid) 
 | |
|     {
 | |
|       printf (" egid=%u", (unsigned) egid);
 | |
|       grp = getgrgid (egid);
 | |
|       if (grp == NULL)
 | |
| 	r = 1;
 | |
|       else
 | |
| 	printf ("(%s)", grp->gr_name);
 | |
|     }
 | |
| 
 | |
|   if (uname)
 | |
|     {
 | |
|       builtin_error ("supplementary groups for other users not yet implemented");
 | |
|       glist = (int *)NULL;
 | |
|       ng = 0;
 | |
|       r = 1;
 | |
|     }
 | |
|   else
 | |
|     glist = get_group_array (&ng);
 | |
| 
 | |
|   if (ng > 0)
 | |
|     printf (" groups=");
 | |
|   for (i = 0; i < ng; i++)
 | |
|     {
 | |
|       if (i > 0)
 | |
| 	printf (", ");
 | |
|       printf ("%u", (unsigned) glist[i]);
 | |
|       grp = getgrgid (glist[i]);
 | |
|       if (grp == NULL)
 | |
| 	r = 1;
 | |
|       else
 | |
| 	printf ("(%s)", grp->gr_name);
 | |
|     }
 | |
| 
 | |
|   return r;
 | |
| }
 | |
| 
 | |
| char *id_doc[] = {
 | |
| 	"Display information about user."
 | |
| 	"",
 | |
| 	"Return information about user identity",
 | |
| 	(char *)NULL
 | |
| };
 | |
| 
 | |
| struct builtin id_struct = {
 | |
| 	"id",
 | |
| 	id_builtin,
 | |
| 	BUILTIN_ENABLED,
 | |
| 	id_doc,
 | |
| 	"id [user]\n\tid -G [-n] [user]\n\tid -g [-nr] [user]\n\tid -u [-nr] [user]",
 | |
| 	0
 | |
| };
 | 
