]>
git.saurik.com Git - apple/network_cmds.git/blob - ypserv.tproj/acl.c
6f0f1f57a74a516c819149d4fb65ae783f9e07b1
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
25 /* $OpenBSD: acl.c,v 1.5 1997/08/05 09:26:55 maja Exp $ */
28 * Copyright (c) 1994 Mats O Jansson <moj@stacken.kth.se>
29 * All rights reserved.
31 * Redistribution and use in source and binary forms, with or without
32 * modification, are permitted provided that the following conditions
34 * 1. Redistributions of source code must retain the above copyright
35 * notice, this list of conditions and the following disclaimer.
36 * 2. Redistributions in binary form must reproduce the above copyright
37 * notice, this list of conditions and the following disclaimer in the
38 * documentation and/or other materials provided with the distribution.
39 * 3. All advertising materials mentioning features or use of this software
40 * must display the following acknowledgement:
41 * This product includes software developed by Mats O Jansson
42 * 4. The name of the author may not be used to endorse or promote products
43 * derived from this software without specific prior written permission.
45 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
46 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
47 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
48 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
49 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
50 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
51 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
53 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
54 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59 static char rcsid
[] = "$OpenBSD: acl.c,v 1.5 1997/08/05 09:26:55 maja Exp $";
62 #include <sys/types.h>
63 #include <sys/socket.h>
64 #include <netinet/in.h>
65 #include <arpa/inet.h>
75 static struct aclent
*acl_root
= NULL
;
77 static int acl_read_line(fp
, buf
, size
)
85 /* Read a line, and remove any comment, trim space */
88 while (fgets(buf
, size
, fp
)) {
91 if ((*c
== '#') || (*c
== '\n')) {
100 if ((isspace(l
) != 0) && (isspace(*c
) != 0)) {
103 l
= *c
++; *p
= l
; p
++;
110 if (isspace(*p
) != 0) {
118 } while (size
> 0 && !feof(fp
));
125 struct in_addr
*addr
;
131 if ((addr
->s_addr
& p
->s_mask
) == p
->s_addr
) {
140 acl_add_net(allow
,addr
,mask
)
142 struct in_addr
*addr
,*mask
;
145 struct aclent
*acl
,*p
;
147 acl
= (struct aclent
*) malloc((unsigned) sizeof(struct aclent
));
151 acl
->s_addr
= addr
->s_addr
;
152 acl
->s_mask
= mask
->s_addr
;
154 if (acl_root
== NULL
) {
158 while (p
->next
!= NULL
)
166 acl_add_host(allow
,addr
)
168 struct in_addr
*addr
;
172 mask
.s_addr
= htonl(0xffffffff);
174 acl_add_net(allow
,addr
,&mask
);
181 char data_line
[1024];
188 struct in_addr addr
,mask
,*host_addr
;
189 struct hostent
*host
;
191 FILE *data_file
= NULL
;
194 data_file
= fopen(file
,"r");
197 while ((data_file
!= NULL
) &&
198 (acl_read_line(data_file
,data_line
,sizeof(data_line
)))) {
202 len
= strlen(data_line
);
207 p
= (char *) &data_line
;
209 /* State 1: Initial State */
212 addr
.s_addr
= mask
.s_addr
= 0;
214 k
= p
; i
= 0; /* save start of verb */
215 while ((*p
!= '\0') &&
216 (!isspace(*p
= tolower(*p
)))) {
224 if (strcmp(k
,"allow") == 0) {
229 if (strcmp(k
,"deny") == 0) {
234 if (state
== ACLS_INIT
) {
238 /* State 2: allow row */
239 /* State 3: deny row */
242 ((state
== ACLS_ALLOW
) || (state
== ACLS_DENY
))) {
244 k
= p
; i
= 0; /* save start of verb */
245 while ((*p
!= '\0') &&
246 (!isspace(*p
= tolower(*p
)))) {
254 if (strcmp(k
,"all") == 0) {
255 state
= state
+ ACLD_ALL
;
258 if (strcmp(k
,"host") == 0) {
259 state
= state
+ ACLD_HOST
;
262 if (strcmp(k
,"net") == 0) {
263 state
= state
+ ACLD_NET
;
266 if ((state
== ACLS_ALLOW
) || (state
== ACLS_DENY
)) {
272 if ((state
== ACLS_ALLOW
) || (state
== ACLS_DENY
)) {
276 /* State 4 & 5: all state, remove any comment */
279 ((state
== ACLS_ALLOW_ALL
) || (state
== ACLS_DENY_ALL
))) {
280 acl_add_net(allow
,&addr
,&mask
);
284 /* State 6 & 7: host line */
285 /* State 8 & 9: net line */
288 (state
>= ACLS_ALLOW_HOST
) && (state
<= ACLS_DENY_NET
)) {
290 k
= p
; i
= 0; /* save start of verb */
291 while ((*p
!= '\0') &&
292 (!isspace(*p
= tolower(*p
)))) {
300 if ((state
== ACLS_ALLOW_HOST
) || (state
== ACLS_DENY_HOST
)) {
301 if ((*k
>= '0') && (*k
<= '9')) {
302 (void)inet_aton(k
,&addr
);
303 acl_add_host(allow
,&addr
);
304 state
= state
+ ACLD_HOST_DONE
;
306 host
= gethostbyname(k
);
310 if (host
->h_addrtype
== AF_INET
) {
311 while ((host_addr
= (struct in_addr
*) *host
->h_addr_list
++)
313 acl_add_host(allow
,host_addr
);
315 state
= state
+ ACLD_HOST_DONE
;
320 if ((state
== ACLS_ALLOW_NET
) || (state
== ACLS_DENY_NET
)) {
321 if ((*k
>= '0') && (*k
<= '9')) {
322 (void)inet_aton(k
,&addr
);
323 state
= state
+ ACLD_NET_DONE
;
325 net
= getnetbyname(k
);
329 addr
.s_addr
= ntohl(net
->n_net
);
330 state
= state
+ ACLD_NET_DONE
;
337 if ((state
>= ACLS_ALLOW_HOST
) && (state
<= ACLS_DENY_NET
)) {
341 /* State 10 & 11: allow/deny host line */
344 ((state
== ACLS_ALLOW_HOST_DONE
) || (state
== ACLS_DENY_HOST_DONE
))) {
348 /* State 12 & 13: allow/deny net line */
351 ((state
== ACLS_ALLOW_NET_DONE
) || (state
== ACLS_DENY_NET_DONE
))) {
352 mask
.s_addr
= htonl(0xffffff00);
353 if (ntohl(addr
.s_addr
) < 0xc0000000) {
354 mask
.s_addr
= htonl(0xffff0000);
356 if (ntohl(addr
.s_addr
) < 0x80000000) {
357 mask
.s_addr
= htonl(0xff000000);
359 acl_add_net(allow
,&addr
,&mask
);
364 ((state
== ACLS_ALLOW_NET_DONE
) || (state
== ACLS_DENY_NET_DONE
))) {
366 k
= p
; i
= 0; /* save start of verb */
367 while ((*p
!= '\0') &&
368 (!isspace(*p
= tolower(*p
)))) {
376 if (strcmp(k
,"netmask") == 0) {
377 state
= state
+ ACLD_NET_MASK
;
380 if ((state
== ACLS_ALLOW_NET_DONE
) || (state
== ACLS_DENY_NET_DONE
)) {
381 state
= ACLE_NONETMASK
;
386 /* State 14 & 15: allow/deny net netmask line */
389 ((state
== ACLS_ALLOW_NET_MASK
) || (state
== ACLS_DENY_NET_MASK
))) {
391 k
= p
; i
= 0; /* save start of verb */
392 while ((*p
!= '\0') &&
393 (!isspace(*p
= tolower(*p
)))) {
401 if ((state
== ACLS_ALLOW_NET_MASK
) || (state
== ACLS_DENY_NET_MASK
)) {
402 if ((*k
>= '0') && (*k
<= '9')) {
403 (void)inet_aton(k
,&mask
);
404 state
= state
+ ACLD_NET_EOL
;
406 net
= getnetbyname(k
);
410 mask
.s_addr
= ntohl(net
->n_net
);
411 state
= state
+ ACLD_NET_EOL
;
418 if ((state
== ACLS_ALLOW_NET_MASK
) || (state
== ACLS_DENY_NET_MASK
)) {
422 /* State 16 & 17: allow/deny host line */
425 ((state
== ACLS_ALLOW_NET_EOL
) || (state
== ACLS_DENY_NET_EOL
))) {
426 acl_add_net(allow
,&addr
,&mask
);
432 fprintf(stderr
,"acl: excpected \"netmask\" missing at line %d\n",line_no
);
436 fprintf(stderr
,"acl: unknown network at line %d\n",line_no
);
440 fprintf(stderr
,"acl: unknown host at line %d\n",line_no
);
444 fprintf(stderr
,"acl: unknown verb at line %d\n",line_no
);
448 fprintf(stderr
,"acl: unknown secondary verb at line %d\n",line_no
);
452 fprintf(stderr
,"acl: unexpected end of line at line %d\n",line_no
);
458 fprintf(stderr
,"acl: unexpected state %d %s\n",state
,k
);
463 if (data_file
!= NULL
) {
464 (void)fflush(stderr
);
465 (void)fclose(data_file
);
468 /* Always add a last allow all if file don't exists or */
469 /* the file doesn't cover all cases. */
471 addr
.s_addr
= mask
.s_addr
= 0;
473 acl_add_net(allow
,&addr
,&mask
);
483 char data_line
[1024];
490 struct in_addr addr
,mask
;
492 FILE *data_file
= NULL
;
495 data_file
= fopen(file
,"r");
498 /* Always add a localhost allow first, to be compatable with sun */
500 addr
.s_addr
= htonl(0x7f000001);
501 mask
.s_addr
= htonl(0xffffffff);
503 acl_add_net(allow
,&addr
,&mask
);
505 while ((data_file
!= NULL
) &&
506 (acl_read_line(data_file
,data_line
,sizeof(data_line
)))) {
510 len
= strlen(data_line
);
515 p
= (char *) &data_line
;
517 /* State 1: Initial State */
520 addr
.s_addr
= mask
.s_addr
= 0;
522 k
= p
; i
= 0; /* save start of verb */
523 while ((*p
!= '\0') &&
524 (!isspace(*p
= tolower(*p
)))) {
530 state
= ACLS_ALLOW_NET_MASK
;
533 if (state
== ACLS_INIT
) {
537 if (state
== ACLS_ALLOW_NET_MASK
) {
539 if ((*k
>= '0') && (*k
<= '9')) {
540 (void)inet_aton(k
,&mask
);
541 state
= ACLS_ALLOW_NET
;
543 net
= getnetbyname(k
);
547 mask
.s_addr
= ntohl(net
->n_net
);
548 state
= ACLS_ALLOW_NET
;
552 k
= p
; i
= 0; /* save start of verb */
553 while ((*p
!= '\0') &&
554 (!isspace(*p
= tolower(*p
)))) {
563 if ((state
== ACLS_ALLOW_NET_MASK
)) {
567 if (state
== ACLS_ALLOW_NET
) {
569 if ((*k
>= '0') && (*k
<= '9')) {
570 (void)inet_aton(k
,&addr
);
571 state
= ACLS_ALLOW_NET_EOL
;
573 net
= getnetbyname(k
);
577 addr
.s_addr
= ntohl(net
->n_net
);
578 state
= ACLS_ALLOW_NET_EOL
;
583 if ((state
== ACLS_ALLOW_NET
)) {
587 if ((*p
== '\0') && (state
== ACLS_ALLOW_NET_EOL
)) {
588 acl_add_net(allow
,&addr
,&mask
);
595 fprintf(stderr
,"securenet: unknown network at line %d\n",line_no
);
599 fprintf(stderr
,"securenet: unexpected end of line at line %d\n",line_no
);
605 fprintf(stderr
,"securenet: unexpected state %d %s\n",state
,k
);
610 if (data_file
!= NULL
) {
611 (void)fflush(stderr
);
612 (void)fclose(data_file
);
614 /* Always add a last deny all if file exists */
616 addr
.s_addr
= mask
.s_addr
= 0;
618 acl_add_net(allow
,&addr
,&mask
);
622 /* Always add a last allow all if file don't exists */
624 addr
.s_addr
= mask
.s_addr
= 0;
626 acl_add_net(allow
,&addr
,&mask
);
637 while (acl_root
!= NULL
) {