xref: /illumos-gate/usr/src/cmd/lp/cmd/lpsched/validate.c (revision 45916cd2fec6e79bca5dee0421bd39e3c2910d1e)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*45916cd2Sjpk  * Common Development and Distribution License (the "License").
6*45916cd2Sjpk  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22*45916cd2Sjpk  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
277c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate 
30*45916cd2Sjpk #pragma ident	"%Z%%M%	%I%	%E% SMI"
31*45916cd2Sjpk /* SVr4.0 1.11.1.10	*/
327c478bd9Sstevel@tonic-gate /* EMACS_MODES: !fill, lnumb, !overwrite, !nodelete, !picture */
337c478bd9Sstevel@tonic-gate 
347c478bd9Sstevel@tonic-gate #include "lpsched.h"
357c478bd9Sstevel@tonic-gate 
367c478bd9Sstevel@tonic-gate #include "validate.h"
377c478bd9Sstevel@tonic-gate 
38*45916cd2Sjpk #include <syslog.h>
39*45916cd2Sjpk #include <errno.h>
40*45916cd2Sjpk #include <deflt.h>
41*45916cd2Sjpk #include <tsol/label.h>
42*45916cd2Sjpk #include <auth_list.h>
43*45916cd2Sjpk 
447c478bd9Sstevel@tonic-gate #define register auto
457c478bd9Sstevel@tonic-gate 
46*45916cd2Sjpk 
477c478bd9Sstevel@tonic-gate int		pickfilter ( RSTATUS * , CANDIDATE * , FSTATUS * );
487c478bd9Sstevel@tonic-gate 
497c478bd9Sstevel@tonic-gate unsigned long		chkprinter_result	= 0;
507c478bd9Sstevel@tonic-gate char *			o_cpi		= 0;
517c478bd9Sstevel@tonic-gate char *			o_lpi		= 0;
527c478bd9Sstevel@tonic-gate char *			o_width		= 0;
537c478bd9Sstevel@tonic-gate char *			o_length	= 0;
547c478bd9Sstevel@tonic-gate 
557c478bd9Sstevel@tonic-gate static int		wants_nobanner	= 0;
56*45916cd2Sjpk static int		wants_nolabels	= 0;
577c478bd9Sstevel@tonic-gate static int		lp_or_root	= 0;
587c478bd9Sstevel@tonic-gate 
597c478bd9Sstevel@tonic-gate static int		_chkopts ( RSTATUS *, CANDIDATE * , FSTATUS * );
607c478bd9Sstevel@tonic-gate static void		free_candidate ( CANDIDATE * );
61*45916cd2Sjpk static int		tsol_check_printer_label_range(char *, const char *);
62*45916cd2Sjpk static int		tsol_lpauth(char *, char *);
63*45916cd2Sjpk static int		secpolicy_chkpolicy(char *policyp);
647c478bd9Sstevel@tonic-gate 
657c478bd9Sstevel@tonic-gate /**
667c478bd9Sstevel@tonic-gate  ** _validate() - FIND A PRINTER TO HANDLE A REQUEST
677c478bd9Sstevel@tonic-gate  **/
687c478bd9Sstevel@tonic-gate 
697c478bd9Sstevel@tonic-gate short
707c478bd9Sstevel@tonic-gate _validate(RSTATUS *prs, PSTATUS *pps, PSTATUS *stop_pps, char **prefixp,
717c478bd9Sstevel@tonic-gate 	 int moving)
727c478bd9Sstevel@tonic-gate {
737c478bd9Sstevel@tonic-gate 	register CANDIDATE	*pc		= 0,
747c478bd9Sstevel@tonic-gate 				*pcend,
757c478bd9Sstevel@tonic-gate 				*best_pc	= 0;
767c478bd9Sstevel@tonic-gate 
777c478bd9Sstevel@tonic-gate 	register FSTATUS	*pfs		= 0;
787c478bd9Sstevel@tonic-gate 
797c478bd9Sstevel@tonic-gate 	register CSTATUS	*pcs		= 0;
807c478bd9Sstevel@tonic-gate 
817c478bd9Sstevel@tonic-gate 	CANDIDATE		*arena		= 0,
827c478bd9Sstevel@tonic-gate 				single;
837c478bd9Sstevel@tonic-gate 
847c478bd9Sstevel@tonic-gate 	size_t			n;
857c478bd9Sstevel@tonic-gate 
867c478bd9Sstevel@tonic-gate 	short			ret;
877c478bd9Sstevel@tonic-gate 
887c478bd9Sstevel@tonic-gate 	chkprinter_result = 0;
897c478bd9Sstevel@tonic-gate 	o_cpi = o_lpi = o_width = o_length = 0;
907c478bd9Sstevel@tonic-gate 	wants_nobanner = 0;
917c478bd9Sstevel@tonic-gate 	memset (&single, 0, sizeof(single));
927c478bd9Sstevel@tonic-gate 
93*45916cd2Sjpk 	wants_nolabels = 0;
94*45916cd2Sjpk 	/*
95*45916cd2Sjpk 	 * If the system is labeled, the printing of postscript files
96*45916cd2Sjpk 	 * is restricted.  All users can print postscript files if the
97*45916cd2Sjpk 	 * file /etc/default/print contains "PRINT_POSTSCRIPT=1".
98*45916cd2Sjpk 	 * (this is checked by secpolicy_chkpolicy).  Otherwise the
99*45916cd2Sjpk 	 * user must have PRINT_POSTSCRIPT_AUTH to print postscript files.
100*45916cd2Sjpk 	 */
101*45916cd2Sjpk 	if ((is_system_labeled() &&
102*45916cd2Sjpk 	    strcmp(prs->request->input_type, "postscript") == 0) &&
103*45916cd2Sjpk 	    (secpolicy_chkpolicy("PRINT_POSTSCRIPT=") == 0)) {
104*45916cd2Sjpk 		if (tsol_lpauth(PRINT_POSTSCRIPT_AUTH, prs->secure->user)
105*45916cd2Sjpk 		    == 0) {
106*45916cd2Sjpk 			ret = MDENYDEST;
107*45916cd2Sjpk 			goto Return;
108*45916cd2Sjpk 		}
109*45916cd2Sjpk 	}
1107c478bd9Sstevel@tonic-gate 	lp_or_root = 0;
1117c478bd9Sstevel@tonic-gate 
1127c478bd9Sstevel@tonic-gate 	if (STREQU(prs->secure->system, Local_System))
1137c478bd9Sstevel@tonic-gate 		if (bangequ(prs->secure->user, "root") ||
1147c478bd9Sstevel@tonic-gate 					bangequ(prs->secure->user, "lp"))
1157c478bd9Sstevel@tonic-gate 			lp_or_root = 1;
1167c478bd9Sstevel@tonic-gate 
1177c478bd9Sstevel@tonic-gate 
1187c478bd9Sstevel@tonic-gate 	if (prefixp)
1197c478bd9Sstevel@tonic-gate 		*prefixp = prs->request->destination;
1207c478bd9Sstevel@tonic-gate 
1217c478bd9Sstevel@tonic-gate 	/*
1227c478bd9Sstevel@tonic-gate 	 * If a destination other than "any" was given,
1237c478bd9Sstevel@tonic-gate 	 * see if it exists in our internal tables.
1247c478bd9Sstevel@tonic-gate 	 */
1257c478bd9Sstevel@tonic-gate 	if (!pps && prs->request->destination &&
1267c478bd9Sstevel@tonic-gate 	    !STREQU(prs->request->destination, NAME_ANY))
1277c478bd9Sstevel@tonic-gate 		if (((pps = search_ptable(prs->request->destination)) != NULL) ||
1287c478bd9Sstevel@tonic-gate 		    ((pcs = search_ctable(prs->request->destination)) != NULL) &&
1297c478bd9Sstevel@tonic-gate 		    pcs->class->members)
1307c478bd9Sstevel@tonic-gate 			/*EMPTY*/;
1317c478bd9Sstevel@tonic-gate 		else {
1327c478bd9Sstevel@tonic-gate 			ret = MNODEST;
1337c478bd9Sstevel@tonic-gate 			goto Return;
1347c478bd9Sstevel@tonic-gate 		}
1357c478bd9Sstevel@tonic-gate 
1367c478bd9Sstevel@tonic-gate 	/*
1377c478bd9Sstevel@tonic-gate 	 * If we are trying to avoid a printer, but the request
1387c478bd9Sstevel@tonic-gate 	 * was destined for just that printer, we're out.
1397c478bd9Sstevel@tonic-gate 	 */
1407c478bd9Sstevel@tonic-gate 	if (pps && pps == stop_pps) {
1417c478bd9Sstevel@tonic-gate 		ret = MERRDEST;
1427c478bd9Sstevel@tonic-gate 		goto Return;
1437c478bd9Sstevel@tonic-gate 	}
1447c478bd9Sstevel@tonic-gate 
1457c478bd9Sstevel@tonic-gate 	/*
1467c478bd9Sstevel@tonic-gate 	 * If a form was given, see if it exists; if so,
1477c478bd9Sstevel@tonic-gate 	 * see if the user is allowed to use it.
1487c478bd9Sstevel@tonic-gate 	 * If a remote printer was specified, then don't use any local
1497c478bd9Sstevel@tonic-gate 	 * form knowledge.
1507c478bd9Sstevel@tonic-gate 	 */
1517c478bd9Sstevel@tonic-gate 	if (prs && prs->request && prs->request->form && (pps || pcs)) {
1527c478bd9Sstevel@tonic-gate 		if ((pfs = search_ftable(prs->request->form))) {
1537c478bd9Sstevel@tonic-gate 			if (lp_or_root || allowed(prs->secure->user,
1547c478bd9Sstevel@tonic-gate 				pfs->users_allowed, pfs->users_denied))
1557c478bd9Sstevel@tonic-gate 				/*EMPTY*/;
1567c478bd9Sstevel@tonic-gate 			else {
1577c478bd9Sstevel@tonic-gate 				ret = MDENYMEDIA;
1587c478bd9Sstevel@tonic-gate 				goto Return;
1597c478bd9Sstevel@tonic-gate 			}
1607c478bd9Sstevel@tonic-gate 		} else {
1617c478bd9Sstevel@tonic-gate 			ret = MNOMEDIA;
1627c478bd9Sstevel@tonic-gate 			goto Return;
1637c478bd9Sstevel@tonic-gate 		}
1647c478bd9Sstevel@tonic-gate 	}
1657c478bd9Sstevel@tonic-gate 
1667c478bd9Sstevel@tonic-gate 	/*
1677c478bd9Sstevel@tonic-gate 	 * If the request includes -o options there may be pitch and
1687c478bd9Sstevel@tonic-gate 	 * size and no-banner requests that have to be checked. One
1697c478bd9Sstevel@tonic-gate 	 * could argue that this shouldn't be in the Spooler, because
1707c478bd9Sstevel@tonic-gate 	 * the Spooler's job is SPOOLING, not PRINTING. That's right,
1717c478bd9Sstevel@tonic-gate 	 * except that the Spooler will be making a choice of printers
1727c478bd9Sstevel@tonic-gate 	 * so it has to evaluate carefully: E.g. user wants ANY printer,
1737c478bd9Sstevel@tonic-gate 	 * so we should pick one that can handle what he/she wants.
1747c478bd9Sstevel@tonic-gate 	 *
1757c478bd9Sstevel@tonic-gate 	 * Parse out the important stuff here so we have it when we
1767c478bd9Sstevel@tonic-gate 	 * need it.
1777c478bd9Sstevel@tonic-gate 	 */
1787c478bd9Sstevel@tonic-gate 	{
1797c478bd9Sstevel@tonic-gate 		register char		**list,
1807c478bd9Sstevel@tonic-gate 					**pl;
1817c478bd9Sstevel@tonic-gate 
1827c478bd9Sstevel@tonic-gate 		if (
1837c478bd9Sstevel@tonic-gate 			prs->request->options
1847c478bd9Sstevel@tonic-gate 		     && (list = dashos(prs->request->options))
1857c478bd9Sstevel@tonic-gate 		) {
1867c478bd9Sstevel@tonic-gate 			for (pl = list ; *pl; pl++)
1877c478bd9Sstevel@tonic-gate 				if (STRNEQU(*pl, "cpi=", 4))
1887c478bd9Sstevel@tonic-gate 					o_cpi = Strdup(*pl + 4);
1897c478bd9Sstevel@tonic-gate 				else if (STRNEQU(*pl, "lpi=", 4))
1907c478bd9Sstevel@tonic-gate 					o_lpi = Strdup(*pl + 4);
1917c478bd9Sstevel@tonic-gate 				else if (STRNEQU(*pl, "width=", 6))
1927c478bd9Sstevel@tonic-gate 					o_width = Strdup(*pl + 6);
1937c478bd9Sstevel@tonic-gate 				else if (STRNEQU(*pl, "length=", 7))
1947c478bd9Sstevel@tonic-gate 					o_length = Strdup(*pl + 7);
1957c478bd9Sstevel@tonic-gate 				else if (STREQU(*pl, "nobanner"))
1967c478bd9Sstevel@tonic-gate 					wants_nobanner = 1;
197*45916cd2Sjpk 				else if (STREQU(*pl, "nolabels"))
198*45916cd2Sjpk 					wants_nolabels = 1;
1997c478bd9Sstevel@tonic-gate 			freelist (list);
2007c478bd9Sstevel@tonic-gate 		}
2017c478bd9Sstevel@tonic-gate 	}
2027c478bd9Sstevel@tonic-gate 
2037c478bd9Sstevel@tonic-gate 	/*
2047c478bd9Sstevel@tonic-gate 	 * This macro checks that a form has a mandatory print wheel
2057c478bd9Sstevel@tonic-gate 	 * (or character set).
2067c478bd9Sstevel@tonic-gate 	 */
2077c478bd9Sstevel@tonic-gate #define	CHKMAND(PFS) \
2087c478bd9Sstevel@tonic-gate 	( \
2097c478bd9Sstevel@tonic-gate 		(PFS) \
2107c478bd9Sstevel@tonic-gate 	     && (PFS)->form->chset \
2117c478bd9Sstevel@tonic-gate 	     && !STREQU((PFS)->form->chset, NAME_ANY) \
2127c478bd9Sstevel@tonic-gate 	     && (PFS)->form->mandatory \
2137c478bd9Sstevel@tonic-gate 	)
2147c478bd9Sstevel@tonic-gate 
2157c478bd9Sstevel@tonic-gate 	/*
2167c478bd9Sstevel@tonic-gate 	 * This macro checks that the user is allowed to use the
2177c478bd9Sstevel@tonic-gate 	 * printer.
2187c478bd9Sstevel@tonic-gate 	 */
2197c478bd9Sstevel@tonic-gate #define CHKU(PRS,PPS) \
2207c478bd9Sstevel@tonic-gate 	( \
2217c478bd9Sstevel@tonic-gate 		lp_or_root \
2227c478bd9Sstevel@tonic-gate 	     || allowed( \
2237c478bd9Sstevel@tonic-gate 			(PRS)->secure->user, \
2247c478bd9Sstevel@tonic-gate 			(PPS)->users_allowed, \
2257c478bd9Sstevel@tonic-gate 			(PPS)->users_denied \
2267c478bd9Sstevel@tonic-gate 		) \
2277c478bd9Sstevel@tonic-gate 	)
2287c478bd9Sstevel@tonic-gate 
2297c478bd9Sstevel@tonic-gate 	/*
2307c478bd9Sstevel@tonic-gate 	 * This macro checks that the form is allowed on the printer,
2317c478bd9Sstevel@tonic-gate 	 * or is already mounted there.
2327c478bd9Sstevel@tonic-gate 	 * Note: By doing this check we don't have to check that the
2337c478bd9Sstevel@tonic-gate 	 * characteristics of the form, such as pitch, size, or
2347c478bd9Sstevel@tonic-gate 	 * character set, against the printer's capabilities, ASSUMING,
2357c478bd9Sstevel@tonic-gate 	 * of course, that the allow list is correct. That is, the
2367c478bd9Sstevel@tonic-gate 	 * allow list lists forms that have already been checked against
2377c478bd9Sstevel@tonic-gate 	 * the printer!
2387c478bd9Sstevel@tonic-gate 	 */
2397c478bd9Sstevel@tonic-gate #define CHKF(PFS,PPS) \
2407c478bd9Sstevel@tonic-gate 	( \
2417c478bd9Sstevel@tonic-gate 		isFormMountedOnPrinter(PPS,PFS) \
2427c478bd9Sstevel@tonic-gate 	     || allowed( \
2437c478bd9Sstevel@tonic-gate 			(PFS)->form->name, \
2447c478bd9Sstevel@tonic-gate 			(PPS)->forms_allowed, \
2457c478bd9Sstevel@tonic-gate 			(PPS)->forms_denied \
2467c478bd9Sstevel@tonic-gate 		) \
2477c478bd9Sstevel@tonic-gate 	)
2487c478bd9Sstevel@tonic-gate 
2497c478bd9Sstevel@tonic-gate 	/*
2507c478bd9Sstevel@tonic-gate 	 * This macro checks that the print wheel is acceptable
2517c478bd9Sstevel@tonic-gate 	 * for the printer or is mounted. Note: If the printer doesn't
2527c478bd9Sstevel@tonic-gate 	 * take print wheels, the check passes. The check for printers
2537c478bd9Sstevel@tonic-gate 	 * that don't take print wheels is below.
2547c478bd9Sstevel@tonic-gate 	 */
2557c478bd9Sstevel@tonic-gate #define CHKPW(PW,PPS) \
2567c478bd9Sstevel@tonic-gate 	( \
2577c478bd9Sstevel@tonic-gate 		!(PPS)->printer->daisy \
2587c478bd9Sstevel@tonic-gate 	     || ( \
2597c478bd9Sstevel@tonic-gate 			(PPS)->pwheel_name \
2607c478bd9Sstevel@tonic-gate 		     && STREQU((PPS)->pwheel_name, (PW)) \
2617c478bd9Sstevel@tonic-gate 		) \
2627c478bd9Sstevel@tonic-gate 	     || searchlist((PW), (PPS)->printer->char_sets) \
2637c478bd9Sstevel@tonic-gate 	)
2647c478bd9Sstevel@tonic-gate 
2657c478bd9Sstevel@tonic-gate 	/*
2667c478bd9Sstevel@tonic-gate 	 * This macro checks the pitch, page size, and (if need be)
2677c478bd9Sstevel@tonic-gate 	 * the character set. The character set isn't checked if the
2687c478bd9Sstevel@tonic-gate 	 * printer takes print wheels, or if the character set is
2697c478bd9Sstevel@tonic-gate 	 * listed in the printer's alias list.
2707c478bd9Sstevel@tonic-gate 	 * The form has to be checked as well; while we're sure that
2717c478bd9Sstevel@tonic-gate 	 * at least one type for each printer can handle the form's
2727c478bd9Sstevel@tonic-gate 	 * cpi/lpi/etc. characteristics (lpadmin made sure), we aren't
2737c478bd9Sstevel@tonic-gate 	 * sure that ALL the types work.
2747c478bd9Sstevel@tonic-gate 	 */
2757c478bd9Sstevel@tonic-gate #define CHKOPTS(PRS,PC,PFS) _chkopts((PRS),(PC),(PFS)) /* was a macro */
2767c478bd9Sstevel@tonic-gate 
2777c478bd9Sstevel@tonic-gate 	/*
2787c478bd9Sstevel@tonic-gate 	 * This macro checks the acceptance status of a printer.
2797c478bd9Sstevel@tonic-gate 	 * If the request is already assigned to that printer,
2807c478bd9Sstevel@tonic-gate 	 * then it's okay. It's ambiguous what should happen if
2817c478bd9Sstevel@tonic-gate 	 * originally a "-d any" request was accepted, temporarily
2827c478bd9Sstevel@tonic-gate 	 * assigned one printer, then the administrator (1) rejected
2837c478bd9Sstevel@tonic-gate 	 * further requests for the printers and (2) made the
2847c478bd9Sstevel@tonic-gate 	 * temporarily assigned printer unusable for the request.
2857c478bd9Sstevel@tonic-gate 	 * What will happen, of course, is that the request will
2867c478bd9Sstevel@tonic-gate 	 * be canceled, even though the other printers would be okay
2877c478bd9Sstevel@tonic-gate 	 * if not rejecting....but if we were to say, gee it's okay,
2887c478bd9Sstevel@tonic-gate 	 * the request has already been accepted, we may be allowing
2897c478bd9Sstevel@tonic-gate 	 * it on printers that were NEVER accepting. Thus we can
2907c478bd9Sstevel@tonic-gate 	 * continue to accept it only for the printer already assigned.
2917c478bd9Sstevel@tonic-gate 	 */
2927c478bd9Sstevel@tonic-gate #define CHKACCEPT(PRS,PPS) \
2937c478bd9Sstevel@tonic-gate 	( \
2947c478bd9Sstevel@tonic-gate 		!((PPS)->status & PS_REJECTED) \
2957c478bd9Sstevel@tonic-gate 	     || (PRS)->printer == (PPS) \
2967c478bd9Sstevel@tonic-gate 	     || moving \
2977c478bd9Sstevel@tonic-gate 	)
2987c478bd9Sstevel@tonic-gate 
2997c478bd9Sstevel@tonic-gate 	/*
3007c478bd9Sstevel@tonic-gate 	 * If a print wheel or character set is given, see if it
3017c478bd9Sstevel@tonic-gate 	 * is allowed on the form.
3027c478bd9Sstevel@tonic-gate 	 */
3037c478bd9Sstevel@tonic-gate 	if (prs->request->charset)
3047c478bd9Sstevel@tonic-gate 		if (
3057c478bd9Sstevel@tonic-gate 			!CHKMAND(pfs)
3067c478bd9Sstevel@tonic-gate 		     || STREQU(prs->request->charset, pfs->form->chset)
3077c478bd9Sstevel@tonic-gate 		)
3087c478bd9Sstevel@tonic-gate 			/*EMPTY*/;
3097c478bd9Sstevel@tonic-gate 		else {
3107c478bd9Sstevel@tonic-gate 			ret = MDENYMEDIA;
3117c478bd9Sstevel@tonic-gate 			chkprinter_result |= PCK_CHARSET;
3127c478bd9Sstevel@tonic-gate 			goto Return;
3137c478bd9Sstevel@tonic-gate 		}
3147c478bd9Sstevel@tonic-gate 
3157c478bd9Sstevel@tonic-gate 	/*
3167c478bd9Sstevel@tonic-gate 	 * If a single printer was named, check the request against it.
3177c478bd9Sstevel@tonic-gate 	 * Do the accept/reject check late so that we give the most
3187c478bd9Sstevel@tonic-gate 	 * useful information to the user.
3197c478bd9Sstevel@tonic-gate 	 */
3207c478bd9Sstevel@tonic-gate 	if (pps) {
3217c478bd9Sstevel@tonic-gate 		(pc = &single)->pps = pps;
3227c478bd9Sstevel@tonic-gate 
3237c478bd9Sstevel@tonic-gate 		/* Does the printer allow the user? */
3247c478bd9Sstevel@tonic-gate 		if (!CHKU(prs, pps)) {
3257c478bd9Sstevel@tonic-gate 			ret = MDENYDEST;
3267c478bd9Sstevel@tonic-gate 			goto Return;
3277c478bd9Sstevel@tonic-gate 		}
3287c478bd9Sstevel@tonic-gate 
329*45916cd2Sjpk 		/* Check printer label range */
330*45916cd2Sjpk 		if (is_system_labeled() && prs->secure->slabel != NULL) {
331*45916cd2Sjpk 			if (tsol_check_printer_label_range(
332*45916cd2Sjpk 			    prs->secure->slabel,
333*45916cd2Sjpk 			    pps->printer->name) == 0) {
334*45916cd2Sjpk 				ret = MDENYDEST;
335*45916cd2Sjpk 				goto Return;
336*45916cd2Sjpk 			}
337*45916cd2Sjpk 		}
338*45916cd2Sjpk 
3397c478bd9Sstevel@tonic-gate 		/* Does the printer allow the form? */
3407c478bd9Sstevel@tonic-gate 		if (pfs && !CHKF(pfs, pps)) {
3417c478bd9Sstevel@tonic-gate 			ret = MNOMOUNT;
3427c478bd9Sstevel@tonic-gate 			goto Return;
3437c478bd9Sstevel@tonic-gate 		}
3447c478bd9Sstevel@tonic-gate 
3457c478bd9Sstevel@tonic-gate 		/* Does the printer allow the pwheel? */
3467c478bd9Sstevel@tonic-gate 		if (
3477c478bd9Sstevel@tonic-gate 			prs->request->charset
3487c478bd9Sstevel@tonic-gate 		     && !CHKPW(prs->request->charset, pps)
3497c478bd9Sstevel@tonic-gate 		) {
3507c478bd9Sstevel@tonic-gate 			ret = MNOMOUNT;
3517c478bd9Sstevel@tonic-gate 			goto Return;
3527c478bd9Sstevel@tonic-gate 		}
3537c478bd9Sstevel@tonic-gate 
3547c478bd9Sstevel@tonic-gate 		/* Can printer handle the pitch/size/charset/nobanner? */
3557c478bd9Sstevel@tonic-gate 		if (!CHKOPTS(prs, pc, pfs)) {
3567c478bd9Sstevel@tonic-gate 			ret = MDENYDEST;
3577c478bd9Sstevel@tonic-gate 			goto Return;
3587c478bd9Sstevel@tonic-gate 		}
3597c478bd9Sstevel@tonic-gate 
3607c478bd9Sstevel@tonic-gate 		/* Is the printer allowing requests? */
3617c478bd9Sstevel@tonic-gate 		if (!CHKACCEPT(prs, pps)) {
3627c478bd9Sstevel@tonic-gate 			ret = MERRDEST;
3637c478bd9Sstevel@tonic-gate 			goto Return;
3647c478bd9Sstevel@tonic-gate 		}
3657c478bd9Sstevel@tonic-gate 
3667c478bd9Sstevel@tonic-gate 		/* Is there a filter which will convert the input? */
3677c478bd9Sstevel@tonic-gate 		if (!pickfilter(prs, pc, pfs)) {
3687c478bd9Sstevel@tonic-gate 			ret = MNOFILTER;
3697c478bd9Sstevel@tonic-gate 			goto Return;
3707c478bd9Sstevel@tonic-gate 		}
3717c478bd9Sstevel@tonic-gate 
3727c478bd9Sstevel@tonic-gate 		best_pc = pc;
3737c478bd9Sstevel@tonic-gate 		ret = MOK;
3747c478bd9Sstevel@tonic-gate 		goto Return;
3757c478bd9Sstevel@tonic-gate 	}
3767c478bd9Sstevel@tonic-gate 
3777c478bd9Sstevel@tonic-gate 	/*
3787c478bd9Sstevel@tonic-gate 	 * Do the acceptance check on the class (if we have one)
3797c478bd9Sstevel@tonic-gate 	 * now so we can proceed with checks on individual printers
3807c478bd9Sstevel@tonic-gate 	 * in the class. Don't toss out the request if it is already
3817c478bd9Sstevel@tonic-gate 	 * assigned a printer just because the class is NOW rejecting.
3827c478bd9Sstevel@tonic-gate 	 */
3837c478bd9Sstevel@tonic-gate 	if (
3847c478bd9Sstevel@tonic-gate 		pcs
3857c478bd9Sstevel@tonic-gate 	     && (pcs->status & CS_REJECTED)
3867c478bd9Sstevel@tonic-gate 	     && !moving
3877c478bd9Sstevel@tonic-gate 	     && !prs->printer
3887c478bd9Sstevel@tonic-gate 	) {
3897c478bd9Sstevel@tonic-gate 		ret = MERRDEST;
3907c478bd9Sstevel@tonic-gate 		goto Return;
3917c478bd9Sstevel@tonic-gate 	}
3927c478bd9Sstevel@tonic-gate 
3937c478bd9Sstevel@tonic-gate 	/*
3947c478bd9Sstevel@tonic-gate 	 * Construct a list of printers based on the destination
3957c478bd9Sstevel@tonic-gate 	 * given. Cross off those that aren't accepting requests,
3967c478bd9Sstevel@tonic-gate 	 * that can't take the form, or which the user can't use.
3977c478bd9Sstevel@tonic-gate 	 * See if the list becomes empty.
3987c478bd9Sstevel@tonic-gate 	 */
3997c478bd9Sstevel@tonic-gate 
4007c478bd9Sstevel@tonic-gate 	if (pcs)
4017c478bd9Sstevel@tonic-gate 		n = lenlist(pcs->class->members);
4027c478bd9Sstevel@tonic-gate 	else {
4037c478bd9Sstevel@tonic-gate 		n = 0;
4047c478bd9Sstevel@tonic-gate 		for (pps = walk_ptable(1); pps; pps = walk_ptable(0))
4057c478bd9Sstevel@tonic-gate 			n++;
4067c478bd9Sstevel@tonic-gate 	}
4077c478bd9Sstevel@tonic-gate 	pcend = arena = (CANDIDATE *)Calloc(n, sizeof(CANDIDATE));
4087c478bd9Sstevel@tonic-gate 
4097c478bd9Sstevel@tonic-gate 	/*
4107c478bd9Sstevel@tonic-gate 	 * Start with a list of printers that are accepting requests.
4117c478bd9Sstevel@tonic-gate 	 * Don't skip a printer if it's rejecting but the request
4127c478bd9Sstevel@tonic-gate 	 * has already been accepted for it.
4137c478bd9Sstevel@tonic-gate 	 */
4147c478bd9Sstevel@tonic-gate 	if (pcs) {
4157c478bd9Sstevel@tonic-gate 		register char		 **pn;
4167c478bd9Sstevel@tonic-gate 
4177c478bd9Sstevel@tonic-gate 		for (pn = pcs->class->members; *pn; pn++)
4187c478bd9Sstevel@tonic-gate 			if (
4197c478bd9Sstevel@tonic-gate 				((pps = search_ptable(*pn)) != NULL)
4207c478bd9Sstevel@tonic-gate 			     && pps != stop_pps
4217c478bd9Sstevel@tonic-gate 			)
4227c478bd9Sstevel@tonic-gate 				(pcend++)->pps = pps;
4237c478bd9Sstevel@tonic-gate 
4247c478bd9Sstevel@tonic-gate 
4257c478bd9Sstevel@tonic-gate 	} else
4267c478bd9Sstevel@tonic-gate 		for (pps = walk_ptable(1); pps; pps = walk_ptable(0))
4277c478bd9Sstevel@tonic-gate 			if (CHKACCEPT(prs, pps) && pps != stop_pps)
4287c478bd9Sstevel@tonic-gate 				(pcend++)->pps = pps;
4297c478bd9Sstevel@tonic-gate 
4307c478bd9Sstevel@tonic-gate 	if (pcend == arena) {
4317c478bd9Sstevel@tonic-gate 		ret = MERRDEST;
4327c478bd9Sstevel@tonic-gate 		goto Return;
4337c478bd9Sstevel@tonic-gate 	}
4347c478bd9Sstevel@tonic-gate 
4357c478bd9Sstevel@tonic-gate 	/*
4367c478bd9Sstevel@tonic-gate 	 * Clean out printers that the user can't use. We piggy-back
4377c478bd9Sstevel@tonic-gate 	 * the pitch/size/banner checks here because the same error return
4387c478bd9Sstevel@tonic-gate 	 * is given (strange, eh?).
4397c478bd9Sstevel@tonic-gate 	 */
4407c478bd9Sstevel@tonic-gate 	{
4417c478bd9Sstevel@tonic-gate 		register CANDIDATE	*pcend2;
4427c478bd9Sstevel@tonic-gate 
4437c478bd9Sstevel@tonic-gate 		for (pcend2 = pc = arena; pc < pcend; pc++) {
4447c478bd9Sstevel@tonic-gate 			if (CHKU(prs, pc->pps) && CHKOPTS(prs, pc, pfs))
4457c478bd9Sstevel@tonic-gate 				*pcend2++ = *pc;
4467c478bd9Sstevel@tonic-gate 			else
4477c478bd9Sstevel@tonic-gate 				free_candidate (pc);
4487c478bd9Sstevel@tonic-gate 		}
4497c478bd9Sstevel@tonic-gate 
4507c478bd9Sstevel@tonic-gate 		if (pcend2 == arena) {
4517c478bd9Sstevel@tonic-gate 			ret = MDENYDEST;
4527c478bd9Sstevel@tonic-gate 			goto Return;
4537c478bd9Sstevel@tonic-gate 		}
4547c478bd9Sstevel@tonic-gate 		pcend = pcend2;
4557c478bd9Sstevel@tonic-gate 
4567c478bd9Sstevel@tonic-gate 	}
4577c478bd9Sstevel@tonic-gate 
4587c478bd9Sstevel@tonic-gate 	/*
4597c478bd9Sstevel@tonic-gate 	 * Clean out printers that can't mount the form,
4607c478bd9Sstevel@tonic-gate 	 * EXCEPT for printers that already have it mounted:
4617c478bd9Sstevel@tonic-gate 	 */
4627c478bd9Sstevel@tonic-gate 	if (pfs) {
4637c478bd9Sstevel@tonic-gate 		register CANDIDATE	*pcend2;
4647c478bd9Sstevel@tonic-gate 
4657c478bd9Sstevel@tonic-gate 		for (pcend2 = pc = arena; pc < pcend; pc++)
4667c478bd9Sstevel@tonic-gate 			if (CHKF(pfs, pc->pps))
4677c478bd9Sstevel@tonic-gate 				*pcend2++ = *pc;
4687c478bd9Sstevel@tonic-gate 			else
4697c478bd9Sstevel@tonic-gate 				free_candidate (pc);
4707c478bd9Sstevel@tonic-gate 
4717c478bd9Sstevel@tonic-gate 		if (pcend2 == arena) {
4727c478bd9Sstevel@tonic-gate 			ret = MNOMOUNT;
4737c478bd9Sstevel@tonic-gate 			goto Return;
4747c478bd9Sstevel@tonic-gate 		}
4757c478bd9Sstevel@tonic-gate 		pcend = pcend2;
4767c478bd9Sstevel@tonic-gate 
4777c478bd9Sstevel@tonic-gate 	}
4787c478bd9Sstevel@tonic-gate 
4797c478bd9Sstevel@tonic-gate 	/*
4807c478bd9Sstevel@tonic-gate 	 * Clean out printers that can't take the print wheel
4817c478bd9Sstevel@tonic-gate 	 * EXCEPT for printers that already have it mounted
4827c478bd9Sstevel@tonic-gate 	 * or printers for which it is a selectable character set:
4837c478bd9Sstevel@tonic-gate 	 */
4847c478bd9Sstevel@tonic-gate 	if (prs->request->charset) {
4857c478bd9Sstevel@tonic-gate 		register CANDIDATE	*pcend2;
4867c478bd9Sstevel@tonic-gate 
4877c478bd9Sstevel@tonic-gate 		for (pcend2 = pc = arena; pc < pcend; pc++)
4887c478bd9Sstevel@tonic-gate 			if (CHKPW(prs->request->charset, pc->pps))
4897c478bd9Sstevel@tonic-gate 				*pcend2++ = *pc;
4907c478bd9Sstevel@tonic-gate 			else
4917c478bd9Sstevel@tonic-gate 				free_candidate (pc);
4927c478bd9Sstevel@tonic-gate 
4937c478bd9Sstevel@tonic-gate 		if (pcend2 == arena) {
4947c478bd9Sstevel@tonic-gate 			ret = MNOMOUNT;
4957c478bd9Sstevel@tonic-gate 			goto Return;
4967c478bd9Sstevel@tonic-gate 		}
4977c478bd9Sstevel@tonic-gate 		pcend = pcend2;
4987c478bd9Sstevel@tonic-gate 
4997c478bd9Sstevel@tonic-gate 	}
5007c478bd9Sstevel@tonic-gate 
5017c478bd9Sstevel@tonic-gate 	/*
5027c478bd9Sstevel@tonic-gate 	 * Clean out printers that can't handle the printing
5037c478bd9Sstevel@tonic-gate 	 * and for which there's no filter to convert the input.
5047c478bd9Sstevel@tonic-gate 	 *
5057c478bd9Sstevel@tonic-gate 	 */
5067c478bd9Sstevel@tonic-gate 
5077c478bd9Sstevel@tonic-gate 	/*
5087c478bd9Sstevel@tonic-gate 	 * Is the form mounted, or is none needed?
5097c478bd9Sstevel@tonic-gate 	 */
5107c478bd9Sstevel@tonic-gate #define CHKFMNT(PFS,PPS) (isFormUsableOnPrinter(PPS,PFS))
5117c478bd9Sstevel@tonic-gate 
5127c478bd9Sstevel@tonic-gate 	/*
5137c478bd9Sstevel@tonic-gate 	 * Is the print-wheel mounted, or is none needed?
5147c478bd9Sstevel@tonic-gate 	 */
5157c478bd9Sstevel@tonic-gate #define CHKPWMNT(PRS,PPS) SAME((PPS)->pwheel_name, (PRS)->request->charset)
5167c478bd9Sstevel@tonic-gate 
5177c478bd9Sstevel@tonic-gate 	/*
5187c478bd9Sstevel@tonic-gate 	 * Do we NOT need a special character set, or can we select
5197c478bd9Sstevel@tonic-gate 	 * it on the printer? Note: Getting this far means that IF
5207c478bd9Sstevel@tonic-gate 	 * the printer has selectable character sets (!daisy) then
5217c478bd9Sstevel@tonic-gate 	 * it can select the one we want.
5227c478bd9Sstevel@tonic-gate 	 */
5237c478bd9Sstevel@tonic-gate #define CHKCHSET(PRS,PPS) \
5247c478bd9Sstevel@tonic-gate 	( \
5257c478bd9Sstevel@tonic-gate 		!(PRS)->request->charset \
5267c478bd9Sstevel@tonic-gate 	     || !(PPS)->printer->daisy \
5277c478bd9Sstevel@tonic-gate 	)
5287c478bd9Sstevel@tonic-gate 
5297c478bd9Sstevel@tonic-gate 	/*
5307c478bd9Sstevel@tonic-gate 	 * Is the printer able to print now?
5317c478bd9Sstevel@tonic-gate 	 */
5327c478bd9Sstevel@tonic-gate #define CHKENB(PPS)	 (!((PPS)->status & (PS_DISABLED|PS_FAULTED)))
5337c478bd9Sstevel@tonic-gate 
5347c478bd9Sstevel@tonic-gate 	/*
5357c478bd9Sstevel@tonic-gate 	 * Is the printer not busy printing another request, or
5367c478bd9Sstevel@tonic-gate 	 * not awaiting an auto-retry after a fault?
5377c478bd9Sstevel@tonic-gate 	 */
5387c478bd9Sstevel@tonic-gate #define CHKFREE(PPS)	 (!((PPS)->status & (PS_BUSY|PS_LATER)))
5397c478bd9Sstevel@tonic-gate 
5407c478bd9Sstevel@tonic-gate 	/*
5417c478bd9Sstevel@tonic-gate 	 * Is the printer local?
5427c478bd9Sstevel@tonic-gate 	 */
5437c478bd9Sstevel@tonic-gate #define CHKLOCAL(PPS)	 (!((PPS)->status & (PS_REMOTE)))
5447c478bd9Sstevel@tonic-gate 
5457c478bd9Sstevel@tonic-gate 	{
5467c478bd9Sstevel@tonic-gate 		register CANDIDATE	*pcend2;
5477c478bd9Sstevel@tonic-gate 
5487c478bd9Sstevel@tonic-gate 		for (pcend2 = pc = arena; pc < pcend; pc++)
5497c478bd9Sstevel@tonic-gate 			if (pickfilter(prs, pc, pfs)) {
5507c478bd9Sstevel@tonic-gate 
5517c478bd9Sstevel@tonic-gate 				/*
5527c478bd9Sstevel@tonic-gate 				 * Compute a ``weight'' for this printer,
5537c478bd9Sstevel@tonic-gate 				 * based on its status. We'll later pick
5547c478bd9Sstevel@tonic-gate 				 * the printer with the highest weight.
5557c478bd9Sstevel@tonic-gate 				 */
5567c478bd9Sstevel@tonic-gate 				pc->weight = 0;
5577c478bd9Sstevel@tonic-gate 				if (!pc->fast && !pc->slow)
5587c478bd9Sstevel@tonic-gate 					pc->weight += WEIGHT_NOFILTER;
5597c478bd9Sstevel@tonic-gate 				if (CHKFREE(pc->pps))
5607c478bd9Sstevel@tonic-gate 					pc->weight += WEIGHT_FREE;
5617c478bd9Sstevel@tonic-gate 				if (CHKENB(pc->pps))
5627c478bd9Sstevel@tonic-gate 					pc->weight += WEIGHT_ENABLED;
5637c478bd9Sstevel@tonic-gate 				if (CHKFMNT(pfs, pc->pps))
5647c478bd9Sstevel@tonic-gate 					pc->weight += WEIGHT_MOUNTED;
5657c478bd9Sstevel@tonic-gate 				if (CHKPWMNT(prs, pc->pps))
5667c478bd9Sstevel@tonic-gate 					pc->weight += WEIGHT_MOUNTED;
5677c478bd9Sstevel@tonic-gate 				if (CHKCHSET(prs, pc->pps))
5687c478bd9Sstevel@tonic-gate 					pc->weight += WEIGHT_SELECTS;
5697c478bd9Sstevel@tonic-gate 				if (CHKLOCAL(pc->pps))
5707c478bd9Sstevel@tonic-gate 					pc->weight += WEIGHT_LOCAL;
5717c478bd9Sstevel@tonic-gate 
5727c478bd9Sstevel@tonic-gate #if	defined(FILTER_EARLY_OUT)
5737c478bd9Sstevel@tonic-gate 				if (pc->weight == WEIGHT_MAX) {
5747c478bd9Sstevel@tonic-gate 					/*
5757c478bd9Sstevel@tonic-gate 					 * This is the one!
5767c478bd9Sstevel@tonic-gate 					 */
5777c478bd9Sstevel@tonic-gate 					best_pc = pc;
5787c478bd9Sstevel@tonic-gate 					ret = MOK;
5797c478bd9Sstevel@tonic-gate 					goto Return;
5807c478bd9Sstevel@tonic-gate 				}
5817c478bd9Sstevel@tonic-gate #endif
5827c478bd9Sstevel@tonic-gate 				/*
5837c478bd9Sstevel@tonic-gate 				 * This is a candidate!
5847c478bd9Sstevel@tonic-gate 				 */
5857c478bd9Sstevel@tonic-gate 				*pcend2++ = *pc;
5867c478bd9Sstevel@tonic-gate 
5877c478bd9Sstevel@tonic-gate 			} else
5887c478bd9Sstevel@tonic-gate 				/*
5897c478bd9Sstevel@tonic-gate 				 * No filter for this one!
5907c478bd9Sstevel@tonic-gate 				 */
5917c478bd9Sstevel@tonic-gate 				free_candidate (pc);
5927c478bd9Sstevel@tonic-gate 
5937c478bd9Sstevel@tonic-gate 		if (pcend2 == arena) {
5947c478bd9Sstevel@tonic-gate 			ret = MNOFILTER;
5957c478bd9Sstevel@tonic-gate 			goto Return;
5967c478bd9Sstevel@tonic-gate 		}
5977c478bd9Sstevel@tonic-gate 		pcend = pcend2;
5987c478bd9Sstevel@tonic-gate 
5997c478bd9Sstevel@tonic-gate 	}
6007c478bd9Sstevel@tonic-gate 
6017c478bd9Sstevel@tonic-gate 	if (pcend - arena == 1) {
6027c478bd9Sstevel@tonic-gate 		best_pc = arena;
6037c478bd9Sstevel@tonic-gate 		ret = MOK;
6047c478bd9Sstevel@tonic-gate 		goto Return;
6057c478bd9Sstevel@tonic-gate 	}
606*45916cd2Sjpk 	/*
607*45916cd2Sjpk 	 * Clean out local printers
608*45916cd2Sjpk 	 * where the request is outside the printer label range.
609*45916cd2Sjpk 	 */
610*45916cd2Sjpk 	{
611*45916cd2Sjpk 		register CANDIDATE	*pcend2;
612*45916cd2Sjpk 
613*45916cd2Sjpk 		if (is_system_labeled()) {
614*45916cd2Sjpk 			for (pcend2 = pc = arena; pc < pcend; pc++) {
615*45916cd2Sjpk 				if (tsol_check_printer_label_range(
616*45916cd2Sjpk 				    prs->secure->slabel,
617*45916cd2Sjpk 				    pps->printer->name) == 1)
618*45916cd2Sjpk 					*pcend2++ = *pc;
619*45916cd2Sjpk 				else
620*45916cd2Sjpk 					free_candidate(pc);
621*45916cd2Sjpk 			}
622*45916cd2Sjpk 		}
623*45916cd2Sjpk 
624*45916cd2Sjpk 		if (pcend2 == arena) {
625*45916cd2Sjpk 			ret = MDENYDEST;
626*45916cd2Sjpk 			goto Return;
627*45916cd2Sjpk 		}
628*45916cd2Sjpk 		pcend = pcend2;
629*45916cd2Sjpk 	}
6307c478bd9Sstevel@tonic-gate 
6317c478bd9Sstevel@tonic-gate #if	defined(OTHER_FACTORS)
6327c478bd9Sstevel@tonic-gate 	/*
6337c478bd9Sstevel@tonic-gate 	 * Here you might want to add code that considers
6347c478bd9Sstevel@tonic-gate 	 * other factors: the size of the file(s) to be
6357c478bd9Sstevel@tonic-gate 	 * printed ("prs->secure->size") in relation to the
6367c478bd9Sstevel@tonic-gate 	 * printer (e.g. printer A gets mostly large
6377c478bd9Sstevel@tonic-gate 	 * files, printer B gets mostly small files); the
6387c478bd9Sstevel@tonic-gate 	 * number/total-size of requests currently queued
6397c478bd9Sstevel@tonic-gate 	 * for the printer; etc.
6407c478bd9Sstevel@tonic-gate 	 *
6417c478bd9Sstevel@tonic-gate 	 * If your code includes eliminating printers drop them
6427c478bd9Sstevel@tonic-gate 	 * from the list (as done in several places above).
6437c478bd9Sstevel@tonic-gate 	 * Otherwise, your code should add weights to the weight
6447c478bd9Sstevel@tonic-gate 	 * already computed. Change the WEIGHT_MAX, increase the
6457c478bd9Sstevel@tonic-gate 	 * other WEIGHT_X values to compensate, etc., as appropriate.
6467c478bd9Sstevel@tonic-gate 	 */
6477c478bd9Sstevel@tonic-gate 	;
6487c478bd9Sstevel@tonic-gate #endif
6497c478bd9Sstevel@tonic-gate 
6507c478bd9Sstevel@tonic-gate 	/*
6517c478bd9Sstevel@tonic-gate 	 * Pick the best printer from a list of eligible candidates.
6527c478bd9Sstevel@tonic-gate 	 */
6537c478bd9Sstevel@tonic-gate 	best_pc = arena;
6547c478bd9Sstevel@tonic-gate 	for (pc = arena + 1; pc < pcend; pc++)
6557c478bd9Sstevel@tonic-gate 		if (pc->weight > best_pc->weight)
6567c478bd9Sstevel@tonic-gate 			best_pc = pc;
6577c478bd9Sstevel@tonic-gate 	ret = MOK;
6587c478bd9Sstevel@tonic-gate 
6597c478bd9Sstevel@tonic-gate 	/*
6607c478bd9Sstevel@tonic-gate 	 * Branch to here if MOK and/or if things have been allocated.
6617c478bd9Sstevel@tonic-gate 	 */
6627c478bd9Sstevel@tonic-gate Return:	if (ret == MOK) {
6637c478bd9Sstevel@tonic-gate 		register USER		*pu = Getuser(prs->secure->user);
6647c478bd9Sstevel@tonic-gate 
6657c478bd9Sstevel@tonic-gate 		register char		*pwheel_name;
6667c478bd9Sstevel@tonic-gate 
6677c478bd9Sstevel@tonic-gate 		PSTATUS			*oldpps = prs->printer;
6687c478bd9Sstevel@tonic-gate 
6697c478bd9Sstevel@tonic-gate 
6707c478bd9Sstevel@tonic-gate 		/*
6717c478bd9Sstevel@tonic-gate 		 * We are going to accept this print request, having
6727c478bd9Sstevel@tonic-gate 		 * found a printer for it. This printer will be assigned
6737c478bd9Sstevel@tonic-gate 		 * to the request, although this assignment may be
6747c478bd9Sstevel@tonic-gate 		 * temporary if other printers qualify and this printer
6757c478bd9Sstevel@tonic-gate 		 * is changed to no longer qualify. Qualification in
6767c478bd9Sstevel@tonic-gate 		 * this context includes being ready to print!
6777c478bd9Sstevel@tonic-gate 		 */
6787c478bd9Sstevel@tonic-gate 		prs->printer = best_pc->pps;
6797c478bd9Sstevel@tonic-gate 		load_str (&(prs->printer_type), best_pc->printer_type);
6807c478bd9Sstevel@tonic-gate 
6817c478bd9Sstevel@tonic-gate 		/*
6827c478bd9Sstevel@tonic-gate 		 * Assign the form (if any) to the request. Adjust
6837c478bd9Sstevel@tonic-gate 		 * the number of requests queued for old and new form
6847c478bd9Sstevel@tonic-gate 		 * accordingly.
6857c478bd9Sstevel@tonic-gate 		 */
6867c478bd9Sstevel@tonic-gate 		if (prs->form != pfs) {
6877c478bd9Sstevel@tonic-gate 			unqueue_form (prs);
6887c478bd9Sstevel@tonic-gate 			queue_form (prs, pfs);
6897c478bd9Sstevel@tonic-gate 		}
6907c478bd9Sstevel@tonic-gate 
6917c478bd9Sstevel@tonic-gate 		/*
6927c478bd9Sstevel@tonic-gate 		 * Ditto for the print wheel, except include here the
6937c478bd9Sstevel@tonic-gate 		 * print wheel needed by the form.
6947c478bd9Sstevel@tonic-gate 		 * CAUTION: When checking this request later, don't
6957c478bd9Sstevel@tonic-gate 		 * refuse to service it if the print wheel for the
6967c478bd9Sstevel@tonic-gate 		 * form isn't mounted but the form is; a mounted form
6977c478bd9Sstevel@tonic-gate 		 * overrides its other needs. Don't be confused by the
6987c478bd9Sstevel@tonic-gate 		 * name of the bit, RSS_PWMAND; a printer that prints
6997c478bd9Sstevel@tonic-gate 		 * this request MUST have the print wheel mounted
7007c478bd9Sstevel@tonic-gate 		 * (if it takes print wheels) if the user asked for
7017c478bd9Sstevel@tonic-gate 		 * a particular print wheel.
7027c478bd9Sstevel@tonic-gate 		 */
7037c478bd9Sstevel@tonic-gate 		prs->status &= ~RSS_PWMAND;
7047c478bd9Sstevel@tonic-gate 		if (CHKMAND(pfs))
7057c478bd9Sstevel@tonic-gate 			pwheel_name = pfs->form->chset;
7067c478bd9Sstevel@tonic-gate 		else
7077c478bd9Sstevel@tonic-gate 			if ((pwheel_name = prs->request->charset) != NULL)
7087c478bd9Sstevel@tonic-gate 				prs->status |= RSS_PWMAND;
7097c478bd9Sstevel@tonic-gate 
7107c478bd9Sstevel@tonic-gate 		if (!SAME(pwheel_name, prs->pwheel_name)) {
7117c478bd9Sstevel@tonic-gate 			unqueue_pwheel (prs);
7127c478bd9Sstevel@tonic-gate 			queue_pwheel (prs, pwheel_name);
7137c478bd9Sstevel@tonic-gate 		}
7147c478bd9Sstevel@tonic-gate 
7157c478bd9Sstevel@tonic-gate 		/*
7167c478bd9Sstevel@tonic-gate 		 * Adjust the priority to lie within the limits allowed
7177c478bd9Sstevel@tonic-gate 		 * for the user (this is a silent adjustment as required).
7187c478bd9Sstevel@tonic-gate 		 * CURRENTLY, ONLY NEW REQUESTS WILL GET QUEUED ACCORDING
7197c478bd9Sstevel@tonic-gate 		 * TO THIS PRIORITY. EXISTING REQUESTS BEING (RE)EVALUATED
7207c478bd9Sstevel@tonic-gate 		 * WILL NOT BE REQUEUED.
7217c478bd9Sstevel@tonic-gate 		 * A wild priority is changed to the default, or the
7227c478bd9Sstevel@tonic-gate 		 * limit, whichever is the lower priority (higher value).
7237c478bd9Sstevel@tonic-gate 		 */
7247c478bd9Sstevel@tonic-gate 		if (prs->request->priority < 0 || 39 < prs->request->priority)
7257c478bd9Sstevel@tonic-gate 			prs->request->priority = getdfltpri();
7267c478bd9Sstevel@tonic-gate 		if (pu && prs->request->priority < pu->priority_limit)
7277c478bd9Sstevel@tonic-gate 			prs->request->priority = pu->priority_limit;
7287c478bd9Sstevel@tonic-gate 
7297c478bd9Sstevel@tonic-gate 		/*
7307c478bd9Sstevel@tonic-gate 		 * If a filter is involved, change the number of
7317c478bd9Sstevel@tonic-gate 		 * copies to 1 (if the filter handles it).
7327c478bd9Sstevel@tonic-gate 		 */
7337c478bd9Sstevel@tonic-gate 		if (
7347c478bd9Sstevel@tonic-gate 			(best_pc->fast || best_pc->slow)
7357c478bd9Sstevel@tonic-gate 		     && (best_pc->flags & FPARM_COPIES)
7367c478bd9Sstevel@tonic-gate 		     && prs->request->copies > 1
7377c478bd9Sstevel@tonic-gate 		)
7387c478bd9Sstevel@tonic-gate 			prs->copies = 1;
7397c478bd9Sstevel@tonic-gate 		else
7407c478bd9Sstevel@tonic-gate 			/*
7417c478bd9Sstevel@tonic-gate 			 * We use two ".copies" because we don't
7427c478bd9Sstevel@tonic-gate 			 * want to lose track of the number requested,
7437c478bd9Sstevel@tonic-gate 			 * but do want to mark the number the interface
7447c478bd9Sstevel@tonic-gate 			 * program is to handle. Here is the best
7457c478bd9Sstevel@tonic-gate 			 * place to know this.
7467c478bd9Sstevel@tonic-gate 			 */
7477c478bd9Sstevel@tonic-gate 			prs->copies = prs->request->copies;
7487c478bd9Sstevel@tonic-gate 
7497c478bd9Sstevel@tonic-gate 		if (best_pc->slow) {
7507c478bd9Sstevel@tonic-gate 			/*
7517c478bd9Sstevel@tonic-gate 			 * If the filter has changed, the request will
7527c478bd9Sstevel@tonic-gate 			 * have to be refiltered. This may mean stopping
7537c478bd9Sstevel@tonic-gate 			 * a currently running filter or interface.
7547c478bd9Sstevel@tonic-gate 			 */
7557c478bd9Sstevel@tonic-gate 			if (!SAME(best_pc->slow, prs->slow)) {
7567c478bd9Sstevel@tonic-gate 
7577c478bd9Sstevel@tonic-gate 			    if (prs->request->outcome & RS_FILTERED)
7587c478bd9Sstevel@tonic-gate 				prs->request->outcome &= ~RS_FILTERED;
7597c478bd9Sstevel@tonic-gate 
7607c478bd9Sstevel@tonic-gate 			    if (
7617c478bd9Sstevel@tonic-gate 				prs->request->outcome & RS_FILTERING
7627c478bd9Sstevel@tonic-gate 			     && !(prs->request->outcome & RS_STOPPED)
7637c478bd9Sstevel@tonic-gate 			    ) {
7647c478bd9Sstevel@tonic-gate 				prs->request->outcome |= RS_REFILTER;
7657c478bd9Sstevel@tonic-gate 				prs->request->outcome |= RS_STOPPED;
7667c478bd9Sstevel@tonic-gate 				terminate (prs->exec);
7677c478bd9Sstevel@tonic-gate 
7687c478bd9Sstevel@tonic-gate 			    } else if (
7697c478bd9Sstevel@tonic-gate 				prs->request->outcome & RS_PRINTING
7707c478bd9Sstevel@tonic-gate 			     && !(prs->request->outcome & RS_STOPPED)
7717c478bd9Sstevel@tonic-gate 			    ) {
7727c478bd9Sstevel@tonic-gate 				prs->request->outcome |= RS_STOPPED;
7737c478bd9Sstevel@tonic-gate 				terminate (oldpps->exec);
7747c478bd9Sstevel@tonic-gate 			    }
7757c478bd9Sstevel@tonic-gate 
7767c478bd9Sstevel@tonic-gate 			}
7777c478bd9Sstevel@tonic-gate 
7787c478bd9Sstevel@tonic-gate 			load_str (&(prs->slow), best_pc->slow);
7797c478bd9Sstevel@tonic-gate 			/* Assumption: if there is a slow filter,
7807c478bd9Sstevel@tonic-gate 			 * there is an output_type
7817c478bd9Sstevel@tonic-gate 			 */
7827c478bd9Sstevel@tonic-gate 
7837c478bd9Sstevel@tonic-gate 			load_str (&(prs->output_type), best_pc->output_type);
7847c478bd9Sstevel@tonic-gate 		} else
7857c478bd9Sstevel@tonic-gate 			unload_str (&(prs->slow));
7867c478bd9Sstevel@tonic-gate 
7877c478bd9Sstevel@tonic-gate 		load_str (&(prs->fast), best_pc->fast);
7887c478bd9Sstevel@tonic-gate 
7897c478bd9Sstevel@tonic-gate 		if (prs->request->actions & ACT_FAST && prs->slow) {
7907c478bd9Sstevel@tonic-gate 			if (prs->fast) {
7917c478bd9Sstevel@tonic-gate 				prs->fast = makestr(
7927c478bd9Sstevel@tonic-gate 					prs->slow,
7937c478bd9Sstevel@tonic-gate 					"|",
7947c478bd9Sstevel@tonic-gate 					prs->fast,
7957c478bd9Sstevel@tonic-gate 					(char *)0
7967c478bd9Sstevel@tonic-gate 				);
7977c478bd9Sstevel@tonic-gate 				Free (prs->slow);
7987c478bd9Sstevel@tonic-gate 			} else
7997c478bd9Sstevel@tonic-gate 				prs->fast = prs->slow;
8007c478bd9Sstevel@tonic-gate 			prs->slow = 0;
8017c478bd9Sstevel@tonic-gate 		}
8027c478bd9Sstevel@tonic-gate 
8037c478bd9Sstevel@tonic-gate 	}
8047c478bd9Sstevel@tonic-gate 
8057c478bd9Sstevel@tonic-gate 
8067c478bd9Sstevel@tonic-gate 	/*
8077c478bd9Sstevel@tonic-gate 	 * Free the space allocated for the candidates, INCLUDING
8087c478bd9Sstevel@tonic-gate 	 * the one chosen. Any allocated space in the chosen candidate
8097c478bd9Sstevel@tonic-gate 	 * that has to be saved should have been COPIED already.
8107c478bd9Sstevel@tonic-gate 	 */
8117c478bd9Sstevel@tonic-gate 	if (arena) {
8127c478bd9Sstevel@tonic-gate 		for (pc = arena; pc < pcend; pc++)
8137c478bd9Sstevel@tonic-gate 			free_candidate (pc);
8147c478bd9Sstevel@tonic-gate 		Free ((char *)arena);
8157c478bd9Sstevel@tonic-gate 	} else if (best_pc)
8167c478bd9Sstevel@tonic-gate 		free_candidate (best_pc);
8177c478bd9Sstevel@tonic-gate 
8187c478bd9Sstevel@tonic-gate 	if (o_length)
8197c478bd9Sstevel@tonic-gate 		Free (o_length);
8207c478bd9Sstevel@tonic-gate 	if (o_width)
8217c478bd9Sstevel@tonic-gate 		Free (o_width);
8227c478bd9Sstevel@tonic-gate 	if (o_lpi)
8237c478bd9Sstevel@tonic-gate 		Free (o_lpi);
8247c478bd9Sstevel@tonic-gate 	if (o_cpi)
8257c478bd9Sstevel@tonic-gate 		Free (o_cpi);
8267c478bd9Sstevel@tonic-gate 
8277c478bd9Sstevel@tonic-gate 
8287c478bd9Sstevel@tonic-gate 	/*
8297c478bd9Sstevel@tonic-gate 	 * The following value is valid ONLY IF the request
8307c478bd9Sstevel@tonic-gate 	 * is canceled or rejected. Not all requests that
8317c478bd9Sstevel@tonic-gate 	 * we fail in this routine are tossed out!
8327c478bd9Sstevel@tonic-gate 	 */
8337c478bd9Sstevel@tonic-gate 	prs->reason = ret;
8347c478bd9Sstevel@tonic-gate 
8357c478bd9Sstevel@tonic-gate 
8367c478bd9Sstevel@tonic-gate 	return (ret);
8377c478bd9Sstevel@tonic-gate }
8387c478bd9Sstevel@tonic-gate 
8397c478bd9Sstevel@tonic-gate /**
8407c478bd9Sstevel@tonic-gate  ** _chkopts() - CHECK -o OPTIONS
8417c478bd9Sstevel@tonic-gate  **/
8427c478bd9Sstevel@tonic-gate 
8437c478bd9Sstevel@tonic-gate static int
8447c478bd9Sstevel@tonic-gate _chkopts(RSTATUS *prs, CANDIDATE *pc, FSTATUS *pfs)
8457c478bd9Sstevel@tonic-gate {
8467c478bd9Sstevel@tonic-gate 	unsigned long		ret	= 0;
8477c478bd9Sstevel@tonic-gate 	unsigned long		chk	= 0;
8487c478bd9Sstevel@tonic-gate 
8497c478bd9Sstevel@tonic-gate 	char *			charset;
8507c478bd9Sstevel@tonic-gate 	char *			cpi	= 0;
8517c478bd9Sstevel@tonic-gate 	char *			lpi	= 0;
8527c478bd9Sstevel@tonic-gate 	char *			width	= 0;
8537c478bd9Sstevel@tonic-gate 	char *			length	= 0;
8547c478bd9Sstevel@tonic-gate 	char *			paper = NULL;
8557c478bd9Sstevel@tonic-gate 
8567c478bd9Sstevel@tonic-gate 	char **			pt;
857*45916cd2Sjpk 	int			nobanner_not_allowed = 0;
8587c478bd9Sstevel@tonic-gate 
8597c478bd9Sstevel@tonic-gate 
8607c478bd9Sstevel@tonic-gate 	/*
8617c478bd9Sstevel@tonic-gate 	 * If we have a form, it overrides whatever print characteristics
8627c478bd9Sstevel@tonic-gate 	 * the user gave.
8637c478bd9Sstevel@tonic-gate 	 */
8647c478bd9Sstevel@tonic-gate 	if (pfs) {
8657c478bd9Sstevel@tonic-gate 		cpi = pfs->cpi;
8667c478bd9Sstevel@tonic-gate 		lpi = pfs->lpi;
8677c478bd9Sstevel@tonic-gate 		width = pfs->pwid;
8687c478bd9Sstevel@tonic-gate 		length = pfs->plen;
8697c478bd9Sstevel@tonic-gate 		paper = pfs->form->paper;
8707c478bd9Sstevel@tonic-gate 	} else {
8717c478bd9Sstevel@tonic-gate 		cpi = o_cpi;
8727c478bd9Sstevel@tonic-gate 		lpi = o_lpi;
8737c478bd9Sstevel@tonic-gate 		width = o_width;
8747c478bd9Sstevel@tonic-gate 		length = o_length;
8757c478bd9Sstevel@tonic-gate 	}
8767c478bd9Sstevel@tonic-gate 
8777c478bd9Sstevel@tonic-gate 	/*
8787c478bd9Sstevel@tonic-gate 	 * If the printer takes print wheels, or the character set
8797c478bd9Sstevel@tonic-gate 	 * the user wants is listed in the character set map for this
8807c478bd9Sstevel@tonic-gate 	 * printer, we needn't check if the printer can handle the
8817c478bd9Sstevel@tonic-gate 	 * character set. (Note: The check for the print wheel case
8827c478bd9Sstevel@tonic-gate 	 * is done elsewhere.)
8837c478bd9Sstevel@tonic-gate 	 */
8847c478bd9Sstevel@tonic-gate 
8857c478bd9Sstevel@tonic-gate 	if (pc->pps->printer->daisy ||
8867c478bd9Sstevel@tonic-gate 	    search_cslist(prs->request->charset, pc->pps->printer->char_sets))
8877c478bd9Sstevel@tonic-gate 		charset = 0;
8887c478bd9Sstevel@tonic-gate 	else
8897c478bd9Sstevel@tonic-gate 		charset = prs->request->charset;
8907c478bd9Sstevel@tonic-gate 
8917c478bd9Sstevel@tonic-gate 	pc->printer_types = 0;
8927c478bd9Sstevel@tonic-gate 	for (pt = pc->pps->printer->printer_types; *pt; pt++) {
8937c478bd9Sstevel@tonic-gate 		unsigned long		this;
8947c478bd9Sstevel@tonic-gate 
8957c478bd9Sstevel@tonic-gate 		if (paper) {
8967c478bd9Sstevel@tonic-gate 			if (allowed(paper,pc->pps->paper_allowed,NULL)) {
8977c478bd9Sstevel@tonic-gate 				addlist (&(pc->printer_types), *pt);
8987c478bd9Sstevel@tonic-gate 			} else {
8997c478bd9Sstevel@tonic-gate 				ret |= PCK_PAPER;
9007c478bd9Sstevel@tonic-gate 			}
9017c478bd9Sstevel@tonic-gate 		} else {
9027c478bd9Sstevel@tonic-gate 			this = chkprinter(*pt, cpi, lpi, length, width,
9037c478bd9Sstevel@tonic-gate 				charset);
9047c478bd9Sstevel@tonic-gate 			if (this == 0)
9057c478bd9Sstevel@tonic-gate 				addlist(&(pc->printer_types), *pt);
9067c478bd9Sstevel@tonic-gate 			chk |= this;
9077c478bd9Sstevel@tonic-gate 		}
9087c478bd9Sstevel@tonic-gate 	}
9097c478bd9Sstevel@tonic-gate 	if (!pc->printer_types)
9107c478bd9Sstevel@tonic-gate 		ret |= chk;
9117c478bd9Sstevel@tonic-gate 
912*45916cd2Sjpk 	/*
913*45916cd2Sjpk 	 * If the sytem is labeled, then user who wants 'nolabels' must
914*45916cd2Sjpk 	 * have PRINT_UNLABELED_AUTH authorizations to allow it.
915*45916cd2Sjpk 	 */
916*45916cd2Sjpk 	if (is_system_labeled() && (wants_nolabels == 1)) {
917*45916cd2Sjpk 		if (!tsol_lpauth(PRINT_UNLABELED_AUTH, prs->secure->user)) {
918*45916cd2Sjpk 			/* if not authorized, remove "nolabels" from options */
919*45916cd2Sjpk 			register char		**list;
920*45916cd2Sjpk 			if (prs->request->options &&
921*45916cd2Sjpk 			    (list = dashos(prs->request->options))) {
922*45916cd2Sjpk 				dellist(&list, "nolabels");
923*45916cd2Sjpk 				free(prs->request->options);
924*45916cd2Sjpk 				prs->request->options = sprintlist(list);
925*45916cd2Sjpk 			}
926*45916cd2Sjpk 		}
927*45916cd2Sjpk 	}
928*45916cd2Sjpk 
929*45916cd2Sjpk 
9307c478bd9Sstevel@tonic-gate 	if (pc->pps->printer->banner == BAN_ALWAYS) {
931*45916cd2Sjpk 		/* delete "nobanner" */
932*45916cd2Sjpk 		char **list;
9337c478bd9Sstevel@tonic-gate 
934*45916cd2Sjpk 		/*
935*45916cd2Sjpk 		 * If the system is labeled, users must have
936*45916cd2Sjpk 		 * PRINT_NOBANNER_AUTH authorization to print
937*45916cd2Sjpk 		 * without a banner.
938*45916cd2Sjpk 		 */
939*45916cd2Sjpk 		if (is_system_labeled()) {
940*45916cd2Sjpk 			if (wants_nobanner == 1) {
941*45916cd2Sjpk 				if (tsol_lpauth(PRINT_NOBANNER_AUTH,
942*45916cd2Sjpk 					prs->secure->user) == 0) {
943*45916cd2Sjpk 					nobanner_not_allowed = 1;
944*45916cd2Sjpk 				}
945*45916cd2Sjpk 			}
946*45916cd2Sjpk 
947*45916cd2Sjpk 		}
948*45916cd2Sjpk 		else if ((wants_nobanner == 1) && (lp_or_root != 1)) {
949*45916cd2Sjpk 			nobanner_not_allowed = 1;
950*45916cd2Sjpk 		}
951*45916cd2Sjpk 		if (nobanner_not_allowed == 1) {
952*45916cd2Sjpk 			/* Take out 'nobanner' from request options. */
9537c478bd9Sstevel@tonic-gate 			if (prs->request->options &&
9547c478bd9Sstevel@tonic-gate 			    (list = dashos(prs->request->options))) {
9557c478bd9Sstevel@tonic-gate 				dellist(&list, "nobanner");
9567c478bd9Sstevel@tonic-gate 				free(prs->request->options);
9577c478bd9Sstevel@tonic-gate 				prs->request->options = sprintlist(list);
9587c478bd9Sstevel@tonic-gate 			}
9597c478bd9Sstevel@tonic-gate 		}
9607c478bd9Sstevel@tonic-gate 	} else if (pc->pps->printer->banner == BAN_NEVER) {
9617c478bd9Sstevel@tonic-gate 		if (wants_nobanner == 0) {
9627c478bd9Sstevel@tonic-gate 			/* add "nobanner" */
9637c478bd9Sstevel@tonic-gate 			char **list = NULL;
9647c478bd9Sstevel@tonic-gate 
9657c478bd9Sstevel@tonic-gate 			if (prs->request->options) {
9667c478bd9Sstevel@tonic-gate 				list = dashos(prs->request->options);
9677c478bd9Sstevel@tonic-gate 				free(prs->request->options);
9687c478bd9Sstevel@tonic-gate 			}
9697c478bd9Sstevel@tonic-gate 			appendlist(&list, "nobanner");
9707c478bd9Sstevel@tonic-gate 			prs->request->options = sprintlist(list);
9717c478bd9Sstevel@tonic-gate 		}
9727c478bd9Sstevel@tonic-gate 	} else /* if (pc->pps->printer->banner == BAN_OPTIONAL) */ {
9737c478bd9Sstevel@tonic-gate 		/* it is optional, leave it alone */
9747c478bd9Sstevel@tonic-gate 	}
9757c478bd9Sstevel@tonic-gate 
9767c478bd9Sstevel@tonic-gate 	chkprinter_result |= ret;
9777c478bd9Sstevel@tonic-gate 	return (ret == 0);
9787c478bd9Sstevel@tonic-gate }
9797c478bd9Sstevel@tonic-gate 
9807c478bd9Sstevel@tonic-gate /**
9817c478bd9Sstevel@tonic-gate  ** free_candidate()
9827c478bd9Sstevel@tonic-gate  **/
9837c478bd9Sstevel@tonic-gate 
9847c478bd9Sstevel@tonic-gate static void
9857c478bd9Sstevel@tonic-gate free_candidate(CANDIDATE *pc)
9867c478bd9Sstevel@tonic-gate {
9877c478bd9Sstevel@tonic-gate 	if (pc->slow)
9887c478bd9Sstevel@tonic-gate 		unload_str (&(pc->slow));
9897c478bd9Sstevel@tonic-gate 	if (pc->fast)
9907c478bd9Sstevel@tonic-gate 		unload_str (&(pc->fast));
9917c478bd9Sstevel@tonic-gate 	if (pc->printer_types) {
9927c478bd9Sstevel@tonic-gate 		freelist (pc->printer_types);
9937c478bd9Sstevel@tonic-gate 		pc->printer_types = 0;
9947c478bd9Sstevel@tonic-gate 	}
9957c478bd9Sstevel@tonic-gate 	if (pc->printer_type)
9967c478bd9Sstevel@tonic-gate 		unload_str (&(pc->printer_type));
9977c478bd9Sstevel@tonic-gate 	if (pc->output_type)
9987c478bd9Sstevel@tonic-gate 		unload_str (&(pc->output_type));
9997c478bd9Sstevel@tonic-gate 	return;
10007c478bd9Sstevel@tonic-gate }
1001*45916cd2Sjpk 
1002*45916cd2Sjpk static int
1003*45916cd2Sjpk tsol_check_printer_label_range(char *slabel, const char *printer)
1004*45916cd2Sjpk {
1005*45916cd2Sjpk 	int			in_range = 0;
1006*45916cd2Sjpk 	int			err = 0;
1007*45916cd2Sjpk 	m_range_t		*range;
1008*45916cd2Sjpk 	m_label_t	*sl = NULL;
1009*45916cd2Sjpk 
1010*45916cd2Sjpk 	if (slabel == NULL)
1011*45916cd2Sjpk 		return (0);
1012*45916cd2Sjpk 
1013*45916cd2Sjpk 	if ((err =
1014*45916cd2Sjpk 	    (str_to_label(slabel, &sl, USER_CLEAR, L_NO_CORRECTION, &in_range)))
1015*45916cd2Sjpk 	    == -1) {
1016*45916cd2Sjpk 		/* stobsl error on printer max label */
1017*45916cd2Sjpk 		return (0);
1018*45916cd2Sjpk 	}
1019*45916cd2Sjpk 	if ((range = getdevicerange(printer)) == NULL) {
1020*45916cd2Sjpk 		m_label_free(sl);
1021*45916cd2Sjpk 		return (0);
1022*45916cd2Sjpk 	}
1023*45916cd2Sjpk 
1024*45916cd2Sjpk 	/* blinrange returns true (1) if in range, false (0) if not */
1025*45916cd2Sjpk 	in_range = blinrange(sl, range);
1026*45916cd2Sjpk 
1027*45916cd2Sjpk 	m_label_free(sl);
1028*45916cd2Sjpk 	m_label_free(range->lower_bound);
1029*45916cd2Sjpk 	m_label_free(range->upper_bound);
1030*45916cd2Sjpk 	free(range);
1031*45916cd2Sjpk 
1032*45916cd2Sjpk 	return (in_range);
1033*45916cd2Sjpk }
1034*45916cd2Sjpk 
1035*45916cd2Sjpk /*
1036*45916cd2Sjpk  * Given a character string with a "username" or "system!username"
1037*45916cd2Sjpk  * this function returns a pointer to "username"
1038*45916cd2Sjpk  */
1039*45916cd2Sjpk static int
1040*45916cd2Sjpk tsol_lpauth(char *auth, char *in_name)
1041*45916cd2Sjpk {
1042*45916cd2Sjpk 	char *cp;
1043*45916cd2Sjpk 	int res;
1044*45916cd2Sjpk 
1045*45916cd2Sjpk 	if ((cp = strchr(in_name, '@')) != NULL) {
1046*45916cd2Sjpk 		/* user@system */
1047*45916cd2Sjpk 		*cp = '\0';
1048*45916cd2Sjpk 		res = chkauthattr(auth, in_name);
1049*45916cd2Sjpk 		*cp = '@';
1050*45916cd2Sjpk 	} else if ((cp = strchr(in_name, '!')) != NULL)
1051*45916cd2Sjpk 		/* system!user */
1052*45916cd2Sjpk 		res = chkauthattr(auth, cp+1);
1053*45916cd2Sjpk 	else
1054*45916cd2Sjpk 		/* user */
1055*45916cd2Sjpk 		res = chkauthattr(auth, in_name);
1056*45916cd2Sjpk 
1057*45916cd2Sjpk 	return (res);
1058*45916cd2Sjpk }
1059*45916cd2Sjpk 
1060*45916cd2Sjpk #define	POLICY_FILE	"/etc/default/print"
1061*45916cd2Sjpk 
1062*45916cd2Sjpk int
1063*45916cd2Sjpk secpolicy_chkpolicy(char *policyp)
1064*45916cd2Sjpk {
1065*45916cd2Sjpk 	char *option;
1066*45916cd2Sjpk 	int opt_val;
1067*45916cd2Sjpk 
1068*45916cd2Sjpk 	if (policyp == NULL)
1069*45916cd2Sjpk 		return (0);
1070*45916cd2Sjpk 	opt_val = 0;
1071*45916cd2Sjpk 	if (defopen(POLICY_FILE) == 0) {
1072*45916cd2Sjpk 
1073*45916cd2Sjpk 		defcntl(DC_SETFLAGS, DC_STD & ~DC_CASE); /* ignore case */
1074*45916cd2Sjpk 
1075*45916cd2Sjpk 		if ((option = defread(policyp)) != NULL)
1076*45916cd2Sjpk 			opt_val = atoi(option);
1077*45916cd2Sjpk 	}
1078*45916cd2Sjpk 	(void) defopen((char *)NULL);
1079*45916cd2Sjpk 	syslog(LOG_DEBUG, "--- Policy %s, opt_val==%d",
1080*45916cd2Sjpk 	    policyp ? policyp : "NULL", opt_val);
1081*45916cd2Sjpk 	return (opt_val);
1082*45916cd2Sjpk }
1083