]> git.ipfire.org Git - thirdparty/squid.git/blob - helpers/external_acl/kerberos_ldap_group/kerberos_ldap_group.cc
Renamed squid.h to squid-old.h and config.h to squid.h
[thirdparty/squid.git] / helpers / external_acl / kerberos_ldap_group / kerberos_ldap_group.cc
1 /*
2 * -----------------------------------------------------------------------------
3 *
4 * Author: Markus Moeller (markus_moeller at compuserve.com)
5 *
6 * Copyright (C) 2007 Markus Moeller. All rights reserved.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
21 *
22 * As a special exemption, M Moeller gives permission to link this program
23 * with MIT, Heimdal or other GSS/Kerberos libraries, and distribute
24 * the resulting executable, without including the source code for
25 * the Libraries in the source distribution.
26 *
27 * -----------------------------------------------------------------------------
28 */
29 /*
30 * Hosted at http://sourceforge.net/projects/squidkerbauth
31 */
32 #include "squid.h"
33 #include "helpers/defines.h"
34 #include "util.h"
35
36 #ifdef HAVE_LDAP
37
38 #include "support.h"
39 #ifdef HAVE_CTYPE_H
40 #include <ctype.h>
41 #endif
42
43 void
44 init_args(struct main_args *margs)
45 {
46 margs->nlist = NULL;
47 margs->glist = NULL;
48 margs->llist = NULL;
49 margs->ulist = NULL;
50 margs->tlist = NULL;
51 margs->luser = NULL;
52 margs->lpass = NULL;
53 margs->lbind = NULL;
54 margs->lurl = NULL;
55 margs->ssl = NULL;
56 margs->rc_allow = 0;
57 margs->AD = 0;
58 margs->mdepth = 5;
59 margs->ddomain = NULL;
60 margs->groups = NULL;
61 margs->ndoms = NULL;
62 margs->lservs = NULL;
63 }
64
65 void clean_gd(struct gdstruct *gdsp);
66 void clean_nd(struct ndstruct *ndsp);
67 void clean_ls(struct ndstruct *lssp);
68
69 void
70 clean_gd(struct gdstruct *gdsp)
71 {
72 struct gdstruct *p = NULL, *pp = NULL;
73
74 p = gdsp;
75 while (p) {
76 while (p->next) {
77 pp = p;
78 p = p->next;
79 }
80 if (p->group) {
81 xfree(p->group);
82 p->group = NULL;
83 }
84 if (p->domain) {
85 xfree(p->domain);
86 p->domain = NULL;
87 }
88 if (pp && pp->next) {
89 xfree(pp->next);
90 pp->next = NULL;
91 }
92 if (p == gdsp) {
93 xfree(gdsp);
94 gdsp = NULL;
95 }
96 p = gdsp;
97 }
98 }
99
100 void
101 clean_nd(struct ndstruct *ndsp)
102 {
103 struct ndstruct *p = NULL, *pp = NULL;
104
105 p = ndsp;
106 while (p) {
107 while (p->next) {
108 pp = p;
109 p = p->next;
110 }
111 if (p->netbios) {
112 xfree(p->netbios);
113 p->netbios = NULL;
114 }
115 if (p->domain) {
116 xfree(p->domain);
117 p->domain = NULL;
118 }
119 if (pp && pp->next) {
120 xfree(pp->next);
121 pp->next = NULL;
122 }
123 if (p == ndsp) {
124 xfree(ndsp);
125 ndsp = NULL;
126 }
127 p = ndsp;
128 }
129 }
130
131 void
132 clean_ls(struct lsstruct *lssp)
133 {
134 struct lsstruct *p = NULL, *pp = NULL;
135
136 p = lssp;
137 while (p) {
138 while (p->next) {
139 pp = p;
140 p = p->next;
141 }
142 if (p->lserver) {
143 xfree(p->lserver);
144 p->lserver = NULL;
145 }
146 if (p->domain) {
147 xfree(p->domain);
148 p->domain = NULL;
149 }
150 if (pp && pp->next) {
151 xfree(pp->next);
152 pp->next = NULL;
153 }
154 if (p == lssp) {
155 xfree(lssp);
156 lssp = NULL;
157 }
158 p = lssp;
159 }
160 }
161
162 void
163 clean_args(struct main_args *margs)
164 {
165 if (margs->glist) {
166 xfree(margs->glist);
167 margs->glist = NULL;
168 }
169 if (margs->ulist) {
170 xfree(margs->ulist);
171 margs->ulist = NULL;
172 }
173 if (margs->tlist) {
174 xfree(margs->tlist);
175 margs->tlist = NULL;
176 }
177 if (margs->nlist) {
178 xfree(margs->nlist);
179 margs->nlist = NULL;
180 }
181 if (margs->llist) {
182 xfree(margs->llist);
183 margs->llist = NULL;
184 }
185 if (margs->luser) {
186 xfree(margs->luser);
187 margs->luser = NULL;
188 }
189 if (margs->lpass) {
190 xfree(margs->lpass);
191 margs->lpass = NULL;
192 }
193 if (margs->lbind) {
194 xfree(margs->lbind);
195 margs->lbind = NULL;
196 }
197 if (margs->lurl) {
198 xfree(margs->lurl);
199 margs->lurl = NULL;
200 }
201 if (margs->ssl) {
202 xfree(margs->ssl);
203 margs->ssl = NULL;
204 }
205 if (margs->ddomain) {
206 xfree(margs->ddomain);
207 margs->ddomain = NULL;
208 }
209 if (margs->groups) {
210 clean_gd(margs->groups);
211 margs->groups = NULL;
212 }
213 if (margs->ndoms) {
214 clean_nd(margs->ndoms);
215 margs->ndoms = NULL;
216 }
217 if (margs->lservs) {
218 clean_ls(margs->lservs);
219 margs->lservs = NULL;
220 }
221 }
222
223 void strup(char *s);
224
225 int
226 main(int argc, char *const argv[])
227 {
228 char buf[6400];
229 char *user, *domain;
230 char *nuser, *nuser8 = NULL, *netbios;
231 char *c;
232 int opt;
233 struct main_args margs;
234
235 setbuf(stdout, NULL);
236 setbuf(stdin, NULL);
237
238 init_args(&margs);
239
240 while (-1 != (opt = getopt(argc, argv, "diasg:D:N:S:u:U:t:T:p:l:b:m:h"))) {
241 switch (opt) {
242 case 'd':
243 debug_enabled = 1;
244 break;
245 case 'i':
246 log_enabled = 1;
247 break;
248 case 'a':
249 margs.rc_allow = 1;
250 break;
251 case 's':
252 margs.ssl = (char *) "yes";
253 break;
254 case 'g':
255 margs.glist = xstrdup(optarg);
256 break;
257 case 'D':
258 margs.ddomain = xstrdup(optarg);
259 break;
260 case 'N':
261 margs.nlist = xstrdup(optarg);
262 break;
263 case 'u':
264 margs.luser = xstrdup(optarg);
265 break;
266 case 'U':
267 margs.ulist = xstrdup(optarg);
268 break;
269 case 't':
270 margs.ulist = xstrdup(optarg);
271 break;
272 case 'T':
273 margs.tlist = xstrdup(optarg);
274 break;
275 case 'p':
276 margs.lpass = xstrdup(optarg);
277 /* Hide Password */
278 memset(optarg, 'X', strlen(optarg));
279 break;
280 case 'l':
281 margs.lurl = xstrdup(optarg);
282 break;
283 case 'b':
284 margs.lbind = xstrdup(optarg);
285 break;
286 case 'm':
287 margs.mdepth = atoi(optarg);
288 break;
289 case 'S':
290 margs.llist = xstrdup(optarg);
291 break;
292 case 'h':
293 fprintf(stderr, "Usage: \n");
294 fprintf(stderr, "squid_kerb_ldap [-d] [-i] -g group list [-D domain] [-N netbios domain map] [-s] [-u ldap user] [-p ldap user password] [-l ldap url] [-b ldap bind path] [-a] [-m max depth] [-h]\n");
295 fprintf(stderr, "-d full debug\n");
296 fprintf(stderr, "-i informational messages\n");
297 fprintf(stderr, "-g group list\n");
298 fprintf(stderr, "-t group list (only group name hex UTF-8 format)\n");
299 fprintf(stderr, "-T group list (all in hex UTF-8 format - except seperator @)\n");
300 fprintf(stderr, "-D default domain\n");
301 fprintf(stderr, "-N netbios to dns domain map\n");
302 fprintf(stderr, "-S ldap server to dns domain map\n");
303 fprintf(stderr, "-u ldap user\n");
304 fprintf(stderr, "-p ldap user password\n");
305 fprintf(stderr, "-l ldap url\n");
306 fprintf(stderr, "-b ldap bind path\n");
307 fprintf(stderr, "-s use SSL encryption with Kerberos authentication\n");
308 fprintf(stderr, "-a allow SSL without cert verification\n");
309 fprintf(stderr, "-m maximal depth for recursive searches\n");
310 fprintf(stderr, "-h help\n");
311 fprintf(stderr, "The ldap url, ldap user and ldap user password details are only used if the kerberised\n");
312 fprintf(stderr, "access fails(e.g. unknown domain) or if the username does not contain a domain part\n");
313 fprintf(stderr, "and no default domain is provided.\n");
314 fprintf(stderr, "If the ldap url starts with ldaps:// it is either start_tls or simple SSL\n");
315 fprintf(stderr, "The group list can be:\n");
316 fprintf(stderr, "group - In this case group can be used for all keberised and non kerberised ldap servers\n");
317 fprintf(stderr, "group@ - In this case group can be used for all keberised ldap servers\n");
318 fprintf(stderr, "group@domain - In this case group can be used for ldap servers of domain domain\n");
319 fprintf(stderr, "group1@domain1:group2@domain2:group3@:group4 - A list is build with a colon as seperator\n");
320 fprintf(stderr, "Group membership is determined with AD servers through the users memberof attribute which\n");
321 fprintf(stderr, "is followed to the top (e.g. if the group is a member of a group)\n");
322 fprintf(stderr, "Group membership is determined with non AD servers through the users memberuid (assuming\n");
323 fprintf(stderr, "PosixGroup) or primary group membership (assuming PosixAccount)\n");
324 fprintf(stderr, "The ldap server list can be:\n");
325 fprintf(stderr, "server - In this case server can be used for all Kerberos domains\n");
326 fprintf(stderr, "server@ - In this case server can be used for all Kerberos domains\n");
327 fprintf(stderr, "server@domain - In this case server can be used for Kerberos domain domain\n");
328 fprintf(stderr, "server1a@domain1:server1b@domain1:server2@domain2:server3@:server4 - A list is build with a colon as seperator\n");
329 clean_args(&margs);
330 exit(0);
331 default:
332 warn((char *) "%s| %s: WARNING: unknown option: -%c.\n", LogTime(), PROGRAM, opt);
333 }
334 }
335
336 debug((char *) "%s| %s: INFO: Starting version %s\n", LogTime(), PROGRAM, KERBEROS_LDAP_GROUP_VERSION);
337 if (create_gd(&margs)) {
338 debug((char *) "%s| %s: FATAL: Error in group list: %s\n", LogTime(), PROGRAM, margs.glist ? margs.glist : "NULL");
339 SEND_ERR("");
340 clean_args(&margs);
341 exit(1);
342 }
343 if (create_nd(&margs)) {
344 debug((char *) "%s| %s: FATAL: Error in netbios list: %s\n", LogTime(), PROGRAM, margs.nlist ? margs.nlist : "NULL");
345 SEND_ERR("");
346 clean_args(&margs);
347 exit(1);
348 }
349 if (create_ls(&margs)) {
350 debug((char *) "%s| %s: Error in ldap server list: %s\n", LogTime(), PROGRAM, margs.llist ? margs.llist : "NULL");
351 SEND_ERR("");
352 clean_args(&margs);
353 exit(1);
354 }
355 while (1) {
356 if (fgets(buf, sizeof(buf) - 1, stdin) == NULL) {
357 if (ferror(stdin)) {
358 debug((char *) "%s| %s: FATAL: fgets() failed! dying..... errno=%d (%s)\n", LogTime(), PROGRAM, ferror(stdin),
359 strerror(ferror(stdin)));
360
361 SEND_ERR("");
362 clean_args(&margs);
363 exit(1); /* BIIG buffer */
364 }
365 SEND_ERR("");
366 clean_args(&margs);
367 exit(0);
368 }
369 c = (char *) memchr(buf, '\n', sizeof(buf) - 1);
370 if (c) {
371 *c = '\0';
372 } else {
373 SEND_ERR("");
374 debug((char *) "%s| %s: ERR\n", LogTime(), PROGRAM);
375 continue;
376 }
377
378 user = buf;
379 nuser = strchr(user, '\\');
380 if (!nuser)
381 nuser8 = strstr(user, "%5C");
382 if (!nuser && !nuser8)
383 nuser8 = strstr(user, "%5c");
384 domain = strrchr(user, '@');
385 if (nuser || nuser8) {
386 if (nuser) {
387 *nuser = '\0';
388 nuser++;
389 } else {
390 *nuser8 = '\0';
391 nuser = nuser8 + 3;
392 }
393 netbios = user;
394 if (debug_enabled)
395 debug((char *) "%s| %s: INFO: Got User: %s Netbios Name: %s\n", LogTime(), PROGRAM, nuser, netbios);
396 else
397 log((char *) "%s| %s: INFO: Got User: %s Netbios Name: %s\n", LogTime(), PROGRAM, nuser, netbios);
398 domain = get_netbios_name(&margs, netbios);
399 user = nuser;
400 } else if (domain) {
401 strup(domain);
402 *domain = '\0';
403 domain++;
404 }
405 if (!domain && margs.ddomain) {
406 domain = xstrdup(margs.ddomain);
407 if (debug_enabled)
408 debug((char *) "%s| %s: INFO: Got User: %s set default domain: %s\n", LogTime(), PROGRAM, user, domain);
409 else
410 log((char *) "%s| %s: INFO: Got User: %s set default domain: %s\n", LogTime(), PROGRAM, user, domain);
411 }
412 if (debug_enabled)
413 debug((char *) "%s| %s: INFO: Got User: %s Domain: %s\n", LogTime(), PROGRAM, user, domain ? domain : "NULL");
414 else
415 log((char *) "%s| %s: INFO: Got User: %s Domain: %s\n", LogTime(), PROGRAM, user, domain ? domain : "NULL");
416
417 if (!strcmp(user, "QQ") && domain && !strcmp(domain, "QQ")) {
418 clean_args(&margs);
419 exit(-1);
420 }
421 if (check_memberof(&margs, user, domain)) {
422 SEND_OK("");
423 debug((char *) "%s| %s: DEBUG: OK\n", LogTime(), PROGRAM);
424 } else {
425 SEND_ERR("");
426 debug((char *) "%s| %s: DEBUG: ERR\n", LogTime(), PROGRAM);
427 }
428 }
429
430
431 }
432
433 void
434 strup(char *s)
435 {
436 while (*s) {
437 *s = toupper((unsigned char) *s);
438 s++;
439 }
440 }
441
442 #else
443 #include <stdio.h>
444 #include <stdlib.h>
445 int
446 main(int argc, char *const argv[])
447 {
448 setbuf(stdout, NULL);
449 setbuf(stdin, NULL);
450 char buf[6400];
451 while (1) {
452 if (fgets(buf, sizeof(buf) - 1, stdin) == NULL) {
453 }
454 fprintf(stdout, "ERR\n");
455 fprintf(stderr, "LDAP group authorisation not supported\n");
456 }
457 }
458 #endif