1/* Copyright (C) 2005 Red Hat, Inc. */
2
3struct semanage_port;
4struct semanage_port_key;
5typedef struct semanage_port_key record_key_t;
6typedef struct semanage_port record_t;
7#define DBASE_RECORD_DEFINED
8
9#include <stdlib.h>
10#include "port_internal.h"
11#include "debug.h"
12#include "handle.h"
13#include "database.h"
14
15int semanage_port_modify_local(semanage_handle_t * handle,
16			       const semanage_port_key_t * key,
17			       const semanage_port_t * data)
18{
19
20	dbase_config_t *dconfig = semanage_port_dbase_local(handle);
21	return dbase_modify(handle, dconfig, key, data);
22}
23
24int semanage_port_del_local(semanage_handle_t * handle,
25			    const semanage_port_key_t * key)
26{
27
28	dbase_config_t *dconfig = semanage_port_dbase_local(handle);
29	return dbase_del(handle, dconfig, key);
30}
31
32int semanage_port_query_local(semanage_handle_t * handle,
33			      const semanage_port_key_t * key,
34			      semanage_port_t ** response)
35{
36
37	dbase_config_t *dconfig = semanage_port_dbase_local(handle);
38	return dbase_query(handle, dconfig, key, response);
39}
40
41int semanage_port_exists_local(semanage_handle_t * handle,
42			       const semanage_port_key_t * key, int *response)
43{
44
45	dbase_config_t *dconfig = semanage_port_dbase_local(handle);
46	return dbase_exists(handle, dconfig, key, response);
47}
48
49int semanage_port_count_local(semanage_handle_t * handle,
50			      unsigned int *response)
51{
52
53	dbase_config_t *dconfig = semanage_port_dbase_local(handle);
54	return dbase_count(handle, dconfig, response);
55}
56
57int semanage_port_iterate_local(semanage_handle_t * handle,
58				int (*handler) (const semanage_port_t * record,
59						void *varg), void *handler_arg)
60{
61
62	dbase_config_t *dconfig = semanage_port_dbase_local(handle);
63	return dbase_iterate(handle, dconfig, handler, handler_arg);
64}
65
66int semanage_port_list_local(semanage_handle_t * handle,
67			     semanage_port_t *** records, unsigned int *count)
68{
69
70	dbase_config_t *dconfig = semanage_port_dbase_local(handle);
71	return dbase_list(handle, dconfig, records, count);
72}
73
74hidden_def(semanage_port_list_local)
75
76int hidden semanage_port_validate_local(semanage_handle_t * handle)
77{
78
79	semanage_port_t **ports = NULL;
80	unsigned int nports = 0;
81	unsigned int i = 0, j = 0;
82
83	/* List and sort the ports */
84	if (semanage_port_list_local(handle, &ports, &nports) < 0)
85		goto err;
86	qsort(ports, nports, sizeof(semanage_port_t *),
87	      (int (*)(const void *, const void *))
88	      &semanage_port_compare2_qsort);
89
90	/* Test each port for overlap */
91	while (i < nports) {
92
93		int proto = semanage_port_get_proto(ports[i]);
94		int low = semanage_port_get_low(ports[i]);
95		int high = semanage_port_get_high(ports[i]);
96		const char *proto_str = semanage_port_get_proto_str(proto);
97
98		const char *proto_str2;
99		int proto2, low2, high2;
100
101		/* Find the first port with matching
102		   protocol to compare against */
103		do {
104			if (j == nports - 1)
105				goto next;
106			j++;
107			proto2 = semanage_port_get_proto(ports[j]);
108			low2 = semanage_port_get_low(ports[j]);
109			high2 = semanage_port_get_high(ports[j]);
110			proto_str2 = semanage_port_get_proto_str(proto2);
111
112		} while (proto != proto2);
113
114		/* Overlap detected */
115		if (low2 <= high) {
116			ERR(handle, "port overlap between ranges "
117			    "%u - %u (%s) <--> %u - %u (%s).",
118			    low, high, proto_str, low2, high2, proto_str2);
119			goto invalid;
120		}
121
122		/* If closest port of matching protocol doesn't overlap with
123		 * test port, neither do the rest of them, because that's
124		 * how the sort function works on ports - lower bound
125		 * ports come first */
126	      next:
127		i++;
128		j = i;
129	}
130
131	for (i = 0; i < nports; i++)
132		semanage_port_free(ports[i]);
133	free(ports);
134	return STATUS_SUCCESS;
135
136      err:
137	ERR(handle, "could not complete ports validity check");
138
139      invalid:
140	for (i = 0; i < nports; i++)
141		semanage_port_free(ports[i]);
142	free(ports);
143	return STATUS_ERR;
144}
145