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