Re: Get a user's all groups

Daniel Sahlberg <[email protected]>
Newsgroups gmane.comp.apache.apr.devel
Message-ID <CAMHy98PsxTRtw3jUikTevihpCmEavvRZwPeoxCjeRDS=8m_02A@mail.gmail.com>
Den tis 2 jan. 2024 kl 12:03 skrev Joe Orton <[email protected]>:

> On Tue, Dec 26, 2023 at 07:17:51PM +0100, Daniel Sahlberg wrote:
> > Hi,
> >
> > apr_uid_current() can retur the user id and primary group id of a user.
> Is
> > there a way to find out if a user also has secondary groups (something
> > similar to getgrouplist(3)?
> >
> > The Subversion project has some bug reports where a user has R/W access
> to
> > a certain file via a secondary group, but APR doesn't pick up the
> secondary
> > groups and thus we don't think the user has R/W access. I'd like to
> improve
> > this by also considering all secondary groups.
>
> How are you testing for readability/writability here exactly? On Unix
> the right way is using access() but there isn't an APR wrapper for it.
> (Trying to manually check against user/groups is not a reliable way to
> test, not just because of groups but also because of things like setuid
> processes and RBAC systems which may exist on top of the user/groups.)
>

I also thought about RBACs (but I didn't know that was the term) and we are
checking exactly the wrong way:

[[[
  SVN_ERR(svn_io_stat(&file_info, path, APR_FINFO_PROT | APR_FINFO_OWNER,
                      pool));
...
#if defined(APR_HAS_USER) && !defined(WIN32) &&!defined(__OS2__)
  apr_err = apr_uid_current(&uid, &gid, pool);

  if (apr_err)
    return svn_error_wrap_apr(apr_err, _("Error getting UID of process"));

  /* Check write bit for current user. */
  if (apr_uid_compare(uid, file_info->user) == APR_SUCCESS)
    *read_only = !(file_info->protection & APR_UWRITE);

  else if (apr_gid_compare(gid, file_info->group) == APR_SUCCESS)
    *read_only = !(file_info->protection & APR_GWRITE);

  else
    *read_only = !(file_info->protection & APR_WWRITE);
#endif
]]]
(And for the eagle eyed reader, the code above is copied from two different
functions, thus file_info is a struct in one case and a pointer-to-struct
in another, but I assume the principle should be clear enough).

The origin of the code is from ~2002 (checking for APR_*EXECUTE), copied to
a new function around 2011 (checking for APR_*WRITE).

My idea was to incrementally improve the code but maybe a better way is to
switch to access() completely. access() seems to be widely available but I
will have to read up on the setuid properties to make sure we don't change
how things has worked in the past.

Background: Subversion has the ability to say a file "needs locking", if a
particular user/working copy doesn't hold the "lock" the file should be
read-only (and inversely if the user holds the lock the file should be
writeable). We check for W access using the code above and then update the
permissions accordingly.

Kind regards,
Daniel
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.