Jak działają grupy użytkowników w systemach Linuksowych

1

Witajcie - w tym temacie chciałbym wziąć na celownik grupy użytkowników - zainteresowała mnie konkretnie ich ilość.
Oto część zawartości pliku /etc/groups

daemon:x:1:
bin:x:2:
tty:x:5:
disk:x:6:
lp:x:7:
mail:x:8:
[...]
video:x:44:
sasl:x:45:
staff:x:50:
games:x:60:
users:x:100:
nogroup:x:65534:
systemd-journal:x:101:
systemd-timesync:x:102:
systemd-network:x:103:

Dlaczego jest tak dużo grup użytkowników w dystrybucjach GNU/Linux takich jak Mint,Ubuntu czy Debian ?
Jakie pełnią one rolę?
Wiele dystrybucji (Red Hat Linux Fedora Core, CentOS,Ubuntu,Mint, etc.) przy zakładaniu konta tworzy też grupę o tej samej nazwie co użytkownik i przypisuje tam nowo powstałego użytkownika - jaki jest tego cel?
Rozumiem mniej więcej co się dzieje gdy mamy właściciela pliku - przy żądaniu dostępu jądro sprawdza czy bieżący użytkownik może uzyskać dostęp do pliku w takim zakresie jaki sobie rości i na ten dostęp pozwala lub nie. Jednak nie rozumiem dlaczego plikowi można nadać grupę i dlaczego
Każda grupa ma nazwę czytelną dla człowieka i numer identyfikujący grupę - GID
Ponoć w Linuksach istnieją takie coś jak Effective GID, Real GID, Saved GID - podobnie jest z User ID (EUID,RUID,SUID)
Czy Real UID(RUID) to jest to samo co UID?
Czy Real GID(RGID) to jest to samo co GID?

Dlaczego mamy kilka rodzajów UID i GID ?

Istnieją ale to inny temat

1

Rozumiem mniej więcej co się dzieje gdy mamy właściciela pliku - przy żadaniu dostępu jądro sprawdza czy bieżący użytkownik może uzyskać dostęp do pliku w takim zakresie jaki sobie rości i na ten dostęp pozwala lub nie. Jednak nie rozumiem dlaczego plikowi można nadać grupę i dlaczego

Właściciel pliku jest jeden. W ten sposób możesz opisać prawa jednego użytkownika do pliku.
A co gdybyś chciał nadać określone prawa do pliku jakiejś (nomen omen) grupie użytkowników?

0

Zrobił mi się mętlik w głowie jeżeli chodzi o kontrole uprawnień.

Mamy plik o następujących uprawnieniach : important_file.txt
Owner:rwx
Group:r--
Ohter:---
Plik należy do użytkownika root i grupy superusers.

Co się stanie gdy ja (kacper) spróbuje uzyskać dostęp do pliku jeżeli
a) nie jestem członkiem superusers - czy wtedy będę miał takie uprawnienia jakie nadano grupie Others?
b) należę do grupy superusers - czy wtedy dotyczą mnie uprawnienia dla grupy a zatem mogę tylko odczytać plik, tak?

@Azarien
Czy możliwe jest należeć do kilku grup - wiem że istnieje takie coś jak grupa podstawowa użytkownika - jeżeli nalezę do kilku grup to jak kernel sprawdza uprawnienia?
Jądro zwraca uwagę TYLKO na grupę podstawową czy sprawdza całą listę grup do których należę?

1
  1. Tak.
  2. Tak.

Tak, można należeć do kilku grup, sprawdza wszystkie sprawdzając uprawnienia - tj. jeżeli plik ma jako właściciela grupę C, a ty jesteś w grupie A (podstawowej), B oraz C, to ciebie obowiązują uprawnienia grupy C.

0

Tak, można należeć do kilku grup, sprawdza wszystkie sprawdzając uprawnienia - tj. jeżeli plik ma jako właściciela grupę C, a ty jesteś w grupie A (podstawowej), B oraz C, to ciebie obowiązują uprawnienia grupy C.

Czyli tak jak sądziłem, w anglojęzycznej części internetu również twierdzą to co ty @Ktos.
Przez ten czas, kiedy nie pisałem próbowałem zlokalizować część jądra - kod - żeby upewnić się co do tych grup i chyba mi się udało.

