On Wed, 2015-11-25 at 16:56 -0500, Boris Ostrovsky wrote:
> getpwnam_r() has fairly complicated return rules. From man pages:
> 
>   RETURN VALUE
>       ...
>       On success, getpwnam_r() and getpwuid_r() return zero, and set
>       *result to pwd.  If no matching  password record was found, these
>       functions return 0 and store NULL in *result. In case of error,
>       an error number is returned, and NULL is stored in *result.
>   ERRORS
>       0 or ENOENT or ESRCH or EBADF or EPERM or ...
>             The given name or uid was not found.

My reference when reviewing this is the (IMHO more canonical) http://pubs.o
pengroup.org/onlinepubs/9699919799/functions/getpwnam.html .

I suppose you are looking at the Linux and/or glibc man pages?

> While it's not clear what ellipses are meant to be, the way we currently
> treat return values from getpwnam_r() is no sufficient. In fact, two of
> my systems behave differently when username is not found: one returns
> ENOENT and the other returns 0.

Which two systems are these? When you say "returns" do you mean "returns 0
and sets errno to XXX" or literally returns ENOENT?

>  Both set *result to NULL.
> 
> This patch adjusts return value management to be more in line with man
> pages.
> 
> While at it, also make sure we don't get stuck on ERANGE.
> 
> Signed-off-by: Boris Ostrovsky <boris.ostrov...@oracle.com>
> ---
>  tools/libxl/libxl_dm.c | 23 ++++++++++++++---------
>  1 file changed, 14 insertions(+), 9 deletions(-)
> 
> diff --git a/tools/libxl/libxl_dm.c b/tools/libxl/libxl_dm.c
> index a4934df..bd3daeb 100644
> --- a/tools/libxl/libxl_dm.c
> +++ b/tools/libxl/libxl_dm.c
> @@ -726,7 +726,7 @@ static int libxl__dm_runas_helper(libxl__gc *gc,
> const char *username)
>      struct passwd pwd, *user = NULL;
>      char *buf = NULL;
>      long buf_size;
> -    int ret;
> +    int ret, retry_cnt = 0;
>  
>      buf_size = sysconf(_SC_GETPW_R_SIZE_MAX);
>      if (buf_size < 0) {
> @@ -740,12 +740,17 @@ static int libxl__dm_runas_helper(libxl__gc *gc,
> const char *username)
>          ret = getpwnam_r(username, &pwd, buf, buf_size, &user);
>          if (ret == ERANGE) {
>              buf_size += 128;
> +            if (retry_cnt++ > 10)
> +                    return ERROR_FAIL;
>              continue;
>          }
> -        if (ret != 0)
> -            return ERROR_FAIL;
> -        if (user != NULL)
> -            return 1;
> +        if (user == NULL) {
> +            if (!ret || (ret == ENOENT) || (ret == ESRCH) ||
> +                (ret == EBADF) || (ret == EPERM))
> +                return ERROR_NOTFOUND;
> +            else
> +                return ERROR_FAIL;
> +        }
>          return 0;
>      }
>  }
> @@ -1261,16 +1266,16 @@ static int
> libxl__build_device_model_args_new(libxl__gc *gc,
>  
>          user = GCSPRINTF("%s%d", LIBXL_QEMU_USER_BASE, guest_domid);
>          ret = libxl__dm_runas_helper(gc, user);
> -        if (ret < 0)
> +        if (ret && (ret != ERROR_NOTFOUND))
>              return ret;
> -        if (ret > 0)
> +        if (!ret)
>              goto end_search;
>  
>          user = LIBXL_QEMU_USER_SHARED;
>          ret = libxl__dm_runas_helper(gc, user);
> -        if (ret < 0)
> +        if (ret && (ret != ERROR_NOTFOUND))
>              return ret;
> -        if (ret > 0) {
> +        if (!ret) {
>              LOG(WARN, "Could not find user %s%d, falling back to %s",
>                      LIBXL_QEMU_USER_BASE, guest_domid,
> LIBXL_QEMU_USER_SHARED);
>              goto end_search;
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

Reply via email to