Logo Search packages:      
Sourcecode: ksh version File versions  Download package

id.c

/***********************************************************************
*                                                                      *
*               This software is part of the ast package               *
*          Copyright (c) 1992-2010 AT&T Intellectual Property          *
*                      and is licensed under the                       *
*                  Common Public License, Version 1.0                  *
*                    by AT&T Intellectual Property                     *
*                                                                      *
*                A copy of the License is available at                 *
*            http://www.opensource.org/licenses/cpl1.0.txt             *
*         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
*                                                                      *
*              Information and Software Systems Research               *
*                            AT&T Research                             *
*                           Florham Park NJ                            *
*                                                                      *
*                 Glenn Fowler <gsf@research.att.com>                  *
*                  David Korn <dgk@research.att.com>                   *
*                                                                      *
***********************************************************************/
#pragma prototyped
/*
 * David Korn
 * Glenn Fowler
 * AT&T Research
 *
 * id
 */

static const char usage[] =
"[-?\n@(#)$Id: id (AT&T Research) 2004-06-11 $\n]"
USAGE_LICENSE
"[+NAME?id - return user identity]"
"[+DESCRIPTION?If no \auser\a operand is specified \bid\b writes user and "
      "group IDs and the corresponding user and group names of the "
      "invoking process to standard output.  If the effective and "
      "real IDs do not match, both are written.  Any supplementary "
      "groups the current process belongs to will also be written.]"
"[+?If a \auser\a operand is specified and the process has permission, "
      "the user and group IDs and any supplementary group IDs of the "
      "selected user will be written to standard output.]"
"[+?If any options are specified, then only a portion of the information "
      "is written.]"
"[n:name?Write the name instead of the numeric ID.]"
"[r:real?Writes real ID instead of the effective ID.]"
"[[a?This option is ignored.]"
"[g:group?Writes only the group ID.]"
"[u:user?Writes only the user ID.]"
"[G:groups?Writes only the supplementary group IDs.]"
"[s:fair-share?Writes fair share scheduler IDs and groups on systems that "
      "support fair share scheduling.]"
"\n"
"\n[user]\n"
"\n"
"[+EXIT STATUS?]{"
        "[+0?Successful completion.]"
        "[+>0?An error occurred.]"
"}"
"[+SEE ALSO?\blogname\b(1), \bwho\b(1), \bgetgroups\b(2)]"
;

#include <cmd.h>

#include "FEATURE/ids"

#include <grp.h>
#include <pwd.h>

#if _lib_fsid
#if _lib_getfsgid && ( _sys_fss || _hdr_fsg )
#define fss_grp         fs_grp
#define fss_id          fs_id
#define fss_mem         fs_mem
#define fss_passwd      fs_passwd
#define fss_shares      fs_shares
#if _sys_fss
#include <sys/fss.h>
#endif
#if _hdr_fsg
#include <fsg.h>
#endif
#if !_lib_isfsg && !defined(isfsg)
#define isfsg(p)  (!(p)->fs_id&&!(p)->fs_shares&&(!(p)->fs_passwd||!*(p)->fs_passwd))
#endif
#else
#undef _lib_fsid
#endif
#endif

#define power2(n) (!((n)&((n)-1)))

#define GG_FLAG         (1<<0)
#define G_FLAG          (1<<1)
#define N_FLAG          (1<<2)
#define R_FLAG          (1<<3)
#define U_FLAG          (1<<4)
#define S_FLAG          (1<<5)
#define O_FLAG          (1<<6)
#define X_FLAG          (1<<7)

#if _lib_fsid
static void
getfsids(Sfio_t* sp, const char* name, int flags, register int lastchar)
{
      register struct fsg*    fs;
      register char*          s;
      register char**         p;
      char**                  x;

      if (lastchar)
      {
            if (flags & O_FLAG) flags = 1;
            else flags = 0;
      }
      else if (flags & N_FLAG) flags = 1;
      else flags = -1;
      setfsgent();
      while (fs = getfsgnam(name))
            if (!isfsg(fs))
            {
                  if (p = fs->fs_mem)
                  {
                        if (flags > 0) x = 0;
                        else
                        {
                              register char**         q;
                              register char*          t;
                              register int            n;

                              n = 0;
                              q = p;
                              while (s = *q++)
                                    n += strlen(s) + 1;
                              if (!(x = newof(0, char*, q - p, n)))
                                    break;
                              s = (char*)(x + (q - p));
                              q = x;
                              while (t = *p++)
                              {
                                    *q++ = s;
                                    while (*s++ = *t++);
                              }
                              *q = 0;
                              p = x;
                        }
                        while (s = *p++)
                        {
                              if (lastchar == '=')
                              {
                                    lastchar = ',';
                                    sfputr(sp, " fsid=", -1);
                              }
                              else if (!lastchar) lastchar = ' ';
                              else sfputc(sp, lastchar);
                              if (flags > 0) sfprintf(sp, "%s", s);
                              else
                              {
                                    setfsgent();
                                    while (fs = getfsgnam(s))
                                          if (isfsg(fs))
                                          {
                                                if (flags < 0) sfprintf(sp, "%u", fs->fs_id);
                                                else sfprintf(sp, "%u(%s)", fs->fs_id, s);
                                                break;
                                          }
                              }
                        }
                        if (x) free(x);
                  }
                  break;
            }
      endfsgent();
      if (lastchar == ' ') sfputc(sp, '\n');
}
#endif

