2 * -----------------------------------------------------------------------------
4 * Author: Markus Moeller (markus_moeller at compuserve.com)
6 * Copyright (C) 2007 Markus Moeller. All rights reserved.
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.
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.
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.
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.
27 * -----------------------------------------------------------------------------
30 * Hosted at http://sourceforge.net/projects/squidkerbauth
33 #include "helpers/defines.h"
45 init_args(struct main_args
*margs
)
60 margs
->ddomain
= NULL
;
66 void clean_gd(struct gdstruct
*gdsp
);
67 void clean_nd(struct ndstruct
*ndsp
);
68 void clean_ls(struct lsstruct
*lssp
);
71 clean_gd(struct gdstruct
*gdsp
)
73 struct gdstruct
*p
= NULL
, *pp
= NULL
;
92 clean_nd(struct ndstruct
*ndsp
)
94 struct ndstruct
*p
= NULL
, *pp
= NULL
;
102 safe_free(p
->netbios
);
103 safe_free(p
->domain
);
113 clean_ls(struct lsstruct
*lssp
)
115 struct lsstruct
*p
= NULL
, *pp
= NULL
;
123 safe_free(p
->lserver
);
124 safe_free(p
->domain
);
134 clean_args(struct main_args
*margs
)
136 safe_free(margs
->glist
);
137 safe_free(margs
->ulist
);
138 safe_free(margs
->tlist
);
139 safe_free(margs
->nlist
);
140 safe_free(margs
->llist
);
141 safe_free(margs
->luser
);
142 safe_free(margs
->lpass
);
143 safe_free(margs
->lbind
);
144 safe_free(margs
->lurl
);
145 safe_free(margs
->ssl
);
146 safe_free(margs
->ddomain
);
148 clean_gd(margs
->groups
);
149 margs
->groups
= NULL
;
152 clean_nd(margs
->ndoms
);
156 clean_ls(margs
->lservs
);
157 margs
->lservs
= NULL
;
164 main(int argc
, char *const argv
[])
167 char *user
, *domain
, *group
;
168 char *up
=NULL
, *dp
=NULL
, *np
=NULL
;
169 char *nuser
, *nuser8
= NULL
, *netbios
;
172 struct main_args margs
;
174 setbuf(stdout
, NULL
);
179 while (-1 != (opt
= getopt(argc
, argv
, "diasg:D:N:S:u:U:t:T:p:l:b:m:h"))) {
191 margs
.ssl
= (char *) "yes";
194 margs
.glist
= xstrdup(optarg
);
197 margs
.ddomain
= xstrdup(optarg
);
200 margs
.nlist
= xstrdup(optarg
);
203 margs
.luser
= xstrdup(optarg
);
206 margs
.ulist
= xstrdup(optarg
);
209 margs
.ulist
= xstrdup(optarg
);
212 margs
.tlist
= xstrdup(optarg
);
215 margs
.lpass
= xstrdup(optarg
);
217 memset(optarg
, 'X', strlen(optarg
));
220 margs
.lurl
= xstrdup(optarg
);
223 margs
.lbind
= xstrdup(optarg
);
226 margs
.mdepth
= atoi(optarg
);
229 margs
.llist
= xstrdup(optarg
);
232 fprintf(stderr
, "Usage: \n");
233 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");
234 fprintf(stderr
, "-d full debug\n");
235 fprintf(stderr
, "-i informational messages\n");
236 fprintf(stderr
, "-g group list\n");
237 fprintf(stderr
, "-t group list (only group name hex UTF-8 format)\n");
238 fprintf(stderr
, "-T group list (all in hex UTF-8 format - except seperator @)\n");
239 fprintf(stderr
, "-D default domain\n");
240 fprintf(stderr
, "-N netbios to dns domain map\n");
241 fprintf(stderr
, "-S ldap server to dns domain map\n");
242 fprintf(stderr
, "-u ldap user\n");
243 fprintf(stderr
, "-p ldap user password\n");
244 fprintf(stderr
, "-l ldap url\n");
245 fprintf(stderr
, "-b ldap bind path\n");
246 fprintf(stderr
, "-s use SSL encryption with Kerberos authentication\n");
247 fprintf(stderr
, "-a allow SSL without cert verification\n");
248 fprintf(stderr
, "-m maximal depth for recursive searches\n");
249 fprintf(stderr
, "-h help\n");
250 fprintf(stderr
, "The ldap url, ldap user and ldap user password details are only used if the kerberised\n");
251 fprintf(stderr
, "access fails(e.g. unknown domain) or if the username does not contain a domain part\n");
252 fprintf(stderr
, "and no default domain is provided.\n");
253 fprintf(stderr
, "If the ldap url starts with ldaps:// it is either start_tls or simple SSL\n");
254 fprintf(stderr
, "The group list can be:\n");
255 fprintf(stderr
, "group - In this case group can be used for all keberised and non kerberised ldap servers\n");
256 fprintf(stderr
, "group@ - In this case group can be used for all keberised ldap servers\n");
257 fprintf(stderr
, "group@domain - In this case group can be used for ldap servers of domain domain\n");
258 fprintf(stderr
, "group1@domain1:group2@domain2:group3@:group4 - A list is build with a colon as seperator\n");
259 fprintf(stderr
, "Group membership is determined with AD servers through the users memberof attribute which\n");
260 fprintf(stderr
, "is followed to the top (e.g. if the group is a member of a group)\n");
261 fprintf(stderr
, "Group membership is determined with non AD servers through the users memberuid (assuming\n");
262 fprintf(stderr
, "PosixGroup) or primary group membership (assuming PosixAccount)\n");
263 fprintf(stderr
, "The ldap server list can be:\n");
264 fprintf(stderr
, "server - In this case server can be used for all Kerberos domains\n");
265 fprintf(stderr
, "server@ - In this case server can be used for all Kerberos domains\n");
266 fprintf(stderr
, "server@domain - In this case server can be used for Kerberos domain domain\n");
267 fprintf(stderr
, "server1a@domain1:server1b@domain1:server2@domain2:server3@:server4 - A list is build with a colon as seperator\n");
271 warn((char *) "%s| %s: WARNING: unknown option: -%c.\n", LogTime(), PROGRAM
, opt
);
275 debug((char *) "%s| %s: INFO: Starting version %s\n", LogTime(), PROGRAM
, KERBEROS_LDAP_GROUP_VERSION
);
277 if (create_gd(&margs
)) {
278 if ( margs
.glist
!= NULL
) {
279 debug((char *) "%s| %s: FATAL: Error in group list: %s\n", LogTime(), PROGRAM
, margs
.glist
? margs
.glist
: "NULL");
284 debug((char *) "%s| %s: INFO: no group list given expect it from stdin\n", LogTime(), PROGRAM
);
288 if (create_nd(&margs
)) {
289 debug((char *) "%s| %s: FATAL: Error in netbios list: %s\n", LogTime(), PROGRAM
, margs
.nlist
? margs
.nlist
: "NULL");
294 if (create_ls(&margs
)) {
295 debug((char *) "%s| %s: Error in ldap server list: %s\n", LogTime(), PROGRAM
, margs
.llist
? margs
.llist
: "NULL");
301 if (fgets(buf
, sizeof(buf
) - 1, stdin
) == NULL
) {
303 debug((char *) "%s| %s: FATAL: fgets() failed! dying..... errno=%d (%s)\n", LogTime(), PROGRAM
, ferror(stdin
),
304 strerror(ferror(stdin
)));
308 exit(1); /* BIIG buffer */
314 c
= (char *) memchr(buf
, '\n', sizeof(buf
) - 1);
318 SEND_ERR("Invalid input. CR missing");
319 debug((char *) "%s| %s: ERR\n", LogTime(), PROGRAM
);
323 user
= strtok(buf
, " \n");
325 debug((char *) "%s| %s: INFO: No Username given\n", LogTime(), PROGRAM
);
326 SEND_ERR("Invalid request. No Username");
329 rfc1738_unescape(user
);
330 nuser
= strchr(user
, '\\');
332 nuser8
= strstr(user
, "%5C");
333 if (!nuser
&& !nuser8
)
334 nuser8
= strstr(user
, "%5c");
335 domain
= strrchr(user
, '@');
336 if (nuser
|| nuser8
) {
345 up
= xstrdup(rfc1738_escape(nuser
));
346 np
= xstrdup(rfc1738_escape(netbios
));
348 debug((char *) "%s| %s: INFO: Got User: %s Netbios Name: %s\n", LogTime(), PROGRAM
, up
, np
);
350 log((char *) "%s| %s: INFO: Got User: %s Netbios Name: %s\n", LogTime(), PROGRAM
, up
, np
);
351 domain
= get_netbios_name(&margs
, netbios
);
360 up
= xstrdup(rfc1738_escape(user
));
362 dp
= xstrdup(rfc1738_escape(domain
));
363 if (!domain
&& margs
.ddomain
) {
364 domain
= xstrdup(margs
.ddomain
);
365 dp
= xstrdup(rfc1738_escape(domain
));
367 debug((char *) "%s| %s: INFO: Got User: %s set default domain: %s\n", LogTime(), PROGRAM
, up
, dp
);
369 log((char *) "%s| %s: INFO: Got User: %s set default domain: %s\n", LogTime(), PROGRAM
, up
, dp
);
372 debug((char *) "%s| %s: INFO: Got User: %s Domain: %s\n", LogTime(), PROGRAM
, up
, domain
? dp
: "NULL");
374 log((char *) "%s| %s: INFO: Got User: %s Domain: %s\n", LogTime(), PROGRAM
, up
, domain
? dp
: "NULL");
378 if (!strcmp(user
, "QQ") && domain
&& !strcmp(domain
, "QQ")) {
383 if ((group
= strtok(NULL
, " \n")) != NULL
) {
384 debug((char *) "%s| %s: INFO: Read group list %s from stdin\n", LogTime(), PROGRAM
, group
);
385 rfc1738_unescape(group
);
387 clean_gd(margs
.groups
);
390 margs
.glist
= xstrdup(group
);
391 if (create_gd(&margs
)) {
392 SEND_ERR("Error in group list");
393 debug((char *) "%s| %s: FATAL: Error in group list: %s\n", LogTime(), PROGRAM
, margs
.glist
? margs
.glist
: "NULL");
397 SEND_ERR("No group list received on stdin");
398 debug((char *) "%s| %s: FATAL: No group list received on stdin\n", LogTime(), PROGRAM
);
402 if (check_memberof(&margs
, user
, domain
)) {
404 debug((char *) "%s| %s: DEBUG: OK\n", LogTime(), PROGRAM
);
407 debug((char *) "%s| %s: DEBUG: ERR\n", LogTime(), PROGRAM
);
417 *s
= (char)toupper((unsigned char) *s
);
426 main(int argc
, char *const argv
[])
428 setbuf(stdout
, NULL
);
432 if (fgets(buf
, sizeof(buf
) - 1, stdin
) == NULL
) {
434 fprintf(stdout
, "ERR\n");
435 fprintf(stderr
, "LDAP group authorisation not supported\n");