00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "policy-query-internal.h"
00031
00032 #include <errno.h>
00033 #include <string.h>
00034
00035 struct apol_role_allow_query
00036 {
00037 char *source, *target;
00038 unsigned int flags;
00039 };
00040
00041 struct apol_role_trans_query
00042 {
00043 char *source, *target, *default_role;
00044 unsigned int flags;
00045 };
00046
00047
00048
00049 int apol_role_allow_get_by_query(const apol_policy_t * p, const apol_role_allow_query_t * r, apol_vector_t ** v)
00050 {
00051 qpol_iterator_t *iter = NULL;
00052 apol_vector_t *source_list = NULL, *target_list = NULL;
00053 int retval = -1, source_as_any = 0;
00054 *v = NULL;
00055
00056 if (r != NULL) {
00057 if (r->source != NULL &&
00058 (source_list = apol_query_create_candidate_role_list(p, r->source, r->flags & APOL_QUERY_REGEX)) == NULL) {
00059 goto cleanup;
00060 }
00061 if ((r->flags & APOL_QUERY_SOURCE_AS_ANY) && r->source != NULL) {
00062 target_list = source_list;
00063 source_as_any = 1;
00064 } else if (r->target != NULL &&
00065 (target_list = apol_query_create_candidate_role_list(p, r->target, r->flags & APOL_QUERY_REGEX)) == NULL)
00066 {
00067 goto cleanup;
00068 }
00069 }
00070 if (qpol_policy_get_role_allow_iter(p->p, &iter) < 0) {
00071 goto cleanup;
00072 }
00073 if ((*v = apol_vector_create(NULL)) == NULL) {
00074 ERR(p, "%s", strerror(errno));
00075 goto cleanup;
00076 }
00077 for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
00078 qpol_role_allow_t *rule;
00079 int match_source = 0, match_target = 0;
00080 size_t i;
00081 if (qpol_iterator_get_item(iter, (void **)&rule) < 0) {
00082 goto cleanup;
00083 }
00084
00085 if (source_list == NULL) {
00086 match_source = 1;
00087 } else {
00088 const qpol_role_t *source_role;
00089 if (qpol_role_allow_get_source_role(p->p, rule, &source_role) < 0) {
00090 goto cleanup;
00091 }
00092 if (apol_vector_get_index(source_list, source_role, NULL, NULL, &i) == 0) {
00093 match_source = 1;
00094 }
00095 }
00096
00097
00098
00099
00100 if (!source_as_any && !match_source) {
00101 continue;
00102 }
00103
00104 if (target_list == NULL || (source_as_any && match_source)) {
00105 match_target = 1;
00106 } else {
00107 const qpol_role_t *target_role;
00108 if (qpol_role_allow_get_target_role(p->p, rule, &target_role) < 0) {
00109 goto cleanup;
00110 }
00111 if (apol_vector_get_index(target_list, target_role, NULL, NULL, &i) == 0) {
00112 match_target = 1;
00113 }
00114 }
00115 if (!match_target) {
00116 continue;
00117 }
00118
00119 if (apol_vector_append(*v, rule)) {
00120 ERR(p, "%s", strerror(ENOMEM));
00121 goto cleanup;
00122 }
00123 }
00124
00125 retval = 0;
00126 cleanup:
00127 if (retval != 0) {
00128 apol_vector_destroy(v);
00129 }
00130 apol_vector_destroy(&source_list);
00131 if (!source_as_any) {
00132 apol_vector_destroy(&target_list);
00133 }
00134 qpol_iterator_destroy(&iter);
00135 return retval;
00136 }
00137
00138 apol_role_allow_query_t *apol_role_allow_query_create(void)
00139 {
00140 return calloc(1, sizeof(apol_role_allow_query_t));
00141 }
00142
00143 void apol_role_allow_query_destroy(apol_role_allow_query_t ** r)
00144 {
00145 if (r != NULL && *r != NULL) {
00146 free((*r)->source);
00147 free((*r)->target);
00148 free(*r);
00149 *r = NULL;
00150 }
00151 }
00152
00153 int apol_role_allow_query_set_source(const apol_policy_t * p, apol_role_allow_query_t * r, const char *role)
00154 {
00155 return apol_query_set(p, &r->source, NULL, role);
00156 }
00157
00158 int apol_role_allow_query_set_target(const apol_policy_t * p, apol_role_allow_query_t * r, const char *role)
00159 {
00160 return apol_query_set(p, &r->target, NULL, role);
00161 }
00162
00163 int apol_role_allow_query_set_source_any(const apol_policy_t * p, apol_role_allow_query_t * r, int is_any)
00164 {
00165 return apol_query_set_flag(p, &r->flags, is_any, APOL_QUERY_SOURCE_AS_ANY);
00166 }
00167
00168 int apol_role_allow_query_set_regex(const apol_policy_t * p, apol_role_allow_query_t * r, int is_regex)
00169 {
00170 return apol_query_set_regex(p, &r->flags, is_regex);
00171 }
00172
00173 char *apol_role_allow_render(const apol_policy_t * policy, const qpol_role_allow_t * rule)
00174 {
00175 char *tmp = NULL;
00176 const char *source_name = NULL, *target_name = NULL;
00177 const qpol_role_t *role = NULL;
00178
00179 if (!policy || !rule) {
00180 ERR(policy, "%s", strerror(EINVAL));
00181 errno = EINVAL;
00182 return NULL;
00183 }
00184
00185
00186 if (qpol_role_allow_get_source_role(policy->p, rule, &role)) {
00187 ERR(policy, "%s", strerror(errno));
00188 return NULL;
00189 }
00190 if (qpol_role_get_name(policy->p, role, &source_name)) {
00191 ERR(policy, "%s", strerror(errno));
00192 return NULL;
00193 }
00194
00195
00196 if (qpol_role_allow_get_target_role(policy->p, rule, &role)) {
00197 ERR(policy, "%s", strerror(errno));
00198 return NULL;
00199 }
00200 if (qpol_role_get_name(policy->p, role, &target_name)) {
00201 ERR(policy, "%s", strerror(errno));
00202 return NULL;
00203 }
00204
00205 if (asprintf(&tmp, "allow %s %s;", source_name, target_name) < 0) {
00206 ERR(policy, "%s", strerror(errno));
00207 return NULL;
00208 }
00209
00210 return tmp;
00211 }
00212
00213
00214
00215 int apol_role_trans_get_by_query(const apol_policy_t * p, const apol_role_trans_query_t * r, apol_vector_t ** v)
00216 {
00217 qpol_iterator_t *iter = NULL;
00218 apol_vector_t *source_list = NULL, *target_list = NULL, *default_list = NULL;
00219 int retval = -1, source_as_any = 0;
00220 *v = NULL;
00221
00222 if (r != NULL) {
00223 if (r->source != NULL &&
00224 (source_list = apol_query_create_candidate_role_list(p, r->source, r->flags & APOL_QUERY_REGEX)) == NULL) {
00225 goto cleanup;
00226 }
00227 if (r->target != NULL &&
00228 (target_list =
00229 apol_query_create_candidate_type_list(p, r->target, r->flags & APOL_QUERY_REGEX,
00230 r->flags & APOL_QUERY_TARGET_INDIRECT,
00231 APOL_QUERY_SYMBOL_IS_BOTH)) == NULL) {
00232 goto cleanup;
00233 }
00234 if ((r->flags & APOL_QUERY_SOURCE_AS_ANY) && r->source != NULL) {
00235 default_list = source_list;
00236 source_as_any = 1;
00237 } else if (r->default_role != NULL &&
00238 (default_list =
00239 apol_query_create_candidate_role_list(p, r->default_role, r->flags & APOL_QUERY_REGEX)) == NULL) {
00240 goto cleanup;
00241 }
00242 }
00243 if (qpol_policy_get_role_trans_iter(p->p, &iter) < 0) {
00244 goto cleanup;
00245 }
00246 if ((*v = apol_vector_create(NULL)) == NULL) {
00247 ERR(p, "%s", strerror(errno));
00248 goto cleanup;
00249 }
00250 for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
00251 qpol_role_trans_t *rule;
00252 int match_source = 0, match_target = 0, match_default = 0;
00253 size_t i;
00254 if (qpol_iterator_get_item(iter, (void **)&rule) < 0) {
00255 goto cleanup;
00256 }
00257
00258 if (source_list == NULL) {
00259 match_source = 1;
00260 } else {
00261 const qpol_role_t *source_role;
00262 if (qpol_role_trans_get_source_role(p->p, rule, &source_role) < 0) {
00263 goto cleanup;
00264 }
00265 if (apol_vector_get_index(source_list, source_role, NULL, NULL, &i) == 0) {
00266 match_source = 1;
00267 }
00268 }
00269
00270
00271
00272
00273 if (!source_as_any && !match_source) {
00274 continue;
00275 }
00276
00277 if (target_list == NULL) {
00278 match_target = 1;
00279 } else {
00280 const qpol_type_t *target_type;
00281 if (qpol_role_trans_get_target_type(p->p, rule, &target_type) < 0) {
00282 goto cleanup;
00283 }
00284 if (apol_vector_get_index(target_list, target_type, NULL, NULL, &i) == 0) {
00285 match_target = 1;
00286 }
00287 }
00288 if (!match_target) {
00289 continue;
00290 }
00291
00292 if (default_list == NULL || (source_as_any && match_source)) {
00293 match_default = 1;
00294 } else {
00295 const qpol_role_t *default_role;
00296 if (qpol_role_trans_get_default_role(p->p, rule, &default_role) < 0) {
00297 goto cleanup;
00298 }
00299 if (apol_vector_get_index(default_list, default_role, NULL, NULL, &i) == 0) {
00300 match_default = 1;
00301 }
00302 }
00303 if (!match_default) {
00304 continue;
00305 }
00306
00307 if (apol_vector_append(*v, rule)) {
00308 ERR(p, "%s", strerror(ENOMEM));
00309 goto cleanup;
00310 }
00311 }
00312
00313 retval = 0;
00314 cleanup:
00315 if (retval != 0) {
00316 apol_vector_destroy(v);
00317 }
00318 apol_vector_destroy(&source_list);
00319 apol_vector_destroy(&target_list);
00320 if (!source_as_any) {
00321 apol_vector_destroy(&default_list);
00322 }
00323 qpol_iterator_destroy(&iter);
00324 return retval;
00325 }
00326
00327 apol_role_trans_query_t *apol_role_trans_query_create(void)
00328 {
00329 return calloc(1, sizeof(apol_role_trans_query_t));
00330 }
00331
00332 void apol_role_trans_query_destroy(apol_role_trans_query_t ** r)
00333 {
00334 if (r != NULL && *r != NULL) {
00335 free((*r)->source);
00336 free((*r)->target);
00337 free((*r)->default_role);
00338 free(*r);
00339 *r = NULL;
00340 }
00341 }
00342
00343 int apol_role_trans_query_set_source(const apol_policy_t * p, apol_role_trans_query_t * r, const char *role)
00344 {
00345 return apol_query_set(p, &r->source, NULL, role);
00346 }
00347
00348 int apol_role_trans_query_set_target(const apol_policy_t * p, apol_role_trans_query_t * r, const char *type, int is_indirect)
00349 {
00350 apol_query_set_flag(p, &r->flags, is_indirect, APOL_QUERY_TARGET_INDIRECT);
00351 return apol_query_set(p, &r->target, NULL, type);
00352 }
00353
00354 int apol_role_trans_query_set_default(const apol_policy_t * p, apol_role_trans_query_t * r, const char *role)
00355 {
00356 return apol_query_set(p, &r->default_role, NULL, role);
00357 }
00358
00359 int apol_role_trans_query_set_source_any(const apol_policy_t * p, apol_role_trans_query_t * r, int is_any)
00360 {
00361 return apol_query_set_flag(p, &r->flags, is_any, APOL_QUERY_SOURCE_AS_ANY);
00362 }
00363
00364 int apol_role_trans_query_set_regex(const apol_policy_t * p, apol_role_trans_query_t * r, int is_regex)
00365 {
00366 return apol_query_set_regex(p, &r->flags, is_regex);
00367 }
00368
00369 char *apol_role_trans_render(const apol_policy_t * policy, const qpol_role_trans_t * rule)
00370 {
00371 char *tmp = NULL;
00372 const char *source_name = NULL, *target_name = NULL, *default_name = NULL;
00373 const qpol_role_t *role = NULL;
00374 const qpol_type_t *type = NULL;
00375
00376 if (!policy || !rule) {
00377 ERR(policy, "%s", strerror(EINVAL));
00378 errno = EINVAL;
00379 return NULL;
00380 }
00381
00382
00383 if (qpol_role_trans_get_source_role(policy->p, rule, &role)) {
00384 ERR(policy, "%s", strerror(errno));
00385 return NULL;
00386 }
00387 if (qpol_role_get_name(policy->p, role, &source_name)) {
00388 ERR(policy, "%s", strerror(errno));
00389 return NULL;
00390 }
00391
00392
00393 if (qpol_role_trans_get_target_type(policy->p, rule, &type)) {
00394 ERR(policy, "%s", strerror(errno));
00395 return NULL;
00396 }
00397 if (qpol_type_get_name(policy->p, type, &target_name)) {
00398 ERR(policy, "%s", strerror(errno));
00399 return NULL;
00400 }
00401
00402
00403 if (qpol_role_trans_get_default_role(policy->p, rule, &role)) {
00404 ERR(policy, "%s", strerror(errno));
00405 return NULL;
00406 }
00407 if (qpol_role_get_name(policy->p, role, &default_name)) {
00408 ERR(policy, "%s", strerror(errno));
00409 return NULL;
00410 }
00411
00412 if (asprintf(&tmp, "role_transition %s %s %s;", source_name, target_name, default_name) < 0) {
00413 ERR(policy, "%s", strerror(errno));
00414 return NULL;
00415 }
00416 return tmp;
00417 }