4

I'm writing some testing code, and I'd like to know if it will be portable if it assumes that the user with UID 1 is named "daemon" on all Unix systems?

EDIT: If not (the answer seems to be no), are there any UID/username mappings that are consistent across Unices (other than 0/root, which I'm already using)?

joshlf
  • 365
  • No, there's nothing you can count on. You can't even really count on the id 0 account being named root - a local admin could change it, though I've never seen it done. Everything else is going to vary among the various distributions. I suggest elaborating on what you are trying to achieve - there might be some way OTHER than knowing what various UIDs are. – Michael Kohne Nov 23 '15 at 20:24
  • I'm OK with assuming that root is 0 - that's going to be almost universally true. If an admin changes that, they'll know why my tests are failing ;) – joshlf Nov 23 '15 at 20:46
  • @MichaelKohne - freebsd systems typically have a second root account (with uid=0, gid=0) called toor that has /bin/sh instead of /bin/csh as its shell. gecos name field is Bourne-again Superuser – cas Nov 23 '15 at 22:52

3 Answers3

4

No, that's not the case everywhere. On a CentOS 7 system, excerpted from /etc/passwd:

bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin

On Linux, you can use getent passwd daemon to find the UID of the daemon user, and getent passwd 1 to find which user has UID 1.

Tom Hunt
  • 10,056
Red5d
  • 66
  • I agree with this, although a single counter-example would be all it would take to turn this knee-jerk response into a complete answer. – type_outcast Nov 23 '15 at 19:59
  • 1
    In response to the suggestion: unfortunately this has to be statically hard-coded, so a dynamic lookup won't help. – joshlf Nov 23 '15 at 20:09
  • Depending on your circumstances, you might be able to generate a table at compile or install time for the specific system you're on. Other than that, I can't think of anything; there are no guarantees for which UIDs map to which names. – Tom Hunt Nov 23 '15 at 20:43
  • @joshlf why does it have to be hard-coded? that sounds like a serious design flaw in whatever it is you're writing. getent and similar tools (or function calls) exist, so it makes sense to use them when you need them. – cas Nov 23 '15 at 22:50
  • It's a test case that's doing string comparison. It's not that I couldn't write it differently - it's just that the testing framework I'm using makes it dead simple to do tests like this, so I'd rather avoid the extra logic if possible. – joshlf Nov 23 '15 at 23:23
1

No. For Linux, binand daemonhas swapped places - bin used to be #1 and daemon #2. On Minix, the #1/bin actually used to be semi-privileged by the operating system kernel (ie. a bit like #0/root). On Solaris, UID #1 is called daemon, while GID #1 is called others - and this is the default group for new users (with the exception of the user made during installation with the root-"role", he belongs to the staff-group).

UID #0 is of course root... GID #0 is usually either root or wheel.

I think the only required user and group is #0. It's however strongly recommended to have a binand daemon group too - to own //bin and //sbin. Then you often got a systo own various system-files and directories - especially /dev (in Linux devices are now usually owned by root and lots of different groups for different groups of devices... only /dev/random, /dev/null and /dev/zero are often still got sys as group. On other OS - like Solaris - lot of stuff is owned by sys:sys). Often you got adm as owner and group of various logs (originally located at /usr/adm) and sometimes run syslog. There was often a manuser/group that owned the man-pages.

operator user and/or group was for those permitted to work at The Console - ie. the terminal connected directly to the computer in the locked computer-room. It often ran back-ups, and thus often a member of the root-group to get access to (almost) everything. staff is a group used for "junior-admins", perhaps allowed control over /home and add local users.

Finally we got a series of user:group pairs for various common - and to some degree - required services... some are today uncommon: lp = printer, news = network-news (NNTP) bulletin board, mail = the (local) mail service, uucp = Unix to Unix CoPy... a way to pack together stuff like mail and newsgroup-posts, and "copy" it to a remote Unix-machine. Much used when when people used mostly dial-ups. tty = TeleTYpe... owns various terminals.

Many also had a gamesuser. Games requiring direct access to stuff like sound-cards and video-cards, where run SetUID as this user (games)... and the game-user was added to the groups of this hardware. This way the game got the access it needed to the hardware, without having to be run with full root-access (ie. SetUID=root). It also allowed for shared "Top Score" lists and such between all users on the system.

0

No, that's not necessarily portable. Any local installation is free to change any UID/name pair (although usually not advised).

For portability, you should always use the operating system's functions to convert to and from numeric/symbolic user and group identifiers (uid and gid).

If you care about the numeric user id (uid) 2, then use commands and system calls which take and return the numeric group ID. Use the getent command or similar to convert from numeric to symbolic, when necessary.

If you care about the user daemon then use the symbolic string daemon when doing user operations, or get the uid for the user named daemon (again, from getent for example) before passing the uid to a command or function.

Many commands such as ls and find contain options for working with both symbolic group names and numeric group identifiers. Other commands such as getent can be used to convert to/from

RobertL
  • 6,780
  • Unfortunately the context is that I'm writing tests for code which pretty-prints ACLs, which rely on doing uid -> username lookups, so it's the mapping itself that I care about. – joshlf Nov 23 '15 at 20:15
  • 1
    So for portability you would always want to lookup the uid from the ACL to get the symbolic name. Not a good idea to hardcode daemon. I just noticed my whole answer was about group. Everything applies I think if you substitute "user" for "group". – RobertL Nov 23 '15 at 20:35