diff options
author | Havoc Pennington <hp@redhat.com> | 2007-06-14 20:59:16 +0000 |
---|---|---|
committer | Havoc Pennington <hp@redhat.com> | 2007-06-14 20:59:16 +0000 |
commit | 48c6f1472dc315c9572cb1aebf8c7b68a66f5bef (patch) | |
tree | 75c1b5a65141ac5a69ee11cf1d6354b5211bc45d /dbus | |
parent | 323790705782bee0d54ea9a342718a49b4ee5be6 (diff) |
2007-06-14 Havoc Pennington <hp@redhat.com>
* dbus/dbus-auth.c: adapt to keyring changes
* dbus/dbus-keyring.c: change to avoid using user ID and home
directory directly; instead use a
keyring-location-from-credentials function in dbus-sysdeps
* fix to use _dbus_append_user_from_current_process() instead of
_dbus_username_from_current_process() or _dbus_append_desired_identity().
Diffstat (limited to 'dbus')
-rw-r--r-- | dbus/dbus-auth-script.c | 7 | ||||
-rw-r--r-- | dbus/dbus-auth.c | 31 | ||||
-rw-r--r-- | dbus/dbus-keyring.c | 130 | ||||
-rw-r--r-- | dbus/dbus-keyring.h | 28 | ||||
-rw-r--r-- | dbus/dbus-sysdeps-unix.c | 93 | ||||
-rw-r--r-- | dbus/dbus-sysdeps.h | 11 | ||||
-rw-r--r-- | dbus/dbus-userdb.c | 39 | ||||
-rw-r--r-- | dbus/dbus-userdb.h | 7 |
8 files changed, 225 insertions, 121 deletions
diff --git a/dbus/dbus-auth-script.c b/dbus/dbus-auth-script.c index eb145e49..b23fbfcb 100644 --- a/dbus/dbus-auth-script.c +++ b/dbus/dbus-auth-script.c @@ -488,7 +488,7 @@ _dbus_auth_script_run (const DBusString *filename) goto out; } - if (!_dbus_append_desired_identity (&username)) + if (!_dbus_append_user_from_current_process (&username)) { _dbus_warn ("no memory for userid\n"); _dbus_string_free (&username); @@ -513,7 +513,6 @@ _dbus_auth_script_run (const DBusString *filename) "USERNAME_HEX", &where)) { DBusString username; - const DBusString *u; if (!_dbus_string_init (&username)) { @@ -522,9 +521,7 @@ _dbus_auth_script_run (const DBusString *filename) goto out; } - if (!_dbus_username_from_current_process (&u) || - !_dbus_string_copy (u, 0, &username, - _dbus_string_get_length (&username))) + if (!_dbus_append_user_from_current_process (&username)) { _dbus_warn ("no memory for username\n"); _dbus_string_free (&username); diff --git a/dbus/dbus-auth.c b/dbus/dbus-auth.c index e47f6e36..5164f17a 100644 --- a/dbus/dbus-auth.c +++ b/dbus/dbus-auth.c @@ -555,8 +555,8 @@ sha1_handle_first_client_response (DBusAuth *auth, * a different DBusAuth for every connection. */ if (auth->keyring && - !_dbus_keyring_is_for_user (auth->keyring, - data)) + !_dbus_keyring_is_for_credentials (auth->keyring, + auth->desired_identity)) { _dbus_keyring_unref (auth->keyring); auth->keyring = NULL; @@ -565,9 +565,9 @@ sha1_handle_first_client_response (DBusAuth *auth, if (auth->keyring == NULL) { dbus_error_init (&error); - auth->keyring = _dbus_keyring_new_homedir (data, - &auth->context, - &error); + auth->keyring = _dbus_keyring_new_for_credentials (auth->desired_identity, + &auth->context, + &error); if (auth->keyring == NULL) { @@ -780,15 +780,18 @@ static dbus_bool_t handle_client_initial_response_cookie_sha1_mech (DBusAuth *auth, DBusString *response) { - const DBusString *username; + DBusString username; dbus_bool_t retval; retval = FALSE; - if (!_dbus_username_from_current_process (&username)) + if (!_dbus_string_init (&username)) + return FALSE; + + if (!_dbus_append_user_from_current_process (&username)) goto out_0; - if (!_dbus_string_hex_encode (username, 0, + if (!_dbus_string_hex_encode (&username, 0, response, _dbus_string_get_length (response))) goto out_0; @@ -796,6 +799,8 @@ handle_client_initial_response_cookie_sha1_mech (DBusAuth *auth, retval = TRUE; out_0: + _dbus_string_free (&username); + return retval; } @@ -887,9 +892,9 @@ handle_client_data_cookie_sha1_mech (DBusAuth *auth, DBusError error; dbus_error_init (&error); - auth->keyring = _dbus_keyring_new_homedir (NULL, - &context, - &error); + auth->keyring = _dbus_keyring_new_for_credentials (NULL, + &context, + &error); if (auth->keyring == NULL) { @@ -1057,7 +1062,7 @@ handle_server_data_external_mech (DBusAuth *auth, } else { - if (!_dbus_credentials_parse_and_add_desired(auth->desired_identity, + if (!_dbus_credentials_parse_and_add_user(auth->desired_identity, &auth->identity)) { _dbus_verbose ("%s: could not get credentials from uid string\n", @@ -1125,7 +1130,7 @@ handle_client_initial_response_external_mech (DBusAuth *auth, if (!_dbus_string_init (&plaintext)) return FALSE; - if (!_dbus_append_desired_identity (&plaintext)) + if (!_dbus_append_user_from_current_process (&plaintext)) goto failed; if (!_dbus_string_hex_encode (&plaintext, 0, diff --git a/dbus/dbus-keyring.c b/dbus/dbus-keyring.c index 17c6b179..5023bd07 100644 --- a/dbus/dbus-keyring.c +++ b/dbus/dbus-keyring.c @@ -110,12 +110,12 @@ typedef struct struct DBusKeyring { int refcount; /**< Reference count */ - DBusString username; /**< Username keyring is for */ DBusString directory; /**< Directory the below two items are inside */ DBusString filename; /**< Keyring filename */ DBusString filename_lock; /**< Name of lockfile */ DBusKey *keys; /**< Keys loaded from the file */ int n_keys; /**< Number of keys */ + DBusCredentials *credentials; /**< Credentials containing user the keyring is for */ }; static DBusKeyring* @@ -135,9 +135,6 @@ _dbus_keyring_new (void) if (!_dbus_string_init (&keyring->filename_lock)) goto out_3; - - if (!_dbus_string_init (&keyring->username)) - goto out_4; keyring->refcount = 1; keyring->keys = NULL; @@ -145,7 +142,7 @@ _dbus_keyring_new (void) return keyring; - out_4: + /* out_4: */ _dbus_string_free (&keyring->filename_lock); out_3: _dbus_string_free (&keyring->filename); @@ -691,7 +688,9 @@ _dbus_keyring_unref (DBusKeyring *keyring) if (keyring->refcount == 0) { - _dbus_string_free (&keyring->username); + if (keyring->credentials) + _dbus_credentials_unref (keyring->credentials); + _dbus_string_free (&keyring->filename); _dbus_string_free (&keyring->filename_lock); _dbus_string_free (&keyring->directory); @@ -701,9 +700,9 @@ _dbus_keyring_unref (DBusKeyring *keyring) } /** - * Creates a new keyring that lives in the ~/.dbus-keyrings - * directory of the given user. If the username is #NULL, - * uses the user owning the current process. + * Creates a new keyring that lives in the ~/.dbus-keyrings directory + * of the given user credentials. If the credentials are #NULL or + * empty, uses those of the current process. * * @param username username to get keyring for, or #NULL * @param context which keyring to get @@ -711,79 +710,58 @@ _dbus_keyring_unref (DBusKeyring *keyring) * @returns the keyring or #NULL on error */ DBusKeyring* -_dbus_keyring_new_homedir (const DBusString *username, - const DBusString *context, - DBusError *error) +_dbus_keyring_new_for_credentials (DBusCredentials *credentials, + const DBusString *context, + DBusError *error) { - DBusString homedir; + DBusString ringdir; DBusKeyring *keyring; dbus_bool_t error_set; - DBusString dotdir; DBusError tmp_error; - + DBusCredentials *our_credentials; + _DBUS_ASSERT_ERROR_IS_CLEAR (error); keyring = NULL; error_set = FALSE; + our_credentials = NULL; - if (!_dbus_string_init (&homedir)) + if (!_dbus_string_init (&ringdir)) { dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); return NULL; } - _dbus_string_init_const (&dotdir, ".dbus-keyrings"); - - if (username == NULL) + if (credentials != NULL) { - const DBusString *const_homedir; - - if (!_dbus_username_from_current_process (&username) || - !_dbus_homedir_from_current_process (&const_homedir)) - goto failed; - - if (!_dbus_string_copy (const_homedir, 0, - &homedir, 0)) - goto failed; + our_credentials = _dbus_credentials_copy (credentials); } else { - if (!_dbus_homedir_from_username (username, &homedir)) - goto failed; + our_credentials = _dbus_credentials_new_from_current_process (); } + + if (our_credentials == NULL) + goto failed; -#ifdef DBUS_BUILD_TESTS - { - const char *override; - - override = _dbus_getenv ("DBUS_TEST_HOMEDIR"); - if (override != NULL && *override != '\0') - { - _dbus_string_set_length (&homedir, 0); - if (!_dbus_string_append (&homedir, override)) - goto failed; - - _dbus_verbose ("Using fake homedir for testing: %s\n", - _dbus_string_get_const_data (&homedir)); - } - else - { - static dbus_bool_t already_warned = FALSE; - if (!already_warned) - { - _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n"); - already_warned = TRUE; - } - } - } -#endif + if (_dbus_credentials_are_anonymous (our_credentials)) + { + if (!_dbus_credentials_add_from_current_process (our_credentials)) + goto failed; + } - _dbus_assert (username != NULL); + if (!_dbus_append_keyring_directory_for_credentials (&ringdir, + our_credentials)) + goto failed; keyring = _dbus_keyring_new (); if (keyring == NULL) goto failed; + _dbus_assert (keyring->credentials == NULL); + keyring->credentials = our_credentials; + our_credentials = NULL; /* so we don't unref it again later */ + /* should have been validated already, but paranoia check here */ if (!_dbus_keyring_validate_context (context)) { @@ -794,18 +772,12 @@ _dbus_keyring_new_homedir (const DBusString *username, goto failed; } - if (!_dbus_string_copy (username, 0, - &keyring->username, 0)) - goto failed; - - if (!_dbus_string_copy (&homedir, 0, + /* Save keyring dir in the keyring object */ + if (!_dbus_string_copy (&ringdir, 0, &keyring->directory, 0)) - goto failed; - - if (!_dbus_concat_dir_and_file (&keyring->directory, - &dotdir)) - goto failed; + goto failed; + /* Create keyring->filename based on keyring dir and context */ if (!_dbus_string_copy (&keyring->directory, 0, &keyring->filename, 0)) goto failed; @@ -814,6 +786,7 @@ _dbus_keyring_new_homedir (const DBusString *username, context)) goto failed; + /* Create lockfile name */ if (!_dbus_string_copy (&keyring->filename, 0, &keyring->filename_lock, 0)) goto failed; @@ -821,6 +794,7 @@ _dbus_keyring_new_homedir (const DBusString *username, if (!_dbus_string_append (&keyring->filename_lock, ".lock")) goto failed; + /* Reload keyring */ dbus_error_init (&tmp_error); if (!_dbus_keyring_reload (keyring, FALSE, &tmp_error)) { @@ -842,7 +816,7 @@ _dbus_keyring_new_homedir (const DBusString *username, dbus_error_free (&tmp_error); } - _dbus_string_free (&homedir); + _dbus_string_free (&ringdir); return keyring; @@ -851,9 +825,11 @@ _dbus_keyring_new_homedir (const DBusString *username, dbus_set_error_const (error, DBUS_ERROR_NO_MEMORY, NULL); + if (our_credentials) + _dbus_credentials_unref (our_credentials); if (keyring) _dbus_keyring_unref (keyring); - _dbus_string_free (&homedir); + _dbus_string_free (&ringdir); return NULL; } @@ -998,19 +974,19 @@ _dbus_keyring_get_best_key (DBusKeyring *keyring, } /** - * Checks whether the keyring is for the given username. + * Checks whether the keyring is for the same user as the given credentials. * * @param keyring the keyring - * @param username the username to check + * @param credentials the credentials to check * * @returns #TRUE if the keyring belongs to the given user */ dbus_bool_t -_dbus_keyring_is_for_user (DBusKeyring *keyring, - const DBusString *username) +_dbus_keyring_is_for_credentials (DBusKeyring *keyring, + DBusCredentials *credentials) { - return _dbus_string_equal (&keyring->username, - username); + return _dbus_credentials_same_user (keyring->credentials, + credentials); } /** @@ -1100,8 +1076,8 @@ _dbus_keyring_test (void) _dbus_string_init_const (&context, "org_freedesktop_dbus_testsuite"); dbus_error_init (&error); - ring1 = _dbus_keyring_new_homedir (NULL, &context, - &error); + ring1 = _dbus_keyring_new_for_credentials (NULL, &context, + &error); _dbus_assert (ring1); _dbus_assert (error.name == NULL); @@ -1113,7 +1089,7 @@ _dbus_keyring_test (void) goto failure; } - ring2 = _dbus_keyring_new_homedir (NULL, &context, &error); + ring2 = _dbus_keyring_new_for_credentials (NULL, &context, &error); _dbus_assert (ring2); _dbus_assert (error.name == NULL); diff --git a/dbus/dbus-keyring.h b/dbus/dbus-keyring.h index 5df0f793..d93d2b90 100644 --- a/dbus/dbus-keyring.h +++ b/dbus/dbus-keyring.h @@ -26,24 +26,26 @@ #include <dbus/dbus-macros.h> #include <dbus/dbus-errors.h> #include <dbus/dbus-string.h> +#include <dbus/dbus-credentials.h> DBUS_BEGIN_DECLS typedef struct DBusKeyring DBusKeyring; -DBusKeyring* _dbus_keyring_new_homedir (const DBusString *username, - const DBusString *context, - DBusError *error); -DBusKeyring* _dbus_keyring_ref (DBusKeyring *keyring); -void _dbus_keyring_unref (DBusKeyring *keyring); -dbus_bool_t _dbus_keyring_validate_context (const DBusString *context); -int _dbus_keyring_get_best_key (DBusKeyring *keyring, - DBusError *error); -dbus_bool_t _dbus_keyring_is_for_user (DBusKeyring *keyring, - const DBusString *username); -dbus_bool_t _dbus_keyring_get_hex_key (DBusKeyring *keyring, - int key_id, - DBusString *hex_key); +DBusKeyring* _dbus_keyring_new_for_credentials (DBusCredentials *credentials, + const DBusString *context, + DBusError *error); +DBusKeyring* _dbus_keyring_ref (DBusKeyring *keyring); +void _dbus_keyring_unref (DBusKeyring *keyring); +dbus_bool_t _dbus_keyring_validate_context (const DBusString *context); +int _dbus_keyring_get_best_key (DBusKeyring *keyring, + DBusError *error); +dbus_bool_t _dbus_keyring_is_for_credentials (DBusKeyring *keyring, + DBusCredentials *credentials); +dbus_bool_t _dbus_keyring_get_hex_key (DBusKeyring *keyring, + int key_id, + DBusString *hex_key); + DBUS_END_DECLS diff --git a/dbus/dbus-sysdeps-unix.c b/dbus/dbus-sysdeps-unix.c index b3ffe04f..725c4de7 100644 --- a/dbus/dbus-sysdeps-unix.c +++ b/dbus/dbus-sysdeps-unix.c @@ -1507,7 +1507,8 @@ _dbus_credentials_add_from_current_process (DBusCredentials *credentials) /** * Parses a desired identity provided from a client in the auth protocol. - * On UNIX this means parsing a UID. + * On UNIX this means parsing a UID, on Windows probably parsing an + * SID string. * * @todo this is broken because it treats OOM and parse error * the same way. Needs a #DBusError. @@ -1517,7 +1518,7 @@ _dbus_credentials_add_from_current_process (DBusCredentials *credentials) * @returns #TRUE if we successfully parsed something */ dbus_bool_t -_dbus_credentials_parse_and_add_desired (DBusCredentials *credentials, +_dbus_credentials_parse_and_add_user (DBusCredentials *credentials, const DBusString *desired_identity) { dbus_uid_t uid; @@ -1532,15 +1533,18 @@ _dbus_credentials_parse_and_add_desired (DBusCredentials *credentials, } /** - * Append to the string the identity we would like to have when we authenticate, - * on UNIX this is the current process UID and on Windows something else. - * No escaping is required, that is done in dbus-auth.c. + * Append to the string the identity we would like to have when we + * authenticate, on UNIX this is the current process UID and on + * Windows something else, probably a Windows SID string. No escaping + * is required, that is done in dbus-auth.c. The username here + * need not be anything human-readable, it can be the machine-readable + * form i.e. a user id. * * @param str the string to append to * @returns #FALSE on no memory */ dbus_bool_t -_dbus_append_desired_identity (DBusString *str) +_dbus_append_user_from_current_process (DBusString *str) { return _dbus_string_append_uint (str, _dbus_getuid ()); @@ -2939,4 +2943,81 @@ _dbus_flush_caches (void) _dbus_user_database_flush_system (); } +/** + * Appends the directory in which a keyring for the given credentials + * should be stored. The credentials should have either a Windows or + * UNIX user in them. The directory should be an absolute path. + * + * On UNIX the directory is ~/.dbus-keyrings while on Windows it should probably + * be something else, since the dotfile convention is not normal on Windows. + * + * @param directory string to append directory to + * @param credentials credentials the directory should be for + * + * @returns #FALSE on no memory + */ +dbus_bool_t +_dbus_append_keyring_directory_for_credentials (DBusString *directory, + DBusCredentials *credentials) +{ + DBusString homedir; + DBusString dotdir; + dbus_uid_t uid; + + _dbus_assert (credentials != NULL); + _dbus_assert (!_dbus_credentials_are_anonymous (credentials)); + + if (!_dbus_string_init (&homedir)) + return FALSE; + + uid = _dbus_credentials_get_unix_uid (credentials); + _dbus_assert (uid != DBUS_UID_UNSET); + + if (!_dbus_homedir_from_uid (uid, &homedir)) + goto failed; + +#ifdef DBUS_BUILD_TESTS + { + const char *override; + + override = _dbus_getenv ("DBUS_TEST_HOMEDIR"); + if (override != NULL && *override != '\0') + { + _dbus_string_set_length (&homedir, 0); + if (!_dbus_string_append (&homedir, override)) + goto failed; + + _dbus_verbose ("Using fake homedir for testing: %s\n", + _dbus_string_get_const_data (&homedir)); + } + else + { + static dbus_bool_t already_warned = FALSE; + if (!already_warned) + { + _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n"); + already_warned = TRUE; + } + } + } +#endif + + _dbus_string_init_const (&dotdir, ".dbus-keyrings"); + if (!_dbus_concat_dir_and_file (&homedir, + &dotdir)) + goto failed; + + if (!_dbus_string_copy (&homedir, 0, + directory, _dbus_string_get_length (directory))) { + goto failed; + } + + _dbus_string_free (&homedir); + return TRUE; + + failed: + _dbus_string_free (&homedir); + return FALSE; +} + /* tests in dbus-sysdeps-util.c */ diff --git a/dbus/dbus-sysdeps.h b/dbus/dbus-sysdeps.h index 0cb92c61..aebf50c6 100644 --- a/dbus/dbus-sysdeps.h +++ b/dbus/dbus-sysdeps.h @@ -165,15 +165,10 @@ dbus_bool_t _dbus_send_credentials_socket (int server_fd, dbus_bool_t _dbus_credentials_add_from_username (DBusCredentials *credentials, const DBusString *username); dbus_bool_t _dbus_credentials_add_from_current_process (DBusCredentials *credentials); -dbus_bool_t _dbus_credentials_parse_and_add_desired (DBusCredentials *credentials, +dbus_bool_t _dbus_credentials_parse_and_add_user (DBusCredentials *credentials, const DBusString *desired_identity); +dbus_bool_t _dbus_append_user_from_current_process (DBusString *str); -dbus_bool_t _dbus_username_from_current_process (const DBusString **username); -dbus_bool_t _dbus_append_desired_identity (DBusString *str); - -dbus_bool_t _dbus_homedir_from_current_process (const DBusString **homedir); -dbus_bool_t _dbus_homedir_from_username (const DBusString *username, - DBusString *homedir); dbus_bool_t _dbus_parse_unix_user_from_config (const DBusString *username, dbus_uid_t *uid_p); dbus_bool_t _dbus_parse_unix_group_from_config (const DBusString *groupname, @@ -186,6 +181,8 @@ dbus_bool_t _dbus_unix_user_is_at_console (dbus_uid_t uid, dbus_bool_t _dbus_unix_user_is_process_owner (dbus_uid_t uid); dbus_bool_t _dbus_windows_user_is_process_owner (const char *windows_sid); +dbus_bool_t _dbus_append_keyring_directory_for_credentials (DBusString *directory, + DBusCredentials *credentials); /** Opaque type representing an atomically-modifiable integer * that can be used from multiple threads. diff --git a/dbus/dbus-userdb.c b/dbus/dbus-userdb.c index 46e2275a..75475999 100644 --- a/dbus/dbus-userdb.c +++ b/dbus/dbus-userdb.c @@ -436,6 +436,45 @@ _dbus_homedir_from_username (const DBusString *username, } /** + * Gets the home directory for the given user. + * + * @param uid the uid + * @param homedir string to append home directory to + * @returns #TRUE if user existed and we appended their homedir + */ +dbus_bool_t +_dbus_homedir_from_uid (dbus_uid_t uid, + DBusString *homedir) +{ + DBusUserDatabase *db; + const DBusUserInfo *info; + _dbus_user_database_lock_system (); + + db = _dbus_user_database_get_system (); + if (db == NULL) + { + _dbus_user_database_unlock_system (); + return FALSE; + } + + if (!_dbus_user_database_get_uid (db, uid, + &info, NULL)) + { + _dbus_user_database_unlock_system (); + return FALSE; + } + + if (!_dbus_string_append (homedir, info->homedir)) + { + _dbus_user_database_unlock_system (); + return FALSE; + } + + _dbus_user_database_unlock_system (); + return TRUE; +} + +/** * Adds the credentials corresponding to the given username. * * @param credentials credentials to fill in diff --git a/dbus/dbus-userdb.h b/dbus/dbus-userdb.h index 4fae6f02..c9e66bc2 100644 --- a/dbus/dbus-userdb.h +++ b/dbus/dbus-userdb.h @@ -108,6 +108,13 @@ dbus_bool_t _dbus_is_console_user (dbus_uid_t uid, dbus_bool_t _dbus_is_a_number (const DBusString *str, unsigned long *num); +dbus_bool_t _dbus_username_from_current_process (const DBusString **username); +dbus_bool_t _dbus_homedir_from_current_process (const DBusString **homedir); +dbus_bool_t _dbus_homedir_from_username (const DBusString *username, + DBusString *homedir); + +dbus_bool_t _dbus_homedir_from_uid (dbus_uid_t uid, + DBusString *homedir); DBUS_END_DECLS |