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
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.
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]
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.
28 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
29 /* All Rights Reserved */
32 #pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.2 */
33 /* EMACS_MODES: !fill, lnumb, !overwrite, !nodelete, !picture */
38 #include "sys/utsname.h"
45 * Key: A - some system
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
58 ** bangequ() - LIKE STREQU, BUT HANDLES system!name CASES
62 bangequ (char *user1p
, char *user2p
)
68 char sysname1
[BUFSIZ
],
70 char username1
[BUFSIZ
],
74 static char *Nodenamep
= (char *) 0;
76 if (! user1p
|| ! user2p
)
80 struct utsname utsbuf
;
82 (void) uname (&utsbuf
);
83 Nodenamep
= Strdup (utsbuf
.nodename
);
87 if (STREQU (NAME_ALL
, user2p
) || STREQU(NAME_ALL
, user1p
))
90 if ((sp
= strrchr(user1p
, '@')) != NULL
) { /* user@host */
92 (void) snprintf(sysname1
, sizeof (sysname1
), "%s", sp
);
93 (void) snprintf(username1
, sizeof (username1
), "%s", user1p
);
95 } else if ((sp
= strchr(user1p
, '!')) != NULL
) { /* host!user */
97 (void) snprintf(sysname1
, sizeof (sysname1
), "%s", user1p
);
98 (void) snprintf(username1
, sizeof (username1
), "%s", sp
);
101 (void) snprintf(sysname1
, sizeof (sysname1
), "%s", Nodenamep
);
102 (void) snprintf(username1
, sizeof (username1
), "%s", user1p
);
105 sysname1_all
= STREQU (NAME_ALL
, sysname1
);
106 username1_all
= STREQU (NAME_ALL
, username1
);
108 /* user2p is simple user name */
109 if (strpbrk (user2p
, "!@") == NULL
)
110 return (username1_all
&& sysname1_all
) ||
111 STREQU (username1
, user2p
);
113 if ((sp
= strrchr(user2p
, '@')) != NULL
) { /* user@host */
115 (void) snprintf(sysname2
, sizeof (sysname2
), "%s", sp
);
116 (void) snprintf(username2
, sizeof (username2
), "%s", user2p
);
118 } else if ((sp
= strchr(user2p
, '!')) != NULL
) { /* host!user */
120 (void) snprintf(sysname2
, sizeof (sysname2
), "%s", user2p
);
121 (void) snprintf(username2
, sizeof (username2
), "%s", sp
);
124 (void) snprintf(sysname2
, sizeof (sysname2
), "%s", Nodenamep
);
125 (void) snprintf(username2
, sizeof (username2
), "%s", user1p
);
128 sysname2_all
= STREQU (NAME_ALL
, sysname2
);
129 username2_all
= STREQU (NAME_ALL
, username2
);
131 if ((sysname1_all
&& username1_all
) ||
132 (sysname2_all
&& username2_all
) ||
133 (sysname1_all
&& username2_all
) ||
134 (sysname2_all
&& username1_all
))
137 if (sysname1_all
|| sysname2_all
)
138 return STREQU (username1
, username2
);
140 if (username1_all
|| username2_all
)
141 return STREQU (sysname1
, sysname2
);
143 if (STREQU (sysname1
, sysname2
) && STREQU (username1
, username2
))
150 ** bang_searchlist() - SEARCH (char **) LIST FOR "system!user" ITEM
153 bang_searchlist(char *item
, char **list
)
159 * This is a linear search--we believe that the lists
163 if (bangequ(item
, *list
))
171 ** bang_dellist() - REMOVE "system!name" ITEM FROM (char **) LIST
175 bang_dellist(char ***plist
, char *item
)
183 * "hole" is a pointer guaranteed not
184 * to point to anyplace malloc'd.
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.
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
212 for (pl
= *plist
; *pl
; pl
++)
213 if (bangequ(item
, *pl
)) {
218 for (n
= 0, ql
= pl
= *plist
; *pl
; pl
++)
225 Free ((char *)*plist
);
228 *plist
= (char **)Realloc(
230 (n
+ 1) * sizeof(char *)