예제 #1
0
papi_status_t
ipp_purge_jobs(papi_service_t svc, papi_attribute_t **request,
		papi_attribute_t ***response)
{
	papi_status_t status;
	papi_job_t *jobs = NULL;
	papi_attribute_t **operational = NULL;

	char *queue = NULL;

	/* Get operational attributes from the request */
	(void) papiAttributeListGetCollection(request, NULL,
				"operational-attributes-group", &operational);

	/*
	 * The operational-attributes-group must contain:
	 *	printer-uri
	 */
	get_printer_id(operational, &queue, NULL);
	if (queue == NULL) {
		ipp_set_status(response, status, "printer-uri: %s",
			papiStatusString(status));
		return (PAPI_BAD_REQUEST);
	}

	if ((status = papiPrinterPurgeJobs(svc, queue, &jobs)) != PAPI_OK) {
		ipp_set_status(response, status, "purge failed: %s: %s",
				(queue ? queue : "(null)"),
				ipp_svc_status_mesg(svc, status));
	}

	papiJobListFree(jobs);

	return (status);
}
예제 #2
0
static papi_status_t
print_service_connect(papi_service_t *svc, papi_attribute_t **request,
		papi_attribute_t ***response)
{
	papi_status_t status;
	papi_attribute_t **operational = NULL;
	char *printer_uri = NULL;
	char *svc_name = NULL;
	char *user = NULL;

	/* Get the operational attributes group from the request */
	(void) papiAttributeListGetCollection(request, NULL,
				"operational-attributes-group", &operational);

	/* get the user name */
	(void) papiAttributeListGetString(request, NULL, "default-user", &user);
	(void) papiAttributeListGetString(operational, NULL,
				"requesting-user-name", &user);

	/* get the printer or service name */
	(void) papiAttributeListGetString(request, NULL,
				"default-service", &svc_name);
	get_printer_id(operational, &svc_name, NULL);

	status = papiServiceCreate(svc, svc_name, user, NULL, NULL,
					PAPI_ENCRYPT_NEVER, NULL);
	if (status != PAPI_OK) {
		ipp_set_status(response, status, "print service: %s",
				papiStatusString(status));
		return (status);
	}

	/*
	 * Trusted Solaris can't be trusting of intermediaries.  Pass
	 * the socket connection to the print service to retrieve the
	 * sensativity label off of a multi-level port.
	 */
	{
		int fd = -1;

		(void) papiAttributeListGetInteger(request, NULL,
					"peer-socket", &fd);
		if (fd != -1)
			papiServiceSetPeer(*svc, fd);
	}

	return (status);
}
예제 #3
0
papi_status_t
ipp_process_request(papi_attribute_t **request, papi_attribute_t ***response,
	ipp_reader_t iread, void *fd)
{
	papi_status_t result = PAPI_OK;

	ipp_initialize_response(request, response);

#ifdef DEBUG
	fprintf(stderr, "REQUEST:");
	papiAttributeListPrint(stderr, request, " %d  ", getpid());
	fprintf(stderr, "\n");
#endif

	/* verify that the request is "well-formed" */
	if ((result = ipp_validate_request(request, response)) == PAPI_OK) {
		papi_service_t svc = NULL;
		ipp_handler_t *handler;

		result = print_service_connect(&svc, request, response);
		handler = ipp_operation_handler(request, response);

		/* process the request */
		if ((result == PAPI_OK) && (handler != NULL))
			result = (handler)(svc, request, response, iread, fd);
#ifdef DEBUG
		fprintf(stderr, "RESULT: %s\n", papiStatusString(result));
#endif
		papiServiceDestroy(svc);
	}

	(void) papiAttributeListAddInteger(response, PAPI_ATTR_EXCL,
				"status-code", result);
	massage_response(request, *response);

#ifdef DEBUG
	fprintf(stderr, "RESPONSE:");
	papiAttributeListPrint(stderr, *response, " %d  ", getpid());
	fprintf(stderr, "\n");
#endif

	return (result);
}
예제 #4
0
/*ARGSUSED0*/
static const char *
ipp_operation(cmd_parms *cmd, void *cfg, char *op, char *toggle)
{
	IPPListenerConfig *config = (IPPListenerConfig *)cfg;
	papi_status_t status;

	status = ipp_configure_operation(&config->operations, op, toggle);
	switch (status) {
	case PAPI_OK:
		return (NULL);
	case PAPI_BAD_ARGUMENT:
		return (gettext("internal error (invalid argument)"));
	default:
		return (papiStatusString(status));
	}

	/* NOTREACHED */
	/* return (gettext("contact your software vendor")); */
}
예제 #5
0
/*
 * When the PAPI supports papiJobCreate(), papiJobStreamAdd() and
 * papiJobClose(), this will be much cleaner and more efficient, but in the
 * meantime, we are using a private, non-standard interface to do this.
 */
