Esempio n. 1
0
static errno_t
sbus_server_bus_get_connection_unix_user(TALLOC_CTX *mem_ctx,
                                         struct sbus_request *sbus_req,
                                         struct sbus_server *server,
                                         const char *name,
                                         uint32_t *_uid)
{
    struct sbus_connection *conn;
    unsigned long uid;
    dbus_bool_t dbret;

    if (strcmp(name, DBUS_SERVICE_DBUS) == 0) {
        *_uid = server->uid;
        return EOK;
    }

    conn = sss_ptr_hash_lookup(server->names, name, struct sbus_connection);
    if (conn == NULL) {
        return ERR_SBUS_UNKNOWN_OWNER;
    }

    dbret = dbus_connection_get_unix_user(conn->connection, &uid);
    if (!dbret) {
        return EIO;
    }

    *_uid = (uint32_t)uid;
    return EOK;
}
Esempio n. 2
0
glong
ibus_connection_get_unix_user (IBusConnection *connection)
{
    IBusConnectionPrivate *priv;
    priv = IBUS_CONNECTION_GET_PRIVATE (connection);

    gulong uid;

    if (priv->connection && dbus_connection_get_unix_user (priv->connection, &uid))
        return uid;
    return -1;
}
static dbus_bool_t
bus_driver_handle_get_connection_unix_user (DBusConnection *connection,
                                            BusTransaction *transaction,
                                            DBusMessage    *message,
                                            DBusError      *error)
{
  const char *service;
  DBusString str;
  BusRegistry *registry;
  BusService *serv;
  DBusConnection *conn;
  DBusMessage *reply;
  unsigned long uid;
  dbus_uint32_t uid32;

  _DBUS_ASSERT_ERROR_IS_CLEAR (error);

  registry = bus_connection_get_registry (connection);

  service = NULL;
  reply = NULL;

  if (! dbus_message_get_args (message, error,
			       DBUS_TYPE_STRING, &service,
			       DBUS_TYPE_INVALID))
      goto failed;

  _dbus_verbose ("asked for UID of connection %s\n", service);

  _dbus_string_init_const (&str, service);
  serv = bus_registry_lookup (registry, &str);
  if (serv == NULL)
    {
      dbus_set_error (error, 
		      DBUS_ERROR_NAME_HAS_NO_OWNER,
		      "Could not get UID of name '%s': no such name", service);
      goto failed;
    }

  conn = bus_service_get_primary_owners_connection (serv);

  reply = dbus_message_new_method_return (message);
  if (reply == NULL)
    goto oom;

  if (!dbus_connection_get_unix_user (conn, &uid))
    {
      dbus_set_error (error,
                      DBUS_ERROR_FAILED,
                      "Could not determine UID for '%s'", service);
      goto failed;
    }

  uid32 = uid;
  if (! dbus_message_append_args (reply,
                                  DBUS_TYPE_UINT32, &uid32,
                                  DBUS_TYPE_INVALID))
    goto oom;

  if (! bus_transaction_send_from_driver (transaction, connection, reply))
    goto oom;

  dbus_message_unref (reply);

  return TRUE;

 oom:
  BUS_SET_OOM (error);

 failed:
  _DBUS_ASSERT_ERROR_IS_SET (error);
  if (reply)
    dbus_message_unref (reply);
  return FALSE;
}
Esempio n. 4
0
/**
 * session_from_dbus:
 * @parent: parent,
 * @message: D-Bus message.
 *
 * Create a new session, based on the specified D-Bus message.
 *
 * Return new Session, or NULL on error.
 **/
Session *
session_from_dbus (const void     *parent,
		   NihDBusMessage *message)
{
	const char     *sender;
	DBusError       dbus_error;
	unsigned long   unix_user;
	unsigned long   unix_process_id;
	char            root[PATH_MAX];
	Session        *session;
	struct passwd  *pwd;
	nih_local char *conf_path = NULL;

	nih_assert (message != NULL);

	/* Handle explicit command-line request and alternative request
	 * method (primarily for test framework) to disable session support.
	 */
	if (disable_sessions || getenv ("UPSTART_NO_SESSIONS"))
		return NULL;

	session_init ();

	/* Ask D-Bus nicely for the origin uid and/or pid of the caller;
	 * sadly we can't ask the bus daemon for the origin pid, so that
	 * one will just have to stay user-session only.
	 */
	dbus_error_init (&dbus_error);

	sender = dbus_message_get_sender (message->message);
	if (sender) {
		unix_user = dbus_bus_get_unix_user (message->connection, sender,
						    &dbus_error);
		if (unix_user == (unsigned long)-1) {
			dbus_error_free (&dbus_error);
			unix_user = 0;
		}

		unix_process_id = 0;

	} else {
		if (! dbus_connection_get_unix_user (message->connection,
						     &unix_user))
			unix_process_id = 0;

		if (! dbus_connection_get_unix_process_id (message->connection,
							   &unix_process_id))
			unix_process_id = 0;
	}

	/* If we retrieved a process id, look up the root path for it;
	 * if it's just '/' don't worry so much about it.
	 */
	if (unix_process_id) {
		nih_local char *symlink = NULL;
		ssize_t len;

		symlink = NIH_MUST (nih_sprintf (NULL, "/proc/%lu/root",
						 unix_process_id));
		len = readlink (symlink, root, sizeof root);
		if (len < 0)
			return NULL;

		root[len] = '\0';

		if (! strcmp (root, "/")) {
			unix_process_id = 0;
			if (! unix_user)
				return NULL;
		}

	} else if (! unix_user) {
		/* No process id or user id found, return the NULL session */
		return NULL;
	}

	if (unix_user) {
		pwd = getpwuid (unix_user);

		if (! pwd || ! pwd->pw_dir) {
			nih_error ("%lu: %s: %s", unix_user,
				   _("Unable to lookup home directory"),
				   strerror (errno));
			return NULL;
		}

		NIH_MUST (nih_strcat_sprintf (&conf_path, NULL, "%s/%s",
					pwd->pw_dir, USERCONFDIR));
	}


	/* Now find in the existing Sessions list */
	NIH_LIST_FOREACH_SAFE (sessions, iter) {
		Session *session = (Session *)iter;

		if (unix_process_id) {
			if (! session->chroot)
				continue;

			/* ignore sessions relating to other chroots */
			if (strcmp (session->chroot, root))
				continue;
		}

		/* ignore sessions relating to other users */
		if (unix_user != session->user)
			continue;

		/* Found a user with the same uid but different
		 * conf_dir to the existing session user. Either the
		 * original user has been deleted and a new user created
		 * with the same uid, or the original users home
		 * directory has changed since they first started
		 * running jobs. Whatever the reason, we (can only) honour
		 * the new value.
		 *
		 * Since multiple users with the same uid are considered
		 * to be "the same user", invalidate the old path,
		 * allowing the correct new path to be set below.
		 *
		 * Note that there may be a possibility of trouble if
		 * the scenario relates to a deleted user and that original
		 * user still has jobs running. However, if that were the
		 * case, those jobs would likely fail anyway since they
		 * would have no working directory due to the original
		 * users home directory being deleted/changed/made inaccessible.
		 */
		if (unix_user && conf_path && session->conf_path &&
				strcmp (conf_path, session->conf_path)) {
			nih_free (session->conf_path);
			session->conf_path = NULL;
		}

		if (! session->conf_path)
			session_create_conf_source (session);

		return session;
	}
Esempio n. 5
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;
}