D-Bus 1.4.10
|
00001 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ 00002 /* dbus-userdb-util.c Would be in dbus-userdb.c, but not used in libdbus 00003 * 00004 * Copyright (C) 2003, 2004, 2005 Red Hat, Inc. 00005 * 00006 * Licensed under the Academic Free License version 2.1 00007 * 00008 * This program is free software; you can redistribute it and/or modify 00009 * it under the terms of the GNU General Public License as published by 00010 * the Free Software Foundation; either version 2 of the License, or 00011 * (at your option) any later version. 00012 * 00013 * This program is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * GNU General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU General Public License 00019 * along with this program; if not, write to the Free Software 00020 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 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 /* HAVE_CONSOLE_OWNER_FILE */ 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 /* TPTD: this should be cache-safe, we've locked the DB and 00091 _dbus_user_at_console doesn't pass it on. */ 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 /* See if the group is really a number */ 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 /* don't use these past here */ 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 /* DBUS_BUILD_TESTS */