3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 *
26 */
27
28 /* $Id: mod_ipp.c 149 2006-04-25 16:55:01Z njacobs $ */
29
30 #pragma ident "%Z%%M% %I% %E% SMI"
31
32 /*
33 * Internet Printing Protocol (IPP) module for Apache.
34 */
35
36 #include "ap_config.h"
37
38 #include <stdio.h>
39 #include <time.h>
40 #include <sys/time.h>
41 #include <values.h>
42 #include <libintl.h>
43 #include <alloca.h>
44
45 #include "httpd.h"
46 #include "http_config.h"
47 #include "http_core.h"
48 #include "http_protocol.h"
49 #include "http_log.h"
50 #include "http_main.h"
51 #include "papi.h"
52 #ifndef APACHE_RELEASE /* appears to only exist in Apache 1.X */
53 #define APACHE2
54 #include "apr_compat.h"
55 #endif
56
57 #include <papi.h>
58 #include <ipp-listener.h>
59
60 #ifndef APACHE2
61 module MODULE_VAR_EXPORT ipp_module;
62 #else
63 module AP_MODULE_DECLARE_DATA ipp_module;
64 #endif
65
66 #ifndef AP_INIT_TAKE1 /* Apache 2.X has this, but 1.3.X does not */
67 #define AP_INIT_NO_ARGS(directive, action, arg, where, mesg) \
68 { directive, action, arg, where, NO_ARGS, mesg }
69 #define AP_INIT_TAKE1(directive, action, arg, where, mesg) \
70 { directive, action, arg, where, TAKE1, mesg }
71 #define AP_INIT_TAKE2(directive, action, arg, where, mesg) \
72 { directive, action, arg, where, TAKE2, mesg }
73 #endif
74
177 }
178
179 void _log_rerror(const char *file, int line, int level, request_rec *r,
180 const char *fmt, ...)
181 {
182 va_list args;
183 size_t size;
184 char *message = alloca(BUFSIZ);
185
186 va_start(args, fmt);
187 /*
188 * fill in the message. If the buffer is too small, allocate
189 * one that is large enough and fill it in.
190 */
191 if ((size = vsnprintf(message, BUFSIZ, fmt, args)) >= BUFSIZ)
192 if ((message = alloca(size)) != NULL)
193 vsnprintf(message, size, fmt, args);
194 va_end(args);
195
196 #ifdef APACHE2
197 ap_log_rerror(file, line, level, NULL, r, message);
198 #else
199 ap_log_rerror(file, line, level, r, message);
200 #endif
201 }
202
203 static int
204 ipp_handler(request_rec *r)
205 {
206 papi_attribute_t **request = NULL, **response = NULL;
207 IPPListenerConfig *config;
208 papi_status_t status;
209 int ret;
210
211 /* Really, IPP is all POST requests */
212 if (r->method_number != M_POST)
213 return (DECLINED);
214
215 #ifndef APACHE2
216 /*
217 * An IPP request must have a MIME type of "application/ipp"
271 }
272 (void) papiAttributeListAddString(&request, PAPI_ATTR_EXCL,
273 "uri-path", r->uri);
274
275 config = ap_get_module_config(r->per_dir_config, &ipp_module);
276 if (config != NULL) {
277 (void) papiAttributeListAddInteger(&request, PAPI_ATTR_EXCL,
278 "conformance", config->conformance);
279 (void) papiAttributeListAddCollection(&request, PAPI_ATTR_EXCL,
280 "operations", config->operations);
281 if (config->default_user != NULL)
282 (void) papiAttributeListAddString(&request,
283 PAPI_ATTR_EXCL, "default-user",
284 config->default_user);
285 if (config->default_svc != NULL)
286 (void) papiAttributeListAddString(&request,
287 PAPI_ATTR_EXCL, "default-service",
288 config->default_svc);
289 }
290
291 /*
292 * For Trusted Solaris, pass the fd number of the socket connection
293 * to the backend so the it can be forwarded to the backend print
294 * service to retrieve the sensativity label off of a multi-level
295 * port.
296 */
297 (void) papiAttributeListAddInteger(&request, PAPI_ATTR_EXCL,
298 "peer-socket", ap_bfileno(r->connection->client, B_RD));
299
300 /* process the request */
301 status = ipp_process_request(request, &response, read_data, r);
302 if (status != PAPI_OK) {
303 errno = 0;
304 _log_rerror(APLOG_MARK, APLOG_ERR, r,
305 "request failed: %s\n", papiStatusString(status));
306 discard_data(r);
307 }
308 #ifdef DEBUG
309 fprintf(stderr, "processing result: %s\n", papiStatusString(status));
310 papiAttributeListPrint(stderr, response, "response (%d) ", getpid());
311 #endif
312
313 /*
314 * If the client is using chunking and we have not yet received the
315 * final "0" sized chunk, we need to discard any data that may
316 * remain in the post request.
317 */
318 if ((r->read_chunked != 0) &&
382 static const char *
383 ipp_conformance(cmd_parms *cmd, void *cfg, const char *arg)
384 {
385 IPPListenerConfig *config = (IPPListenerConfig *)cfg;
386
387 if (strncasecmp(arg, "automatic", 4) == 0) {
388 config->conformance = IPP_PARSE_CONFORMANCE_RASH;
389 } else if (strcasecmp(arg, "1.0") == 0) {
390 config->conformance = IPP_PARSE_CONFORMANCE_LOOSE;
391 } else if (strcasecmp(arg, "1.1") == 0) {
392 config->conformance = IPP_PARSE_CONFORMANCE_STRICT;
393 } else {
394 return ("unknown conformance, try (automatic/1.0/1.1)");
395 }
396
397 return (NULL);
398 }
399
400 /*ARGSUSED0*/
401 static const char *
402 ipp_operation(cmd_parms *cmd, void *cfg, char *op, char *toggle)
403 {
404 IPPListenerConfig *config = (IPPListenerConfig *)cfg;
405 papi_status_t status;
406
407 status = ipp_configure_operation(&config->operations, op, toggle);
408 switch (status) {
409 case PAPI_OK:
410 return (NULL);
411 case PAPI_BAD_ARGUMENT:
412 return (gettext("internal error (invalid argument)"));
413 default:
414 return (papiStatusString(status));
415 }
416
417 /* NOTREACHED */
418 /* return (gettext("contact your software vendor")); */
419 }
420
421 static const char *
422 ipp_default_user(cmd_parms *cmd, void *cfg, const char *arg)
|
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
24 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
25 * Use is subject to license terms.
26 *
27 */
28
29 /* $Id: mod_ipp.c 149 2006-04-25 16:55:01Z njacobs $ */
30
31 /*
32 * Internet Printing Protocol (IPP) module for Apache.
33 */
34
35 #include "ap_config.h"
36
37 #include <stdio.h>
38 #include <time.h>
39 #include <sys/time.h>
40 #include <values.h>
41 #include <libintl.h>
42 #include <alloca.h>
43
44 #include "httpd.h"
45 #include "http_config.h"
46 #include "http_core.h"
47 #include "http_protocol.h"
48 #include "http_log.h"
49 #include "http_main.h"
50 #include "papi.h"
51 #ifndef APACHE_RELEASE /* appears to only exist in Apache 1.X */
52 #define APACHE2
53 #define ap_table_get apr_table_get
54 #endif
55
56 #include <papi.h>
57 #include <ipp-listener.h>
58
59 #ifndef APACHE2
60 module MODULE_VAR_EXPORT ipp_module;
61 #else
62 module AP_MODULE_DECLARE_DATA ipp_module;
63 #endif
64
65 #ifndef AP_INIT_TAKE1 /* Apache 2.X has this, but 1.3.X does not */
66 #define AP_INIT_NO_ARGS(directive, action, arg, where, mesg) \
67 { directive, action, arg, where, NO_ARGS, mesg }
68 #define AP_INIT_TAKE1(directive, action, arg, where, mesg) \
69 { directive, action, arg, where, TAKE1, mesg }
70 #define AP_INIT_TAKE2(directive, action, arg, where, mesg) \
71 { directive, action, arg, where, TAKE2, mesg }
72 #endif
73
176 }
177
178 void _log_rerror(const char *file, int line, int level, request_rec *r,
179 const char *fmt, ...)
180 {
181 va_list args;
182 size_t size;
183 char *message = alloca(BUFSIZ);
184
185 va_start(args, fmt);
186 /*
187 * fill in the message. If the buffer is too small, allocate
188 * one that is large enough and fill it in.
189 */
190 if ((size = vsnprintf(message, BUFSIZ, fmt, args)) >= BUFSIZ)
191 if ((message = alloca(size)) != NULL)
192 vsnprintf(message, size, fmt, args);
193 va_end(args);
194
195 #ifdef APACHE2
196 ap_log_rerror(file, line, level, APR_SUCCESS, r, message);
197 #else
198 ap_log_rerror(file, line, level, r, message);
199 #endif
200 }
201
202 static int
203 ipp_handler(request_rec *r)
204 {
205 papi_attribute_t **request = NULL, **response = NULL;
206 IPPListenerConfig *config;
207 papi_status_t status;
208 int ret;
209
210 /* Really, IPP is all POST requests */
211 if (r->method_number != M_POST)
212 return (DECLINED);
213
214 #ifndef APACHE2
215 /*
216 * An IPP request must have a MIME type of "application/ipp"
270 }
271 (void) papiAttributeListAddString(&request, PAPI_ATTR_EXCL,
272 "uri-path", r->uri);
273
274 config = ap_get_module_config(r->per_dir_config, &ipp_module);
275 if (config != NULL) {
276 (void) papiAttributeListAddInteger(&request, PAPI_ATTR_EXCL,
277 "conformance", config->conformance);
278 (void) papiAttributeListAddCollection(&request, PAPI_ATTR_EXCL,
279 "operations", config->operations);
280 if (config->default_user != NULL)
281 (void) papiAttributeListAddString(&request,
282 PAPI_ATTR_EXCL, "default-user",
283 config->default_user);
284 if (config->default_svc != NULL)
285 (void) papiAttributeListAddString(&request,
286 PAPI_ATTR_EXCL, "default-service",
287 config->default_svc);
288 }
289
290 #ifndef APACHE2
291 /*
292 * For Trusted Solaris, pass the fd number of the socket connection
293 * to the backend so the it can be forwarded to the backend print
294 * service to retrieve the sensativity label off of a multi-level
295 * port.
296 */
297 (void) papiAttributeListAddInteger(&request, PAPI_ATTR_EXCL,
298 "peer-socket", ap_bfileno(r->connection->client, B_RD));
299 #endif
300
301 /* process the request */
302 status = ipp_process_request(request, &response, read_data, r);
303 if (status != PAPI_OK) {
304 errno = 0;
305 _log_rerror(APLOG_MARK, APLOG_ERR, r,
306 "request failed: %s\n", papiStatusString(status));
307 discard_data(r);
308 }
309 #ifdef DEBUG
310 fprintf(stderr, "processing result: %s\n", papiStatusString(status));
311 papiAttributeListPrint(stderr, response, "response (%d) ", getpid());
312 #endif
313
314 /*
315 * If the client is using chunking and we have not yet received the
316 * final "0" sized chunk, we need to discard any data that may
317 * remain in the post request.
318 */
319 if ((r->read_chunked != 0) &&
383 static const char *
384 ipp_conformance(cmd_parms *cmd, void *cfg, const char *arg)
385 {
386 IPPListenerConfig *config = (IPPListenerConfig *)cfg;
387
388 if (strncasecmp(arg, "automatic", 4) == 0) {
389 config->conformance = IPP_PARSE_CONFORMANCE_RASH;
390 } else if (strcasecmp(arg, "1.0") == 0) {
391 config->conformance = IPP_PARSE_CONFORMANCE_LOOSE;
392 } else if (strcasecmp(arg, "1.1") == 0) {
393 config->conformance = IPP_PARSE_CONFORMANCE_STRICT;
394 } else {
395 return ("unknown conformance, try (automatic/1.0/1.1)");
396 }
397
398 return (NULL);
399 }
400
401 /*ARGSUSED0*/
402 static const char *
403 ipp_operation(cmd_parms *cmd, void *cfg, const char *op, const char *toggle)
404 {
405 IPPListenerConfig *config = (IPPListenerConfig *)cfg;
406 papi_status_t status;
407
408 status = ipp_configure_operation(&config->operations, op, toggle);
409 switch (status) {
410 case PAPI_OK:
411 return (NULL);
412 case PAPI_BAD_ARGUMENT:
413 return (gettext("internal error (invalid argument)"));
414 default:
415 return (papiStatusString(status));
416 }
417
418 /* NOTREACHED */
419 /* return (gettext("contact your software vendor")); */
420 }
421
422 static const char *
423 ipp_default_user(cmd_parms *cmd, void *cfg, const char *arg)
|