2

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

Thanks, Frank

3
  • Looks like there is no API. How come it never occured to the developers about providing such an API. The only solution seems to be using a system call. Commented Sep 10, 2010 at 1:53
  • Why do you need this? Two guesses: package installation, in which case you should probably be doing this from some sort of script, or a remote user information directory, in which case it is probably better to use PAM and/or NSS to redirect the system's requests for user/group information to the directory. Commented Sep 10, 2010 at 20:51
  • I wanted this to automate some tasks. my program reads a file and creates users and groups. Anyways, I m using system calls now to acheive this. Commented Sep 17, 2010 at 19:48

2 Answers 2

1

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.

Sign up to request clarification or add additional context in comments.

1 Comment

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.
1

I found this question while looking for a way to list all groups on a Unix. But to create and delete users you can programatically call the utility programs useradd, userdel, groupadd, groupdel since you would know the user name been sent. But I guess you will need superuser rights to invoke them. Anyway you can check the process exit code for command status.

 useradd xxx // status zero operation completed
 useradd xxx // status nine user already exists

Hope it helps.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.