/** * @file * * Implementation of utility functions. * * @author Jeremy A. Mowery jmowery@tresys.com * @author Jason Tang jtang@tresys.com * * Copyright (C) 2006-2008 Tresys Technology, LLC * * 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 */ #include #include "qpol_internal.h" #include #include #include #include #include #include #include #include #include #include const char *libqpol_get_version(void) { return LIBQPOL_VERSION_STRING; } static int search_policy_source_file(char **path) { int error; char *source_path; if (asprintf(&source_path, "%s/src/policy/policy.conf", selinux_policy_root()) < 0) { return -1; } if (access(source_path, R_OK) < 0) { error = errno; free(source_path); errno = error; return 1; } *path = source_path; return 0; } static int get_binpol_version(const char *policy_fname) { FILE *policy_fp = NULL; int ret_version, error; policy_fp = fopen(policy_fname, "r"); if (policy_fp == NULL) { return -1; } if (!qpol_is_file_binpol(policy_fp)) { error = errno; fclose(policy_fp); errno = error; return -1; } ret_version = qpol_binpol_version(policy_fp); fclose(policy_fp); return ret_version; } static int search_policy_binary_file(char **path) { const char *binary_path = selinux_current_policy_path(); if (binary_path) { *path = strdup(binary_path); if (*path) return 0; } return -1; } int qpol_default_policy_find(char **path) { int rt; if (path == NULL) { errno = EINVAL; return -1; } *path = NULL; /* Try default source policy first as a source policy contains * more useful information. */ if ((rt = search_policy_source_file(path)) <= 0) { return rt; } /* Try a binary policy */ return search_policy_binary_file(path); } #include #include #include #include #define BZ2_MAGICSTR "BZh" #define BZ2_MAGICLEN (sizeof(BZ2_MAGICSTR)-1) /* qpol_bunzip() uncompresses a file to '*data', returning the total number of * uncompressed bytes in the file. * Returns -1 if file could not be decompressed. * Originally from libsemanage/src/direct_api.c, with slight mods */ ssize_t qpol_bunzip(FILE *f, char **data) { BZFILE* b; size_t nBuf; char buf[1<<18]; size_t size = sizeof(buf); int bzerror; size_t total=0; int small=0; // Set to 1 to use less memory decompressing (about 2x slower) bzerror = fread(buf, 1, BZ2_MAGICLEN, f); rewind(f); if ((bzerror != BZ2_MAGICLEN) || memcmp(buf, BZ2_MAGICSTR, BZ2_MAGICLEN)) return -1; b = BZ2_bzReadOpen ( &bzerror, f, 0, small, NULL, 0 ); if ( bzerror != BZ_OK ) { BZ2_bzReadClose ( &bzerror, b ); return -1; } char *uncompress = realloc(NULL, size); while ( bzerror == BZ_OK) { nBuf = BZ2_bzRead ( &bzerror, b, buf, sizeof(buf)); if (( bzerror == BZ_OK ) || ( bzerror == BZ_STREAM_END )) { if (total + nBuf > size) { size *= 2; uncompress = realloc(uncompress, size); } memcpy(&uncompress[total], buf, nBuf); total += nBuf; } } if ( bzerror != BZ_STREAM_END ) { BZ2_bzReadClose ( &bzerror, b ); free(uncompress); return -1; } BZ2_bzReadClose ( &bzerror, b ); *data = uncompress; return total; }