Nie jestem pewien tego co napisze poniżej, niekoniecznie musi to być prawda, mogłem przeoczyć jakiś opis,szczegół albo coś źle zrozumieć.

https://github.com/torvalds/linux/blob/9256d5a308c95a50c6e85d682492ae1f86a70f9b/security/keys/permission.c#L30
Znajdujemy tu funkcję odpowiedzialna za sprawdzenie uprawnień.

///Check to see whether permission is granted to use a key in the desired way,but permit the security modules to override.
int key_task_permission(const key_ref_t key_ref, const struct cred *cred,unsigned perm)

Podaje się jej jako argumenty kolejno :

  • Referencje do klucza - niestety nie wiem co ten klucz przechowuje, został on zdefiniowany w ten sposób.
typedef struct __key_reference_with_attributes *key_ref_t;

w pliku https://github.com/torvalds/linux/blob/07b75260ebc2c789724c594d7eaf0194fa47b3be/include/linux/key.h#L111
Można o nim w tym pliku przeczytać:

key reference with possession attribute handling
NOTE! key_ref_t is a typedef'd pointer to a type that is not actuallydefined.

  • Drugim argumentem jest struktura zawierająca poświadczenia
  • Trzecim argumentem jest liczba całkowita, zawiera ona uprawnienia do sprawdzenia.

Jeżeli chodzi o ciało funkcji interesuje nas linijka:

ret = groups_search(cred->group_info, key->gid);

Ciało funkcji znajduje się w pliku https://github.com/torvalds/linux/blob/9256d5a308c95a50c6e85d682492ae1f86a70f9b/kernel/groups.c#L133
Kiedy funkcja

 int groups_search(const struct group_info *group_info, kgid_t grp)

zwróci prawdę przechodzimy do dalszej części weryfikacji uprawnień poprzez skok goto use_these_perms;

Z tego co się zorientowałem i udało mi się zrozumieć to właśnie ta funkcja sprawdza listę grup do których należy użytkownik.
Wkleję tu jej kod:
```c
/* a simple bsearch */
int groups_search(const struct group_info *group_info, kgid_t grp)
{
	unsigned int left, right;

	if (!group_info)
		return 0;

	left = 0;
	right = group_info->ngroups;
	while (left < right) {
		unsigned int mid = (left+right)/2;
		if (gid_gt(grp, GROUP_AT(group_info, mid)))
			left = mid + 1;
		else if (gid_lt(grp, GROUP_AT(group_info, mid)))
			right = mid;
		else
			return 1;
	}
	return 0;
}

==========
Czy powinno się używać instrukcji goto i to w kodzie jądra - użycie jej w nadmiernych ilościach powoduje zaciemnienie kodu.
Proszę również żeby ktoś wyjaśnił co znaczą te dwa zapisy - zwyczajnie ich nie rozumiem, nie umiem ich nawet odczytać:
(@mlyszczek - wybacz że ci zawracam głowę ale pisałeś że zajmujesz/zajmowałeś się niskopoziomowymi rzeczami.)

a) https://github.com/torvalds/linux/blob/c05c2ec96bb8b7310da1055c7b9d786a3ec6dc0c/include/linux/cred.h#L92

#define GROUP_AT(gi, i) \
((gi)->blocks[(i) / NGROUPS_PER_BLOCK][(i) % NGROUPS_PER_BLOCK])

Zadaje sobie sprawę że tu chodzi o makro (funkcyjne?? - bo wywołuje się je jak funkcję) ale nie wiem co oznacza ten zapis.
b)https://github.com/torvalds/linux/blob/07b75260ebc2c789724c594d7eaf0194fa47b3be/include/linux/key.h#L119

static inline struct key *key_ref_to_ptr(const key_ref_t key_ref)
{
	return (struct key *) ((unsigned long) key_ref & ~1UL);
}

Funkcja ta oczywiście zwraca wskaźnik a przyjmuje referencje a w komentarzu powyżej znajdujemy informacje

  * the three functions are used to assemble and disassemble references

Jednak również tutaj nie rozumiem zapisu - patrz ciało funkcji.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.