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