Esempio n. 1
0
DBusUserInfo*
_dbus_user_database_lookup (DBusUserDatabase *db,
                            dbus_uid_t        uid,
                            const DBusString *username,
                            DBusError        *error)
{
  DBusUserInfo *info;

  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
  _dbus_assert (uid != DBUS_UID_UNSET || username != NULL);

  /* See if the username is really a number */
  if (uid == DBUS_UID_UNSET)
    {
      unsigned long n;

      if (_dbus_is_a_number (username, &n))
        uid = n;
    }

  if (uid != DBUS_UID_UNSET)
    info = _dbus_hash_table_lookup_ulong (db->users, uid);
  else
    info = _dbus_hash_table_lookup_string (db->users_by_name, _dbus_string_get_const_data (username));
  
  if (info)
    {
      _dbus_verbose ("Using cache for UID "DBUS_UID_FORMAT" information\n",
                     info->uid);
      return info;
    }
  else
    {
      if (uid != DBUS_UID_UNSET)
	_dbus_verbose ("No cache for UID "DBUS_UID_FORMAT"\n",
		       uid);
      else
	_dbus_verbose ("No cache for user \"%s\"\n",
		       _dbus_string_get_const_data (username));
      
      info = dbus_new0 (DBusUserInfo, 1);
      if (info == NULL)
        {
          dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
          return NULL;
        }

      if (uid != DBUS_UID_UNSET)
        {
          if (!_dbus_user_info_fill_uid (info, uid, error))
            {
              _DBUS_ASSERT_ERROR_IS_SET (error);
              _dbus_user_info_free_allocated (info);
              return NULL;
            }
        }
      else
        {
          if (!_dbus_user_info_fill (info, username, error))
            {
              _DBUS_ASSERT_ERROR_IS_SET (error);
              _dbus_user_info_free_allocated (info);
              return NULL;
            }
        }

      /* be sure we don't use these after here */
      uid = DBUS_UID_UNSET;
      username = NULL;

      /* insert into hash */
      if (!_dbus_hash_table_insert_ulong (db->users, info->uid, info))
        {
          dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
          _dbus_user_info_free_allocated (info);
          return NULL;
        }

      if (!_dbus_hash_table_insert_string (db->users_by_name,
                                           info->username,
                                           info))
        {
          _dbus_hash_table_remove_ulong (db->users, info->uid);
          dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
          return NULL;
        }
      
      return info;
    }
}
Esempio n. 2
0
/**
 * Looks up a gid or group name in the user database.  Only one of
 * name or GID can be provided. There are wrapper functions for this
 * that are better to use, this one does no locking or anything on the
 * database and otherwise sort of sucks.
 *
 * @param db the database
 * @param gid the group ID or #DBUS_GID_UNSET
 * @param groupname group name or #NULL 
 * @param error error to fill in
 * @returns the entry in the database
 */
