PageRenderTime 38ms CodeModel.GetById 9ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/users.y

#
Happy | 374 lines | 326 code | 48 blank | 0 comment | 0 complexity | 041a808d2def40453ac8a7bd31e17f0f MD5 | raw file
Possible License(s): GPL-3.0, CC-BY-SA-3.0, LGPL-3.0
  1. %{
  2. /* This file is part of GNU Radius.
  3. Copyright (C) 2000, 2001, 2002, 2003, 2004, 2007, 2008, 2010, 2013 Free
  4. Software Foundation, Inc.
  5. Written by Sergey Poznyakoff
  6. GNU Radius is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 3 of the License, or
  9. (at your option) any later version.
  10. GNU Radius is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with GNU Radius. If not, see <http://www.gnu.org/licenses/>. */
  16. #if defined(HAVE_CONFIG_H)
  17. # include <config.h>
  18. #endif
  19. #include <sys/types.h>
  20. #include <sys/socket.h>
  21. #include <sys/time.h>
  22. #include <sys/file.h>
  23. #include <sys/stat.h>
  24. #include <netinet/in.h>
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #include <netdb.h>
  28. #include <fcntl.h>
  29. #include <ctype.h>
  30. #include <unistd.h>
  31. #include <signal.h>
  32. #include <errno.h>
  33. #include <sys/wait.h>
  34. #include <radlib.h>
  35. #include "intprops.h"
  36. #define YYMAXDEPTH 10
  37. static grad_locus_t start_loc;
  38. static void *closure;
  39. static register_rule_fp add_entry;
  40. static grad_avp_t *grad_create_pair0(char *name, int op, char *valstr);
  41. int yyerror(char *s);
  42. extern int yylex();
  43. %}
  44. %token EQ LT GT NE LE GE
  45. %token NUL
  46. %token BOGUS
  47. %token <string> STRING QUOTE
  48. %type <string> user value
  49. %type <descr> descr
  50. %type <pair> npairlist pairlist pair
  51. %type <rule> entry
  52. %type <op> op
  53. %start input
  54. %union {
  55. char *string;
  56. grad_matching_rule_t *rule;
  57. struct {
  58. grad_avp_t *lhs, *rhs;
  59. } descr;
  60. grad_avp_t *pair;
  61. enum grad_operator op;
  62. }
  63. %%
  64. input : /* empty */
  65. | list
  66. ;
  67. list : entry
  68. {
  69. }
  70. | list entry
  71. | list error
  72. {
  73. grad_parser_lex_sync(); yyerrok; yyclearin;
  74. }
  75. ;
  76. entry : user descr
  77. {
  78. add_entry(closure, &start_loc, $1, $2.lhs, $2.rhs);
  79. }
  80. | user error
  81. {
  82. grad_log(GRAD_LOG_ERR, _("discarding user `%s'"), $1);
  83. if (grad_parser_lex_sync() <= 0)
  84. yychar = 0; /* force end-of-file */
  85. else {
  86. yyerrok;
  87. yyclearin;
  88. }
  89. }
  90. ;
  91. user : value
  92. {
  93. start_loc = grad_parser_source_locus;
  94. }
  95. ;
  96. descr : npairlist npairlist
  97. {
  98. $$.lhs = $1;
  99. $$.rhs = $2;
  100. }
  101. ;
  102. npairlist: NUL
  103. {
  104. $$ = NULL;
  105. }
  106. | pairlist
  107. ;
  108. pairlist : pair
  109. | pairlist ',' pair
  110. {
  111. if ($1) {
  112. if ($3)
  113. grad_avl_add_list(&$1, $3);
  114. $$ = $1;
  115. } else
  116. $$ = $3;
  117. }
  118. ;
  119. pair : STRING op value
  120. {
  121. $$ = grad_create_pair0($1, $2, $3);
  122. }
  123. | STRING op BOGUS
  124. {
  125. YYERROR;
  126. }
  127. ;
  128. op : EQ
  129. {
  130. $$ = grad_operator_equal;
  131. }
  132. | LT
  133. {
  134. $$ = grad_operator_less_than;
  135. }
  136. | GT
  137. {
  138. $$ = grad_operator_greater_than;
  139. }
  140. | NE
  141. {
  142. $$ = grad_operator_not_equal;
  143. }
  144. | LE
  145. {
  146. $$ = grad_operator_less_equal;
  147. }
  148. | GE
  149. {
  150. $$ = grad_operator_greater_equal;
  151. }
  152. ;
  153. value : STRING
  154. | QUOTE
  155. ;
  156. %%
  157. int
  158. yyerror(char *s)
  159. {
  160. grad_log_loc(GRAD_LOG_ERR, &grad_parser_source_locus, "%s", s);
  161. return 0;
  162. }
  163. grad_avp_t *
  164. grad_create_pair0(char *name, int op, char *valstr)
  165. {
  166. return grad_create_pair(&grad_parser_source_locus, name, op, valstr);
  167. }
  168. grad_avp_t *
  169. grad_create_pair(grad_locus_t *loc, char *name,
  170. enum grad_operator op, char *valstr)
  171. {
  172. grad_dict_attr_t *attr = NULL;
  173. grad_dict_value_t *dval;
  174. grad_avp_t *pair, *pair2;
  175. char *s;
  176. int x;
  177. time_t timeval;
  178. struct tm *tm, tms;
  179. if ((attr = grad_attr_name_to_dict(name)) == NULL) {
  180. grad_log_loc(GRAD_LOG_ERR, loc, _("unknown attribute `%s'"),
  181. name);
  182. return NULL;
  183. }
  184. pair = grad_avp_alloc();
  185. pair->next = NULL;
  186. pair->name = attr->name;
  187. pair->attribute = attr->value;
  188. pair->type = attr->type;
  189. pair->prop = attr->prop;
  190. pair->operator = op;
  191. if (valstr[0] == '=') {
  192. pair->eval_type = grad_eval_interpret;
  193. pair->avp_strvalue = grad_estrdup(valstr+1);
  194. pair->avp_strlength = strlen(pair->avp_strvalue);
  195. return pair;
  196. }
  197. pair->eval_type = grad_eval_const;
  198. switch (pair->type) {
  199. case GRAD_TYPE_STRING:
  200. if (pair->attribute == DA_EXEC_PROGRAM ||
  201. pair->attribute == DA_EXEC_PROGRAM_WAIT) {
  202. if (valstr[0] != '/' && valstr[0] != '|') {
  203. grad_log_loc(GRAD_LOG_ERR, loc,
  204. _("%s: not an absolute pathname"),
  205. name);
  206. grad_avp_free(pair);
  207. return NULL;
  208. }
  209. }
  210. pair->avp_strvalue = grad_estrdup(valstr);
  211. pair->avp_strlength = strlen(pair->avp_strvalue);
  212. if (attr->parser && attr->parser(pair, &s)) {
  213. grad_log_loc(GRAD_LOG_ERR, loc,
  214. "%s %s: %s",
  215. _("attribute"),
  216. pair->name, s);
  217. free(s);
  218. grad_avp_free(pair);
  219. return NULL;
  220. }
  221. break;
  222. case GRAD_TYPE_INTEGER:
  223. /*
  224. * For DA_NAS_PORT_ID, allow a
  225. * port range instead of just a port.
  226. */
  227. if (attr->value == DA_NAS_PORT_ID) {
  228. for (s = valstr; *s; s++)
  229. if (!isdigit(*s))
  230. break;
  231. if (*s) {
  232. pair->type = GRAD_TYPE_STRING;
  233. pair->avp_strvalue = grad_estrdup(valstr);
  234. pair->avp_strlength = strlen(pair->avp_strvalue);
  235. break;
  236. }
  237. }
  238. if (isdigit(*valstr)) {
  239. pair->avp_lvalue = atoi(valstr);
  240. } else if ((dval = grad_value_name_to_value(valstr,
  241. pair->attribute))
  242. == NULL) {
  243. grad_avp_free(pair);
  244. grad_log_loc(GRAD_LOG_ERR, loc,
  245. _("value %s is not declared for attribute %s"),
  246. valstr, name);
  247. return NULL;
  248. } else {
  249. pair->avp_lvalue = dval->value;
  250. }
  251. break;
  252. case GRAD_TYPE_IPADDR:
  253. if (pair->attribute != DA_FRAMED_IP_ADDRESS) {
  254. pair->avp_lvalue = grad_ip_gethostaddr(valstr);
  255. } else {
  256. /*
  257. * We allow a "+" at the end to
  258. * indicate that we should add the
  259. * portno. to the IP address.
  260. */
  261. x = 0;
  262. if (valstr[0]) {
  263. for(s = valstr; s[1]; s++)
  264. ;
  265. if (*s == '+') {
  266. *s = 0;
  267. x = 1;
  268. }
  269. }
  270. pair->avp_lvalue = grad_ip_gethostaddr(valstr);
  271. if (x) {
  272. char *s;
  273. char buf[INT_BUFSIZE_BOUND(long)];
  274. grad_longtostr(pair->avp_lvalue,
  275. buf, sizeof buf);
  276. grad_astrcat(&s, buf, "+", "%{NAS-Port-Id}",
  277. NULL);
  278. pair->avp_strvalue = grad_estrdup(s);
  279. pair->avp_strlength = strlen(pair->avp_strvalue);
  280. pair->eval_type = grad_eval_interpret;
  281. free(s);
  282. }
  283. }
  284. break;
  285. case GRAD_TYPE_DATE:
  286. timeval = time(0);
  287. tm = localtime_r(&timeval, &tms);
  288. if (grad_parse_time_string(valstr, tm)) {
  289. grad_log_loc(GRAD_LOG_ERR, loc, _("%s: can't parse date"),
  290. name);
  291. grad_avp_free(pair);
  292. return NULL;
  293. }
  294. pair->avp_lvalue = (grad_uint32_t)grad_tm_to_epoch(tm);
  295. break;
  296. default:
  297. grad_log_loc(GRAD_LOG_ERR, loc,
  298. _("%s: unknown attribute type %d"),
  299. name, pair->type);
  300. grad_avp_free(pair);
  301. return NULL;
  302. }
  303. return pair;
  304. }
  305. extern int yydebug;
  306. int
  307. grad_parse_rule_file(char *file, void *c, register_rule_fp f)
  308. {
  309. int rc;
  310. if (grad_parser_lex_init(file))
  311. return -1;
  312. closure = c;
  313. add_entry = f;
  314. yydebug = 0;
  315. rc = yyparse();
  316. grad_parser_lex_finish();
  317. return rc;
  318. }
  319. void
  320. grad_enable_rule_debug(int val)
  321. {
  322. yydebug = val;
  323. grad_log_loc(GRAD_LOG_NOTICE, &grad_parser_source_locus,
  324. yydebug ? _("enabled userfile parser debugging") :
  325. _("disabled userfile parser debugging"));
  326. }