summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArthur de Jong <arthur@arthurdejong.org>2007-12-26 17:58:05 +0000
committerArthur de Jong <arthur@arthurdejong.org>2007-12-26 17:58:05 +0000
commit7fea0fe5b96322fecca698c47367cc596ff8b537 (patch)
treef13faa6a3a00d4fb84f7b5cb1fdeb9ab193b7578
parentc13343c4a11b88e289866085244fb26d8d40edf0 (diff)
properly handle spaces in some configuration options (major change in code in cfg module)
git-svn-id: http://arthurdejong.org/svn/nss-pam-ldapd/nss-ldapd@534 ef36b2f9-881f-0410-afb5-c4e39611909c
-rw-r--r--nslcd/cfg.c543
-rw-r--r--nslcd/cfg.h2
-rw-r--r--tests/test_cfg.c109
3 files changed, 366 insertions, 288 deletions
diff --git a/nslcd/cfg.c b/nslcd/cfg.c
index 7f99b1b..4fb9bc3 100644
--- a/nslcd/cfg.c
+++ b/nslcd/cfg.c
@@ -28,6 +28,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <ctype.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>
@@ -53,10 +54,10 @@ struct ldap_config *nslcd_cfg=NULL;
/* the maximum line length in the configuration file */
#define MAX_LINE_LENGTH 4096
-/* the maximum number of keywords/options on the line */
-#define MAX_LINE_OPTIONS 10
+/* the delimiters of tokens */
+#define TOKEN_DELIM " \t\n\r"
-/* clear the configuration information back to the defaults */
+/* set the configuration information to the defaults */
static void cfg_defaults(struct ldap_config *cfg)
{
int i;
@@ -238,7 +239,39 @@ static int parse_scope(const char *filename,int lnr,const char *value)
}
}
-static enum ldap_map_selector parse_map(const char *filename,int lnr,const char *value)
+/* This function works like strtok() except that the original string is
+ not modified and a pointer within str to where the next token begins
+ is returned (this can be used to pass to the function on the next
+ iteration). If no more tokens are found or the token will not fit in
+ the buffer, NULL is returned. */
+static char *get_token(char **line,char *buf,size_t buflen)
+{
+ size_t len;
+ if ((line==NULL)||(*line==NULL)||(**line=='\0')||(buf==NULL))
+ return NULL;
+ /* find the beginning and length of the token */
+ *line+=strspn(*line,TOKEN_DELIM);
+ len=strcspn(*line,TOKEN_DELIM);
+ /* check if there is a token */
+ if (len==0)
+ {
+ *line=NULL;
+ return NULL;
+ }
+ /* limit the token length */
+ if (len>=buflen)
+ len=buflen-1;
+ /* copy the token */
+ strncpy(buf,*line,len);
+ buf[len]='\0';
+ /* skip to the next token */
+ *line+=len;
+ *line+=strspn(*line,TOKEN_DELIM);
+ /* return the token */
+ return buf;
+}
+
+static enum ldap_map_selector parse_map(const char *value)
{
if ( (strcasecmp(value,"alias")==0) || (strcasecmp(value,"aliases")==0) )
return LM_ALIASES;
@@ -263,10 +296,25 @@ static enum ldap_map_selector parse_map(const char *filename,int lnr,const char
else if (strcasecmp(value,"shadow")==0)
return LM_SHADOW;
else
- {
- log_log(LOG_ERR,"%s:%d: unknown mapping: '%s'",filename,lnr,value);
- exit(EXIT_FAILURE);
- }
+ return LM_NONE;
+}
+
+/* check to see if the line begins with a named map */
+static enum ldap_map_selector get_map(char **line)
+{
+ char token[32];
+ char *old;
+ enum ldap_map_selector map;
+ /* get the token */
+ old=*line;
+ if (get_token(line,token,sizeof(token))==NULL)
+ return LM_NONE;
+ /* find the map if any */
+ map=parse_map(token);
+ /* unknown map, return to the previous state */
+ if (map==LM_NONE)
+ *line=old;
+ return map;
}
/* check that the condition is true and otherwise log an error
@@ -282,17 +330,19 @@ static inline void check_argumentcount(const char *filename,int lnr,
}
static void parse_krb5_ccname_statement(const char *filename,int lnr,
- const char **opts,int nopts)
+ const char *keyword,char *line)
{
+ char token[80];
const char *ccname;
const char *ccfile;
size_t ccenvlen;
char *ccenv;
OM_uint32 minor_status;
+ /* get token */
+ check_argumentcount(filename,lnr,keyword,
+ (get_token(&line,token,sizeof(token))!=NULL)&&(*line=='\0'));
/* set default kerberos ticket cache for SASL-GSSAPI */
- log_log(LOG_WARNING,"%s:%d: option %s is currently untested (please report any successes)",filename,lnr,opts[0]);
- check_argumentcount(filename,lnr,opts[0],nopts==2);
- ccname=opts[1];
+ ccname=token;
/* check that cache exists and is readable if it is a file */
if ( (strncasecmp(ccname,"FILE:",sizeof("FILE:")-1)==0) ||
(strncasecmp(ccname,"WRFILE:",sizeof("WRFILE:")-1)==0))
@@ -348,170 +398,163 @@ static void set_base(const char *filename,int lnr,
}
static void parse_base_statement(const char *filename,int lnr,
- const char **opts,int nopts,
+ const char *keyword,char *line,
struct ldap_config *cfg)
{
- enum ldap_map_selector map;
const char **var;
- if (nopts==2)
- set_base(filename,lnr,opts[1],(const char **)&(cfg->ldc_base));
- else if (nopts==3)
- {
- /* get the map */
- map=parse_map(filename,lnr,opts[1]);
- /* get the base variable to set */
- var=base_get_var(map);
- if (var==NULL)
- {
- log_log(LOG_ERR,"%s:%d: unknown map: '%s'",filename,lnr,opts[1]);
- exit(EXIT_FAILURE);
- }
- set_base(filename,lnr,opts[2],var);
- }
- else
- check_argumentcount(filename,lnr,opts[0],0);
+ var=base_get_var(get_map(&line));
+ if (var==NULL)
+ var=(const char **)&(cfg->ldc_base);
+ check_argumentcount(filename,lnr,keyword,(line!=NULL)&&(*line!='\0'));
+ set_base(filename,lnr,line,var);
}
static void parse_scope_statement(const char *filename,int lnr,
- const char **opts,int nopts,
+ const char *keyword,char *line,
struct ldap_config *cfg)
{
- enum ldap_map_selector map;
int *var;
- if (nopts==2)
- cfg->ldc_scope=parse_scope(filename,lnr,opts[1]);
- else if (nopts==3)
- {
- /* get the map */
- map=parse_map(filename,lnr,opts[1]);
- /* get the scope variable to set */
- var=scope_get_var(map);
- if (var==NULL)
- {
- log_log(LOG_ERR,"%s:%d: unknown map: '%s'",filename,lnr,opts[1]);
- exit(EXIT_FAILURE);
- }
- /* set the scope */
- *var=parse_scope(filename,lnr,opts[2]);
- }
- else
- check_argumentcount(filename,lnr,opts[0],0);
+ var=scope_get_var(get_map(&line));
+ if (var==NULL)
+ var=&cfg->ldc_scope;
+ check_argumentcount(filename,lnr,keyword,(line!=NULL)&&(*line!='\0'));
+ *var=parse_scope(filename,lnr,line);
}
static void parse_filter_statement(const char *filename,int lnr,
- const char **opts,int nopts)
+ const char *keyword,char *line)
{
- enum ldap_map_selector map;
const char **var;
- check_argumentcount(filename,lnr,opts[0],nopts==3);
- /* get the map */
- map=parse_map(filename,lnr,opts[1]);
- /* get the filter variable to set */
- var=filter_get_var(map);
+ var=filter_get_var(get_map(&line));
if (var==NULL)
{
- log_log(LOG_ERR,"%s:%d: unknown map: '%s'",filename,lnr,opts[1]);
+ log_log(LOG_ERR,"%s:%d: unknown map: '%s'",filename,lnr,line);
exit(EXIT_FAILURE);
}
+ check_argumentcount(filename,lnr,keyword,(line!=NULL)&&(*line!='\0'));
/* check if the value will be changed */
- if (strcmp(*var,opts[2])!=0)
+ if (strcmp(*var,line)!=0)
{
/* Note: we have a memory leak here if a single mapping is changed
multiple times in one config (deemed not a problem) */
- *var=xstrdup(opts[2]);
+ *var=xstrdup(line);
}
}
/* this function modifies the statement argument passed */
static void parse_map_statement(const char *filename,int lnr,
- const char **opts,int nopts)
+ const char *keyword,char *line)
{
enum ldap_map_selector map;
const char **var;
- check_argumentcount(filename,lnr,opts[0],nopts==4);
+ char oldatt[32], newatt[32];
/* get the map */
- map=parse_map(filename,lnr,opts[1]);
+ if ((map=get_map(&line))==LM_NONE)
+ {
+ log_log(LOG_ERR,"%s:%d: unknown map: '%s'",filename,lnr,line);
+ exit(EXIT_FAILURE);
+ }
+ /* read the other tokens */
+ check_argumentcount(filename,lnr,keyword,
+ (get_token(&line,oldatt,sizeof(oldatt))!=NULL)&&
+ (get_token(&line,newatt,sizeof(newatt))!=NULL));
+ check_argumentcount(filename,lnr,keyword,(line!=NULL)&&(*line!='\0'));
/* get the attribute variable to set */
- var=attmap_get_var(map,opts[2]);
+ var=attmap_get_var(map,oldatt);
if (var==NULL)
{
- log_log(LOG_ERR,"%s:%d: unknown attribute to map: '%s'",filename,lnr,opts[2]);
+ log_log(LOG_ERR,"%s:%d: unknown attribute to map: '%s'",filename,lnr,oldatt);
exit(EXIT_FAILURE);
}
/* check if the value will be changed */
- if (strcmp(*var,opts[3])!=0)
+ if (strcmp(*var,newatt)!=0)
+ {
+ /* Note: we have a memory leak here if a single mapping is changed
+ multiple times in one config (deemed not a problem) */
+ *var=xstrdup(newatt);
+ }
+}
+
+static void get_int(const char *filename,int lnr,
+ const char *keyword,char **line,
+ int *var)
+{
+ /* TODO: refactor to have less overhead */
+ char token[32];
+ check_argumentcount(filename,lnr,keyword,get_token(line,token,sizeof(token))!=NULL);
+ /* TODO: replace with correct numeric parse */
+ *var=atoi(token);
+}
+
+static void get_boolean(const char *filename,int lnr,
+ const char *keyword,char **line,
+ int *var)
+{
+ /* TODO: refactor to have less overhead */
+ char token[32];
+ check_argumentcount(filename,lnr,keyword,get_token(line,token,sizeof(token))!=NULL);
+ *var=parse_boolean(filename,lnr,token);
+}
+
+static void get_strdup(const char *filename,int lnr,
+ const char *keyword,char **line,
+ char **var)
+{
+ /* TODO: refactor to have less overhead */
+ char token[64];
+ check_argumentcount(filename,lnr,keyword,get_token(line,token,sizeof(token))!=NULL);
+ if ((*var==NULL)||(strcmp(*var,token)!=0))
{
/* Note: we have a memory leak here if a single mapping is changed
multiple times in one config (deemed not a problem) */
- *var=xstrdup(opts[3]);
+ *var=xstrdup(token);
}
}
-/* split a line from the configuration file
- note that this code is not thread safe since a pointer to the same
- storage will be returned with each call
- the line string is modified */
-static const char **tokenize(const char *filename,int lnr,char *line,int *nopt)
+static void get_restdup(const char *filename,int lnr,
+ const char *keyword,char **line,
+ char **var)
{
- static const char *retv[MAX_LINE_OPTIONS];
- int opt;
- for (opt=0;opt<MAX_LINE_OPTIONS;opt++)
+ check_argumentcount(filename,lnr,keyword,(*line!=NULL)&&(**line!='\0'));
+ if ((*var==NULL)||(strcmp(*var,*line)!=0))
{
- /* skip beginning spaces */
- while ((*line==' ')||(*line=='\t'))
- line++;
- /* check for end of line or comment */
- if ((*line=='\0')||(*line=='#'))
- break; /* we're done */
- /* we have a new keyword */
- retv[opt]=line;
- if (*line=='"')
- {
- line++;
- /* find end quote */
- while ((*line!='"')&&(*line!='\0'))
- line++;
- if (*line!='"')
- {
- log_log(LOG_ERR,"%s:%d: quoted value not terminated",filename,lnr);
- exit(EXIT_FAILURE);
- }
- line++;
- }
- else
- {
- /* find the end of the token */
- while ((*line!=' ')&&(*line!='\t')&&(*line!='\0'))
- line++;
- }
- /* mark the end of the token */
- if (*line!='\0')
- *line++='\0';
+ /* Note: we have a memory leak here if a single mapping is changed
+ multiple times in one config (deemed not a problem) */
+ *var=xstrdup(*line);
+ }
+ *line=NULL;
+}
+
+static void get_eol(const char *filename,int lnr,
+ const char *keyword,char **line)
+{
+ if ((line!=NULL)&&(*line!=NULL)&&(**line!='\0'))
+ {
+ log_log(LOG_ERR,"%s:%d: %s: too may arguments",filename,lnr,keyword);
+ exit(EXIT_FAILURE);
}
- *nopt=opt;
- return retv;
}
static void cfg_read(const char *filename,struct ldap_config *cfg)
{
FILE *fp;
int lnr=0;
- char line[MAX_LINE_LENGTH];
+ char linebuf[MAX_LINE_LENGTH];
+ char *line;
+ char keyword[32];
+ char token[64];
int i;
- const char **opts;
- int nopts;
-
/* open config file */
if ((fp=fopen(filename,"r"))==NULL)
{
log_log(LOG_ERR,"cannot open config file (%s): %s",filename,strerror(errno));
exit(EXIT_FAILURE);
}
-
/* read file and parse lines */
- while (fgets(line,MAX_LINE_LENGTH,fp)!=NULL)
+ while (fgets(linebuf,MAX_LINE_LENGTH,fp)!=NULL)
{
lnr++;
+ line=linebuf;
/* strip newline */
i=(int)strlen(line);
if ((i<=0)||(line[i-1]!='\n'))
@@ -520,242 +563,246 @@ static void cfg_read(const char *filename,struct ldap_config *cfg)
exit(EXIT_FAILURE);
}
line[i-1]='\0';
- /* split the line in tokens */
- opts=tokenize(filename,lnr,line,&nopts);
-
- /* ignore empty lines */
- if (nopts==0)
+ /* ignore comment lines */
+ if (line[0]=='#')
+ continue;
+ /* strip trailing spaces */
+ for (i--;(i>0)&&isspace(line[i-1]);i--)
+ line[i-1]='\0';
+ /* get keyword from line and ignore empty lines */
+ if (get_token(&line,keyword,sizeof(keyword))==NULL)
continue;
-
- /* TODO: replace atoi() calls with proper parser routine with checks */
-
/* general connection options */
- if (strcasecmp(opts[0],"uri")==0)
+ if (strcasecmp(keyword,"uri")==0)
{
- check_argumentcount(filename,lnr,opts[0],nopts>1);
- for (i=1;i<nopts;i++)
+ check_argumentcount(filename,lnr,keyword,(line!=NULL)&&(*line!='\0'));
+ while (get_token(&line,token,sizeof(token))!=NULL)
{
- if (strcasecmp(opts[i],"dns")==0)
+ if (strcasecmp(token,"dns")==0)
add_uris_from_dns(filename,lnr,cfg);
else
- add_uri(filename,lnr,cfg,opts[i]);
+ add_uri(filename,lnr,cfg,token);
}
}
- else if (strcasecmp(opts[0],"ldap_version")==0)
+ else if (strcasecmp(keyword,"ldap_version")==0)
{
- check_argumentcount(filename,lnr,opts[0],nopts==2);
- cfg->ldc_version=atoi(opts[1]);
+ get_int(filename,lnr,keyword,&line,&cfg->ldc_version);
+ get_eol(filename,lnr,keyword,&line);
}
- else if (strcasecmp(opts[0],"binddn")==0)
+ else if (strcasecmp(keyword,"binddn")==0)
{
- check_argumentcount(filename,lnr,opts[0],nopts==2);
- cfg->ldc_binddn=xstrdup(opts[1]);
+ get_restdup(filename,lnr,keyword,&line,&cfg->ldc_binddn);
}
- else if (strcasecmp(opts[0],"bindpw")==0)
+ else if (strcasecmp(keyword,"bindpw")==0)
{
- check_argumentcount(filename,lnr,opts[0],nopts==2);
- cfg->ldc_bindpw=xstrdup(opts[1]);
+ get_restdup(filename,lnr,keyword,&line,&cfg->ldc_bindpw);
}
- else if (strcasecmp(opts[0],"rootbinddn")==0)
+ else if (strcasecmp(keyword,"rootbinddn")==0)
{
- log_log(LOG_ERR,"%s:%d: option %s is currently unsupported",filename,lnr,opts[0]);
+ log_log(LOG_ERR,"%s:%d: option %s is currently unsupported",filename,lnr,keyword);
exit(EXIT_FAILURE);
- check_argumentcount(filename,lnr,opts[0],nopts==2);
- cfg->ldc_rootbinddn=xstrdup(opts[1]);
+ get_restdup(filename,lnr,keyword,&line,&cfg->ldc_rootbinddn);
}
- else if (strcasecmp(opts[0],"rootbindpw")==0)
+ else if (strcasecmp(keyword,"rootbindpw")==0)
{
- log_log(LOG_ERR,"%s:%d: option %s is currently unsupported",filename,lnr,opts[0]);
+ log_log(LOG_ERR,"%s:%d: option %s is currently unsupported",filename,lnr,keyword);
exit(EXIT_FAILURE);
- check_argumentcount(filename,lnr,opts[0],nopts==2);
- cfg->ldc_rootbindpw=xstrdup(opts[1]);
+ get_restdup(filename,lnr,keyword,&line,&cfg->ldc_rootbinddn);
}
/* SASL authentication options */
- else if (strcasecmp(opts[0], "sasl_authid")==0)
+ else if (strcasecmp(keyword,"sasl_authid")==0)
{
- log_log(LOG_WARNING,"%s:%d: option %s is currently untested (please report any successes)",filename,lnr,opts[0]);
- check_argumentcount(filename,lnr,opts[0],nopts==2);
- cfg->ldc_saslid=xstrdup(opts[1]);
+ log_log(LOG_WARNING,"%s:%d: option %s is currently untested (please report any successes)",filename,lnr,keyword);
+ get_strdup(filename,lnr,keyword,&line,&cfg->ldc_saslid);
+ get_eol(filename,lnr,keyword,&line);
}
- else if (strcasecmp(opts[0],"rootsasl_authid")==0)
+ else if (strcasecmp(keyword,"rootsasl_authid")==0)
{
- log_log(LOG_ERR,"%s:%d: option %s is currently unsupported",filename,lnr,opts[0]);
+ log_log(LOG_ERR,"%s:%d: option %s is currently unsupported",filename,lnr,keyword);
exit(EXIT_FAILURE);
- check_argumentcount(filename,lnr,opts[0],nopts==2);
- cfg->ldc_rootsaslid=xstrdup(opts[1]);
+ get_strdup(filename,lnr,keyword,&line,&cfg->ldc_rootsaslid);
+ get_eol(filename,lnr,keyword,&line);
}
- else if (strcasecmp(opts[0],"sasl_secprops")==0)
+ else if (strcasecmp(keyword,"sasl_secprops")==0)
{
- log_log(LOG_WARNING,"%s:%d: option %s is currently untested (please report any successes)",filename,lnr,opts[0]);
- check_argumentcount(filename,lnr,opts[0],nopts==2);
- cfg->ldc_sasl_secprops=xstrdup(opts[1]);
+ log_log(LOG_WARNING,"%s:%d: option %s is currently untested (please report any successes)",filename,lnr,keyword);
+ get_strdup(filename,lnr,keyword,&line,&cfg->ldc_sasl_secprops);
+ get_eol(filename,lnr,keyword,&line);
}
- else if (strcasecmp(opts[0],"use_sasl")==0)
+ else if (strcasecmp(keyword,"use_sasl")==0)
{
- log_log(LOG_WARNING,"%s:%d: option %s is currently untested (please report any successes)",filename,lnr,opts[0]);
- check_argumentcount(filename,lnr,opts[0],nopts==2);
- cfg->ldc_usesasl=parse_boolean(filename,lnr,opts[1]);
+ log_log(LOG_WARNING,"%s:%d: option %s is currently untested (please report any successes)",filename,lnr,keyword);
+ get_boolean(filename,lnr,keyword,&line,&cfg->ldc_usesasl);
+ get_eol(filename,lnr,keyword,&line);
}
- else if (strcasecmp(opts[0],"rootuse_sasl")==0)
+ else if (strcasecmp(keyword,"rootuse_sasl")==0)
{
- log_log(LOG_ERR,"%s:%d: option %s is currently unsupported",filename,lnr,opts[0]);
+ log_log(LOG_ERR,"%s:%d: option %s is currently unsupported",filename,lnr,keyword);
exit(EXIT_FAILURE);
- check_argumentcount(filename,lnr,opts[0],nopts==2);
- cfg->ldc_rootusesasl=parse_boolean(filename,lnr,opts[1]);
+ get_boolean(filename,lnr,keyword,&line,&cfg->ldc_rootusesasl);
+ get_eol(filename,lnr,keyword,&line);
}
/* Kerberos authentication options */
- else if (strcasecmp(opts[0],"krb5_ccname")==0)
+ else if (strcasecmp(keyword,"krb5_ccname")==0)
{
- parse_krb5_ccname_statement(filename,lnr,opts,nopts);
+ parse_krb5_ccname_statement(filename,lnr,keyword,line);
}
/* search/mapping options */
- else if (strcasecmp(opts[0],"base")==0)
+ else if (strcasecmp(keyword,"base")==0)
{
- parse_base_statement(filename,lnr,opts,nopts,cfg);
+ parse_base_statement(filename,lnr,keyword,line,cfg);
}
- else if (strcasecmp(opts[0],"scope")==0)
+ else if (strcasecmp(keyword,"scope")==0)
{
- parse_scope_statement(filename,lnr,opts,nopts,cfg);
+ parse_scope_statement(filename,lnr,keyword,line,cfg);
}
- else if (strcasecmp(opts[0],"deref")==0)
+ else if (strcasecmp(keyword,"deref")==0)
{
- check_argumentcount(filename,lnr,opts[0],nopts==2);
- if (strcasecmp(opts[1],"never")==0)
+ check_argumentcount(filename,lnr,keyword,
+ (get_token(&line,token,sizeof(token))!=NULL));
+ if (strcasecmp(token,"never")==0)
cfg->ldc_deref=LDAP_DEREF_NEVER;
- else if (strcasecmp(opts[1],"searching")==0)
+ else if (strcasecmp(token,"searching")==0)
cfg->ldc_deref=LDAP_DEREF_SEARCHING;
- else if (strcasecmp(opts[1],"finding")==0)
+ else if (strcasecmp(token,"finding")==0)
cfg->ldc_deref=LDAP_DEREF_FINDING;
- else if (strcasecmp(opts[1],"always")==0)
+ else if (strcasecmp(token,"always")==0)
cfg->ldc_deref=LDAP_DEREF_ALWAYS;
else
{
- log_log(LOG_ERR,"%s:%d: wrong argument: '%s'",filename,lnr,opts[1]);
+ log_log(LOG_ERR,"%s:%d: wrong argument: '%s'",filename,lnr,token);
exit(EXIT_FAILURE);
}
+ get_eol(filename,lnr,keyword,&line);
}
- else if (strcasecmp(opts[0],"referrals")==0)
+ else if (strcasecmp(keyword,"referrals")==0)
{
- check_argumentcount(filename,lnr,opts[0],nopts==2);
- cfg->ldc_referrals=parse_boolean(filename,lnr,opts[1]);
+ get_boolean(filename,lnr,keyword,&line,&cfg->ldc_referrals);
+ get_eol(filename,lnr,keyword,&line);
}
- else if (strcasecmp(opts[0],"filter")==0)
+ else if (strcasecmp(keyword,"filter")==0)
{
- parse_filter_statement(filename,lnr,opts,nopts);
+ parse_filter_statement(filename,lnr,keyword,line);
}
- else if (strcasecmp(opts[0],"map")==0)
+ else if (strcasecmp(keyword,"map")==0)
{
- parse_map_statement(filename,lnr,opts,nopts);
+ parse_map_statement(filename,lnr,keyword,line);
}
/* timing/reconnect options */
- else if (strcasecmp(opts[0],"bind_timelimit")==0)
+ else if (strcasecmp(keyword,"bind_timelimit")==0)
{
- check_argumentcount(filename,lnr,opts[0],nopts==2);
- cfg->ldc_bind_timelimit=atoi(opts[1]);
+ get_int(filename,lnr,keyword,&line,&cfg->ldc_bind_timelimit);
+ get_eol(filename,lnr,keyword,&line);
}
- else if (strcasecmp(opts[0],"timelimit")==0)
+ else if (strcasecmp(keyword,"timelimit")==0)
{
- check_argumentcount(filename,lnr,opts[0],nopts==2);
- cfg->ldc_timelimit=atoi(opts[1]);
+ get_int(filename,lnr,keyword,&line,&cfg->ldc_timelimit);
+ get_eol(filename,lnr,keyword,&line);
}
- else if (strcasecmp(opts[0],"idle_timelimit")==0)
+ else if (strcasecmp(keyword,"idle_timelimit")==0)
{
- check_argumentcount(filename,lnr,opts[0],nopts==2);
- cfg->ldc_idle_timelimit=atoi(opts[1]);
+ get_int(filename,lnr,keyword,&line,&cfg->ldc_idle_timelimit);
+ get_eol(filename,lnr,keyword,&line);
}
- else if (strcasecmp(opts[0],"reconnect_tries")==0)
+ else if (strcasecmp(keyword,"reconnect_tries")==0)
{
- check_argumentcount(filename,lnr,opts[0],nopts==2);
- cfg->ldc_reconnect_tries=atoi(opts[1]);
+ get_int(filename,lnr,keyword,&line,&cfg->ldc_reconnect_tries);
+ get_eol(filename,lnr,keyword,&line);
}
- else if (!strcasecmp(opts[0],"reconnect_sleeptime"))
+ else if (!strcasecmp(keyword,"reconnect_sleeptime"))
{
- check_argumentcount(filename,lnr,opts[0],nopts==2);
- cfg->ldc_reconnect_sleeptime=atoi(opts[1]);
+ get_int(filename,lnr,keyword,&line,&cfg->ldc_reconnect_sleeptime);
+ get_eol(filename,lnr,keyword,&line);
}
- else if (strcasecmp(opts[0],"reconnect_maxsleeptime")==0)
+ else if (strcasecmp(keyword,"reconnect_maxsleeptime")==0)
{
- check_argumentcount(filename,lnr,opts[0],nopts==2);
- cfg->ldc_reconnect_maxsleeptime=atoi(opts[1]);
+ get_int(filename,lnr,keyword,&line,&cfg->ldc_reconnect_maxsleeptime);
+ get_eol(filename,lnr,keyword,&line);
}
/* SSL/TLS options */
- else if (strcasecmp(opts[0],"ssl")==0)
+ else if (strcasecmp(keyword,"ssl")==0)
{
- log_log(LOG_WARNING,"%s:%d: option %s is currently untested (please report any successes)",filename,lnr,opts[0]);
- check_argumentcount(filename,lnr,opts[0],nopts==2);
- if (strcasecmp(opts[1],"start_tls")==0)
+ log_log(LOG_WARNING,"%s:%d: option %s is currently untested (please report any successes)",filename,lnr,keyword);
+ check_argumentcount(filename,lnr,keyword,
+ (get_token(&line,token,sizeof(token))!=NULL));
+ if (strcasecmp(token,"start_tls")==0)
cfg->ldc_ssl_on=SSL_START_TLS;
- else if (parse_boolean(filename,lnr,opts[1]))
+ else if (parse_boolean(filename,lnr,token))
cfg->ldc_ssl_on=SSL_LDAPS;
+ get_eol(filename,lnr,keyword,&line);
}
- else if (strcasecmp(opts[0],"sslpath")==0)
+ else if (strcasecmp(keyword,"sslpath")==0)
{
- log_log(LOG_WARNING,"%s:%d: option %s is currently untested (please report any successes)",filename,lnr,opts[0]);
- check_argumentcount(filename,lnr,opts[0],nopts==2);
- cfg->ldc_sslpath=xstrdup(opts[1]);
+ log_log(LOG_WARNING,"%s:%d: option %s is currently untested (please report any successes)",filename,lnr,keyword);
+ get_strdup(filename,lnr,keyword,&line,&cfg->ldc_sslpath);
+ get_eol(filename,lnr,keyword,&line);
+ /* TODO: check that the path is valid */
}
- else if (strcasecmp(opts[0],"tls_checkpeer")==0)
+ else if (strcasecmp(keyword,"tls_checkpeer")==0)
{
- log_log(LOG_WARNING,"%s:%d: option %s is currently untested (please report any successes)",filename,lnr,opts[0]);
- check_argumentcount(filename,lnr,opts[0],nopts==2);
- cfg->ldc_tls_checkpeer=parse_boolean(filename,lnr,opts[1]);
+ log_log(LOG_WARNING,"%s:%d: option %s is currently untested (please report any successes)",filename,lnr,keyword);
+ get_boolean(filename,lnr,keyword,&line,&cfg->ldc_tls_checkpeer);
+ get_eol(filename,lnr,keyword,&line);
}
- else if (strcasecmp(opts[0],"tls_cacertdir")==0)
+ else if (strcasecmp(keyword,"tls_cacertdir")==0)
{
- log_log(LOG_WARNING,"%s:%d: option %s is currently untested (please report any successes)",filename,lnr,opts[0]);
- check_argumentcount(filename,lnr,opts[0],nopts==2);
- cfg->ldc_tls_cacertdir=xstrdup(opts[1]);
+ log_log(LOG_WARNING,"%s:%d: option %s is currently untested (please report any successes)",filename,lnr,keyword);
+ get_strdup(filename,lnr,keyword,&line,&cfg->ldc_tls_cacertdir);
+ get_eol(filename,lnr,keyword,&line);
+ /* TODO: check that the path is valid */
}
- else if (strcasecmp(opts[0],"tls_cacertfile")==0)
+ else if (strcasecmp(keyword,"tls_cacertfile")==0)
{
- log_log(LOG_WARNING,"%s:%d: option %s is currently untested (please report any successes)",filename,lnr,opts[0]);
- check_argumentcount(filename,lnr,opts[0],nopts==2);
- cfg->ldc_tls_cacertfile=xstrdup(opts[1]);
+ log_log(LOG_WARNING,"%s:%d: option %s is currently untested (please report any successes)",filename,lnr,keyword);
+ get_strdup(filename,lnr,keyword,&line,&cfg->ldc_tls_cacertfile);
+ get_eol(filename,lnr,keyword,&line);
+ /* TODO: check that the path is valid */
}
- else if (strcasecmp(opts[0],"tls_randfile")==0)
+ else if (strcasecmp(keyword,"tls_randfile")==0)
{
- log_log(LOG_WARNING,"%s:%d: option %s is currently untested (please report any successes)",filename,lnr,opts[0]);
- check_argumentcount(filename,lnr,opts[0],nopts==2);
- cfg->ldc_tls_randfile=xstrdup(opts[1]);
+ log_log(LOG_WARNING,"%s:%d: option %s is currently untested (please report any successes)",filename,lnr,keyword);
+ get_strdup(filename,lnr,keyword,&line,&cfg->ldc_tls_randfile);
+ get_eol(filename,lnr,keyword,&line);
+ /* TODO: check that the path is valid */
}
- else if (strcasecmp(opts[0],"tls_ciphers")==0)
+ else if (strcasecmp(keyword,"tls_ciphers")==0)
{
- log_log(LOG_WARNING,"%s:%d: option %s is currently untested (please report any successes)",filename,lnr,opts[0]);
- check_argumentcount(filename,lnr,opts[0],nopts==2);
- cfg->ldc_tls_ciphers=xstrdup(opts[1]);
+ log_log(LOG_WARNING,"%s:%d: option %s is currently untested (please report any successes)",filename,lnr,keyword);
+ get_restdup(filename,lnr,keyword,&line,&cfg->ldc_tls_ciphers);
}
- else if (strcasecmp(opts[0],"tls_cert")==0)
+ else if (strcasecmp(keyword,"tls_cert")==0)
{
- log_log(LOG_WARNING,"%s:%d: option %s is currently untested (please report any successes)",filename,lnr,opts[0]);
- check_argumentcount(filename,lnr,opts[0],nopts==2);
- cfg->ldc_tls_cert=xstrdup(opts[1]);
+ log_log(LOG_WARNING,"%s:%d: option %s is currently untested (please report any successes)",filename,lnr,keyword);
+ get_strdup(filename,lnr,keyword,&line,&cfg->ldc_tls_cert);
+ get_eol(filename,lnr,keyword,&line);
+ /* TODO: check that the path is valid */
}
- else if (strcasecmp(opts[0],"tls_key")==0)
+ else if (strcasecmp(keyword,"tls_key")==0)
{
- log_log(LOG_WARNING,"%s:%d: option %s is currently untested (please report any successes)",filename,lnr,opts[0]);
- check_argumentcount(filename,lnr,opts[0],nopts==2);
- cfg->ldc_tls_key=xstrdup(opts[1]);
+ log_log(LOG_WARNING,"%s:%d: option %s is currently untested (please report any successes)",filename,lnr,keyword);
+ get_strdup(filename,lnr,keyword,&line,&cfg->ldc_tls_key);
+ get_eol(filename,lnr,keyword,&line);
+ /* TODO: check that the path is valid */
}
/* other options */
- else if (strcasecmp(opts[0],"restart")==0)
+ else if (strcasecmp(keyword,"restart")==0)
{
- log_log(LOG_WARNING,"%s:%d: option %s is currently untested (and may be removed in an upcoming release)",filename,lnr,opts[0]);
- check_argumentcount(filename,lnr,opts[0],nopts==2);
- cfg->ldc_restart=parse_boolean(filename,lnr,opts[1]);
+ log_log(LOG_WARNING,"%s:%d: option %s is currently untested (and may be removed in an upcoming release)",filename,lnr,keyword);
+ get_boolean(filename,lnr,keyword,&line,&cfg->ldc_restart);
+ get_eol(filename,lnr,keyword,&line);
}
- else if (strcasecmp(opts[0],"pagesize")==0)
+ else if (strcasecmp(keyword,"pagesize")==0)
{
- check_argumentcount(filename,lnr,opts[0],nopts==2);
- cfg->ldc_pagesize=atoi(opts[1]);
+ get_int(filename,lnr,keyword,&line,&cfg->ldc_pagesize);
+ get_eol(filename,lnr,keyword,&line);
}
/* fallthrough */
else
{
- log_log(LOG_ERR,"%s:%d: unknown keyword: '%s'",filename,lnr,opts[0]);
+ log_log(LOG_ERR,"%s:%d: unknown keyword: '%s'",filename,lnr,keyword);
exit(EXIT_FAILURE);
}
}
-
/* we're done reading file, close */
fclose(fp);
}
diff --git a/nslcd/cfg.h b/nslcd/cfg.h
index 54974f6..eecc2eb 100644
--- a/nslcd/cfg.h
+++ b/nslcd/cfg.h
@@ -92,7 +92,7 @@ struct ldap_config
/* search timelimit */
int ldc_timelimit;
/* idle timeout */
- time_t ldc_idle_timelimit;
+ int ldc_idle_timelimit;
/* number of sleeping reconnect attempts */
int ldc_reconnect_tries;
/* seconds to sleep; doubled until max */
diff --git a/tests/test_cfg.c b/tests/test_cfg.c
index 6cbcf83..bbcecbc 100644
--- a/tests/test_cfg.c
+++ b/tests/test_cfg.c
@@ -127,35 +127,36 @@ static void test_parse_map(void)
(LM_NETGROUP!=LM_RPC)&&(LM_NETGROUP!=LM_SERVICES)&&(LM_NETGROUP!=LM_SHADOW));
assert((LM_NETWORKS!=LM_PASSWD)&&(LM_NETWORKS!=LM_PROTOCOLS)&&(LM_NETWORKS!=LM_RPC)&&
(LM_NETWORKS!=LM_SERVICES)&&(LM_NETWORKS!=LM_SHADOW));
- assert((LM_PASSWD!=LM_PROTOCOLS)&&(LM_PASSWD!=LM_RPC)&&(LM_PASSWD!=LM_SERVICES)&& (LM_PASSWD!=LM_SHADOW));
+ assert((LM_PASSWD!=LM_PROTOCOLS)&&(LM_PASSWD!=LM_RPC)&&(LM_PASSWD!=LM_SERVICES)&&
+ (LM_PASSWD!=LM_SHADOW));
assert((LM_PROTOCOLS!=LM_RPC)&&(LM_PROTOCOLS!=LM_SERVICES)&&(LM_PROTOCOLS!=LM_SHADOW));
assert((LM_RPC!=LM_SERVICES)&&(LM_RPC!=LM_SHADOW));
assert((LM_SERVICES!=LM_SHADOW));
/* test supported names */
- assert(parse_map(__FILE__,__LINE__,"alIas")==LM_ALIASES);
- assert(parse_map(__FILE__,__LINE__,"AliasES")==LM_ALIASES);
- assert(parse_map(__FILE__,__LINE__,"ether")==LM_ETHERS);
- assert(parse_map(__FILE__,__LINE__,"ethers")==LM_ETHERS);
- assert(parse_map(__FILE__,__LINE__,"group")==LM_GROUP);
- /* assert(parse_map(__FILE__,__LINE__,"groups")==LM_GROUP); */
- assert(parse_map(__FILE__,__LINE__,"host")==LM_HOSTS);
- assert(parse_map(__FILE__,__LINE__,"hosts")==LM_HOSTS);
- assert(parse_map(__FILE__,__LINE__,"netgroup")==LM_NETGROUP);
- /* assert(parse_map(__FILE__,__LINE__,"netgroups")==LM_NETGROUP); */
- assert(parse_map(__FILE__,__LINE__,"network")==LM_NETWORKS);
- assert(parse_map(__FILE__,__LINE__,"networks")==LM_NETWORKS);
- assert(parse_map(__FILE__,__LINE__,"passwd")==LM_PASSWD);
- /* assert(parse_map(__FILE__,__LINE__,"passwds")==LM_PASSWD); */
- assert(parse_map(__FILE__,__LINE__,"protocol")==LM_PROTOCOLS);
- assert(parse_map(__FILE__,__LINE__,"protocols")==LM_PROTOCOLS);
- assert(parse_map(__FILE__,__LINE__,"rpc")==LM_RPC);
- /* assert(parse_map(__FILE__,__LINE__,"rpcs")==LM_RPC); */
- assert(parse_map(__FILE__,__LINE__,"service")==LM_SERVICES);
- assert(parse_map(__FILE__,__LINE__,"services")==LM_SERVICES);
- assert(parse_map(__FILE__,__LINE__,"shadow")==LM_SHADOW);
- /* assert(parse_map(__FILE__,__LINE__,"shadows")==LM_SHADOW); */
+ assert(parse_map("alIas")==LM_ALIASES);
+ assert(parse_map("AliasES")==LM_ALIASES);
+ assert(parse_map("ether")==LM_ETHERS);
+ assert(parse_map("ethers")==LM_ETHERS);
+ assert(parse_map("group")==LM_GROUP);
+ /* assert(parse_map("groups")==LM_GROUP); */
+ assert(parse_map("host")==LM_HOSTS);
+ assert(parse_map("hosts")==LM_HOSTS);
+ assert(parse_map("netgroup")==LM_NETGROUP);
+ /* assert(parse_map("netgroups")==LM_NETGROUP); */
+ assert(parse_map("network")==LM_NETWORKS);
+ assert(parse_map("networks")==LM_NETWORKS);
+ assert(parse_map("passwd")==LM_PASSWD);
+ /* assert(parse_map("passwds")==LM_PASSWD); */
+ assert(parse_map("protocol")==LM_PROTOCOLS);
+ assert(parse_map("protocols")==LM_PROTOCOLS);
+ assert(parse_map("rpc")==LM_RPC);
+ /* assert(parse_map("rpcs")==LM_RPC); */
+ assert(parse_map("service")==LM_SERVICES);
+ assert(parse_map("services")==LM_SERVICES);
+ assert(parse_map("shadow")==LM_SHADOW);
+ /* assert(parse_map("shadows")==LM_SHADOW); */
/* most other values should call exit():
- assert(parse_map(__FILE__,__LINE__,"publickey")==LM_SERVICES); */
+ assert(parse_map("publickey")==LM_SERVICES); */
}
static void test_parse_map_statement(void)
@@ -165,21 +166,50 @@ static void test_parse_map_statement(void)
static void test_tokenize(void)
{
- const char **opts;
- int nopts;
- /* this also has memory leaks (the strdup() calls) */
- opts=tokenize(__FILE__,__LINE__,strdup("this is a simple line"),&nopts);
- assert(nopts==5);
- assertstreq(opts[0],"this");
- assertstreq(opts[1],"is");
- assertstreq(opts[2],"a");
- assertstreq(opts[3],"simple");
- assertstreq(opts[4],"line");
- opts=tokenize(__FILE__,__LINE__,strdup("this contains \"quoted text\""),&nopts);
- assert(nopts==3);
- assertstreq(opts[0],"this");
- assertstreq(opts[1],"contains");
- assertstreq(opts[2],"\"quoted text\"");
+ /* this leaks memory all over the place */
+ char *line=strdup("yes this is 1 simple line");
+ char *str;
+ int i;
+ get_boolean(__FILE__,__LINE__,__PRETTY_FUNCTION__,&line,&i);
+ assert(i==1);
+ get_strdup(__FILE__,__LINE__,__PRETTY_FUNCTION__,&line,&str);
+ assertstreq(str,"this");
+ get_strdup(__FILE__,__LINE__,__PRETTY_FUNCTION__,&line,&str);
+ assertstreq(str,"is");
+ get_int(__FILE__,__LINE__,__PRETTY_FUNCTION__,&line,&i);
+ assert(i==1);
+ get_restdup(__FILE__,__LINE__,__PRETTY_FUNCTION__,&line,&str);
+ assertstreq(str,"simple line");
+}
+
+extern const char *passwd_base;
+
+static void test_read(void)
+{
+ FILE *fp;
+ struct ldap_config cfg;
+ /* write some stuff to a temporary file */
+ fp=fopen("temp.cfg","w");
+ assert(fp!=NULL);
+ fprintf(fp,"# a line of comments\n"
+ "uri ldap://127.0.0.1/\n"
+ "uri ldap:/// ldaps://127.0.0.1/\n"
+ "base dc=test, dc=tld\n"
+ "base passwd ou=Some People,dc=test,dc=tld\n");
+ fclose(fp);
+ /* parse the file */
+ cfg_defaults(&cfg);
+ cfg_read("temp.cfg",&cfg);
+ /* check results */
+ assert(cfg.ldc_uris[0]!=NULL);
+ assert(cfg.ldc_uris[1]!=NULL);
+ assert(cfg.ldc_uris[2]!=NULL);
+ assertstreq(cfg.ldc_uris[0],"ldap://127.0.0.1/");
+ assertstreq(cfg.ldc_uris[1],"ldap:///");
+ assertstreq(cfg.ldc_uris[2],"ldaps://127.0.0.1/");
+ assert(cfg.ldc_uris[3]==NULL);
+ assertstreq(cfg.ldc_base,"dc=test, dc=tld");
+ assertstreq(passwd_base,"ou=Some People,dc=test,dc=tld");
}
/* the main program... */
@@ -192,5 +222,6 @@ int main(int UNUSED(argc),char UNUSED(*argv[]))
test_parse_map();
test_parse_map_statement();
test_tokenize();
+ test_read();
return EXIT_SUCCESS;
}