00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <config.h>
00024 #define DBUS_USERDB_INCLUDES_PRIVATE 1
00025 #include "dbus-userdb.h"
00026 #include "dbus-test.h"
00027 #include "dbus-internals.h"
00028 #include "dbus-protocol.h"
00029 #include <string.h>
00030
00031 #if HAVE_SYSTEMD
00032 #include <systemd/sd-daemon.h>
00033 #include <systemd/sd-login.h>
00034 #endif
00035
00048 dbus_bool_t
00049 _dbus_is_console_user (dbus_uid_t uid,
00050 DBusError *error)
00051 {
00052
00053 DBusUserDatabase *db;
00054 const DBusUserInfo *info;
00055 dbus_bool_t result = FALSE;
00056
00057 #ifdef HAVE_SYSTEMD
00058 if (sd_booted () > 0)
00059 {
00060 int r;
00061
00062
00063
00064 r = sd_uid_get_seats (uid, 0, NULL);
00065 if (r < 0)
00066 {
00067 dbus_set_error (error, _dbus_error_from_errno (-r),
00068 "Failed to determine seats of user \"" DBUS_UID_FORMAT "\": %s",
00069 uid,
00070 _dbus_strerror (-r));
00071 return FALSE;
00072 }
00073
00074 return (r > 0);
00075 }
00076 #endif
00077
00078 #ifdef HAVE_CONSOLE_OWNER_FILE
00079
00080 DBusString f;
00081 DBusStat st;
00082
00083 if (!_dbus_string_init (&f))
00084 {
00085 _DBUS_SET_OOM (error);
00086 return FALSE;
00087 }
00088
00089 if (!_dbus_string_append(&f, DBUS_CONSOLE_OWNER_FILE))
00090 {
00091 _dbus_string_free(&f);
00092 _DBUS_SET_OOM (error);
00093 return FALSE;
00094 }
00095
00096 if (_dbus_stat(&f, &st, NULL) && (st.uid == uid))
00097 {
00098 _dbus_string_free(&f);
00099 return TRUE;
00100 }
00101
00102 _dbus_string_free(&f);
00103
00104 #endif
00105
00106 _dbus_user_database_lock_system ();
00107
00108 db = _dbus_user_database_get_system ();
00109 if (db == NULL)
00110 {
00111 dbus_set_error (error, DBUS_ERROR_FAILED, "Could not get system database.");
00112 _dbus_user_database_unlock_system ();
00113 return FALSE;
00114 }
00115
00116
00117
00118 info = _dbus_user_database_lookup (db, uid, NULL, error);
00119
00120 if (info == NULL)
00121 {
00122 _dbus_user_database_unlock_system ();
00123 return FALSE;
00124 }
00125
00126 result = _dbus_user_at_console (info->username, error);
00127
00128 _dbus_user_database_unlock_system ();
00129
00130 return result;
00131 }
00132
00140 dbus_bool_t
00141 _dbus_get_user_id (const DBusString *username,
00142 dbus_uid_t *uid)
00143 {
00144 return _dbus_get_user_id_and_primary_group (username, uid, NULL);
00145 }
00146
00154 dbus_bool_t
00155 _dbus_get_group_id (const DBusString *groupname,
00156 dbus_gid_t *gid)
00157 {
00158 DBusUserDatabase *db;
00159 const DBusGroupInfo *info;
00160 _dbus_user_database_lock_system ();
00161
00162 db = _dbus_user_database_get_system ();
00163 if (db == NULL)
00164 {
00165 _dbus_user_database_unlock_system ();
00166 return FALSE;
00167 }
00168
00169 if (!_dbus_user_database_get_groupname (db, groupname,
00170 &info, NULL))
00171 {
00172 _dbus_user_database_unlock_system ();
00173 return FALSE;
00174 }
00175
00176 *gid = info->gid;
00177
00178 _dbus_user_database_unlock_system ();
00179 return TRUE;
00180 }
00181
00190 dbus_bool_t
00191 _dbus_get_user_id_and_primary_group (const DBusString *username,
00192 dbus_uid_t *uid_p,
00193 dbus_gid_t *gid_p)
00194 {
00195 DBusUserDatabase *db;
00196 const DBusUserInfo *info;
00197 _dbus_user_database_lock_system ();
00198
00199 db = _dbus_user_database_get_system ();
00200 if (db == NULL)
00201 {
00202 _dbus_user_database_unlock_system ();
00203 return FALSE;
00204 }
00205
00206 if (!_dbus_user_database_get_username (db, username,
00207 &info, NULL))
00208 {
00209 _dbus_user_database_unlock_system ();
00210 return FALSE;
00211 }
00212
00213 if (uid_p)
00214 *uid_p = info->uid;
00215 if (gid_p)
00216 *gid_p = info->primary_gid;
00217
00218 _dbus_user_database_unlock_system ();
00219 return TRUE;
00220 }
00221
00234 DBusGroupInfo*
00235 _dbus_user_database_lookup_group (DBusUserDatabase *db,
00236 dbus_gid_t gid,
00237 const DBusString *groupname,
00238 DBusError *error)
00239 {
00240 DBusGroupInfo *info;
00241
00242 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00243
00244
00245 if (gid == DBUS_UID_UNSET)
00246 {
00247 unsigned long n;
00248
00249 if (_dbus_is_a_number (groupname, &n))
00250 gid = n;
00251 }
00252
00253 #ifdef DBUS_ENABLE_USERDB_CACHE
00254 if (gid != DBUS_GID_UNSET)
00255 info = _dbus_hash_table_lookup_uintptr (db->groups, gid);
00256 else
00257 info = _dbus_hash_table_lookup_string (db->groups_by_name,
00258 _dbus_string_get_const_data (groupname));
00259 if (info)
00260 {
00261 _dbus_verbose ("Using cache for GID "DBUS_GID_FORMAT" information\n",
00262 info->gid);
00263 return info;
00264 }
00265 else
00266 #else
00267 if (1)
00268 #endif
00269 {
00270 if (gid != DBUS_GID_UNSET)
00271 _dbus_verbose ("No cache for GID "DBUS_GID_FORMAT"\n",
00272 gid);
00273 else
00274 _dbus_verbose ("No cache for groupname \"%s\"\n",
00275 _dbus_string_get_const_data (groupname));
00276
00277 info = dbus_new0 (DBusGroupInfo, 1);
00278 if (info == NULL)
00279 {
00280 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00281 return NULL;
00282 }
00283
00284 if (gid != DBUS_GID_UNSET)
00285 {
00286 if (!_dbus_group_info_fill_gid (info, gid, error))
00287 {
00288 _DBUS_ASSERT_ERROR_IS_SET (error);
00289 _dbus_group_info_free_allocated (info);
00290 return NULL;
00291 }
00292 }
00293 else
00294 {
00295 if (!_dbus_group_info_fill (info, groupname, error))
00296 {
00297 _DBUS_ASSERT_ERROR_IS_SET (error);
00298 _dbus_group_info_free_allocated (info);
00299 return NULL;
00300 }
00301 }
00302
00303
00304 gid = DBUS_GID_UNSET;
00305 groupname = NULL;
00306
00307 if (!_dbus_hash_table_insert_uintptr (db->groups, info->gid, info))
00308 {
00309 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00310 _dbus_group_info_free_allocated (info);
00311 return NULL;
00312 }
00313
00314
00315 if (!_dbus_hash_table_insert_string (db->groups_by_name,
00316 info->groupname,
00317 info))
00318 {
00319 _dbus_hash_table_remove_uintptr (db->groups, info->gid);
00320 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00321 return NULL;
00322 }
00323
00324 return info;
00325 }
00326 }
00327
00328
00339 dbus_bool_t
00340 _dbus_user_database_get_groupname (DBusUserDatabase *db,
00341 const DBusString *groupname,
00342 const DBusGroupInfo **info,
00343 DBusError *error)
00344 {
00345 *info = _dbus_user_database_lookup_group (db, DBUS_GID_UNSET, groupname, error);
00346 return *info != NULL;
00347 }
00348
00359 dbus_bool_t
00360 _dbus_user_database_get_gid (DBusUserDatabase *db,
00361 dbus_gid_t gid,
00362 const DBusGroupInfo **info,
00363 DBusError *error)
00364 {
00365 *info = _dbus_user_database_lookup_group (db, gid, NULL, error);
00366 return *info != NULL;
00367 }
00368
00369
00380 dbus_bool_t
00381 _dbus_groups_from_uid (dbus_uid_t uid,
00382 dbus_gid_t **group_ids,
00383 int *n_group_ids)
00384 {
00385 DBusUserDatabase *db;
00386 const DBusUserInfo *info;
00387 *group_ids = NULL;
00388 *n_group_ids = 0;
00389
00390 _dbus_user_database_lock_system ();
00391
00392 db = _dbus_user_database_get_system ();
00393 if (db == NULL)
00394 {
00395 _dbus_user_database_unlock_system ();
00396 return FALSE;
00397 }
00398
00399 if (!_dbus_user_database_get_uid (db, uid,
00400 &info, NULL))
00401 {
00402 _dbus_user_database_unlock_system ();
00403 return FALSE;
00404 }
00405
00406 _dbus_assert (info->uid == uid);
00407
00408 if (info->n_group_ids > 0)
00409 {
00410 *group_ids = dbus_new (dbus_gid_t, info->n_group_ids);
00411 if (*group_ids == NULL)
00412 {
00413 _dbus_user_database_unlock_system ();
00414 return FALSE;
00415 }
00416
00417 *n_group_ids = info->n_group_ids;
00418
00419 memcpy (*group_ids, info->group_ids, info->n_group_ids * sizeof (dbus_gid_t));
00420 }
00421
00422 _dbus_user_database_unlock_system ();
00423 return TRUE;
00424 }
00427 #ifdef DBUS_BUILD_TESTS
00428 #include <stdio.h>
00429
00435 dbus_bool_t
00436 _dbus_userdb_test (const char *test_data_dir)
00437 {
00438 const DBusString *username;
00439 const DBusString *homedir;
00440 dbus_uid_t uid;
00441 unsigned long *group_ids;
00442 int n_group_ids, i;
00443 DBusError error;
00444
00445 if (!_dbus_username_from_current_process (&username))
00446 _dbus_assert_not_reached ("didn't get username");
00447
00448 if (!_dbus_homedir_from_current_process (&homedir))
00449 _dbus_assert_not_reached ("didn't get homedir");
00450
00451 if (!_dbus_get_user_id (username, &uid))
00452 _dbus_assert_not_reached ("didn't get uid");
00453
00454 if (!_dbus_groups_from_uid (uid, &group_ids, &n_group_ids))
00455 _dbus_assert_not_reached ("didn't get groups");
00456
00457 printf (" Current user: %s homedir: %s gids:",
00458 _dbus_string_get_const_data (username),
00459 _dbus_string_get_const_data (homedir));
00460
00461 for (i=0; i<n_group_ids; i++)
00462 printf(" %ld", group_ids[i]);
00463
00464 printf ("\n");
00465
00466 dbus_error_init (&error);
00467 printf ("Is Console user: %i\n",
00468 _dbus_is_console_user (uid, &error));
00469 printf ("Invocation was OK: %s\n", error.message ? error.message : "yes");
00470 dbus_error_free (&error);
00471 printf ("Is Console user 4711: %i\n",
00472 _dbus_is_console_user (4711, &error));
00473 printf ("Invocation was OK: %s\n", error.message ? error.message : "yes");
00474 dbus_error_free (&error);
00475
00476 dbus_free (group_ids);
00477
00478 return TRUE;
00479 }
00480 #endif