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