papi_status_t
ipp_send_document(papi_service_t svc, papi_attribute_t **request,
		papi_attribute_t ***response, ipp_reader_t iread, void *fd)
{
	papi_status_t status;
	papi_stream_t s = NULL;
	papi_job_t j = NULL;
	papi_attribute_t **operational = NULL;
	papi_attribute_t **job_attributes = NULL;
	char *queue = NULL;
	ssize_t rc;
	int id = -1;
	char buf[BUFSIZ];
	char last = PAPI_FALSE;
	char *keys[] = { "attributes-natural-language", "attributes-charset",
			"printer-uri", "job-id", "job-uri", "last-document",
			NULL };

	/* Get operational attributes from the request */
	(void) papiAttributeListGetCollection(request, NULL,
				"operational-attributes-group", &operational);

	/*
	 * the operational-attributes-group must contain:
	 *	job-uri (or printer-uri/job-id)
	 *	last-document
	 */
	get_printer_id(operational, &queue, &id);
	if (id < 0) {
		ipp_set_status(response, PAPI_BAD_REQUEST,
				"missing job-uri or job-id");
		return (PAPI_BAD_REQUEST);
	} else if (queue == NULL) {
		ipp_set_status(response, PAPI_BAD_REQUEST,
				"missing printer-uri or job-uri");
		return (PAPI_BAD_REQUEST);
	}

	status = papiAttributeListGetBoolean(operational, NULL,
			"last-document", &last);
	if (status != PAPI_OK) {
		ipp_set_status(response, status, "last-document: %s",
				papiStatusString(status));
		return (PAPI_BAD_REQUEST);
	}

	/*
	 * the operational-attributes-group may contain:
	 *	document-name
	 *	compression
	 *	document-format
	 *	document-natural-language
	 * Simply copy the entire contents of the operational-attributes-group
	 * for the PAPI call's possible use.
	 */
	split_and_copy_attributes(keys, operational, NULL, &job_attributes);

	/* copy any job-attributes-group attributes for the PAPI call */
	if (papiAttributeListGetCollection(request, NULL,
			"job-attributes-group", &operational) == PAPI_OK)
		copy_attributes(&job_attributes, operational);

	/* create a stream to write the document data on */
	status = papiJobStreamAdd(svc, queue, id, &s);
	papiAttributeListFree(job_attributes);
	if (status != PAPI_OK) {
		ipp_set_status(response, status, "job submission: %s",
				ipp_svc_status_mesg(svc, status));
		return (status);
	}

	/* copy the document data from the IPP connection to the stream */
	while ((status == PAPI_OK) && ((rc = iread(fd, buf, sizeof (buf))) > 0))
		status = papiJobStreamWrite(svc, s, buf, rc);
	if (status != PAPI_OK) {
		ipp_set_status(response, status, "write job data: %s",
				ipp_svc_status_mesg(svc, status));
		return (status);
	}

	/* close the stream */
	status = papiJobStreamClose(svc, s, &j);
	if (status != PAPI_OK) {
		ipp_set_status(response, status, "close job stream: %s",
				ipp_svc_status_mesg(svc, status));
		papiJobFree(j); /* we shouldn't have a job, but just in case */
		return (status);
	}

	/* if it's the last document, commit the job */
	if (last == PAPI_TRUE) {
		status = papiJobCommit(svc, queue, id);
	}

	/* add the job attributes to the response in a job-attributes-group */
	if (j != NULL) {
		papi_to_ipp_job_group(response, request, PAPI_ATTR_REPLACE, j);
		papiJobFree(j);
	}

	return (status);
}
예제 #6
0
papi_status_t
ipp_validate_job(papi_service_t svc, papi_attribute_t **request,
		papi_attribute_t ***response, ipp_reader_t iread, void *fd)
{
	papi_status_t status;
	papi_job_t j = NULL;
	papi_attribute_t **operational = NULL;
	papi_attribute_t **job_attributes = NULL;
	char *queue = NULL;
	char *files[] = { "/etc/syslog.conf", NULL };
	ssize_t rc;
	char buf[BUFSIZ];
	char *keys[] = { "attributes-natural-language", "attributes-charset",
			"printer-uri", NULL };

	/* Get operational attributes from the request */
	(void) papiAttributeListGetCollection(request, NULL,
				"operational-attributes-group", &operational);

	/*
	 * The operational-attributes-group must contain:
	 *	printer-uri
	 */
	get_printer_id(operational, &queue, NULL);
	if (queue == NULL) {
		ipp_set_status(response, status, "printer-uri: %s",
			papiStatusString(status));
		return (PAPI_BAD_REQUEST);
	}

	/*
	 * The operational-attributes-group may contain:
	 *	job-name
	 *	ipp-attribute-fidelity
	 *	document-name
	 *	compression
	 *	document-format
	 *	document-natural-language
	 *	job-k-octets
	 *	job-impressions
	 *	job-media-sheets
	 * Simply copy the entire contents of the operational-attributes-group
	 * for the PAPI call's possible use.
	 */
	split_and_copy_attributes(keys, operational, NULL, &job_attributes);

	/* copy any job-attributes-group attributes for the PAPI call */
	if (papiAttributeListGetCollection(request, NULL,
			"job-attributes-group", &operational) == PAPI_OK)
		copy_attributes(&job_attributes, operational);

	/* request job validation */
	status = papiJobValidate(svc, queue, job_attributes, NULL, files, &j);
	papiAttributeListFree(job_attributes);

	if (status != PAPI_OK) {
		ipp_set_status(response, status, "validating job: %s",
				ipp_svc_status_mesg(svc, status));
		papiJobFree(j);	/* we shouldn't have a job, but just in case */
		return (status);
	}

	/* add the job attributes to the response in a job-attributes-group */
	if (j != NULL) {
		papi_to_ipp_job_group(response, request, PAPI_ATTR_REPLACE, j);
		papiJobFree(j);
	}

	return (status);
}
예제 #7
0
static int
ipp_handler(request_rec *r)
{
	papi_attribute_t **request = NULL, **response = NULL;
	IPPListenerConfig *config;
	papi_status_t status;
	int ret;

	/* Really, IPP is all POST requests */
	if (r->method_number != M_POST)
		return (DECLINED);

#ifndef APACHE2
	/*
	 * An IPP request must have a MIME type of "application/ipp"
	 * (RFC-2910, Section 4, page 19).  If it doesn't match this
	 * MIME type, we should decline the request and let someone else
	 * try and handle it.
	 */
	if (r->headers_in != NULL) {
		char *mime_type = (char *)ap_table_get(r->headers_in,
							"Content-Type");

		if ((mime_type == NULL) ||
		    (strcasecmp(mime_type, "application/ipp") != 0))
			return (DECLINED);
	}
#endif
	/* CHUNKED_DECHUNK might not work right for IPP? */
	if ((ret = ap_setup_client_block(r, REQUEST_CHUNKED_DECHUNK)) != OK)
		return (ret);

	if (!ap_should_client_block(r))
		return (HTTP_INTERNAL_SERVER_ERROR);

#ifndef APACHE2
	ap_soft_timeout("ipp_module: read/reply request ", r);
#endif
	/* read the IPP request off the network */
	status = ipp_read_message(read_data, r, &request, IPP_TYPE_REQUEST);

	if (status != PAPI_OK)
		_log_rerror(APLOG_MARK, APLOG_ERR, r,
			"read failed: %s\n", papiStatusString(status));
#ifdef DEBUG
	papiAttributeListPrint(stderr, request, "request (%d)  ", getpid());
#endif

	(void) papiAttributeListAddString(&request, PAPI_ATTR_EXCL,
		"originating-host", (char *)
#ifdef APACHE2
		ap_get_remote_host
			(r->connection, r->per_dir_config, REMOTE_NAME, NULL));
#else
		ap_get_remote_host
			(r->connection, r->per_dir_config, REMOTE_NAME));
