Fix limits on reading user policy files.
[yaid] / yaid.h
... / ...
CommitLineData
1/* -*-c-*-
2 *
3 * Common definitions for YAID
4 *
5 * (c) 2012 Straylight/Edgeware
6 */
7
8/*----- Licensing notice --------------------------------------------------*
9 *
10 * This file is part of Yet Another Ident Daemon (YAID).
11 *
12 * YAID is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * YAID is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with YAID; if not, write to the Free Software Foundation,
24 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 */
26
27#ifndef YAID_H
28#define YAID_H
29
30#ifdef __cplusplus
31 extern "C" {
32#endif
33
34/*----- Header files ------------------------------------------------------*/
35
36#include "config.h"
37
38#include <assert.h>
39#include <ctype.h>
40#include <errno.h>
41#include <limits.h>
42#include <stdarg.h>
43#include <stdio.h>
44#include <string.h>
45#include <string.h>
46#include <time.h>
47
48#include <sys/types.h>
49#include <sys/time.h>
50#include <unistd.h>
51#include <fcntl.h>
52
53#include <grp.h>
54#include <pwd.h>
55
56#include <sys/socket.h>
57#include <netinet/in.h>
58#include <arpa/inet.h>
59#include <netdb.h>
60
61#include <syslog.h>
62
63#include <mLib/bits.h>
64#include <mLib/conn.h>
65#include <mLib/daemonize.h>
66#include <mLib/darray.h>
67#include <mLib/dstr.h>
68#include <mLib/fdflags.h>
69#include <mLib/fwatch.h>
70#include <mLib/mdwopt.h>
71#include <mLib/quis.h>
72#include <mLib/report.h>
73#include <mLib/sel.h>
74#include <mLib/selbuf.h>
75#include <mLib/sig.h>
76
77/*----- Address family handling -------------------------------------------*/
78
79/* The maximum length of an address formatted as a text string, including the
80 * terminating null byte.
81 */
82#define ADDRLEN 64
83
84/* A list of address types. */
85#define ADDRTYPES(_) \
86 _(ipv4, IPV4) \
87 _(ipv6, IPV6)
88
89/* Address types for the various families, in the form acceptable to
90 * inet_ntop(3) and inet_pton(3). */
91#define TYPE_IPV4 struct in_addr
92#define TYPE_IPV6 struct in6_addr
93
94/* A union of address types. */
95union addr {
96#define UMEMB(ty, TY) TYPE_##TY ty;
97 ADDRTYPES(UMEMB)
98#undef UMEMB
99};
100
101/* A socket holds an address and a port number. */
102struct socket {
103 union addr addr; /* The address */
104 unsigned port; /* The port, in /host/ byte order */
105};
106
107/* An address pattern consists of an address and a prefix length: the
108 * pattern matches an address if they agree in the first LEN bits.
109 */
110struct addrpat {
111 union addr addr; /* The base address */
112 unsigned len; /* The prefix length */
113};
114
115/* A port pattern matches a port if the port is within the stated (inclusive)
116 * bounds.
117 */
118struct portpat {
119 unsigned lo, hi;
120};
121
122/* A socket pattern consists simply of an address pattern and a port pattern:
123 * it matches a socket componentwise.
124 */
125struct sockpat {
126 struct addrpat addr;
127 struct portpat port;
128};
129
130/* The table of address-type operations. Each address family has one of
131 * these, so that most of the program doesn't need to worry about these
132 * details.
133 */
134struct addrops {
135 int af; /* The AF_* constant */
136 const char *name; /* Name of the protocol, for logs */
137 unsigned len; /* Length of an address, in bits */
138 const union addr *any; /* A wildcard address */
139 const struct addrops_sys *sys; /* Pointer to system-specific ops */
140
141 int (*addreq)(const union addr *, const union addr *);
142 /* Return nonzero if the two addresses are equal. */
143
144 int (*match_addrpat)(const struct addrpat *, const union addr *);
145 /* Return nonzero if the pattern matches the address. */
146
147 void (*socket_to_sockaddr)(const struct socket *s, void *, size_t *);
148 /* Convert a socket structure to a `struct sockaddr', and return the
149 * size of the latter.
150 */
151
152 void (*sockaddr_to_addr)(const void *, union addr *);
153 /* Extract the address from a `struct sockaddr'. */
154
155 int (*init_listen_socket)(int);
156 /* Perform any necessary extra operations on a socket which is going
157 * to be used to listen for incoming connections.
158 */
159};
160
161/* A handy constant for each address family. These are more useful than the
162 * AF_* constants in that they form a dense sequence.
163 */
164enum {
165#define DEFADDR(ty, TY) ADDR_##TY,
166 ADDRTYPES(DEFADDR)
167#undef DEFADDR
168 ADDR_LIMIT
169};
170
171/* The table of address operations, indexed by the ADDR_* constants defined
172 * just above.
173 */
174extern const struct addrops addroptab[];
175
176/* System-specific operations, provided by the system-specific code for its
177 * own purposes.
178 */
179#define OPS_SYS(ty, TY) \
180 extern const struct addrops_sys addrops_sys_##ty;
181ADDRTYPES(OPS_SYS)
182#undef OPS_SYS
183
184/* Answer whether the sockets SA and SB are equal. */
185extern int sockeq(const struct addrops */*ao*/,
186 const struct socket */*sa*/, const struct socket */*sb*/);
187
188/* Write a textual description of S to the string D. */
189extern void dputsock(dstr */*d*/, const struct addrops */*ao*/,
190 const struct socket */*s*/);
191
192/*----- Queries and responses ---------------------------------------------*/
193
194/* Constants for describing the `L'ocal and `R'emote ends of a connection. */
195enum { L, R, NDIR };
196
197/* Response types, and the data needed to represent any associated data. A
198 * U_(MEMB, TYPE) constructs a union member; an N_ means no associated data.
199 */
200#define RESPONSE(_) \
201 _(ERROR, U_(error, unsigned)) \
202 _(UID, U_(uid, uid_t)) \
203 _(NAT, U_(nat, struct socket))
204
205enum {
206#define DEFENUM(what, branch) R_##what,
207 RESPONSE(DEFENUM)
208#undef DEFENUM
209 R_LIMIT
210};
211
212/* Protocol error tokens. */
213#define ERROR(_) \
214 _(INVPORT, "INVALID-PORT") \
215 _(NOUSER, "NO-USER") \
216 _(HIDDEN, "HIDDEN-USER") \
217 _(UNKNOWN, "UNKNOWN-ERROR")
218
219enum {
220#define DEFENUM(err, tok) E_##err,
221 ERROR(DEFENUM)
222#undef DEFENUM
223 E_LIMIT
224};
225
226extern const char *const errtok[];
227
228/* The query structure keeps together the parameters to the client's query
229 * and our response to it.
230 */
231struct query {
232 const struct addrops *ao; /* Address family operations */
233 struct socket s[NDIR]; /* The local and remote ends */
234 unsigned resp; /* Our response type */
235 union { /* A union of response data */
236#define DEFBRANCH(WHAT, branch) branch
237#define U_(memb, ty) ty memb;
238#define N_
239 RESPONSE(DEFBRANCH)
240#undef U_
241#undef N_
242#undef DEFBRANCH
243 } u;
244} query;
245
246/*----- Common utility functions ------------------------------------------*/
247
248/* Format and log MSG somewhere sensible, at the syslog(3) priority PRIO.
249 * Prefix it with a description of the query Q, if non-null.
250 */
251extern void logmsg(const struct query */*q*/,
252 int /*prio*/, const char */*msg*/, ...);
253
254/*----- System-specific connection identification code --------------------*/
255
256/* Find out who is responsible for the connection described in the query Q.
257 * Write the answer to Q. Errors are logged and reported via the query
258 * structure.
259 */
260extern void identify(struct query */*q*/);
261
262/* Initialize the system-specific code. */
263extern void init_sys(void);
264
265/*----- Policy management -------------------------------------------------*/
266
267/* The possible policy actions and their names. */
268#define ACTIONS(_) \
269 _(USER, "user") \
270 _(TOKEN, "token") \
271 _(NAME, "name") \
272 _(DENY, "deny") \
273 _(HIDE, "hide") \
274 _(LIE, "lie")
275
276enum {
277#define DEFENUM(tag, word) A_##tag,
278 ACTIONS(DEFENUM)
279#undef DEFENUM
280 A_LIMIT
281};
282
283/* A policy action. */
284struct action {
285 unsigned act;
286 union {
287 unsigned user; /* Bitmask of permitted actions */
288 char *lie; /* The user name to impersonate */
289 } u;
290};
291
292/* A user pattern matches a user if the uid is within the given bounds. */
293struct userpat {
294 unsigned lo, hi;
295};
296
297/* A policy rule: if the query matches the pattern, then perform the
298 * action.
299 */
300struct policy {
301 const struct addrops *ao;
302 struct sockpat sp[NDIR];
303 struct userpat up;
304 struct action act;
305};
306#define POLICY_INIT(a) { .act.act = a }
307DA_DECL(policy_v, struct policy);
308
309/* Initialize a policy structure. In this state, it doesn't actually have
310 * any resources allocated (so can be simply discarded) but it's safe to free
311 * (using `free_policy').
312 */
313extern void init_policy(struct policy */*p*/);
314
315/* Free a policy structure, resetting it to its freshly-initialized state.
316 * This function is idempotent.
317 */
318extern void free_policy(struct policy */*p*/);
319
320/* Print a policy rule to standard output. */
321extern void print_policy(const struct policy */*p*/);
322
323/* Return true if the query matches the patterns in the policy rule. */
324extern int match_policy(const struct policy */*p*/,
325 const struct query */*q*/);
326
327/*----- Parsing policy files ----------------------------------------------*/
328
329/* Possible results from a parse. */
330enum {
331 T_OK, /* Successful: results returned */
332 T_EOL, /* End-of-line found immediately */
333 T_ERROR, /* Some kind of error occurred */
334 T_EOF /* End-of-file found immediately */
335};
336
337/* A context for parsing a policy file. */
338struct policy_file {
339 FILE *fp; /* The file to read from */
340 const struct query *q; /* A query to use for logging */
341 const char *name; /* The name of the file */
342 const char *what; /* A description of the file */
343 int err; /* Have there been any errors? */
344 int lno; /* The current line number */
345 struct policy p; /* Parsed policy rule goes here */
346};
347
348/* Open a policy file by NAME. The description WHAT and query Q are used for
349 * formatting error messages for the log.
350 */
351extern int open_policy_file(struct policy_file */*pf*/, const char */*name*/,
352 const char */*what*/, const struct query */*q*/,
353 unsigned /*f*/);
354#define OPF_NOENTOK 1u /* Don't complain if file missing */
355
356/* Read a policy rule from the file, storing it in PF->p. Return one of the
357 * T_* codes.
358 */
359extern int read_policy_file(struct policy_file */*pf*/);
360
361/* Close a policy file. It doesn't matter whether the file was completely
362 * read.
363 */
364extern void close_policy_file(struct policy_file */*pf*/);
365
366/* Load a policy file, writing a vector of records into PV. If the policy
367 * file has errors, then leave PV unchanged and return nonzero.
368 */
369extern int load_policy_file(const char */*file*/, policy_v */*pv*/);
370
371/*----- That's all, folks -------------------------------------------------*/
372
373#ifdef __cplusplus
374 }
375#endif
376
377#endif