Help answer threads with 0 replies.
Go Back > Linux Answers > Applications / GUI / Multimedia
User Name


By krishvij at 2005-05-04 01:30
There has always been a void in every newbies mind when it comes to sticky bits. The books say that the SUID allows an unprivileged user to run executables and scripts with the credentials of the owner of the file. But we all try to implement it and fail as newbies. This HOWTO is dedicated to newbies of sticky bit so that they don't have to waste time in implementing it. The answer is right here.

I am taking an example of a huge organization with 1 Sysadmin who has under him/her a few Assistant Admins. In such cases, the sysadmin cannot be creating users all the time. So, the Assistant Admins do the user creation. But, to create users, the root password needs to be given to them, which is a big headache for the main Sysadmin. So, what does the sysadmin do? He/She will need to do the following :-

1. Login as root.
2. Create a shell script that will create the users specified and set a default password for each of these users
3. Copy this script to the home directory of these assistant admins.
4. Set SUID Sticky bit to the script copied in each of the assistant admins' directories
5. Copy the sysadmin commands that will be used by your script to /bin (because most of the sysadmin commands are in the /usr/sbin directory and unprivileged users' PATH does not point to /usr/sbin)
6. Set SUID to each and every command that you copy into the bin as well (my script uses the useradd, chown and chpasswd commands)

My example shell script that creates users and sets default password for each user is as follows :-
echo -n "enter the starting login id : "
read beg
echo -n "enter the ending login id : "
read final
fend=`date +"%d%m%y"`
rm -f "users$fend"
touch "users$fend"
while [ $i -le $final ];
if [ $i -lt 10 ]; then
useradd "j2ee00$i"
chown -R "j2ee00$i:j2ee00$i" "/home/j2ee00$i"
echo "j2ee00$i:elmaqedu" >> "users$fend"
if [ $i -ge 10 ] && [ $i -lt 100 ]; then
useradd "j2ee0$i"
chown -R "j2ee0$i:j2ee0$i" "/home/j2ee0$i"
echo "j2ee0$i:elmaqedu" >> "users$fend"
if [ $i -ge 100 ] && [ $i -lt 1000 ]; then
useradd "j2ee$i"
chown -R "j2ee$i:j2ee$i" "/home/j2ee$i"
echo "j2ee$i:elmaqedu" >> "users$fend"
i=$[ $i + 1 ]
chpasswd < "users$fend"

Save this script as

copy this script to the directories of each assistant admin. once you have copied the script, set SUID to this file using the following command :-

chmod 4755
chmod u+s

copy the useradd and chpasswd scripts to /bin and then, issue the following commands to set the SUID to these files :-

chmod 4755 /bin/useradd
chmod 4755 /bin/chpasswd
chmod 4755 /bin/chown

THAT'S IT. IT'S ALL DONE. Now, login as any of the assistant admins and execute the script. The unprivileged users will be added to the /etc/passwd file

When an unprivileged user logs into Linux, his uid and gid are embedded into his shell. From this point on, any command or script that you run forks a child shell process. Remember, every process runs with the uid and gid of the currently logged on user and hence, unprivileged users cannot write to files like /etc/passwd. Hence, SUID is actually a way in which the sysadmin can create scripts to be run by unprivileged users but still need some root like access to some system files.

once the SUID sticky bit is set on an executable created by root, the following happens :-

1. unprivileged user with uid 501 and gid 501 logs on.
2. executes a script which has SUID set.
3. Script creates a child shell process and sets it's uid and gid to 0 (the root)
4. Performs all that it needs to do and then exits

If the same unprivileged user tries to run a script without SUID set, the process will run with uid 501 and gid 501 and hence, will not have permissions to perform desired actions on system centric files, even though the sysadmin would want it to.

Hope this HOWTO helps people out there. In case you have any suggestions or feedback, please mail me at

by Artanicus on Wed, 2005-06-15 03:42
Um, please do correct me if im wrong, as this is confusing me severely..
We fisr make the script, and suid it, yes, that I can understand. The thing is, why do the commands used have to be suid too?
exec suid script > child process with uid 0 > exec the commands as uid 0
So why are the tools suid too? A thought comes to mind, that now that the tools are suid, any user can use adduser and so on with the suid binaries?
What am I getting wrong here? (:

by krishvij on Thu, 2005-06-16 03:23
Hi Artanicus,

Thanks for your comment. Would like to clarify a few things here. What I have used is just an example to understand the concept of SUID. It is not to be taken as is and applied onto the production systems. Basic idea is to make people understand the concept of SUID.

One part of what you have said is right. If you apply whatever I have said in my example as is, then yes, anyone and everyone can use the suid'd useradd, chpasswd etc without being root. This is actually a security loophole. so, probably u can just copy these binaries into the home directories of each user who needs to use it and make them as SUID instead of making the /usr/bin binaries as SUID. Further, the same things can also be done by using sudo in a more secure way.

With regard to your query of a process execing another one, the same UID's do not pass on.That means, if is suid'd as root, then it will run as UID 0. But, if it calls useradd and if useradd is not suid'd, then useradd will take the UID of the user and so, it will not be able to write to the /etc/passwd file. Just try out the same example by setting SUID for just the and then execute. You will find that the users will not be added. Of course, login as an unpreviliged user and try it out :-)

by Artanicus on Thu, 2005-06-16 03:40
Thanks this clarified alot.. (:

Only one question remains, why suid the script in the first place if the only real root tools we are using are suid too? Can't the script run suid binaries if it isn't suid itself?

Sorry for the troublesome questions, but your great article confused me a tad, but on some level I now understand how suid works, thanks for that.. (:

by krishvij on Thu, 2005-06-16 06:41
Hi Artanicus,

There is no need for the to be suid'd. Guess I got a little bit carried away while writing this article :-). It is not necessary for in my example to be suid'd. It will still work. Good to note that the info helped you. That gives me a lot of satisfaction and also, makes me believe that the effort I spent on writing that article was worth it.

by oriate on Fri, 2005-06-17 07:13
As you said,such a program cannot get a root shell:
#include <unistd.h>

int main()
char *name[2];
name[0] = "/bin/sh";
name[1] = 0;


I tried, yes, I cannot get root shell, but how do buffer flow get root shell using suid ?

by krishvij on Sat, 2005-06-18 00:33
every process is just a running instance of a program. it needs to have a UID/GID (just like an ID card) while running so that the OS can decide what the process can access and what it can't.

in unix/linux, when a user executes a program, the OS checks if it has a SUID/SGID set on it. If it is set, then it looks at the owner/group owner of the program, gets the corresponding UID/GID and then, runs the process with these UID/GID. Otherwise, it starts the process by exporting the logged in user's UID/GID.

by oriate on Sat, 2005-06-18 06:43
Can you explain how "buffer flow" get the root shell?

by donald.j.wood on Tue, 2005-06-21 14:36
There is a big problem with this example beyond the fact that SUID is not required. SUID/SGID is considered insecure, and as such the Linux kernel ignores the bit when running shell scripts.

by oriate on Tue, 2005-06-21 22:49
Originally posted by donald.j.wood
There is a big problem with this example beyond the fact that SUID is not required. SUID/SGID is considered insecure, and as such the Linux kernel ignores the bit when running shell scripts.
I am sorry, I cannot much understad you.
"shell scripts" do you mean "shell code" ?
But how does the kernel know whether a piece of code is shell code?

by Michael Slade on Sat, 2009-02-28 08:38
This post demonstrates a clear misunderstanding of setuid and it security implications. If followed, the directions given will allow any user with local access to the machine, to change the password of any other user, including root. Thus it essentially disables all security.

When most programs have their setuid bit set, they will execute as the owner of the program file rather than the executing user. The exceptions are scripts - basically any programs whose first line starts with "#!".

I won't explain further than this, but please see if you want to know more.



All times are GMT -5. The time now is 12:38 PM.

Main Menu
Write for LQ is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration