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