Ludovic Courtès wrote: > Hi Paul, > > Paul Eggert <egg...@cs.ucla.edu> skribis: > >> On 11/12/11 13:48, Ludovic Courtès wrote: >>> +#ifdef __GNU__ >>> + if (euid == -1 && !use_real >>> + && !just_group && !just_group_list && !just_context) >>> + error (EXIT_FAILURE, errno, _("cannot get effective UID")); >>> +#endif >> >> I suggest removing the "#ifdef __GNU__" here and in its other >> three uses in the patch, as functions like as geteuid() can fail on >> a few non-GNU systems too. See: >> >> http://publib.boulder.ibm.com/infocenter/iseries/v5r3/index.jsp?topic=%2Fapis%2Fgeteuid.htm >> >> For this particular application (the 'id' program) I doubt whether >> it's worth our time to configure this stuff at compile-time, >> and that it's fine to do a run-time check on all platforms. > > OTOH, on POSIX-conforming systems (which includes GNU/Linux, so it may > be the majority of systems in use), -1 may well be a valid UID/GID. > > That’s why I was conservative and decided to ifdef that. This ifdef > also served as a documentation that this is a GNU extension to POSIX. > > Perhaps it’d be safer to keep an ifdef and list all the OSes known to > have this behavior?
Thanks for persevering. I tested this on a gnu/linux system and found that I could indeed create a user with a UID of 2^32-1 (though not directly via adduser -- it imposes a maximum of 2^32-2), and that without something like those #ifdefs, GNU id would mistakenly fail for such a user: id: cannot get effective UID: No such file or directory However, with the patch below, it does this: $ ./id -u 4294967295 diff --git a/src/id.c b/src/id.c index 19cf0cf..047e40b 100644 --- a/src/id.c +++ b/src/id.c @@ -38,6 +38,13 @@ proper_name ("Arnold Robbins"), \ proper_name ("David MacKenzie") +/* Whether the functions getuid, geteuid, getgid and getegid may fail. */ +#ifdef __GNU__ +# define GETID_MAY_FAIL 1 +#else +# define GETID_MAY_FAIL 0 +#endif + /* If nonzero, output only the SELinux context. -Z */ static int just_context = 0; @@ -202,21 +209,21 @@ main (int argc, char **argv) else { euid = geteuid (); - if (euid == -1 && !use_real + if (GETID_MAY_FAIL && euid == -1 && !use_real && !just_group && !just_group_list && !just_context) error (EXIT_FAILURE, errno, _("cannot get effective UID")); ruid = getuid (); - if (ruid == -1 && use_real + if (GETID_MAY_FAIL && ruid == -1 && use_real && !just_group && !just_group_list && !just_context) error (EXIT_FAILURE, errno, _("cannot get real UID")); egid = getegid (); - if (egid == -1 && !use_real && !just_user) + if (GETID_MAY_FAIL && egid == -1 && !use_real && !just_user) error (EXIT_FAILURE, errno, _("cannot get effective GID")); rgid = getgid (); - if (rgid == -1 && use_real && !just_user) + if (GETID_MAY_FAIL && rgid == -1 && use_real && !just_user) error (EXIT_FAILURE, errno, _("cannot get real GID")); }