Jason Tang jtang@tresys.com
This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Definition in file mls_range.c.
#include <config.h>
#include <apol/mls_range.h>
#include <assert.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include "policy-query-internal.h"
#include <qpol/iterator.h>
#include <apol/vector.h>
Go to the source code of this file.
Classes | |
| struct | apol_mls_range |
Functions | |
| apol_mls_range_t * | apol_mls_range_create (void) |
| Allocate and return a new MLS range structure. | |
| apol_mls_range_t * | apol_mls_range_create_from_mls_range (const apol_mls_range_t *range) |
| Allocate and return a new MLS range structure, initialized by an existing apol_mls_range_t. | |
| apol_mls_range_t * | apol_mls_range_create_from_string (const apol_policy_t *p, const char *mls_range_string) |
| Take a MLS range string (e.g., S0:C0.C10-S1:C0.C127) and parse it. | |
| apol_mls_range_t * | apol_mls_range_create_from_literal (const char *mls_range_string) |
| Take a literal MLS range string (e.g., S0:C0.C10-S1:C0.C127), fill in a newly allocated apol_mls_range_t and return it. | |
| apol_mls_range_t * | apol_mls_range_create_from_qpol_mls_range (const apol_policy_t *p, const qpol_mls_range_t *qpol_range) |
| Create a new apol_mls_range_t and initialize it with a qpol_mls_range_t. | |
| void | apol_mls_range_destroy (apol_mls_range_t **range) |
| Deallocate all memory associated with a MLS range structure and then set it to NULL. | |
| int | apol_mls_range_set_low (const apol_policy_t *p, apol_mls_range_t *range, apol_mls_level_t *level) |
| Set the low level component of a MLS range structure. | |
| int | apol_mls_range_set_high (const apol_policy_t *p, apol_mls_range_t *range, apol_mls_level_t *level) |
| Set the high level component of a MLS range structure. | |
| const apol_mls_level_t * | apol_mls_range_get_low (const apol_mls_range_t *range) |
| Get the low level component of a MLS range structure. | |
| const apol_mls_level_t * | apol_mls_range_get_high (const apol_mls_range_t *range) |
| Get the high level component of a MLS range structure. | |
| int | apol_mls_range_compare (const apol_policy_t *p, const apol_mls_range_t *target, const apol_mls_range_t *search, unsigned int range_compare_type) |
| Compare two ranges, determining if one matches the other. | |
| int | apol_mls_range_does_include_level (const apol_policy_t *p, const apol_mls_range_t *range, const apol_mls_level_t *level) |
| int | apol_mls_range_contain_subrange (const apol_policy_t *p, const apol_mls_range_t *range, const apol_mls_range_t *subrange) |
| Determine if a range completely contains a subrange given a certain policy. | |
| int | apol_mls_range_validate (const apol_policy_t *p, const apol_mls_range_t *range) |
| Given a range, determine if it is legal according to the supplied policy. | |
| int | mls_range_comp (const void *a, const void *b, void *data) |
| int | mls_level_name_to_cat_comp (const void *a, const void *b, void *data) |
| void | mls_level_free (void *elem) |
| apol_vector_t * | apol_mls_range_get_levels (const apol_policy_t *p, const apol_mls_range_t *range) |
| Given a range, return a vector of levels (type apol_mls_level_t *) that constitutes that range. | |
| char * | apol_mls_range_render (const apol_policy_t *p, const apol_mls_range_t *range) |
| Creates a string containing the textual representation of a MLS range. | |
| int | apol_mls_range_convert (const apol_policy_t *p, apol_mls_range_t *range) |
| Given a range, convert any literal MLS levels within it (as per apol_mls_level_convert()) to a complete level. | |
| int | apol_mls_range_is_literal (const apol_mls_range_t *range) |
| Determine if the range contains any literal levels. | |
|
|
Allocate and return a new MLS range structure. All fields are initialized to nothing. The caller must call apol_mls_range_destroy() upon the return value afterwards.
Definition at line 44 of file mls_range.c. References apol_mls_range_t. Referenced by apol_mls_range_create_from_literal(), apol_mls_range_create_from_mls_range(), and apol_mls_range_create_from_string(). 00045 {
00046 return calloc(1, sizeof(apol_mls_range_t));
00047 }
|
|
|
Allocate and return a new MLS range structure, initialized by an existing apol_mls_range_t. The caller must call apol_mls_range_destroy() upon the return value afterwards.
Definition at line 49 of file mls_range.c. References apol_mls_level_create_from_mls_level(), apol_mls_range_create(), apol_mls_range_destroy(), apol_mls_range_t, apol_mls_range::high, and apol_mls_range::low. 00050 {
00051 apol_mls_range_t *r;
00052 if ((r = apol_mls_range_create()) == NULL) {
00053 return NULL;
00054 }
00055 if (range != NULL &&
00056 ((r->low = apol_mls_level_create_from_mls_level(range->low)) == NULL ||
00057 (r->high = apol_mls_level_create_from_mls_level(range->high)) == NULL)) {
00058 apol_mls_range_destroy(&r);
00059 return NULL;
00060 }
00061 return r;
00062 }
|
|
||||||||||||
|
Take a MLS range string (e.g., S0:C0.C10-S1:C0.C127) and parse it. Fill in a newly allocated apol_mls_range_t and return it. This function needs a policy to resolve dots within categories and to ensure that the high level dominates the low. If the string represents an illegal range then return NULL. The caller must call apol_mls_range_destroy() upon the returned value afterwards.
Definition at line 64 of file mls_range.c. References apol_mls_level_create_from_string(), apol_mls_level_t, apol_mls_range_create(), apol_mls_range_destroy(), apol_mls_range_t, apol_mls_range_validate(), apol_policy_t, ERR, apol_mls_range::high, and apol_mls_range::low. Referenced by db_range_compare(), sefs_filesystem::isQueryMatch(), sefs_filesystem::runQueryMap(), sefs_fcfile::runQueryMap(), and sefs_db::runQueryMap(). 00065 {
00066 if (p == NULL || mls_range_string == NULL) {
00067 ERR(p, "%s", strerror(EINVAL));
00068 errno = EINVAL;
00069 return NULL;
00070 }
00071
00072 apol_mls_range_t *r = apol_mls_range_create();
00073 if (r == NULL) {
00074 ERR(p, "%s", strerror(errno));
00075 return NULL;
00076 }
00077 char *dash;
00078 if ((dash = strchr(mls_range_string, '-')) == NULL) {
00079 // just a low level
00080 apol_mls_level_t *l = apol_mls_level_create_from_string(p, mls_range_string);
00081 if (l == NULL) {
00082 ERR(p, "%s", strerror(errno));
00083 apol_mls_range_destroy(&r);
00084 return NULL;
00085 }
00086 r->low = l;
00087 } else {
00088 // both a low and a high level
00089 if (dash == mls_range_string) {
00090 apol_mls_range_destroy(&r);
00091 ERR(p, "%s", strerror(EINVAL));
00092 errno = EINVAL;
00093 return NULL;
00094 }
00095 char *s = strndup(mls_range_string, dash - mls_range_string);
00096 if (s == NULL) {
00097 ERR(p, "%s", strerror(errno));
00098 apol_mls_range_destroy(&r);
00099 return NULL;
00100 }
00101 apol_mls_level_t *l = apol_mls_level_create_from_string(p, s);
00102 if (l == NULL) {
00103 ERR(p, "%s", strerror(errno));
00104 apol_mls_range_destroy(&r);
00105 free(s);
00106 return NULL;
00107 }
00108 r->low = l;
00109 free(s);
00110 l = NULL;
00111
00112 if ((l = apol_mls_level_create_from_string(p, dash + 1)) == NULL) {
00113 ERR(p, "%s", strerror(errno));
00114 apol_mls_range_destroy(&r);
00115 return NULL;
00116 }
00117 r->high = l;
00118 }
00119
00120 if (apol_mls_range_validate(p, r) <= 0) {
00121 ERR(p, "%s", strerror(EINVAL));
00122 errno = EINVAL;
00123 apol_mls_range_destroy(&r);
00124 return NULL;
00125 }
00126 return r;
00127 }
|
|
|
Take a literal MLS range string (e.g., S0:C0.C10-S1:C0.C127), fill in a newly allocated apol_mls_range_t and return it. The category portions of the levels will not be expanded (i.e., dots will not be resolved); likewise there is no check that the high level dominates the low. The caller must call apol_mls_range_destroy() upon the returned value afterwards. Because this function creates a range without the benefit of a policy, its levels are "incomplete" and thus most operations will fail. Call apol_mls_range_convert() to make a literal MLS range complete, so that it can be used in all functions.
Definition at line 129 of file mls_range.c. References apol_mls_level_create_from_literal(), apol_mls_level_t, apol_mls_range_create(), apol_mls_range_destroy(), apol_mls_range_t, apol_mls_range::high, and apol_mls_range::low. Referenced by apol_context_create_from_literal(), and sefs_fclist::getContext(). 00130 {
00131 if (mls_range_string == NULL) {
00132 errno = EINVAL;
00133 return NULL;
00134 }
00135
00136 apol_mls_range_t *r = apol_mls_range_create();
00137 if (r == NULL) {
00138 return NULL;
00139 }
00140 char *dash;
00141 if ((dash = strchr(mls_range_string, '-')) == NULL) {
00142 // just a low level
00143 apol_mls_level_t *l = apol_mls_level_create_from_literal(mls_range_string);
00144 if (l == NULL) {
00145 apol_mls_range_destroy(&r);
00146 return NULL;
00147 }
00148 r->low = l;
00149 } else {
00150 // both a low and a high level
00151 if (dash == mls_range_string) {
00152 apol_mls_range_destroy(&r);
00153 errno = EINVAL;
00154 return NULL;
00155 }
00156 char *s = strndup(mls_range_string, dash - mls_range_string);
00157 if (s == NULL) {
00158 apol_mls_range_destroy(&r);
00159 return NULL;
00160 }
00161 apol_mls_level_t *l = apol_mls_level_create_from_literal(s);
00162 if (l == NULL) {
00163 apol_mls_range_destroy(&r);
00164 free(s);
00165 return NULL;
00166 }
00167 r->low = l;
00168 free(s);
00169 l = NULL;
00170
00171 if ((l = apol_mls_level_create_from_literal(dash + 1)) == NULL) {
00172 apol_mls_range_destroy(&r);
00173 return NULL;
00174 }
00175 r->high = l;
00176 }
00177 return r;
00178 }
|
|
||||||||||||
|
Create a new apol_mls_range_t and initialize it with a qpol_mls_range_t. The caller must call apol_mls_range_destroy() upon the return value afterwards.
Definition at line 180 of file mls_range.c. References apol_mls_level_create_from_qpol_mls_level(), apol_mls_level_destroy(), apol_mls_level_t, apol_mls_range_destroy(), apol_mls_range_set_high(), apol_mls_range_set_low(), apol_mls_range_t, apol_policy_t, ERR, apol_policy::p, qpol_mls_level_t, qpol_mls_range_get_high_level(), and qpol_mls_range_get_low_level(). Referenced by apol_context_create_from_qpol_context(), apol_context_validate_partial(), apol_range_trans_get_by_query(), apol_range_trans_render(), apol_user_get_by_query(), imp_range_trans_run(), print_user_roles(), and range_create(). 00181 {
00182 apol_mls_range_t *apol_range = NULL;
00183 const qpol_mls_level_t *tmp = NULL;
00184 apol_mls_level_t *tmp_lvl = NULL;
00185 int error = 0;
00186
00187 if (!p || !qpol_range) {
00188 ERR(p, "%s", strerror(EINVAL));
00189 errno = EINVAL;
00190 return NULL;
00191 }
00192
00193 apol_range = calloc(1, sizeof(apol_mls_range_t));
00194 if (!apol_range) {
00195 ERR(p, "%s", strerror(ENOMEM));
00196 return NULL;
00197 }
00198
00199 /* low */
00200 if (qpol_mls_range_get_low_level(p->p, qpol_range, &tmp) ||
00201 !(tmp_lvl = apol_mls_level_create_from_qpol_mls_level(p, tmp)) || apol_mls_range_set_low(p, apol_range, tmp_lvl)) {
00202 error = errno;
00203 apol_mls_level_destroy(&tmp_lvl);
00204 goto err;
00205 }
00206 tmp_lvl = NULL;
00207
00208 /* high */
00209 if (qpol_mls_range_get_high_level(p->p, qpol_range, &tmp) ||
00210 !(tmp_lvl = apol_mls_level_create_from_qpol_mls_level(p, tmp)) || apol_mls_range_set_high(p, apol_range, tmp_lvl)) {
00211 error = errno;
00212 apol_mls_level_destroy(&tmp_lvl);
00213 goto err;
00214 }
00215
00216 return apol_range;
00217
00218 err:
00219 apol_mls_range_destroy(&apol_range);
00220 errno = error;
00221 return NULL;
00222 }
|
|
|
||||||||||||||||
|
Set the low level component of a MLS range structure. This function takes ownership of the level, such that the caller must not modify nor destroy it afterwards. It is legal to pass in the same pointer for the range's low and high level.
Definition at line 237 of file mls_range.c. References apol_mls_level_destroy(), apol_mls_level_t, apol_mls_range_t, apol_policy_t, ERR, and apol_mls_range::low. Referenced by apol_mls_range_create_from_qpol_mls_range(). 00238 {
00239 if (!range) {
00240 ERR(p, "%s", strerror(EINVAL));
00241 errno = EINVAL;
00242 return -1;
00243 }
00244 if (range->low != level) {
00245 apol_mls_level_destroy(&(range->low));
00246 range->low = level;
00247 }
00248 return 0;
00249 }
|
|
||||||||||||||||
|
Set the high level component of a MLS range structure. This function takes ownership of the level, such that the caller must not modify nor destroy it afterwards. It is legal to pass in the same pointer for the range's low and high level.
Definition at line 251 of file mls_range.c. References apol_mls_level_destroy(), apol_mls_level_t, apol_mls_range_t, apol_policy_t, ERR, apol_mls_range::high, and apol_mls_range::low. Referenced by apol_mls_range_create_from_qpol_mls_range(). 00252 {
00253 if (!range) {
00254 ERR(p, "%s", strerror(EINVAL));
00255 errno = EINVAL;
00256 return -1;
00257 }
00258
00259 if (range->high != level) {
00260 if (range->low != range->high) {
00261 apol_mls_level_destroy(&(range->high));
00262 }
00263 range->high = level;
00264 }
00265 return 0;
00266 }
|
|
|
Get the low level component of a MLS range structure.
Definition at line 268 of file mls_range.c. References apol_mls_level_t, apol_mls_range_t, and apol_mls_range::low. Referenced by range_deep_diff(). 00269 {
00270 if (!range) {
00271 errno = EINVAL;
00272 return NULL;
00273 }
00274 return range->low;
00275 }
|
|
|
Get the high level component of a MLS range structure.
Definition at line 277 of file mls_range.c. References apol_mls_level_t, apol_mls_range_t, and apol_mls_range::high. 00278 {
00279 if (!range) {
00280 errno = EINVAL;
00281 return NULL;
00282 }
00283 return range->high;
00284 }
|
|
||||||||||||||||||||
|
Compare two ranges, determining if one matches the other. The fifth parameter gives how to match the ranges. For APOL_QUERY_SUB, if search is a subset of target. For APOL_QUERY_SUPER, if search is a superset of target. Other valid compare types are APOL_QUERY_EXACT and APOL_QUERY_INTERSECT. If a range is not valid according to the policy then this function returns -1. If search is NULL then comparison always succeeds.
Definition at line 286 of file mls_range.c. References apol_mls_range_contain_subrange(), apol_mls_range_t, apol_policy_t, ERR, and apol_mls_range::low. Referenced by apol_context_compare(), apol_context_validate_partial(), apol_range_trans_get_by_query(), apol_user_get_by_query(), db_range_compare(), sefs_filesystem::isQueryMatch(), and sefs_fcfile::runQueryMap(). 00288 {
00289 int ans1 = -1, ans2 = -1;
00290 if (search == NULL) {
00291 return 1;
00292 }
00293 if (p == NULL || target == NULL || target->low == NULL || search->low == NULL) {
00294 ERR(p, "%s", strerror(EINVAL));
00295 errno = EINVAL;
00296 return -1;
00297 }
00298 /* FIX ME: intersect does not work */
00299 if ((range_compare_type & APOL_QUERY_SUB) || (range_compare_type & APOL_QUERY_INTERSECT)) {
00300 ans1 = apol_mls_range_contain_subrange(p, target, search);
00301 if (ans1 < 0) {
00302 return -1;
00303 }
00304 }
00305 if ((range_compare_type & APOL_QUERY_SUPER) || (range_compare_type & APOL_QUERY_INTERSECT)) {
00306 ans2 = apol_mls_range_contain_subrange(p, search, target);
00307 if (ans2 < 0) {
00308 return -1;
00309 }
00310 }
00311 /* EXACT has to come first because its bits are both SUB and SUPER */
00312 if ((range_compare_type & APOL_QUERY_EXACT) == APOL_QUERY_EXACT) {
00313 return (ans1 && ans2);
00314 } else if (range_compare_type & APOL_QUERY_SUB) {
00315 return ans1;
00316 } else if (range_compare_type & APOL_QUERY_SUPER) {
00317 return ans2;
00318 } else if (range_compare_type & APOL_QUERY_INTERSECT) {
00319 return (ans1 || ans2);
00320 }
00321 ERR(p, "%s", "Invalid range compare type argument.");
00322 errno = EINVAL;
00323 return -1;
00324 }
|
|
||||||||||||||||
|
Definition at line 326 of file mls_range.c. References APOL_MLS_EQ, apol_mls_level_compare(), apol_mls_level_get_sens(), apol_mls_level_t, apol_mls_range_t, apol_mls_sens_compare(), apol_policy_t, apol_mls_range::high, level, and apol_mls_range::low. Referenced by apol_mls_range_contain_subrange(). 00328 {
00329 int high_cmp = -1, low_cmp = -1;
00330
00331 if (range->low != range->high) {
00332 low_cmp = apol_mls_level_compare(p, range->low, level);
00333 if (low_cmp < 0) {
00334 return -1;
00335 }
00336 }
00337 const apol_mls_level_t *high_level = (range->high != NULL ? range->high : range->low);
00338 high_cmp = apol_mls_level_compare(p, high_level, level);
00339 if (high_cmp < 0) {
00340 return -1;
00341 }
00342
00343 if (high_cmp == APOL_MLS_EQ || high_cmp == APOL_MLS_DOM) {
00344 if ((low_cmp == APOL_MLS_EQ || low_cmp == APOL_MLS_DOMBY) && range->low != high_level) {
00345 return 1;
00346 } else if (range->low == high_level) {
00347 return apol_mls_sens_compare(p, apol_mls_level_get_sens(range->low), apol_mls_level_get_sens(level));
00348 }
00349 }
00350
00351 return 0;
00352 }
|
|
||||||||||||||||
|
Determine if a range completely contains a subrange given a certain policy. If a range is not valid according to the policy then this function returns -1.
Definition at line 354 of file mls_range.c. References apol_mls_range_does_include_level(), apol_mls_range_t, apol_mls_range_validate(), apol_policy_t, ERR, apol_mls_range::high, and apol_mls_range::low. Referenced by apol_mls_range_compare(). 00355 {
00356 if (p == NULL || apol_mls_range_validate(p, subrange) != 1) {
00357 ERR(p, "%s", strerror(EINVAL));
00358 return -1;
00359 }
00360 /* parent range validity will be checked via
00361 * apol_mls_range_include_level() */
00362
00363 if (apol_mls_range_does_include_level(p, range, subrange->low)) {
00364 if (subrange->high == NULL || apol_mls_range_does_include_level(p, range, subrange->high)) {
00365 return 1;
00366 }
00367 }
00368 return 0;
00369 }
|
|
||||||||||||
|
Given a range, determine if it is legal according to the supplied policy. This function will convert from aliases to canonical forms as necessary.
Definition at line 371 of file mls_range.c. References APOL_MLS_EQ, apol_mls_level_compare(), apol_mls_level_validate(), apol_mls_range_t, apol_policy_t, ERR, apol_mls_range::high, and apol_mls_range::low. Referenced by apol_context_validate_partial(), apol_mls_range_contain_subrange(), and apol_mls_range_create_from_string(). 00372 {
00373 int retv;
00374
00375 if (p == NULL || range == NULL || range->low == NULL) {
00376 ERR(p, "%s", strerror(EINVAL));
00377 errno = EINVAL;
00378 return -1;
00379 }
00380
00381 if ((retv = apol_mls_level_validate(p, range->low)) != 1) {
00382 return retv;
00383 }
00384
00385 if (range->high == NULL) {
00386 return retv;
00387 }
00388 if (range->high != range->low && (retv = apol_mls_level_validate(p, range->high)) != 1) {
00389 return retv;
00390 }
00391
00392 /* both low and high levels exist, so now check that high
00393 * dominates low */
00394 retv = apol_mls_level_compare(p, range->low, range->high);
00395 if (retv < 0) {
00396 return -1;
00397 } else if (retv != APOL_MLS_EQ && retv != APOL_MLS_DOMBY) {
00398 return 0;
00399 }
00400
00401 return 1;
00402 }
|
|
||||||||||||||||
|
Definition at line 404 of file mls_range.c. References apol_mls_level_get_sens(), apol_mls_level_t, qpol_level_get_value(), qpol_level_t, qpol_policy_get_level_by_name(), and qpol_policy_t. Referenced by apol_mls_range_get_levels(). 00405 {
00406 const apol_mls_level_t *l1 = a;
00407 const apol_mls_level_t *l2 = b;
00408 qpol_policy_t *q = (qpol_policy_t *) data;
00409 const qpol_level_t *l;
00410 uint32_t low_value, high_value;
00411 qpol_policy_get_level_by_name(q, apol_mls_level_get_sens(l1), &l);
00412 qpol_level_get_value(q, l, &low_value);
00413 qpol_policy_get_level_by_name(q, apol_mls_level_get_sens(l2), &l);
00414 qpol_level_get_value(q, l, &high_value);
00415 assert(low_value != 0 && high_value != 0);
00416 return low_value - high_value;
00417 }
|
|
||||||||||||||||
|
Definition at line 419 of file mls_range.c. References qpol_cat_get_name(), qpol_cat_t, and qpol_policy_t. Referenced by apol_mls_range_get_levels(). 00420 {
00421 const qpol_cat_t *cat = a;
00422 const char *name = (const char *)b;
00423 qpol_policy_t *q = (qpol_policy_t *) data;
00424 const char *cat_name = "";
00425 qpol_cat_get_name(q, cat, &cat_name);
00426 return strcmp(name, cat_name);
00427 }
|
|
|
Definition at line 429 of file mls_range.c. References apol_mls_level_destroy(), apol_mls_level_t, and level. Referenced by apol_mls_level_destroy(), and apol_mls_range_get_levels(). 00430 {
00431 apol_mls_level_t *level = elem;
00432 apol_mls_level_destroy(&level);
00433 }
|
|
||||||||||||
|
Given a range, return a vector of levels (type apol_mls_level_t *) that constitutes that range. The vector will be sorted in policy order.
Definition at line 435 of file mls_range.c. References apol_mls_level_append_cats(), apol_mls_level_create(), apol_mls_level_destroy(), apol_mls_level_get_cats(), apol_mls_level_get_sens(), apol_mls_level_set_sens(), apol_mls_level_t, apol_mls_range_t, apol_policy_get_qpol(), apol_policy_t, apol_vector_append(), apol_vector_create(), apol_vector_create_from_iter(), apol_vector_destroy(), apol_vector_get_element(), apol_vector_get_index(), apol_vector_get_size(), apol_vector_sort(), apol_vector_t, ERR, apol_mls_range::high, apol_mls_range::low, mls_level_free(), mls_level_name_to_cat_comp(), mls_range_comp(), qpol_iterator_destroy(), qpol_iterator_end(), qpol_iterator_get_item(), qpol_iterator_next(), qpol_iterator_t, qpol_level_get_cat_iter(), qpol_level_get_name(), qpol_level_get_value(), qpol_level_t, qpol_policy_get_level_by_name(), qpol_policy_get_level_iter(), and qpol_policy_t. Referenced by range_create(), and range_deep_diff(). 00436 {
00437 qpol_policy_t *q = apol_policy_get_qpol(p);
00438 apol_vector_t *v = NULL, *catv = NULL;
00439 const qpol_level_t *l;
00440 uint32_t low_value, high_value, value;
00441 int error = 0;
00442 qpol_iterator_t *iter = NULL, *catiter = NULL;
00443
00444 if (p == NULL || range == NULL || range->low == NULL) {
00445 error = EINVAL;
00446 ERR(p, "%s", strerror(error));
00447 goto err;
00448 }
00449 apol_mls_level_t *low_level, *high_level;
00450 low_level = range->low;
00451 if (range->high == NULL) {
00452 high_level = low_level;
00453 } else {
00454 high_level = range->high;
00455 }
00456 if (qpol_policy_get_level_by_name(q, apol_mls_level_get_sens(low_level), &l) < 0 ||
00457 qpol_level_get_value(q, l, &low_value) < 0) {
00458 error = errno;
00459 goto err;
00460 }
00461 if (qpol_policy_get_level_by_name(q, apol_mls_level_get_sens(high_level), &l) < 0 ||
00462 qpol_level_get_value(q, l, &high_value) < 0) {
00463 error = errno;
00464 goto err;
00465 }
00466 assert(low_value <= high_value);
00467 if ((v = apol_vector_create(mls_level_free)) == NULL) {
00468 error = errno;
00469 ERR(p, "%s", strerror(error));
00470 goto err;
00471 }
00472 if (qpol_policy_get_level_iter(q, &iter) < 0) {
00473 error = errno;
00474 goto err;
00475 }
00476 for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
00477 const char *name;
00478 apol_mls_level_t *ml;
00479 if (qpol_iterator_get_item(iter, (void **)&l) < 0 ||
00480 qpol_level_get_value(q, l, &value) < 0 || qpol_level_get_name(q, l, &name) < 0) {
00481 error = errno;
00482 goto err;
00483 }
00484 if (value < low_value || value > high_value) {
00485 continue;
00486 }
00487 if ((ml = apol_mls_level_create()) == NULL || (apol_mls_level_set_sens(p, ml, name) < 0)) {
00488 error = errno;
00489 apol_mls_level_destroy(&ml);
00490 ERR(p, "%s", strerror(error));
00491 goto err;
00492 }
00493
00494 if (qpol_level_get_cat_iter(q, l, &catiter) < 0 || (catv = apol_vector_create_from_iter(catiter, NULL)) == NULL) {
00495 error = errno;
00496 goto err;
00497 }
00498
00499 const apol_vector_t *high_cats = apol_mls_level_get_cats(high_level);
00500 for (size_t i = 0; i < apol_vector_get_size(high_cats); i++) {
00501 char *cat_name = apol_vector_get_element(high_cats, i);
00502
00503 size_t j;
00504 /* do not add categories that are not members of
00505 the level */
00506 if (apol_vector_get_index(catv, cat_name, mls_level_name_to_cat_comp, q, &j) < 0) {
00507 /* this category is not legal under the given policy */
00508 continue;
00509 }
00510 if (apol_mls_level_append_cats(p, ml, cat_name) < 0) {
00511 error = errno;
00512 apol_mls_level_destroy(&ml);
00513 ERR(p, "%s", strerror(error));
00514 goto err;
00515 }
00516 }
00517
00518 qpol_iterator_destroy(&catiter);
00519 apol_vector_destroy(&catv);
00520
00521 if (apol_vector_append(v, ml) < 0) {
00522 error = errno;
00523 apol_mls_level_destroy(&ml);
00524 ERR(p, "%s", strerror(error));
00525 goto err;
00526 }
00527 }
00528 apol_vector_sort(v, mls_range_comp, q);
00529 qpol_iterator_destroy(&iter);
00530 qpol_iterator_destroy(&catiter);
00531 apol_vector_destroy(&catv);
00532 return v;
00533 err:
00534 qpol_iterator_destroy(&iter);
00535 qpol_iterator_destroy(&catiter);
00536 apol_vector_destroy(&v);
00537 apol_vector_destroy(&catv);
00538 errno = error;
00539 return NULL;
00540 }
|
|
||||||||||||
|
Creates a string containing the textual representation of a MLS range.
Definition at line 542 of file mls_range.c. References APOL_MLS_DOM, apol_mls_level_compare(), apol_mls_level_render(), apol_mls_range_is_literal(), apol_mls_range_t, apol_policy_t, apol_str_append(), apol_str_appendf(), ERR, apol_mls_range::high, and apol_mls_range::low. Referenced by apol_context_render(), apol_range_trans_render(), main(), poldiff_range_to_string_brief(), poldiff_range_trans_to_string(), print_user_roles(), rangetrans_to_string(), and replace_entry(). 00543 {
00544 char *rt = NULL, *retval = NULL;
00545 char *sub_str = NULL;
00546 int retv;
00547 size_t sz = 0;
00548
00549 if (!range || range->low == NULL) {
00550 ERR(p, "%s", strerror(EINVAL));
00551 errno = EINVAL;
00552 goto cleanup;
00553 }
00554 if (p == NULL && apol_mls_range_is_literal(range) != 1) {
00555 ERR(p, "%s", strerror(EINVAL));
00556 errno = EINVAL;
00557 goto cleanup;
00558 }
00559
00560 if ((sub_str = apol_mls_level_render(p, range->low)) == NULL) {
00561 goto cleanup;
00562 }
00563 if (apol_str_append(&rt, &sz, sub_str)) {
00564 ERR(p, "%s", strerror(errno));
00565 goto cleanup;
00566 }
00567 free(sub_str);
00568 sub_str = NULL;
00569 if (range->high == NULL) {
00570 /* no high level set, so skip the rest of this render
00571 * function */
00572 retval = rt;
00573 goto cleanup;
00574 }
00575 if (p == NULL) {
00576 // no policy, so assume that high level dominates low level
00577 retv = APOL_MLS_DOM;
00578 } else {
00579 retv = apol_mls_level_compare(p, range->low, range->high);
00580 if (retv < 0) {
00581 goto cleanup;
00582 }
00583 }
00584 /* if (high level != low level) */
00585 if ((retv == APOL_MLS_DOM || retv == APOL_MLS_DOMBY) && range->high != NULL) {
00586 sub_str = apol_mls_level_render(p, range->high);
00587 if (!sub_str)
00588 goto cleanup;
00589 if (apol_str_appendf(&rt, &sz, " - %s", sub_str)) {
00590 ERR(p, "%s", strerror(errno));
00591 goto cleanup;
00592 }
00593 }
00594 retval = rt;
00595 cleanup:
00596 if (retval != rt) {
00597 free(rt);
00598 }
00599 free(sub_str);
00600 return retval;
00601 }
|
|
||||||||||||
|
Given a range, convert any literal MLS levels within it (as per apol_mls_level_convert()) to a complete level. If the range has no levels or has no literal levels then do nothing.
Definition at line 603 of file mls_range.c. References apol_mls_level_convert(), apol_mls_level_t, apol_mls_range_t, apol_policy_t, ERR, apol_mls_range::high, and apol_mls_range::low. Referenced by apol_context_convert(). 00604 {
00605 if (p == NULL || range == NULL) {
00606 ERR(p, "%s", strerror(EINVAL));
00607 errno = EINVAL;
00608 return -1;
00609 }
00610 apol_mls_level_t *low = range->low;
00611 apol_mls_level_t *high = range->high;
00612 int retval;
00613 if (low != NULL) {
00614 retval = apol_mls_level_convert(p, low);
00615 if (retval < 0) {
00616 return retval;
00617 }
00618 }
00619 if (high != NULL && high != low) {
00620 retval = apol_mls_level_convert(p, high);
00621 if (retval < 0) {
00622 return retval;
00623 }
00624 }
00625 return 0;
00626 }
|
|
|
Determine if the range contains any literal levels. (Levels that have been converted are still considered literal.)
Definition at line 628 of file mls_range.c. References apol_mls_level_is_literal(), apol_mls_range_t, apol_mls_range::high, and apol_mls_range::low. Referenced by apol_context_render(), and apol_mls_range_render(). 00629 {
00630 if (range == NULL) {
00631 return -1;
00632 }
00633 int ret;
00634 if ((ret = apol_mls_level_is_literal(range->low)) != 0) {
00635 return ret;
00636 }
00637 if (range->high != NULL) {
00638 ret = apol_mls_level_is_literal(range->high);
00639 }
00640 return ret;
00641 }
|