Update virtual sql functions to support multiple constraints by brian-mckinney · Pull Request #8746 · osquery/osquery
Background
USER_BASEDtables must supply auidconstraint, or else the logged in user is used as the constraint.- the
vscode_extensionstable, and potentially others, pass this constraint to[usersFromContext](https://github.com/osquery/osquery/blob/a12cf1b59a52a9cafb4246d1adb4e34f7969e514/osquery/tables/system/system_utils.cpp#L17-L32), which makes a virtual SQL call to select all users with the supplieduid - SQL::selectAllFrom only supports a single constraint, in this case
uidis the constraint.
Problem
- On linux, there is a special case where remote users can only be returned by the users table if
include_remote = 1is specified as a constraint. - This means that on linux, if you need to select a remote user via a
uid, you must supply two constraints.uid = 123 and include_remote = 1 - This means that
USER_BASEDtables (like vscode_extensions) on linux are unable to select remote users, even if the correctuidis supplied, becauseusersFromContextwill ignore the second constraint. - The obvious solution was to modify
usersFromContextto support theinclude_remoteconstraint. However, this was hindered by the fact, thatSQL::selectAllFromonly supported a single constraint.
Solution
- This PR adds a new overload function to
SQL::selectFromthat can support multiple constraints. - A small amount of refactoring was done, to make the existing functions use the new function, in order to reduce code duplication
- A test was added to the sql tests
usersFromContextwas modified to supportinclude_remotetransparently- if a uid is supplied, we make the assumption that the user exists
- We attempt first to select from the users table without
include_remote. If no results are returned, we will try again withinclude_remote=1, but only on linux. - We do not attempt to include remote users in the first check, because LDAP queries may still happen depending on the search order of sssd.conf on the host system, which we do not control.
Manual Testing
Setup
I set up a docker stack that implemented open ldap and created a remote user named alice and pre-populated the home directory with vscode extensions
root@d5ecad67c1bd:/# getent passwd alice alice:*:10001:10001:alice:/home/alice:/bin/bash root@d5ecad67c1bd:/# grep alice /etc/passwd root@d5ecad67c1bd:/#
osquery> select * from users where uid = 10001; osquery> select * from users where uid = 10001 and include_remote=1; +-------+-------+------------+------------+----------+-------------+-------------+-----------+------+ | uid | gid | uid_signed | gid_signed | username | description | directory | shell | uuid | +-------+-------+------------+------------+----------+-------------+-------------+-----------+------+ | 10001 | 10001 | 10001 | 10001 | alice | alice | /home/alice | /bin/bash | | +-------+-------+------------+------------+----------+-------------+-------------+-----------+------+
Build from master - Validate vscode_extensions cannot see remote users
direct query
osquery> SELECT uid, name, publisher ...> FROM vscode_extensions ...> WHERE uid = 10001 ...> LIMIT 5; osquery>
subquery attempt
osquery> SELECT uid, name, publisher ...> FROM vscode_extensions ...> WHERE uid in (SELECT uid FROM users WHERE include_remote = 1) ...> LIMIT 5; osquery>
join attempt
osquery> SELECT users.uid, username, name, publisher ...> FROM vscode_extensions ...> JOIN users ...> ON users.uid = vscode_extensions.uid ...> WHERE users.uid in (SELECT uid FROM users WHERE include_remote = 1) ...> AND users.include_remote = 1 ...> LIMIT 5; osquery>
Build from this PR - validate vscode_extensions can see remote users
direct query
osquery> SELECT uid, name, publisher ...> FROM vscode_extensions ...> WHERE uid = 10001 ...> LIMIT 5; +-------+-----------------------------------+-----------+ | uid | name | publisher | +-------+-----------------------------------+-----------+ | 10001 | github.copilot-chat | GitHub | | 10001 | github.copilot | GitHub | | 10001 | ms-vscode.cpptools-extension-pack | Microsoft | | 10001 | ms-vscode.cpptools-themes | Microsoft | | 10001 | ms-vscode.cmake-tools | Microsoft | +-------+-----------------------------------+-----------+
subquery example
osquery> SELECT uid, name, publisher ...> FROM vscode_extensions ...> WHERE uid in (SELECT uid FROM users WHERE include_remote = 1) ...> LIMIT 5; +-------+-----------------------------------+-----------+ | uid | name | publisher | +-------+-----------------------------------+-----------+ | 10001 | github.copilot-chat | GitHub | | 10001 | github.copilot | GitHub | | 10001 | ms-vscode.cpptools-extension-pack | Microsoft | | 10001 | ms-vscode.cpptools-themes | Microsoft | | 10001 | ms-vscode.cmake-tools | Microsoft | +-------+-----------------------------------+-----------+ osquery>
join example
osquery> SELECT users.uid, username, name, publisher ...> FROM vscode_extensions ...> JOIN users ...> ON users.uid = vscode_extensions.uid ...> WHERE users.uid in (SELECT uid FROM users WHERE include_remote = 1) ...> AND users.include_remote = 1 ...> LIMIT 5; +-------+----------+-----------------------------------+-----------+ | uid | username | name | publisher | +-------+----------+-----------------------------------+-----------+ | 10001 | alice | github.copilot-chat | GitHub | | 10001 | alice | github.copilot | GitHub | | 10001 | alice | ms-vscode.cpptools-extension-pack | Microsoft | | 10001 | alice | ms-vscode.cpptools-themes | Microsoft | | 10001 | alice | ms-vscode.cmake-tools | Microsoft | +-------+----------+-----------------------------------+-----------+ osquery>