Blame lib/nss_parse.y

Packit 8480eb
%{
Packit 8480eb
/* ----------------------------------------------------------------------- *
Packit 8480eb
 *   
Packit 8480eb
 *  nss_parser.y - nsswitch parser.
Packit 8480eb
 *
Packit 8480eb
 *   Copyright 2006 Ian Kent <raven@themaw.net>
Packit 8480eb
 *
Packit 8480eb
 *   This program is free software; you can redistribute it and/or modify
Packit 8480eb
 *   it under the terms of the GNU General Public License as published by
Packit 8480eb
 *   the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139,
Packit 8480eb
 *   USA; either version 2 of the License, or (at your option) any later
Packit 8480eb
 *   version.
Packit 8480eb
 *   
Packit 8480eb
 *   This program is distributed in the hope that it will be useful,
Packit 8480eb
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 8480eb
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit 8480eb
 *   GNU General Public License for more details.
Packit 8480eb
 *
Packit 8480eb
 * ----------------------------------------------------------------------- */
Packit 8480eb
Packit 8480eb
#include <stdio.h>
Packit 8480eb
#include <stdlib.h>
Packit 8480eb
#include <string.h>
Packit 8480eb
#include <memory.h>
Packit 8480eb
#include <limits.h>
Packit 8480eb
Packit 8480eb
#include "automount.h"
Packit 8480eb
#include "nsswitch.h"
Packit 8480eb
#include "nss_parse.tab.h"
Packit 8480eb
Packit 8480eb
static pthread_mutex_t parse_mutex = PTHREAD_MUTEX_INITIALIZER;
Packit 8480eb
Packit 8480eb
static struct list_head *nss_list;
Packit 8480eb
static struct nss_source *src;
Packit 8480eb
struct nss_action act[NSS_STATUS_MAX];
Packit 8480eb
Packit 8480eb
#define YYDEBUG 0
Packit 8480eb
Packit 8480eb
#ifndef YYENABLE_NLS
Packit 8480eb
#define YYENABLE_NLS 0
Packit 8480eb
#endif
Packit 8480eb
#ifndef YYLTYPE_IS_TRIVIAL
Packit 8480eb
#define YYLTYPE_IS_TRIVIAL 0
Packit 8480eb
#endif
Packit 8480eb
Packit 8480eb
unsigned int nss_automount_found;
Packit 8480eb
Packit 8480eb
extern int nss_lineno;
Packit 8480eb
extern int nss_lex(void);
Packit 8480eb
extern FILE *nss_in;
Packit 8480eb
Packit 8480eb
static int nss_ignore(const char *s);
Packit 8480eb
static int nss_error(const char *s);
Packit 8480eb
Packit 8480eb
%}
Packit 8480eb
Packit 8480eb
%union {
Packit 8480eb
char strval[128];
Packit 8480eb
}
Packit 8480eb
Packit 8480eb
%token LBRACKET RBRACKET EQUAL BANG NL
Packit 8480eb
%token <strval> SOURCE
Packit 8480eb
%token <strval> STATUS
Packit 8480eb
%token <strval> ACTION
Packit 8480eb
Packit 8480eb
%start file
Packit 8480eb
Packit 8480eb
%%
Packit 8480eb
Packit 8480eb
file: {
Packit 8480eb
#if YYDEBUG != 0
Packit 8480eb
		nss_debug = YYDEBUG;
Packit 8480eb
#endif
Packit 8480eb
	} sources NL
Packit 8480eb
	| /* empty */
Packit 8480eb
	;
Packit 8480eb
Packit 8480eb
sources: nss_source
Packit 8480eb
	| nss_source sources
Packit 8480eb
	;
Packit 8480eb
Packit 8480eb
nss_source: SOURCE
Packit 8480eb
{
Packit 8480eb
	if (!strcmp($1, "files") || !strcmp($1, "yp") ||
Packit 8480eb
	    !strcmp($1, "nis") || !strcmp($1, "ldap") ||
Packit 8480eb
	    !strcmp($1, "nisplus") || !strcmp($1, "hesiod") ||
Packit 8480eb
	    !strcmp($1, "sss"))
Packit 8480eb
		src = add_source(nss_list, $1);
Packit 8480eb
	else
Packit 8480eb
		nss_ignore($1);
Packit 8480eb
} | SOURCE LBRACKET status_exp_list RBRACKET
Packit 8480eb
{
Packit 8480eb
	enum nsswitch_status a;
Packit 8480eb
Packit 8480eb
	if (!strcmp($1, "files") || !strcmp($1, "yp") ||
Packit 8480eb
	    !strcmp($1, "nis") || !strcmp($1, "ldap") ||
Packit 8480eb
	    !strcmp($1, "nisplus") || !strcmp($1, "hesiod") ||
Packit 8480eb
	    !strcmp($1, "sss")) {
Packit 8480eb
		src = add_source(nss_list, $1);
Packit 8480eb
		for (a = 0; a < NSS_STATUS_MAX; a++) {
Packit 8480eb
			if (act[a].action != NSS_ACTION_UNKNOWN) {
Packit 8480eb
				src->action[a].action = act[a].action;
Packit 8480eb
				src->action[a].negated = act[a].negated;
Packit 8480eb
			}
Packit 8480eb
		}
Packit 8480eb
	} else
Packit 8480eb
		nss_ignore($1);
Packit 8480eb
} | SOURCE LBRACKET status_exp_list SOURCE { nss_error("missing close bracket"); YYABORT; }
Packit 8480eb
  | SOURCE LBRACKET status_exp_list NL { nss_error("missing close bracket"); YYABORT; }
