views:

47

answers:

1

Hi, Does anyone know the api for adding users and groups in unix and removing them ? I want to do this programatically.

Thanks, Frank

A: 

I started looking at some system calls and found the following. Note that they are of varying standards, so not all may work on your Unix version:

  • getpwent
  • setpwent
  • putpwent

These however, all assume a password file. Out of curiosity, I straced useradd to find out what he did. Here's a small section of it's output:

# grep -E 'passwd|shadow' useradd.log.20283
...
open("/etc/shadow", O_RDONLY|O_CLOEXEC) = 3
open("/etc/passwd", O_RDONLY|O_CLOEXEC) = 3
open("/etc/passwd.20283", O_WRONLY|O_CREAT|O_EXCL, 0600) = 4
link("/etc/passwd.20283", "/etc/passwd.lock") = 0
stat("/etc/passwd.20283", {st_mode=S_IFREG|0600, st_size=6, ...}) = 0
unlink("/etc/passwd.20283")             = 0
open("/etc/passwd", O_RDWR)             = 4
open("/etc/shadow.20283", O_WRONLY|O_CREAT|O_EXCL, 0600) = 5
link("/etc/shadow.20283", "/etc/shadow.lock") = 0
stat("/etc/shadow.20283", {st_mode=S_IFREG|0600, st_size=6, ...}) = 0
unlink("/etc/shadow.20283")             = 0
open("/etc/shadow", O_RDWR)             = 5
open("/etc/gshadow.20283", O_WRONLY|O_CREAT|O_EXCL, 0600) = 7
link("/etc/gshadow.20283", "/etc/gshadow.lock") = 0
stat("/etc/gshadow.20283", {st_mode=S_IFREG|0600, st_size=6, ...}) = 0
unlink("/etc/gshadow.20283")            = 0
open("/etc/gshadow", O_RDWR)            = 7
open("/etc/passwd", O_RDONLY|O_CLOEXEC) = 8
open("/etc/passwd", O_RDONLY|O_CLOEXEC) = 9
open("/etc/passwd-", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 9
utime("/etc/passwd-", [2010/09/02-07:07:34, 2010/09/02-07:07:34]) = 0
open("/etc/passwd+", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 4
lstat("/etc/passwd", {st_mode=S_IFREG|0644, st_size=2479, ...}) = 0
rename("/etc/passwd+", "/etc/passwd")   = 0
open("/etc/shadow-", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 4
utime("/etc/shadow-", [2010/09/02-07:07:34, 2010/09/02-07:07:34]) = 0
open("/etc/shadow+", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 4
lstat("/etc/shadow", {st_mode=S_IFREG|0600, st_size=1429, ...}) = 0
r    ename("/etc/shadow+", "/etc/shadow")   = 0
open("/etc/gshadow-", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 4
utime("/etc/gshadow-", [2010/09/02-07:07:34, 2010/09/02-07:07:34]) = 0
open("/etc/gshadow+", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 4
lstat("/etc/gshadow", {st_mode=S_IFREG|0400, st_size=1069, ...}) = 0
rename("/etc/gshadow+", "/etc/gshadow") = 0
unlink("/etc/shadow.lock")              = 0
unlink("/etc/passwd.lock")              = 0
unlink("/etc/gshadow.lock")             = 0

Although you get a better idea what's going on with the full context, note that it links a temporary file it created (/etc/passwd.20283) to /etc/passwd.lock. useradd does similarly with the shadow, and gshadow files as well.

It's also important to note that useradd made four calls out to nscd. Two of these were for passwd, and two were for group:

execve("/usr/sbin/nscd", ["/usr/sbin/nscd", "nscd", "-i", "passwd"], [/* 0 vars */]) = 0

If there isn't an API (and I can't seem to find one), it may be because there's many more ways to store users than simple passwd files. Indeed, it's possible that the machine has no control at all over the users.

EDIT: I suppose it's also important to note that useradd consulted /etc/nsswitch.conf as well, likely to verify the origin of the user database. Furthermore, userdel behaved almost identically, creating similarly named temporary and lock files.

I tested under Linux using the following command:

strace -o useradd.log -f -ff -s 1024 useradd tempuser

strace may also appear as truss and ktrace on other unix systems.

Kaleb Pederson
It seems complex to implement all these details and lock handling programmatically, so I would stick to using useradd and alike. For task automation I would suggest shell script.
Ricardo