version 1.1, 2004/07/25 03:29:34 |
version 1.2, 2004/08/03 14:46:35 |
|
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
* |
* |
*/ |
*/ |
%{ |
|
/* |
/* |
* Configuration parser for the CVS daemon |
* Configuration parser for the CVS daemon |
|
* |
|
* Thanks should go to Henning Brauer for providing insight on some |
|
* questions I had regarding my grammar. |
*/ |
*/ |
|
|
|
%{ |
#include <sys/types.h> |
#include <sys/types.h> |
#include <sys/queue.h> |
#include <sys/queue.h> |
|
|
#include <errno.h> |
#include <errno.h> |
|
#include <ctype.h> |
#include <stdio.h> |
#include <stdio.h> |
#include <stdlib.h> |
#include <stdlib.h> |
#include <stdarg.h> |
#include <stdarg.h> |
|
|
#include "cvsd.h" |
#include "cvsd.h" |
#include "cvs.h" |
#include "cvs.h" |
#include "log.h" |
#include "log.h" |
#include "event.h" |
#include "file.h" |
|
|
|
|
#define CVS_ACL_MAXRULES 256 |
#define CVS_ACL_MAXRULES 256 |
|
|
#define CVS_ACL_DENY 0 |
#define CVS_ACL_DENY 0 |
|
|
|
|
|
|
int lgetc (FILE *); |
int lgetc (FILE *); |
|
int lungetc (int, FILE *); |
|
|
|
|
int yyerror (const char *, ...); |
int yyerror (const char *, ...); |
|
|
u_int cvs_acl_matchpath (const char *, const char *); |
u_int cvs_acl_matchpath (const char *, const char *); |
|
|
|
|
|
/* parse buffer for easier macro expansion */ |
|
static char *conf_pbuf = NULL; |
|
static int conf_pbind = 0; |
|
|
|
|
|
|
static const char *conf_file; |
static const char *conf_file; |
static FILE *conf_fin; |
static FILE *conf_fin; |
static int conf_lineno = 1; |
static int conf_lineno = 1; |
|
|
} |
} |
; |
; |
|
|
directive : LISTEN address { cvsd_set(CVSD_SET_ADDR, $2); } |
directive : LISTEN address |
|
{ |
|
cvsd_set(CVSD_SET_ADDR, $2); |
|
free($2); |
|
} |
| CVSROOT STRING |
| CVSROOT STRING |
{ |
{ |
cvsd_set(CVSD_SET_ROOT, $2); |
cvsd_set(CVSD_SET_ROOT, $2); |
|
|
{ |
{ |
int c; |
int c; |
|
|
|
/* check if we've got something in the parse buffer first */ |
|
if (conf_pbuf != NULL) { |
|
c = conf_pbuf[conf_pbind++]; |
|
if (c != '\0') |
|
return (c); |
|
|
|
free(conf_pbuf); |
|
conf_pbuf = NULL; |
|
conf_pbind = 0; |
|
} |
|
|
c = getc(f); |
c = getc(f); |
if ((c == '\t') || (c == ' ')) { |
if ((c == '\t') || (c == ' ')) { |
do { |
do { |
c = getc(f); |
c = getc(f); |
} while ((c == ' ') || (c == '\t')); |
} while ((c == ' ') || (c == '\t')); |
ungetc(c, f); |
lungetc(c, f); |
c = ' '; |
c = ' '; |
} |
} |
else if (c == '\\') |
else if (c == '\\') |
|
|
|
|
|
|
int |
int |
|
lungetc(int c, FILE *f) |
|
{ |
|
if ((conf_pbuf != NULL) && (conf_pbind > 0)) { |
|
conf_pbind--; |
|
return (0); |
|
} |
|
|
|
return ungetc(c, f); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int |
yylex(void) |
yylex(void) |
{ |
{ |
int c; |
int c; |
char buf[1024], *bp, *ep; |
char buf[1024], *bp, *ep; |
|
const char *mval; |
|
|
|
lex_start: |
bp = buf; |
bp = buf; |
ep = buf + sizeof(buf) - 1; |
ep = buf + sizeof(buf) - 1; |
|
|
|
|
c = lgetc(conf_fin); |
c = lgetc(conf_fin); |
} while ((c != '\n') && (c != EOF)); |
} while ((c != '\n') && (c != EOF)); |
} |
} |
else if (c == EOF) |
|
|
if (c == EOF) |
c = 0; |
c = 0; |
else if (c == '\n') |
else if (c == '\n') |
conf_lineno++; |
yylval.lineno = conf_lineno++; |
else if (c != ',') { |
else if (c == '$') { |
|
c = lgetc(conf_fin); |
do { |
do { |
*bp++ = c; |
*bp++ = (char)c; |
if (bp == ep) { |
if (bp == ep) { |
|
yyerror("macro name too long"); |
|
return (-1); |
|
} |
|
c = lgetc(conf_fin); |
|
} while (isalnum(c) || c == '_'); |
|
lungetc(c, conf_fin); |
|
*bp = '\0'; |
|
|
|
mval = cvs_conf_getmacro(buf); |
|
if (mval == NULL) { |
|
yyerror("undefined macro `%s'", buf); |
|
return (-1); |
|
} |
|
|
|
conf_pbuf = strdup(mval); |
|
conf_pbind = 0; |
|
goto lex_start; |
|
} |
|
else if ((c == '=') || (c == ',')) |
|
; /* nothing */ |
|
else { |
|
do { |
|
*bp++ = (char)c; |
|
if (bp == ep) { |
yyerror("string too long"); |
yyerror("string too long"); |
return (-1); |
return (-1); |
} |
} |
|
|
c = lgetc(conf_fin); |
c = lgetc(conf_fin); |
if (c == EOF) |
|
break; |
|
} while ((c != EOF) && (c != ' ') && (c != '\n')); |
} while ((c != EOF) && (c != ' ') && (c != '\n')); |
ungetc(c, conf_fin); |
lungetc(c, conf_fin); |
*bp = '\0'; |
*bp = '\0'; |
c = lookup(buf); |
c = lookup(buf); |
if (c == STRING) { |
if (c == STRING) { |
|
|
} |
} |
|
|
/* these strings were already dup'ed by the lexer */ |
/* these strings were already dup'ed by the lexer */ |
printf("macro(%s) = `%s'\n", macro, val); |
|
cmp->cm_name = macro; |
cmp->cm_name = macro; |
cmp->cm_val = val; |
cmp->cm_val = val; |
|
|
|
|
cvs_acl_eval(struct cvs_op *op) |
cvs_acl_eval(struct cvs_op *op) |
{ |
{ |
u_int res; |
u_int res; |
struct acl_rule *arp; |
CVSFILE *cf; |
|
struct acl_rule *rule; |
|
|
/* deny by default */ |
/* deny by default */ |
res = acl_defact; |
res = acl_defact; |
|
|
TAILQ_FOREACH(arp, &acl_rules, ar_list) { |
TAILQ_FOREACH(rule, &acl_rules, ar_list) { |
if (((op->co_op != CVS_OP_ANY) && (op->co_op != arp->ar_op)) || |
if (((op->co_op != CVS_OP_ANY) && (op->co_op != rule->ar_op)) || |
!cvs_acl_matchuid(arp, op->co_uid) || |
!cvs_acl_matchuid(rule, op->co_uid) || |
!cvs_acl_matchtag(op->co_tag, arp->ar_tag) || |
!cvs_acl_matchtag(op->co_tag, rule->ar_tag)) |
!cvs_acl_matchpath(op->co_path, arp->ar_path)) |
|
continue; |
continue; |
|
|
res = arp->ar_act; |
/* see if one of the files has a matching path */ |
|
TAILQ_FOREACH(cf, &(op->co_files), cf_list) |
|
if (!cvs_acl_matchpath(cf->cf_path, rule->ar_path)) |
|
continue; |
|
|
if (arp->ar_opts & CVS_ACL_LOGOPT) |
res = rule->ar_act; |
cvs_log(LP_WARN, "act=%u, path=%s, tag=%s, uid=%u", |
|
op->co_op, op->co_path, op->co_tag, op->co_uid); |
if (rule->ar_opts & CVS_ACL_LOGOPT) |
if (arp->ar_opts & CVS_ACL_QUICKOPT) |
cvs_log(LP_WARN, "act=%u, tag=%s, uid=%u", |
|
op->co_op, op->co_tag, op->co_uid); |
|
if (rule->ar_opts & CVS_ACL_QUICKOPT) |
break; |
break; |
} |
} |
|
|
|
|
return (0); |
return (0); |
} |
} |
|
|
printf("comparing `%s' to `%s'\n", rop_path, acl_path); |
|
len = strlen(rop_path); |
len = strlen(rop_path); |
|
|
if (strncmp(rop_path, acl_path, len) == 0) |
if (strncmp(rop_path, acl_path, len) == 0) |