1 %{ 2 #include <stdio.h> 3 #include <grp.h> 4 #include "doinkd.h" 5 #include <pwd.h> 6 7 #ifndef DEBUG 8 #define DEBUG 0 9 #endif 10 11 #define debug if (DEBUG > 0) logfile 12 13 int num; 14 char *name; 15 struct group *grp; 16 17 extern char *yytext; 18 19 extern char *config_file; /* The name of the config file, from doinkd.c */ 20 extern char *strchr(); 21 extern void addlist(); 22 23 /************************************************************************ 24 * The order of the tokens in the *first line* is significant. * 25 * * 26 * They dictate which rules and exemptions have precedence. * 27 * Hence, TTY has precedence over HOST has precedence over LOGIN, etc. * 28 * * 29 * The second two %token lines may be ordered anyway. * 30 * DEFAULT is the least specific, but will always match. * 31 * It must always remain in the last position. * 32 ************************************************************************/ 33 %} 34 35 %token TTY HOST LOGIN GROUP FILECOM DEFAULT 36 37 %token EXEMPT TIMEOUT SLEEP WARN IDLEMETHOD CONSWINS SESSION REFUSE MULTIPLES MAXUSER 38 %token NUM IDLE MULTIPLE NAME ALL 39 %token THRESHOLD NL 40 %token USERINPUT INPUTOUTPUT 41 %token NORMAL OFF 42 43 %union { 44 char *sb; 45 int nb; 46 } 47 48 %type <sb> NAME 49 %type <nb> NUM LOGIN GROUP TTY ALL IDLE MULTIPLE 50 %type <nb> who exempt_type name_type 51 52 %start cmd_cmd 53 54 %% 55 56 cmd_cmd : /*EMPTY*/ 57 | cmd_cmd exempt_cmd 58 | cmd_cmd idle_cmd 59 | cmd_cmd refuse_cmd 60 | cmd_cmd sleep_cmd 61 | cmd_cmd warn_cmd 62 | cmd_cmd idlemethod_cmd 63 | cmd_cmd conswins_cmd 64 | cmd_cmd session_cmd 65 | cmd_cmd thresh_cmd 66 | cmd_cmd mult_cmd 67 | cmd_cmd maxuser_cmd 68 | cmd_cmd error NL 69 | cmd_cmd NL 70 ; 71 72 thresh_cmd : THRESHOLD MULTIPLE NUM NL 73 { 74 m_threshold = $3; 75 } 76 | THRESHOLD SESSION NUM NL 77 { 78 s_threshold = $3; 79 } 80 | THRESHOLD error NL 81 { 82 yyerror("Malformed threshold command."); 83 } 84 ; 85 86 87 exempt_cmd : EXEMPT who exempt_type NL 88 { 89 addlist(exmpt, $2, name, num, $3); 90 } 91 | EXEMPT FILECOM NAME exempt_type NL 92 { 93 filecom_parse(EXEMPT,$3,$4); 94 } 95 | EXEMPT error NL 96 { 97 yyerror("Malformed exempt command."); 98 } 99 ; 100 101 refuse_cmd : REFUSE who NL 102 { 103 addlist(refuse, $2, name, num, 0); 104 } 105 | REFUSE FILECOM NAME NL 106 { 107 filecom_parse(REFUSE,$3,/* time or thing if any */0); 108 } 109 | REFUSE error NL 110 { 111 yyerror("Malformed refuse command."); 112 } 113 ; 114 115 session_cmd : SESSION who NUM NL 116 { 117 addlist(session, $2, name, num, $3); 118 } 119 | SESSION FILECOM NAME NUM NL 120 { 121 filecom_parse(SESSION,$3,$4); 122 } 123 | SESSION DEFAULT NUM NL 124 { 125 session_default = $3; 126 } 127 | SESSION REFUSE NUM NL 128 { 129 sess_refuse_len = $3 * 60; 130 } 131 | SESSION error NL 132 { 133 yyerror("Malformed session command."); 134 } 135 ; 136 137 idle_cmd : TIMEOUT who NUM NL 138 { 139 addlist(rules, $2, name, num, $3); 140 } 141 | TIMEOUT FILECOM NAME NUM NL 142 { 143 filecom_parse(TIMEOUT,$3,$4); 144 } 145 | TIMEOUT DEFAULT NUM NL 146 { 147 addlist(rules, DEFAULT, NULL, 0, $3); 148 } 149 | TIMEOUT error NL 150 { 151 yyerror("Malformed timeout command."); 152 } 153 ; 154 155 sleep_cmd : SLEEP NUM NL 156 { 157 sleeptime = $2; 158 } 159 | SLEEP error NL 160 { 161 yyerror("Malformed sleep command."); 162 } 163 ; 164 165 warn_cmd : WARN NUM NL 166 { 167 warntime = $2; 168 } 169 | WARN error NL 170 { 171 yyerror("Malformed warn command."); 172 } 173 ; 174 175 idlemethod_cmd : IDLEMETHOD USERINPUT NL 176 { 177 ioidle = FALSE; 178 } 179 | IDLEMETHOD INPUTOUTPUT NL 180 { 181 ioidle = TRUE; 182 } 183 | IDLEMETHOD error NL 184 { 185 yyerror("Malformed idlemethod command."); 186 } 187 ; 188 189 conswins_cmd : CONSWINS IDLE NUM NL 190 { 191 conswins_idle = $3 * 60; 192 } 193 | CONSWINS IDLE NORMAL NL 194 { 195 conswins_idle = -2; 196 } 197 | CONSWINS IDLE OFF NL 198 { 199 conswins_idle = -1; 200 } 201 | CONSWINS SESSION NUM NL 202 { 203 conswins_sess = $3 * 60; 204 } 205 | CONSWINS SESSION NORMAL NL 206 { 207 conswins_sess = -2; 208 } 209 | CONSWINS SESSION OFF NL 210 { 211 conswins_sess = -1; 212 } 213 | CONSWINS MULTIPLE NUM NL 214 { 215 conswins_mult = $3; 216 } 217 | CONSWINS MULTIPLE NORMAL NL 218 { 219 conswins_mult = -2; 220 } 221 | CONSWINS MULTIPLE OFF NL 222 { 223 conswins_mult = -1; 224 } 225 | CONSWINS error NL 226 { 227 yyerror("Malformed cons(ole) win(dow)s command."); 228 } 229 ; 230 231 mult_cmd : MULTIPLES NUM NL 232 { 233 mult_per_user = $2; 234 } 235 | MULTIPLES error NL 236 { 237 yyerror("Malformed multiples command."); 238 } 239 ; 240 maxuser_cmd : MAXUSER who NUM NL 241 { 242 addlist(maxuser, $2, name, num, $3); 243 } 244 | MAXUSER FILECOM NAME NUM NL 245 { 246 filecom_parse(MAXUSER,$3,$4); 247 } 248 | MAXUSER error NL 249 { 250 yyerror("Malformed maxuser command."); 251 } 252 ; 253 254 who : name_type NAME 255 { 256 $$ = $1; 257 name = $2; 258 259 if ($1 == GROUP) 260 { 261 grp = getgrnam(name); 262 if (grp != NULL) 263 num = grp->gr_gid; 264 else 265 logfile("Error parsing conf file: unknown group name '%s'.",name); 266 } 267 if ($1 == LOGIN) 268 { 269 if (getpwnam(name) == NULL) 270 logfile("Warning parsing conf file: unknown login name '%s'.",name); 271 } 272 } 273 ; 274 275 name_type : LOGIN { $$ = LOGIN; } 276 | HOST { $$ = HOST; } 277 | GROUP { $$ = GROUP; } 278 | TTY { $$ = TTY; } 279 ; 280 281 exempt_type : ALL { $$ = ALL; } 282 | IDLE { $$ = IDLE; } 283 | MULTIPLE { $$ = MULTIPLE; } 284 | REFUSE { $$ = REFUSE; } 285 | SESSION { $$ = SESSION; } 286 ; 287 288 %% 289 290 static int errorcnt = 0; 291 292 293 294 int 295 yyerror(sb) 296 char *sb; 297 { 298 extern int linenum; 299 300 logfile("%s: line %d: %s", config_file, linenum, sb); 301 errorcnt++; 302 return 0; 303 } 304 305 306 307 int 308 yywrap() 309 { 310 extern int linenum; 311 extern time_t conf_oldstamp; 312 313 if ( errorcnt > 0 && conf_oldstamp <= 1 ) 314 { 315 logfile("Aborting due to conf file syntax errors."); 316 exit(1); 317 } 318 319 linenum = 1; 320 return 1; 321 } 322 323 #ifndef HAVE_YYRESTART 324 void yyrestart(handle) 325 FILE *handle; 326 { 327 extern int linenum; 328 329 linenum = 1; 330 } 331 #endif 332 333 /************************************************************************** 334 * Reads in more rules from a separate file, which contains the * 335 * login names of the users for that type, one per line. * 336 **************************************************************************/ 337 void filecom_parse(type,filename,param) 338 int type; /* REFUSE, SESSION, TIMEOUT, or EXEMPT */ 339 char *filename; 340 int param; /* idle/session time or exempt type */ 341 { 342 FILE *handle; 343 handle = fopen(filename,"r"); 344 if (handle == NULL) 345 { 346 char *buffer; 347 buffer = (char *) malloc(20+sizeof(filename)); 348 sprintf(buffer,"Could not open file '%s'",filename); 349 yyerror(buffer); 350 free(buffer); 351 } 352 else 353 { 354 char lname[NAMELEN+1], trash[100], *c; 355 while (!feof(handle) && (fgets(lname,NAMELEN+1,handle) != NULL)) 356 { 357 /* If we didn't read in the newline, do so now */ 358 if (strchr(lname,'\n') == NULL) 359 fscanf(handle,"%[^\n]\n",trash); 360 361 /* First, strip away beyond the first space or newline */ 362 c = strchr(lname,' '); if (c != NULL) *c = '\0'; 363 c = strchr(lname,'\n'); if (c != NULL) *c = '\0'; 364 365 if ((int)strlen(lname) > 0) 366 { 367 char *username; 368 username = (char *) malloc (strlen(lname)+1); 369 strcpy(username,lname); 370 switch(type) 371 { 372 case REFUSE: 373 debug("Refusing user %s.",username); 374 addlist(refuse, LOGIN, username, 0, 0); 375 break; 376 case MAXUSER: 377 debug("MaxUser Limiting group %s to %d logins.",username,param); 378 addlist(maxuser, GROUP, username, 0, param); 379 break; 380 case SESSION: 381 debug("Session Limiting user %s to %d minutes.",username,param); 382 addlist(session, LOGIN, username, 0, param); 383 break; 384 case TIMEOUT: 385 debug("Setting Idle timeout for user %s to %d minutes.",username,param); 386 addlist(rules, LOGIN, username, 0, param); 387 break; 388 case EXEMPT: 389 debug("Exempting user %s from type %d.",username,param); 390 addlist(exmpt, LOGIN, username, 0, param); 391 break; 392 } 393 } 394 } 395 } 396 } 397 398