COMP3000 Operating Systems F23: Tutorial 4: Difference between revisions
Created page with "In this tutorial, you will learn about how user accounts and logging in work through exploring [https://people.scs.carleton.ca/~lianyingzhao/comp3000/w23/tut4/3000userlogin.c 3000userlogin.c]. You’ll also have a better understanding of the permission system and the shell/terminal environment. ==General Instructions (same for all tutorials)== <div class="mw-collapsible mw-collapsed"> Click on Expand to view. <div class="mw-collapsible-content"> Tutorials are graded ba..." |
No edit summary |
||
(7 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
In this tutorial, you will learn about how user accounts and logging in work through exploring [https://people.scs.carleton.ca/~ | In this tutorial, you will learn about how user accounts and logging in work through exploring [https://people.scs.carleton.ca/~abdou/comp3000/f23/tut4/3000userlogin.c 3000userlogin.c]. You’ll also have a better understanding of the permission system and the shell/terminal environment. | ||
==Logging in to a Linux system== | ==Logging in to a Linux system== | ||
As mentioned in the lecture, in order to log in to a Linux-like system (including UNIX), the following steps must occur (potentially not in this order). | As mentioned in the lecture, in order to log in to a Linux-like system (including UNIX), the following steps must occur (potentially not in this order). | ||
# The user must use a terminal to connect to the system, locally or remotely (e.g., initiated by < | # The user must use a terminal to connect to the system, locally or remotely (e.g., initiated by <code>/usr/sbin/getty</code>) | ||
# The user must authenticate themselves, proving an identify with authorized access to the system. By default, this is done through a username and password (e.g., by exec’ing < | # The user must authenticate themselves, proving an identify with authorized access to the system. By default, this is done through a username and password (e.g., by exec’ing <code>/usr/bin/login</code>). | ||
# After authentication, login changes uid and gid to that of the new user. | # After authentication, login changes uid and gid to that of the new user. | ||
# Login sets up other aspects of the user's context (mainly setting key environment variables). | # Login sets up other aspects of the user's context (mainly setting key environment variables). | ||
# Login does an exec of the user's chosen/default shell. | # Login does an exec of the user's chosen/default shell. | ||
[https://people.scs.carleton.ca/~ | [https://people.scs.carleton.ca/~abdou/comp3000/f23/tut4/3000userlogin.c 3000userlogin] is a basic implementation of steps 3-5. (Steps 1 and 2 are accomplished by running 3000userlogin in a shell, as running an external command means the shell also creates a new process for it, assuming an authenticated session with a terminal.) | ||
When 3000userlogin is properly compiled and set up, you can run: | When 3000userlogin is properly compiled and set up, you can run: | ||
Line 34: | Line 17: | ||
and you'll be logged in (again) as "student". This only works when you’re already logged in as student (see below). | and you'll be logged in (again) as "student". This only works when you’re already logged in as student (see below). | ||
You can add a user with the < | You can add a user with the <code>adduser</code> command. For example, to create the user "someuser": | ||
sudo adduser someuser | sudo adduser someuser | ||
Note you'll have to answer several questions. Then you need to switch to someuser (< | Note you'll have to answer several questions. Then you need to switch to someuser (<code>su someuser</code>). | ||
If you just compile 3000userlogin normally, you won't be able to log in as anyone except the current user (be it student or someuser). To set up 3000userlogin properly, do the following: | If you just compile 3000userlogin normally, you won't be able to log in as anyone except the current user (be it student or someuser). To set up 3000userlogin properly, do the following: | ||
Line 45: | Line 28: | ||
sudo chmod u+s 3000userlogin | sudo chmod u+s 3000userlogin | ||
Feel free to read the < | Feel free to read the <code>man</code> pages for both commands to learn more. | ||
The < | The <code>chown</code> command makes the binary owned by root, and the <code>chmod</code> command makes it setuid. Thus, when the program is exec'd it will have an effective user ID of root (euid=0). To facilitate the following tasks, you may also want to create different versions of 3000userlogin by naming them, e.g., 3000userlogin.setuid and 3000userlogin.orig, of your choice. | ||
==Tasks/Questions== | ==Tasks/Questions== | ||
# Compile and setup [https://people.scs.carleton.ca/~ | # Compile and setup [https://people.scs.carleton.ca/~abdou/comp3000/f23/tut4/3000userlogin.c 3000userlogin] as described above. Create a new user account. Verify that you can use 3000userlogin to login as the new user without typing the password of the new user (without logging in beforehand). Think about <u>why</u> you are able to avoid typing the password and still get authenticated. | ||
# <u>Why</u> is the syntax highlighting gone (coloring characters)? What simple change (one line) can you make to have 3000userlogin preserve the colors? (Hint: check the environment variables) | # <u>Why</u> is the syntax highlighting gone (coloring characters)? What simple change (one line) can you make to have 3000userlogin preserve the colors? (Hint: check the environment variables) | ||
# What is returned as the user's password by < | # What is returned as the user's password by <code>getpwnam()</code> (in terms of type)? Is this what you expected? Read the manual page as you find necessary. | ||
# Compare the uid, gid, euid, egid when running 3000userlogin as a regular user (this means without the “chown” and “chmod” commands above), running it setuid root, and running it as root (i.e., running it from a root shell without the setuid bit set, e.g., “< | # Compare the uid, gid, euid, egid when running 3000userlogin as a regular user (this means without the “chown” and “chmod” commands above), running it setuid root, and running it as root (i.e., running it from a root shell without the setuid bit set, e.g., “<code>sudo ./3000userlogin someuser</code>”). Also check to see what happens when you set the setgid bit. | ||
# <u>Why</u> does 3000userlogin change its gid before changing its uid? <u>What happens</u> if you switch the order of these operations? | # <u>Why</u> does 3000userlogin change its gid before changing its uid? <u>What happens</u> if you switch the order of these operations? | ||
# Make 3000userlogin use the shell that is specified in the user's password entry (which is actually read from < | # Make 3000userlogin use the shell that is specified in the user's password entry (which is actually read from <code>/etc/passwd</code>). Check by setting someuser’s shell to a new shell and then see if that new shell runs when you run 3000userlogin. You can change a user's shell with the <code>chsh</code> command. | ||
# Can you set 3000shell to be a user's default shell? What changes do you have to make for < | # Can you set 3000shell to be a user's default shell? What changes do you have to make for <code>chsh</code> to accept 3000shell? Does anything obvious break when running 3000shell this way, and how can you change 3000userlogin to fix it? | ||
# Does a user's default shell have to be a regular shell? Could it instead be an arbitrary program? <u>How do you know</u>? | # Does a user's default shell have to be a regular shell? Could it instead be an arbitrary program? <u>How do you know</u>? | ||
# Are the environment variables set by 3000userlogin the only environment variables that are set (visible) after you successfully login? <u>How do you know</u>? | # Are the environment variables set by 3000userlogin the only environment variables that are set (visible) after you successfully login? <u>How do you know</u>? | ||
# Note that 3000userlogin uses < | # Note that 3000userlogin uses <code>environ</code> not <code>envp</code> (as an argument to <code>main()</code>) to access environment variables. <u>Why not</u> use <code>envp</code>? (Try changing the code to use <code>envp</code> and see what happens: worse or better?) | ||
==Optional/advanced tasks== | ==Optional/advanced tasks== | ||
# Prompt for the user's password before logging the user in (Step 2 above). To do this, you'll need to get the right password hash and then figure out how to hash the entered password to check if it matches. Recall the format of < | # Prompt for the user's password before logging the user in (Step 2 above). To do this, you'll need to get the right password hash and then figure out how to hash the entered password to check if it matches. Recall the format of <code>/etc/shadow</code> and you may need to learn how to use the <code>openssl passwd</code> command. | ||
Latest revision as of 01:14, 25 October 2023
In this tutorial, you will learn about how user accounts and logging in work through exploring 3000userlogin.c. You’ll also have a better understanding of the permission system and the shell/terminal environment.
Logging in to a Linux system
As mentioned in the lecture, in order to log in to a Linux-like system (including UNIX), the following steps must occur (potentially not in this order).
- The user must use a terminal to connect to the system, locally or remotely (e.g., initiated by
/usr/sbin/getty
) - The user must authenticate themselves, proving an identify with authorized access to the system. By default, this is done through a username and password (e.g., by exec’ing
/usr/bin/login
). - After authentication, login changes uid and gid to that of the new user.
- Login sets up other aspects of the user's context (mainly setting key environment variables).
- Login does an exec of the user's chosen/default shell.
3000userlogin is a basic implementation of steps 3-5. (Steps 1 and 2 are accomplished by running 3000userlogin in a shell, as running an external command means the shell also creates a new process for it, assuming an authenticated session with a terminal.)
When 3000userlogin is properly compiled and set up, you can run:
./3000userlogin student
and you'll be logged in (again) as "student". This only works when you’re already logged in as student (see below).
You can add a user with the adduser
command. For example, to create the user "someuser":
sudo adduser someuser
Note you'll have to answer several questions. Then you need to switch to someuser (su someuser
).
If you just compile 3000userlogin normally, you won't be able to log in as anyone except the current user (be it student or someuser). To set up 3000userlogin properly, do the following:
sudo chown root:root 3000userlogin sudo chmod u+s 3000userlogin
Feel free to read the man
pages for both commands to learn more.
The chown
command makes the binary owned by root, and the chmod
command makes it setuid. Thus, when the program is exec'd it will have an effective user ID of root (euid=0). To facilitate the following tasks, you may also want to create different versions of 3000userlogin by naming them, e.g., 3000userlogin.setuid and 3000userlogin.orig, of your choice.
Tasks/Questions
- Compile and setup 3000userlogin as described above. Create a new user account. Verify that you can use 3000userlogin to login as the new user without typing the password of the new user (without logging in beforehand). Think about why you are able to avoid typing the password and still get authenticated.
- Why is the syntax highlighting gone (coloring characters)? What simple change (one line) can you make to have 3000userlogin preserve the colors? (Hint: check the environment variables)
- What is returned as the user's password by
getpwnam()
(in terms of type)? Is this what you expected? Read the manual page as you find necessary. - Compare the uid, gid, euid, egid when running 3000userlogin as a regular user (this means without the “chown” and “chmod” commands above), running it setuid root, and running it as root (i.e., running it from a root shell without the setuid bit set, e.g., “
sudo ./3000userlogin someuser
”). Also check to see what happens when you set the setgid bit. - Why does 3000userlogin change its gid before changing its uid? What happens if you switch the order of these operations?
- Make 3000userlogin use the shell that is specified in the user's password entry (which is actually read from
/etc/passwd
). Check by setting someuser’s shell to a new shell and then see if that new shell runs when you run 3000userlogin. You can change a user's shell with thechsh
command. - Can you set 3000shell to be a user's default shell? What changes do you have to make for
chsh
to accept 3000shell? Does anything obvious break when running 3000shell this way, and how can you change 3000userlogin to fix it? - Does a user's default shell have to be a regular shell? Could it instead be an arbitrary program? How do you know?
- Are the environment variables set by 3000userlogin the only environment variables that are set (visible) after you successfully login? How do you know?
- Note that 3000userlogin uses
environ
notenvp
(as an argument tomain()
) to access environment variables. Why not useenvp
? (Try changing the code to useenvp
and see what happens: worse or better?)
Optional/advanced tasks
- Prompt for the user's password before logging the user in (Step 2 above). To do this, you'll need to get the right password hash and then figure out how to hash the entered password to check if it matches. Recall the format of
/etc/shadow
and you may need to learn how to use theopenssl passwd
command.