Changin uid/gid of a running non-provileged process - c

I need to implement an small capability system for Linux similar to Plan 9 cap device. Host owner (root in Linux) allows user1 to impersonate user2 writing user1#user2#random-string to /dev/caphash. Any user1 process that knows random-string can change its uid to user2 writing user1#user2#random-string to /dev/capuse.
On Linux, any privileged process can impersonate any unprivileged user with setuid(2) system call, but I do not know any mechanism to allow horizontal impersonation. How do Linux do it?

Serge E. Hallyn submitted p9auth to the Linux-kernel mailing list in April 2010, which would have provided pretty much this functionality (albeit in the last submitted form, with a slightly different interface). Unfortunately, it was not included in the Linux kernel.
The underlying security paradigm in Linux is vertical, rather than horizontal.
Privileges are separated into capabilities, and they can be acquired at exec time only. Extra privileges can be dropped at any time. In practice, you use filesystem capabilities and the setcap utility to give an unprivileged binary some specific capabilities whenever it is executed, regardless of the identity of the user executing it. (With Linux kernels 2.6.33 and later, it is no longer possible for any process to modify the capabilities of another running process.)
The key point to notice is that in Linux, only a privileged process (a process with the CAP_SETUID) can change its identity at run time.
In other words, point of exec is used in Linux for elevation of privileges, with the now-privileged binary changing to the specified user (and/or group and perhaps supplementary groups), dropping extra privileges. I am not aware of any mechanism that would allow an unprivileged process to change its credentials without an exec.
For the OP, this means that the Plan 9 interface (/dev/caphash, /dev/capuse) will not work. A comparable Linux interface implemented in userspace will require the exec of a binary as part of the change in credentials, but other than that, I don't know enough of OP's use cases to make any suggestion.
In-kernel, such an interface is obviously possible (as shown by the first link in this answer), just not available in the vanilla kernels.

In linux (and in unix in general) there's a similar feature that has to do with one of the bit permissions of an executable file. If you have an executable binary file, marked as setuid bit, then when you execute that file, the kernel runs that executable by setting the effective user id of the process to the owner of that file. So the mechanism works if you have execute permissions to execute that file. Let's suppose you want users a, b and c to impersonate user d on execution of some program. You first create a group of users (group setuid_d) in the system and put on it all the users a, b and c. then you create the executable, make it belong to user d, and group setuid_d. Once this has been done, as user d or as root make the file executable only by the group setuid_d and activate the set uid bit in the permissions
$ chgrp setuid_d program
$ chown d program
$ chmod ug+x,o-x,u+s program
$ program # you'll be effectively user d when executing program

Related

Given a path to an executable, how can I determine when the program is launched without root privilege, and without polling /proc/

I'm trying to create a program that determines when a program would run on a Linux system given the path to it's executable without needing root privileges, or scanning /proc/. The reason I don't want to use root privilege is because my program should only look for processes launched by the user that ran it, so I don't see why it should require escalated privilege.
I'm currently periodically scanning /proc/ as I've failed to find any other solution that satisfies my requirements, but it's a very slow way to go about things. The only other solutions that I've come up with are to use the proc connector which I really don't want to do since that requires root, or to use X11's CreateNotify which I also don't want to do since I want this program to run on Wayland as well.

How do I drop supplementary groups in Linux?

I have an executable that's ug+s to a non-root user and group. I would like it to leave all the supplementary groups it originally had behind. Is there a way to make this happen? It doesn't look like the setgroups call allows you to do this if you're not root. And when I try it, I get EPERM.
It seems like there ought to be a way to lose privileges you previously possessed.
The short answer is "A process without CAP_SETGID can't.". And it is by design that setgroups can't be used to remove groups when the process has no privileges. The previous link is to an excellent LWN article detailing why not.
In my particular case, since I'm immediately creating a user namespace, those supplementary groups get mapped to 'nobody' anyway. And so it isn't very important. If it is important, you can use setcap(8) to set capabilities on a wrapper executable that checks that it's being run by the expected user with the expected group permissions and then drops the groups and drops CAP_SETGID and runs the executable you really want to run. The command you would use to do this is:
sudo setcap cap_setgid+ep wrapper_exe
Be careful though, it's now possible that someone who has a shell on your system can use that executable to run some sort of privilege escalation attack if you did not write it very carefully.

How can I switch user during execution using C on Linux

