|
Line 0
Link Here
|
|
|
1 |
/* $OpenBSD: ldapconf.c,v 1.1 2009/12/03 03:34:42 jfch Exp $ */ |
| 2 |
/* |
| 3 |
* Copyright (c) 2009 Jan F. Chadima. All rights reserved. |
| 4 |
* |
| 5 |
* Redistribution and use in source and binary forms, with or without |
| 6 |
* modification, are permitted provided that the following conditions |
| 7 |
* are met: |
| 8 |
* 1. Redistributions of source code must retain the above copyright |
| 9 |
* notice, this list of conditions and the following disclaimer. |
| 10 |
* 2. Redistributions in binary form must reproduce the above copyright |
| 11 |
* notice, this list of conditions and the following disclaimer in the |
| 12 |
* documentation and/or other materials provided with the distribution. |
| 13 |
* |
| 14 |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
| 15 |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
| 16 |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
| 17 |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
| 18 |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
| 19 |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 20 |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 21 |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 22 |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
| 23 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 24 |
*/ |
| 25 |
|
| 26 |
#include "ldapincludes.h" |
| 27 |
#include "ldap-helper.h" |
| 28 |
#include "log.h" |
| 29 |
#include "misc.h" |
| 30 |
#include "xmalloc.h" |
| 31 |
#include "ldapconf.h" |
| 32 |
#include <unistd.h> |
| 33 |
#include <string.h> |
| 34 |
|
| 35 |
/* Keyword tokens. */ |
| 36 |
|
| 37 |
typedef enum { |
| 38 |
lBadOption, |
| 39 |
lHost, lURI, lBase, lBindDN, lBindPW, lRootBindDN, |
| 40 |
lScope, lDeref, lPort, lTimeLimit, lBind_TimeLimit, |
| 41 |
lLdap_Version, lBind_Policy, lSSLPath, lSSL, lReferrals, |
| 42 |
lRestart, lTLS_CheckPeer, lTLS_CaCertFile, |
| 43 |
lTLS_CaCertDir, lTLS_Ciphers, lTLS_Cert, lTLS_Key, |
| 44 |
lTLS_RandFile, lLogDir, lDebug, lSSH_Filter, |
| 45 |
lDeprecated, lUnsupported |
| 46 |
} OpCodes; |
| 47 |
|
| 48 |
/* Textual representations of the tokens. */ |
| 49 |
|
| 50 |
static struct { |
| 51 |
const char *name; |
| 52 |
OpCodes opcode; |
| 53 |
} keywords[] = { |
| 54 |
{ "URI", lURI }, |
| 55 |
{ "Base", lBase }, |
| 56 |
{ "BindDN", lBindDN }, |
| 57 |
{ "BindPW", lBindPW }, |
| 58 |
{ "RootBindDN", lRootBindDN }, |
| 59 |
{ "Host", lHost }, |
| 60 |
{ "Port", lPort }, |
| 61 |
{ "Scope", lScope }, |
| 62 |
{ "Deref", lDeref }, |
| 63 |
{ "TimeLimit", lTimeLimit }, |
| 64 |
{ "TimeOut", lTimeLimit }, |
| 65 |
{ "Bind_Timelimit", lBind_TimeLimit }, |
| 66 |
{ "Network_TimeOut", lBind_TimeLimit }, |
| 67 |
/* |
| 68 |
* Todo |
| 69 |
* SIZELIMIT |
| 70 |
*/ |
| 71 |
{ "Ldap_Version", lLdap_Version }, |
| 72 |
{ "Version", lLdap_Version }, |
| 73 |
{ "Bind_Policy", lBind_Policy }, |
| 74 |
{ "SSLPath", lSSLPath }, |
| 75 |
{ "SSL", lSSL }, |
| 76 |
{ "Referrals", lReferrals }, |
| 77 |
{ "Restart", lRestart }, |
| 78 |
{ "TLS_CheckPeer", lTLS_CheckPeer }, |
| 79 |
{ "TLS_ReqCert", lTLS_CheckPeer }, |
| 80 |
{ "TLS_CaCertFile", lTLS_CaCertFile }, |
| 81 |
{ "TLS_CaCert", lTLS_CaCertFile }, |
| 82 |
{ "TLS_CaCertDir", lTLS_CaCertDir }, |
| 83 |
{ "TLS_Ciphers", lTLS_Ciphers }, |
| 84 |
{ "TLS_Cipher_Suite", lTLS_Ciphers }, |
| 85 |
{ "TLS_Cert", lTLS_Cert }, |
| 86 |
{ "TLS_Certificate", lTLS_Cert }, |
| 87 |
{ "TLS_Key", lTLS_Key }, |
| 88 |
{ "TLS_RandFile", lTLS_RandFile }, |
| 89 |
/* |
| 90 |
* Todo |
| 91 |
* TLS_CRLCHECK |
| 92 |
* TLS_CRLFILE |
| 93 |
*/ |
| 94 |
{ "LogDir", lLogDir }, |
| 95 |
{ "Debug", lDebug }, |
| 96 |
{ "SSH_Filter", lSSH_Filter }, |
| 97 |
{ NULL, lBadOption } |
| 98 |
}; |
| 99 |
|
| 100 |
/* Configuration ptions. */ |
| 101 |
|
| 102 |
Options options; |
| 103 |
|
| 104 |
/* |
| 105 |
* Returns the number of the token pointed to by cp or oBadOption. |
| 106 |
*/ |
| 107 |
|
| 108 |
static OpCodes |
| 109 |
parse_token(const char *cp, const char *filename, int linenum) |
| 110 |
{ |
| 111 |
u_int i; |
| 112 |
|
| 113 |
for (i = 0; keywords[i].name; i++) |
| 114 |
if (strcasecmp(cp, keywords[i].name) == 0) |
| 115 |
return keywords[i].opcode; |
| 116 |
|
| 117 |
if (config_warning_config_file) |
| 118 |
logit("%s: line %d: Bad configuration option: %s", |
| 119 |
filename, linenum, cp); |
| 120 |
return lBadOption; |
| 121 |
} |
| 122 |
|
| 123 |
/* |
| 124 |
* Processes a single option line as used in the configuration files. This |
| 125 |
* only sets those values that have not already been set. |
| 126 |
*/ |
| 127 |
#define WHITESPACE " \t\r\n" |
| 128 |
|
| 129 |
static int |
| 130 |
process_config_line(char *line, const char *filename, int linenum) |
| 131 |
{ |
| 132 |
char *s, **charptr, **xstringptr, *endofnumber, *keyword, *arg; |
| 133 |
char *rootbinddn = NULL; |
| 134 |
int opcode, *intptr, value; |
| 135 |
size_t len; |
| 136 |
|
| 137 |
/* Strip trailing whitespace */ |
| 138 |
for (len = strlen(line) - 1; len > 0; len--) { |
| 139 |
if (strchr(WHITESPACE, line[len]) == NULL) |
| 140 |
break; |
| 141 |
line[len] = '\0'; |
| 142 |
} |
| 143 |
|
| 144 |
s = line; |
| 145 |
/* Get the keyword. (Each line is supposed to begin with a keyword). */ |
| 146 |
if ((keyword = strdelim(&s)) == NULL) |
| 147 |
return 0; |
| 148 |
/* Ignore leading whitespace. */ |
| 149 |
if (*keyword == '\0') |
| 150 |
keyword = strdelim(&s); |
| 151 |
if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#') |
| 152 |
return 0; |
| 153 |
|
| 154 |
opcode = parse_token(keyword, filename, linenum); |
| 155 |
|
| 156 |
switch (opcode) { |
| 157 |
case lBadOption: |
| 158 |
/* don't panic, but count bad options */ |
| 159 |
return -1; |
| 160 |
/* NOTREACHED */ |
| 161 |
|
| 162 |
case lHost: |
| 163 |
xstringptr = &options.host; |
| 164 |
parse_xstring: |
| 165 |
if (!s || *s == '\0') |
| 166 |
fatal("%s line %d: missing dn",filename,linenum); |
| 167 |
if (*xstringptr == NULL) |
| 168 |
*xstringptr = xstrdup(s); |
| 169 |
return 0; |
| 170 |
|
| 171 |
case lURI: |
| 172 |
xstringptr = &options.uri; |
| 173 |
goto parse_xstring; |
| 174 |
|
| 175 |
case lBase: |
| 176 |
xstringptr = &options.base; |
| 177 |
goto parse_xstring; |
| 178 |
|
| 179 |
case lBindDN: |
| 180 |
xstringptr = &options.binddn; |
| 181 |
goto parse_xstring; |
| 182 |
|
| 183 |
case lBindPW: |
| 184 |
charptr = &options.bindpw; |
| 185 |
parse_string: |
| 186 |
arg = strdelim(&s); |
| 187 |
if (!arg || *arg == '\0') |
| 188 |
fatal("%.200s line %d: Missing argument.", filename, linenum); |
| 189 |
if (*charptr == NULL) |
| 190 |
*charptr = xstrdup(arg); |
| 191 |
break; |
| 192 |
|
| 193 |
case lRootBindDN: |
| 194 |
xstringptr = &rootbinddn; |
| 195 |
goto parse_xstring; |
| 196 |
|
| 197 |
case lScope: |
| 198 |
intptr = &options.scope; |
| 199 |
arg = strdelim(&s); |
| 200 |
if (!arg || *arg == '\0') |
| 201 |
fatal("%.200s line %d: Missing sub/one/base argument.", filename, linenum); |
| 202 |
value = 0; /* To avoid compiler warning... */ |
| 203 |
if (strcasecmp (arg, "sub") == 0 || strcasecmp (arg, "subtree") == 0) |
| 204 |
value = LDAP_SCOPE_SUBTREE; |
| 205 |
else if (strcasecmp (arg, "one") == 0) |
| 206 |
value = LDAP_SCOPE_ONELEVEL; |
| 207 |
else if (strcasecmp (arg, "base") == 0) |
| 208 |
value = LDAP_SCOPE_BASE; |
| 209 |
else |
| 210 |
fatal("%.200s line %d: Bad sub/one/base argument.", filename, linenum); |
| 211 |
if (*intptr == -1) |
| 212 |
*intptr = value; |
| 213 |
break; |
| 214 |
|
| 215 |
case lDeref: |
| 216 |
intptr = &options.scope; |
| 217 |
arg = strdelim(&s); |
| 218 |
if (!arg || *arg == '\0') |
| 219 |
fatal("%.200s line %d: Missing never/searching/finding/always argument.", filename, linenum); |
| 220 |
value = 0; /* To avoid compiler warning... */ |
| 221 |
if (!strcasecmp (arg, "never")) |
| 222 |
value = LDAP_DEREF_NEVER; |
| 223 |
else if (!strcasecmp (arg, "searching")) |
| 224 |
value = LDAP_DEREF_SEARCHING; |
| 225 |
else if (!strcasecmp (arg, "finding")) |
| 226 |
value = LDAP_DEREF_FINDING; |
| 227 |
else if (!strcasecmp (arg, "always")) |
| 228 |
value = LDAP_DEREF_ALWAYS; |
| 229 |
else |
| 230 |
fatal("%.200s line %d: Bad never/searching/finding/always argument.", filename, linenum); |
| 231 |
if (*intptr == -1) |
| 232 |
*intptr = value; |
| 233 |
break; |
| 234 |
|
| 235 |
case lPort: |
| 236 |
intptr = &options.port; |
| 237 |
parse_int: |
| 238 |
arg = strdelim(&s); |
| 239 |
if (!arg || *arg == '\0') |
| 240 |
fatal("%.200s line %d: Missing argument.", filename, linenum); |
| 241 |
if (arg[0] < '0' || arg[0] > '9') |
| 242 |
fatal("%.200s line %d: Bad number.", filename, linenum); |
| 243 |
|
| 244 |
/* Octal, decimal, or hex format? */ |
| 245 |
value = strtol(arg, &endofnumber, 0); |
| 246 |
if (arg == endofnumber) |
| 247 |
fatal("%.200s line %d: Bad number.", filename, linenum); |
| 248 |
if (*intptr == -1) |
| 249 |
*intptr = value; |
| 250 |
break; |
| 251 |
|
| 252 |
case lTimeLimit: |
| 253 |
intptr = &options.timelimit; |
| 254 |
parse_time: |
| 255 |
arg = strdelim(&s); |
| 256 |
if (!arg || *arg == '\0') |
| 257 |
fatal("%s line %d: missing time value.", |
| 258 |
filename, linenum); |
| 259 |
if ((value = convtime(arg)) == -1) |
| 260 |
fatal("%s line %d: invalid time value.", |
| 261 |
filename, linenum); |
| 262 |
if (*intptr == -1) |
| 263 |
*intptr = value; |
| 264 |
break; |
| 265 |
|
| 266 |
case lBind_TimeLimit: |
| 267 |
intptr = &options.bind_timelimit; |
| 268 |
goto parse_time; |
| 269 |
|
| 270 |
case lLdap_Version: |
| 271 |
intptr = &options.ldap_version; |
| 272 |
goto parse_int; |
| 273 |
|
| 274 |
case lBind_Policy: |
| 275 |
intptr = &options.bind_policy; |
| 276 |
arg = strdelim(&s); |
| 277 |
if (!arg || *arg == '\0') |
| 278 |
fatal("%.200s line %d: Missing soft/hard argument.", filename, linenum); |
| 279 |
value = 0; /* To avoid compiler warning... */ |
| 280 |
if (strcasecmp(arg, "hard") == 0 || strcasecmp(arg, "hard_open") == 0 || strcasecmp(arg, "hard_init") == 0) |
| 281 |
value = 1; |
| 282 |
else if (strcasecmp(arg, "soft") == 0) |
| 283 |
value = 0; |
| 284 |
else |
| 285 |
fatal("%.200s line %d: Bad soft/hard argument.", filename, linenum); |
| 286 |
if (*intptr == -1) |
| 287 |
break; |
| 288 |
|
| 289 |
case lSSLPath: |
| 290 |
charptr = &options.sslpath; |
| 291 |
goto parse_string; |
| 292 |
|
| 293 |
case lSSL: |
| 294 |
intptr = &options.ssl; |
| 295 |
arg = strdelim(&s); |
| 296 |
if (!arg || *arg == '\0') |
| 297 |
fatal("%.200s line %d: Missing yes/no/start_tls argument.", filename, linenum); |
| 298 |
value = 0; /* To avoid compiler warning... */ |
| 299 |
if (strcasecmp(arg, "yes") == 0 || strcasecmp(arg, "true") == 0 || strcasecmp(arg, "on") == 0) |
| 300 |
value = SSL_LDAPS; |
| 301 |
else if (strcasecmp(arg, "no") == 0 || strcasecmp(arg, "false") == 0 || strcasecmp(arg, "off") == 0) |
| 302 |
value = SSL_OFF; |
| 303 |
else if (!strcasecmp (arg, "start_tls")) |
| 304 |
value = SSL_START_TLS; |
| 305 |
else |
| 306 |
fatal("%.200s line %d: Bad yes/no/start_tls argument.", filename, linenum); |
| 307 |
if (*intptr == -1) |
| 308 |
*intptr = value; |
| 309 |
break; |
| 310 |
|
| 311 |
case lReferrals: |
| 312 |
intptr = &options.referrals; |
| 313 |
parse_flag: |
| 314 |
arg = strdelim(&s); |
| 315 |
if (!arg || *arg == '\0') |
| 316 |
fatal("%.200s line %d: Missing yes/no argument.", filename, linenum); |
| 317 |
value = 0; /* To avoid compiler warning... */ |
| 318 |
if (strcasecmp(arg, "yes") == 0 || strcasecmp(arg, "true") == 0 || strcasecmp(arg, "on") == 0) |
| 319 |
value = 1; |
| 320 |
else if (strcasecmp(arg, "no") == 0 || strcasecmp(arg, "false") == 0 || strcasecmp(arg, "off") == 0) |
| 321 |
value = 0; |
| 322 |
else |
| 323 |
fatal("%.200s line %d: Bad yes/no argument.", filename, linenum); |
| 324 |
if (*intptr == -1) |
| 325 |
*intptr = value; |
| 326 |
break; |
| 327 |
|
| 328 |
case lRestart: |
| 329 |
intptr = &options.restart; |
| 330 |
goto parse_flag; |
| 331 |
|
| 332 |
case lTLS_CheckPeer: |
| 333 |
intptr = &options.tls_checkpeer; |
| 334 |
arg = strdelim(&s); |
| 335 |
if (!arg || *arg == '\0') |
| 336 |
fatal("%.200s line %d: Missing never/hard/demand/alow/try argument.", filename, linenum); |
| 337 |
value = 0; /* To avoid compiler warning... */ |
| 338 |
if (strcasecmp(arg, "never") == 0 || strcasecmp(arg, "no") == 0 || strcasecmp(arg, "false") == 0 || strcasecmp(arg, "off") == 0) |
| 339 |
value = LDAP_OPT_X_TLS_NEVER; |
| 340 |
else if (strcasecmp(arg, "hard") == 0 || strcasecmp(arg, "yes") == 0 || strcasecmp(arg, "true") == 0 || strcasecmp(arg, "on") == 0) |
| 341 |
value = LDAP_OPT_X_TLS_HARD; |
| 342 |
else if (strcasecmp(arg, "demand") == 0) |
| 343 |
value = LDAP_OPT_X_TLS_DEMAND; |
| 344 |
else if (strcasecmp(arg, "allow") == 0) |
| 345 |
value = LDAP_OPT_X_TLS_ALLOW; |
| 346 |
else if (strcasecmp(arg, "try") == 0) |
| 347 |
value = LDAP_OPT_X_TLS_TRY; |
| 348 |
else |
| 349 |
fatal("%.200s line %d: Bad never/hard/demand/alow/try argument.", filename, linenum); |
| 350 |
if (*intptr == -1) |
| 351 |
break; |
| 352 |
|
| 353 |
case lTLS_CaCertFile: |
| 354 |
charptr = &options.tls_cacertfile; |
| 355 |
goto parse_string; |
| 356 |
|
| 357 |
case lTLS_CaCertDir: |
| 358 |
charptr = &options.tls_cacertdir; |
| 359 |
goto parse_string; |
| 360 |
|
| 361 |
case lTLS_Ciphers: |
| 362 |
xstringptr = &options.tls_ciphers; |
| 363 |
goto parse_xstring; |
| 364 |
|
| 365 |
case lTLS_Cert: |
| 366 |
charptr = &options.tls_cert; |
| 367 |
goto parse_string; |
| 368 |
|
| 369 |
case lTLS_Key: |
| 370 |
charptr = &options.tls_key; |
| 371 |
goto parse_string; |
| 372 |
|
| 373 |
case lTLS_RandFile: |
| 374 |
charptr = &options.tls_randfile; |
| 375 |
goto parse_string; |
| 376 |
|
| 377 |
case lLogDir: |
| 378 |
charptr = &options.logdir; |
| 379 |
goto parse_string; |
| 380 |
|
| 381 |
case lDebug: |
| 382 |
intptr = &options.debug; |
| 383 |
goto parse_int; |
| 384 |
|
| 385 |
case lSSH_Filter: |
| 386 |
xstringptr = &options.ssh_filter; |
| 387 |
goto parse_xstring; |
| 388 |
|
| 389 |
case lDeprecated: |
| 390 |
debug("%s line %d: Deprecated option \"%s\"", |
| 391 |
filename, linenum, keyword); |
| 392 |
return 0; |
| 393 |
|
| 394 |
case lUnsupported: |
| 395 |
error("%s line %d: Unsupported option \"%s\"", |
| 396 |
filename, linenum, keyword); |
| 397 |
return 0; |
| 398 |
|
| 399 |
default: |
| 400 |
fatal("process_config_line: Unimplemented opcode %d", opcode); |
| 401 |
} |
| 402 |
|
| 403 |
/* Check that there is no garbage at end of line. */ |
| 404 |
if ((arg = strdelim(&s)) != NULL && *arg != '\0') { |
| 405 |
fatal("%.200s line %d: garbage at end of line; \"%.200s\".", |
| 406 |
filename, linenum, arg); |
| 407 |
} |
| 408 |
return 0; |
| 409 |
} |
| 410 |
|
| 411 |
/* |
| 412 |
* Reads the config file and modifies the options accordingly. Options |
| 413 |
* should already be initialized before this call. This never returns if |
| 414 |
* there is an error. If the file does not exist, this returns 0. |
| 415 |
*/ |
| 416 |
|
| 417 |
void |
| 418 |
read_config_file(const char *filename) |
| 419 |
{ |
| 420 |
FILE *f; |
| 421 |
char line[1024]; |
| 422 |
int active, linenum; |
| 423 |
int bad_options = 0; |
| 424 |
struct stat sb; |
| 425 |
|
| 426 |
if ((f = fopen(filename, "r")) == NULL) |
| 427 |
fatal("fopen %s: %s", filename, strerror(errno)); |
| 428 |
|
| 429 |
if (fstat(fileno(f), &sb) == -1) |
| 430 |
fatal("fstat %s: %s", filename, strerror(errno)); |
| 431 |
if (((sb.st_uid != 0 && sb.st_uid != getuid()) || |
| 432 |
(sb.st_mode & 022) != 0)) |
| 433 |
fatal("Bad owner or permissions on %s", filename); |
| 434 |
|
| 435 |
debug("Reading configuration data %.200s", filename); |
| 436 |
|
| 437 |
/* |
| 438 |
* Mark that we are now processing the options. This flag is turned |
| 439 |
* on/off by Host specifications. |
| 440 |
*/ |
| 441 |
active = 1; |
| 442 |
linenum = 0; |
| 443 |
while (fgets(line, sizeof(line), f)) { |
| 444 |
/* Update line number counter. */ |
| 445 |
linenum++; |
| 446 |
if (process_config_line(line, filename, linenum) != 0) |
| 447 |
bad_options++; |
| 448 |
} |
| 449 |
fclose(f); |
| 450 |
if ((bad_options > 0) && config_exclusive_config_file) |
| 451 |
fatal("%s: terminating, %d bad configuration options", |
| 452 |
filename, bad_options); |
| 453 |
} |
| 454 |
|
| 455 |
/* |
| 456 |
* Initializes options to special values that indicate that they have not yet |
| 457 |
* been set. Read_config_file will only set options with this value. Options |
| 458 |
* are processed in the following order: command line, user config file, |
| 459 |
* system config file. Last, fill_default_options is called. |
| 460 |
*/ |
| 461 |
|
| 462 |
void |
| 463 |
initialize_options(void) |
| 464 |
{ |
| 465 |
memset(&options, 'X', sizeof(options)); |
| 466 |
options.host = NULL; |
| 467 |
options.uri = NULL; |
| 468 |
options.base = NULL; |
| 469 |
options.binddn = NULL; |
| 470 |
options.bindpw = NULL; |
| 471 |
options.scope = -1; |
| 472 |
options.deref = -1; |
| 473 |
options.port = -1; |
| 474 |
options.timelimit = -1; |
| 475 |
options.bind_timelimit = -1; |
| 476 |
options.ldap_version = -1; |
| 477 |
options.bind_policy = -1; |
| 478 |
options.sslpath = NULL; |
| 479 |
options.ssl = -1; |
| 480 |
options.referrals = -1; |
| 481 |
options.restart = -1; |
| 482 |
options.tls_checkpeer = -1; |
| 483 |
options.tls_cacertfile = NULL; |
| 484 |
options.tls_cacertdir = NULL; |
| 485 |
options.tls_ciphers = NULL; |
| 486 |
options.tls_cert = NULL; |
| 487 |
options.tls_key = NULL; |
| 488 |
options.tls_randfile = NULL; |
| 489 |
options.logdir = NULL; |
| 490 |
options.debug = -1; |
| 491 |
options.ssh_filter = NULL; |
| 492 |
} |
| 493 |
|
| 494 |
/* |
| 495 |
* Called after processing other sources of option data, this fills those |
| 496 |
* options for which no value has been specified with their default values. |
| 497 |
*/ |
| 498 |
|
| 499 |
void |
| 500 |
fill_default_options(void) |
| 501 |
{ |
| 502 |
if (options.uri != NULL) { |
| 503 |
LDAPURLDesc *ludp; |
| 504 |
|
| 505 |
if (ldap_url_parse(options.uri, &ludp) == LDAP_SUCCESS) { |
| 506 |
if (options.ssl == -1) { |
| 507 |
if (strcmp (ludp->lud_scheme, "ldap") == 0) |
| 508 |
options.ssl = 2; |
| 509 |
if (strcmp (ludp->lud_scheme, "ldapi") == 0) |
| 510 |
options.ssl = 0; |
| 511 |
else if (strcmp (ludp->lud_scheme, "ldaps") == 0) |
| 512 |
options.ssl = 1; |
| 513 |
} |
| 514 |
if (options.host == NULL) |
| 515 |
options.host = xstrdup (ludp->lud_host); |
| 516 |
if (options.port == -1) |
| 517 |
options.port = ludp->lud_port; |
| 518 |
|
| 519 |
ldap_free_urldesc (ludp); |
| 520 |
} |
| 521 |
} |
| 522 |
if (options.ssl == -1) |
| 523 |
options.ssl = SSL_START_TLS; |
| 524 |
if (options.port == -1) |
| 525 |
options.port = (options.ssl == 0) ? 389 : 636; |
| 526 |
if (options.uri == NULL) { |
| 527 |
int len; |
| 528 |
#define MAXURILEN 4096 |
| 529 |
|
| 530 |
options.uri = xmalloc (MAXURILEN); |
| 531 |
len = snprintf (options.uri, MAXURILEN, "ldap%s://%s:%d", |
| 532 |
(options.ssl == 0) ? "" : "s", options.host, options.port); |
| 533 |
options.uri[MAXURILEN - 1] = 0; |
| 534 |
options.uri = xrealloc (options.uri, len + 1, 1); |
| 535 |
} |
| 536 |
if (options.binddn == NULL) |
| 537 |
options.binddn = ""; |
| 538 |
if (options.bindpw == NULL) |
| 539 |
options.bindpw = ""; |
| 540 |
if (options.scope == -1) |
| 541 |
options.scope = LDAP_SCOPE_SUBTREE; |
| 542 |
if (options.deref == -1) |
| 543 |
options.deref = LDAP_DEREF_NEVER; |
| 544 |
if (options.timelimit == -1) |
| 545 |
options.timelimit = 10; |
| 546 |
if (options.bind_timelimit == -1) |
| 547 |
options.bind_timelimit = 10; |
| 548 |
if (options.ldap_version == -1) |
| 549 |
options.ldap_version = 3; |
| 550 |
if (options.bind_policy == -1) |
| 551 |
options.bind_policy = 1; |
| 552 |
if (options.referrals == -1) |
| 553 |
options.referrals = 1; |
| 554 |
if (options.restart == -1) |
| 555 |
options.restart = 1; |
| 556 |
if (options.tls_checkpeer == -1) |
| 557 |
options.tls_checkpeer = LDAP_OPT_X_TLS_HARD; |
| 558 |
if (options.debug == -1) |
| 559 |
options.debug = 0; |
| 560 |
if (options.ssh_filter == NULL) |
| 561 |
options.ssh_filter = ""; |
| 562 |
} |
| 563 |
|
| 564 |
static const char * |
| 565 |
lookup_opcode_name(OpCodes code) |
| 566 |
{ |
| 567 |
u_int i; |
| 568 |
|
| 569 |
for (i = 0; keywords[i].name != NULL; i++) |
| 570 |
if (keywords[i].opcode == code) |
| 571 |
return(keywords[i].name); |
| 572 |
return "UNKNOWN"; |
| 573 |
} |
| 574 |
|
| 575 |
static void |
| 576 |
dump_cfg_string(OpCodes code, const char *val) |
| 577 |
{ |
| 578 |
if (val == NULL) |
| 579 |
debug3("%s <UNDEFINED>", lookup_opcode_name(code)); |
| 580 |
else |
| 581 |
debug3("%s %s", lookup_opcode_name(code), val); |
| 582 |
} |
| 583 |
|
| 584 |
static void |
| 585 |
dump_cfg_int(OpCodes code, int val) |
| 586 |
{ |
| 587 |
if (val == -1) |
| 588 |
debug3("%s <UNDEFINED>", lookup_opcode_name(code)); |
| 589 |
else |
| 590 |
debug3("%s %d", lookup_opcode_name(code), val); |
| 591 |
} |
| 592 |
|
| 593 |
struct names { |
| 594 |
int value; |
| 595 |
char *name; |
| 596 |
}; |
| 597 |
|
| 598 |
static void |
| 599 |
dump_cfg_namedint(OpCodes code, int val, struct names *names) |
| 600 |
{ |
| 601 |
u_int i; |
| 602 |
|
| 603 |
if (val == -1) |
| 604 |
debug3("%s <UNDEFINED>", lookup_opcode_name(code)); |
| 605 |
else { |
| 606 |
for (i = 0; names[i].value != -1; i++) |
| 607 |
if (names[i].value == val) { |
| 608 |
debug3("%s %s", lookup_opcode_name(code), names[i].name); |
| 609 |
return; |
| 610 |
} |
| 611 |
debug3("%s unknown: %d", lookup_opcode_name(code), val); |
| 612 |
} |
| 613 |
} |
| 614 |
|
| 615 |
static struct names _yesnotls[] = { |
| 616 |
{ 0, "No" }, |
| 617 |
{ 1, "Yes" }, |
| 618 |
{ 2, "Start_TLS" }, |
| 619 |
{ -1, NULL }}; |
| 620 |
|
| 621 |
static struct names _scope[] = { |
| 622 |
{ LDAP_SCOPE_BASE, "Base" }, |
| 623 |
{ LDAP_SCOPE_ONELEVEL, "One" }, |
| 624 |
{ LDAP_SCOPE_SUBTREE, "Sub"}, |
| 625 |
{ -1, NULL }}; |
| 626 |
|
| 627 |
static struct names _deref[] = { |
| 628 |
{ LDAP_DEREF_NEVER, "Never" }, |
| 629 |
{ LDAP_DEREF_SEARCHING, "Searching" }, |
| 630 |
{ LDAP_DEREF_FINDING, "Finding" }, |
| 631 |
{ LDAP_DEREF_ALWAYS, "Always" }, |
| 632 |
{ -1, NULL }}; |
| 633 |
|
| 634 |
static struct names _yesno[] = { |
| 635 |
{ 0, "No" }, |
| 636 |
{ 1, "Yes" }, |
| 637 |
{ -1, NULL }}; |
| 638 |
|
| 639 |
static struct names _bindpolicy[] = { |
| 640 |
{ 0, "Soft" }, |
| 641 |
{ 1, "Hard" }, |
| 642 |
{ -1, NULL }}; |
| 643 |
|
| 644 |
static struct names _checkpeer[] = { |
| 645 |
{ LDAP_OPT_X_TLS_NEVER, "Never" }, |
| 646 |
{ LDAP_OPT_X_TLS_HARD, "Hard" }, |
| 647 |
{ LDAP_OPT_X_TLS_DEMAND, "Demand" }, |
| 648 |
{ LDAP_OPT_X_TLS_ALLOW, "Allow" }, |
| 649 |
{ LDAP_OPT_X_TLS_TRY, "TRY" }, |
| 650 |
{ -1, NULL }}; |
| 651 |
|
| 652 |
void |
| 653 |
dump_config(void) |
| 654 |
{ |
| 655 |
dump_cfg_string(lURI, options.uri); |
| 656 |
dump_cfg_string(lHost, options.host); |
| 657 |
dump_cfg_int(lPort, options.port); |
| 658 |
dump_cfg_namedint(lSSL, options.ssl, _yesnotls); |
| 659 |
dump_cfg_int(lLdap_Version, options.ldap_version); |
| 660 |
dump_cfg_int(lTimeLimit, options.timelimit); |
| 661 |
dump_cfg_int(lBind_TimeLimit, options.bind_timelimit); |
| 662 |
dump_cfg_string(lBase, options.base); |
| 663 |
dump_cfg_string(lBindDN, options.binddn); |
| 664 |
dump_cfg_string(lBindPW, options.bindpw); |
| 665 |
dump_cfg_namedint(lScope, options.scope, _scope); |
| 666 |
dump_cfg_namedint(lDeref, options.deref, _deref); |
| 667 |
dump_cfg_namedint(lReferrals, options.referrals, _yesno); |
| 668 |
dump_cfg_namedint(lRestart, options.restart, _yesno); |
| 669 |
dump_cfg_namedint(lBind_Policy, options.bind_policy, _bindpolicy); |
| 670 |
dump_cfg_string(lSSLPath, options.sslpath); |
| 671 |
dump_cfg_namedint(lTLS_CheckPeer, options.tls_checkpeer, _checkpeer); |
| 672 |
dump_cfg_string(lTLS_CaCertFile, options.tls_cacertfile); |
| 673 |
dump_cfg_string(lTLS_CaCertDir, options.tls_cacertdir); |
| 674 |
dump_cfg_string(lTLS_Ciphers, options.tls_ciphers); |
| 675 |
dump_cfg_string(lTLS_Cert, options.tls_cert); |
| 676 |
dump_cfg_string(lTLS_Key, options.tls_key); |
| 677 |
dump_cfg_string(lTLS_RandFile, options.tls_randfile); |
| 678 |
dump_cfg_string(lLogDir, options.logdir); |
| 679 |
dump_cfg_int(lDebug, options.debug); |
| 680 |
dump_cfg_string(lSSH_Filter, options.ssh_filter); |
| 681 |
} |
| 682 |
|