00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #define DBUS_USERDB_INCLUDES_PRIVATE 1
00024 #include "dbus-userdb.h"
00025 #include "dbus-test.h"
00026 #include "dbus-internals.h"
00027 #include "dbus-protocol.h"
00028 #include <string.h>
00029
00042 dbus_bool_t
00043 _dbus_is_console_user (dbus_uid_t uid,
00044 DBusError *error)
00045 {
00046
00047 DBusUserDatabase *db;
00048 const DBusUserInfo *info;
00049 dbus_bool_t result = FALSE;
00050
00051 #ifdef HAVE_CONSOLE_OWNER_FILE
00052
00053 DBusString f;
00054 DBusStat st;
00055
00056 if (!_dbus_string_init (&f))
00057 {
00058 _DBUS_SET_OOM (error);
00059 return FALSE;
00060 }
00061
00062 if (!_dbus_string_append(&f, DBUS_CONSOLE_OWNER_FILE))
00063 {
00064 _dbus_string_free(&f);
00065 _DBUS_SET_OOM (error);
00066 return FALSE;
00067 }
00068
00069 if (_dbus_stat(&f, &st, NULL) && (st.uid == uid))
00070 {
00071 _dbus_string_free(&f);
00072 return TRUE;
00073 }
00074
00075 _dbus_string_free(&f);
00076
00077 #endif
00078
00079 _dbus_user_database_lock_system ();
00080
00081 db = _dbus_user_database_get_system ();
00082 if (db == NULL)
00083 {
00084 dbus_set_error (error, DBUS_ERROR_FAILED, "Could not get system database.");
00085 _dbus_user_database_unlock_system ();
00086 return FALSE;
00087 }
00088
00089 info = _dbus_user_database_lookup (db, uid, NULL, error);
00090
00091 if (info == NULL)
00092 {
00093 _dbus_user_database_unlock_system ();
00094 return FALSE;
00095 }
00096
00097 result = _dbus_user_at_console (info->username, error);
00098
00099 _dbus_user_database_unlock_system ();
00100
00101 return result;
00102 }
00103
00104
00112 dbus_bool_t
00113 _dbus_credentials_from_uid (dbus_uid_t uid,
00114 DBusCredentials *credentials)
00115 {
00116 DBusUserDatabase *db;
00117 const DBusUserInfo *info;
00118 _dbus_user_database_lock_system ();
00119
00120 db = _dbus_user_database_get_system ();
00121 if (db == NULL)
00122 {
00123 _dbus_user_database_unlock_system ();
00124 return FALSE;
00125 }
00126
00127 if (!_dbus_user_database_get_uid (db, uid,
00128 &info, NULL))
00129 {
00130 _dbus_user_database_unlock_system ();
00131 return FALSE;
00132 }
00133
00134 _dbus_assert (info->uid == uid);
00135
00136 credentials->pid = DBUS_PID_UNSET;
00137 credentials->uid = info->uid;
00138 credentials->gid = info->primary_gid;
00139
00140 _dbus_user_database_unlock_system ();
00141 return TRUE;
00142 }
00143
00144
00152 dbus_bool_t
00153 _dbus_get_user_id (const DBusString *username,
00154 dbus_uid_t *uid)
00155 {
00156 DBusCredentials creds;
00157
00158 if (!_dbus_credentials_from_username (username, &creds))
00159 return FALSE;
00160
00161 if (creds.uid == DBUS_UID_UNSET)
00162 return FALSE;
00163
00164 *uid = creds.uid;
00165
00166 return TRUE;
00167 }
00168
00176 dbus_bool_t
00177 _dbus_get_group_id (const DBusString *groupname,
00178 dbus_gid_t *gid)
00179 {
00180 DBusUserDatabase *db;
00181 const DBusGroupInfo *info;
00182 _dbus_user_database_lock_system ();
00183
00184 db = _dbus_user_database_get_system ();
00185 if (db == NULL)
00186 {
00187 _dbus_user_database_unlock_system ();
00188 return FALSE;
00189 }
00190
00191 if (!_dbus_user_database_get_groupname (db, groupname,
00192 &info, NULL))
00193 {
00194 _dbus_user_database_unlock_system ();
00195 return FALSE;
00196 }
00197
00198 *gid = info->gid;
00199
00200 _dbus_user_database_unlock_system ();
00201 return TRUE;
00202 }
00203
00216 DBusGroupInfo*
00217 _dbus_user_database_lookup_group (DBusUserDatabase *db,
00218 dbus_gid_t gid,
00219 const DBusString *groupname,
00220 DBusError *error)
00221 {
00222 DBusGroupInfo *info;
00223
00224 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00225
00226
00227 if (gid == DBUS_UID_UNSET)
00228 {
00229 unsigned long n;
00230
00231 if (_dbus_is_a_number (groupname, &n))
00232 gid = n;
00233 }
00234
00235
00236 if (gid != DBUS_GID_UNSET)
00237 info = _dbus_hash_table_lookup_ulong (db->groups, gid);
00238 else
00239 info = _dbus_hash_table_lookup_string (db->groups_by_name,
00240 _dbus_string_get_const_data (groupname));
00241 if (info)
00242 {
00243 _dbus_verbose ("Using cache for GID "DBUS_GID_FORMAT" information\n",
00244 info->gid);
00245 return info;
00246 }
00247 else
00248 {
00249 if (gid != DBUS_GID_UNSET)
00250 _dbus_verbose ("No cache for GID "DBUS_GID_FORMAT"\n",
00251 gid);
00252 else
00253 _dbus_verbose ("No cache for groupname \"%s\"\n",
00254 _dbus_string_get_const_data (groupname));
00255
00256 info = dbus_new0 (DBusGroupInfo, 1);
00257 if (info == NULL)
00258 {
00259 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00260 return NULL;
00261 }
00262
00263 if (gid != DBUS_GID_UNSET)
00264 {
00265 if (!_dbus_group_info_fill_gid (info, gid, error))
00266 {
00267 _DBUS_ASSERT_ERROR_IS_SET (error);
00268 _dbus_group_info_free_allocated (info);
00269 return NULL;
00270 }
00271 }
00272 else
00273 {
00274 if (!_dbus_group_info_fill (info, groupname, error))
00275 {
00276 _DBUS_ASSERT_ERROR_IS_SET (error);
00277 _dbus_group_info_free_allocated (info);
00278 return NULL;
00279 }
00280 }
00281
00282
00283 gid = DBUS_GID_UNSET;
00284 groupname = NULL;
00285
00286 if (!_dbus_hash_table_insert_ulong (db->groups, info->gid, info))
00287 {
00288 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00289 _dbus_group_info_free_allocated (info);
00290 return NULL;
00291 }
00292
00293
00294 if (!_dbus_hash_table_insert_string (db->groups_by_name,
00295 info->groupname,
00296 info))
00297 {
00298 _dbus_hash_table_remove_ulong (db->groups, info->gid);
00299 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00300 return NULL;
00301 }
00302
00303 return info;
00304 }
00305 }
00306
00307
00318 dbus_bool_t
00319 _dbus_user_database_get_groupname (DBusUserDatabase *db,
00320 const DBusString *groupname,
00321 const DBusGroupInfo **info,
00322 DBusError *error)
00323 {
00324 *info = _dbus_user_database_lookup_group (db, DBUS_GID_UNSET, groupname, error);
00325 return *info != NULL;
00326 }
00327
00338 dbus_bool_t
00339 _dbus_user_database_get_gid (DBusUserDatabase *db,
00340 dbus_gid_t gid,
00341 const DBusGroupInfo **info,
00342 DBusError *error)
00343 {
00344 *info = _dbus_user_database_lookup_group (db, gid, NULL, error);
00345 return *info != NULL;
00346 }
00347
00348
00362 dbus_bool_t
00363 _dbus_user_database_get_groups (DBusUserDatabase *db,
00364 dbus_uid_t uid,
00365 dbus_gid_t **group_ids,
00366 int *n_group_ids,
00367 DBusError *error)
00368 {
00369 DBusUserInfo *info;
00370
00371 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00372
00373 *group_ids = NULL;
00374 *n_group_ids = 0;
00375
00376 info = _dbus_user_database_lookup (db, uid, NULL, error);
00377 if (info == NULL)
00378 {
00379 _DBUS_ASSERT_ERROR_IS_SET (error);
00380 return FALSE;
00381 }
00382
00383 if (info->n_group_ids > 0)
00384 {
00385 *group_ids = dbus_new (dbus_gid_t, info->n_group_ids);
00386 if (*group_ids == NULL)
00387 {
00388 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00389 return FALSE;
00390 }
00391
00392 *n_group_ids = info->n_group_ids;
00393
00394 memcpy (*group_ids, info->group_ids, info->n_group_ids * sizeof (dbus_gid_t));
00395 }
00396
00397 return TRUE;
00398 }
00399
00402 #ifdef DBUS_BUILD_TESTS
00403 #include <stdio.h>
00404
00410 dbus_bool_t
00411 _dbus_userdb_test (const char *test_data_dir)
00412 {
00413 const DBusString *username;
00414 const DBusString *homedir;
00415
00416 if (!_dbus_username_from_current_process (&username))
00417 _dbus_assert_not_reached ("didn't get username");
00418
00419 if (!_dbus_homedir_from_current_process (&homedir))
00420 _dbus_assert_not_reached ("didn't get homedir");
00421
00422 printf (" Current user: %s homedir: %s\n",
00423 _dbus_string_get_const_data (username),
00424 _dbus_string_get_const_data (homedir));
00425
00426 return TRUE;
00427 }
00428 #endif