summaryrefslogtreecommitdiff
path: root/src/util
diff options
context:
space:
mode:
authorEdward Thomson <ethomson@edwardthomson.com>2022-07-04 15:20:59 -0400
committerEdward Thomson <ethomson@edwardthomson.com>2022-07-07 10:37:49 -0400
commit433f0166c946257214758b94d9ddbb8516e4fb98 (patch)
tree123f23c1b03bda77e97381a6da2c0684352fc299 /src/util
parentdf354ec25d22e70ad4bf3a58a6a7883975d31bb6 (diff)
downloadlibgit2-433f0166c946257214758b94d9ddbb8516e4fb98.tar.gz
fs: refactor file ownership checks
Refactor the file ownership checks so that callers can provide discrete information about the ownership expectations to a single function.
Diffstat (limited to 'src/util')
-rw-r--r--src/util/fs_path.c130
-rw-r--r--src/util/fs_path.h21
2 files changed, 49 insertions, 102 deletions
diff --git a/src/util/fs_path.c b/src/util/fs_path.c
index 58bab7026..7ff6b27af 100644
--- a/src/util/fs_path.c
+++ b/src/util/fs_path.c
@@ -1879,74 +1879,41 @@ static int file_owner_sid(PSID *out, const char *path)
return error;
}
-int git_fs_path_owner_is_current_user(bool *out, const char *path)
+int git_fs_path_owner_is(
+ bool *out,
+ const char *path,
+ git_fs_path_owner_t owner_type)
{
PSID owner_sid = NULL, user_sid = NULL;
- int error = -1;
+ int error;
if (mock_owner) {
- *out = (mock_owner == GIT_FS_PATH_OWNER_CURRENT_USER);
+ *out = ((mock_owner & owner_type) != 0);
return 0;
}
- if ((error = file_owner_sid(&owner_sid, path)) < 0 ||
- (error = current_user_sid(&user_sid)) < 0)
+ if ((error = file_owner_sid(&owner_sid, path)) < 0)
goto done;
- *out = EqualSid(owner_sid, user_sid);
- error = 0;
-
-done:
- git__free(owner_sid);
- git__free(user_sid);
- return error;
-}
-
-int git_fs_path_owner_is_system(bool *out, const char *path)
-{
- PSID owner_sid;
-
- if (mock_owner) {
- *out = (mock_owner == GIT_FS_PATH_OWNER_ADMINISTRATOR);
- return 0;
- }
+ if ((owner_type & GIT_FS_PATH_OWNER_CURRENT_USER) != 0) {
+ if ((error = current_user_sid(&user_sid)) < 0)
+ goto done;
- if (file_owner_sid(&owner_sid, path) < 0)
- return -1;
-
- *out = IsWellKnownSid(owner_sid, WinBuiltinAdministratorsSid) ||
- IsWellKnownSid(owner_sid, WinLocalSystemSid);
-
- git__free(owner_sid);
- return 0;
-}
-
-int git_fs_path_owner_is_system_or_current_user(bool *out, const char *path)
-{
- PSID owner_sid = NULL, user_sid = NULL;
- int error = -1;
-
- if (mock_owner) {
- *out = (mock_owner == GIT_FS_PATH_OWNER_ADMINISTRATOR ||
- mock_owner == GIT_FS_PATH_OWNER_CURRENT_USER);
- return 0;
+ if (EqualSid(owner_sid, user_sid)) {
+ *out = true;
+ goto done;
+ }
}
- if (file_owner_sid(&owner_sid, path) < 0)
- goto done;
-
- if (IsWellKnownSid(owner_sid, WinBuiltinAdministratorsSid) ||
- IsWellKnownSid(owner_sid, WinLocalSystemSid)) {
- *out = 1;
- error = 0;
- goto done;
+ if ((owner_type & GIT_FS_PATH_OWNER_ADMINISTRATOR) != 0) {
+ if (IsWellKnownSid(owner_sid, WinBuiltinAdministratorsSid) ||
+ IsWellKnownSid(owner_sid, WinLocalSystemSid)) {
+ *out = true;
+ goto done;
+ }
}
- if (current_user_sid(&user_sid) < 0)
- goto done;
-
- *out = EqualSid(owner_sid, user_sid);
- error = 0;
+ *out = false;
done:
git__free(owner_sid);
@@ -1956,10 +1923,25 @@ done:
#else
-static int fs_path_owner_is(bool *out, const char *path, uid_t *uids, size_t uids_len)
+int git_fs_path_owner_is(
+ bool *out,
+ const char *path,
+ git_fs_path_owner_t owner_type)
{
+ uid_t uids[2] = { 0 };
+ size_t uid_count = 0, i;
struct stat st;
- size_t i;
+
+ if (mock_owner) {
+ *out = ((mock_owner & owner_type) != 0);
+ return 0;
+ }
+
+ if (owner_type & GIT_FS_PATH_OWNER_CURRENT_USER)
+ uids[uid_count++] = geteuid();
+
+ if (owner_type & GIT_FS_PATH_OWNER_ADMINISTRATOR)
+ uids[uid_count++] = 0;
*out = false;
@@ -1971,7 +1953,7 @@ static int fs_path_owner_is(bool *out, const char *path, uid_t *uids, size_t uid
return -1;
}
- for (i = 0; i < uids_len; i++) {
+ for (i = 0; i < uid_count; i++) {
if (uids[i] == st.st_uid) {
*out = true;
break;
@@ -1980,46 +1962,18 @@ static int fs_path_owner_is(bool *out, const char *path, uid_t *uids, size_t uid
return 0;
}
+#endif
int git_fs_path_owner_is_current_user(bool *out, const char *path)
{
- uid_t userid = geteuid();
-
- if (mock_owner) {
- *out = (mock_owner == GIT_FS_PATH_OWNER_CURRENT_USER);
- return 0;
- }
-
- return fs_path_owner_is(out, path, &userid, 1);
+ return git_fs_path_owner_is(out, path, GIT_FS_PATH_OWNER_CURRENT_USER);
}
int git_fs_path_owner_is_system(bool *out, const char *path)
{
- uid_t userid = 0;
-
- if (mock_owner) {
- *out = (mock_owner == GIT_FS_PATH_OWNER_ADMINISTRATOR);
- return 0;
- }
-
- return fs_path_owner_is(out, path, &userid, 1);
+ return git_fs_path_owner_is(out, path, GIT_FS_PATH_OWNER_ADMINISTRATOR);
}
-int git_fs_path_owner_is_system_or_current_user(bool *out, const char *path)
-{
- uid_t userids[2] = { geteuid(), 0 };
-
- if (mock_owner) {
- *out = (mock_owner == GIT_FS_PATH_OWNER_ADMINISTRATOR ||
- mock_owner == GIT_FS_PATH_OWNER_CURRENT_USER);
- return 0;
- }
-
- return fs_path_owner_is(out, path, userids, 2);
-}
-
-#endif
-
int git_fs_path_find_executable(git_str *fullpath, const char *executable)
{
#ifdef GIT_WIN32
diff --git a/src/util/fs_path.h b/src/util/fs_path.h
index ae28479f9..2dc6d569c 100644
--- a/src/util/fs_path.h
+++ b/src/util/fs_path.h
@@ -740,15 +740,8 @@ typedef enum {
/** The file must be owned by the system account. */
GIT_FS_PATH_OWNER_ADMINISTRATOR = (1 << 1),
- /**
- * The file may be owned by a system account if the current
- * user is in an administrator group. Windows only; this is
- * a noop on non-Windows systems.
- */
- GIT_FS_PATH_OWNER_CURRENT_USER_IS_ADMINISTRATOR = (1 << 2),
-
/** The file may be owned by another user. */
- GIT_FS_PATH_OWNER_OTHER = (1 << 4)
+ GIT_FS_PATH_OWNER_OTHER = (1 << 2)
} git_fs_path_owner_t;
/**
@@ -758,6 +751,12 @@ typedef enum {
*/
void git_fs_path__set_owner(git_fs_path_owner_t owner);
+/** Verify that the file in question is owned by the given owner. */
+int git_fs_path_owner_is(
+ bool *out,
+ const char *path,
+ git_fs_path_owner_t owner_type);
+
/**
* Verify that the file in question is owned by an administrator or system
* account.
@@ -771,12 +770,6 @@ int git_fs_path_owner_is_system(bool *out, const char *path);
int git_fs_path_owner_is_current_user(bool *out, const char *path);
/**
- * Verify that the file in question is owned by an administrator or system
- * account _or_ the current user;
- */
-int git_fs_path_owner_is_system_or_current_user(bool *out, const char *path);
-
-/**
* Search the current PATH for the given executable, returning the full
* path if it is found.
*/