RHEL/CentOS 8.x, Ruby 2.5.5, irb 0.9.6
We have a specialized set up that keeps user and group information in /usr/local/etc/[user|group]
and a custom Makefile to add that information to /var/db/[group|passwd].db
accordingly.
I am trying to get the list of groups a user belongs to, in Ruby, after login.
I'm relatively new to the language, and have just read the documentation for the Etc module but that seems to exclusively work with the /etc/
filesystem. Not outrageous tbh.
Is there an easy way to access the Berkley DB info in /var/db
or am I going to have to iterate through the /usr/local/etc/group
file to get this information?
I suspect that the documentation of that module is heavily simplified, heavily outdated, or both. I am almost 100% sure that
Etc
will use the OS-provided standard library functions instead of going off and parsing system files by itself. (Why would the Ruby developers write parsers for the configuration files of every single OS they support, instead of just calling a POSIX function?)You can confirm this suspicion using
strace
.If you look at how the Ruby
Etc
module is structured, it maps 1:1 to the POSIX functions:Etc::gegtrent
: gets the next group entry.Etc::endgtrent
: stops iterating the groups.Etc::settrent
: resets the iteration.Here are the POSIX functions for comparison:
endgrent
,getgrent
,setgrent
– group database entry functionsIn my case, I am testing this on macOS (which already has specialized user handling), but furthermore, I tested it on my company laptop, which is macOS joined to a Microsoft ActiveDirectory Domain. My user account and its group aren't even mentioned in either
/etc/passwd
or/etc/group
, and yet, I can easily read them withEtc
. I am very sure that the Ruby developers did not implement ActiveDirector just to accommodate my personal weird use case, so it must use system functions.So, if you have e.g. a
uid
and want to know what groups it belongs to, you need to first get its name, and then search the groups. Unfortunately, it looks like the provided iterator wrappers do not support the common idiom that not supplying the block returns anEnumerator
, so you have to create one yourself.