#endif

	(void) papiAttributeListAddInteger(&request, PAPI_ATTR_EXCL,
				"uri-port", ap_get_server_port(r));
	if (r->headers_in != NULL) {
		char *host = (char *)ap_table_get(r->headers_in, "Host");

		if ((host == NULL) || (host[0] == '\0'))
			host = (char *)ap_get_server_name(r);

		(void) papiAttributeListAddString(&request, PAPI_ATTR_EXCL,
				"uri-host", host);
	}
	(void) papiAttributeListAddString(&request, PAPI_ATTR_EXCL,
				"uri-path", r->uri);

	config = ap_get_module_config(r->per_dir_config, &ipp_module);
	if (config != NULL) {
		(void) papiAttributeListAddInteger(&request, PAPI_ATTR_EXCL,
				"conformance", config->conformance);
		(void) papiAttributeListAddCollection(&request, PAPI_ATTR_EXCL,
				"operations", config->operations);
		if (config->default_user != NULL)
			(void) papiAttributeListAddString(&request,
						PAPI_ATTR_EXCL, "default-user",
						config->default_user);
		if (config->default_svc != NULL)
			(void) papiAttributeListAddString(&request,
					PAPI_ATTR_EXCL, "default-service",
					config->default_svc);
	}

	/*
	 * For Trusted Solaris, pass the fd number of the socket connection
	 * to the backend so the it can be forwarded to the backend print
	 * service to retrieve the sensativity label off of a multi-level
	 * port.
	 */
	(void) papiAttributeListAddInteger(&request, PAPI_ATTR_EXCL,
			"peer-socket", ap_bfileno(r->connection->client, B_RD));

	/* process the request */
	status = ipp_process_request(request, &response, read_data, r);
	if (status != PAPI_OK) {
		errno = 0;
		_log_rerror(APLOG_MARK, APLOG_ERR, r,
			"request failed: %s\n", papiStatusString(status));
		discard_data(r);
	}
