Esempio n. 1
0
int bus_image_method_remove(
                sd_bus_message *message,
                void *userdata,
                sd_bus_error *error) {

        _cleanup_close_pair_ int errno_pipe_fd[2] = { -1, -1 };
        Image *image = userdata;
        Manager *m = image->userdata;
        pid_t child;
        int r;

        assert(message);
        assert(image);

        if (m->n_operations >= OPERATIONS_MAX)
                return sd_bus_error_setf(error, SD_BUS_ERROR_LIMITS_EXCEEDED, "Too many ongoing operations.");

        r = bus_verify_polkit_async(
                        message,
                        CAP_SYS_ADMIN,
                        "org.freedesktop.machine1.manage-images",
                        NULL,
                        false,
                        UID_INVALID,
                        &m->polkit_registry,
                        error);
        if (r < 0)
                return r;
        if (r == 0)
                return 1; /* Will call us back */

        if (pipe2(errno_pipe_fd, O_CLOEXEC|O_NONBLOCK) < 0)
                return sd_bus_error_set_errnof(error, errno, "Failed to create pipe: %m");

        child = fork();
        if (child < 0)
                return sd_bus_error_set_errnof(error, errno, "Failed to fork(): %m");
        if (child == 0) {
                errno_pipe_fd[0] = safe_close(errno_pipe_fd[0]);

                r = image_remove(image);
                if (r < 0) {
                        (void) write(errno_pipe_fd[1], &r, sizeof(r));
                        _exit(EXIT_FAILURE);
                }

                _exit(EXIT_SUCCESS);
        }

        errno_pipe_fd[1] = safe_close(errno_pipe_fd[1]);

        r = operation_new(m, NULL, child, message, errno_pipe_fd[0]);
        if (r < 0) {
                (void) sigkill_wait(child);
                return r;
        }

        errno_pipe_fd[0] = -1;

        return 1;
}
Esempio n. 2
0
static int
_ger_new_gerpb (
	Slapi_PBlock    *pb,
	Slapi_Entry	    *e,
	const char 		*subjectndn,
	Slapi_PBlock	**gerpb,
	void			**aclcb,	/* original aclcb */
	char			**errbuf
	)
{
	Connection *conn;
	struct acl_cblock *geraclcb;
	Acl_PBlock *geraclpb;
	Operation *gerop;
	int rc = LDAP_SUCCESS;

	*aclcb = NULL;
	*gerpb = slapi_pblock_new ();
	if ( *gerpb == NULL )
	{
		rc = LDAP_NO_MEMORY;
		goto bailout;
	}

	{
		/* aclpb initialization needs the backend */
		Slapi_Backend *be;
		slapi_pblock_get ( pb, SLAPI_BACKEND, &be );
		slapi_pblock_set ( *gerpb, SLAPI_BACKEND, be );
	}

	{
		int isroot = slapi_dn_isroot ( subjectndn );
		slapi_pblock_set ( *gerpb, SLAPI_REQUESTOR_ISROOT, &isroot );
	}

	/* Save requestor's aclcb and set subjectdn's one */
	{
		slapi_pblock_get ( pb, SLAPI_CONNECTION, &conn );
		slapi_pblock_set ( *gerpb, SLAPI_CONNECTION, conn );

		/* Can't share the conn->aclcb because of different context */
		geraclcb = (struct acl_cblock *) acl_conn_ext_constructor ( NULL, NULL);
		if ( geraclcb == NULL )
		{
			rc = LDAP_NO_MEMORY;
			goto bailout;
		}
		slapi_sdn_set_ndn_byval ( geraclcb->aclcb_sdn, subjectndn );
		*aclcb = acl_get_ext ( ACL_EXT_CONNECTION, conn );
		acl_set_ext ( ACL_EXT_CONNECTION, conn, (void *) geraclcb );
	}

	{
		gerop = operation_new ( OP_FLAG_INTERNAL );
		if ( gerop == NULL )
		{
			rc = LDAP_NO_MEMORY;
			goto bailout;
		}
		/*
		 * conn is a no-use parameter in the functions
		 * chained down from factory_create_extension
		 */
		gerop->o_extension = factory_create_extension ( get_operation_object_type(), (void *)gerop, (void *)conn );
		slapi_pblock_set ( *gerpb, SLAPI_OPERATION, gerop );
		slapi_sdn_set_ndn_byval ( &gerop->o_sdn, subjectndn );
		geraclpb = acl_get_ext ( ACL_EXT_OPERATION, (void *)gerop);
		acl_init_aclpb ( *gerpb, geraclpb, subjectndn, 0 );
		geraclpb->aclpb_res_type |= ACLPB_EFFECTIVE_RIGHTS;
	}


bailout:
	if ( rc != LDAP_SUCCESS )
	{
		_ger_release_gerpb ( gerpb, aclcb, pb );
	}

	return rc;
}
Esempio n. 3
0
int bus_image_common_remove(
                Manager *m,
                sd_bus_message *message,
                const char *name_or_path,
                Image *image,
                sd_bus_error *error) {

        _cleanup_close_pair_ int errno_pipe_fd[2] = { -1, -1 };
        _cleanup_(sigkill_waitp) pid_t child = 0;
        PortableState state;
        int r;

        assert(message);
        assert(name_or_path || image);

        if (!m) {
                assert(image);
                m = image->userdata;
        }

        if (m->n_operations >= OPERATIONS_MAX)
                return sd_bus_error_setf(error, SD_BUS_ERROR_LIMITS_EXCEEDED, "Too many ongoing operations.");

        r = bus_image_acquire(m,
                              message,
                              name_or_path,
                              image,
                              BUS_IMAGE_AUTHENTICATE_ALL,
                              "org.freedesktop.portable1.manage-images",
                              &image,
                              error);
        if (r < 0)
                return r;
        if (r == 0)
                return 1; /* Will call us back */

        r = portable_get_state(
                        sd_bus_message_get_bus(message),
                        image->path,
                        0,
                        &state,
                        error);
        if (r < 0)
                return r;

        if (state != PORTABLE_DETACHED)
                return sd_bus_error_set_errnof(error, EBUSY, "Image '%s' is not detached, refusing.", image->path);

        if (pipe2(errno_pipe_fd, O_CLOEXEC|O_NONBLOCK) < 0)
                return sd_bus_error_set_errnof(error, errno, "Failed to create pipe: %m");

        r = safe_fork("(sd-imgrm)", FORK_RESET_SIGNALS, &child);
        if (r < 0)
                return sd_bus_error_set_errnof(error, r, "Failed to fork(): %m");
        if (r == 0) {
                errno_pipe_fd[0] = safe_close(errno_pipe_fd[0]);

                r = image_remove(image);
                if (r < 0) {
                        (void) write(errno_pipe_fd[1], &r, sizeof(r));
                        _exit(EXIT_FAILURE);
                }

                _exit(EXIT_SUCCESS);
        }

        errno_pipe_fd[1] = safe_close(errno_pipe_fd[1]);

        r = operation_new(m, child, message, errno_pipe_fd[0], NULL);
        if (r < 0)
                return r;

        child = 0;
        errno_pipe_fd[0] = -1;

        return 1;
}