# SO Lista 6 ## Zadanie 1 ![](https://i.imgur.com/AfMev1a.png) ### Pojęcia: **Tożsamość procesu** - grupa identyfikatorów procesu, jednoznacznie go identyfikująca Real User ID - Identyfikator użytkownika procesu Efective User ID - Identyfikator aktualnego użytkownika Saved User ID - Zapisany drugie ID ### Zadania: :::spoiler ```shell= RUID = 1000 EUID = 0 SUID = 0 ``` ![](https://i.imgur.com/CcoW7UW.png) ```setuid(2000)``` - EUID to 0, więc zostaną zmienione wszystkie identyfikatory ```setreuid(-1, 2000)``` - setreuid przyjmuje argumenty (ruid, euid). RUID zostaje niezmienione, a EUID przyjmuje wartość 2000. Dodatkowo ``` If the real user ID is set (i.e., ruid is not -1) or the effective user ID is set to a value not equal to the previous real user ID, the saved set-user-ID will be set to the new effective user ID. ``` więc SUID również przyjmie wartość 2000 ```seteuid(2000)``` - Proces jest uprzywilejowany, więc zmienia EUID na 2000 ```setresuid(-1, 2000, 3000)``` - Zmienia EUID i SUID, a RUID zostaje bez zmian Proces ```ruid = 0, euid = 1000, suid = 1000``` nie jest uprzywilejowany, bo Efective User ID jest równe 1000, a nie 0 ::: ## Zadanie 2 ![](https://i.imgur.com/Nx6Fd2b.png) ### Pojęcia: Struktura ```rwx```: ```r``` - Czytanie katalogu ```w``` - Edycja katalogu ```x``` - Przeszukiwanie katalogu ### Zadania: :::spoiler Uprawnienia: ``` d | rws | rwx | rwx user group other setuid setgid sticky ``` The setgid affects both files as well as directories. When used on a file, it executes with the privileges of the group of the user who owns it instead of executing with those of the group of the user who executed it. When the bit is set for a directory, the set of files in that directory will have the same group as the group of the parent directory, and not that of the user who created those files. This is used for file sharing since they can be now modified by all the users who are part of the group of the parent directory. ```c= my_access(struct stat *sb, int mode) { if geteuid()==0 return true; userprotREAD = mode & R_OK; userprotWRITE = mode & W_OK; userprotEXEC = mode & X_OK; stat_mode = sb->st_mode; if sb.st_uid==geteuid() { fileprotREAD = stat_mode & S_IRUSR; fileprotWRITE = stat_mode & S_IWUSR; fileprotEXECUTE = stat_mode & S_IXUSR; } if sb.st_gid in getgroups() { fileprotREAD = stat_mode & S_IRGRP; fileprotWRITE = stat_mode & S_IWGRP; fileprotEXECUTE = stat_mode & S_IXGRP; } else { fileprotREAD = stat_mode & S_IROTH; fileprotWRITE = stat_mode & S_IWOTH; fileprotEXECUTE = stat_mode & S_IXOTH; } if (fileprotREAD < userprotREAD return false | fileprotWRITE < userprotWRITE return false | fileprotEXECUTE < userprotEXEC return false) return false; return true; } ``` ``` S_ISUID 04000 set-user-ID bit (see execve(2)) S_ISGID 02000 set-group-ID bit (see below) S_ISVTX 01000 sticky bit (see below) S_IRWXU 00700 owner has read, write, and execute permission S_IRUSR 00400 owner has read permission S_IWUSR 00200 owner has write permission S_IXUSR 00100 owner has execute permission S_IRWXG 00070 group has read, write, and execute permission S_IRGRP 00040 group has read permission S_IWGRP 00020 group has write permission S_IXGRP 00010 group has execute permission S_IRWXO 00007 others (not in group) have read, write, and execute permission S_IROTH 00004 others have read permission S_IWOTH 00002 others have write permission S_IXOTH 00001 others have execute permission ``` ```sticky bit``` - Pliki w danym katalogu mogą być edytowane tylko przez użytkowników, będąch ich właścicielami ::: ## Zadanie 3 ![](https://i.imgur.com/BuC44IC.png) ### Pojęcia: ### Zadania: :::spoiler Kod: ```c 1 /* See LICENSE file for copyright and license details. */ 2 #include <sys/types.h> 3 4 #include <errno.h> 5 #include <grp.h> 6 #include <pwd.h> 7 #include <stdio.h> 8 #include <stdlib.h> 9 #include <string.h> 10 #include <unistd.h> 11 12 #include "config.h" 13 #include "passwd.h" 14 #include "util.h" 15 16 extern char **environ; 17 18 static int lflag = 0; 19 static int pflag = 0; 20 21 static int 22 dologin(struct passwd *pw) 23 { 24 char *shell = pw->pw_shell[0] == '\0' ? "/bin/sh" : pw->pw_shell; 25 char *term = getenv("TERM"); 26 clearenv(); 27 setenv("HOME", pw->pw_dir, 1); 28 setenv("SHELL", shell, 1); 29 setenv("USER", pw->pw_name, 1); 30 setenv("LOGNAME", pw->pw_name, 1); 31 setenv("TERM", term ? term : "linux", 1); 32 if (strcmp(pw->pw_name, "root") == 0) 33 setenv("PATH", ENV_SUPATH, 1); 34 else 35 setenv("PATH", ENV_PATH, 1); 36 if (chdir(pw->pw_dir) < 0) 37 eprintf("chdir %s:", pw->pw_dir); 38 execlp(shell, shell, "-l", NULL); //uruchamia powłokę tak jakby sie zalogował 39 weprintf("execlp %s:", shell); 40 return (errno == ENOENT) ? 127 : 126; 41 } 42 43 static void 44 usage(void) 45 { 46 eprintf("usage: %s [-lp] [username]\n", argv0); 47 } 48 49 int 50 main(int argc, char *argv[]) 51 { 52 char *usr = "root", *pass; 53 char *shell; 54 struct passwd *pw; 55 char *newargv[2]; 56 uid_t uid; 57 58 ARGBEGIN { 59 case 'l': 60 lflag = 1; 61 break; 62 case 'p': 63 pflag = 1; 64 break; 65 default: 66 usage(); 67 } ARGEND; 68 69 if (argc < 1) 70 ; 71 else if (argc == 1) 72 usr = argv[0]; 73 else 74 usage(); 75 76 errno = 0; 77 pw = getpwnam(usr); //Get password file entry from /etc/passwd 78 if (!pw) { 79 if (errno) 80 eprintf("getpwnam: %s:", usr); 81 else 82 eprintf("who are you?\n"); 83 } 84 85 uid = getuid(); 86 if (uid) { // Jak jest rootem to idziemy dalej 87 pass = getpass("Password: "); 88 if (!pass) 89 eprintf("getpass:"); 90 if (pw_check(pw, pass) <= 0) //Sprawdza czy hasło się zgadza 91 exit(1); 92 } 93 94 if (initgroups(usr, pw->pw_gid) < 0) //Tworzymy listę grup użytkownika, dodając do niej grupę pw_gid 95 eprintf("initgroups:"); 96 if (setgid(pw->pw_gid) < 0) 97 eprintf("setgid:"); 98 if (setuid(pw->pw_uid) < 0) 99 eprintf("setuid:"); 100 101 if (lflag) { 102 return dologin(pw); 103 } else { 104 shell = pw->pw_shell[0] == '\0' ? "/bin/sh" : pw->pw_shell; 105 newargv[0] = shell; 106 newargv[1] = NULL; 107 if (!pflag) { 108 setenv("HOME", pw->pw_dir, 1); 109 setenv("SHELL", shell, 1); 110 if (strcmp(pw->pw_name, "root") != 0) { 111 setenv("USER", pw->pw_name, 1); 112 setenv("LOGNAME", pw->pw_name, 1); 113 } 114 } 115 if (strcmp(pw->pw_name, "root") == 0) 116 setenv("PATH", ENV_SUPATH, 1); 117 else 118 setenv("PATH", ENV_PATH, 1); 119 execve(pflag ? getenv("SHELL") : shell, 120 newargv, environ); 121 weprintf("execve %s:", shell); 122 return (errno == ENOENT) ? 127 : 126; 123 } 124 return 0; 125 } ``` Tożsamość to ```ruid=1000, euid=0, suid=0``` ::: ## Zadanie 4 ![](https://i.imgur.com/qipfPFM.png) ### Pojęcia: ### Zadania: Capabilities - Uprawnienia dla programów: CAP_KILL - możesz wysyłać sygnały, ale tylko to CAP_DAC_READ_SEARCH - uprawnienia do czytania wszystkich plików Sygnały możemy też wysyłać sygnały, jeśli mamy ten sam: ![](https://i.imgur.com/a0RjVhC.png) albo SIGCONT jeśli są w tej samej sesji ## Zadanie 5 ![](https://i.imgur.com/4pdxyW2.png) ### Pojęcia: ### Zadania: ```Exit``` z biblioteki standardowej zamyka program, ale tak grzecznie i miło Problemy: * _exit nie dba o bufory * duplikuje bufor Jak zapobiec problemom: - Dbać o bufor ![](https://i.imgur.com/71MuwPq.png) Domyślne strategie: * Plik terminala - Buforowane wierszowo (Cahir powiedział) * Plik zwykły - Fully buffered (cały na raz) * stderr - errory chcemy widzieć od razu! - Nie buforowane ***tcflush()*** discards data written to the object referred to by fd but not transmitted, or data received but not read, depending on the value of queue_selector.