#ifdef DEBUG
	fprintf(stderr, "processing result: %s\n", papiStatusString(status));
	papiAttributeListPrint(stderr, response, "response (%d)  ", getpid());
#endif

	/*
	 * If the client is using chunking and we have not yet received the
	 * final "0" sized chunk, we need to discard any data that may
	 * remain in the post request.
	 */
	if ((r->read_chunked != 0) &&
	    (ap_table_get(r->headers_in, "Content-Length") == NULL))
		discard_data(r);

	/* write an IPP response back to the network */
	r->content_type = "application/ipp";

#ifndef	APACHE2
	ap_send_http_header(r);
#endif

	status = ipp_write_message(write_data, r, response);
	if (status != PAPI_OK)
		_log_rerror(APLOG_MARK, APLOG_ERR, r,
			"write failed: %s\n", papiStatusString(status));
#ifdef DEBUG
	fprintf(stderr, "write result: %s\n", papiStatusString(status));
	fflush(stderr);
#endif

	papiAttributeListFree(request);
	papiAttributeListFree(response);

#ifndef APACHE2
	ap_kill_timeout(r);
	if (ap_rflush(r) < 0)
		_log_rerror(APLOG_MARK, APLOG_ERR, r,
			"flush failed, response may not have been sent");
#endif

	return (OK);
}
예제 #8
0
int
main(int ac, char *av[])
{
	int exit_code = 0;
	char *user = NULL;
	papi_encryption_t encryption = PAPI_ENCRYPT_NEVER;
	int c;
	int32_t rid = -1;
	int first_dest = 0;


	(void) setlocale(LC_ALL, "");
	(void) textdomain("SUNW_OST_OSCMD");

	if (ac == 1)
		usage(av[0]);

	while ((c = getopt(ac, av, "Eu:")) != EOF)
		switch (c) {
		case 'E':
			encryption = PAPI_ENCRYPT_REQUIRED;
			break;
		case 'u':
			user = optarg;
			break;
		default:
			usage(av[0]);
		}

	for (c = optind; c < ac; c++) {
		papi_status_t status;
		papi_service_t svc = NULL;
		papi_job_t *jobs = NULL;
		char *printer = NULL;
		int32_t id = -1;

		status = papiServiceCreate(&svc, av[c], NULL, NULL,
		    cli_auth_callback, encryption, NULL);
		if (status != PAPI_OK) {
			if (first_dest == 0) {
				(void) get_printer_id(av[c], &printer, &id);
				status = papiServiceCreate(&svc, printer, NULL,
				    NULL, cli_auth_callback, encryption, NULL);
			}
			if (status != PAPI_OK) {
				fprintf(stderr, gettext(
				    "Failed to contact service for %s: %s\n"),
				    printer,
				    verbose_papi_message(svc, status));
				exit(1);
			}
		} else {
			first_dest = 1;
			printer = av[c];
		}

#define	OUT	((status == PAPI_OK) ? stdout : stderr)

		if (id != -1) {	/* it's a job */
			char *mesg = gettext("cancelled");

			/*
			 * Check if the job-id is job-id-requested
			 * or job-id. If it is job-id-requested then find
			 * corresponding job-id and send it to cancel
			 */
			rid = job_to_be_queried(svc, printer, id);
			if (rid < 0) {
				/*
				 * Either it is a remote job which cannot be
				 * cancelled based on job-id or job-id is
				 * not found
				 */
				exit_code = 1;
				fprintf(OUT, "%s-%d: %s\n",
				    printer, id, gettext("not-found"));
			} else {
				status = papiJobCancel(svc, printer, rid);
				if (status == PAPI_NOT_AUTHORIZED) {
					mesg = papiStatusString(status);
					exit_code = 1;
				} else if (status != PAPI_OK) {
					mesg = gettext(
					    verbose_papi_message(
					    svc, status));
					exit_code = 1;
				}
				fprintf(OUT, "%s-%d: %s\n", printer, id, mesg);
			}

		} else {	/* it's a printer */
			if (user == NULL) {

				/* Remove first job from printer */

				status = papiPrinterListJobs(svc, printer,
				    NULL, NULL, 0, &jobs);

				if (status != PAPI_OK) {
					fprintf(stderr, gettext(
					    "ListJobs %s: %s\n"), printer,
					    verbose_papi_message(svc, status));
					exit_code = 1;
				}

				if (jobs != NULL && *jobs != NULL) {
					char *mesg = gettext("cancelled");
					id = papiJobGetId(*jobs);

					status = papiJobCancel(svc,
					    printer, id);

					if (status == PAPI_NOT_AUTHORIZED) {
						mesg = papiStatusString(status);
						exit_code = 1;
					} else if (status != PAPI_OK) {
						mesg = gettext(
						    verbose_papi_message(
						    svc, status));
						exit_code = 1;
					}
					/*
					 * If job-id-requested exists for this
					 * job-id then that should be displayed
					 */
					rid = get_job_id_requested(*jobs);
					if (rid >= 0)
						fprintf(OUT, "%s-%d: %s\n",
						    printer, rid, mesg);
					else
						fprintf(OUT, "%s-%d: %s\n",
						    printer, id, mesg);
				}
				papiJobListFree(jobs);

			} else {
				/* Purging user's print jobs */
				exit_code = cancel_jobs_for_user(user,
				    encryption, printer);
			}
		}
		papiServiceDestroy(svc);
	}

	if (optind == ac)
		exit_code = cancel_jobs_for_user(user, encryption, NULL);

	return (exit_code);
}