tzh
2024-08-22 c7d0944258c7d0943aa7b2211498fd612971ce27
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
/* Copyright (C) 2017 Mellanox Technologies Inc. */
 
struct semanage_ibpkey;
struct semanage_ibpkey_key;
typedef struct semanage_ibpkey_key record_key_t;
typedef struct semanage_ibpkey record_t;
#define DBASE_RECORD_DEFINED
 
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include "ibpkey_internal.h"
#include "debug.h"
#include "handle.h"
#include "database.h"
 
int semanage_ibpkey_modify_local(semanage_handle_t *handle,
                const semanage_ibpkey_key_t *key,
                const semanage_ibpkey_t *data)
{
   dbase_config_t *dconfig = semanage_ibpkey_dbase_local(handle);
 
   return dbase_modify(handle, dconfig, key, data);
}
 
int semanage_ibpkey_del_local(semanage_handle_t *handle,
                 const semanage_ibpkey_key_t *key)
{
   dbase_config_t *dconfig = semanage_ibpkey_dbase_local(handle);
 
   return dbase_del(handle, dconfig, key);
}
 
int semanage_ibpkey_query_local(semanage_handle_t *handle,
               const semanage_ibpkey_key_t *key,
               semanage_ibpkey_t **response)
{
   dbase_config_t *dconfig = semanage_ibpkey_dbase_local(handle);
 
   return dbase_query(handle, dconfig, key, response);
}
 
int semanage_ibpkey_exists_local(semanage_handle_t *handle,
                const semanage_ibpkey_key_t *key,
                int *response)
{
   dbase_config_t *dconfig = semanage_ibpkey_dbase_local(handle);
 
   return dbase_exists(handle, dconfig, key, response);
}
 
int semanage_ibpkey_count_local(semanage_handle_t *handle,
               unsigned int *response)
{
   dbase_config_t *dconfig = semanage_ibpkey_dbase_local(handle);
 
   return dbase_count(handle, dconfig, response);
}
 
int semanage_ibpkey_iterate_local(semanage_handle_t *handle,
                 int (*handler)(const semanage_ibpkey_t *record,
                        void *varg), void *handler_arg)
{
   dbase_config_t *dconfig = semanage_ibpkey_dbase_local(handle);
 
   return dbase_iterate(handle, dconfig, handler, handler_arg);
}
 
int semanage_ibpkey_list_local(semanage_handle_t *handle,
                  semanage_ibpkey_t ***records, unsigned int *count)
{
   dbase_config_t *dconfig = semanage_ibpkey_dbase_local(handle);
 
   return dbase_list(handle, dconfig, records, count);
}
 
hidden_def(semanage_ibpkey_list_local)
 
int hidden semanage_ibpkey_validate_local(semanage_handle_t *handle)
{
   semanage_ibpkey_t **ibpkeys = NULL;
   unsigned int nibpkeys = 0;
   unsigned int i = 0, j = 0;
   uint64_t subnet_prefix;
   uint64_t subnet_prefix2;
   char *subnet_prefix_str;
   char *subnet_prefix_str2;
   int low, high;
   int low2, high2;
 
   /* List and sort the ibpkeys */
   if (semanage_ibpkey_list_local(handle, &ibpkeys, &nibpkeys) < 0)
       goto err;
 
   qsort(ibpkeys, nibpkeys, sizeof(semanage_ibpkey_t *),
         (int (*)(const void *, const void *))
         &semanage_ibpkey_compare2_qsort);
 
   /* Test each ibpkey for overlap */
   while (i < nibpkeys) {
       if (STATUS_SUCCESS != semanage_ibpkey_get_subnet_prefix(handle,
                                   ibpkeys[i],
                                   &subnet_prefix_str)) {
           ERR(handle, "Couldn't get subnet prefix string");
           goto err;
       }
 
       subnet_prefix = semanage_ibpkey_get_subnet_prefix_bytes(ibpkeys[i]);
       low = semanage_ibpkey_get_low(ibpkeys[i]);
       high = semanage_ibpkey_get_high(ibpkeys[i]);
 
       /* Find the first ibpkey with matching
        * subnet_prefix to compare against
        */
       do {
           if (j == nibpkeys - 1)
               goto next;
           j++;
 
           if (STATUS_SUCCESS !=
               semanage_ibpkey_get_subnet_prefix(handle,
                                 ibpkeys[j],
                                 &subnet_prefix_str2)) {
               ERR(handle, "Couldn't get subnet prefix string");
               goto err;
           }
           subnet_prefix2 = semanage_ibpkey_get_subnet_prefix_bytes(ibpkeys[j]);
           low2 = semanage_ibpkey_get_low(ibpkeys[j]);
           high2 = semanage_ibpkey_get_high(ibpkeys[j]);
       } while (subnet_prefix != subnet_prefix2);
 
       /* Overlap detected */
       if (low2 <= high) {
           ERR(handle, "ibpkey overlap between ranges "
               "(%s) %u - %u <--> (%s) %u - %u.",
               subnet_prefix_str, low, high,
               subnet_prefix_str2, low2, high2);
           goto invalid;
       }
 
       /* If closest ibpkey of matching subnet prefix doesn't overlap
        * with test ibpkey, neither do the rest of them, because that's
        * how the sort function works on ibpkeys - lower bound
        * ibpkeys come first
        */
next:
       i++;
       j = i;
   }
 
   for (i = 0; i < nibpkeys; i++)
       semanage_ibpkey_free(ibpkeys[i]);
   free(ibpkeys);
   return STATUS_SUCCESS;
 
err:
   ERR(handle, "could not complete ibpkeys validity check");
 
invalid:
   for (i = 0; i < nibpkeys; i++)
       semanage_ibpkey_free(ibpkeys[i]);
   free(ibpkeys);
   return STATUS_ERR;
}