Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use SIDs as UIDs on Windows #930

Merged
merged 4 commits into from
Feb 12, 2023
Merged

Use SIDs as UIDs on Windows #930

merged 4 commits into from
Feb 12, 2023

Conversation

mbikovitsky
Copy link
Contributor

The reason for implementing this is correctness.

Right now, the user list returned by SystemExt::users can contain different UIDs than those returned by ProcessExt::user_id. The reason is that ProcessExt::user_id uses LookupAccountSidW to convert an SID to a name (which is used as an ID). On the other hand, SystemExt::users uses NetUserEnum and LsaEnumerateLogonSessions/LsaGetLogonSessionData to harvest usernames. For system accounts (e.g. LocalSystem or NetworkService) these two techniques return different names. For example, for LocalSystem (S-1-5-18) LookupAccountSidW returns SYSTEM, while LsaGetLogonSessionData returns <COMPUTER NAME>$.

The effect is that SystemExt::get_user_by_id is effectively broken for these users. Which means that given a Uid from a process owned by such a user it's impossible to get a username out of it, without relying on the implementation detail that the Uid is actually a username.

Note that this PR is a breaking change:

  1. Uid, Gid, and User no longer implement PartialOrd and Ord. This is because SIDs have no meaningful ordering.
    • Since both Uid and Gid are implemented using the same xid! macro, PartialOrd and Ord were removed from both.
    • I would argue than even numeric UIDs and GIDs have no inherent ordering — they're just arbitrary identifiers. But that's another matter.
  2. Uid on Windows no longer implements TryFrom<usize>. This is because an SID cannot be constructed from a single number.

Re: #790 — I have added a Windows-only test that for every process for which we can retrieve a UID, we can also find that UID (using EqualSid) in the list returned by SystemExt::users.

I tested this both on Windows 10 (22H2) and on Windows 7 SP1, both 64-bit systems.

@GuillaumeGomez
Copy link
Owner

I would argue than even numeric UIDs and GIDs have no inherent ordering — they're just arbitrary identifiers. But that's another matter.

You're absolutely right on this, the ordering is very much a convenience that doesn't really make sense, but in case you're storing them in an array or anything that can be sorted, it's quite useful.

In that regard, I think it's fine to have a PartialOrd/Ord implementations for these types to keep this possibility, even though it doesn't really make sense as is. Again, it's just a convenience.

Otherwise, this PR looks really great and I'm glad you were able to fix the current situation! I wasn't even able to find out how to make processes' users match the user list with the SID but I guess I overlooked it.

So just a few comments and then I think it's ready for merge.

@mbikovitsky
Copy link
Contributor Author

Done!

@mbikovitsky
Copy link
Contributor Author

Okay, so funnily enough the new test fails on FreeBSD... I don't have this OS handy to investigate, but at a glance it looks like the code parses the user list from /etc/passwd, and it skips certain entries. Maybe there are processes with UIDs that are skipped during this parse?

@mbikovitsky
Copy link
Contributor Author

And the Android failures seem to be related to this: rust-lang/rust#103673. But I'm not sure.

@GuillaumeGomez
Copy link
Owner

Don't worry about other CIs than windows. If your test allowed to discover new bugs, I'm very happy. :) I'll fix them in a follow-up PR.

Otherwise we're almost there. Some suggestions about memory allocations that could be skipped and some naming nitpicking.

@GuillaumeGomez
Copy link
Owner

This is great, thanks a lot for working on this! We'll see if we encounter issues with PartialOrd and other trait implementations on SID. We can always update the implementation later on.

I'll send a patch for the freebsd bug that this PR allowed to uncover in the next days.

@GuillaumeGomez GuillaumeGomez merged commit 544a83f into GuillaumeGomez:master Feb 12, 2023
@mbikovitsky mbikovitsky deleted the windows-sid branch February 13, 2023 04:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants