15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Generalized labeling frontend for userspace object managers. 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Author : Eamon Walsh <ewalsh@epoch.ncsc.mil> 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/types.h> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <ctype.h> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <errno.h> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdio.h> 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <stdlib.h> 12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include <string.h> 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <selinux/selinux.h> 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "callbacks.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "label_internal.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef int (*selabel_initfunc)(struct selabel_handle *rec, 207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const struct selinux_opt *opts, 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned nopts); 22c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static selabel_initfunc initfuncs[] = { 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &selabel_file_init, 255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu NULL, 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NULL, 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NULL, 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &selabel_property_init, 29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}; 30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Validation functions 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline int selabel_is_validate_set(const struct selinux_opt *opts, 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned n) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (n--) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (opts[n].type == SELABEL_OPT_VALIDATE) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return !!opts[n].value; 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)int selabel_validate(struct selabel_handle *rec, 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) struct selabel_lookup_rec *contexts) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc = 0; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!rec->validating || contexts->validated) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto out; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = selinux_validate(&contexts->ctx_raw); 547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (rc < 0) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto out; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) contexts->validated = 1; 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)out: 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rc; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 63a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) * Public API 64a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) */ 65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct selabel_handle *selabel_open(unsigned int backend, 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const struct selinux_opt *opts, 68a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) unsigned nopts) 69a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles){ 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct selabel_handle *rec = NULL; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (backend >= ARRAY_SIZE(initfuncs)) { 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) errno = EINVAL; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto out; 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (initfuncs[backend] == NULL) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto out; 79a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 80a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) rec = (struct selabel_handle *)malloc(sizeof(*rec)); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!rec) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto out; 83a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(rec, 0, sizeof(*rec)); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rec->backend = backend; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rec->validating = selabel_is_validate_set(opts, nopts); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((*initfuncs[backend])(rec, opts, nopts)) { 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(rec); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rec = NULL; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 93a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)out: 94a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return rec; 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static struct selabel_lookup_rec * 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)selabel_lookup_common(struct selabel_handle *rec, 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *key, int type) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct selabel_lookup_rec *lr; 102a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) lr = rec->func_lookup(rec, key, type); 103a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!lr) 104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return NULL; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return lr; 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int selabel_lookup(struct selabel_handle *rec, char **con, 1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const char *key, int type) 1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles){ 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) struct selabel_lookup_rec *lr; 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lr = selabel_lookup_common(rec, key, type); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!lr) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *con = strdup(lr->ctx_raw); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return *con ? 0 : -1; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 122a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)bool selabel_partial_match(struct selabel_handle *rec, const char *key) 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!rec->func_partial_match) { 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /* 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If the label backend does not support partial matching, 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * then assume a match is possible. 1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) */ 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 130a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rec->func_partial_match(rec, key); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void selabel_close(struct selabel_handle *rec) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rec->func_close(rec); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(rec); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void selabel_stats(struct selabel_handle *rec) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rec->func_stats(rec); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)