DBusGroupInfo*
_dbus_user_database_lookup_group (DBusUserDatabase *db,
                                  dbus_gid_t        gid,
                                  const DBusString *groupname,
                                  DBusError        *error)
{
  DBusGroupInfo *info;

  _DBUS_ASSERT_ERROR_IS_CLEAR (error);

   /* See if the group is really a number */
   if (gid == DBUS_UID_UNSET)
    {
      unsigned long n;

      if (_dbus_is_a_number (groupname, &n))
        gid = n;
    }

#ifdef DBUS_ENABLE_USERDB_CACHE
  if (gid != DBUS_GID_UNSET)
    info = _dbus_hash_table_lookup_ulong (db->groups, gid);
  else
    info = _dbus_hash_table_lookup_string (db->groups_by_name,
                                           _dbus_string_get_const_data (groupname));
  if (info)
    {
      _dbus_verbose ("Using cache for GID "DBUS_GID_FORMAT" information\n",
                     info->gid);
      return info;
    }
  else
#else
  if (1)
#endif
    {
      if (gid != DBUS_GID_UNSET)
	_dbus_verbose ("No cache for GID "DBUS_GID_FORMAT"\n",
		       gid);
      else
	_dbus_verbose ("No cache for groupname \"%s\"\n",
		       _dbus_string_get_const_data (groupname));
      
      info = dbus_new0 (DBusGroupInfo, 1);
      if (info == NULL)
        {
          dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
          return NULL;
        }

      if (gid != DBUS_GID_UNSET)
        {
          if (!_dbus_group_info_fill_gid (info, gid, error))
            {
              _DBUS_ASSERT_ERROR_IS_SET (error);
              _dbus_group_info_free_allocated (info);
              return NULL;
            }
        }
      else
        {
          if (!_dbus_group_info_fill (info, groupname, error))
            {
              _DBUS_ASSERT_ERROR_IS_SET (error);
              _dbus_group_info_free_allocated (info);
              return NULL;
            }
        }

      /* don't use these past here */
      gid = DBUS_GID_UNSET;
      groupname = NULL;

      if (!_dbus_hash_table_insert_ulong (db->groups, info->gid, info))
        {
          dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
          _dbus_group_info_free_allocated (info);
          return NULL;
        }


      if (!_dbus_hash_table_insert_string (db->groups_by_name,
                                           info->groupname,
                                           info))
        {
          _dbus_hash_table_remove_ulong (db->groups, info->gid);
          dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
          return NULL;
        }
      
      return info;
    }
}
Esempio n. 3
0
BusClientPolicy*
bus_policy_create_client_policy (BusPolicy      *policy,
                                 DBusConnection *connection,
                                 DBusError      *error)
{
    BusClientPolicy *client;
    dbus_uid_t uid;
    dbus_bool_t at_console;

    _dbus_assert (dbus_connection_get_is_authenticated (connection));
    _DBUS_ASSERT_ERROR_IS_CLEAR (error);

    client = bus_client_policy_new ();
    if (client == NULL)
        goto nomem;

    if (!add_list_to_client (&policy->default_rules,
                             client))
        goto nomem;

    /* we avoid the overhead of looking up user's groups
     * if we don't have any group rules anyway
     */
    if (_dbus_hash_table_get_n_entries (policy->rules_by_gid) > 0)
    {
        unsigned long *groups;
        int n_groups;
        int i;

        if (!bus_connection_get_groups (connection, &groups, &n_groups, error))
            goto failed;

        i = 0;
        while (i < n_groups)
        {
            DBusList **list;

            list = _dbus_hash_table_lookup_ulong (policy->rules_by_gid,
                                                  groups[i]);

            if (list != NULL)
            {
                if (!add_list_to_client (list, client))
                {
                    dbus_free (groups);
                    goto nomem;
                }
            }

            ++i;
        }

        dbus_free (groups);
    }

    if (!dbus_connection_get_unix_user (connection, &uid))
    {
        dbus_set_error (error, DBUS_ERROR_FAILED,
                        "No user ID known for connection, cannot determine security policy\n");
        goto failed;
    }

    if (_dbus_hash_table_get_n_entries (policy->rules_by_uid) > 0)
    {
        DBusList **list;

        list = _dbus_hash_table_lookup_ulong (policy->rules_by_uid,
                                              uid);

        if (list != NULL)
        {
            if (!add_list_to_client (list, client))
                goto nomem;
        }
    }

    /* Add console rules */
    at_console = _dbus_is_console_user (uid, error);

    if (at_console)
    {
        if (!add_list_to_client (&policy->at_console_true_rules, client))
            goto nomem;
    }
    else if (dbus_error_is_set (error) == TRUE)
    {
        goto failed;
    }
    else if (!add_list_to_client (&policy->at_console_false_rules, client))
    {
        goto nomem;
    }

    if (!add_list_to_client (&policy->mandatory_rules,
                             client))
        goto nomem;

    bus_client_policy_optimize (client);

    return client;

nomem:
    BUS_SET_OOM (error);
failed:
    _DBUS_ASSERT_ERROR_IS_SET (error);
    if (client)
        bus_client_policy_unref (client);
    return NULL;
}