dbus-userdb-util.c

00001 /* -*- mode: C; c-file-style: "gnu" -*- */
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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 /* HAVE_CONSOLE_OWNER_FILE */
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   info = _dbus_user_database_lookup (db, uid, NULL, error);
00090 
00091   if (info == NULL)
00092     {
00093       _dbus_user_database_unlock_system ();
00094        return FALSE;
00095     }
00096 
00097   result = _dbus_user_at_console (info->username, error);
00098 
00099   _dbus_user_database_unlock_system ();
00100 
00101   return result;
00102 }
00103 
00104 
00112 dbus_bool_t
00113 _dbus_credentials_from_uid (dbus_uid_t        uid,
00114                             DBusCredentials  *credentials)
00115 {
00116   DBusUserDatabase *db;
00117   const DBusUserInfo *info;
00118   _dbus_user_database_lock_system ();
00119 
00120   db = _dbus_user_database_get_system ();
00121   if (db == NULL)
00122     {
00123       _dbus_user_database_unlock_system ();
00124       return FALSE;
00125     }
00126 
00127   if (!_dbus_user_database_get_uid (db, uid,
00128                                     &info, NULL))
00129     {
00130       _dbus_user_database_unlock_system ();
00131       return FALSE;
00132     }
00133 
00134   _dbus_assert (info->uid == uid);
00135   
00136   credentials->pid = DBUS_PID_UNSET;
00137   credentials->uid = info->uid;
00138   credentials->gid = info->primary_gid;
00139   
00140   _dbus_user_database_unlock_system ();
00141   return TRUE;
00142 }
00143 
00144 
00152 dbus_bool_t
00153 _dbus_get_user_id (const DBusString  *username,
00154                    dbus_uid_t        *uid)
00155 {
00156   DBusCredentials creds;
00157 
00158   if (!_dbus_credentials_from_username (username, &creds))
00159     return FALSE;
00160 
00161   if (creds.uid == DBUS_UID_UNSET)
00162     return FALSE;
00163 
00164   *uid = creds.uid;
00165 
00166   return TRUE;
00167 }
00168 
00176 dbus_bool_t
00177 _dbus_get_group_id (const DBusString  *groupname,
00178                     dbus_gid_t        *gid)
00179 {
00180   DBusUserDatabase *db;
00181   const DBusGroupInfo *info;
00182   _dbus_user_database_lock_system ();
00183 
00184   db = _dbus_user_database_get_system ();
00185   if (db == NULL)
00186     {
00187       _dbus_user_database_unlock_system ();
00188       return FALSE;
00189     }
00190 
00191   if (!_dbus_user_database_get_groupname (db, groupname,
00192                                           &info, NULL))
00193     {
00194       _dbus_user_database_unlock_system ();
00195       return FALSE;
00196     }
00197 
00198   *gid = info->gid;
00199   
00200   _dbus_user_database_unlock_system ();
00201   return TRUE;
00202 }
00203 
00216 DBusGroupInfo*
00217 _dbus_user_database_lookup_group (DBusUserDatabase *db,
00218                                   dbus_gid_t        gid,
00219                                   const DBusString *groupname,
00220                                   DBusError        *error)
00221 {
00222   DBusGroupInfo *info;
00223 
00224   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00225 
00226    /* See if the group is really a number */
00227    if (gid == DBUS_UID_UNSET)
00228     {
00229       unsigned long n;
00230 
00231       if (_dbus_is_a_number (groupname, &n))
00232         gid = n;
00233     }
00234 
00235 
00236   if (gid != DBUS_GID_UNSET)
00237     info = _dbus_hash_table_lookup_ulong (db->groups, gid);
00238   else
00239     info = _dbus_hash_table_lookup_string (db->groups_by_name,
00240                                            _dbus_string_get_const_data (groupname));
00241   if (info)
00242     {
00243       _dbus_verbose ("Using cache for GID "DBUS_GID_FORMAT" information\n",
00244                      info->gid);
00245       return info;
00246     }
00247   else
00248     {
00249       if (gid != DBUS_GID_UNSET)
00250         _dbus_verbose ("No cache for GID "DBUS_GID_FORMAT"\n",
00251                        gid);
00252       else
00253         _dbus_verbose ("No cache for groupname \"%s\"\n",
00254                        _dbus_string_get_const_data (groupname));
00255       
00256       info = dbus_new0 (DBusGroupInfo, 1);
00257       if (info == NULL)
00258         {
00259           dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00260           return NULL;
00261         }
00262 
00263       if (gid != DBUS_GID_UNSET)
00264         {
00265           if (!_dbus_group_info_fill_gid (info, gid, error))
00266             {
00267               _DBUS_ASSERT_ERROR_IS_SET (error);
00268               _dbus_group_info_free_allocated (info);
00269               return NULL;
00270             }
00271         }
00272       else
00273         {
00274           if (!_dbus_group_info_fill (info, groupname, error))
00275             {
00276               _DBUS_ASSERT_ERROR_IS_SET (error);
00277               _dbus_group_info_free_allocated (info);
00278               return NULL;
00279             }
00280         }
00281 
00282       /* don't use these past here */
00283       gid = DBUS_GID_UNSET;
00284       groupname = NULL;
00285 
00286       if (!_dbus_hash_table_insert_ulong (db->groups, info->gid, info))
00287         {
00288           dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00289           _dbus_group_info_free_allocated (info);
00290           return NULL;
00291         }
00292 
00293 
00294       if (!_dbus_hash_table_insert_string (db->groups_by_name,
00295                                            info->groupname,
00296                                            info))
00297         {
00298           _dbus_hash_table_remove_ulong (db->groups, info->gid);
00299           dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00300           return NULL;
00301         }
00302       
00303       return info;
00304     }
00305 }
00306 
00307 
00318 dbus_bool_t
00319 _dbus_user_database_get_groupname (DBusUserDatabase     *db,
00320                                    const DBusString     *groupname,
00321                                    const DBusGroupInfo **info,
00322                                    DBusError            *error)
00323 {
00324   *info = _dbus_user_database_lookup_group (db, DBUS_GID_UNSET, groupname, error);
00325   return *info != NULL;
00326 }
00327 
00338 dbus_bool_t
00339 _dbus_user_database_get_gid (DBusUserDatabase     *db,
00340                              dbus_gid_t            gid,
00341                              const DBusGroupInfo **info,
00342                              DBusError            *error)
00343 {
00344   *info = _dbus_user_database_lookup_group (db, gid, NULL, error);
00345   return *info != NULL;
00346 }
00347 
00348 
00362 dbus_bool_t
00363 _dbus_user_database_get_groups (DBusUserDatabase  *db,
00364                                 dbus_uid_t         uid,
00365                                 dbus_gid_t       **group_ids,
00366                                 int               *n_group_ids,
00367                                 DBusError         *error)
00368 {
00369   DBusUserInfo *info;
00370   
00371   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00372 
00373   *group_ids = NULL;
00374   *n_group_ids = 0;
00375   
00376   info = _dbus_user_database_lookup (db, uid, NULL, error);
00377   if (info == NULL)
00378     {
00379       _DBUS_ASSERT_ERROR_IS_SET (error);
00380       return FALSE;
00381     }
00382 
00383   if (info->n_group_ids > 0)
00384     {
00385       *group_ids = dbus_new (dbus_gid_t, info->n_group_ids);
00386       if (*group_ids == NULL)
00387         {
00388           dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00389           return FALSE;
00390         }
00391 
00392       *n_group_ids = info->n_group_ids;
00393 
00394       memcpy (*group_ids, info->group_ids, info->n_group_ids * sizeof (dbus_gid_t));
00395     }
00396 
00397   return TRUE;
00398 }
00399 
00402 #ifdef DBUS_BUILD_TESTS
00403 #include <stdio.h>
00404 
00410 dbus_bool_t
00411 _dbus_userdb_test (const char *test_data_dir)
00412 {
00413   const DBusString *username;
00414   const DBusString *homedir;
00415 
00416   if (!_dbus_username_from_current_process (&username))
00417     _dbus_assert_not_reached ("didn't get username");
00418 
00419   if (!_dbus_homedir_from_current_process (&homedir))
00420     _dbus_assert_not_reached ("didn't get homedir");  
00421 
00422   printf ("    Current user: %s homedir: %s\n",
00423           _dbus_string_get_const_data (username),
00424           _dbus_string_get_const_data (homedir));
00425   
00426   return TRUE;
00427 }
00428 #endif /* DBUS_BUILD_TESTS */

Generated on Tue Apr 15 15:54:03 2008 for D-Bus by  doxygen 1.5.1