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 #include <unistd.h>
00025 #define DBUS_USERDB_INCLUDES_PRIVATE 1
00026 #include "dbus-userdb.h"
00027 #include "dbus-test.h"
00028 #include "dbus-internals.h"
00029 #include "dbus-protocol.h"
00030 #include <string.h>
00031
00032 #if HAVE_SYSTEMD
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
00059 if (access ("/run/systemd/seats/", F_OK) >= 0)
00060 {
00061 int r;
00062
00063
00064
00065 r = sd_uid_get_seats (uid, 0, NULL);
00066 if (r < 0)
00067 {
00068 dbus_set_error (error, _dbus_error_from_errno (-r),
00069 "Failed to determine seats of user \"" DBUS_UID_FORMAT "\": %s",
00070 uid,
00071 _dbus_strerror (-r));
00072 return FALSE;
00073 }
00074
00075 return (r > 0);
00076 }
00077 #endif
00078
00079 #ifdef HAVE_CONSOLE_OWNER_FILE
00080
00081 DBusString f;
00082 DBusStat st;
00083
00084 if (!_dbus_string_init (&f))
00085 {
00086 _DBUS_SET_OOM (error);
00087 return FALSE;
00088 }
00089
00090 if (!_dbus_string_append(&f, DBUS_CONSOLE_OWNER_FILE))
00091 {
00092 _dbus_string_free(&f);
00093 _DBUS_SET_OOM (error);
00094 return FALSE;
00095 }
00096
00097 if (_dbus_stat(&f, &st, NULL) && (st.uid == uid))
00098 {
00099 _dbus_string_free(&f);
00100 return TRUE;
00101 }
00102
00103 _dbus_string_free(&f);
00104
00105 #endif
00106
00107 if (!_dbus_user_database_lock_system ())
00108 {
00109 _DBUS_SET_OOM (error);
00110 return FALSE;
00111 }
00112
00113 db = _dbus_user_database_get_system ();
00114 if (db == NULL)
00115 {
00116 dbus_set_error (error, DBUS_ERROR_FAILED, "Could not get system database.");
00117 _dbus_user_database_unlock_system ();
00118 return FALSE;
00119 }
00120
00121
00122
00123 info = _dbus_user_database_lookup (db, uid, NULL, error);
00124
00125 if (info == NULL)
00126 {
00127 _dbus_user_database_unlock_system ();
00128 return FALSE;
00129 }
00130
00131 result = _dbus_user_at_console (info->username, error);
00132
00133 _dbus_user_database_unlock_system ();
00134
00135 return result;
00136 }
00137
00145 dbus_bool_t
00146 _dbus_get_user_id (const DBusString *username,
00147 dbus_uid_t *uid)
00148 {
00149 return _dbus_get_user_id_and_primary_group (username, uid, NULL);
00150 }
00151
00159 dbus_bool_t
00160 _dbus_get_group_id (const DBusString *groupname,
00161 dbus_gid_t *gid)
00162 {
00163 DBusUserDatabase *db;
00164 const DBusGroupInfo *info;
00165
00166
00167 if (!_dbus_user_database_lock_system ())
00168 return FALSE;
00169
00170 db = _dbus_user_database_get_system ();
00171 if (db == NULL)
00172 {
00173 _dbus_user_database_unlock_system ();
00174 return FALSE;
00175 }
00176
00177 if (!_dbus_user_database_get_groupname (db, groupname,
00178 &info, NULL))
00179 {
00180 _dbus_user_database_unlock_system ();
00181 return FALSE;
00182 }
00183
00184 *gid = info->gid;
00185
00186 _dbus_user_database_unlock_system ();
00187 return TRUE;
00188 }
00189
00198 dbus_bool_t
00199 _dbus_get_user_id_and_primary_group (const DBusString *username,
00200 dbus_uid_t *uid_p,
00201 dbus_gid_t *gid_p)
00202 {
00203 DBusUserDatabase *db;
00204 const DBusUserInfo *info;
00205
00206
00207 if (!_dbus_user_database_lock_system ())
00208 return FALSE;
00209
00210 db = _dbus_user_database_get_system ();
00211 if (db == NULL)
00212 {
00213 _dbus_user_database_unlock_system ();
00214 return FALSE;
00215 }
00216
00217 if (!_dbus_user_database_get_username (db, username,
00218 &info, NULL))
00219 {
00220 _dbus_user_database_unlock_system ();
00221 return FALSE;
00222 }
00223
00224 if (uid_p)
00225 *uid_p = info->uid;
00226 if (gid_p)
00227 *gid_p = info->primary_gid;
00228
00229 _dbus_user_database_unlock_system ();
00230 return TRUE;
00231 }
00232
00245 DBusGroupInfo*
00246 _dbus_user_database_lookup_group (DBusUserDatabase *db,
00247 dbus_gid_t gid,
00248 const DBusString *groupname,
00249 DBusError *error)
00250 {
00251 DBusGroupInfo *info;
00252
00253 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00254
00255
00256 if (gid == DBUS_UID_UNSET)
00257 {
00258 unsigned long n;
00259
00260 if (_dbus_is_a_number (groupname, &n))
00261 gid = n;
00262 }
00263
00264 if (gid != DBUS_GID_UNSET)
00265 info = _dbus_hash_table_lookup_uintptr (db->groups, gid);
00266 else
00267 info = _dbus_hash_table_lookup_string (db->groups_by_name,
00268 _dbus_string_get_const_data (groupname));
00269 if (info)
00270 {
00271 _dbus_verbose ("Using cache for GID "DBUS_GID_FORMAT" information\n",
00272 info->gid);
00273 return info;
00274 }
00275 else
00276 {
00277 if (gid != DBUS_GID_UNSET)
00278 _dbus_verbose ("No cache for GID "DBUS_GID_FORMAT"\n",
00279 gid);
00280 else
00281 _dbus_verbose ("No cache for groupname \"%s\"\n",
00282 _dbus_string_get_const_data (groupname));
00283
00284 info = dbus_new0 (DBusGroupInfo, 1);
00285 if (info == NULL)
00286 {
00287 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00288 return NULL;
00289 }
00290
00291 if (gid != DBUS_GID_UNSET)
00292 {
00293 if (!_dbus_group_info_fill_gid (info, gid, error))
00294 {
00295 _DBUS_ASSERT_ERROR_IS_SET (error);
00296 _dbus_group_info_free_allocated (info);
00297 return NULL;
00298 }
00299 }
00300 else
00301 {
00302 if (!_dbus_group_info_fill (info, groupname, error))
00303 {
00304 _DBUS_ASSERT_ERROR_IS_SET (error);
00305 _dbus_group_info_free_allocated (info);
00306 return NULL;
00307 }
00308 }
00309
00310
00311 gid = DBUS_GID_UNSET;
00312 groupname = NULL;
00313
00314 if (!_dbus_hash_table_insert_uintptr (db->groups, info->gid, info))
00315 {
00316 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00317 _dbus_group_info_free_allocated (info);
00318 return NULL;
00319 }
00320
00321
00322 if (!_dbus_hash_table_insert_string (db->groups_by_name,
00323 info->groupname,
00324 info))
00325 {
00326 _dbus_hash_table_remove_uintptr (db->groups, info->gid);
00327 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00328 return NULL;
00329 }
00330
00331 return info;
00332 }
00333 }
00334
00335
00346 dbus_bool_t
00347 _dbus_user_database_get_groupname (DBusUserDatabase *db,
00348 const DBusString *groupname,
00349 const DBusGroupInfo **info,
00350 DBusError *error)
00351 {
00352 *info = _dbus_user_database_lookup_group (db, DBUS_GID_UNSET, groupname, error);
00353 return *info != NULL;
00354 }
00355
00366 dbus_bool_t
00367 _dbus_user_database_get_gid (DBusUserDatabase *db,
00368 dbus_gid_t gid,
00369 const DBusGroupInfo **info,
00370 DBusError *error)
00371 {
00372 *info = _dbus_user_database_lookup_group (db, gid, NULL, error);
00373 return *info != NULL;
00374 }
00375
00376
00387 dbus_bool_t
00388 _dbus_groups_from_uid (dbus_uid_t uid,
00389 dbus_gid_t **group_ids,
00390 int *n_group_ids)
00391 {
00392 DBusUserDatabase *db;
00393 const DBusUserInfo *info;
00394 *group_ids = NULL;
00395 *n_group_ids = 0;
00396
00397
00398 if (!_dbus_user_database_lock_system ())
00399 return FALSE;
00400
00401 db = _dbus_user_database_get_system ();
00402 if (db == NULL)
00403 {
00404 _dbus_user_database_unlock_system ();
00405 return FALSE;
00406 }
00407
00408 if (!_dbus_user_database_get_uid (db, uid,
00409 &info, NULL))
00410 {
00411 _dbus_user_database_unlock_system ();
00412 return FALSE;
00413 }
00414
00415 _dbus_assert (info->uid == uid);
00416
00417 if (info->n_group_ids > 0)
00418 {
00419 *group_ids = dbus_new (dbus_gid_t, info->n_group_ids);
00420 if (*group_ids == NULL)
00421 {
00422 _dbus_user_database_unlock_system ();
00423 return FALSE;
00424 }
00425
00426 *n_group_ids = info->n_group_ids;
00427
00428 memcpy (*group_ids, info->group_ids, info->n_group_ids * sizeof (dbus_gid_t));
00429 }
00430
00431 _dbus_user_database_unlock_system ();
00432 return TRUE;
00433 }
00436 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
00437 #include <stdio.h>
00438
00444 dbus_bool_t
00445 _dbus_userdb_test (const char *test_data_dir)
00446 {
00447 const DBusString *username;
00448 const DBusString *homedir;
00449 dbus_uid_t uid;
00450 unsigned long *group_ids;
00451 int n_group_ids, i;
00452 DBusError error;
00453
00454 if (!_dbus_username_from_current_process (&username))
00455 _dbus_assert_not_reached ("didn't get username");
00456
00457 if (!_dbus_homedir_from_current_process (&homedir))
00458 _dbus_assert_not_reached ("didn't get homedir");
00459
00460 if (!_dbus_get_user_id (username, &uid))
00461 _dbus_assert_not_reached ("didn't get uid");
00462
00463 if (!_dbus_groups_from_uid (uid, &group_ids, &n_group_ids))
00464 _dbus_assert_not_reached ("didn't get groups");
00465
00466 printf (" Current user: %s homedir: %s gids:",
00467 _dbus_string_get_const_data (username),
00468 _dbus_string_get_const_data (homedir));
00469
00470 for (i=0; i<n_group_ids; i++)
00471 printf(" %ld", group_ids[i]);
00472
00473 printf ("\n");
00474
00475 dbus_error_init (&error);
00476 printf ("Is Console user: %i\n",
00477 _dbus_is_console_user (uid, &error));
00478 printf ("Invocation was OK: %s\n", error.message ? error.message : "yes");
00479 dbus_error_free (&error);
00480 printf ("Is Console user 4711: %i\n",
00481 _dbus_is_console_user (4711, &error));
00482 printf ("Invocation was OK: %s\n", error.message ? error.message : "yes");
00483 dbus_error_free (&error);
00484
00485 dbus_free (group_ids);
00486
00487 return TRUE;
00488 }
00489 #endif