I'm writing an application using C on Linux. In my application, I need to do some tasks at the beginning with normal user (Non root user) while I need to do some tasks with root user in the middle of execution as well.
By the way, I cannot modify configurations of normal user. So I cannot add normal user to sudoers. I cannot modify any OS configurations as well.
What my application really do is execute applications, get their outputs for analysing.
Some applications need to be run with root. I use multi-threads to execute and analyse outputs of these applications in parallel then stores report of each application in a singleton called Report. I call these applications using execvp in sub-process.
The main purpose of my application is to automate software testing. And most task is required to run in software owner which shall not be root.
So, the problem is
how can I switch user during execution?
Is there anyway that I can implement this within 1 executable?
Do this with POSIX APIs is better.
Run my application with normal user, provide root password to my application, switch to root using root password.
Read more about setuid executables and setreuid(2) and execve(2) syscalls. Be careful, you'll need to put the setuid flag on the executable with chmod u+s (see chmod(1)) after changing its ownership (with chown(1)) and code carefully to avoid security holes.
(so I recommend to have your code reviewed by someone knowing the setuid mechanism and aware of security issues)
Setuid is the basic mechanism (used by su, sudo, super, login etc...) programs to get (or revoke) privileges. See credentials(7) & capabilities(7).
It could be safer to start some helper process (as root, or start some setuid executable perhaps in /usr/libexec/ ...) and communicate with it using some inter-process communication facilities (like pipe(7)...). For example, it is not recommended to use GUI toolkits like GTK or Qt in root processes. If your app has some GUI, it is reasonable to run its GUI in a non-root (ordinary user) process and run as root the (hopefully small) helper process doing the real job requiring special privileges.
Before coding, I recommend reading a good book like Advanced Linux Programming and syscalls(2) and the documentation of every system call you would use. Security aspects are especially important.
Setuid executables don't necessarily require or use any password; it is the other way round: programs requiring passwords (notably login, su, sudo etc....) are setuid (and they are free software on Linux so you can study their source code); try ls -l /bin/su /usr/bin/sudo /bin/login to check that.
Since you want to emulate various user environments, be aware of environ(7).

Can we change permissions from user to root?

I have a written a C program that creates a file "abcd.txt" and write some data into it. I was executing my code by logging with a username"bobby" and so the file abcd.txt was created with owner as bobby.
But my task is, even though I execute my code with some username "bobby", the file should always be created with owner as root. Can someone help me by saying how this could possible?
As a general principle you need your effective uid (euid to be root) either when you are are writing the file or when you perform a chown(2) on the file.
If you are doing this under Linux then there are linux specific methods that you can use.
Generic Solution
Without availability of sudo
This is the old UNIX DAC approach, it's fraught with peril. It assumes that you do not have something like sudo installed or cannot install it.
Your executable should be owned by root and have the executables setuid bit set.
Process
You should use seteuid () to drop your privileges from root to bobby for most of the operation, including writing. When you are done, bring your privilege level back up to root using seteuid(0) and perform a chown() (or fchown on the fd) on the file to change its ownership to root.
some basic safety
For safety set it up so that your executable is owned by root:safegrp where 'safegrp' is name of a group unique to users who are allowed to execute this file (add bobby to safegrp) ; and ensure that the setuid executable's mode is 4510 ;
With availability of sudo
If sudo is available on your system then follow the same process as above for dealing with privileges within the executable but DO NOT set the file mode to setuid, have safegrp added to sudoers for this executable and now bobby can run it with sudo /your/bin/prog
Linux specific solution
POSIX.1e
It is possible to have tighter control over the file use POSIX.1e capabilities support. In your case you wish to grant SYS_CHOWN to your program;
For security reasons, I would probably set that up as a COMPLETELY separate binary or a sub process and still use sudo and perform appropriate dropping of privileges.
linuxacl[ACL Using Access Control Lists on Linux] has excellent tutorial on this topic
SE-Linux
You can use Mandatory Access Control to limit the access to such a dangerous binary but SE linux is a pain to configure :^) although a possibly a good approach
You probably don't want to run your program as root, unless you really have to. Perhaps run "chown" from a shell script after running your program? Or, you can use chown(2) from a program running as root (or with equivalent capabilities, on linux).
Use the chown() method. There are probably more authoritative links, but this one is nice since it includes the calls to getpwnam(). I've done all of this in the past, but unfortunately I don't still have the code (it's owned by IBM).
http://manpages.courier-mta.org/htmlman2/chown.2.html

C Privilege Escalation (With Password)

I need to write a C program that will allow me to read/write files that are owned by root. However, I can only run the code under another user. I have the root password, but there are no "sudo" or "su" commands on the system, so I have no way of accessing the root account (there are practically no shell commands whatsoever, actually). I don't know a whole lot about UNIX permissions, so I don't know whether or not it is actually possible to do this without exploiting the system in some way or running a program owned by root itself (with +s or whatever). Any advice?
Thanks!
P.S. No, this isn't anything malicious, this is on an iPhone.
Under the UNIX permissions system, you need to run a file owned by root itself that's marked setuid-root (+s, as you said) or communicate with some process that is already running as root.
If there is no such file, you are out of luck.
You can do this with setting suid bit to application, but if you want from this c application run a some shell this was be runned on local user if you do it normally this is security system.
However you can read/write/execute files owned by root, but if your user is not in group of file your target file must have setted read/write/execute on last 3 bits or when your user is in file owner group you must check/apply this to 3 bits in middle position. (3 first bits setting permission to owner but this may not by a usable information for you).
If you dont have any access to root account. Then if group and other user permissions dont access functions as you must have, you can't do with this anything except trying get some prilveaged user for access this file. In other cases you can do some fixes in file access permissions but not from this system, you must get hard drive from this device and attach to other to change it or load on this device some live system to change this. However you can do this on privleaged system not on this.
More information about SUID bits you can find at:
http://www.codecoffee.com/tipsforlinux/articles/028.html
http://www.everyjoe.com/newlinuxuser/explain-what-is-setuid-and-setgid/
The iPhone SDK doesn't allow this. Your application is sandboxed and it is not allowed to go outside of that sandbox except in very specific ways provided by Apple. The only way to do this on an iPhone is to jailbreak it.

Resources