Home | History | Annotate | Download | only in access
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License, Version 1.0 only
      6  * (the "License").  You may not use this file except in compliance
      7  * with the License.
      8  *
      9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
     10  * or http://www.opensolaris.org/os/licensing.
     11  * See the License for the specific language governing permissions
     12  * and limitations under the License.
     13  *
     14  * When distributing Covered Code, include this CDDL HEADER in each
     15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     16  * If applicable, add the following below this CDDL HEADER, with the
     17  * fields enclosed by brackets "[]" replaced with your own identifying
     18  * information: Portions Copyright [yyyy] [name of copyright owner]
     19  *
     20  * CDDL HEADER END
     21  */
     22 /*
     23  * Copyright 1999 Sun Microsystems, Inc.  All rights reserved.
     24  * Use is subject to license terms.
     25  */
     26 
     27 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
     28 /*	  All Rights Reserved  	*/
     29 
     30 
     31 #pragma ident	"%Z%%M%	%I%	%E% SMI"	/* SVr4.0 1.2	*/
     32 /* EMACS_MODES: !fill, lnumb, !overwrite, !nodelete, !picture */
     33 
     34 #include "string.h"
     35 #include "unistd.h"
     36 #include "stdlib.h"
     37 #include "sys/utsname.h"
     38 
     39 #include "lp.h"
     40 
     41 /*
     42  * The rules:
     43  *
     44  *	Key:	A - some system
     45  *		X - some user
     46  *
     47  *	X	a user named X on the local system
     48  *	A!X	the user named X from the system A
     49  *	all!X	all users named X from any system
     50  *	all	all users from local system
     51  *	A!all	all users from the system A
     52  *	all!all	all users from any system
     53  */
     54 
     55 
     56 /**
     57  ** bangequ() - LIKE STREQU, BUT HANDLES system!name CASES
     58  **/
     59 
     60 int
     61 bangequ (char *user1p, char *user2p)
     62 {
     63 	int	sysname1_all	= 0,
     64 		username1_all	= 0;
     65 	int	sysname2_all	= 0,
     66 		username2_all	= 0;
     67 	char	sysname1[BUFSIZ],
     68 		sysname2[BUFSIZ];
     69 	char	username1[BUFSIZ],
     70 		username2[BUFSIZ],
     71 		*sp;
     72 
     73 	static	char *Nodenamep = (char *) 0;
     74 
     75 	if (! user1p || ! user2p)
     76 		return	1;
     77 
     78 	if (! Nodenamep) {
     79 		struct utsname	utsbuf;
     80 
     81 		(void)	uname (&utsbuf);
     82 		Nodenamep = Strdup (utsbuf.nodename);
     83 	}
     84 
     85 	/* pattern=all */
     86 	if (STREQU (NAME_ALL, user2p) || STREQU(NAME_ALL, user1p))
     87 		return	1;
     88 
     89 	if ((sp = strrchr(user1p, '@')) != NULL) {	 /* user@host */
     90 		*sp++ = '\0';
     91 		(void) snprintf(sysname1, sizeof (sysname1), "%s", sp);
     92 		(void) snprintf(username1, sizeof (username1), "%s", user1p);
     93 		*--sp = '@';
     94 	} else if ((sp = strchr(user1p, '!')) != NULL) { /* host!user */
     95 		*sp++ = '\0';
     96 		(void) snprintf(sysname1, sizeof (sysname1), "%s", user1p);
     97 		(void) snprintf(username1, sizeof (username1), "%s", sp);
     98 		*--sp = '!';
     99 	} else {					 /* user */
    100 		(void) snprintf(sysname1, sizeof (sysname1), "%s", Nodenamep);
    101 		(void) snprintf(username1, sizeof (username1), "%s", user1p);
    102 	}
    103 
    104 	sysname1_all = STREQU (NAME_ALL, sysname1);
    105 	username1_all = STREQU (NAME_ALL, username1);
    106 
    107 	/* user2p is simple user name */
    108 	if (strpbrk (user2p, "!@") == NULL)
    109 		return	(username1_all && sysname1_all) ||
    110 			 STREQU (username1, user2p);
    111 
    112 	if ((sp = strrchr(user2p, '@')) != NULL) {	 /* user@host */
    113 		*sp++ = '\0';
    114 		(void) snprintf(sysname2, sizeof (sysname2), "%s", sp);
    115 		(void) snprintf(username2, sizeof (username2), "%s", user2p);
    116 		*--sp = '@';
    117 	} else if ((sp = strchr(user2p, '!')) != NULL) { /* host!user */
    118 		*sp++ = '\0';
    119 		(void) snprintf(sysname2, sizeof (sysname2), "%s", user2p);
    120 		(void) snprintf(username2, sizeof (username2), "%s", sp);
    121 		*--sp = '!';
    122 	} else {					 /* user */
    123 		(void) snprintf(sysname2, sizeof (sysname2), "%s", Nodenamep);
    124 		(void) snprintf(username2, sizeof (username2), "%s", user1p);
    125 	}
    126 
    127 	sysname2_all = STREQU (NAME_ALL, sysname2);
    128 	username2_all = STREQU (NAME_ALL, username2);
    129 
    130 	if ((sysname1_all && username1_all) ||
    131 	    (sysname2_all && username2_all) ||
    132 	    (sysname1_all && username2_all) ||
    133 	    (sysname2_all && username1_all))
    134 		return 1;
    135 
    136 	if (sysname1_all || sysname2_all)
    137 		return	STREQU (username1, username2);
    138 
    139 	if (username1_all || username2_all)
    140 		return STREQU (sysname1, sysname2);
    141 
    142 	if (STREQU (sysname1, sysname2) && STREQU (username1, username2))
    143 		return 1;
    144 
    145 	return 0;
    146 }
    147 
    148 /**
    149  ** bang_searchlist() - SEARCH (char **) LIST FOR "system!user" ITEM
    150  **/
    151 int
    152 bang_searchlist(char *item, char **list)
    153 {
    154 	if (!list || !*list)
    155 		return (0);
    156 
    157 	/*
    158 	 * This is a linear search--we believe that the lists
    159 	 * will be short.
    160 	 */
    161 	while (*list) {
    162 		if (bangequ(item, *list))
    163 			return (1);
    164 		list++;
    165 	}
    166 	return (0);
    167 }
    168 
    169 /**
    170  ** bang_dellist() - REMOVE "system!name" ITEM FROM (char **) LIST
    171  **/
    172 
    173 int
    174 bang_dellist(char ***plist, char *item)
    175 {
    176 	register char **	pl;
    177 	register char **	ql;
    178 
    179 	register int		n;
    180 
    181 				/*
    182 				 * "hole" is a pointer guaranteed not
    183 				 * to point to anyplace malloc'd.
    184 				 */
    185 	char *			hole	= "";
    186 
    187 
    188 	/*
    189 	 * There are two ways this routine is different from the
    190 	 * regular "dellist()" routine: First, the items are of the form
    191 	 * ``system!name'', which means there is a two part matching
    192 	 * for ``all'' cases (all systems and/or all names). Second,
    193 	 * ALL matching items in the list are deleted.
    194 	 *
    195 	 * Now suppose the list contains just the word ``all'', and
    196 	 * the item to be deleted is the name ``fred''. What will
    197 	 * happen? The word ``all'' will be deleted, leaving the list
    198 	 * empty (null)! This may sound odd at first, but keep in mind
    199 	 * that this routine is paired with the regular "addlist()"
    200 	 * routine; the item (``fred'') is ADDED to an opposite list
    201 	 * (we are either deleting from a deny list and adding to an allow
    202 	 * list or vice versa). So, to continue the example, if previously
    203 	 * ``all'' were allowed, removing ``fred'' from the allow list
    204 	 * does indeed empty that list, but then putting him in the deny
    205 	 * list means only ``fred'' is denied, which is the effect we
    206 	 * want.
    207 	 */
    208 
    209 	if (*plist) {
    210 
    211 		for (pl = *plist; *pl; pl++)
    212 			if (bangequ(item, *pl)) {
    213 				Free (*pl);
    214 				*pl = hole;
    215 			}
    216 
    217 		for (n = 0, ql = pl = *plist; *pl; pl++)
    218 			if (*pl != hole) {
    219 				*ql++ = *pl;
    220 				n++;
    221 			}
    222 
    223 		if (n == 0) {
    224 			Free ((char *)*plist);
    225 			*plist = 0;
    226 		} else {
    227 			*plist = (char **)Realloc(
    228 				(char *)*plist,
    229 				(n + 1) * sizeof(char *)
    230 			);
    231 			if (!*plist)
    232 				return (-1);
    233 			(*plist)[n] = 0;
    234 		}
    235 	}
    236 
    237 	return (0);
    238 }
    239