]> git.ipfire.org Git - thirdparty/sarg.git/blob - usertab.c
Merge commit 'f209e4f043007b3bb6'
[thirdparty/sarg.git] / usertab.c
1 /*
2 * SARG Squid Analysis Report Generator http://sarg.sourceforge.net
3 * 1998, 2010
4 *
5 * SARG donations:
6 * please look at http://sarg.sourceforge.net/donations.php
7 * Support:
8 * http://sourceforge.net/projects/sarg/forums/forum/363374
9 * ---------------------------------------------------------------------
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
24 *
25 */
26
27 #include "include/conf.h"
28 #include "include/defs.h"
29
30 #ifdef HAVE_LDAP_H
31 #define LDAP_DEPRECATED 1
32
33 #include <ldap.h>
34 #include <ldap_cdefs.h>
35 #include <ldap_features.h>
36 #endif //HAVE_LDAP_H
37
38 enum UserTabEnum
39 {
40 //! Users matched against the ::UserTabFile file.
41 UTT_File,
42 //! Users matched agains a LDAP.
43 UTT_Ldap,
44 //! No user matching performed.
45 UTT_None
46 };
47
48 enum UserTabEnum which_usertab=UTT_None;
49
50 static char *userfile=NULL;
51
52 #ifdef HAVE_LDAP_H
53 static LDAP *ldap_handle=NULL;
54 #endif //HAVE_LDAP_H
55
56 static void init_file_usertab(const char *UserTabFile)
57 {
58 FILE *fp_usr;
59 long int nreg;
60 char buf[MAXLEN];
61 int z1, z2;
62
63 if((fp_usr=fopen(UserTabFile,"r"))==NULL) {
64 debuga(_("(usertab) Cannot open file %s - %s\n"),UserTabFile,strerror(errno));
65 exit(EXIT_FAILURE);
66 }
67 if (fseek(fp_usr, 0, SEEK_END)==-1) {
68 debuga(_("Failed to move till the end of the usertab file %s: %s\n"),UserTabFile,strerror(errno));
69 exit(EXIT_FAILURE);
70 }
71 nreg = ftell(fp_usr);
72 if (nreg<0) {
73 debuga(_("Cannot get the size of file %s"),UserTabFile);
74 exit(EXIT_FAILURE);
75 }
76 nreg += 100;
77 if (fseek(fp_usr, 0, SEEK_SET)==-1) {
78 debuga(_("Failed to rewind the usertab file %s: %s\n"),UserTabFile,strerror(errno));
79 exit(EXIT_FAILURE);
80 }
81 if((userfile=(char *) malloc(nreg))==NULL){
82 debuga(_("ERROR: Cannot load. Memory fault"));
83 exit(EXIT_FAILURE);
84 }
85 userfile[0]='\t';
86 z2=1;
87 while(fgets(buf,sizeof(buf),fp_usr)!=NULL) {
88 if (buf[0]=='#') continue;
89 fixendofline(buf);
90 z1=0;
91 while(buf[z1] && (unsigned char)buf[z1]>' ') {
92 if (z2+3>=nreg) { //need at least 3 additional bytes for the minimum string "\n\t\0"
93 debuga(_("The list of the users is too long in your %s file.\n"),UserTabFile);
94 exit(EXIT_FAILURE);
95 }
96 userfile[z2++]=buf[z1++];
97 }
98 while(buf[z1] && (unsigned char)buf[z1]<=' ') z1++;
99 userfile[z2++]='\n';
100 while(buf[z1] && (unsigned char)buf[z1]>=' ') {
101 if (z2+2>=nreg) { //need at least 2 additional bytes for "\t\0"
102 debuga(_("The list of the users is too long in your %s file.\n"),UserTabFile);
103 exit(EXIT_FAILURE);
104 }
105 userfile[z2++]=buf[z1++];
106 }
107 while(userfile[z2-1]==' ') z2--;
108 userfile[z2++]='\t';
109 }
110 userfile[z2]='\0';
111 fclose(fp_usr);
112 }
113
114 static void get_usertab_name(const char *user,char *name,int namelen)
115 {
116 char warea[MAXLEN];
117 char *str;
118
119 namelen--;
120 sprintf(warea,"\t%s\n",user);
121 if((str=(char *) strstr(userfile,warea)) == (char *) NULL ) {
122 strncpy(name,user,namelen);
123 name[namelen]=0;
124 } else {
125 str=strchr(str+1,'\n');
126 str++;
127 for(z1=0; *str != '\t' && z1<namelen ; z1++) {
128 name[z1]=*str++;
129 }
130 name[z1]=0;
131 }
132 }
133
134 #ifdef HAVE_LDAP_H
135 static void init_ldap_usertab(void) {
136 /* Setting LDAP connection and initializing cache */
137 ldap_handle = NULL;
138 if ((ldap_handle = ldap_init(LDAPHost, LDAPPort)) == NULL) {
139 debuga(_("Unable to connect to LDAP server %s on port %d\n"), LDAPHost, LDAPPort);
140 exit(EXIT_FAILURE);
141 }
142
143 int ldap_protocol_version = LDAPProtocolVersion;
144 if (ldap_set_option(ldap_handle, LDAP_OPT_PROTOCOL_VERSION, &ldap_protocol_version) != LDAP_SUCCESS) {
145 debuga(_("Could not set LDAP protocol version %d\n"), ldap_protocol_version);
146 exit(EXIT_FAILURE);
147 }
148
149 /* Bind to the LDAP server. */
150 int rc;
151 rc = ldap_simple_bind_s( ldap_handle, LDAPBindDN, LDAPBindPW );
152 if ( rc != LDAP_SUCCESS ) {
153 debuga(_("Cannot bind to LDAP server: %s\n"), ldap_err2string(rc));
154 exit(EXIT_FAILURE);
155 }
156
157 /* Initializing cache */
158
159 init_cache();
160 }
161
162 static void get_ldap_name(const char *userlogin,char *mappedname,int namelen)
163 {
164 /* Start searching username in cache */
165 // According to rfc2254 section 4, only *()\ and NUL must be escaped. This list is rather conservative !
166 const char strictchars[] = " ~!@^&(){}|<>?:;\"\'\\[]`,\r\n\0";
167 char filtersearch[256], *searched_in_cache;
168 char searchloginname[3*MAX_USER_LEN];
169 char *attr, **vals;
170 LDAPMessage *result, *e;
171 BerElement *ber;
172 int i;
173
174 for (i=0 ; i<sizeof(searchloginname)-1 && *userlogin ; userlogin++) {
175 if (strchr(strictchars,*userlogin)) {
176 // escape character according to rfc2254 section 4
177 if (i+3>=sizeof(searchloginname)-1) break;
178 i+=sprintf(searchloginname+i,"\\%02X",*userlogin);
179 } else {
180 searchloginname[i++]=*userlogin;
181 }
182 }
183 searchloginname[i]='\0';
184
185 if (!(searched_in_cache = search_in_cache(searchloginname))) {
186 snprintf(filtersearch, sizeof(filtersearch), LDAPFilterSearch, searchloginname, searchloginname, searchloginname, searchloginname, searchloginname);
187
188 /* Search record(s) in LDAP base */
189
190 int rc= ldap_search_s(ldap_handle, LDAPBaseSearch, LDAP_SCOPE_SUBTREE, filtersearch, NULL, 0, &result);
191 if ( rc != LDAP_SUCCESS ) {
192 debuga(_("LDAP search failed: %s\n"), ldap_err2string(rc));
193 strncpy(mappedname,searchloginname,namelen-1);
194 mappedname[namelen-1]='\0';
195 return;
196 }
197
198 if (!(e = ldap_first_entry(ldap_handle, result)))
199 insert_to_cache(searchloginname, searchloginname);
200 else
201 for (attr = ldap_first_attribute(ldap_handle, e, &ber); attr != NULL; attr = ldap_next_attribute(ldap_handle, e, ber)) {
202 if (!strcasecmp(attr, LDAPTargetAttr)) {
203 if ((vals = (char **)ldap_get_values(ldap_handle, e, attr))!=NULL) {
204 insert_to_cache(searchloginname, vals[0]);
205 strncpy(mappedname, vals[0],namelen-1);
206 mappedname[namelen-1]='\0';
207 ldap_memfree(vals);
208 }
209 ldap_memfree(attr);
210 break;
211 }
212 ldap_memfree(attr);
213 }
214 ldap_msgfree(result);
215 } else {
216 strncpy(mappedname, searched_in_cache,namelen-1);
217 mappedname[namelen-1]='\0';
218 }
219 }
220 #endif //HAVE_LDAP_H
221
222 void init_usertab(const char *UserTabFile)
223 {
224 if (strcmp(UserTabFile, "ldap") == 0) {
225 if(debug)
226 debuga(_("Loading User table: %s\n"),UserTabFile);
227 #ifdef HAVE_LDAP_H
228 which_usertab=UTT_Ldap;
229 init_ldap_usertab();
230 #else
231 debuga(_("LDAP module not compiled in sarg\n"));
232 exit(EXIT_FAILURE);
233 #endif //HAVE_LDAP_H
234 } else if (UserTabFile[0] != '\0') {
235 if(debug)
236 debuga(_("Loading User table: %s\n"),UserTabFile);
237 which_usertab=UTT_File;
238 init_file_usertab(UserTabFile);
239 } else {
240 which_usertab=UTT_None;
241 }
242 }
243
244 void user_find(char *mappedname, int namelen, const char *userlogin)
245 {
246 if (which_usertab==UTT_File) {
247 get_usertab_name(userlogin,mappedname,namelen);
248 }
249 #ifdef HAVE_LDAP_H
250 else if (which_usertab==UTT_Ldap) {
251 get_ldap_name(userlogin,mappedname,namelen);
252 }
253 #endif //HAVE_LDAP_H
254 else {
255 strncpy(mappedname,userlogin,namelen-1);
256 mappedname[namelen-1]='\0';
257 }
258 }
259
260 void close_usertab(void)
261 {
262 #ifdef HAVE_LDAP_H
263 if (ldap_handle) {
264 destroy_cache();
265 ldap_unbind(ldap_handle);
266 ldap_handle=NULL;
267 }
268 #endif //HAVE_LDAP_H
269 if(userfile) {
270 free(userfile);
271 userfile=NULL;
272 }
273 }
274