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