[libvirt] [PATCH 1/2] util: Don't fail virGetUserIDByName when user not found
Peter Krempa
pkrempa at redhat.com
Thu Dec 6 09:59:09 UTC 2012
On 12/06/12 10:25, Osier Yang wrote:
> On 2012年12月05日 20:03, Christophe Fergeau wrote:
>> virGetUserIDByName is documented as returning 1 if the username
>> cannot be found. getpwnam_r is documented as returning:
>> « 0 or ENOENT or ESRCH or EBADF or EPERM or ... The given name
>> or uid was not found. »
>> and that:
>> « The formulation given above under "RETURN VALUE" is from POSIX.1-2001.
>> It does not call "not found" an error, hence does not specify what
>> value errno might have in this situation. But that makes it
>> impossible to
>> recognize errors. One might argue that according to POSIX errno
>> should be
>> left unchanged if an entry is not found. Experiments on various
>> UNIX-like
>> systems shows that lots of different values occur in this situation: 0,
>> ENOENT, EBADF, ESRCH, EWOULDBLOCK, EPERM and probably others. »
>>
>> virGetUserIDByName returns an error when the return value of getpwnam_r
>> is non-0. However on my RHEL system, getpwnam_r returns ENOENT when the
>> requested user cannot be found, which then causes virGetUserID not
>> to behave as documented (it returns an error instead of falling back
>> to parsing the passed-in value as an uid).
>>
>> This commit makes virGetUserIDByName ignore the various values listed
>> in getpwnam_r manpage and return a 'user not found' result in such
>> cases.
>> ---
>> src/util/util.c | 3 ++-
>> 1 file changed, 2 insertions(+), 1 deletion(-)
>>
>> diff --git a/src/util/util.c b/src/util/util.c
>> index 2fd0f2c..df1af7e 100644
>> --- a/src/util/util.c
>> +++ b/src/util/util.c
>> @@ -2530,7 +2530,8 @@ virGetUserIDByName(const char *name, uid_t *uid)
>> }
>> }
>>
>> - if (rc != 0) {
>> + if ((rc != 0)&& (rc != ENOENT)&& (rc != ESRCH)
>> +&& (rc != EBADF)&& (rc != EPERM)) {
>
> Correct indention should be:
>
> if ((rc != 0) && (rc != ENOENT) && (rc != ESRCH) &&
> (rc != EBADF) && (rc != EPERM))
When I was changing the code the first time, I got rid of this as the
docs for getpwnam_r seemed clear enough to me that this shouldn't be
needed. But I was wrong and I'd rather not reintroduce this ugly and
nondeterministic error checking.
>
> Per the POSIX standard, even these errors are not enough,
> should we give up using getpwnam_r/getgrnam_r, and create
> helpers using getpwent/getgrent to do the lookup work
> ourselves?
Hmm, those look fine to me. I didn't do my research properly when
changing the code the first time.
>
> <...>
> The getpwent() function returns a pointer to a passwd structure,
> or NULL if there are no more entries or an error occurs. If an
> error occurs, errno is set appropriately. If one wants to check
> errno after the call, it should be set to zero before the call.
> </...>
>
> <...>
> ERRORS
> EINTR A signal was caught.
>
> EIO I/O error.
>
> EMFILE The maximum number (OPEN_MAX) of files was open already
> in the calling process.
>
> ENFILE The maximum number of files was open already in the system.
>
> ENOMEM Insufficient memory to allocate passwd structure.
>
> ERANGE Insufficient buffer space supplied.
> </...>
>
> I think it's pretty easy to distiguish NOT FOUND and other error
> then.
That's true. I'll look into this and check if it's feasible for us to do
in libvirt.
>
> Regards,
> Osier
>
> --
> libvir-list mailing list
> libvir-list at redhat.com
> https://www.redhat.com/mailman/listinfo/libvir-list
More information about the libvir-list
mailing list