]> git.ipfire.org Git - thirdparty/squid.git/blob - helpers/external_acl/ip_user/dict.c
SourceFormat: enforcement
[thirdparty/squid.git] / helpers / external_acl / ip_user / dict.c
1 /* $Id$
2 * Copyright (C) 2002 Rodrigo Campos
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 *
18 * Author: Rodrigo Campos (rodrigo@geekbunker.org)
19 *
20 */
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <sys/types.h>
26 #include <sys/socket.h>
27 #include <netinet/in.h>
28 #include <arpa/inet.h>
29
30 #include "ip_user.h"
31
32 #ifndef DEBUG
33 #undef DEBUG
34 #endif
35
36
37 /* This function parses the dictionary file and loads it
38 * in memory. All IP addresses are processed with a bitwise AND
39 * with their netmasks before they are stored.
40 * If there´s no netmask (no /) in the in the lhs , a mask
41 * 255.255.255.255 is assumed.
42 * It returns a pointer to the first entry of the linked list
43 */
44 struct ip_user_dict *
45 load_dict (FILE * FH) {
46 struct ip_user_dict *current_entry; /* the structure used to
47 store data */
48 struct ip_user_dict *first_entry = NULL; /* the head of the
49 linked list */
50 char line[BUFSIZE]; /* the buffer for the lines read
51 from the dict file */
52 char *cp; /* a char pointer used to parse
53 each line */
54 char *username; /* for the username */
55 char *tmpbuf; /* for the address before the
56 bitwise AND */
57
58 /* the pointer to the first entry in the linked list */
59 first_entry = malloc (sizeof (struct ip_user_dict));
60 current_entry = first_entry;
61
62 while ((cp = fgets (line, sizeof (line), FH)) != NULL) {
63 if (line[0] == '#') {
64 continue;
65 }
66 if ((cp = strchr (line, '\n')) != NULL) {
67 /* chop \n characters */
68 *cp = '\0';
69 }
70 if ((cp = strtok (line, "\t ")) != NULL) {
71 /* get the username */
72 username = strtok (NULL, "\t ");
73 /* look for a netmask */
74 if ((cp = strtok (line, "/")) != NULL) {
75 /* store the ip address in a temporary buffer */
76 tmpbuf = cp;
77 cp = strtok (NULL, "/");
78 if (cp != NULL) {
79 /* if we have a slash in the lhs, we have a netmask */
80 current_entry->netmask = (inet_addr (cp));
81 current_entry->address =
82 (((inet_addr (tmpbuf))) & current_entry->netmask);
83 } else {
84 /* when theres no slash, we figure the netmask is /32 */
85 current_entry->address = (inet_addr (tmpbuf));
86 current_entry->netmask = (inet_addr ("255.255.255.255"));
87 }
88 }
89 /* get space for the username */
90 current_entry->username =
91 calloc (strlen (username) + 1, sizeof (char));
92 strcpy (current_entry->username, username);
93
94 /* get space and point current_entry to the new entry */
95 current_entry->next_entry =
96 malloc (sizeof (struct ip_user_dict));
97 current_entry = current_entry->next_entry;
98 }
99
100 }
101
102 /* Return a pointer to the first entry linked list */
103 return first_entry;
104 } /* load_dict */
105
106 /* This function looks for a matching ip/mask in
107 * the dict file loaded in memory.
108 * It returns 1 if it finds a match or 0 if no match is found
109 */
110 int
111 dict_lookup (struct ip_user_dict *first_entry, char *username,
112 char *address)
113 {
114 /* Move the pointer to the first entry of the linked list. */
115 struct ip_user_dict *current_entry = first_entry;
116
117 while (current_entry->username != NULL) {
118 #ifdef DEBUG
119 printf ("user: %s\naddr: %lu\nmask: %lu\n\n",
120 current_entry->username, current_entry->address,
121 current_entry->netmask);
122 #endif
123
124 if ((inet_addr (address) & (unsigned long) current_entry->
125 netmask) == current_entry->address) {
126 /* If the username contains an @ we assume it´s a group and
127 call the corresponding function */
128 if ((strchr (current_entry->username, '@')) == NULL) {
129 if ((match_user (current_entry->username, username)) == 1)
130 return 1;
131 } else {
132 if ((match_group (current_entry->username, username)) == 1)
133 return 1;
134 }
135 }
136 current_entry = current_entry->next_entry;
137 }
138
139 /* If no match was found we return 0 */
140 return 0;
141 } /* dict_lookup */