Unix / Linux: Sự khác biệt giữa ID người dùng thực, ID người dùng hiệu quả và ID người dùng đã lưu


102

Tôi đã biết về id người dùng thực . Đây là số duy nhất cho một người dùng trong hệ thống.

Trong hệ thống của tôi, tôi uid

$ echo $UID
1014
$                 

Hai ID còn lại là viết tắt của gì?
Và việc sử dụng id người dùng hiệu quảid người dùng đã lưu là gì và chúng ta sử dụng nó ở đâu trong hệ thống?


FYI - cũng có id người dùng hệ thống tệp, như được nêu trên trang Wikipedia: en.wikipedia.org/wiki/User_identifier
Willem van Ketwich,

Tôi nghĩ anh ấy không đề cập đến nó bởi vì (từ liên kết wiki của bạn): "Kể từ kernel 2.0, sự tồn tại của fsuid không còn cần thiết nữa vì Linux tuân thủ các quy tắc SUSv3 để gửi tín hiệu, nhưng fsuid vẫn còn vì lý do tương thích."
RtmY

Câu trả lời:


147

Sự phân biệt giữa id người dùng thực và id người dùng hiệu quả được thực hiện bởi vì bạn có thể cần tạm thời lấy danh tính của người dùng khác (hầu hết thời gian là vậy root, nhưng đó có thể là bất kỳ người dùng nào). Nếu bạn chỉ có một id người dùng, thì sẽ không có cách nào thay đổi trở lại id người dùng ban đầu của bạn sau đó (ngoài việc coi thường lời nói của bạn và trong trường hợp bạn có root, sử dụng rootcác đặc quyền của để thay đổi thành bất kỳ người dùng nào).

Vì vậy, id người dùng thực là bạn thực sự là ai (người sở hữu quy trình) và id người dùng hiệu quả là những gì hệ điều hành xem xét để đưa ra quyết định xem bạn có được phép làm điều gì đó hay không (hầu hết thời gian , có một số ngoại lệ).

Khi bạn đăng nhập, trình bao đăng nhập đặt cả id người dùng thực và id người dùng hiệu quả thành cùng một giá trị (id người dùng thực của bạn) như được cung cấp bởi tệp mật khẩu.

Bây giờ, nó cũng xảy ra khi bạn thực thi một chương trình setuid và bên cạnh việc chạy với tư cách người dùng khác (ví dụ root), chương trình setuid cũng phải làm điều gì đó thay mặt bạn. Cái này hoạt động ra sao?
Sau khi thực thi chương trình setuid, nó sẽ có id thực của bạn (vì bạn là chủ sở hữu quá trình) và id người dùng hiệu quả của chủ sở hữu tệp (ví dụ root) vì nó là setuid.

Chương trình thực hiện bất cứ điều gì kỳ diệu cần làm với các đặc quyền của người dùng siêu cấp và sau đó muốn thay mặt bạn làm điều gì đó. Điều đó có nghĩa là cố gắng làm điều gì đó mà bạn không thể làm sẽ thất bại . sao làm được vậy? Vâng, rõ ràng là bằng cách thay đổi id người dùng hiệu quả của nó thành id người dùng thực!

Bây giờ chương trình setuid đó không có cách nào chuyển lại vì tất cả những gì kernel biết là id của bạn và ... id của bạn . Bang, bạn chết rồi.

Đây là những gì mà id người dùng đã lưu dành cho.


6
Để rõ hơn về điểm cuối cùng về id người dùng đã lưu, hãy xem Wikipedia.
GDP2

Bạn có thể chỉ cho tôi một số bài đọc nơi tôi có thể tìm thấy cuộc gọi hệ thống nào kiểm tra uid thực không? cảm ơn bạn
mik1904

1
@ mik1904: Điều quan trọng nhất mà bạn có thể sử dụng để kiểm tra UID thực access. Đó là 99,9% của nó. Ngoài ra setfsuid(nhưng hiếm khi cần thiết), và một số chức năng cấp rất thấp và bạn cần (nhưng không được kiểm tra) ID người dùng thực để nhận / thiết lập mức độ ưu tiên hoặc trình lập lịch, và các ID được chuyển đến trình xử lý tín hiệu hoặc được trả lại bởi waitet al. các ID thực. execvekhông kiểm tra, nhưng có thể không thành công nếu bạn đã thay đổi id người dùng thực. Cũng forkkhông kiểm tra, nhưng có thể không thành công nếu bạn đạt đến hạn ngạch quy trình tối đa trên UID thực. Google với site:man7.orglà bạn của bạn ở đây.
Damon

"lệnh ping cần mở một ổ cắm và nhân Linux yêu cầu đặc quyền root cho điều đó." điều này không thực sự chính xác. pingcần một ổ cắm thô . bất kỳ người dùng có thể (thường) mở một ổ cắm, và cho nghe, trên 1024.
Daniel Farrell

