Home | History | Annotate | Download | only in lpsched
      1     0   stevel /*
      2     0   stevel  * CDDL HEADER START
      3     0   stevel  *
      4     0   stevel  * The contents of this file are subject to the terms of the
      5  1676      jpk  * Common Development and Distribution License (the "License").
      6  1676      jpk  * You may not use this file except in compliance with the License.
      7     0   stevel  *
      8     0   stevel  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9     0   stevel  * or http://www.opensolaris.org/os/licensing.
     10     0   stevel  * See the License for the specific language governing permissions
     11     0   stevel  * and limitations under the License.
     12     0   stevel  *
     13     0   stevel  * When distributing Covered Code, include this CDDL HEADER in each
     14     0   stevel  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15     0   stevel  * If applicable, add the following below this CDDL HEADER, with the
     16     0   stevel  * fields enclosed by brackets "[]" replaced with your own identifying
     17     0   stevel  * information: Portions Copyright [yyyy] [name of copyright owner]
     18     0   stevel  *
     19     0   stevel  * CDDL HEADER END
     20     0   stevel  */
     21     0   stevel /*
     22  4633  keerthi  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
     23     0   stevel  * Use is subject to license terms.
     24     0   stevel  */
     25     0   stevel 
     26     0   stevel /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
     27     0   stevel /*	  All Rights Reserved  	*/
     28     0   stevel 
     29     0   stevel 
     30  1676      jpk #pragma ident	"%Z%%M%	%I%	%E% SMI"
     31  1676      jpk /* SVr4.0 1.11.1.10	*/
     32     0   stevel /* EMACS_MODES: !fill, lnumb, !overwrite, !nodelete, !picture */
     33     0   stevel 
     34     0   stevel #include "lpsched.h"
     35     0   stevel 
     36     0   stevel #include "validate.h"
     37     0   stevel 
     38  1676      jpk #include <syslog.h>
     39  1676      jpk #include <errno.h>
     40  1676      jpk #include <deflt.h>
     41  1676      jpk #include <tsol/label.h>
     42  1676      jpk #include <auth_list.h>
     43  1676      jpk 
     44     0   stevel #define register auto
     45  1676      jpk 
     46     0   stevel 
     47     0   stevel int		pickfilter ( RSTATUS * , CANDIDATE * , FSTATUS * );
     48     0   stevel 
     49     0   stevel unsigned long		chkprinter_result	= 0;
     50     0   stevel char *			o_cpi		= 0;
     51     0   stevel char *			o_lpi		= 0;
     52     0   stevel char *			o_width		= 0;
     53     0   stevel char *			o_length	= 0;
     54     0   stevel 
     55     0   stevel static int		wants_nobanner	= 0;
     56  1676      jpk static int		wants_nolabels	= 0;
     57     0   stevel static int		lp_or_root	= 0;
     58     0   stevel 
     59     0   stevel static int		_chkopts ( RSTATUS *, CANDIDATE * , FSTATUS * );
     60     0   stevel static void		free_candidate ( CANDIDATE * );
     61  1676      jpk static int		tsol_check_printer_label_range(char *, const char *);
     62  1676      jpk static int		tsol_lpauth(char *, char *);
     63  1676      jpk static int		secpolicy_chkpolicy(char *policyp);
     64     0   stevel 
     65     0   stevel /**
     66     0   stevel  ** _validate() - FIND A PRINTER TO HANDLE A REQUEST
     67     0   stevel  **/
     68     0   stevel 
     69     0   stevel short
     70     0   stevel _validate(RSTATUS *prs, PSTATUS *pps, PSTATUS *stop_pps, char **prefixp,
     71     0   stevel 	 int moving)
     72     0   stevel {
     73     0   stevel 	register CANDIDATE	*pc		= 0,
     74     0   stevel 				*pcend,
     75     0   stevel 				*best_pc	= 0;
     76     0   stevel 
     77     0   stevel 	register FSTATUS	*pfs		= 0;
     78     0   stevel 
     79     0   stevel 	register CSTATUS	*pcs		= 0;
     80     0   stevel 
     81     0   stevel 	CANDIDATE		*arena		= 0,
     82     0   stevel 				single;
     83     0   stevel 
     84     0   stevel 	size_t			n;
     85  3125   jacobs 	int i;
     86     0   stevel 
     87     0   stevel 	short			ret;
     88     0   stevel 
     89     0   stevel 	chkprinter_result = 0;
     90     0   stevel 	o_cpi = o_lpi = o_width = o_length = 0;
     91     0   stevel 	wants_nobanner = 0;
     92     0   stevel 	memset (&single, 0, sizeof(single));
     93     0   stevel 
     94  1676      jpk 	wants_nolabels = 0;
     95  1676      jpk 	/*
     96  1676      jpk 	 * If the system is labeled, the printing of postscript files
     97  1676      jpk 	 * is restricted.  All users can print postscript files if the
     98  1676      jpk 	 * file /etc/default/print contains "PRINT_POSTSCRIPT=1".
     99  1676      jpk 	 * (this is checked by secpolicy_chkpolicy).  Otherwise the
    100  1676      jpk 	 * user must have PRINT_POSTSCRIPT_AUTH to print postscript files.
    101  1676      jpk 	 */
    102  1676      jpk 	if ((is_system_labeled() &&
    103  1676      jpk 	    strcmp(prs->request->input_type, "postscript") == 0) &&
    104  1676      jpk 	    (secpolicy_chkpolicy("PRINT_POSTSCRIPT=") == 0)) {
    105  1676      jpk 		if (tsol_lpauth(PRINT_POSTSCRIPT_AUTH, prs->secure->user)
    106  1676      jpk 		    == 0) {
    107  1676      jpk 			ret = MDENYDEST;
    108  1676      jpk 			goto Return;
    109  1676      jpk 		}
    110  1676      jpk 	}
    111     0   stevel 	lp_or_root = 0;
    112     0   stevel 
    113  3125   jacobs 	if (bangequ(prs->secure->user, "root") ||
    114  3125   jacobs 	    bangequ(prs->secure->user, "lp"))
    115     0   stevel 			lp_or_root = 1;
    116     0   stevel 
    117     0   stevel 	if (prefixp)
    118     0   stevel 		*prefixp = prs->request->destination;
    119     0   stevel 
    120     0   stevel 	/*
    121     0   stevel 	 * If a destination other than "any" was given,
    122     0   stevel 	 * see if it exists in our internal tables.
    123     0   stevel 	 */
    124     0   stevel 	if (!pps && prs->request->destination &&
    125     0   stevel 	    !STREQU(prs->request->destination, NAME_ANY))
    126  3125   jacobs 		if (((pps = search_pstatus(prs->request->destination)) != NULL) ||
    127  3125   jacobs 		    ((pcs = search_cstatus(prs->request->destination)) != NULL) &&
    128     0   stevel 		    pcs->class->members)
    129     0   stevel 			/*EMPTY*/;
    130     0   stevel 		else {
    131     0   stevel 			ret = MNODEST;
    132     0   stevel 			goto Return;
    133     0   stevel 		}
    134     0   stevel 
    135     0   stevel 	/*
    136     0   stevel 	 * If we are trying to avoid a printer, but the request
    137     0   stevel 	 * was destined for just that printer, we're out.
    138     0   stevel 	 */
    139     0   stevel 	if (pps && pps == stop_pps) {
    140     0   stevel 		ret = MERRDEST;
    141     0   stevel 		goto Return;
    142     0   stevel 	}
    143     0   stevel 
    144     0   stevel 	/*
    145     0   stevel 	 * If a form was given, see if it exists; if so,
    146     0   stevel 	 * see if the user is allowed to use it.
    147     0   stevel 	 * If a remote printer was specified, then don't use any local
    148     0   stevel 	 * form knowledge.
    149     0   stevel 	 */
    150     0   stevel 	if (prs && prs->request && prs->request->form && (pps || pcs)) {
    151  3125   jacobs 		if ((pfs = search_fstatus(prs->request->form))) {
    152     0   stevel 			if (lp_or_root || allowed(prs->secure->user,
    153     0   stevel 				pfs->users_allowed, pfs->users_denied))
    154     0   stevel 				/*EMPTY*/;
    155     0   stevel 			else {
    156     0   stevel 				ret = MDENYMEDIA;
    157     0   stevel 				goto Return;
    158     0   stevel 			}
    159     0   stevel 		} else {
    160     0   stevel 			ret = MNOMEDIA;
    161     0   stevel 			goto Return;
    162     0   stevel 		}
    163     0   stevel 	}
    164     0   stevel 
    165     0   stevel 	/*
    166     0   stevel 	 * If the request includes -o options there may be pitch and
    167     0   stevel 	 * size and no-banner requests that have to be checked. One
    168     0   stevel 	 * could argue that this shouldn't be in the Spooler, because
    169     0   stevel 	 * the Spooler's job is SPOOLING, not PRINTING. That's right,
    170     0   stevel 	 * except that the Spooler will be making a choice of printers
    171     0   stevel 	 * so it has to evaluate carefully: E.g. user wants ANY printer,
    172     0   stevel 	 * so we should pick one that can handle what he/she wants.
    173     0   stevel 	 *
    174     0   stevel 	 * Parse out the important stuff here so we have it when we
    175     0   stevel 	 * need it.
    176     0   stevel 	 */
    177     0   stevel 	{
    178     0   stevel 		register char		**list,
    179     0   stevel 					**pl;
    180     0   stevel 
    181     0   stevel 		if (
    182     0   stevel 			prs->request->options
    183     0   stevel 		     && (list = dashos(prs->request->options))
    184     0   stevel 		) {
    185     0   stevel 			for (pl = list ; *pl; pl++)
    186     0   stevel 				if (STRNEQU(*pl, "cpi=", 4))
    187     0   stevel 					o_cpi = Strdup(*pl + 4);
    188     0   stevel 				else if (STRNEQU(*pl, "lpi=", 4))
    189     0   stevel 					o_lpi = Strdup(*pl + 4);
    190     0   stevel 				else if (STRNEQU(*pl, "width=", 6))
    191     0   stevel 					o_width = Strdup(*pl + 6);
    192     0   stevel 				else if (STRNEQU(*pl, "length=", 7))
    193     0   stevel 					o_length = Strdup(*pl + 7);
    194     0   stevel 				else if (STREQU(*pl, "nobanner"))
    195     0   stevel 					wants_nobanner = 1;
    196  1676      jpk 				else if (STREQU(*pl, "nolabels"))
    197  1676      jpk 					wants_nolabels = 1;
    198     0   stevel 			freelist (list);
    199     0   stevel 		}
    200     0   stevel 	}
    201     0   stevel 
    202     0   stevel 	/*
    203     0   stevel 	 * This macro checks that a form has a mandatory print wheel
    204     0   stevel 	 * (or character set).
    205     0   stevel 	 */
    206     0   stevel #define	CHKMAND(PFS) \
    207     0   stevel 	( \
    208     0   stevel 		(PFS) \
    209     0   stevel 	     && (PFS)->form->chset \
    210     0   stevel 	     && !STREQU((PFS)->form->chset, NAME_ANY) \
    211     0   stevel 	     && (PFS)->form->mandatory \
    212     0   stevel 	)
    213     0   stevel 
    214     0   stevel 	/*
    215     0   stevel 	 * This macro checks that the user is allowed to use the
    216     0   stevel 	 * printer.
    217     0   stevel 	 */
    218     0   stevel #define CHKU(PRS,PPS) \
    219     0   stevel 	( \
    220     0   stevel 		lp_or_root \
    221     0   stevel 	     || allowed( \
    222     0   stevel 			(PRS)->secure->user, \
    223     0   stevel 			(PPS)->users_allowed, \
    224     0   stevel 			(PPS)->users_denied \
    225     0   stevel 		) \
    226     0   stevel 	)
    227     0   stevel 
    228     0   stevel 	/*
    229     0   stevel 	 * This macro checks that the form is allowed on the printer,
    230     0   stevel 	 * or is already mounted there.
    231     0   stevel 	 * Note: By doing this check we don't have to check that the
    232     0   stevel 	 * characteristics of the form, such as pitch, size, or
    233     0   stevel 	 * character set, against the printer's capabilities, ASSUMING,
    234     0   stevel 	 * of course, that the allow list is correct. That is, the
    235     0   stevel 	 * allow list lists forms that have already been checked against
    236     0   stevel 	 * the printer!
    237     0   stevel 	 */
    238     0   stevel #define CHKF(PFS,PPS) \
    239     0   stevel 	( \
    240     0   stevel 		isFormMountedOnPrinter(PPS,PFS) \
    241     0   stevel 	     || allowed( \
    242     0   stevel 			(PFS)->form->name, \
    243     0   stevel 			(PPS)->forms_allowed, \
    244     0   stevel 			(PPS)->forms_denied \
    245     0   stevel 		) \
    246     0   stevel 	)
    247     0   stevel 
    248     0   stevel 	/*
    249     0   stevel 	 * This macro checks that the print wheel is acceptable
    250     0   stevel 	 * for the printer or is mounted. Note: If the printer doesn't
    251     0   stevel 	 * take print wheels, the check passes. The check for printers
    252     0   stevel 	 * that don't take print wheels is below.
    253     0   stevel 	 */
    254     0   stevel #define CHKPW(PW,PPS) \
    255     0   stevel 	( \
    256     0   stevel 		!(PPS)->printer->daisy \
    257     0   stevel 	     || ( \
    258     0   stevel 			(PPS)->pwheel_name \
    259     0   stevel 		     && STREQU((PPS)->pwheel_name, (PW)) \
    260     0   stevel 		) \
    261     0   stevel 	     || searchlist((PW), (PPS)->printer->char_sets) \
    262     0   stevel 	)
    263     0   stevel 
    264     0   stevel 	/*
    265     0   stevel 	 * This macro checks the pitch, page size, and (if need be)
    266     0   stevel 	 * the character set. The character set isn't checked if the
    267     0   stevel 	 * printer takes print wheels, or if the character set is
    268     0   stevel 	 * listed in the printer's alias list.
    269     0   stevel 	 * The form has to be checked as well; while we're sure that
    270     0   stevel 	 * at least one type for each printer can handle the form's
    271     0   stevel 	 * cpi/lpi/etc. characteristics (lpadmin made sure), we aren't
    272     0   stevel 	 * sure that ALL the types work.
    273     0   stevel 	 */
    274     0   stevel #define CHKOPTS(PRS,PC,PFS) _chkopts((PRS),(PC),(PFS)) /* was a macro */
    275     0   stevel 
    276     0   stevel 	/*
    277     0   stevel 	 * This macro checks the acceptance status of a printer.
    278     0   stevel 	 * If the request is already assigned to that printer,
    279     0   stevel 	 * then it's okay. It's ambiguous what should happen if
    280     0   stevel 	 * originally a "-d any" request was accepted, temporarily
    281     0   stevel 	 * assigned one printer, then the administrator (1) rejected
    282     0   stevel 	 * further requests for the printers and (2) made the
    283     0   stevel 	 * temporarily assigned printer unusable for the request.
    284     0   stevel 	 * What will happen, of course, is that the request will
    285     0   stevel 	 * be canceled, even though the other printers would be okay
    286     0   stevel 	 * if not rejecting....but if we were to say, gee it's okay,
    287     0   stevel 	 * the request has already been accepted, we may be allowing
    288     0   stevel 	 * it on printers that were NEVER accepting. Thus we can
    289     0   stevel 	 * continue to accept it only for the printer already assigned.
    290     0   stevel 	 */
    291     0   stevel #define CHKACCEPT(PRS,PPS) \
    292     0   stevel 	( \
    293     0   stevel 		!((PPS)->status & PS_REJECTED) \
    294     0   stevel 	     || (PRS)->printer == (PPS) \
    295     0   stevel 	     || moving \
    296     0   stevel 	)
    297     0   stevel 
    298     0   stevel 	/*
    299     0   stevel 	 * If a print wheel or character set is given, see if it
    300     0   stevel 	 * is allowed on the form.
    301     0   stevel 	 */
    302     0   stevel 	if (prs->request->charset)
    303     0   stevel 		if (
    304     0   stevel 			!CHKMAND(pfs)
    305     0   stevel 		     || STREQU(prs->request->charset, pfs->form->chset)
    306     0   stevel 		)
    307     0   stevel 			/*EMPTY*/;
    308     0   stevel 		else {
    309     0   stevel 			ret = MDENYMEDIA;
    310     0   stevel 			chkprinter_result |= PCK_CHARSET;
    311     0   stevel 			goto Return;
    312     0   stevel 		}
    313     0   stevel 
    314     0   stevel 	/*
    315     0   stevel 	 * If a single printer was named, check the request against it.
    316     0   stevel 	 * Do the accept/reject check late so that we give the most
    317     0   stevel 	 * useful information to the user.
    318     0   stevel 	 */
    319     0   stevel 	if (pps) {
    320     0   stevel 		(pc = &single)->pps = pps;
    321     0   stevel 
    322     0   stevel 		/* Does the printer allow the user? */
    323     0   stevel 		if (!CHKU(prs, pps)) {
    324     0   stevel 			ret = MDENYDEST;
    325     0   stevel 			goto Return;
    326  1676      jpk 		}
    327  1676      jpk 
    328  1676      jpk 		/* Check printer label range */
    329  1676      jpk 		if (is_system_labeled() && prs->secure->slabel != NULL) {
    330  1676      jpk 			if (tsol_check_printer_label_range(
    331  1676      jpk 			    prs->secure->slabel,
    332  1676      jpk 			    pps->printer->name) == 0) {
    333  1676      jpk 				ret = MDENYDEST;
    334  1676      jpk 				goto Return;
    335  1676      jpk 			}
    336     0   stevel 		}
    337     0   stevel 
    338     0   stevel 		/* Does the printer allow the form? */
    339     0   stevel 		if (pfs && !CHKF(pfs, pps)) {
    340     0   stevel 			ret = MNOMOUNT;
    341     0   stevel 			goto Return;
    342     0   stevel 		}
    343     0   stevel 
    344     0   stevel 		/* Does the printer allow the pwheel? */
    345     0   stevel 		if (
    346     0   stevel 			prs->request->charset
    347     0   stevel 		     && !CHKPW(prs->request->charset, pps)
    348     0   stevel 		) {
    349     0   stevel 			ret = MNOMOUNT;
    350     0   stevel 			goto Return;
    351     0   stevel 		}
    352     0   stevel 
    353     0   stevel 		/* Can printer handle the pitch/size/charset/nobanner? */
    354     0   stevel 		if (!CHKOPTS(prs, pc, pfs)) {
    355     0   stevel 			ret = MDENYDEST;
    356     0   stevel 			goto Return;
    357     0   stevel 		}
    358     0   stevel 
    359     0   stevel 		/* Is the printer allowing requests? */
    360     0   stevel 		if (!CHKACCEPT(prs, pps)) {
    361     0   stevel 			ret = MERRDEST;
    362     0   stevel 			goto Return;
    363     0   stevel 		}
    364     0   stevel 
    365     0   stevel 		/* Is there a filter which will convert the input? */
    366     0   stevel 		if (!pickfilter(prs, pc, pfs)) {
    367     0   stevel 			ret = MNOFILTER;
    368     0   stevel 			goto Return;
    369     0   stevel 		}
    370     0   stevel 
    371     0   stevel 		best_pc = pc;
    372     0   stevel 		ret = MOK;
    373     0   stevel 		goto Return;
    374     0   stevel 	}
    375     0   stevel 
    376     0   stevel 	/*
    377     0   stevel 	 * Do the acceptance check on the class (if we have one)
    378     0   stevel 	 * now so we can proceed with checks on individual printers
    379     0   stevel 	 * in the class. Don't toss out the request if it is already
    380     0   stevel 	 * assigned a printer just because the class is NOW rejecting.
    381     0   stevel 	 */
    382     0   stevel 	if (
    383     0   stevel 		pcs
    384     0   stevel 	     && (pcs->status & CS_REJECTED)
    385     0   stevel 	     && !moving
    386     0   stevel 	     && !prs->printer
    387     0   stevel 	) {
    388     0   stevel 		ret = MERRDEST;
    389     0   stevel 		goto Return;
    390     0   stevel 	}
    391     0   stevel 
    392     0   stevel 	/*
    393     0   stevel 	 * Construct a list of printers based on the destination
    394     0   stevel 	 * given. Cross off those that aren't accepting requests,
    395     0   stevel 	 * that can't take the form, or which the user can't use.
    396     0   stevel 	 * See if the list becomes empty.
    397     0   stevel 	 */
    398     0   stevel 
    399     0   stevel 	if (pcs)
    400     0   stevel 		n = lenlist(pcs->class->members);
    401     0   stevel 	else {
    402  3125   jacobs 		for (n = 0; PStatus != NULL && PStatus[n] != NULL; n++) ;
    403     0   stevel 	}
    404     0   stevel 	pcend = arena = (CANDIDATE *)Calloc(n, sizeof(CANDIDATE));
    405     0   stevel 
    406     0   stevel 	/*
    407     0   stevel 	 * Start with a list of printers that are accepting requests.
    408     0   stevel 	 * Don't skip a printer if it's rejecting but the request
    409     0   stevel 	 * has already been accepted for it.
    410     0   stevel 	 */
    411     0   stevel 	if (pcs) {
    412     0   stevel 		register char		 **pn;
    413     0   stevel 
    414     0   stevel 		for (pn = pcs->class->members; *pn; pn++)
    415     0   stevel 			if (
    416  3125   jacobs 				((pps = search_pstatus(*pn)) != NULL)
    417     0   stevel 			     && pps != stop_pps
    418     0   stevel 			)
    419     0   stevel 				(pcend++)->pps = pps;
    420     0   stevel 
    421     0   stevel 
    422     0   stevel 	} else
    423  3125   jacobs 		for (i = 0; PStatus != NULL && PStatus[i] != NULL; i++) {
    424  3125   jacobs 			pps = PStatus[i];
    425  3125   jacobs 
    426     0   stevel 			if (CHKACCEPT(prs, pps) && pps != stop_pps)
    427     0   stevel 				(pcend++)->pps = pps;
    428  3125   jacobs 		}
    429     0   stevel 
    430     0   stevel 	if (pcend == arena) {
    431     0   stevel 		ret = MERRDEST;
    432     0   stevel 		goto Return;
    433     0   stevel 	}
    434     0   stevel 
    435     0   stevel 	/*
    436     0   stevel 	 * Clean out printers that the user can't use. We piggy-back
    437     0   stevel 	 * the pitch/size/banner checks here because the same error return
    438     0   stevel 	 * is given (strange, eh?).
    439     0   stevel 	 */
    440     0   stevel 	{
    441     0   stevel 		register CANDIDATE	*pcend2;
    442     0   stevel 
    443     0   stevel 		for (pcend2 = pc = arena; pc < pcend; pc++) {
    444     0   stevel 			if (CHKU(prs, pc->pps) && CHKOPTS(prs, pc, pfs))
    445     0   stevel 				*pcend2++ = *pc;
    446     0   stevel 			else
    447     0   stevel 				free_candidate (pc);
    448     0   stevel 		}
    449     0   stevel 
    450     0   stevel 		if (pcend2 == arena) {
    451     0   stevel 			ret = MDENYDEST;
    452     0   stevel 			goto Return;
    453     0   stevel 		}
    454     0   stevel 		pcend = pcend2;
    455     0   stevel 
    456     0   stevel 	}
    457     0   stevel 
    458     0   stevel 	/*
    459     0   stevel 	 * Clean out printers that can't mount the form,
    460     0   stevel 	 * EXCEPT for printers that already have it mounted:
    461     0   stevel 	 */
    462     0   stevel 	if (pfs) {
    463     0   stevel 		register CANDIDATE	*pcend2;
    464     0   stevel 
    465     0   stevel 		for (pcend2 = pc = arena; pc < pcend; pc++)
    466     0   stevel 			if (CHKF(pfs, pc->pps))
    467     0   stevel 				*pcend2++ = *pc;
    468     0   stevel 			else
    469     0   stevel 				free_candidate (pc);
    470     0   stevel 
    471     0   stevel 		if (pcend2 == arena) {
    472     0   stevel 			ret = MNOMOUNT;
    473     0   stevel 			goto Return;
    474     0   stevel 		}
    475     0   stevel 		pcend = pcend2;
    476     0   stevel 
    477     0   stevel 	}
    478     0   stevel 
    479     0   stevel 	/*
    480     0   stevel 	 * Clean out printers that can't take the print wheel
    481     0   stevel 	 * EXCEPT for printers that already have it mounted
    482     0   stevel 	 * or printers for which it is a selectable character set:
    483     0   stevel 	 */
    484     0   stevel 	if (prs->request->charset) {
    485     0   stevel 		register CANDIDATE	*pcend2;
    486     0   stevel 
    487     0   stevel 		for (pcend2 = pc = arena; pc < pcend; pc++)
    488     0   stevel 			if (CHKPW(prs->request->charset, pc->pps))
    489     0   stevel 				*pcend2++ = *pc;
    490     0   stevel 			else
    491     0   stevel 				free_candidate (pc);
    492     0   stevel 
    493     0   stevel 		if (pcend2 == arena) {
    494     0   stevel 			ret = MNOMOUNT;
    495     0   stevel 			goto Return;
    496     0   stevel 		}
    497     0   stevel 		pcend = pcend2;
    498     0   stevel 
    499     0   stevel 	}
    500     0   stevel 
    501     0   stevel 	/*
    502     0   stevel 	 * Clean out printers that can't handle the printing
    503     0   stevel 	 * and for which there's no filter to convert the input.
    504     0   stevel 	 *
    505     0   stevel 	 */
    506     0   stevel 
    507     0   stevel 	/*
    508     0   stevel 	 * Is the form mounted, or is none needed?
    509     0   stevel 	 */
    510     0   stevel #define CHKFMNT(PFS,PPS) (isFormUsableOnPrinter(PPS,PFS))
    511     0   stevel 
    512     0   stevel 	/*
    513     0   stevel 	 * Is the print-wheel mounted, or is none needed?
    514     0   stevel 	 */
    515     0   stevel #define CHKPWMNT(PRS,PPS) SAME((PPS)->pwheel_name, (PRS)->request->charset)
    516     0   stevel 
    517     0   stevel 	/*
    518     0   stevel 	 * Do we NOT need a special character set, or can we select
    519     0   stevel 	 * it on the printer? Note: Getting this far means that IF
    520     0   stevel 	 * the printer has selectable character sets (!daisy) then
    521     0   stevel 	 * it can select the one we want.
    522     0   stevel 	 */
    523     0   stevel #define CHKCHSET(PRS,PPS) \
    524     0   stevel 	( \
    525     0   stevel 		!(PRS)->request->charset \
    526     0   stevel 	     || !(PPS)->printer->daisy \
    527     0   stevel 	)
    528     0   stevel 
    529     0   stevel 	/*
    530     0   stevel 	 * Is the printer able to print now?
    531     0   stevel 	 */
    532     0   stevel #define CHKENB(PPS)	 (!((PPS)->status & (PS_DISABLED|PS_FAULTED)))
    533     0   stevel 
    534     0   stevel 	/*
    535     0   stevel 	 * Is the printer not busy printing another request, or
    536     0   stevel 	 * not awaiting an auto-retry after a fault?
    537     0   stevel 	 */
    538     0   stevel #define CHKFREE(PPS)	 (!((PPS)->status & (PS_BUSY|PS_LATER)))
    539     0   stevel 
    540     0   stevel 	{
    541     0   stevel 		register CANDIDATE	*pcend2;
    542     0   stevel 
    543     0   stevel 		for (pcend2 = pc = arena; pc < pcend; pc++)
    544     0   stevel 			if (pickfilter(prs, pc, pfs)) {
    545     0   stevel 
    546     0   stevel 				/*
    547     0   stevel 				 * Compute a ``weight'' for this printer,
    548     0   stevel 				 * based on its status. We'll later pick
    549     0   stevel 				 * the printer with the highest weight.
    550     0   stevel 				 */
    551     0   stevel 				pc->weight = 0;
    552     0   stevel 				if (!pc->fast && !pc->slow)
    553     0   stevel 					pc->weight += WEIGHT_NOFILTER;
    554     0   stevel 				if (CHKFREE(pc->pps))
    555     0   stevel 					pc->weight += WEIGHT_FREE;
    556     0   stevel 				if (CHKENB(pc->pps))
    557     0   stevel 					pc->weight += WEIGHT_ENABLED;
    558     0   stevel 				if (CHKFMNT(pfs, pc->pps))
    559     0   stevel 					pc->weight += WEIGHT_MOUNTED;
    560     0   stevel 				if (CHKPWMNT(prs, pc->pps))
    561     0   stevel 					pc->weight += WEIGHT_MOUNTED;
    562     0   stevel 				if (CHKCHSET(prs, pc->pps))
    563     0   stevel 					pc->weight += WEIGHT_SELECTS;
    564     0   stevel 
    565     0   stevel #if	defined(FILTER_EARLY_OUT)
    566     0   stevel 				if (pc->weight == WEIGHT_MAX) {
    567     0   stevel 					/*
    568     0   stevel 					 * This is the one!
    569     0   stevel 					 */
    570     0   stevel 					best_pc = pc;
    571     0   stevel 					ret = MOK;
    572     0   stevel 					goto Return;
    573     0   stevel 				}
    574     0   stevel #endif
    575     0   stevel 				/*
    576     0   stevel 				 * This is a candidate!
    577     0   stevel 				 */
    578     0   stevel 				*pcend2++ = *pc;
    579     0   stevel 
    580     0   stevel 			} else
    581     0   stevel 				/*
    582     0   stevel 				 * No filter for this one!
    583     0   stevel 				 */
    584     0   stevel 				free_candidate (pc);
    585     0   stevel 
    586     0   stevel 		if (pcend2 == arena) {
    587     0   stevel 			ret = MNOFILTER;
    588     0   stevel 			goto Return;
    589     0   stevel 		}
    590     0   stevel 		pcend = pcend2;
    591     0   stevel 
    592     0   stevel 	}
    593     0   stevel 
    594     0   stevel 	if (pcend - arena == 1) {
    595     0   stevel 		best_pc = arena;
    596     0   stevel 		ret = MOK;
    597     0   stevel 		goto Return;
    598     0   stevel 	}
    599  1676      jpk 	/*
    600  1676      jpk 	 * Clean out local printers
    601  1676      jpk 	 * where the request is outside the printer label range.
    602  1676      jpk 	 */
    603  1676      jpk 	{
    604  4633  keerthi 		register CANDIDATE	*pcend2 = pcend;
    605  1676      jpk 
    606  1676      jpk 		if (is_system_labeled()) {
    607  1676      jpk 			for (pcend2 = pc = arena; pc < pcend; pc++) {
    608  1676      jpk 				if (tsol_check_printer_label_range(
    609  1676      jpk 				    prs->secure->slabel,
    610  1676      jpk 				    pps->printer->name) == 1)
    611  1676      jpk 					*pcend2++ = *pc;
    612  1676      jpk 				else
    613  1676      jpk 					free_candidate(pc);
    614  1676      jpk 			}
    615  1676      jpk 		}
    616  1676      jpk 
    617  1676      jpk 		if (pcend2 == arena) {
    618  1676      jpk 			ret = MDENYDEST;
    619  1676      jpk 			goto Return;
    620  1676      jpk 		}
    621  1676      jpk 		pcend = pcend2;
    622  1676      jpk 	}
    623     0   stevel 
    624     0   stevel #if	defined(OTHER_FACTORS)
    625     0   stevel 	/*
    626     0   stevel 	 * Here you might want to add code that considers
    627     0   stevel 	 * other factors: the size of the file(s) to be
    628     0   stevel 	 * printed ("prs->secure->size") in relation to the
    629     0   stevel 	 * printer (e.g. printer A gets mostly large
    630     0   stevel 	 * files, printer B gets mostly small files); the
    631     0   stevel 	 * number/total-size of requests currently queued
    632     0   stevel 	 * for the printer; etc.
    633     0   stevel 	 *
    634     0   stevel 	 * If your code includes eliminating printers drop them
    635     0   stevel 	 * from the list (as done in several places above).
    636     0   stevel 	 * Otherwise, your code should add weights to the weight
    637     0   stevel 	 * already computed. Change the WEIGHT_MAX, increase the
    638     0   stevel 	 * other WEIGHT_X values to compensate, etc., as appropriate.
    639     0   stevel 	 */
    640     0   stevel 	;
    641     0   stevel #endif
    642     0   stevel 
    643     0   stevel 	/*
    644     0   stevel 	 * Pick the best printer from a list of eligible candidates.
    645     0   stevel 	 */
    646     0   stevel 	best_pc = arena;
    647     0   stevel 	for (pc = arena + 1; pc < pcend; pc++)
    648     0   stevel 		if (pc->weight > best_pc->weight)
    649     0   stevel 			best_pc = pc;
    650     0   stevel 	ret = MOK;
    651     0   stevel 
    652     0   stevel 	/*
    653     0   stevel 	 * Branch to here if MOK and/or if things have been allocated.
    654     0   stevel 	 */
    655     0   stevel Return:	if (ret == MOK) {
    656     0   stevel 		register USER		*pu = Getuser(prs->secure->user);
    657     0   stevel 
    658     0   stevel 		register char		*pwheel_name;
    659     0   stevel 
    660     0   stevel 		PSTATUS			*oldpps = prs->printer;
    661     0   stevel 
    662     0   stevel 
    663     0   stevel 		/*
    664     0   stevel 		 * We are going to accept this print request, having
    665     0   stevel 		 * found a printer for it. This printer will be assigned
    666     0   stevel 		 * to the request, although this assignment may be
    667     0   stevel 		 * temporary if other printers qualify and this printer
    668     0   stevel 		 * is changed to no longer qualify. Qualification in
    669     0   stevel 		 * this context includes being ready to print!
    670     0   stevel 		 */
    671     0   stevel 		prs->printer = best_pc->pps;
    672     0   stevel 		load_str (&(prs->printer_type), best_pc->printer_type);
    673     0   stevel 
    674     0   stevel 		/*
    675     0   stevel 		 * Assign the form (if any) to the request. Adjust
    676     0   stevel 		 * the number of requests queued for old and new form
    677     0   stevel 		 * accordingly.
    678     0   stevel 		 */
    679     0   stevel 		if (prs->form != pfs) {
    680     0   stevel 			unqueue_form (prs);
    681     0   stevel 			queue_form (prs, pfs);
    682     0   stevel 		}
    683     0   stevel 
    684     0   stevel 		/*
    685     0   stevel 		 * Ditto for the print wheel, except include here the
    686     0   stevel 		 * print wheel needed by the form.
    687     0   stevel 		 * CAUTION: When checking this request later, don't
    688     0   stevel 		 * refuse to service it if the print wheel for the
    689     0   stevel 		 * form isn't mounted but the form is; a mounted form
    690     0   stevel 		 * overrides its other needs. Don't be confused by the
    691     0   stevel 		 * name of the bit, RSS_PWMAND; a printer that prints
    692     0   stevel 		 * this request MUST have the print wheel mounted
    693     0   stevel 		 * (if it takes print wheels) if the user asked for
    694     0   stevel 		 * a particular print wheel.
    695     0   stevel 		 */
    696     0   stevel 		prs->status &= ~RSS_PWMAND;
    697     0   stevel 		if (CHKMAND(pfs))
    698     0   stevel 			pwheel_name = pfs->form->chset;
    699     0   stevel 		else
    700     0   stevel 			if ((pwheel_name = prs->request->charset) != NULL)
    701     0   stevel 				prs->status |= RSS_PWMAND;
    702     0   stevel 
    703     0   stevel 		if (!SAME(pwheel_name, prs->pwheel_name)) {
    704     0   stevel 			unqueue_pwheel (prs);
    705     0   stevel 			queue_pwheel (prs, pwheel_name);
    706     0   stevel 		}
    707     0   stevel 
    708     0   stevel 		/*
    709     0   stevel 		 * Adjust the priority to lie within the limits allowed
    710     0   stevel 		 * for the user (this is a silent adjustment as required).
    711     0   stevel 		 * CURRENTLY, ONLY NEW REQUESTS WILL GET QUEUED ACCORDING
    712     0   stevel 		 * TO THIS PRIORITY. EXISTING REQUESTS BEING (RE)EVALUATED
    713     0   stevel 		 * WILL NOT BE REQUEUED.
    714     0   stevel 		 * A wild priority is changed to the default, or the
    715     0   stevel 		 * limit, whichever is the lower priority (higher value).
    716     0   stevel 		 */
    717     0   stevel 		if (prs->request->priority < 0 || 39 < prs->request->priority)
    718     0   stevel 			prs->request->priority = getdfltpri();
    719     0   stevel 		if (pu && prs->request->priority < pu->priority_limit)
    720     0   stevel 			prs->request->priority = pu->priority_limit;
    721     0   stevel 
    722     0   stevel 		/*
    723     0   stevel 		 * If a filter is involved, change the number of
    724     0   stevel 		 * copies to 1 (if the filter handles it).
    725     0   stevel 		 */
    726     0   stevel 		if (
    727     0   stevel 			(best_pc->fast || best_pc->slow)
    728     0   stevel 		     && (best_pc->flags & FPARM_COPIES)
    729     0   stevel 		     && prs->request->copies > 1
    730     0   stevel 		)
    731     0   stevel 			prs->copies = 1;
    732     0   stevel 		else
    733     0   stevel 			/*
    734     0   stevel 			 * We use two ".copies" because we don't
    735     0   stevel 			 * want to lose track of the number requested,
    736     0   stevel 			 * but do want to mark the number the interface
    737     0   stevel 			 * program is to handle. Here is the best
    738     0   stevel 			 * place to know this.
    739     0   stevel 			 */
    740     0   stevel 			prs->copies = prs->request->copies;
    741     0   stevel 
    742     0   stevel 		if (best_pc->slow) {
    743     0   stevel 			/*
    744     0   stevel 			 * If the filter has changed, the request will
    745     0   stevel 			 * have to be refiltered. This may mean stopping
    746     0   stevel 			 * a currently running filter or interface.
    747     0   stevel 			 */
    748     0   stevel 			if (!SAME(best_pc->slow, prs->slow)) {
    749     0   stevel 
    750     0   stevel 			    if (prs->request->outcome & RS_FILTERED)
    751     0   stevel 				prs->request->outcome &= ~RS_FILTERED;
    752     0   stevel 
    753     0   stevel 			    if (
    754     0   stevel 				prs->request->outcome & RS_FILTERING
    755     0   stevel 			     && !(prs->request->outcome & RS_STOPPED)
    756     0   stevel 			    ) {
    757     0   stevel 				prs->request->outcome |= RS_REFILTER;
    758     0   stevel 				prs->request->outcome |= RS_STOPPED;
    759     0   stevel 				terminate (prs->exec);
    760     0   stevel 
    761     0   stevel 			    } else if (
    762     0   stevel 				prs->request->outcome & RS_PRINTING
    763     0   stevel 			     && !(prs->request->outcome & RS_STOPPED)
    764     0   stevel 			    ) {
    765     0   stevel 				prs->request->outcome |= RS_STOPPED;
    766     0   stevel 				terminate (oldpps->exec);
    767     0   stevel 			    }
    768     0   stevel 
    769     0   stevel 			}
    770     0   stevel 
    771     0   stevel 			load_str (&(prs->slow), best_pc->slow);
    772     0   stevel 			/* Assumption: if there is a slow filter,
    773     0   stevel 			 * there is an output_type
    774     0   stevel 			 */
    775     0   stevel 
    776     0   stevel 			load_str (&(prs->output_type), best_pc->output_type);
    777     0   stevel 		} else
    778     0   stevel 			unload_str (&(prs->slow));
    779     0   stevel 
    780     0   stevel 		load_str (&(prs->fast), best_pc->fast);
    781     0   stevel 
    782     0   stevel 		if (prs->request->actions & ACT_FAST && prs->slow) {
    783     0   stevel 			if (prs->fast) {
    784     0   stevel 				prs->fast = makestr(
    785     0   stevel 					prs->slow,
    786     0   stevel 					"|",
    787     0   stevel 					prs->fast,
    788     0   stevel 					(char *)0
    789     0   stevel 				);
    790     0   stevel 				Free (prs->slow);
    791     0   stevel 			} else
    792     0   stevel 				prs->fast = prs->slow;
    793     0   stevel 			prs->slow = 0;
    794     0   stevel 		}
    795     0   stevel 
    796     0   stevel 	}
    797     0   stevel 
    798     0   stevel 
    799     0   stevel 	/*
    800     0   stevel 	 * Free the space allocated for the candidates, INCLUDING
    801     0   stevel 	 * the one chosen. Any allocated space in the chosen candidate
    802     0   stevel 	 * that has to be saved should have been COPIED already.
    803     0   stevel 	 */
    804     0   stevel 	if (arena) {
    805     0   stevel 		for (pc = arena; pc < pcend; pc++)
    806     0   stevel 			free_candidate (pc);
    807     0   stevel 		Free ((char *)arena);
    808     0   stevel 	} else if (best_pc)
    809     0   stevel 		free_candidate (best_pc);
    810     0   stevel 
    811     0   stevel 	if (o_length)
    812     0   stevel 		Free (o_length);
    813     0   stevel 	if (o_width)
    814     0   stevel 		Free (o_width);
    815     0   stevel 	if (o_lpi)
    816     0   stevel 		Free (o_lpi);
    817     0   stevel 	if (o_cpi)
    818     0   stevel 		Free (o_cpi);
    819     0   stevel 
    820     0   stevel 
    821     0   stevel 	/*
    822     0   stevel 	 * The following value is valid ONLY IF the request
    823     0   stevel 	 * is canceled or rejected. Not all requests that
    824     0   stevel 	 * we fail in this routine are tossed out!
    825     0   stevel 	 */
    826     0   stevel 	prs->reason = ret;
    827     0   stevel 
    828     0   stevel 
    829     0   stevel 	return (ret);
    830     0   stevel }
    831     0   stevel 
    832     0   stevel /**
    833     0   stevel  ** _chkopts() - CHECK -o OPTIONS
    834     0   stevel  **/
    835     0   stevel 
    836     0   stevel static int
    837     0   stevel _chkopts(RSTATUS *prs, CANDIDATE *pc, FSTATUS *pfs)
    838     0   stevel {
    839     0   stevel 	unsigned long		ret	= 0;
    840     0   stevel 	unsigned long		chk	= 0;
    841     0   stevel 
    842     0   stevel 	char *			charset;
    843     0   stevel 	char *			cpi	= 0;
    844     0   stevel 	char *			lpi	= 0;
    845     0   stevel 	char *			width	= 0;
    846     0   stevel 	char *			length	= 0;
    847     0   stevel 	char *			paper = NULL;
    848     0   stevel 
    849     0   stevel 	char **			pt;
    850  1676      jpk 	int			nobanner_not_allowed = 0;
    851     0   stevel 
    852     0   stevel 
    853     0   stevel 	/*
    854     0   stevel 	 * If we have a form, it overrides whatever print characteristics
    855     0   stevel 	 * the user gave.
    856     0   stevel 	 */
    857     0   stevel 	if (pfs) {
    858     0   stevel 		cpi = pfs->cpi;
    859     0   stevel 		lpi = pfs->lpi;
    860     0   stevel 		width = pfs->pwid;
    861     0   stevel 		length = pfs->plen;
    862     0   stevel 		paper = pfs->form->paper;
    863     0   stevel 	} else {
    864     0   stevel 		cpi = o_cpi;
    865     0   stevel 		lpi = o_lpi;
    866     0   stevel 		width = o_width;
    867     0   stevel 		length = o_length;
    868     0   stevel 	}
    869     0   stevel 
    870     0   stevel 	/*
    871     0   stevel 	 * If the printer takes print wheels, or the character set
    872     0   stevel 	 * the user wants is listed in the character set map for this
    873     0   stevel 	 * printer, we needn't check if the printer can handle the
    874     0   stevel 	 * character set. (Note: The check for the print wheel case
    875     0   stevel 	 * is done elsewhere.)
    876     0   stevel 	 */
    877     0   stevel 
    878     0   stevel 	if (pc->pps->printer->daisy ||
    879     0   stevel 	    search_cslist(prs->request->charset, pc->pps->printer->char_sets))
    880     0   stevel 		charset = 0;
    881     0   stevel 	else
    882     0   stevel 		charset = prs->request->charset;
    883     0   stevel 
    884     0   stevel 	pc->printer_types = 0;
    885     0   stevel 	for (pt = pc->pps->printer->printer_types; *pt; pt++) {
    886     0   stevel 		unsigned long		this;
    887     0   stevel 
    888     0   stevel 		if (paper) {
    889     0   stevel 			if (allowed(paper,pc->pps->paper_allowed,NULL)) {
    890     0   stevel 				addlist (&(pc->printer_types), *pt);
    891     0   stevel 			} else {
    892     0   stevel 				ret |= PCK_PAPER;
    893     0   stevel 			}
    894     0   stevel 		} else {
    895     0   stevel 			this = chkprinter(*pt, cpi, lpi, length, width,
    896     0   stevel 				charset);
    897     0   stevel 			if (this == 0)
    898     0   stevel 				addlist(&(pc->printer_types), *pt);
    899     0   stevel 			chk |= this;
    900     0   stevel 		}
    901     0   stevel 	}
    902     0   stevel 	if (!pc->printer_types)
    903     0   stevel 		ret |= chk;
    904     0   stevel 
    905  1676      jpk 	/*
    906  1676      jpk 	 * If the sytem is labeled, then user who wants 'nolabels' must
    907  1676      jpk 	 * have PRINT_UNLABELED_AUTH authorizations to allow it.
    908  1676      jpk 	 */
    909  1676      jpk 	if (is_system_labeled() && (wants_nolabels == 1)) {
    910  1676      jpk 		if (!tsol_lpauth(PRINT_UNLABELED_AUTH, prs->secure->user)) {
    911  1676      jpk 			/* if not authorized, remove "nolabels" from options */
    912  1676      jpk 			register char		**list;
    913  1676      jpk 			if (prs->request->options &&
    914  1676      jpk 			    (list = dashos(prs->request->options))) {
    915  1676      jpk 				dellist(&list, "nolabels");
    916  1676      jpk 				free(prs->request->options);
    917  1676      jpk 				prs->request->options = sprintlist(list);
    918  1676      jpk 			}
    919  1676      jpk 		}
    920  1676      jpk 	}
    921  1676      jpk 
    922  1676      jpk 
    923     0   stevel 	if (pc->pps->printer->banner == BAN_ALWAYS) {
    924  1676      jpk 		/* delete "nobanner" */
    925  1676      jpk 		char **list;
    926     0   stevel 
    927  1676      jpk 		/*
    928  1676      jpk 		 * If the system is labeled, users must have
    929  1676      jpk 		 * PRINT_NOBANNER_AUTH authorization to print
    930  1676      jpk 		 * without a banner.
    931  1676      jpk 		 */
    932  1676      jpk 		if (is_system_labeled()) {
    933  1676      jpk 			if (wants_nobanner == 1) {
    934  1676      jpk 				if (tsol_lpauth(PRINT_NOBANNER_AUTH,
    935  1676      jpk 					prs->secure->user) == 0) {
    936  1676      jpk 					nobanner_not_allowed = 1;
    937  1676      jpk 				}
    938  1676      jpk 			}
    939  1676      jpk 
    940  1676      jpk 		}
    941  1676      jpk 		else if ((wants_nobanner == 1) && (lp_or_root != 1)) {
    942  1676      jpk 			nobanner_not_allowed = 1;
    943  1676      jpk 		}
    944  1676      jpk 		if (nobanner_not_allowed == 1) {
    945  1676      jpk 			/* Take out 'nobanner' from request options. */
    946     0   stevel 			if (prs->request->options &&
    947     0   stevel 			    (list = dashos(prs->request->options))) {
    948     0   stevel 				dellist(&list, "nobanner");
    949     0   stevel 				free(prs->request->options);
    950     0   stevel 				prs->request->options = sprintlist(list);
    951     0   stevel 			}
    952     0   stevel 		}
    953     0   stevel 	} else if (pc->pps->printer->banner == BAN_NEVER) {
    954     0   stevel 		if (wants_nobanner == 0) {
    955     0   stevel 			/* add "nobanner" */
    956     0   stevel 			char **list = NULL;
    957     0   stevel 
    958     0   stevel 			if (prs->request->options) {
    959     0   stevel 				list = dashos(prs->request->options);
    960     0   stevel 				free(prs->request->options);
    961     0   stevel 			}
    962     0   stevel 			appendlist(&list, "nobanner");
    963     0   stevel 			prs->request->options = sprintlist(list);
    964     0   stevel 		}
    965     0   stevel 	} else /* if (pc->pps->printer->banner == BAN_OPTIONAL) */ {
    966     0   stevel 		/* it is optional, leave it alone */
    967     0   stevel 	}
    968     0   stevel 
    969     0   stevel 	chkprinter_result |= ret;
    970     0   stevel 	return (ret == 0);
    971     0   stevel }
    972     0   stevel 
    973     0   stevel /**
    974     0   stevel  ** free_candidate()
    975     0   stevel  **/
    976     0   stevel 
    977     0   stevel static void
    978     0   stevel free_candidate(CANDIDATE *pc)
    979     0   stevel {
    980     0   stevel 	if (pc->slow)
    981     0   stevel 		unload_str (&(pc->slow));
    982     0   stevel 	if (pc->fast)
    983     0   stevel 		unload_str (&(pc->fast));
    984     0   stevel 	if (pc->printer_types) {
    985     0   stevel 		freelist (pc->printer_types);
    986     0   stevel 		pc->printer_types = 0;
    987     0   stevel 	}
    988     0   stevel 	if (pc->printer_type)
    989     0   stevel 		unload_str (&(pc->printer_type));
    990     0   stevel 	if (pc->output_type)
    991     0   stevel 		unload_str (&(pc->output_type));
    992     0   stevel 	return;
    993     0   stevel }
    994  1676      jpk 
    995  1676      jpk static int
    996  1676      jpk tsol_check_printer_label_range(char *slabel, const char *printer)
    997  1676      jpk {
    998  1676      jpk 	int			in_range = 0;
    999  1676      jpk 	int			err = 0;
   1000  1676      jpk 	m_range_t		*range;
   1001  1676      jpk 	m_label_t	*sl = NULL;
   1002  1676      jpk 
   1003  1676      jpk 	if (slabel == NULL)
   1004  1676      jpk 		return (0);
   1005  1676      jpk 
   1006  1676      jpk 	if ((err =
   1007  1676      jpk 	    (str_to_label(slabel, &sl, USER_CLEAR, L_NO_CORRECTION, &in_range)))
   1008  1676      jpk 	    == -1) {
   1009  1676      jpk 		/* stobsl error on printer max label */
   1010  1676      jpk 		return (0);
   1011  1676      jpk 	}
   1012  1676      jpk 	if ((range = getdevicerange(printer)) == NULL) {
   1013  1676      jpk 		m_label_free(sl);
   1014  1676      jpk 		return (0);
   1015  1676      jpk 	}
   1016  1676      jpk 
   1017  1676      jpk 	/* blinrange returns true (1) if in range, false (0) if not */
   1018  1676      jpk 	in_range = blinrange(sl, range);
   1019  1676      jpk 
   1020  1676      jpk 	m_label_free(sl);
   1021  1676      jpk 	m_label_free(range->lower_bound);
   1022  1676      jpk 	m_label_free(range->upper_bound);
   1023  1676      jpk 	free(range);
   1024  1676      jpk 
   1025  1676      jpk 	return (in_range);
   1026  1676      jpk }
   1027  1676      jpk 
   1028  1676      jpk /*
   1029  1676      jpk  * Given a character string with a "username" or "system!username"
   1030  1676      jpk  * this function returns a pointer to "username"
   1031  1676      jpk  */
   1032  1676      jpk static int
   1033  1676      jpk tsol_lpauth(char *auth, char *in_name)
   1034  1676      jpk {
   1035  1676      jpk 	char *cp;
   1036  1676      jpk 	int res;
   1037  1676      jpk 
   1038  1676      jpk 	if ((cp = strchr(in_name, '@')) != NULL) {
   1039  1676      jpk 		/* user@system */
   1040  1676      jpk 		*cp = '\0';
   1041  1676      jpk 		res = chkauthattr(auth, in_name);
   1042  1676      jpk 		*cp = '@';
   1043  1676      jpk 	} else if ((cp = strchr(in_name, '!')) != NULL)
   1044  1676      jpk 		/* system!user */
   1045  1676      jpk 		res = chkauthattr(auth, cp+1);
   1046  1676      jpk 	else
   1047  1676      jpk 		/* user */
   1048  1676      jpk 		res = chkauthattr(auth, in_name);
   1049  1676      jpk 
   1050  1676      jpk 	return (res);
   1051  1676      jpk }
   1052  1676      jpk 
   1053  1676      jpk #define	POLICY_FILE	"/etc/default/print"
   1054  1676      jpk 
   1055  1676      jpk int
   1056  1676      jpk secpolicy_chkpolicy(char *policyp)
   1057  1676      jpk {
   1058  1676      jpk 	char *option;
   1059  1676      jpk 	int opt_val;
   1060  1676      jpk 
   1061  1676      jpk 	if (policyp == NULL)
   1062  1676      jpk 		return (0);
   1063  1676      jpk 	opt_val = 0;
   1064  1676      jpk 	if (defopen(POLICY_FILE) == 0) {
   1065  1676      jpk 
   1066  1676      jpk 		defcntl(DC_SETFLAGS, DC_STD & ~DC_CASE); /* ignore case */
   1067  1676      jpk 
   1068  1676      jpk 		if ((option = defread(policyp)) != NULL)
   1069  1676      jpk 			opt_val = atoi(option);
   1070  1676      jpk 	}
   1071  1676      jpk 	(void) defopen((char *)NULL);
   1072  1676      jpk 	syslog(LOG_DEBUG, "--- Policy %s, opt_val==%d",
   1073  1676      jpk 	    policyp ? policyp : "NULL", opt_val);
   1074  1676      jpk 	return (opt_val);
   1075  1676      jpk }
   1076