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; }
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; }
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; }