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
00090
00091 info = _dbus_user_database_lookup (db, uid, NULL, error);
00092
00093 if (info == NULL)
00094 {
00095 _dbus_user_database_unlock_system ();
00096 return FALSE;
00097 }
00098
00099 result = _dbus_user_at_console (info->username, error);
00100
00101 _dbus_user_database_unlock_system ();
00102
00103 return result;
00104 }
00105
00113 dbus_bool_t
00114 _dbus_get_user_id (const DBusString *username,
00115 dbus_uid_t *uid)
00116 {
00117 return _dbus_get_user_id_and_primary_group (username, uid, NULL);
00118 }
00119
00127 dbus_bool_t
00128 _dbus_get_group_id (const DBusString *groupname,
00129 dbus_gid_t *gid)
00130 {
00131 DBusUserDatabase *db;
00132 const DBusGroupInfo *info;
00133 _dbus_user_database_lock_system ();
00134
00135 db = _dbus_user_database_get_system ();
00136 if (db == NULL)
00137 {
00138 _dbus_user_database_unlock_system ();
00139 return FALSE;
00140 }
00141
00142 if (!_dbus_user_database_get_groupname (db, groupname,
00143 &info, NULL))
00144 {
00145 _dbus_user_database_unlock_system ();
00146 return FALSE;
00147 }
00148
00149 *gid = info->gid;
00150
00151 _dbus_user_database_unlock_system ();
00152 return TRUE;
00153 }
00154
00163 dbus_bool_t
00164 _dbus_get_user_id_and_primary_group (const DBusString *username,
00165 dbus_uid_t *uid_p,
00166 dbus_gid_t *gid_p)
00167 {
00168 DBusUserDatabase *db;
00169 const DBusUserInfo *info;
00170 _dbus_user_database_lock_system ();
00171
00172 db = _dbus_user_database_get_system ();
00173 if (db == NULL)
00174 {
00175 _dbus_user_database_unlock_system ();
00176 return FALSE;
00177 }
00178
00179 if (!_dbus_user_database_get_username (db, username,
00180 &info, NULL))
00181 {
00182 _dbus_user_database_unlock_system ();
00183 return FALSE;
00184 }
00185
00186 if (uid_p)
00187 *uid_p = info->uid;
00188 if (gid_p)
00189 *gid_p = info->primary_gid;
00190
00191 _dbus_user_database_unlock_system ();
00192 return TRUE;
00193 }
00194
00207 DBusGroupInfo*
00208 _dbus_user_database_lookup_group (DBusUserDatabase *db,
00209 dbus_gid_t gid,
00210 const DBusString *groupname,
00211 DBusError *error)
00212 {
00213 DBusGroupInfo *info;
00214
00215 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00216
00217
00218 if (gid == DBUS_UID_UNSET)
00219 {
00220 unsigned long n;
00221
00222 if (_dbus_is_a_number (groupname, &n))
00223 gid = n;
00224 }
00225
00226 #ifdef DBUS_ENABLE_USERDB_CACHE
00227 if (gid != DBUS_GID_UNSET)
00228 info = _dbus_hash_table_lookup_ulong (db->groups, gid);
00229 else
00230 info = _dbus_hash_table_lookup_string (db->groups_by_name,
00231 _dbus_string_get_const_data (groupname));
00232 if (info)
00233 {
00234 _dbus_verbose ("Using cache for GID "DBUS_GID_FORMAT" information\n",
00235 info->gid);
00236 return info;
00237 }
00238 else
00239 #else
00240 if (1)
00241 #endif
00242 {
00243 if (gid != DBUS_GID_UNSET)
00244 _dbus_verbose ("No cache for GID "DBUS_GID_FORMAT"\n",
00245 gid);
00246 else
00247 _dbus_verbose ("No cache for groupname \"%s\"\n",
00248 _dbus_string_get_const_data (groupname));
00249
00250 info = dbus_new0 (DBusGroupInfo, 1);
00251 if (info == NULL)
00252 {
00253 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00254 return NULL;
00255 }
00256
00257 if (gid != DBUS_GID_UNSET)
00258 {
00259 if (!_dbus_group_info_fill_gid (info, gid, error))
00260 {
00261 _DBUS_ASSERT_ERROR_IS_SET (error);
00262 _dbus_group_info_free_allocated (info);
00263 return NULL;
00264 }
00265 }
00266 else
00267 {
00268 if (!_dbus_group_info_fill (info, groupname, error))
00269 {
00270 _DBUS_ASSERT_ERROR_IS_SET (error);
00271 _dbus_group_info_free_allocated (info);
00272 return NULL;
00273 }
00274 }
00275
00276
00277 gid = DBUS_GID_UNSET;
00278 groupname = NULL;
00279
00280 if (!_dbus_hash_table_insert_ulong (db->groups, info->gid, info))
00281 {
00282 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00283 _dbus_group_info_free_allocated (info);
00284 return NULL;
00285 }
00286
00287
00288 if (!_dbus_hash_table_insert_string (db->groups_by_name,
00289 info->groupname,
00290 info))
00291 {
00292 _dbus_hash_table_remove_ulong (db->groups, info->gid);
00293 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00294 return NULL;
00295 }
00296
00297 return info;
00298 }
00299 }
00300
00301
00312 dbus_bool_t
00313 _dbus_user_database_get_groupname (DBusUserDatabase *db,
00314 const DBusString *groupname,
00315 const DBusGroupInfo **info,
00316 DBusError *error)
00317 {
00318 *info = _dbus_user_database_lookup_group (db, DBUS_GID_UNSET, groupname, error);
00319 return *info != NULL;
00320 }
00321
00332 dbus_bool_t
00333 _dbus_user_database_get_gid (DBusUserDatabase *db,
00334 dbus_gid_t gid,
00335 const DBusGroupInfo **info,
00336 DBusError *error)
00337 {
00338 *info = _dbus_user_database_lookup_group (db, gid, NULL, error);
00339 return *info != NULL;
00340 }
00341
00342
00353 dbus_bool_t
00354 _dbus_groups_from_uid (dbus_uid_t uid,
00355 dbus_gid_t **group_ids,
00356 int *n_group_ids)
00357 {
00358 DBusUserDatabase *db;
00359 const DBusUserInfo *info;
00360 *group_ids = NULL;
00361 *n_group_ids = 0;
00362
00363 _dbus_user_database_lock_system ();
00364
00365 db = _dbus_user_database_get_system ();
00366 if (db == NULL)
00367 {
00368 _dbus_user_database_unlock_system ();
00369 return FALSE;
00370 }
00371
00372 if (!_dbus_user_database_get_uid (db, uid,
00373 &info, NULL))
00374 {
00375 _dbus_user_database_unlock_system ();
00376 return FALSE;
00377 }
00378
00379 _dbus_assert (info->uid == uid);
00380
00381 if (info->n_group_ids > 0)
00382 {
00383 *group_ids = dbus_new (dbus_gid_t, info->n_group_ids);
00384 if (*group_ids == NULL)
00385 {
00386 _dbus_user_database_unlock_system ();
00387 return FALSE;
00388 }
00389
00390 *n_group_ids = info->n_group_ids;
00391
00392 memcpy (*group_ids, info->group_ids, info->n_group_ids * sizeof (dbus_gid_t));
00393 }
00394
00395 _dbus_user_database_unlock_system ();
00396 return TRUE;
00397 }
00400 #ifdef DBUS_BUILD_TESTS
00401 #include <stdio.h>
00402
00408 dbus_bool_t
00409 _dbus_userdb_test (const char *test_data_dir)
00410 {
00411 const DBusString *username;
00412 const DBusString *homedir;
00413 dbus_uid_t uid;
00414 unsigned long *group_ids;
00415 int n_group_ids, i;
00416
00417 if (!_dbus_username_from_current_process (&username))
00418 _dbus_assert_not_reached ("didn't get username");
00419
00420 if (!_dbus_homedir_from_current_process (&homedir))
00421 _dbus_assert_not_reached ("didn't get homedir");
00422
00423 if (!_dbus_get_user_id (username, &uid))
00424 _dbus_assert_not_reached ("didn't get uid");
00425
00426 if (!_dbus_groups_from_uid (uid, &group_ids, &n_group_ids))
00427 _dbus_assert_not_reached ("didn't get groups");
00428
00429 printf (" Current user: %s homedir: %s gids:",
00430 _dbus_string_get_const_data (username),
00431 _dbus_string_get_const_data (homedir));
00432
00433 for (i=0; i<n_group_ids; i++)
00434 printf(" %ld", group_ids[i]);
00435
00436 printf ("\n");
00437
00438 dbus_free (group_ids);
00439
00440 return TRUE;
00441 }
00442 #endif