0

I want to run process as a different user in Linux with its personal rights. In server program I ask user to enter login and password to get an access to the system. Next I have to run client program as another user to separate workspaces and provide the authentication. Then client program is supposed to send and receive messages from server via Linux IPC sockets. I have found some ways to run a program as another user:

int pid = fork();
if(pid == 0) // child
{
    int ret = system("sudo -u username ./client.out");
}
else if(pid > 0) // server
{
    // communicate with client via socket
}
else {
    exit(EXIT_FAILURE);
}

But it does not use password. My question is how to run a program as another user and pass a password? Also using system command is not a good solution. sudo is a command line program, but I have to call it from C. How to run another program properly in C?

SokolovVadim
  • 34
  • 1
  • 10
  • 2
    Does this answer your question? [setuid equivalent for non-root users](https://stackoverflow.com/questions/13040644/setuid-equivalent-for-non-root-users) – user14063792468 Oct 26 '20 at 17:40
  • You should use SO search option more often. Use `man setuid` and search SO carefully. There are **lots** of similar questions with **lots** of answers. – user14063792468 Oct 26 '20 at 17:43

1 Answers1

0

I don't have privileges to comment, so I'll write this as an answer. One way to do it would be to prompt for a password and validate it yourself, then fork and set the new user for that process. You can check Given a linux username and a password how can I test if it is a valid account? to see how to validate a password, basically it's generating a hash for the password you have, reading the hash for the user inside /etc/shadow, and comparing both of them. For switching the user, you need to call setuid and setgid(which sets the groupid). Check this answer: Linux C programming execute as user

You can get the uid and gid for a user from /etc/password. A sample entry in that file would be:

irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin

The third field is the userid, the fourth field is the groupid, in this case 39 and 39. After calling setuid, your process will be running under the new user's identity. Then you can start whatever process you want. For this to work, your program must have the setuid bit on.

Edit:

You don't need to set the setuid bit in the executable if you run it as root.

Since you're using fork() already, you may want to call any variant of exec() instead of system(), as system() will create an additional process. See Difference between "system" and "exec" in Linux?

You can use getpwdnam() to read /etc/passwd as it will parse the fields for you. See How to get linux user id by user name?

Martin Ferrari
  • 186
  • 1
  • 7
  • Thank you for your answer! It is the most complete information I have seen on this topic. Should I use my program running with root rights to read etc/shadow? – SokolovVadim Oct 27 '20 at 06:54
  • you're welcome! Yes, you will need root rights to read /etc/shadow. I've edited the answer and added a little more info at the bottom. – Martin Ferrari Oct 27 '20 at 16:39
  • You want to use PAM, not parse /etc/shadow manually – Grzegorz Nosek Oct 30 '20 at 09:15
  • @GrzegorzNosek I need to check password from source code of my program. How can I manage to use PAM in the way you suggest? – SokolovVadim Oct 31 '20 at 19:51
  • The Linux-PAM Application Developers' Guide (http://www.linux-pam.org/Linux-PAM-html/Linux-PAM_ADG.html) should be a good start, including an example application: http://www.linux-pam.org/Linux-PAM-html/adg-example.html – Grzegorz Nosek Nov 01 '20 at 13:27