2
/* ----------------------------------------------------------------------- *
4
* master_parser.y - master map buffer parser.
6
* Copyright 2006 Ian Kent <raven@themaw.net>
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, Inc., 675 Mass Ave, Cambridge MA 02139,
11
* USA; either version 2 of the License, or (at your option) any later
14
* This program is distributed in the hope that it will be useful,
15
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
* GNU General Public License for more details.
19
* ----------------------------------------------------------------------- */
26
#include <sys/ioctl.h>
28
#include "automount.h"
31
#define MAX_ERR_LEN 512
33
extern struct master *master_list;
35
char **add_argv(int, char **, char *);
36
const char **copy_argv(int, const char **);
37
int free_argv(int, const char **);
39
extern FILE *master_in;
40
extern char *master_text;
41
extern int master_lex(void);
42
extern int master_lineno;
43
extern void master_set_scan_buffer(const char *);
45
static char *master_strdup(char *);
46
static void local_init_vars(void);
47
static void local_free_vars(void);
48
static void trim_maptype(char *);
49
static int add_multi_mapstr(void);
51
static int master_error(const char *s);
52
static int master_notify(const char *s);
53
static int master_msg(const char *s);
59
static long negative_timeout;
60
static unsigned ghost;
61
extern unsigned global_random_selection;
62
static unsigned random_selection;
63
static char **tmp_argv;
65
static char **local_argv;
66
static int local_argc;
68
static char errstr[MAX_ERR_LEN];
70
static unsigned int verbose;
71
static unsigned int debug;
78
#define YYENABLE_NLS 0
80
#ifndef YYLTYPE_IS_TRIVIAL
81
#define YYLTYPE_IS_TRIVIAL 0
85
static int master_fprintf(FILE *, char *, ...);
87
#define YYFPRINTF master_fprintf
100
%token OPT_TIMEOUT OPT_NTIMEOUT OPT_NOGHOST OPT_GHOST OPT_VERBOSE
101
%token OPT_DEBUG OPT_RANDOM
102
%token COLON COMMA NL DDASH
104
%type <strtype> options
106
%type <strtype> dnattrs
107
%type <strtype> dnattr
108
%type <strtype> option
109
%type <strtype> daemon_option
110
%type <strtype> mount_option
111
%token <strtype> PATH
112
%token <strtype> QUOTE
113
%token <strtype> NILL
114
%token <strtype> SPACE
115
%token <strtype> EQUAL
116
%token <strtype> MULTITYPE
117
%token <strtype> MAPTYPE
118
%token <strtype> DNSERVER
119
%token <strtype> DNATTR
120
%token <strtype> DNNAME
121
%token <strtype> MAPHOSTS
122
%token <strtype> MAPNULL
123
%token <strtype> MAPXFN
124
%token <strtype> MAPNAME
125
%token <longtype> NUMBER
126
%token <strtype> OPTION
135
master_debug = YYDEBUG;
143
path = master_strdup($1);
149
| PATH MULTITYPE maplist
155
path = master_strdup($1);
157
master_error("memory allocation error");
162
if ((tmp = strchr($2, ',')))
165
type = master_strdup($2);
167
master_error("memory allocation error");
172
format = master_strdup(tmp);
174
master_error("memory allocation error");
180
| PATH COLON { master_notify($1); YYABORT; }
181
| PATH OPTION { master_notify($2); YYABORT; }
182
| PATH NILL { master_notify($2); YYABORT; }
183
| PATH OPT_RANDOM { master_notify($1); YYABORT; }
184
| PATH OPT_DEBUG { master_notify($1); YYABORT; }
185
| PATH OPT_TIMEOUT { master_notify($1); YYABORT; }
186
| PATH OPT_GHOST { master_notify($1); YYABORT; }
187
| PATH OPT_NOGHOST { master_notify($1); YYABORT; }
188
| PATH OPT_VERBOSE { master_notify($1); YYABORT; }
189
| PATH { master_notify($1); YYABORT; }
190
| QUOTE { master_notify($1); YYABORT; }
191
| OPTION { master_notify($1); YYABORT; }
192
| NILL { master_notify($1); YYABORT; }
193
| COMMENT { YYABORT; }
198
local_argc = tmp_argc;
199
local_argv = tmp_argv;
205
local_argc = tmp_argc;
206
local_argv = tmp_argv;
214
if (!add_multi_mapstr()) {
215
master_error("memory allocation error");
222
if (!add_multi_mapstr()) {
223
master_error("memory allocation error");
231
local_argv = add_argv(local_argc, local_argv, "--");
233
master_error("memory allocation error");
237
if (!add_multi_mapstr()) {
238
master_error("memory allocation error");
243
| maplist DDASH map options
246
local_argv = add_argv(local_argc, local_argv, "--");
248
master_error("memory allocation error");
252
if (!add_multi_mapstr()) {
253
master_error("memory allocation error");
263
tmp_argv = add_argv(tmp_argc, tmp_argv, $1);
265
master_error("memory allocation error");
273
tmp_argv = add_argv(tmp_argc, tmp_argv, $1);
275
master_error("memory allocation error");
282
type = master_strdup($1 + 1);
291
master_msg("X/Open Federated Naming service not supported");
296
type = master_strdup($1 + 1);
304
type = master_strdup("ldap");
310
tmp_argv = add_argv(tmp_argc, tmp_argv, $1);
312
master_error("memory allocation error");
323
if ((tmp = strchr($1, ',')))
326
type = master_strdup($1);
328
master_error("memory allocation error");
333
format = master_strdup(tmp);
335
master_error("memory allocation error");
341
tmp_argv = add_argv(tmp_argc, tmp_argv, $2);
343
master_error("memory allocation error");
354
if ((tmp = strchr($1, ',')))
357
type = master_strdup($1);
359
master_error("memory allocation error");
364
format = master_strdup(tmp);
366
master_error("memory allocation error");
372
tmp_argv = add_argv(tmp_argc, tmp_argv, $2);
374
master_error("memory allocation error");
385
if ((tmp = strchr($1, ',')))
388
type = master_strdup($1);
390
master_error("memory allocation error");
395
format = master_strdup(tmp);
397
master_error("memory allocation error");
403
tmp_argv = add_argv(tmp_argc, tmp_argv, $2);
405
master_error("memory allocation error");
409
/* Add back the type for lookup_ldap.c to handle ldaps */
411
tmp = malloc(strlen(type) + strlen(tmp_argv[0]) + 2);
413
master_error("memory allocation error");
419
strcat(tmp, tmp_argv[0]);
437
master_notify("syntax error in dn");
442
dnattrs: DNATTR EQUAL DNNAME
444
if (strcasecmp($1, "cn") &&
445
strcasecmp($1, "ou") &&
446
strcasecmp($1, "automountMapName") &&
447
strcasecmp($1, "nisMapName")) {
451
master_notify(errstr);
458
| DNATTR EQUAL DNNAME COMMA dnattr
460
if (strcasecmp($1, "cn") &&
461
strcasecmp($1, "ou") &&
462
strcasecmp($1, "automountMapName") &&
463
strcasecmp($1, "nisMapName")) {
467
master_notify(errstr);
478
/* Matches map in old style syntax ldap:server:map */
488
dnattr: DNATTR EQUAL DNNAME
490
if (!strcasecmp($1, "automountMapName") ||
491
!strcasecmp($1, "nisMapName")) {
495
master_notify(errstr);
502
| DNATTR EQUAL DNNAME COMMA dnattr
504
if (!strcasecmp($1, "automountMapName") ||
505
!strcasecmp($1, "nisMapName")) {
509
master_notify(errstr);
531
| options COMMA option {}
533
| options COMMA COMMA option
545
option: daemon_option
549
master_notify("bogus option");
554
daemon_option: OPT_TIMEOUT NUMBER { timeout = $2; }
555
| OPT_NTIMEOUT NUMBER { negative_timeout = $2; }
556
| OPT_NOGHOST { ghost = 0; }
557
| OPT_GHOST { ghost = 1; }
558
| OPT_VERBOSE { verbose = 1; }
559
| OPT_DEBUG { debug = 1; }
560
| OPT_RANDOM { random_selection = 1; }
566
tmp_argv = add_argv(tmp_argc, tmp_argv, $1);
568
master_error("memory allocation error");
577
static int master_fprintf(FILE *f, char *msg, ...)
581
vsyslog(LOG_DEBUG, msg, ap);
587
static char *master_strdup(char *str)
593
master_error("memory allocation error");
597
static int master_error(const char *s)
599
logmsg("%s while parsing map.", s);
603
static int master_notify(const char *s)
605
logmsg("syntax error in map near [ %s ]", s);
609
static int master_msg(const char *s)
615
static void local_init_vars(void)
623
negative_timeout = 0;
624
ghost = defaults_get_browse_mode();
625
random_selection = global_random_selection;
632
static void local_free_vars(void)
644
free_argv(local_argc, (const char **) local_argv);
650
free_argv(tmp_argc, (const char **) tmp_argv);
656
static void trim_maptype(char *type)
660
tmp = strchr(type, ':');
664
int len = strlen(type);
665
while (len-- && isblank(type[len]))
671
static int add_multi_mapstr(void)
674
/* If type given and format is non-null add it back */
676
int len = strlen(type) + strlen(format) + 2;
677
char *tmp = realloc(type, len);
682
strcat(type, format);
688
local_argv = add_argv(local_argc, local_argv, type);
699
local_argv = append_argv(local_argc, local_argv, tmp_argc, tmp_argv);
705
local_argc += tmp_argc;
713
void master_init_scan(void)
718
int master_parse_entry(const char *buffer, unsigned int default_timeout, unsigned int logging, time_t age)
720
struct master *master = master_list;
721
struct mapent_cache *nc;
722
struct master_mapent *entry, *new;
723
struct map_source *source;
724
unsigned int logopt = logging;
725
unsigned int m_logopt = master->logopt;
732
master_set_scan_buffer(buffer);
734
ret = master_parse();
742
/* Add null map entries to the null map cache */
743
if (type && !strcmp(type, "null")) {
745
cache_update(nc, NULL, path, NULL, lineno);
751
/* Ignore all subsequent matching nulled entries */
753
if (cache_lookup_distinct(nc, path)) {
760
if (debug || verbose) {
761
logopt = (debug ? LOGOPT_DEBUG : 0);
762
logopt |= (verbose ? LOGOPT_VERBOSE : 0);
766
timeout = default_timeout;
769
entry = master_find_mapent(master, path);
771
new = master_new_mapent(master, path, age);
778
if (entry->age && entry->age == age) {
779
if (strcmp(path, "/-")) {
781
"ignoring duplicate indirect mount %s",
790
ret = master_add_autofs_point(entry, timeout, logopt, ghost, 0);
792
error(m_logopt, "failed to add autofs_point");
794
master_free_mapent(new);
799
struct ioctl_ops *ops = get_ioctl_ops();
800
struct autofs_point *ap = entry->ap;
801
time_t tout = timeout;
804
* Second and subsequent instances of a mount point
805
* use the ghost, log and timeout of the first
807
if (entry->age < age) {
808
ap->exp_timeout = timeout;
809
ap->exp_runfreq = (ap->exp_timeout + CHECK_RATIO - 1) / CHECK_RATIO;
810
if (ap->ioctlfd != -1 && ap->type == LKP_INDIRECT)
811
ops->timeout(ap->logopt, ap->ioctlfd, &tout);
814
if (random_selection)
815
entry->ap->flags |= MOUNT_FLAG_RANDOM_SELECT;
816
if (negative_timeout)
817
entry->ap->negative_timeout = negative_timeout;
820
source = master_find_map_source(entry, type, format,
821
local_argc, (const char **) local_argv);
823
source = master_add_map_source(entry, type, format, age,
824
local_argc, (const char **) local_argv);
828
source = master_add_map_source(entry, type, format, age,
829
local_argc, (const char **) local_argv);
831
error(m_logopt, "failed to add source");
833
master_free_mapent(new);
839
source->mc = cache_init(entry->ap, source);
841
error(m_logopt, "failed to init source cache");
843
master_free_mapent(new);
848
source->master_line = lineno;
851
entry->current = NULL;
854
master_add_mapent(master, entry);