#include <stdio.h>
#include <string.h>
#include <string.h>
+#include <time.h>
#include <sys/types.h>
+#include <sys/time.h>
#include <unistd.h>
#include <fcntl.h>
+#include <grp.h>
#include <pwd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
+#include <netdb.h>
#include <syslog.h>
#include <mLib/bits.h>
#include <mLib/conn.h>
+#include <mLib/daemonize.h>
#include <mLib/darray.h>
#include <mLib/dstr.h>
#include <mLib/fdflags.h>
#include <mLib/fwatch.h>
+#include <mLib/macros.h>
+#include <mLib/mdwopt.h>
#include <mLib/quis.h>
#include <mLib/report.h>
#include <mLib/sel.h>
#include <mLib/selbuf.h>
+#include <mLib/sig.h>
/*----- Address family handling -------------------------------------------*/
enum { L, R, NDIR };
/* Response types, and the data needed to represent any associated data. A
- * U(MEMB, TYPE) constructs a union member; an N means no associated data.
+ * U_(MEMB, TYPE) constructs a union member; an N_ means no associated data.
*/
#define RESPONSE(_) \
- _(ERROR, U(error, unsigned)) \
- _(UID, U(uid, uid_t)) \
- _(NAT, U(nat, struct socket))
+ _(ERROR, U_(error, unsigned)) \
+ _(UID, U_(uid, uid_t)) \
+ _(NAT, U_(nat, struct socket))
enum {
#define DEFENUM(what, branch) R_##what,
unsigned resp; /* Our response type */
union { /* A union of response data */
#define DEFBRANCH(WHAT, branch) branch
-#define U(memb, ty) ty memb;
-#define N
+#define U_(memb, ty) ty memb;
+#define N_
RESPONSE(DEFBRANCH)
-#undef U
-#undef N
+#undef U_
+#undef N_
#undef DEFBRANCH
} u;
} query;
/* Format and log MSG somewhere sensible, at the syslog(3) priority PRIO.
* Prefix it with a description of the query Q, if non-null.
*/
-extern void logmsg(const struct query */*q*/,
- int /*prio*/, const char */*msg*/, ...);
+extern void PRINTF_LIKE(3, 4)
+ logmsg(const struct query */*q*/, int /*prio*/, const char */*msg*/, ...);
/*----- System-specific connection identification code --------------------*/
} u;
};
+/* A user pattern matches a user if the uid is within the given bounds. */
+struct userpat {
+ unsigned lo, hi;
+};
+
/* A policy rule: if the query matches the pattern, then perform the
* action.
*/
struct policy {
const struct addrops *ao;
struct sockpat sp[NDIR];
+ struct userpat up;
struct action act;
};
#define POLICY_INIT(a) { .act.act = a }
enum {
T_OK, /* Successful: results returned */
T_EOL, /* End-of-line found immediately */
- T_EOF, /* End-of-file found immediately */
- T_ERROR /* Some kind of error occurred */
+ T_ERROR, /* Some kind of error occurred */
+ T_EOF /* End-of-file found immediately */
};
/* A context for parsing a policy file. */
* formatting error messages for the log.
*/
extern int open_policy_file(struct policy_file */*pf*/, const char */*name*/,
- const char */*what*/, const struct query */*q*/);
+ const char */*what*/, const struct query */*q*/,
+ unsigned /*f*/);
+#define OPF_NOENTOK 1u /* Don't complain if file missing */
/* Read a policy rule from the file, storing it in PF->p. Return one of the
* T_* codes.