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
bangequ(char * user1p,char * user2p)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
bang_searchlist(char * item,char ** list)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
bang_dellist(char *** plist,char * item)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