diff options
| author | Gordon Ross <gwr@nexenta.com> | 2015-02-11 22:03:23 -0500 |
|---|---|---|
| committer | Gordon Ross <gwr@nexenta.com> | 2015-02-20 17:39:46 -0500 |
| commit | b0e753dd6a955fb2f10a0ce17d32bd33172e0400 (patch) | |
| tree | 0f7dce01db9bba61fdfbc85e8bc39a74bad6fca1 /usr/src/lib/print | |
| parent | e6cb0f7efa539f8e48e8c1be930a922d8f78ff21 (diff) | |
| download | illumos-joyent-b0e753dd6a955fb2f10a0ce17d32bd33172e0400.tar.gz | |
5609 port mod_ipp to Apache 2.2
Reviewed by: Garrett D'Amore <garrett@damore.org>
Reviewed by: Alexander Pyhalov <alp@rsu.ru>
Approved by: Garrett D'Amore <garrett@damore.org>
Diffstat (limited to 'usr/src/lib/print')
| -rw-r--r-- | usr/src/lib/print/mod_ipp/Makefile | 40 | ||||
| -rw-r--r-- | usr/src/lib/print/mod_ipp/httpd-standalone-ipp.conf | 38 | ||||
| -rw-r--r-- | usr/src/lib/print/mod_ipp/httpd-syms.map | 43 | ||||
| -rw-r--r-- | usr/src/lib/print/mod_ipp/ipp-listener.xml | 3 | ||||
| -rw-r--r-- | usr/src/lib/print/mod_ipp/mod_ipp.c | 129 |
5 files changed, 162 insertions, 91 deletions
diff --git a/usr/src/lib/print/mod_ipp/Makefile b/usr/src/lib/print/mod_ipp/Makefile index 8d6500fb41..395c75e0e3 100644 --- a/usr/src/lib/print/mod_ipp/Makefile +++ b/usr/src/lib/print/mod_ipp/Makefile @@ -22,6 +22,8 @@ # Copyright 2010 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # +# Copyright 2015 Nexenta Systems, Inc. All rights reserved. +# LIBRARY = mod_ipp.a VERS = @@ -30,13 +32,22 @@ OBJECTS = mod_ipp.o include ../../Makefile.lib include ../../Makefile.rootfs -APACHEMODDIR = $(ROOT)/usr/apache/libexec -APACHECONFDIR = $(ROOT)/etc/apache +# These *BASE paths are used ONLY at build time to locate headers. +# This builds against Apache 2.2 but the module should work with +# any Apache 2.x version +APACHEBASE = /usr/apache2/2.2 +APR_BASE = /usr/apr +APRUBASE = /usr/apr-util + +IPPCONFDIR = $(ROOT)/etc/lp/ipp +IPPLIBDIR = $(ROOT)/usr/lib/lp/ipp LISTENERDIR = $(ROOT)/var/lp/ipp-listener -ROOTDIRS = $(ROOT)/usr/apache $(APACHEMODDIR) $(APACHECONFDIR) \ +ROOTDIRS = $(ROOT)/etc/lp $(IPPCONFDIR) \ + $(ROOT)/usr/lib/lp $(IPPLIBDIR) \ $(ROOT)/var/lp $(LISTENERDIR) +$(ROOT)/etc/lp:= DIRMODE = 775 $(ROOT)/var/lp:= DIRMODE = 775 $(ROOT)/var/lp:= FILEMODE = 775 @@ -48,11 +59,17 @@ SRCS = $(OBJECTS:%.o = %.c) CFLAGS += $(CCVERBOSE) CPPFLAGS += -I../libipp-listener/common CPPFLAGS += -I../libipp-core/common -CPPFLAGS += -I/usr/apache/include +CPPFLAGS += -I$(ADJUNCT_PROTO)$(APACHEBASE)/include +CPPFLAGS += -I$(ADJUNCT_PROTO)$(APR_BASE)/include +CPPFLAGS += -I$(ADJUNCT_PROTO)$(APRUBASE)/include +CPPFLAGS += -DAPACHE2 CPPFLAGS += -DEAPI -ZDEFS = $(ZNODEFS) -MAPFILES = mapfile +# See: /usr/apache2/2.2/build/config_vars.mk +# Make sure to build with compatible flags. +CPPFLAGS += -D_REENTRANT -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 + +MAPFILES = mapfile httpd-syms.map LDLIBS += -lipp-listener -lipp-core -lpapi -lc @@ -63,19 +80,20 @@ ROOTMANIFEST= $(MANIFEST:%=$(ROOTMANIFESTDIR)/%) $(ROOTMANIFEST) := FILEMODE= 444 # Apache module -$(APACHEMODDIR)/$(LIBLINKS): $(ROOTDIRS) +# LIBLINKS is not a link here, just the bare *.so name +$(IPPLIBDIR)/$(LIBLINKS): $(ROOTDIRS) # Apache config -APACHECONFFILE= $(APACHECONFDIR)/httpd-standalone-ipp.conf +APACHECONFFILE= $(IPPCONFDIR)/httpd-standalone-ipp.conf $(APACHECONFFILE) := FILEMODE= 644 LISTENERFILE= $(LISTENERDIR)/index.html $(LISTENERFILE) := FILEMODE= 444 $(ROOT)/var/lp:= FILEMODE = 0775 -$(APACHEMODDIR)/$(LIBLINKS):= FILEMODE = 0555 +$(IPPLIBDIR)/$(LIBLINKS):= FILEMODE = 0555 -$(ROOTMANIFESTDIR)/% $(APACHEMODDIR)/% $(APACHECONFDIR)/% $(LISTENERDIR)/%: % +$(ROOTMANIFESTDIR)/% $(IPPLIBDIR)/% $(IPPCONFDIR)/% $(LISTENERDIR)/%: % $(INS.file) $(ROOTDIRS): @@ -85,7 +103,7 @@ $(ROOTDIRS): all: $(LIBS) -install: all $(APACHEMODDIR)/$(LIBLINKS) $(APACHECONFFILE) \ +install: all $(IPPLIBDIR)/$(LIBLINKS) $(APACHECONFFILE) \ $(LISTENERFILE) $(ROOTMANIFEST) install_h: diff --git a/usr/src/lib/print/mod_ipp/httpd-standalone-ipp.conf b/usr/src/lib/print/mod_ipp/httpd-standalone-ipp.conf index 07a4b8dc11..419f23fb93 100644 --- a/usr/src/lib/print/mod_ipp/httpd-standalone-ipp.conf +++ b/usr/src/lib/print/mod_ipp/httpd-standalone-ipp.conf @@ -28,8 +28,6 @@ # "$Id: httpd-standalone-ipp.conf,v 1.4 2006/03/24 00:26:54 njacobs Exp $" # -# ident "%Z%%M% %I% %E% SMI" - ## ## httpd-standalone-ipp.conf -- Apache HTTP server configuration file for ## an Internet Print Protocol (IPP) listener @@ -53,12 +51,6 @@ # # -# ServerType is either inetd, or standalone. Inetd mode is only supported on -# Unix platforms. -# -ServerType standalone - -# # ServerRoot: The top of the directory tree under which the server's # configuration, error, and log files are kept. # @@ -67,7 +59,8 @@ ServerType standalone # (available at <URL:http://www.apache.org/docs/mod/core.html#lockfile>); # you will save yourself a lot of trouble. # -ServerRoot "/usr/apache" +# Change /usr/apache2/... if Apache 2.x is elsewhere. +ServerRoot "/usr/apache2/2.2" # # The LockFile directive sets the path to the lockfile used when Apache @@ -192,24 +185,14 @@ MaxRequestsPerChild 10 # Note: The order in which modules are loaded is important. Don't change # the order below without expert advice. # -LoadModule access_module libexec/mod_access.so LoadModule alias_module libexec/mod_alias.so -LoadModule auth_module libexec/mod_auth.so +LoadModule auth_basic_module libexec/mod_auth_basic.so +LoadModule authn_file_module libexec/mod_authn_file.so +LoadModule authz_host_module libexec/mod_authz_host.so +LoadModule authz_user_module libexec/mod_authz_user.so LoadModule mime_module libexec/mod_mime.so LoadModule mime_magic_module libexec/mod_mime_magic.so -LoadModule ipp_module libexec/mod_ipp.so - -# Reconstruction of the complete module list from all available modules -# (static and shared ones) to achieve correct module execution order. -# [WHENEVER YOU CHANGE THE LOADMODULE SECTION ABOVE UPDATE THIS, TOO] -ClearModuleList -AddModule mod_access.c -AddModule mod_alias.c -AddModule mod_auth.c -AddModule mod_mime.c -AddModule mod_mime_magic.c -AddModule mod_ipp.c -AddModule mod_so.c +LoadModule ipp_module /usr/lib/lp/ipp/mod_ipp.so ### Section 2: 'Main' server configuration # @@ -234,11 +217,11 @@ AddModule mod_so.c # Port: The port to which the standalone server listens. For # ports < 1023, you will need httpd to be run as root initially. # -Port 631 +Listen 631 # # If you wish httpd to run as a different user or group, you must run -# httpd as root initially and it will switch. +# httpd as root initially and it will switch. # # User/Group: The name (or #number) of the user/group to run httpd as. # . On SCO (ODT 3) use "User nouser" and "Group nogroup". @@ -327,6 +310,8 @@ Alias /etc/lp/ppd/ /etc/lp/ppd/ # ipp-default-user nobody ipp-default-service lpsched + # To be more restrictive, use this intead: + # ipp-operation required on ipp-operation all on AuthType Basic @@ -338,4 +323,3 @@ Alias /etc/lp/ppd/ /etc/lp/ppd/ ErrorDocument 404 /index.html </Location> </IfModule> - diff --git a/usr/src/lib/print/mod_ipp/httpd-syms.map b/usr/src/lib/print/mod_ipp/httpd-syms.map new file mode 100644 index 0000000000..2a08f20538 --- /dev/null +++ b/usr/src/lib/print/mod_ipp/httpd-syms.map @@ -0,0 +1,43 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2015 Nexenta Systems, Inc. All rights reserved. +# + +# +# These are the symbols in Apache (httpd) that this module needs +# to bind with. By explicitly telling the linker these are external, +# we can detect any other binding problems at link time. +# + +$mapfile_version 2 + +SYMBOL_SCOPE { + core_module { TYPE = data; FLAGS = extern }; + + ap_discard_request_body { TYPE = function; FLAGS = extern }; + ap_get_client_block { TYPE = function; FLAGS = extern }; + ap_get_remote_host { TYPE = function; FLAGS = extern }; + ap_get_server_name { TYPE = function; FLAGS = extern }; + ap_get_server_port { TYPE = function; FLAGS = extern }; + ap_hook_default_port { TYPE = function; FLAGS = extern }; + ap_hook_handler { TYPE = function; FLAGS = extern }; + ap_hook_http_scheme { TYPE = function; FLAGS = extern }; + ap_log_rerror { TYPE = function; FLAGS = extern }; + ap_rwrite { TYPE = function; FLAGS = extern }; + ap_setup_client_block { TYPE = function; FLAGS = extern }; + ap_should_client_block { TYPE = function; FLAGS = extern }; + + apr_os_sock_get { TYPE = function; FLAGS = extern }; + apr_palloc { TYPE = function; FLAGS = extern }; + apr_table_get { TYPE = function; FLAGS = extern }; +}; diff --git a/usr/src/lib/print/mod_ipp/ipp-listener.xml b/usr/src/lib/print/mod_ipp/ipp-listener.xml index 686646a78c..9b4c15f17c 100644 --- a/usr/src/lib/print/mod_ipp/ipp-listener.xml +++ b/usr/src/lib/print/mod_ipp/ipp-listener.xml @@ -41,10 +41,11 @@ CDDL HEADER END <service_fmri value='svc:/application/print/server' /> </dependency> + <!-- Change /usr/apache2/... if Apache 2.x is elsewhere. --> <exec_method type='method' name='start' - exec='/usr/apache/bin/httpd -f /etc/apache/httpd-standalone-ipp.conf' + exec='/usr/apache2/2.2/bin/httpd -f /etc/lp/ipp/httpd-standalone-ipp.conf' timeout_seconds='10' /> <exec_method diff --git a/usr/src/lib/print/mod_ipp/mod_ipp.c b/usr/src/lib/print/mod_ipp/mod_ipp.c index 2d9ece2287..813b04723c 100644 --- a/usr/src/lib/print/mod_ipp/mod_ipp.c +++ b/usr/src/lib/print/mod_ipp/mod_ipp.c @@ -23,12 +23,11 @@ * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. * + * Copyright 2015 Nexenta Systems, Inc. All rights reserved. */ /* $Id: mod_ipp.c 149 2006-04-25 16:55:01Z njacobs $ */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * Internet Printing Protocol (IPP) module for Apache. */ @@ -36,6 +35,7 @@ #include "ap_config.h" #include <stdio.h> +#include <unistd.h> #include <time.h> #include <sys/time.h> #include <values.h> @@ -48,11 +48,12 @@ #include "http_protocol.h" #include "http_log.h" #include "http_main.h" -#include "papi.h" -#ifndef APACHE_RELEASE /* appears to only exist in Apache 1.X */ -#define APACHE2 +#ifndef APACHE2 #include "apr_compat.h" -#endif +#define apr_table_get ap_table_get +#endif /* APACHE2 */ + +#include "papi.h" #include <papi.h> #include <ipp-listener.h> @@ -123,7 +124,7 @@ read_data(void *fd, void *buf, size_t siz) #ifdef DEBUG fprintf(stderr, "read_data(0x%8.8x, 0x%8.8x, %d): %d", - fd, buf, siz, len_read); + fd, buf, siz, len_read); if (len_read < 0) fprintf(stderr, ": %s", strerror(errno)); putc('\n', stderr); @@ -194,7 +195,7 @@ void _log_rerror(const char *file, int line, int level, request_rec *r, va_end(args); #ifdef APACHE2 - ap_log_rerror(file, line, level, NULL, r, message); + ap_log_rerror(file, line, level, APR_SUCCESS, r, message); #else ap_log_rerror(file, line, level, r, message); #endif @@ -206,28 +207,26 @@ ipp_handler(request_rec *r) papi_attribute_t **request = NULL, **response = NULL; IPPListenerConfig *config; papi_status_t status; + const char *s; + int sockfd = -1; 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 (r->headers_in == NULL) + return (DECLINED); + s = apr_table_get(r->headers_in, "Content-Type"); + if ((s == NULL) || (strcasecmp(s, "application/ipp") != 0)) + return (DECLINED); - 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); @@ -243,49 +242,50 @@ ipp_handler(request_rec *r) if (status != PAPI_OK) _log_rerror(APLOG_MARK, APLOG_ERR, r, - "read failed: %s\n", papiStatusString(status)); + "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)); + s = 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)); + s = ap_get_remote_host(r->connection, r->per_dir_config, + REMOTE_NAME); #endif + (void) papiAttributeListAddString(&request, PAPI_ATTR_EXCL, + "originating-host", (char *)s); (void) papiAttributeListAddInteger(&request, PAPI_ATTR_EXCL, - "uri-port", ap_get_server_port(r)); + "uri-port", ap_get_server_port(r)); + if (r->headers_in != NULL) { - char *host = (char *)ap_table_get(r->headers_in, "Host"); + char *host = (char *)apr_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); + "uri-host", host); } (void) papiAttributeListAddString(&request, PAPI_ATTR_EXCL, - "uri-path", r->uri); + "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); + "conformance", config->conformance); (void) papiAttributeListAddCollection(&request, PAPI_ATTR_EXCL, - "operations", config->operations); + "operations", config->operations); if (config->default_user != NULL) (void) papiAttributeListAddString(&request, - PAPI_ATTR_EXCL, "default-user", - config->default_user); + PAPI_ATTR_EXCL, "default-user", + config->default_user); if (config->default_svc != NULL) (void) papiAttributeListAddString(&request, - PAPI_ATTR_EXCL, "default-service", - config->default_svc); + PAPI_ATTR_EXCL, "default-service", + config->default_svc); } /* @@ -294,15 +294,35 @@ ipp_handler(request_rec *r) * 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)); +#ifdef APACHE2 + /* + * In Apache 2.4 and later, could use: ap_get_conn_socket() + * Apache 2.2 uses ap_get_module_config() but that needs + * &core_module, for .module_index (which is just zero). + * Could either inline that with index zero, or declare + * core_module here. Latter seems less evil. + */ + { + extern module core_module; + apr_socket_t *csd = ap_get_module_config( + r->connection->conn_config, &core_module); + if (csd != NULL) + (void) apr_os_sock_get(&sockfd, csd); + } +#else + sockfd = ap_bfileno(r->connection->client, B_RD); +#endif + if (sockfd != -1) { + (void) papiAttributeListAddInteger(&request, + PAPI_ATTR_EXCL, "peer-socket", sockfd); + } /* 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)); + "request failed: %s\n", papiStatusString(status)); discard_data(r); } #ifdef DEBUG @@ -316,7 +336,7 @@ ipp_handler(request_rec *r) * remain in the post request. */ if ((r->read_chunked != 0) && - (ap_table_get(r->headers_in, "Content-Length") == NULL)) + (apr_table_get(r->headers_in, "Content-Length") == NULL)) discard_data(r); /* write an IPP response back to the network */ @@ -329,7 +349,7 @@ ipp_handler(request_rec *r) 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)); + "write failed: %s\n", papiStatusString(status)); #ifdef DEBUG fprintf(stderr, "write result: %s\n", papiStatusString(status)); fflush(stderr); @@ -342,7 +362,7 @@ ipp_handler(request_rec *r) ap_kill_timeout(r); if (ap_rflush(r) < 0) _log_rerror(APLOG_MARK, APLOG_ERR, r, - "flush failed, response may not have been sent"); + "flush failed, response may not have been sent"); #endif return (OK); @@ -359,11 +379,11 @@ create_ipp_dir_config( #endif char *dirspec) { - IPPListenerConfig *config = + IPPListenerConfig *config; #ifndef APACHE2 - ap_pcalloc(p, sizeof (*config)); + config = ap_pcalloc(p, sizeof (*config)); #else - apr_pcalloc(p, sizeof (*config)); + config = apr_pcalloc(p, sizeof (*config)); #endif if (config != NULL) { @@ -371,8 +391,8 @@ create_ipp_dir_config( config->conformance = IPP_PARSE_CONFORMANCE_RASH; config->default_user = NULL; config->default_svc = NULL; - (void) ipp_configure_operation(&config->operations, "required", - "enable"); + (void) ipp_configure_operation(&config->operations, + "required", "enable"); } return (config); @@ -399,12 +419,13 @@ ipp_conformance(cmd_parms *cmd, void *cfg, const char *arg) /*ARGSUSED0*/ static const char * -ipp_operation(cmd_parms *cmd, void *cfg, char *op, char *toggle) +ipp_operation(cmd_parms *cmd, void *cfg, const char *op, const char *toggle) { IPPListenerConfig *config = (IPPListenerConfig *)cfg; papi_status_t status; - status = ipp_configure_operation(&config->operations, op, toggle); + status = ipp_configure_operation(&config->operations, + (char *)op, (char *)toggle); switch (status) { case PAPI_OK: return (NULL); @@ -440,13 +461,17 @@ ipp_default_svc(cmd_parms *cmd, void *cfg, const char *arg) #ifdef DEBUG /*ARGSUSED0*/ +volatile int ipp_module_hang_sleeping = 1; static const char * ipp_module_hang(cmd_parms *cmd, void *cfg) { - static int i = 1; - /* wait so we can attach a debugger, assign i = 0, and step through */ - while (i); + /* + * Wait so we can attach with a debugger. Once attached, + * assign ipp_module_hang_sleeping = 0 and step through. + */ + while (ipp_module_hang_sleeping) + sleep(1); return (NULL); } @@ -472,7 +497,7 @@ static const command_rec ipp_cmds[] = #ifdef APACHE2 /*ARGSUSED0*/ static const char * -ipp_method(const request_rec *r) +ipp_scheme(const request_rec *r) { return ("ipp"); } @@ -494,7 +519,7 @@ ipp_register_hooks(apr_pool_t *p) /* Need to make sure we don't get directory listings by accident */ ap_hook_handler(ipp_handler, NULL, modules, APR_HOOK_MIDDLE); ap_hook_default_port(ipp_port, NULL, NULL, APR_HOOK_MIDDLE); - ap_hook_http_method(ipp_method, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_http_scheme(ipp_scheme, NULL, NULL, APR_HOOK_MIDDLE); } module AP_MODULE_DECLARE_DATA ipp_module = { |
