Identity Page 1 Thesis, antithesis, synthesis Thursday, December 01, 2011 4:00 PM Thesis, antithesis, synthesis We began the course by considering the system programmer's point of view. Mid-course, we switched to studying how to write the operating system itself. Finally, we take a look at programming again, knowing what's "under the hood." And things look very different now... Before: how to do things? After: what can we get away with?
Identity Page 2 Beyond the kernel Wednesday, November 30, 2011 4:35 PM So far, we've concentrated on the kernel, where: drivers live. processes are executed. scheduling is accomplished. everything is a number. Now, we shift gears yet another time: Assume that the filesystem works. Utilize the filesystem to do useful things. Consider parts of the operating system outside the kernel.
Identity Page 3 Revisiting systems programming Thursday, December 01, 2011 4:03 PM What we've learned about systems programming: Creating and reaping processes. Inter-process communications. Threads and mutexes. Revisiting systems programming: Manipulating filesystems. Understanding and manipulating privilege. Daemons as operating system extensions. Basics of security.
Identity Page 4 Manipulating the filesystem Thursday, December 01, 2011 7:36 AM Manipulating the filesystem stat - read an inode. opendir, readdir, closedir - manipulate directories.
stat Thursday, December 01, 2011 7:36 AM stat Purpose of stat: read most of an inode struct stat { dev_t st_dev; /* ID of device containing file */ ino_t st_ino; /* inode number */ mode_t st_mode; /* protection */ nlink_t st_nlink; /* number of hard links */ uid_t st_uid; /* user ID of owner */ gid_t st_gid; /* group ID of owner */ dev_t st_rdev; /* device ID (if special file) */ off_t st_size; /* total size, in bytes */ blksize_t st_blksize; /* blocksize for filesystem I/O */ blkcnt_t st_blocks; /* number of blocks allocated */ time_t st_atime; /* time of last access */ time_t st_mtime; /* time of last modification */ time_t st_ctime; /* time of last status change */ }; int stat(const char *path, struct stat *buf); int fstat(int filedes, struct stat *buf); int lstat(const char *path, struct stat *buf); Three different forms: stat: reads inode information from a path. fstat: reads from open file descriptor. lstat: reads the stat for a symlink, rather than following the link. Identity Page 5
opendir, readdir, closedir Thursday, December 01, 2011 7:43 AM opendir, readdir, closedir A directory is a special kind of file. So it needs a special reader. #include <sys/types.h> #include <dirent.h> struct dirent { ino_t d_ino; /* inode number */ off_t d_off; /* offset to the next dirent */ unsigned short d_reclen; /* length of this record */ unsigned char d_type; /* type of file */ char d_name[256]; /* filename */ }; // DIR *opendir(const char *name); // struct dirent *readdir(dir *dir); // int closedir(dir *dir); Identity Page 6
Identity Page 7 Example: how to write 'ls' Thursday, December 01, 2011 7:50 AM #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <dirent.h> main() { DIR *d = opendir("."); if (d) { struct dirent *e; while ((e=readdir(d))!= NULL) { struct stat s; if (stat(e->d_name, &s)==0) { printf("%s mode=0%o uid=%d gid=%d\n", e->d_name, s.st_mode, s.st_uid, s.st_gid); } else { perror("ls"); } } } else { // protection failure } perror("ls"); } closedir(d); Pasted from <http://www.cs.tufts.edu/comp/111/examples/identity/ls.c>
Identity Page 8 Oops! Thursday, December 01, 2011 8:06 AM Oops! We don't have most of what normal 'ls' provides us Name of owner, group Pretty-printed mode Why? These are not in the inode! Info is contained elsewhere!
Identity Page 9 Users and Groups Thursday, December 01, 2011 8:07 AM Users and Groups Users and Groups are represented as numbers. The names are for humans only. Somewhere, we must maintain a mapping between numbers and names.
Identity Page 10 The "configuration" Wednesday, November 30, 2011 4:38 PM The "configuration": The filesystem contains everything the operating system needs to run. That part of the filesystem that determines OS function is called the configuration of the operating system. A configuration is a set of files. Configuration management is the process of controlling the configuration to create desired behaviors in the OS. The configuration mostly resides in /etc.
Identity Page 11 The concept of identity Wednesday, November 30, 2011 4:40 PM Our first configuration concept: identity Who can login? What can someone who logs in actually do?
Identity Page 12 UIDs Wednesday, November 30, 2011 4:54 PM Givin' you a number: Users in linux are known by numbers. Names are only for humans. The User ID (UID) of a user is an integer Between 0-65535 0=root <1024: users necessary for operating system operation >=1024: human users.
Identity Page 13 User attributes Wednesday, November 30, 2011 4:59 PM User attributes: name password (hashed) user id (UID) primary group id (GID) list of groups for which the user is a member. quotas for filesystems This is not in one file: login name: /etc/passwd password (hashed) /etc/shadow user id (UID) /etc/passwd primary group id (GID) /etc/passwd list of groups for which the user is a member. /etc/group quotas for filesystems stored are separately.
Identity Page 14 The concept of a group Wednesday, November 30, 2011 5:03 PM A group is a set of users that share access to things Again by number: group identifier (GID). Defined in /etc/group, which contains group name GID list of login names that are members.
Identity Page 15 Federated identity Wednesday, November 30, 2011 5:05 PM Federated identity Alas, /etc/passwd, group, shadow aren't that interesting on our linux stations. Reason: our identity management is federated: we use a network service to define user identity. Most common federation: Lightweight Directory Access Protocol (LDAP) Second most common: Windows Active Directory We run both: LDAP for Linux, AD for Windows. See /etc/nsswitch.conf for details.
Identity Page 16 Daemons Wednesday, December 2, 2015 3:36 PM LDAP is actually serviced via a network daemon. daemon: a program that runs all the time. Answers requests. Using network programming (see COMP112)
Exploring LDAP Thursday, November 29, 2012 11:27 AM Exploring LDAP ldapsearch -x uid=couch # user couch ldapsearch -x cn=grade111 # group grade111 Identity Page 17
Identity Page 18 Basic principle of configuration Thursday, December 01, 2011 8:08 AM Basic principle of configuration Never read a configuration file directly. Instead, utilize library functions (man 3) to access it. These functions Read the files. Cache information for repeated use. Eliminate excess reads. Understand federation semantics.
Identity Page 19 Reading users Thursday, December 01, 2011 8:10 AM Reading users: getpwuid, getpwnam struct passwd { char *pw_name; /* user name */ char *pw_passwd; /* user password */ uid_t pw_uid; /* user ID */ gid_t pw_gid; /* group ID */ char *pw_gecos; /* real name */ char *pw_dir; /* home directory */ char *pw_shell; /* shell program */ }; #include <sys/types.h> #include <pwd.h> struct passwd *getpwnam(const char *name); struct passwd *getpwuid(uid_t uid);
Identity Page 20 Reading groups Thursday, December 01, 2011 8:17 AM Reading groups: getgrnam, getgrgid struct group { char *gr_name; /* group name */ char *gr_passwd; /* group password */ gid_t gr_gid; /* group ID */ char **gr_mem; /* group members */ }; #include <sys/types.h> #include <grp.h> struct group *getgrnam(const char *name); struct group *getgrgid(gid_t gid);
Identity Page 21 What getgr*, getpw* do Thursday, December 01, 2011 8:20 AM What getgr*, getpw* do: Read /etc/nsswitch.conf to determine data sources. Cache it in memory. Read data sources, cache them. Return a result that is a pointer into a data source. Caveats: Returned pointer is not persistent: content can change at next call of getgr*, getpw*.
Identity Page 22 Example: a better 'ls' Thursday, December 01, 2011 8:20 AM #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <dirent.h> #include <pwd.h> #include <grp.h> #include <string.h> main() { DIR *d = opendir("."); if (d) { struct dirent *e; while ((e=readdir(d))!= NULL) { struct stat s; if (stat(e->d_name, &s)==0) { char username[256]; struct passwd *p = getpwuid(s.st_uid); if (p) { strcpy(username, p->pw_name); // name } else { sprintf(username, "%d", s.st_uid); // number } char groupname[256]; struct group *g = getgrgid(s.st_gid); if (g) { strcpy(groupname, g->gr_name); // name } else { sprintf(groupname, "%d", s.st_gid); // number } printf("%s mode=0%o owner=%s group=%s\n", e->d_name, s.st_mode, username, groupname); } else { perror("ls"); } } } else { // protection failure perror("ls"); }
} Pasted from <http://www.cs.tufts.edu/comp/111/examples/identity/ls2.c> Identity Page 23
Identity Page 24 Basic concepts of user privilege Wednesday, November 30, 2011 5:08 PM Basic concepts of user privilege Defined as a filesystem concept. Every file has an owner: the UID of the person who owns it. group: the GID of its group. protection word: defines what people can do with the file.
Identity Page 25 The protection word Wednesday, November 30, 2011 5:10 PM The protection word A binary integer Basic pattern: 1111110000000000 5432109876543210 -- bit number ttttugouuugggooo -- scope sstrwxrwxrwx -- meaning Where t is a bit referring to the type of node u is a bit referring to owner privilege g is a bit referring to group privilege o is a bit referring to privilege for everyone other than the owner or group and, for each kind of privilege r means the item is readable w means the item is writeable x means the item is executable s is 1 means that this file executes for its own owner or in its own group. t is 1 means that the directory file exhibits temporary ownership characteristics. Values of tttt: (octal!) 014 socket 012 symbolic link 010 regular file 006 block device
004 directory 002 character device 001 FIFO (named pipe) Identity Page 26
Identity Page 27 Files versus directories Wednesday, November 30, 2011 5:24 PM Protections mean different things depending upon whether a node is a file or directory: Protection Files Directories r can read it can ls it w can write it can create and delete files in it x can execute it as a program can access things in it if you know their names already Typical protections: Your files: rw------ only owner can read and write Your a.out: rwx------ can also execute it. Your directories: rwx------: you can read, write, and search. Typical system protections Shared files: rw-r--r--: anyone can read. Shared programs: rwxr-xr-x: anyone can run it as a program. Shared directories: rwxr-xr-x: anyone can ls or search it. Changing the mode of a file chmod 644 file: make the file public (rw-r--r--: octal) chmod go+x file: make the file executable to group and other if it is executable to owner. Your umask
Attribute of a process. Stored in the PCB. Inherited by sub-processes. Determines which bits of the protection word you won't set, in octal: umask 077: don't let others see what I am doing. umask 022: let others see but not write. Identity Page 28
Identity Page 29 Privilege and nested directories Thursday, December 01, 2011 9:21 AM Privilege and nested directories In order to access something, you must be able to: get to it, by searching its directory (x). Thus you must have access to all directories in its path. change it, by modifying its inode. Thus you must have access to the object itself.
Identity Page 30 A simple protection quandary Thursday, December 01, 2011 9:24 AM A simple protection quandary /foo rwx--x--x owner=root group=root /foo/bar rwx--x--x owner=couch group=grade111 /foo/bar/baz.txt rw------- owner=rveroy group=student What can rveroy do with baz.txt? cannot ls /foo cannot ls /foo/bar can edit /foo/bar/baz.txt (!) What can couch do with baz.txt? cannot ls /foo can ls /foo/bar can delete baz.txt cannot read or write baz.txt (!) In other words, Changing a file requires file permission. Adding or deleting a file requires permission in its directory. It is possible to be able to delete a file without being able to read it!
Identity Page 31 setuid, setgid, and the sticky bit Wednesday, November 30, 2011 The 10th-12th bits of the protection word are special. bit 12: setuid: for programs, run as the file owner, not the user. bit 11: setgid: for programs, run as the file group, not the user's group. bit 10: sticky bit: for directory, only owner can change contained files, even if directory is shared. A brief map of bits 12-10: s (12) s (11) t (10) for files setuid setgid no meaning for directories 5:33 PM no meaning group inheritance sticky behavior
Identity Page 32 An even better 'ls' Thursday, December 01, 2011 8:47 AM #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <dirent.h> #include <pwd.h> #include <grp.h> #include <string.h> void showmode(int mode, char *buffer); main() { DIR *d = opendir("."); if (d) { struct dirent *e; while ((e=readdir(d))!= NULL) { struct stat s; if (stat(e->d_name, &s)==0) { char username[256]; struct passwd *p = getpwuid(s.st_uid); if (p) { strcpy(username, p->pw_name); // name } else { sprintf(username, "%d", s.st_uid); // number } char groupname[256]; struct group *g = getgrgid(s.st_gid); if (g) { strcpy(groupname, g->gr_name); // name } else { sprintf(groupname, "%d", s.st_gid); // number } char mode[10]; showmode(s.st_mode, mode); printf("%s mode=%s owner=%s group=%s\n", e->d_name, mode, username, groupname); } else { perror("ls"); } } } else { // protection failure
Identity Page 33 perror("ls"); } } void showmode(int mode, char *buffer) { buffer[0]= (mode&(1<<8))?'r':'-'; buffer[1]= (mode&(1<<7))?'w':'-'; buffer[2]= (mode&(1<<6))?'x':'-'; buffer[3]= (mode&(1<<5))?'r':'-'; buffer[4]= (mode&(1<<4))?'w':'-'; buffer[5]= (mode&(1<<3))?'x':'-'; buffer[6]= (mode&(1<<2))?'r':'-'; buffer[7]= (mode&(1<<1))?'w':'-'; buffer[8]= (mode&(1<<0))?'x':'-'; buffer[9]='\0'; if (mode&(1<<11)) { // setuid buffer[2]= (buffer[2]=='x'? 's' : 'S'); } if (mode&(1<<10)) { // setgid buffer[5]= (buffer[5]=='x'? 's' : 'S'); } if (mode&(1<<9)) { // sticky bit buffer[8]= (buffer[8]=='x'? 't' : 'T'); } } Pasted from <http://www.cs.tufts.edu/comp/111/examples/identity/ls3.c>
Identity Page 34 File privilege and process privilege Thursday, December 01, 2011 8:52 AM File privilege: setuid: run as file owner. setgid: run as file group. Process privilege: real uid: the one inherited from one's parent process. effective uid: the one specified by file mode. real gid: the one inherited from one's parent process. effective gid: the one specified by file mode.
Identity Page 35 Discovering and manipulating privilege Thursday, December 01, 2011 8:54 AM Discovering and manipulating privilege: int uid = getuid(); // real uid int euid = geteuid(); // effective uid int gid = getgid(); // real gid int egid = getegid(); // effective gid setuid(uid); // set the real uid seteuid(euid); // set the effective uid setgid(gid); // set the real gid setegid(egid); // set the effective gid Watch out: Regular processes can only set the euid to either the uid or an old euid. Root can set the uid or euid to anything. But once root sets the uid to non-root, there is no going back. Likewise for groups. Here is an example of manipulating protections: http://www.cs.tufts.edu/comp/111/examples/identity/k now.c
Example: provide protections Wednesday, November 30, 2011 5:40 PM How provide protections work: /comp/111/grading has protection -s-rwxrws--- owner couch group grade111 which means that I own it, and either I or the group can modify it. group inheritance is enabled: things created in this directory have group grade111. Directories inside /comp/111/grading have the same protection Files inside /comp/111/grading have protection ---rw-rw---- owner: you or me group: grade111 grade111 has members couch,zhaokun,srao02 So Zhaokun can modify it. But you can't normally see it. But provide has to see it: provide is setuid root. The very first thing provide does is to figure out what its class is, and then downgrade its privilege to that class: start out as s--rwxr-xr-x root grading: setuid root. use root privilege to change effective group of process to grade111 (thus invoking setgid). downgrade privilege to that of user (you). At this point, provide is running as you, but with the ta group! Identity Page 36
What happens now is that you post your files to my directories. Now things get interesting: your grades are reported in progress.cgi This has Protections -s-rwxr-xr-x Owner couch Group grade111 So, it runs as group grade111, which means that it gets access to your work! Identity Page 37
Identity Page 38 What you don't want to see Wednesday, November 30, 2011 6:56 PM What you don't want to see in your account: foo mode=rwsrwsrwx owner=root group=root Setuid root Setgid root world executable Whoever runs this gets root on your workstation. What a rootkit actually does, in some form: cp /bin/csh foo chown root foo chgrp root foo chmod 06777 foo so that anyone who runs foo gets a root shell.