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