6
6
Copyright (C) 1997-2005 Luke Howard
7
7
Copyright (C) 2007 West Consulting
8
Copyright (C) 2007, 2008, 2009, 2010 Arthur de Jong
8
Copyright (C) 2007, 2008, 2009, 2010, 2011 Arthur de Jong
10
10
This library is free software; you can redistribute it and/or
11
11
modify it under the terms of the GNU Lesser General Public
158
168
cfg->ldc_uris[i].uri=xstrdup(uri);
161
#ifndef HOST_NAME_MAX
162
#define HOST_NAME_MAX 255
163
#endif /* not HOST_NAME_MAX */
165
171
#ifdef HAVE_LDAP_DOMAIN2HOSTLIST
166
172
/* return the domain name of the current host
167
173
the returned string must be freed by caller */
168
static char *cfg_getdomainname(const char *filename,int lnr)
174
static const char *cfg_getdomainname(const char *filename,int lnr)
170
char hostname[HOST_NAME_MAX+1],*domain;
173
struct hostent *host=NULL;
174
/* get system hostname */
175
if (gethostname(hostname,sizeof(hostname))<0)
177
log_log(LOG_ERR,"%s:%d: gethostname() failed: %s",filename,lnr,strerror(errno));
180
hostnamelen=strlen(hostname);
182
host=gethostbyname(hostname);
185
log_log(LOG_ERR,"%s:%d: gethostbyname(%s): %s",filename,lnr,hostname,hstrerror(h_errno));
188
/* check h_name for fqdn starting with our hostname */
189
if ((strncasecmp(hostname,host->h_name,hostnamelen)==0)&&
190
(host->h_name[hostnamelen]=='.')&&
191
(host->h_name[hostnamelen+1]!='\0'))
192
return strdup(host->h_name+hostnamelen+1);
193
/* also check h_aliases */
194
for (i=0;host->h_aliases[i]!=NULL;i++)
196
if ((strncasecmp(hostname,host->h_aliases[i],hostnamelen)==0)&&
197
(host->h_aliases[i][hostnamelen]=='.')&&
198
(host->h_aliases[i][hostnamelen+1]!='\0'))
199
return strdup(host->h_aliases[i]+hostnamelen+1);
201
/* fall back to any domain part in h_name */
202
if (((domain=strchr(host->h_name,'.'))!=NULL)&&
204
return strdup(domain+1);
205
/* also check h_aliases */
206
for (i=0;host->h_aliases[i]!=NULL;i++)
208
if (((domain=strchr(host->h_aliases[i],'.'))!=NULL)&&
210
return strdup(domain+1);
212
/* we've tried everything now */
213
log_log(LOG_ERR,"%s:%d: unable to determinate a domainname for hostname %s",
214
filename,lnr,hostname);
176
const char *fqdn,*domain;
178
if ((fqdn!=NULL)&&((domain=strchr(fqdn,'.'))!=NULL)&&(domain[1]!='\0'))
180
log_log(LOG_ERR,"%s:%d: unable to determinate a domain name",
215
182
exit(EXIT_FAILURE);
218
185
/* add URIs by doing DNS queries for SRV records */
219
186
static void add_uris_from_dns(const char *filename,int lnr,
220
struct ldap_config *cfg)
187
struct ldap_config *cfg,
224
191
char *hostlist=NULL,*nxt;
225
192
char buf[HOST_NAME_MAX+sizeof("ldap://")];
226
domain=cfg_getdomainname(filename,lnr);
227
ret=ldap_domain2hostlist(domain,&hostlist);
193
log_log(LOG_DEBUG,"query %s for SRV records",domain);
194
rc=ldap_domain2hostlist(domain,&hostlist);
228
195
/* FIXME: have better error handling */
229
196
if ((hostlist==NULL)||(*hostlist=='\0'))
346
/* check that the file is not world readable */
347
static void check_permissions(const char *filename,const char *keyword)
350
/* get file status */
351
if (stat(filename,&sb))
353
log_log(LOG_ERR,"cannot stat() %s: %s",filename,strerror(errno));
356
/* check permissions */
357
if ((sb.st_mode&0007)!=0)
360
log_log(LOG_ERR,"%s: file should not be world readable if %s is set",
363
log_log(LOG_ERR,"%s: file should not be world readable",filename);
380
368
static void get_int(const char *filename,int lnr,
381
369
const char *keyword,char **line,
417
405
check_argumentcount(filename,lnr,keyword,(*line!=NULL)&&(**line!='\0'));
418
if ((*var==NULL)||(strcmp(*var,*line)!=0))
420
/* Note: we have a memory leak here if a single mapping is changed
421
multiple times in one config (deemed not a problem) */
406
/* Note: we have a memory leak here if a single mapping is changed
407
multiple times in one config (deemed not a problem) */
409
/* mark that we are at the end of the line */
445
431
check_argumentcount(filename,lnr,keyword,get_token(line,token,sizeof(token))!=NULL);
446
432
/* check if it is a valid numerical uid */
447
*var=(uid_t)strtol(token,&tmp,0);
448
if ((*token!='\0')&&(*tmp=='\0'))
434
*var=strtouid(token,&tmp,0);
435
if ((*token!='\0')&&(*tmp=='\0')&&(errno==0))
450
437
/* find by name */
451
438
pwent=getpwnam(token);
470
457
check_argumentcount(filename,lnr,keyword,get_token(line,token,sizeof(token))!=NULL);
471
458
/* check if it is a valid numerical gid */
472
*var=(gid_t)strtol(token,&tmp,0);
473
if ((*token!='\0')&&(*tmp=='\0'))
460
*var=strtogid(token,&tmp,0);
461
if ((*token!='\0')&&(*tmp=='\0')&&(errno==0))
475
463
/* find by name */
476
464
grent=getgrnam(token);
588
575
*var=xstrdup(value);
578
/* parse the validnames statement */
579
static void parse_validnames_statement(const char *filename,int lnr,
580
const char *keyword,char *line,struct ldap_config *cfg)
584
int flags=REG_EXTENDED|REG_NOSUB;
585
/* the rest of the line should be a regular expression */
586
get_restdup(filename,lnr,keyword,&line,&value);
587
/* check formatting and update flags */
590
log_log(LOG_ERR,"%s:%d: regular expression incorrectly delimited",filename,lnr);
602
log_log(LOG_ERR,"%s:%d: regular expression incorrectly delimited",filename,lnr);
606
/* compile the regular expression */
607
if ((i=regcomp(&cfg->validnames,value+1,flags))!= 0)
609
/* get the error message */
610
l=regerror(i,&cfg->validnames,NULL,0);
613
log_log(LOG_ERR,"%s:%d: invalid regular expression",filename,lnr);
616
regerror(i,&cfg->validnames,value,l);
617
log_log(LOG_ERR,"%s:%d: invalid regular expression: %s",filename,lnr,
591
624
static void parse_base_statement(const char *filename,int lnr,
592
625
const char *keyword,char *line,
593
626
struct ldap_config *cfg)
760
static void parse_pam_authz_search_statement(
761
const char *filename,int lnr,const char *keyword,
762
char *line,struct ldap_config *cfg)
767
check_argumentcount(filename,lnr,keyword,(line!=NULL)&&(*line!='\0'));
768
cfg->ldc_pam_authz_search=xstrdup(line);
769
/* check the variables used in the expression */
770
set=expr_vars(cfg->ldc_pam_authz_search,NULL);
771
list=set_tolist(set);
772
for (i=0;list[i]!=NULL;i++)
774
if ((strcmp(list[i],"username")!=0)&&
775
(strcmp(list[i],"service")!=0)&&
776
(strcmp(list[i],"ruser")!=0)&&
777
(strcmp(list[i],"rhost")!=0)&&
778
(strcmp(list[i],"tty")!=0)&&
779
(strcmp(list[i],"hostname")!=0)&&
780
(strcmp(list[i],"fqdn")!=0)&&
781
(strcmp(list[i],"dn")!=0)&&
782
(strcmp(list[i],"uid")!=0))
784
log_log(LOG_ERR,"%s:%d: unknown variable $%s",filename,lnr,list[i]);
727
793
static void cfg_read(const char *filename,struct ldap_config *cfg)
790
856
if (strcasecmp(token,"dns")==0)
792
858
#ifdef HAVE_LDAP_DOMAIN2HOSTLIST
793
add_uris_from_dns(filename,lnr,cfg);
859
add_uris_from_dns(filename,lnr,cfg,cfg_getdomainname(filename,lnr));
860
#else /* not HAVE_LDAP_DOMAIN2HOSTLIST */
861
log_log(LOG_ERR,"%s:%d: value %s not supported on platform",filename,lnr,token);
863
#endif /* not HAVE_LDAP_DOMAIN2HOSTLIST */
865
else if (strncasecmp(token,"dns:",4)==0)
867
#ifdef HAVE_LDAP_DOMAIN2HOSTLIST
868
add_uris_from_dns(filename,lnr,cfg,strdup(token+sizeof("dns")));
794
869
#else /* not HAVE_LDAP_DOMAIN2HOSTLIST */
795
870
log_log(LOG_ERR,"%s:%d: value %s not supported on platform",filename,lnr,token);
796
871
exit(EXIT_FAILURE);
812
887
else if (strcasecmp(keyword,"bindpw")==0)
889
check_permissions(filename,keyword);
814
890
get_restdup(filename,lnr,keyword,&line,&cfg->ldc_bindpw);
816
892
else if (strcasecmp(keyword,"rootpwmoddn")==0)
818
894
get_restdup(filename,lnr,keyword,&line,&cfg->ldc_rootpwmoddn);
896
else if (strcasecmp(keyword,"rootpwmodpw")==0)
898
check_permissions(filename,keyword);
899
get_restdup(filename,lnr,keyword,&line,&cfg->ldc_rootpwmodpw);
820
901
/* SASL authentication options */
821
902
else if (strcasecmp(keyword,"use_sasl")==0)
956
1037
LDAP_SET_OPTION(NULL,LDAP_OPT_X_TLS_CACERTDIR,value);
959
else if (strcasecmp(keyword,"tls_cacertfile")==0)
1040
else if ( (strcasecmp(keyword,"tls_cacertfile")==0) ||
1041
(strcasecmp(keyword,"tls_cacert")==0) )
961
1043
get_strdup(filename,lnr,keyword,&line,&value);
962
1044
get_eol(filename,lnr,keyword,&line);
1019
1101
else if (strcasecmp(keyword,"pam_authz_search")==0)
1021
check_argumentcount(filename,lnr,keyword,(line!=NULL)&&(*line!='\0'));
1022
cfg->ldc_pam_authz_search=xstrdup(line);
1103
parse_pam_authz_search_statement(filename,lnr,keyword,line,cfg);
1105
else if (strcasecmp(keyword,"nss_min_uid")==0)
1107
get_uid(filename,lnr,keyword,&line,&cfg->ldc_nss_min_uid);
1108
get_eol(filename,lnr,keyword,&line);
1110
else if (strcasecmp(keyword,"validnames")==0)
1112
parse_validnames_statement(filename,lnr,keyword,line,cfg);
1024
1114
#ifdef ENABLE_CONFIGFILE_CHECKING
1025
1115
/* fallthrough */