Packit 8480eb
  | SOURCE LBRACKET SOURCE { nss_error($3); YYABORT; }
Packit 8480eb
  | error SOURCE { nss_error($2); YYABORT; };
Packit 8480eb
Packit 8480eb
status_exp_list: status_exp
Packit 8480eb
		| status_exp status_exp_list
Packit 8480eb
Packit 8480eb
status_exp: STATUS EQUAL ACTION
Packit 8480eb
{
Packit 8480eb
	set_action(act, $1, $3, 0);
Packit 8480eb
} | BANG STATUS EQUAL ACTION
Packit 8480eb
{
Packit 8480eb
	set_action(act, $2, $4, 1);
Packit 8480eb
} | STATUS EQUAL SOURCE {nss_error($3); YYABORT; }
Packit 8480eb
  | STATUS SOURCE {nss_error($2); YYABORT; }
Packit 8480eb
  | BANG STATUS EQUAL SOURCE {nss_error($4); YYABORT; }
Packit 8480eb
  | BANG STATUS SOURCE {nss_error($3); YYABORT; }
Packit 8480eb
  | BANG SOURCE {nss_error($2); YYABORT; };
Packit 8480eb
Packit 8480eb
%%
Packit 8480eb
Packit 8480eb
static int nss_ignore(const char *s)
Packit 8480eb
{
Packit 8480eb
	logmsg("ignored unsupported autofs nsswitch source \"%s\"", s);
Packit 8480eb
	return(0);
Packit 8480eb
}
Packit 8480eb
Packit 8480eb
static int nss_error(const char *s)
Packit 8480eb
{
Packit 8480eb
	logmsg("syntax error in nsswitch config near [ %s ]\n", s);
Packit 8480eb
	return(0);
Packit 8480eb
}
Packit 8480eb
Packit 8480eb
static void parse_mutex_lock(void)
Packit 8480eb
{
Packit 8480eb
	int status = pthread_mutex_lock(&parse_mutex);
Packit 8480eb
	if (status)
Packit 8480eb
		fatal(status);
Packit 8480eb
	return;
Packit 8480eb
}
Packit 8480eb
Packit 8480eb
static void parse_mutex_unlock(void *arg)
Packit 8480eb
{
Packit 8480eb
	int status = pthread_mutex_unlock(&parse_mutex);
Packit 8480eb
	if (status)
Packit 8480eb
		fatal(status);
Packit 8480eb
	return;
Packit 8480eb
}
Packit 8480eb
Packit 8480eb
static void parse_close_nsswitch(void *arg)
Packit 8480eb
{
Packit 8480eb
	FILE *nsswitch = (FILE *) arg;
Packit 8480eb
	fclose(nsswitch);
Packit 8480eb
	return;
Packit 8480eb
}
Packit 8480eb
Packit 8480eb
int nsswitch_parse(struct list_head *list)
Packit 8480eb
{
Packit 8480eb
	FILE *nsswitch;
Packit 8480eb
	int status;
Packit 8480eb
Packit 8480eb
	nsswitch = open_fopen_r(NSSWITCH_FILE);
Packit 8480eb
	if (!nsswitch) {
Packit 8480eb
		logerr("couldn't open %s", NSSWITCH_FILE);
Packit 8480eb
		return 1;
Packit 8480eb
	}
Packit 8480eb
Packit 8480eb
	pthread_cleanup_push(parse_close_nsswitch, nsswitch);
Packit 8480eb
Packit 8480eb
	parse_mutex_lock();
Packit 8480eb
	pthread_cleanup_push(parse_mutex_unlock, NULL);
Packit 8480eb
Packit 8480eb
	nss_in = nsswitch;
Packit 8480eb
Packit 8480eb
	nss_automount_found = 0;
Packit 8480eb
	nss_list = list;
Packit 8480eb
	status = nss_parse();
Packit 8480eb
	nss_list = NULL;
Packit 8480eb
Packit 8480eb
	/* No "automount" nsswitch entry, use "files" */
Packit 8480eb
	if (!nss_automount_found)
Packit 8480eb
		if (add_source(list, "files"))
Packit 8480eb
			status = 0;
Packit 8480eb
Packit 8480eb
	pthread_cleanup_pop(1);
Packit 8480eb
	pthread_cleanup_pop(1);
Packit 8480eb
Packit 8480eb
	if (status)
Packit 8480eb
		return 1;
Packit 8480eb
Packit 8480eb
	return 0;
Packit 8480eb
}