[Toybox] [PATCH] id can work without /etc/{passwd,groups}

enh enh at google.com
Thu Mar 19 22:43:54 PDT 2015


i'm guessing you didn't build this against bionic? bionic never reads
/etc/passwd because there isn't one on Android. try again with bionic!

On Thu, Mar 19, 2015 at 10:40 PM, hhm <heehooman at gmail.com> wrote:
> dunno :-S
>
> I tested this on a nexus 5 with android 5.1. It errors out with "id:
> bad uid <uid>". Tested with adb shell and with jackpal.androidterm.
>
> Stracing shows that it is ENOENTing on /etc/passwd.
>
> Regardless, I think it would be good to only use /etc/passwd or
> /etc/group when possible (even if it works OK on android with them
> being queried). This can be useful, for example, when running a very
> barebones linux install, or in other situations.
>
> However, I am not sure if my patch is the best way to do this :-) I am
> not so familiar with the toybox code, and may not have implemented
> this in the best/cleanest way.
>
> Thank you for your feedback, enh!
>
> On 3/19/15, enh <enh at google.com> wrote:
>> the version of toybox checked in to AOSP works just fine already:
>>
>> $ adb shell toybox id -u
>> 0
>> $ adb shell toybox id -g
>> 0
>> $ adb unroot
>> restarting adbd as non root
>> $ adb shell toybox id -u
>> 2000
>> $ adb shell toybox id -g
>> 2000
>> $
>>
>>
>> On Thu, Mar 19, 2015 at 7:08 PM, hhm <heehooman at gmail.com> wrote:
>>
>>> The toybox implementation of `id` shouldn't error out when no
>>> /etc/passwd or /etc/group is present (other implementations, for
>>> example busybox, didn't error when tested).
>>>
>>> Currently, doing `id -u` (or `id -g` etc.) will error out, even though
>>> no data from the above files is necessary; all the information can be
>>> gotten from the syscalls. This is because pw->pw_uid and grp->gr_gid
>>> are used while only the values of getuid() and getgid() are required.
>>>
>>> Therefore, these commands will error out on stock android, where none
>>> of these files are present in their standard locations.
>>>
>>> This can easily be remedied by just using the values returned by the
>>> syscalls, which are in fact already stored in variables in the present
>>> implementation, for -u and -g, when -n is not used and no [user] is
>>> provided on the command line (in which case those files need to be
>>> queried anyway).
>>>
>>>
>>> diff --git a/toys/posix/id.c b/toys/posix/id.c
>>> index a5a94a5..950b02b 100644
>>> --- a/toys/posix/id.c
>>> +++ b/toys/posix/id.c
>>> @@ -86,8 +86,8 @@ void do_id(char *username)
>>>    int flags, i, ngroups;
>>>    struct passwd *pw;
>>>    struct group *grp;
>>> -  uid_t uid = getuid(), euid = geteuid();
>>> -  gid_t gid = getgid(), egid = getegid(), *groups;
>>> +  uid_t uid = getuid(), euid = geteuid(), iuid;
>>> +  gid_t gid = getgid(), egid = getegid(), *groups, igid;
>>>
>>>    flags = toys.optflags;
>>>
>>> @@ -100,66 +100,77 @@ void do_id(char *username)
>>>    }
>>>
>>>    i = flags & FLAG_r;
>>> -  pw = xgetpwuid(i ? uid : euid);
>>> -  if (TT.do_u) s_or_u(pw->pw_name, pw->pw_uid, 1);
>>> -
>>> -  grp = xgetgrgid(i ? gid : egid);
>>> -  if (flags & FLAG_g) s_or_u(grp->gr_name, grp->gr_gid, 1);
>>> +  iuid = i ? uid : euid;
>>> +  igid = i ? gid : egid;
>>> +
>>> +  if ((!TT.do_n) && (TT.do_u || (flags & FLAG_g))) {
>>> +    if (TT.do_u) {
>>> +      s_or_u("", iuid, 1);
>>> +    } else {
>>> +      s_or_u("", igid, 1);
>>> +    }
>>> +  } else {
>>> +    pw = xgetpwuid(iuid);
>>> +    if (TT.do_u) s_or_u(pw->pw_name, pw->pw_uid, 1);
>>> +
>>> +    grp = xgetgrgid(igid);
>>> +    if (flags & FLAG_g) s_or_u(grp->gr_name, grp->gr_gid, 1);
>>> +
>>> +    if (!TT.do_G && !TT.do_Z) {
>>> +      showid("uid=", pw->pw_uid, pw->pw_name);
>>> +      showid(" gid=", grp->gr_gid, grp->gr_name);
>>> +
>>> +      if (!i) {
>>> +        if (uid != euid) {
>>> +          pw = xgetpwuid(euid);
>>> +          showid(" euid=", pw->pw_uid, pw->pw_name);
>>> +        }
>>> +        if (gid != egid) {
>>> +          grp = xgetgrgid(egid);
>>> +          showid(" egid=", grp->gr_gid, grp->gr_name);
>>> +        }
>>> +      }
>>>
>>> -  if (!TT.do_G && !TT.do_Z) {
>>> -    showid("uid=", pw->pw_uid, pw->pw_name);
>>> -    showid(" gid=", grp->gr_gid, grp->gr_name);
>>> +      showid(" groups=", grp->gr_gid, grp->gr_name);
>>> +    }
>>>
>>> -    if (!i) {
>>> -      if (uid != euid) {
>>> -        pw = xgetpwuid(euid);
>>> -        showid(" euid=", pw->pw_uid, pw->pw_name);
>>> +    if (!TT.do_Z) {
>>> +      groups = (gid_t *)toybuf;
>>> +      i = sizeof(toybuf)/sizeof(gid_t);
>>> +      ngroups = username ? getgrouplist(username, gid, groups, &i)
>>> +        : getgroups(i, groups);
>>> +      if (ngroups<0) perror_exit(0);
>>> +
>>> +      int show_separator = !TT.do_G;
>>> +      for (i = 0; i<ngroups; i++) {
>>> +        if (show_separator) xputc(TT.do_G ? ' ' : ',');
>>> +        show_separator = 1;
>>> +        if (!(grp = getgrgid(groups[i]))) perror_msg(0);
>>> +        else if (TT.do_G) s_or_u(grp->gr_name, grp->gr_gid, 0);
>>> +        else if (grp->gr_gid != egid) showid("", grp->gr_gid,
>>> grp->gr_name);
>>> +        else show_separator = 0; // Because we didn't show anything this
>>> time.
>>>        }
>>> -      if (gid != egid) {
>>> -        grp = xgetgrgid(egid);
>>> -        showid(" egid=", grp->gr_gid, grp->gr_name);
>>> +      if (TT.do_G) {
>>> +        xputc('\n');
>>> +        exit(0);
>>>        }
>>>      }
>>>
>>> -    showid(" groups=", grp->gr_gid, grp->gr_name);
>>> -  }
>>> +    if (CFG_TOYBOX_SELINUX) {
>>> +      char *context = NULL;
>>>
>>> -  if (!TT.do_Z) {
>>> -    groups = (gid_t *)toybuf;
>>> -    i = sizeof(toybuf)/sizeof(gid_t);
>>> -    ngroups = username ? getgrouplist(username, gid, groups, &i)
>>> -      : getgroups(i, groups);
>>> -    if (ngroups<0) perror_exit(0);
>>> -
>>> -    int show_separator = !TT.do_G;
>>> -    for (i = 0; i<ngroups; i++) {
>>> -      if (show_separator) xputc(TT.do_G ? ' ' : ',');
>>> -      show_separator = 1;
>>> -      if (!(grp = getgrgid(groups[i]))) perror_msg(0);
>>> -      else if (TT.do_G) s_or_u(grp->gr_name, grp->gr_gid, 0);
>>> -      else if (grp->gr_gid != egid) showid("", grp->gr_gid,
>>> grp->gr_name);
>>> -      else show_separator = 0; // Because we didn't show anything this
>>> time.
>>> -    }
>>> -    if (TT.do_G) {
>>> -      xputc('\n');
>>> -      exit(0);
>>> +      if (is_selinux_enabled() < 1) {
>>> +        if (TT.do_Z)
>>> +          error_exit("SELinux disabled");
>>> +      } else if (getcon(&context) == 0) {
>>> +        if (!TT.do_Z) xputc(' ');
>>> +        printf("context=%s", context);
>>> +      }
>>> +      if (CFG_TOYBOX_FREE) free(context);
>>>      }
>>> -  }
>>> -
>>> -  if (CFG_TOYBOX_SELINUX) {
>>> -    char *context = NULL;
>>>
>>> -    if (is_selinux_enabled() < 1) {
>>> -      if (TT.do_Z)
>>> -        error_exit("SELinux disabled");
>>> -    } else if (getcon(&context) == 0) {
>>> -      if (!TT.do_Z) xputc(' ');
>>> -      printf("context=%s", context);
>>> -    }
>>> -    if (CFG_TOYBOX_FREE) free(context);
>>> +    xputc('\n');
>>>    }
>>> -
>>> -  xputc('\n');
>>>  }
>>>
>>>  void id_main(void)
>>> _______________________________________________
>>> Toybox mailing list
>>> Toybox at lists.landley.net
>>> http://lists.landley.net/listinfo.cgi/toybox-landley.net
>>>
>>
>>
>>
>> --
>> Elliott Hughes - http://who/enh - http://jessies.org/~enh/
>> Android native code/tools questions? Mail me/drop by/add me as a reviewer.
>>



-- 
Elliott Hughes - http://who/enh - http://jessies.org/~enh/
Android native code/tools questions? Mail me/drop by/add me as a reviewer.

 1426830234.0


More information about the Toybox mailing list