static void
putid(Sfio_t* sp, int flags, const char* label, const char* name, long number)
{
      sfprintf(sp, "%s=", label);
      if (flags & O_FLAG)
      {
            if (name) sfputr(sp, name, -1);
            else sfprintf(sp, "%lu", number);
      }
      else
      {
            sfprintf(sp, "%u", number);
            if (name) sfprintf(sp, "(%s)", name);
      }
}

static int
getids(Sfio_t* sp, const char* name, register int flags)
{
      register struct passwd* pw;
      register struct group*  grp;
      register int            i;
      register int            j;
      register int            k;
#if _lib_fsid
      register struct fsg*    fs;
      const char*       fs_name;
      int               fs_id;
#endif
      char**                  p;
      char*             s;
      int               lastchar;
      int               ngroups = 0;
      const char*       gname;
      uid_t             user;
      uid_t             euid;
      gid_t             group;
      gid_t             egid;

      static gid_t*           groups;

      if (flags & GG_FLAG)
      {
            static int  maxgroups;

            /*
             * get supplemental groups if required
             */

            if (!maxgroups)
            {
                  /*
                   * first time
                   */

                  if ((maxgroups = getgroups(0, groups)) <= 0)
                        maxgroups = NGROUPS_MAX;
                  if (!(groups = newof(0, gid_t, maxgroups + 1, 0)))
                        error(ERROR_exit(1), "out of space [group array]");
            }
            ngroups = getgroups(maxgroups, groups);
            for (i = j = 0; i < ngroups; i++)
            {
                  for (k = 0; k < j && groups[k] != groups[i]; k++);
                  if (k >= j) groups[j++] = groups[i];
            }
            ngroups = j;
      }
      if (name)
      {
            flags |= X_FLAG;
            if (!(flags & N_FLAG) || (flags & (G_FLAG|GG_FLAG)))
            {
                  if (!(pw = getpwnam(name)))
                  {
                        user = strtol(name, &s, 0);
                        if (*s || !(pw = getpwuid(user)))
                              error(ERROR_exit(1), "%s: name not found", name);
                        name = pw->pw_name;
                  }
                  user = pw->pw_uid;
                  group = pw->pw_gid;
            }
#if _lib_fsid
            if (!(flags & N_FLAG) || (flags & S_FLAG))
            {
                  setfsgent();
                  do
                        {
                                if (!(fs = getfsgnam(name)))
                                        error(ERROR_exit(1), "%u: fss name not found", name);
                        } while (isfsg(fs));
                        fs_id = fs->fs_id;
            }
#endif
      }
      else
      {
            if (flags & G_FLAG)
                  group = (flags & R_FLAG) ? getgid() : getegid();
            if (flags & (GG_FLAG|N_FLAG|U_FLAG))
                  user = (flags & R_FLAG) ? getuid() : geteuid();
#if _lib_fsid
            if (flags & S_FLAG)
                  fs_id = fsid(0);
#endif
            if (flags & N_FLAG)
                  name = (pw = getpwuid(user)) ? pw->pw_name : (char*)0;
      }
      if (ngroups == 1 && groups[0] == group)
            ngroups = 0;
      if ((flags & N_FLAG) && (flags & G_FLAG))
            gname = (grp = getgrgid(group)) ? grp->gr_name : (char*)0;
#if _lib_fsid
      if ((flags & N_FLAG) && (flags & S_FLAG))
      {
            setfsgent();
            fs_name = (fs = getfsgid(fs_id)) ? fs->fs_grp : (char*)0;
      }
#endif
      if ((flags & (U_FLAG|G_FLAG|S_FLAG)) == (U_FLAG|G_FLAG|S_FLAG))
      {
            putid(sp, flags, "uid", name, user);
            putid(sp, flags, " gid", gname, group);
            if ((flags & X_FLAG) && name)
            {
#if _lib_getgrent
#if _lib_setgrent
                  setgrent();
#endif
                  lastchar = '=';
                  while (grp = getgrent())
                        if (p = grp->gr_mem)
                              while (s = *p++)
                                    if (streq(s, name))
                                    {
                                          if (lastchar == '=')
                                                sfputr(sp, " groups", -1);
                                          sfputc(sp, lastchar);
                                          lastchar = ',';
                                          if (flags & O_FLAG)
                                                sfprintf(sp, "%s", grp->gr_name);
                                          else sfprintf(sp, "%u(%s)", grp->gr_gid, grp->gr_name);
                                    }
#if _lib_endgrent
                  endgrent();
#endif
#endif
#if _lib_fsid
                  getfsids(sp, name, flags, '=');
#endif
            }
            else
            {
                  if ((euid = geteuid()) != user)
                        putid(sp, flags, " euid", (pw = getpwuid(euid)) ? pw->pw_name : (char*)0, euid);
                  if ((egid = getegid()) != group)
                        putid(sp, flags, " egid", (grp = getgrgid(egid)) ? grp->gr_name : (char*)0, egid);
                  if (ngroups > 0)
                  {
                        sfputr(sp, " groups", -1);
                        lastchar = '=';
                        for (i = 0; i < ngroups; i++)
                        {
                              group = groups[i];
                              sfputc(sp, lastchar);
                              if (grp = getgrgid(group))
                              {
                                    if (flags & O_FLAG) sfprintf(sp, "%s", grp->gr_name);
                                    else sfprintf(sp, "%u(%s)", group, grp->gr_name);
                              }
                              else sfprintf(sp, "%u", group);
                              lastchar = ',';
                        }
                  }
#if _lib_fsid
                  putid(sp, flags, " fsid", fs_name, fs_id);
#endif
            }
            sfputc(sp,'\n');
            return(0);
      }
      if (flags & U_FLAG)
      {
            if ((flags & N_FLAG) && name) sfputr(sp, name, '\n');
            else sfprintf(sp, "%u\n", user);
      }
      else if (flags & G_FLAG)
      {
            if ((flags & N_FLAG) && gname) sfputr(sp, gname, '\n');
            else sfprintf(sp, "%u\n", group);
      }
      else if (flags & GG_FLAG)
      {
            if ((flags & X_FLAG) && name)
            {
#if _lib_getgrent
#if _lib_setgrent
                  setgrent();
#endif
                  i = 0;
                  while (grp = getgrent())
                        if (p = grp->gr_mem)
                              while (s = *p++)
                                    if (streq(s, name))
                                    {
                                          if (i++) sfputc(sp, ' ');
                                          if (flags & N_FLAG) sfprintf(sp, "%s", grp->gr_name);
                                          else sfprintf(sp, "%u", grp->gr_gid);
                                    }
#if _lib_endgrent
                  endgrent();
#endif
                  if (i) sfputc(sp, '\n');
#endif
            }
            else if (ngroups > 0)
            {
                  for (i = 0;;)
                  {
                        group = groups[i];
                        if ((flags & N_FLAG) && (grp = getgrgid(group)))
                              sfprintf(sp, "%s", grp->gr_name);
                        else sfprintf(sp, "%u", group);
                        if (++i >= ngroups) break;
                        sfputc(sp, ' ');
                  }
                  sfputc(sp, '\n');
            }
      }
#if _lib_fsid
      else if (flags & S_FLAG)
      {
            if ((flags & X_FLAG) && name) getfsids(sp, name, flags, 0);
            else if ((flags & N_FLAG) && fs_name) sfputr(sp, fs_name, '\n');
            else sfprintf(sp, "%u\n", fs_id);
      }
#endif
      return(0);
}