36

Tôi sẽ cố gắng giải thích từng bước với một số ví dụ.

Nền ngắn

Mỗi tiến trình có riêng 'Quy trình thông tin' của nó bao gồm các thuộc tính như PID, các PPID, PGID, session IDvà cũng là người dùng và nhóm ID thực và hiệu quả: RUID, EUID, RGID, EGID.

Chúng tôi sẽ tập trung vào những điều đó.


Phần 1: Hiểu UID và GID

Bây giờ tôi sẽ đăng nhập vào một trình bao bằng thông tin đăng nhập của mình và chạy:

$ grep $LOGNAME /etc/passwd
rotem:x:1000:1000:rotem,,,:/home/rotem:/bin/bash

Bạn có thể thấy tên đăng nhập (rotem) của tôi, UIDGID đều là 1000 và các chi tiết khác như shell mà tôi đã đăng nhập.


Phần 2: Hiểu RUID và RGID

Mọi quy trình đều có chủ sở hữu và thuộc về một nhóm .
Trong trình bao của chúng tôi, mọi quy trình mà bây giờ chúng tôi sẽ chạy sẽ kế thừa các đặc quyền của tài khoản người dùng của tôi và sẽ chạy với cùng một UID và GID.

Hãy chạy một lệnh đơn giản để kiểm tra nó:

$ sleep 10 & ps aux | grep 'sleep'

Và kiểm tra UID và GID của quá trình:

$ stat -c "%u %g" /proc/$pid/
1000 1000

Đó là ID người dùng thực ( ) và ID nhóm thực ( ) của quy trình .RUIDRGID

(*) Kiểm tra các tùy chọn khác để xem UID và GID và các cách để có được điều này trong một lớp lót .

Hiện tại, hãy chấp nhận sự thật rằng các thuộc tính EUIDEGIDthuộc tính là 'dư thừa' và chỉ bằng với RUIDRGIDở phía sau.

Phần 3: Hiểu EUID và EGID

Hãy lấy pinglệnh làm ví dụ.

Tìm kiếm vị trí nhị phân bằng whichlệnh sau đó chạy ls -la:

-rwsr-xr-x  1 root root   64424 Mar 10  2017  ping

Bạn có thể thấy rằng chủ sở hữu và nhóm của tệp root. Điều này là do pinglệnh cần mở một ổ cắm và nhân Linux yêu cầu rootđặc quyền cho việc đó.

Nhưng làm thế nào tôi có thể sử dụng pingnếu tôi không có rootđặc quyền?
Chú ý ký tự 's' thay vì 'x' trong phần chủ sở hữu quyền đối với tệp.
Đây là một bit cấp phép đặc biệt cho các tệp thực thi nhị phân cụ thể (như pingsudo) được gọi là setuid .

Đây là nơi EUIDEGIDphát huy tác dụng.
Điều gì sẽ xảy ra là khi tệp nhị phân setuid như pingthực thi, quá trình thay đổi ID người dùng hiệu quả ( EUID) của nó từ mặc định RUIDthành chủ sở hữu của tệp thực thi nhị phân đặc biệt này, trong trường hợp này là -root .
Tất cả điều này được thực hiện bởi thực tế đơn giản là tệp này có setuidbit.

Kernel đưa ra quyết định liệu quá trình này có đặc quyền hay không bằng cách xem xét EUIDquá trình của quá trình. Bởi vì bây giờ các EUIDđiểm đến root, hoạt động sẽ không bị hạt nhân từ chối.

Lưu ý : Trên các bản phát hành Linux mới nhất, đầu ra của pinglệnh sẽ trông khác vì thực tế là họ đã áp dụng cách tiếp cận Khả năng của Linux thay vì cách tiếp cận setuid này - đối với những người chưa quen - hãy đọc ở đây .

Phần 4: Còn SUID và SGID?

ID người dùng đã lưu ( SUID) đang được sử dụng khi một quy trình đặc quyền đang chạy ( rootchẳng hạn như) và nó cần thực hiện một số tác vụ không đặc quyền.

Trong trường hợp đó, UID ( EUID) có hiệu lực từ trước đó sẽ được lưu bên trong SUIDvà sau đó được thay đổi thành một tác vụ không đặc quyền. Khi nhiệm vụ không đặc quyền được hoàn thành, EUIDý chí sẽ được lấy từ giá trị của SUIDvà chuyển trở lại tài khoản đặc quyền.



1
Câu trả lời rõ ràng ngoại trừ đoạn cuối trên SUID. Đã nhầm lẫn với các nhiệm vụ đặc quyền và đặc quyền. Hữu ích nếu một ví dụ được cung cấp. Cảm ơn.
Upendra

2
Câu trả lời rất chính xác. Cảm ơn!!
user37416
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.