int
b_id(int argc, char *argv[], void* context)
{
      register int      flags = 0;
      register int      n;

      cmdinit(argc, argv, context, ERROR_CATALOG, 0);
      for (;;)
      {
            switch (optget(argv, usage))
            {
            case 'a':
                  continue;
            case 'G':
                  flags |= GG_FLAG;
                  continue;
            case 'g':
                  flags |= G_FLAG;
                  continue;
            case 'n':
                  flags |= N_FLAG;
                  continue;
            case 'r':
                  flags |= R_FLAG;
                  continue;
            case 's':
                  flags |= S_FLAG;
                  continue;
            case 'u':
                  flags |= U_FLAG;
                  continue;
            case ':':
                  error(2, "%s", opt_info.arg);
                  break;
            case '?':
                  error(ERROR_usage(2), "%s", opt_info.arg);
                  break;
            }
            break;
      }
      argv += opt_info.index;
      argc -= opt_info.index;
      n = (flags & (GG_FLAG|G_FLAG|S_FLAG|U_FLAG));
      if (!power2(n))
            error(2, "incompatible options selected");
      if (error_info.errors || argc > 1)
            error(ERROR_usage(2), "%s", optusage(NiL));
      if (!(flags & ~(N_FLAG|R_FLAG)))
      {
            if (flags & N_FLAG) flags |= O_FLAG;
            flags |= (U_FLAG|G_FLAG|N_FLAG|R_FLAG|S_FLAG|GG_FLAG);
      }
      error_info.errors = getids(sfstdout, *argv, flags);
      return(error_info.errors);
}

Generated by  Doxygen 1.6.0   Back to index