|
Packit Service |
102278 |
/* Author: Jason Tang <jtang@tresys.com>
|
|
Packit Service |
102278 |
* Christopher Ashworth <cashworth@tresys.com>
|
|
Packit Service |
102278 |
*
|
|
Packit Service |
102278 |
* Copyright (C) 2004-2006 Tresys Technology, LLC
|
|
Packit Service |
102278 |
* Copyright (C) 2005 Red Hat, Inc.
|
|
Packit Service |
102278 |
*
|
|
Packit Service |
102278 |
* This library is free software; you can redistribute it and/or
|
|
Packit Service |
102278 |
* modify it under the terms of the GNU Lesser General Public
|
|
Packit Service |
102278 |
* License as published by the Free Software Foundation; either
|
|
Packit Service |
102278 |
* version 2.1 of the License, or (at your option) any later version.
|
|
Packit Service |
102278 |
*
|
|
Packit Service |
102278 |
* This library is distributed in the hope that it will be useful,
|
|
Packit Service |
102278 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
102278 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit Service |
102278 |
* Lesser General Public License for more details.
|
|
Packit Service |
102278 |
*
|
|
Packit Service |
102278 |
* You should have received a copy of the GNU Lesser General Public
|
|
Packit Service |
102278 |
* License along with this library; if not, write to the Free Software
|
|
Packit Service |
102278 |
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
Packit Service |
102278 |
*/
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
#include <sepol/module.h>
|
|
Packit Service |
102278 |
#include <sepol/handle.h>
|
|
Packit Service |
102278 |
#include <sepol/cil/cil.h>
|
|
Packit Service |
102278 |
#include <selinux/selinux.h>
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
#include <assert.h>
|
|
Packit Service |
102278 |
#include <fcntl.h>
|
|
Packit Service |
102278 |
#include <stdio.h>
|
|
Packit Service |
102278 |
#include <stdio_ext.h>
|
|
Packit Service |
102278 |
#include <stdlib.h>
|
|
Packit Service |
102278 |
#include <string.h>
|
|
Packit Service |
102278 |
#include <unistd.h>
|
|
Packit Service |
102278 |
#include <sys/stat.h>
|
|
Packit Service |
102278 |
#include <sys/types.h>
|
|
Packit Service |
102278 |
#include <limits.h>
|
|
Packit Service |
102278 |
#include <errno.h>
|
|
Packit Service |
102278 |
#include <dirent.h>
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
#include "user_internal.h"
|
|
Packit Service |
102278 |
#include "seuser_internal.h"
|
|
Packit Service |
102278 |
#include "port_internal.h"
|
|
Packit Service |
102278 |
#include "ibpkey_internal.h"
|
|
Packit Service |
102278 |
#include "ibendport_internal.h"
|
|
Packit Service |
102278 |
#include "iface_internal.h"
|
|
Packit Service |
102278 |
#include "boolean_internal.h"
|
|
Packit Service |
102278 |
#include "fcontext_internal.h"
|
|
Packit Service |
102278 |
#include "node_internal.h"
|
|
Packit Service |
102278 |
#include "genhomedircon.h"
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
#include "debug.h"
|
|
Packit Service |
102278 |
#include "handle.h"
|
|
Packit Service |
102278 |
#include "modules.h"
|
|
Packit Service |
102278 |
#include "direct_api.h"
|
|
Packit Service |
102278 |
#include "semanage_store.h"
|
|
Packit Service |
102278 |
#include "database_policydb.h"
|
|
Packit Service |
102278 |
#include "policy.h"
|
|
Packit Service |
102278 |
#include <sys/mman.h>
|
|
Packit Service |
102278 |
#include <sys/wait.h>
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
#define PIPE_READ 0
|
|
Packit Service |
102278 |
#define PIPE_WRITE 1
|
|
Packit Service |
102278 |
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
static void semanage_direct_destroy(semanage_handle_t * sh);
|
|
Packit Service |
102278 |
static int semanage_direct_disconnect(semanage_handle_t * sh);
|
|
Packit Service |
102278 |
static int semanage_direct_begintrans(semanage_handle_t * sh);
|
|
Packit Service |
102278 |
static int semanage_direct_commit(semanage_handle_t * sh);
|
|
Packit Service |
102278 |
static int semanage_direct_install(semanage_handle_t * sh, char *data,
|
|
Packit Service |
102278 |
size_t data_len, const char *module_name, const char *lang_ext);
|
|
Packit Service |
102278 |
static int semanage_direct_install_file(semanage_handle_t * sh, const char *module_name);
|
|
Packit Service |
102278 |
static int semanage_direct_extract(semanage_handle_t * sh,
|
|
Packit Service |
102278 |
semanage_module_key_t *modkey,
|
|
Packit Service |
102278 |
int extract_cil,
|
|
Packit Service |
102278 |
void **mapped_data,
|
|
Packit Service |
102278 |
size_t *data_len,
|
|
Packit Service |
102278 |
semanage_module_info_t **modinfo);
|
|
Packit Service |
102278 |
static int semanage_direct_remove(semanage_handle_t * sh, char *module_name);
|
|
Packit Service |
102278 |
static int semanage_direct_list(semanage_handle_t * sh,
|
|
Packit Service |
102278 |
semanage_module_info_t ** modinfo,
|
|
Packit Service |
102278 |
int *num_modules);
|
|
Packit Service |
102278 |
static int semanage_direct_get_enabled(semanage_handle_t *sh,
|
|
Packit Service |
102278 |
const semanage_module_key_t *modkey,
|
|
Packit Service |
102278 |
int *enabled);
|
|
Packit Service |
102278 |
static int semanage_direct_set_enabled(semanage_handle_t *sh,
|
|
Packit Service |
102278 |
const semanage_module_key_t *modkey,
|
|
Packit Service |
102278 |
int enabled);
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
static int semanage_direct_get_module_info(semanage_handle_t *sh,
|
|
Packit Service |
102278 |
const semanage_module_key_t *modkey,
|
|
Packit Service |
102278 |
semanage_module_info_t **modinfo);
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
static int semanage_direct_list_all(semanage_handle_t *sh,
|
|
Packit Service |
102278 |
semanage_module_info_t **modinfo,
|
|
Packit Service |
102278 |
int *num_modules);
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
static int semanage_direct_install_info(semanage_handle_t *sh,
|
|
Packit Service |
102278 |
const semanage_module_info_t *modinfo,
|
|
Packit Service |
102278 |
char *data,
|
|
Packit Service |
102278 |
size_t data_len);
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
static int semanage_direct_remove_key(semanage_handle_t *sh,
|
|
Packit Service |
102278 |
const semanage_module_key_t *modkey);
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
static struct semanage_policy_table direct_funcs = {
|
|
Packit Service |
102278 |
.get_serial = semanage_direct_get_serial,
|
|
Packit Service |
102278 |
.destroy = semanage_direct_destroy,
|
|
Packit Service |
102278 |
.disconnect = semanage_direct_disconnect,
|
|
Packit Service |
102278 |
.begin_trans = semanage_direct_begintrans,
|
|
Packit Service |
102278 |
.commit = semanage_direct_commit,
|
|
Packit Service |
102278 |
.install = semanage_direct_install,
|
|
Packit Service |
102278 |
.extract = semanage_direct_extract,
|
|
Packit Service |
102278 |
.install_file = semanage_direct_install_file,
|
|
Packit Service |
102278 |
.remove = semanage_direct_remove,
|
|
Packit Service |
102278 |
.list = semanage_direct_list,
|
|
Packit Service |
102278 |
.get_enabled = semanage_direct_get_enabled,
|
|
Packit Service |
102278 |
.set_enabled = semanage_direct_set_enabled,
|
|
Packit Service |
102278 |
.get_module_info = semanage_direct_get_module_info,
|
|
Packit Service |
102278 |
.list_all = semanage_direct_list_all,
|
|
Packit Service |
102278 |
.install_info = semanage_direct_install_info,
|
|
Packit Service |
102278 |
.remove_key = semanage_direct_remove_key,
|
|
Packit Service |
102278 |
};
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
int semanage_direct_is_managed(semanage_handle_t * sh)
|
|
Packit Service |
102278 |
{
|
|
Packit Service |
102278 |
if (semanage_check_init(sh, sh->conf->store_root_path))
|
|
Packit Service |
102278 |
goto err;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (semanage_access_check(sh) < 0)
|
|
Packit Service |
102278 |
return 0;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
return 1;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
err:
|
|
Packit Service |
102278 |
ERR(sh, "could not check whether policy is managed");
|
|
Packit Service |
102278 |
return STATUS_ERR;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* Check that the module store exists, creating it if necessary.
|
|
Packit Service |
102278 |
*/
|
|
Packit Service |
102278 |
int semanage_direct_connect(semanage_handle_t * sh)
|
|
Packit Service |
102278 |
{
|
|
Packit Service |
102278 |
const char *path;
|
|
Packit Service |
102278 |
struct stat sb;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (semanage_check_init(sh, sh->conf->store_root_path))
|
|
Packit Service |
102278 |
goto err;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (sh->create_store)
|
|
Packit Service |
102278 |
if (semanage_create_store(sh, 1))
|
|
Packit Service |
102278 |
goto err;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
sh->u.direct.translock_file_fd = -1;
|
|
Packit Service |
102278 |
sh->u.direct.activelock_file_fd = -1;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* set up function pointers */
|
|
Packit Service |
102278 |
sh->funcs = &direct_funcs;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* Object databases: local modifications */
|
|
Packit Service |
102278 |
if (user_base_file_dbase_init(sh,
|
|
Packit Service |
102278 |
semanage_path(SEMANAGE_ACTIVE,
|
|
Packit Service |
102278 |
SEMANAGE_USERS_BASE_LOCAL),
|
|
Packit Service |
102278 |
semanage_path(SEMANAGE_TMP,
|
|
Packit Service |
102278 |
SEMANAGE_USERS_BASE_LOCAL),
|
|
Packit Service |
102278 |
semanage_user_base_dbase_local(sh)) < 0)
|
|
Packit Service |
102278 |
goto err;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (user_extra_file_dbase_init(sh,
|
|
Packit Service |
102278 |
semanage_path(SEMANAGE_ACTIVE,
|
|
Packit Service |
102278 |
SEMANAGE_USERS_EXTRA_LOCAL),
|
|
Packit Service |
102278 |
semanage_path(SEMANAGE_TMP,
|
|
Packit Service |
102278 |
SEMANAGE_USERS_EXTRA_LOCAL),
|
|
Packit Service |
102278 |
semanage_user_extra_dbase_local(sh)) < 0)
|
|
Packit Service |
102278 |
goto err;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (user_join_dbase_init(sh,
|
|
Packit Service |
102278 |
semanage_user_base_dbase_local(sh),
|
|
Packit Service |
102278 |
semanage_user_extra_dbase_local(sh),
|
|
Packit Service |
102278 |
semanage_user_dbase_local(sh)) < 0)
|
|
Packit Service |
102278 |
goto err;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (port_file_dbase_init(sh,
|
|
Packit Service |
102278 |
semanage_path(SEMANAGE_ACTIVE,
|
|
Packit Service |
102278 |
SEMANAGE_PORTS_LOCAL),
|
|
Packit Service |
102278 |
semanage_path(SEMANAGE_TMP,
|
|
Packit Service |
102278 |
SEMANAGE_PORTS_LOCAL),
|
|
Packit Service |
102278 |
semanage_port_dbase_local(sh)) < 0)
|
|
Packit Service |
102278 |
goto err;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (iface_file_dbase_init(sh,
|
|
Packit Service |
102278 |
semanage_path(SEMANAGE_ACTIVE,
|
|
Packit Service |
102278 |
SEMANAGE_INTERFACES_LOCAL),
|
|
Packit Service |
102278 |
semanage_path(SEMANAGE_TMP,
|
|
Packit Service |
102278 |
SEMANAGE_INTERFACES_LOCAL),
|
|
Packit Service |
102278 |
semanage_iface_dbase_local(sh)) < 0)
|
|
Packit Service |
102278 |
goto err;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (bool_file_dbase_init(sh,
|
|
Packit Service |
102278 |
semanage_path(SEMANAGE_ACTIVE,
|
|
Packit Service |
102278 |
SEMANAGE_BOOLEANS_LOCAL),
|
|
Packit Service |
102278 |
semanage_path(SEMANAGE_TMP,
|
|
Packit Service |
102278 |
SEMANAGE_BOOLEANS_LOCAL),
|
|
Packit Service |
102278 |
semanage_bool_dbase_local(sh)) < 0)
|
|
Packit Service |
102278 |
goto err;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (fcontext_file_dbase_init(sh,
|
|
Packit Service |
102278 |
semanage_path(SEMANAGE_ACTIVE, SEMANAGE_STORE_FC_LOCAL),
|
|
Packit Service |
102278 |
semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC_LOCAL),
|
|
Packit Service |
102278 |
semanage_fcontext_dbase_local(sh)) < 0)
|
|
Packit Service |
102278 |
goto err;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (fcontext_file_dbase_init(sh,
|
|
Packit Service |
102278 |
semanage_path(SEMANAGE_ACTIVE, SEMANAGE_STORE_FC_HOMEDIRS),
|
|
Packit Service |
102278 |
semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC_HOMEDIRS),
|
|
Packit Service |
102278 |
semanage_fcontext_dbase_homedirs(sh)) < 0)
|
|
Packit Service |
102278 |
goto err;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (seuser_file_dbase_init(sh,
|
|
Packit Service |
102278 |
semanage_path(SEMANAGE_ACTIVE,
|
|
Packit Service |
102278 |
SEMANAGE_SEUSERS_LOCAL),
|
|
Packit Service |
102278 |
semanage_path(SEMANAGE_TMP,
|
|
Packit Service |
102278 |
SEMANAGE_SEUSERS_LOCAL),
|
|
Packit Service |
102278 |
semanage_seuser_dbase_local(sh)) < 0)
|
|
Packit Service |
102278 |
goto err;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (node_file_dbase_init(sh,
|
|
Packit Service |
102278 |
semanage_path(SEMANAGE_ACTIVE,
|
|
Packit Service |
102278 |
SEMANAGE_NODES_LOCAL),
|
|
Packit Service |
102278 |
semanage_path(SEMANAGE_TMP,
|
|
Packit Service |
102278 |
SEMANAGE_NODES_LOCAL),
|
|
Packit Service |
102278 |
semanage_node_dbase_local(sh)) < 0)
|
|
Packit Service |
102278 |
goto err;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (ibpkey_file_dbase_init(sh,
|
|
Packit Service |
102278 |
semanage_path(SEMANAGE_ACTIVE,
|
|
Packit Service |
102278 |
SEMANAGE_IBPKEYS_LOCAL),
|
|
Packit Service |
102278 |
semanage_path(SEMANAGE_TMP,
|
|
Packit Service |
102278 |
SEMANAGE_IBPKEYS_LOCAL),
|
|
Packit Service |
102278 |
semanage_ibpkey_dbase_local(sh)) < 0)
|
|
Packit Service |
102278 |
goto err;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (ibendport_file_dbase_init(sh,
|
|
Packit Service |
102278 |
semanage_path(SEMANAGE_ACTIVE,
|
|
Packit Service |
102278 |
SEMANAGE_IBENDPORTS_LOCAL),
|
|
Packit Service |
102278 |
semanage_path(SEMANAGE_TMP,
|
|
Packit Service |
102278 |
SEMANAGE_IBENDPORTS_LOCAL),
|
|
Packit Service |
102278 |
semanage_ibendport_dbase_local(sh)) < 0)
|
|
Packit Service |
102278 |
goto err;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* Object databases: local modifications + policy */
|
|
Packit Service |
102278 |
if (user_base_policydb_dbase_init(sh,
|
|
Packit Service |
102278 |
semanage_user_base_dbase_policy(sh)) <
|
|
Packit Service |
102278 |
0)
|
|
Packit Service |
102278 |
goto err;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (user_extra_file_dbase_init(sh,
|
|
Packit Service |
102278 |
semanage_path(SEMANAGE_ACTIVE,
|
|
Packit Service |
102278 |
SEMANAGE_USERS_EXTRA),
|
|
Packit Service |
102278 |
semanage_path(SEMANAGE_TMP,
|
|
Packit Service |
102278 |
SEMANAGE_USERS_EXTRA),
|
|
Packit Service |
102278 |
semanage_user_extra_dbase_policy(sh)) <
|
|
Packit Service |
102278 |
0)
|
|
Packit Service |
102278 |
goto err;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (user_join_dbase_init(sh,
|
|
Packit Service |
102278 |
semanage_user_base_dbase_policy(sh),
|
|
Packit Service |
102278 |
semanage_user_extra_dbase_policy(sh),
|
|
Packit Service |
102278 |
semanage_user_dbase_policy(sh)) < 0)
|
|
Packit Service |
102278 |
goto err;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (port_policydb_dbase_init(sh, semanage_port_dbase_policy(sh)) < 0)
|
|
Packit Service |
102278 |
goto err;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (ibpkey_policydb_dbase_init(sh, semanage_ibpkey_dbase_policy(sh)) < 0)
|
|
Packit Service |
102278 |
goto err;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (ibendport_policydb_dbase_init(sh, semanage_ibendport_dbase_policy(sh)) < 0)
|
|
Packit Service |
102278 |
goto err;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (iface_policydb_dbase_init(sh, semanage_iface_dbase_policy(sh)) < 0)
|
|
Packit Service |
102278 |
goto err;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (bool_policydb_dbase_init(sh, semanage_bool_dbase_policy(sh)) < 0)
|
|
Packit Service |
102278 |
goto err;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (fcontext_file_dbase_init(sh,
|
|
Packit Service |
102278 |
semanage_path(SEMANAGE_ACTIVE, SEMANAGE_STORE_FC),
|
|
Packit Service |
102278 |
semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC),
|
|
Packit Service |
102278 |
semanage_fcontext_dbase_policy(sh)) < 0)
|
|
Packit Service |
102278 |
goto err;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (seuser_file_dbase_init(sh,
|
|
Packit Service |
102278 |
semanage_path(SEMANAGE_ACTIVE, SEMANAGE_STORE_SEUSERS),
|
|
Packit Service |
102278 |
semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_SEUSERS),
|
|
Packit Service |
102278 |
semanage_seuser_dbase_policy(sh)) < 0)
|
|
Packit Service |
102278 |
goto err;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (node_policydb_dbase_init(sh, semanage_node_dbase_policy(sh)) < 0)
|
|
Packit Service |
102278 |
goto err;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* Active kernel policy */
|
|
Packit Service |
102278 |
if (bool_activedb_dbase_init(sh, semanage_bool_dbase_active(sh)) < 0)
|
|
Packit Service |
102278 |
goto err;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* set the disable dontaudit value */
|
|
Packit Service |
102278 |
path = semanage_path(SEMANAGE_ACTIVE, SEMANAGE_DISABLE_DONTAUDIT);
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (stat(path, &sb) == 0)
|
|
Packit Service |
102278 |
sepol_set_disable_dontaudit(sh->sepolh, 1);
|
|
Packit Service |
102278 |
else if (errno == ENOENT) {
|
|
Packit Service |
102278 |
/* The file does not exist */
|
|
Packit Service |
102278 |
sepol_set_disable_dontaudit(sh->sepolh, 0);
|
|
Packit Service |
102278 |
} else {
|
|
Packit Service |
102278 |
ERR(sh, "Unable to access %s: %s\n", path, strerror(errno));
|
|
Packit Service |
102278 |
goto err;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
return STATUS_SUCCESS;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
err:
|
|
Packit Service |
102278 |
ERR(sh, "could not establish direct connection");
|
|
Packit Service |
102278 |
return STATUS_ERR;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
static void semanage_direct_destroy(semanage_handle_t * sh
|
|
Packit Service |
102278 |
__attribute__ ((unused)))
|
|
Packit Service |
102278 |
{
|
|
Packit Service |
102278 |
/* do nothing */
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
static int semanage_remove_tmps(semanage_handle_t *sh)
|
|
Packit Service |
102278 |
{
|
|
Packit Service |
102278 |
if (sh->commit_err)
|
|
Packit Service |
102278 |
return 0;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* destroy sandbox if it exists */
|
|
Packit Service |
102278 |
if (semanage_remove_directory
|
|
Packit Service |
102278 |
(semanage_path(SEMANAGE_TMP, SEMANAGE_TOPLEVEL)) < 0) {
|
|
Packit Service |
102278 |
if (errno != ENOENT) {
|
|
Packit Service |
102278 |
ERR(sh, "Could not cleanly remove sandbox %s.",
|
|
Packit Service |
102278 |
semanage_path(SEMANAGE_TMP, SEMANAGE_TOPLEVEL));
|
|
Packit Service |
102278 |
return -1;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* destroy tmp policy if it exists */
|
|
Packit Service |
102278 |
if (semanage_remove_directory
|
|
Packit Service |
102278 |
(semanage_final_path(SEMANAGE_FINAL_TMP,
|
|
Packit Service |
102278 |
SEMANAGE_FINAL_TOPLEVEL)) < 0) {
|
|
Packit Service |
102278 |
if (errno != ENOENT) {
|
|
Packit Service |
102278 |
ERR(sh, "Could not cleanly remove tmp %s.",
|
|
Packit Service |
102278 |
semanage_final_path(SEMANAGE_FINAL_TMP,
|
|
Packit Service |
102278 |
SEMANAGE_FINAL_TOPLEVEL));
|
|
Packit Service |
102278 |
return -1;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
return 0;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
static int semanage_direct_disconnect(semanage_handle_t *sh)
|
|
Packit Service |
102278 |
{
|
|
Packit Service |
102278 |
int retval = 0;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* destroy transaction and remove tmp files if no commit error */
|
|
Packit Service |
102278 |
if (sh->is_in_transaction) {
|
|
Packit Service |
102278 |
retval = semanage_remove_tmps(sh);
|
|
Packit Service |
102278 |
semanage_release_trans_lock(sh);
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* Release object databases: local modifications */
|
|
Packit Service |
102278 |
user_base_file_dbase_release(semanage_user_base_dbase_local(sh));
|
|
Packit Service |
102278 |
user_extra_file_dbase_release(semanage_user_extra_dbase_local(sh));
|
|
Packit Service |
102278 |
user_join_dbase_release(semanage_user_dbase_local(sh));
|
|
Packit Service |
102278 |
port_file_dbase_release(semanage_port_dbase_local(sh));
|
|
Packit Service |
102278 |
ibpkey_file_dbase_release(semanage_ibpkey_dbase_local(sh));
|
|
Packit Service |
102278 |
ibendport_file_dbase_release(semanage_ibendport_dbase_local(sh));
|
|
Packit Service |
102278 |
iface_file_dbase_release(semanage_iface_dbase_local(sh));
|
|
Packit Service |
102278 |
bool_file_dbase_release(semanage_bool_dbase_local(sh));
|
|
Packit Service |
102278 |
fcontext_file_dbase_release(semanage_fcontext_dbase_local(sh));
|
|
Packit Service |
102278 |
fcontext_file_dbase_release(semanage_fcontext_dbase_homedirs(sh));
|
|
Packit Service |
102278 |
seuser_file_dbase_release(semanage_seuser_dbase_local(sh));
|
|
Packit Service |
102278 |
node_file_dbase_release(semanage_node_dbase_local(sh));
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* Release object databases: local modifications + policy */
|
|
Packit Service |
102278 |
user_base_policydb_dbase_release(semanage_user_base_dbase_policy(sh));
|
|
Packit Service |
102278 |
user_extra_file_dbase_release(semanage_user_extra_dbase_policy(sh));
|
|
Packit Service |
102278 |
user_join_dbase_release(semanage_user_dbase_policy(sh));
|
|
Packit Service |
102278 |
port_policydb_dbase_release(semanage_port_dbase_policy(sh));
|
|
Packit Service |
102278 |
ibpkey_policydb_dbase_release(semanage_ibpkey_dbase_policy(sh));
|
|
Packit Service |
102278 |
ibendport_policydb_dbase_release(semanage_ibendport_dbase_policy(sh));
|
|
Packit Service |
102278 |
iface_policydb_dbase_release(semanage_iface_dbase_policy(sh));
|
|
Packit Service |
102278 |
bool_policydb_dbase_release(semanage_bool_dbase_policy(sh));
|
|
Packit Service |
102278 |
fcontext_file_dbase_release(semanage_fcontext_dbase_policy(sh));
|
|
Packit Service |
102278 |
seuser_file_dbase_release(semanage_seuser_dbase_policy(sh));
|
|
Packit Service |
102278 |
node_policydb_dbase_release(semanage_node_dbase_policy(sh));
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* Release object databases: active kernel policy */
|
|
Packit Service |
102278 |
bool_activedb_dbase_release(semanage_bool_dbase_active(sh));
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
return retval;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
static int semanage_direct_begintrans(semanage_handle_t * sh)
|
|
Packit Service |
102278 |
{
|
|
Packit Service |
102278 |
if (semanage_get_trans_lock(sh) < 0) {
|
|
Packit Service |
102278 |
return -1;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
if ((semanage_make_sandbox(sh)) < 0) {
|
|
Packit Service |
102278 |
return -1;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
if ((semanage_make_final(sh)) < 0) {
|
|
Packit Service |
102278 |
return -1;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
return 0;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/********************* utility functions *********************/
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* Takes a module stored in 'module_data' and parses its headers.
|
|
Packit Service |
102278 |
* Sets reference variables 'module_name' to module's name, and
|
|
Packit Service |
102278 |
* 'version' to module's version. The caller is responsible for
|
|
Packit Service |
102278 |
* free()ing 'module_name', and 'version'; they will be
|
|
Packit Service |
102278 |
* set to NULL upon entering this function. Returns 0 on success, -1
|
|
Packit Service |
102278 |
* if out of memory.
|
|
Packit Service |
102278 |
*/
|
|
Packit Service |
102278 |
static int parse_module_headers(semanage_handle_t * sh, char *module_data,
|
|
Packit Service |
102278 |
size_t data_len, char **module_name,
|
|
Packit Service |
102278 |
char **version)
|
|
Packit Service |
102278 |
{
|
|
Packit Service |
102278 |
struct sepol_policy_file *pf;
|
|
Packit Service |
102278 |
int file_type;
|
|
Packit Service |
102278 |
*module_name = *version = NULL;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (sepol_policy_file_create(&pf)) {
|
|
Packit Service |
102278 |
ERR(sh, "Out of memory!");
|
|
Packit Service |
102278 |
return -1;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
sepol_policy_file_set_mem(pf, module_data, data_len);
|
|
Packit Service |
102278 |
sepol_policy_file_set_handle(pf, sh->sepolh);
|
|
Packit Service |
102278 |
if (module_data != NULL && data_len > 0)
|
|
Packit Service |
102278 |
sepol_module_package_info(pf, &file_type, module_name,
|
|
Packit Service |
102278 |
version);
|
|
Packit Service |
102278 |
sepol_policy_file_free(pf);
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
return 0;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
#include <stdlib.h>
|
|
Packit Service |
102278 |
#include <bzlib.h>
|
|
Packit Service |
102278 |
#include <string.h>
|
|
Packit Service |
102278 |
#include <sys/sendfile.h>
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* bzip() a data to a file, returning the total number of compressed bytes
|
|
Packit Service |
102278 |
* in the file. Returns -1 if file could not be compressed. */
|
|
Packit Service |
102278 |
static ssize_t bzip(semanage_handle_t *sh, const char *filename, char *data,
|
|
Packit Service |
102278 |
size_t num_bytes)
|
|
Packit Service |
102278 |
{
|
|
Packit Service |
102278 |
BZFILE* b;
|
|
Packit Service |
102278 |
size_t size = 1<<16;
|
|
Packit Service |
102278 |
int bzerror;
|
|
Packit Service |
102278 |
size_t total = 0;
|
|
Packit Service |
102278 |
size_t len = 0;
|
|
Packit Service |
102278 |
FILE *f;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if ((f = fopen(filename, "wb")) == NULL) {
|
|
Packit Service |
102278 |
return -1;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (!sh->conf->bzip_blocksize) {
|
|
Packit Service |
102278 |
if (fwrite(data, 1, num_bytes, f) < num_bytes) {
|
|
Packit Service |
102278 |
fclose(f);
|
|
Packit Service |
102278 |
return -1;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
fclose(f);
|
|
Packit Service |
102278 |
return num_bytes;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
b = BZ2_bzWriteOpen( &bzerror, f, sh->conf->bzip_blocksize, 0, 0);
|
|
Packit Service |
102278 |
if (bzerror != BZ_OK) {
|
|
Packit Service |
102278 |
BZ2_bzWriteClose ( &bzerror, b, 1, 0, 0 );
|
|
Packit Service |
102278 |
return -1;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
while ( num_bytes > total ) {
|
|
Packit Service |
102278 |
if (num_bytes - total > size) {
|
|
Packit Service |
102278 |
len = size;
|
|
Packit Service |
102278 |
} else {
|
|
Packit Service |
102278 |
len = num_bytes - total;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
BZ2_bzWrite ( &bzerror, b, &data[total], len );
|
|
Packit Service |
102278 |
if (bzerror == BZ_IO_ERROR) {
|
|
Packit Service |
102278 |
BZ2_bzWriteClose ( &bzerror, b, 1, 0, 0 );
|
|
Packit Service |
102278 |
return -1;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
total += len;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
BZ2_bzWriteClose ( &bzerror, b, 0, 0, 0 );
|
|
Packit Service |
102278 |
fclose(f);
|
|
Packit Service |
102278 |
if (bzerror == BZ_IO_ERROR) {
|
|
Packit Service |
102278 |
return -1;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
return total;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
#define BZ2_MAGICSTR "BZh"
|
|
Packit Service |
102278 |
#define BZ2_MAGICLEN (sizeof(BZ2_MAGICSTR)-1)
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* bunzip() a file to '*data', returning the total number of uncompressed bytes
|
|
Packit Service |
102278 |
* in the file. Returns -1 if file could not be decompressed. */
|
|
Packit Service |
102278 |
ssize_t bunzip(semanage_handle_t *sh, FILE *f, char **data)
|
|
Packit Service |
102278 |
{
|
|
Packit Service |
102278 |
BZFILE* b = NULL;
|
|
Packit Service |
102278 |
size_t nBuf;
|
|
Packit Service |
102278 |
char* buf = NULL;
|
|
Packit Service |
102278 |
size_t size = 1<<18;
|
|
Packit Service |
102278 |
size_t bufsize = size;
|
|
Packit Service |
102278 |
int bzerror;
|
|
Packit Service |
102278 |
size_t total=0;
|
|
Packit Service |
102278 |
char* uncompress = NULL;
|
|
Packit Service |
102278 |
char* tmpalloc = NULL;
|
|
Packit Service |
102278 |
int ret = -1;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
buf = malloc(bufsize);
|
|
Packit Service |
102278 |
if (buf == NULL) {
|
|
Packit Service |
102278 |
ERR(sh, "Failure allocating memory.");
|
|
Packit Service |
102278 |
goto exit;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* Check if the file is bzipped */
|
|
Packit Service |
102278 |
bzerror = fread(buf, 1, BZ2_MAGICLEN, f);
|
|
Packit Service |
102278 |
rewind(f);
|
|
Packit Service |
102278 |
if ((bzerror != BZ2_MAGICLEN) || memcmp(buf, BZ2_MAGICSTR, BZ2_MAGICLEN)) {
|
|
Packit Service |
102278 |
goto exit;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
b = BZ2_bzReadOpen ( &bzerror, f, 0, sh->conf->bzip_small, NULL, 0 );
|
|
Packit Service |
102278 |
if ( bzerror != BZ_OK ) {
|
|
Packit Service |
102278 |
ERR(sh, "Failure opening bz2 archive.");
|
|
Packit Service |
102278 |
goto exit;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
uncompress = malloc(size);
|
|
Packit Service |
102278 |
if (uncompress == NULL) {
|
|
Packit Service |
102278 |
ERR(sh, "Failure allocating memory.");
|
|
Packit Service |
102278 |
goto exit;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
while ( bzerror == BZ_OK) {
|
|
Packit Service |
102278 |
nBuf = BZ2_bzRead ( &bzerror, b, buf, bufsize);
|
|
Packit Service |
102278 |
if (( bzerror == BZ_OK ) || ( bzerror == BZ_STREAM_END )) {
|
|
Packit Service |
102278 |
if (total + nBuf > size) {
|
|
Packit Service |
102278 |
size *= 2;
|
|
Packit Service |
102278 |
tmpalloc = realloc(uncompress, size);
|
|
Packit Service |
102278 |
if (tmpalloc == NULL) {
|
|
Packit Service |
102278 |
ERR(sh, "Failure allocating memory.");
|
|
Packit Service |
102278 |
goto exit;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
uncompress = tmpalloc;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
memcpy(&uncompress[total], buf, nBuf);
|
|
Packit Service |
102278 |
total += nBuf;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
if ( bzerror != BZ_STREAM_END ) {
|
|
Packit Service |
102278 |
ERR(sh, "Failure reading bz2 archive.");
|
|
Packit Service |
102278 |
goto exit;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
ret = total;
|
|
Packit Service |
102278 |
*data = uncompress;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
exit:
|
|
Packit Service |
102278 |
BZ2_bzReadClose ( &bzerror, b );
|
|
Packit Service |
102278 |
free(buf);
|
|
Packit Service |
102278 |
if ( ret < 0 ) {
|
|
Packit Service |
102278 |
free(uncompress);
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
return ret;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* mmap() a file to '*data',
|
|
Packit Service |
102278 |
* If the file is bzip compressed map_file will uncompress
|
|
Packit Service |
102278 |
* the file into '*data'.
|
|
Packit Service |
102278 |
* Returns the total number of bytes in memory .
|
|
Packit Service |
102278 |
* Returns -1 if file could not be opened or mapped. */
|
|
Packit Service |
102278 |
static ssize_t map_file(semanage_handle_t *sh, const char *path, char **data,
|
|
Packit Service |
102278 |
int *compressed)
|
|
Packit Service |
102278 |
{
|
|
Packit Service |
102278 |
ssize_t size = -1;
|
|
Packit Service |
102278 |
char *uncompress;
|
|
Packit Service |
102278 |
int fd = -1;
|
|
Packit Service |
102278 |
FILE *file = NULL;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
fd = open(path, O_RDONLY);
|
|
Packit Service |
102278 |
if (fd == -1) {
|
|
Packit Service |
102278 |
ERR(sh, "Unable to open %s\n", path);
|
|
Packit Service |
102278 |
return -1;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
file = fdopen(fd, "r");
|
|
Packit Service |
102278 |
if (file == NULL) {
|
|
Packit Service |
102278 |
ERR(sh, "Unable to open %s\n", path);
|
|
Packit Service |
102278 |
close(fd);
|
|
Packit Service |
102278 |
return -1;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if ((size = bunzip(sh, file, &uncompress)) > 0) {
|
|
Packit Service |
102278 |
*data = mmap(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
|
|
Packit Service |
102278 |
if (*data == MAP_FAILED) {
|
|
Packit Service |
102278 |
free(uncompress);
|
|
Packit Service |
102278 |
fclose(file);
|
|
Packit Service |
102278 |
return -1;
|
|
Packit Service |
102278 |
} else {
|
|
Packit Service |
102278 |
memcpy(*data, uncompress, size);
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
free(uncompress);
|
|
Packit Service |
102278 |
*compressed = 1;
|
|
Packit Service |
102278 |
} else {
|
|
Packit Service |
102278 |
struct stat sb;
|
|
Packit Service |
102278 |
if (fstat(fd, &sb) == -1 ||
|
|
Packit Service |
102278 |
(*data = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0)) ==
|
|
Packit Service |
102278 |
MAP_FAILED) {
|
|
Packit Service |
102278 |
size = -1;
|
|
Packit Service |
102278 |
} else {
|
|
Packit Service |
102278 |
size = sb.st_size;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
*compressed = 0;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
fclose(file);
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
return size;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* Writes a block of data to a file. Returns 0 on success, -1 on
|
|
Packit Service |
102278 |
* error. */
|
|
Packit Service |
102278 |
static int write_file(semanage_handle_t * sh,
|
|
Packit Service |
102278 |
const char *filename, char *data, size_t num_bytes)
|
|
Packit Service |
102278 |
{
|
|
Packit Service |
102278 |
int out;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if ((out =
|
|
Packit Service |
102278 |
open(filename, O_WRONLY | O_CREAT | O_TRUNC,
|
|
Packit Service |
102278 |
S_IRUSR | S_IWUSR)) == -1) {
|
|
Packit Service |
102278 |
ERR(sh, "Could not open %s for writing.", filename);
|
|
Packit Service |
102278 |
return -1;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
if (write(out, data, num_bytes) == -1) {
|
|
Packit Service |
102278 |
ERR(sh, "Error while writing to %s.", filename);
|
|
Packit Service |
102278 |
close(out);
|
|
Packit Service |
102278 |
return -1;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
close(out);
|
|
Packit Service |
102278 |
return 0;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
static int semanage_direct_update_user_extra(semanage_handle_t * sh, cil_db_t *cildb)
|
|
Packit Service |
102278 |
{
|
|
Packit Service |
102278 |
const char *ofilename = NULL;
|
|
Packit Service |
102278 |
int retval = -1;
|
|
Packit Service |
102278 |
char *data = NULL;
|
|
Packit Service |
102278 |
size_t size = 0;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
dbase_config_t *pusers_extra = semanage_user_extra_dbase_policy(sh);
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
retval = cil_userprefixes_to_string(cildb, &data, &size);
|
|
Packit Service |
102278 |
if (retval != SEPOL_OK) {
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (size > 0) {
|
|
Packit Service |
102278 |
/*
|
|
Packit Service |
102278 |
* Write the users_extra entries from CIL modules.
|
|
Packit Service |
102278 |
* This file is used as our baseline when we do not require
|
|
Packit Service |
102278 |
* re-linking.
|
|
Packit Service |
102278 |
*/
|
|
Packit Service |
102278 |
ofilename = semanage_path(SEMANAGE_TMP,
|
|
Packit Service |
102278 |
SEMANAGE_USERS_EXTRA_LINKED);
|
|
Packit Service |
102278 |
if (ofilename == NULL) {
|
|
Packit Service |
102278 |
retval = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
retval = write_file(sh, ofilename, data, size);
|
|
Packit Service |
102278 |
if (retval < 0)
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/*
|
|
Packit Service |
102278 |
* Write the users_extra file; users_extra.local
|
|
Packit Service |
102278 |
* will be merged into this file.
|
|
Packit Service |
102278 |
*/
|
|
Packit Service |
102278 |
ofilename = semanage_path(SEMANAGE_TMP, SEMANAGE_USERS_EXTRA);
|
|
Packit Service |
102278 |
if (ofilename == NULL) {
|
|
Packit Service |
102278 |
retval = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
retval = write_file(sh, ofilename, data, size);
|
|
Packit Service |
102278 |
if (retval < 0)
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
pusers_extra->dtable->drop_cache(pusers_extra->dbase);
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
} else {
|
|
Packit Service |
102278 |
retval = pusers_extra->dtable->clear(sh, pusers_extra->dbase);
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
cleanup:
|
|
Packit Service |
102278 |
free(data);
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
return retval;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
static int semanage_direct_update_seuser(semanage_handle_t * sh, cil_db_t *cildb)
|
|
Packit Service |
102278 |
{
|
|
Packit Service |
102278 |
const char *ofilename = NULL;
|
|
Packit Service |
102278 |
int retval = -1;
|
|
Packit Service |
102278 |
char *data = NULL;
|
|
Packit Service |
102278 |
size_t size = 0;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
dbase_config_t *pseusers = semanage_seuser_dbase_policy(sh);
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
retval = cil_selinuxusers_to_string(cildb, &data, &size);
|
|
Packit Service |
102278 |
if (retval != SEPOL_OK) {
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (size > 0) {
|
|
Packit Service |
102278 |
/*
|
|
Packit Service |
102278 |
* Write the seusers entries from CIL modules.
|
|
Packit Service |
102278 |
* This file is used as our baseline when we do not require
|
|
Packit Service |
102278 |
* re-linking.
|
|
Packit Service |
102278 |
*/
|
|
Packit Service |
102278 |
ofilename = semanage_path(SEMANAGE_TMP,
|
|
Packit Service |
102278 |
SEMANAGE_SEUSERS_LINKED);
|
|
Packit Service |
102278 |
if (ofilename == NULL) {
|
|
Packit Service |
102278 |
retval = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
retval = write_file(sh, ofilename, data, size);
|
|
Packit Service |
102278 |
if (retval < 0)
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/*
|
|
Packit Service |
102278 |
* Write the seusers file; seusers.local will be merged into
|
|
Packit Service |
102278 |
* this file.
|
|
Packit Service |
102278 |
*/
|
|
Packit Service |
102278 |
ofilename = semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_SEUSERS);
|
|
Packit Service |
102278 |
if (ofilename == NULL) {
|
|
Packit Service |
102278 |
retval = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
retval = write_file(sh, ofilename, data, size);
|
|
Packit Service |
102278 |
if (retval < 0)
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
pseusers->dtable->drop_cache(pseusers->dbase);
|
|
Packit Service |
102278 |
} else {
|
|
Packit Service |
102278 |
retval = pseusers->dtable->clear(sh, pseusers->dbase);
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
cleanup:
|
|
Packit Service |
102278 |
free(data);
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
return retval;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
static int read_from_pipe_to_data(semanage_handle_t *sh, size_t initial_len, int fd, char **out_data_read, size_t *out_read_len)
|
|
Packit Service |
102278 |
{
|
|
Packit Service |
102278 |
size_t max_len = initial_len;
|
|
Packit Service |
102278 |
size_t read_len = 0;
|
|
Packit Service |
102278 |
size_t data_read_len = 0;
|
|
Packit Service |
102278 |
char *data_read = NULL;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (max_len <= 0) {
|
|
Packit Service |
102278 |
max_len = 1;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
data_read = malloc(max_len * sizeof(*data_read));
|
|
Packit Service |
102278 |
if (data_read == NULL) {
|
|
Packit Service |
102278 |
ERR(sh, "Failed to malloc, out of memory.\n");
|
|
Packit Service |
102278 |
return -1;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
while ((read_len = read(fd, data_read + data_read_len, max_len - data_read_len)) > 0) {
|
|
Packit Service |
102278 |
data_read_len += read_len;
|
|
Packit Service |
102278 |
if (data_read_len == max_len) {
|
|
Packit Service |
102278 |
max_len *= 2;
|
|
Packit Service |
102278 |
data_read = realloc(data_read, max_len);
|
|
Packit Service |
102278 |
if (data_read == NULL) {
|
|
Packit Service |
102278 |
ERR(sh, "Failed to realloc, out of memory.\n");
|
|
Packit Service |
102278 |
return -1;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
*out_read_len = data_read_len;
|
|
Packit Service |
102278 |
*out_data_read = data_read;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
return 0;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
static int semanage_pipe_data(semanage_handle_t *sh, char *path, char *in_data, size_t in_data_len, char **out_data, size_t *out_data_len, char **err_data, size_t *err_data_len)
|
|
Packit Service |
102278 |
{
|
|
Packit Service |
102278 |
int input_fd[2] = {-1, -1};
|
|
Packit Service |
102278 |
int output_fd[2] = {-1, -1};
|
|
Packit Service |
102278 |
int err_fd[2] = {-1, -1};
|
|
Packit Service |
102278 |
pid_t pid;
|
|
Packit Service |
102278 |
char *data_read = NULL;
|
|
Packit Service |
102278 |
char *err_data_read = NULL;
|
|
Packit Service |
102278 |
int retval;
|
|
Packit Service |
102278 |
int status = 0;
|
|
Packit Service |
102278 |
size_t initial_len;
|
|
Packit Service |
102278 |
size_t data_read_len = 0;
|
|
Packit Service |
102278 |
size_t err_data_read_len = 0;
|
|
Packit Service |
102278 |
struct sigaction old_signal;
|
|
Packit Service |
102278 |
struct sigaction new_signal;
|
|
Packit Service |
102278 |
new_signal.sa_handler = SIG_IGN;
|
|
Packit Service |
102278 |
sigemptyset(&new_signal.sa_mask);
|
|
Packit Service |
102278 |
new_signal.sa_flags = 0;
|
|
Packit Service |
102278 |
/* This is needed in case the read end of input_fd is closed causing a SIGPIPE signal to be sent.
|
|
Packit Service |
102278 |
* If SIGPIPE is not caught, the signal will cause semanage to terminate immediately. The sigaction below
|
|
Packit Service |
102278 |
* creates a new_signal that ignores SIGPIPE allowing the write to exit cleanly.
|
|
Packit Service |
102278 |
*
|
|
Packit Service |
102278 |
* Another sigaction is called in cleanup to restore the original behavior when a SIGPIPE is received.
|
|
Packit Service |
102278 |
*/
|
|
Packit Service |
102278 |
sigaction(SIGPIPE, &new_signal, &old_signal);
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
retval = pipe(input_fd);
|
|
Packit Service |
102278 |
if (retval == -1) {
|
|
Packit Service |
102278 |
ERR(sh, "Unable to create pipe for input pipe: %s\n", strerror(errno));
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
retval = pipe(output_fd);
|
|
Packit Service |
102278 |
if (retval == -1) {
|
|
Packit Service |
102278 |
ERR(sh, "Unable to create pipe for output pipe: %s\n", strerror(errno));
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
retval = pipe(err_fd);
|
|
Packit Service |
102278 |
if (retval == -1) {
|
|
Packit Service |
102278 |
ERR(sh, "Unable to create pipe for error pipe: %s\n", strerror(errno));
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
pid = fork();
|
|
Packit Service |
102278 |
if (pid == -1) {
|
|
Packit Service |
102278 |
ERR(sh, "Unable to fork from parent: %s.", strerror(errno));
|
|
Packit Service |
102278 |
retval = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
} else if (pid == 0) {
|
|
Packit Service |
102278 |
retval = dup2(input_fd[PIPE_READ], STDIN_FILENO);
|
|
Packit Service |
102278 |
if (retval == -1) {
|
|
Packit Service |
102278 |
ERR(sh, "Unable to dup2 input pipe: %s\n", strerror(errno));
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
retval = dup2(output_fd[PIPE_WRITE], STDOUT_FILENO);
|
|
Packit Service |
102278 |
if (retval == -1) {
|
|
Packit Service |
102278 |
ERR(sh, "Unable to dup2 output pipe: %s\n", strerror(errno));
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
retval = dup2(err_fd[PIPE_WRITE], STDERR_FILENO);
|
|
Packit Service |
102278 |
if (retval == -1) {
|
|
Packit Service |
102278 |
ERR(sh, "Unable to dup2 error pipe: %s\n", strerror(errno));
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
retval = close(input_fd[PIPE_WRITE]);
|
|
Packit Service |
102278 |
if (retval == -1) {
|
|
Packit Service |
102278 |
ERR(sh, "Unable to close input pipe: %s\n", strerror(errno));
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
retval = close(output_fd[PIPE_READ]);
|
|
Packit Service |
102278 |
if (retval == -1) {
|
|
Packit Service |
102278 |
ERR(sh, "Unable to close output pipe: %s\n", strerror(errno));
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
retval = close(err_fd[PIPE_READ]);
|
|
Packit Service |
102278 |
if (retval == -1) {
|
|
Packit Service |
102278 |
ERR(sh, "Unable to close error pipe: %s\n", strerror(errno));
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
retval = execl(path, path, NULL);
|
|
Packit Service |
102278 |
if (retval == -1) {
|
|
Packit Service |
102278 |
ERR(sh, "Unable to execute %s : %s\n", path, strerror(errno));
|
|
Packit Service |
102278 |
_exit(EXIT_FAILURE);
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
} else {
|
|
Packit Service |
102278 |
retval = close(input_fd[PIPE_READ]);
|
|
Packit Service |
102278 |
input_fd[PIPE_READ] = -1;
|
|
Packit Service |
102278 |
if (retval == -1) {
|
|
Packit Service |
102278 |
ERR(sh, "Unable to close read end of input pipe: %s\n", strerror(errno));
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
retval = close(output_fd[PIPE_WRITE]);
|
|
Packit Service |
102278 |
output_fd[PIPE_WRITE] = -1;
|
|
Packit Service |
102278 |
if (retval == -1) {
|
|
Packit Service |
102278 |
ERR(sh, "Unable to close write end of output pipe: %s\n", strerror(errno));
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
retval = close(err_fd[PIPE_WRITE]);
|
|
Packit Service |
102278 |
err_fd[PIPE_WRITE] = -1;
|
|
Packit Service |
102278 |
if (retval == -1) {
|
|
Packit Service |
102278 |
ERR(sh, "Unable to close write end of error pipe: %s\n", strerror(errno));
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
retval = write(input_fd[PIPE_WRITE], in_data, in_data_len);
|
|
Packit Service |
102278 |
if (retval == -1) {
|
|
Packit Service |
102278 |
ERR(sh, "Failed to write data to input pipe: %s\n", strerror(errno));
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
retval = close(input_fd[PIPE_WRITE]);
|
|
Packit Service |
102278 |
input_fd[PIPE_WRITE] = -1;
|
|
Packit Service |
102278 |
if (retval == -1) {
|
|
Packit Service |
102278 |
ERR(sh, "Unable to close write end of input pipe: %s\n", strerror(errno));
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
initial_len = 1 << 17;
|
|
Packit Service |
102278 |
retval = read_from_pipe_to_data(sh, initial_len, output_fd[PIPE_READ], &data_read, &data_read_len);
|
|
Packit Service |
102278 |
if (retval != 0) {
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
retval = close(output_fd[PIPE_READ]);
|
|
Packit Service |
102278 |
output_fd[PIPE_READ] = -1;
|
|
Packit Service |
102278 |
if (retval == -1) {
|
|
Packit Service |
102278 |
ERR(sh, "Unable to close read end of output pipe: %s\n", strerror(errno));
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
initial_len = 1 << 9;
|
|
Packit Service |
102278 |
retval = read_from_pipe_to_data(sh, initial_len, err_fd[PIPE_READ], &err_data_read, &err_data_read_len);
|
|
Packit Service |
102278 |
if (retval != 0) {
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
retval = close(err_fd[PIPE_READ]);
|
|
Packit Service |
102278 |
err_fd[PIPE_READ] = -1;
|
|
Packit Service |
102278 |
if (retval == -1) {
|
|
Packit Service |
102278 |
ERR(sh, "Unable to close read end of error pipe: %s\n", strerror(errno));
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (waitpid(pid, &status, 0) == -1 || !WIFEXITED(status)) {
|
|
Packit Service |
102278 |
ERR(sh, "Child process %s did not exit cleanly.", path);
|
|
Packit Service |
102278 |
retval = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
if (WEXITSTATUS(status) != 0) {
|
|
Packit Service |
102278 |
ERR(sh, "Child process %s failed with code: %d.", path, WEXITSTATUS(status));
|
|
Packit Service |
102278 |
retval = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
retval = 0;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
cleanup:
|
|
Packit Service |
102278 |
sigaction(SIGPIPE, &old_signal, NULL);
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (data_read != NULL) {
|
|
Packit Service |
102278 |
*out_data = data_read;
|
|
Packit Service |
102278 |
*out_data_len = data_read_len;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (err_data_read != NULL) {
|
|
Packit Service |
102278 |
*err_data = err_data_read;
|
|
Packit Service |
102278 |
*err_data_len = err_data_read_len;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (output_fd[PIPE_READ] != -1) {
|
|
Packit Service |
102278 |
close(output_fd[PIPE_READ]);
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
if (output_fd[PIPE_WRITE] != -1) {
|
|
Packit Service |
102278 |
close(output_fd[PIPE_WRITE]);
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
if (err_fd[PIPE_READ] != -1) {
|
|
Packit Service |
102278 |
close(err_fd[PIPE_READ]);
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
if (err_fd[PIPE_WRITE] != -1) {
|
|
Packit Service |
102278 |
close(err_fd[PIPE_WRITE]);
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
if (input_fd[PIPE_READ] != -1) {
|
|
Packit Service |
102278 |
close(input_fd[PIPE_READ]);
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
if (input_fd[PIPE_WRITE] != -1) {
|
|
Packit Service |
102278 |
close(input_fd[PIPE_WRITE]);
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
return retval;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
static int semanage_direct_write_langext(semanage_handle_t *sh,
|
|
Packit Service |
102278 |
const char *lang_ext,
|
|
Packit Service |
102278 |
const semanage_module_info_t *modinfo)
|
|
Packit Service |
102278 |
{
|
|
Packit Service |
102278 |
int ret = -1;
|
|
Packit Service |
102278 |
char fn[PATH_MAX];
|
|
Packit Service |
102278 |
FILE *fp = NULL;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
ret = semanage_module_get_path(sh,
|
|
Packit Service |
102278 |
modinfo,
|
|
Packit Service |
102278 |
SEMANAGE_MODULE_PATH_LANG_EXT,
|
|
Packit Service |
102278 |
fn,
|
|
Packit Service |
102278 |
sizeof(fn));
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
fp = fopen(fn, "w");
|
|
Packit Service |
102278 |
if (fp == NULL) {
|
|
Packit Service |
102278 |
ERR(sh, "Unable to open %s module ext file.", modinfo->name);
|
|
Packit Service |
102278 |
ret = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (fputs(lang_ext, fp) < 0) {
|
|
Packit Service |
102278 |
ERR(sh, "Unable to write %s module ext file.", modinfo->name);
|
|
Packit Service |
102278 |
ret = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (fclose(fp) != 0) {
|
|
Packit Service |
102278 |
ERR(sh, "Unable to close %s module ext file.", modinfo->name);
|
|
Packit Service |
102278 |
ret = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
fp = NULL;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
return 0;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
cleanup:
|
|
Packit Service |
102278 |
if (fp != NULL) fclose(fp);
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
return ret;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
static int semanage_compile_module(semanage_handle_t *sh,
|
|
Packit Service |
102278 |
semanage_module_info_t *modinfo)
|
|
Packit Service |
102278 |
{
|
|
Packit Service |
102278 |
char cil_path[PATH_MAX];
|
|
Packit Service |
102278 |
char hll_path[PATH_MAX];
|
|
Packit Service |
102278 |
char *compiler_path = NULL;
|
|
Packit Service |
102278 |
char *cil_data = NULL;
|
|
Packit Service |
102278 |
char *err_data = NULL;
|
|
Packit Service |
102278 |
char *hll_data = NULL;
|
|
Packit Service |
102278 |
char *start = NULL;
|
|
Packit Service |
102278 |
char *end = NULL;
|
|
Packit Service |
102278 |
ssize_t hll_data_len = 0;
|
|
Packit Service |
102278 |
ssize_t bzip_status;
|
|
Packit Service |
102278 |
int status = 0;
|
|
Packit Service |
102278 |
int compressed;
|
|
Packit Service |
102278 |
size_t cil_data_len = 0;
|
|
Packit Service |
102278 |
size_t err_data_len = 0;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (!strcasecmp(modinfo->lang_ext, "cil")) {
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
status = semanage_get_hll_compiler_path(sh, modinfo->lang_ext, &compiler_path);
|
|
Packit Service |
102278 |
if (status != 0) {
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
status = semanage_module_get_path(
|
|
Packit Service |
102278 |
sh,
|
|
Packit Service |
102278 |
modinfo,
|
|
Packit Service |
102278 |
SEMANAGE_MODULE_PATH_CIL,
|
|
Packit Service |
102278 |
cil_path,
|
|
Packit Service |
102278 |
sizeof(cil_path));
|
|
Packit Service |
102278 |
if (status != 0) {
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
status = semanage_module_get_path(
|
|
Packit Service |
102278 |
sh,
|
|
Packit Service |
102278 |
modinfo,
|
|
Packit Service |
102278 |
SEMANAGE_MODULE_PATH_HLL,
|
|
Packit Service |
102278 |
hll_path,
|
|
Packit Service |
102278 |
sizeof(hll_path));
|
|
Packit Service |
102278 |
if (status != 0) {
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if ((hll_data_len = map_file(sh, hll_path, &hll_data, &compressed)) <= 0) {
|
|
Packit Service |
102278 |
ERR(sh, "Unable to read file %s\n", hll_path);
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
status = semanage_pipe_data(sh, compiler_path, hll_data, (size_t)hll_data_len, &cil_data, &cil_data_len, &err_data, &err_data_len);
|
|
Packit Service |
102278 |
if (err_data_len > 0) {
|
|
Packit Service |
102278 |
for (start = end = err_data; end < err_data + err_data_len; end++) {
|
|
Packit Service |
102278 |
if (*end == '\n') {
|
|
Packit Service |
102278 |
fprintf(stderr, "%s: ", modinfo->name);
|
|
Packit Service |
102278 |
fwrite(start, 1, end - start + 1, stderr);
|
|
Packit Service |
102278 |
start = end + 1;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (end != start) {
|
|
Packit Service |
102278 |
fprintf(stderr, "%s: ", modinfo->name);
|
|
Packit Service |
102278 |
fwrite(start, 1, end - start, stderr);
|
|
Packit Service |
102278 |
fprintf(stderr, "\n");
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
if (status != 0) {
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
bzip_status = bzip(sh, cil_path, cil_data, cil_data_len);
|
|
Packit Service |
102278 |
if (bzip_status == -1) {
|
|
Packit Service |
102278 |
ERR(sh, "Failed to bzip %s\n", cil_path);
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (sh->conf->remove_hll == 1) {
|
|
Packit Service |
102278 |
status = unlink(hll_path);
|
|
Packit Service |
102278 |
if (status != 0) {
|
|
Packit Service |
102278 |
ERR(sh, "Error while removing HLL file %s: %s", hll_path, strerror(errno));
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
status = semanage_direct_write_langext(sh, "cil", modinfo);
|
|
Packit Service |
102278 |
if (status != 0) {
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
cleanup:
|
|
Packit Service |
102278 |
if (hll_data_len > 0) {
|
|
Packit Service |
102278 |
munmap(hll_data, hll_data_len);
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
free(cil_data);
|
|
Packit Service |
102278 |
free(err_data);
|
|
Packit Service |
102278 |
free(compiler_path);
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
return status;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
static int semanage_compile_hll_modules(semanage_handle_t *sh,
|
|
Packit Service |
102278 |
semanage_module_info_t *modinfos,
|
|
Packit Service |
102278 |
int num_modinfos)
|
|
Packit Service |
102278 |
{
|
|
Packit Service |
102278 |
int status = 0;
|
|
Packit Service |
102278 |
int i;
|
|
Packit Service |
102278 |
char cil_path[PATH_MAX];
|
|
Packit Service |
102278 |
struct stat sb;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
assert(sh);
|
|
Packit Service |
102278 |
assert(modinfos);
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
for (i = 0; i < num_modinfos; i++) {
|
|
Packit Service |
102278 |
status = semanage_module_get_path(
|
|
Packit Service |
102278 |
sh,
|
|
Packit Service |
102278 |
&modinfos[i],
|
|
Packit Service |
102278 |
SEMANAGE_MODULE_PATH_CIL,
|
|
Packit Service |
102278 |
cil_path,
|
|
Packit Service |
102278 |
sizeof(cil_path));
|
|
Packit Service |
102278 |
if (status != 0) {
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (semanage_get_ignore_module_cache(sh) == 0 &&
|
|
Packit Service |
102278 |
(status = stat(cil_path, &sb)) == 0) {
|
|
Packit Service |
102278 |
continue;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
if (status != 0 && errno != ENOENT) {
|
|
Packit Service |
102278 |
ERR(sh, "Unable to access %s: %s\n", cil_path, strerror(errno));
|
|
Packit Service |
102278 |
goto cleanup; //an error in the "stat" call
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
status = semanage_compile_module(sh, &modinfos[i]);
|
|
Packit Service |
102278 |
if (status < 0) {
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
status = 0;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
cleanup:
|
|
Packit Service |
102278 |
return status;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* Copies a file from src to dst. If dst already exists then
|
|
Packit Service |
102278 |
* overwrite it. If source doesn't exist then return success.
|
|
Packit Service |
102278 |
* Returns 0 on success, -1 on error. */
|
|
Packit Service |
102278 |
static int copy_file_if_exists(const char *src, const char *dst, mode_t mode){
|
|
Packit Service |
102278 |
int rc = semanage_copy_file(src, dst, mode, false);
|
|
Packit Service |
102278 |
return (rc < 0 && errno != ENOENT) ? rc : 0;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/********************* direct API functions ********************/
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* Commits all changes in sandbox to the actual kernel policy.
|
|
Packit Service |
102278 |
* Returns commit number on success, -1 on error.
|
|
Packit Service |
102278 |
*/
|
|
Packit Service |
102278 |
static int semanage_direct_commit(semanage_handle_t * sh)
|
|
Packit Service |
102278 |
{
|
|
Packit Service |
102278 |
char **mod_filenames = NULL;
|
|
Packit Service |
102278 |
char *fc_buffer = NULL;
|
|
Packit Service |
102278 |
size_t fc_buffer_len = 0;
|
|
Packit Service |
102278 |
const char *ofilename = NULL;
|
|
Packit Service |
102278 |
const char *path;
|
|
Packit Service |
102278 |
int retval = -1, num_modinfos = 0, i;
|
|
Packit Service |
102278 |
sepol_policydb_t *out = NULL;
|
|
Packit Service |
102278 |
struct cil_db *cildb = NULL;
|
|
Packit Service |
102278 |
semanage_module_info_t *modinfos = NULL;
|
|
Packit Service |
102278 |
mode_t mask = umask(0077);
|
|
Packit Service |
102278 |
struct stat sb;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
int do_rebuild, do_write_kernel, do_install;
|
|
Packit Service |
102278 |
int fcontexts_modified, ports_modified, seusers_modified,
|
|
Packit Service |
102278 |
disable_dontaudit, preserve_tunables, ibpkeys_modified,
|
|
Packit Service |
102278 |
ibendports_modified;
|
|
Packit Service |
102278 |
dbase_config_t *users = semanage_user_dbase_local(sh);
|
|
Packit Service |
102278 |
dbase_config_t *users_base = semanage_user_base_dbase_local(sh);
|
|
Packit Service |
102278 |
dbase_config_t *pusers_base = semanage_user_base_dbase_policy(sh);
|
|
Packit Service |
102278 |
dbase_config_t *pusers_extra = semanage_user_extra_dbase_policy(sh);
|
|
Packit Service |
102278 |
dbase_config_t *ports = semanage_port_dbase_local(sh);
|
|
Packit Service |
102278 |
dbase_config_t *pports = semanage_port_dbase_policy(sh);
|
|
Packit Service |
102278 |
dbase_config_t *ibpkeys = semanage_ibpkey_dbase_local(sh);
|
|
Packit Service |
102278 |
dbase_config_t *pibpkeys = semanage_ibpkey_dbase_policy(sh);
|
|
Packit Service |
102278 |
dbase_config_t *ibendports = semanage_ibendport_dbase_local(sh);
|
|
Packit Service |
102278 |
dbase_config_t *pibendports = semanage_ibendport_dbase_policy(sh);
|
|
Packit Service |
102278 |
dbase_config_t *bools = semanage_bool_dbase_local(sh);
|
|
Packit Service |
102278 |
dbase_config_t *pbools = semanage_bool_dbase_policy(sh);
|
|
Packit Service |
102278 |
dbase_config_t *ifaces = semanage_iface_dbase_local(sh);
|
|
Packit Service |
102278 |
dbase_config_t *pifaces = semanage_iface_dbase_policy(sh);
|
|
Packit Service |
102278 |
dbase_config_t *nodes = semanage_node_dbase_local(sh);
|
|
Packit Service |
102278 |
dbase_config_t *pnodes = semanage_node_dbase_policy(sh);
|
|
Packit Service |
102278 |
dbase_config_t *fcontexts = semanage_fcontext_dbase_local(sh);
|
|
Packit Service |
102278 |
dbase_config_t *pfcontexts = semanage_fcontext_dbase_policy(sh);
|
|
Packit Service |
102278 |
dbase_config_t *seusers = semanage_seuser_dbase_local(sh);
|
|
Packit Service |
102278 |
dbase_config_t *pseusers = semanage_seuser_dbase_policy(sh);
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* Modified flags that we need to use more than once. */
|
|
Packit Service |
102278 |
ports_modified = ports->dtable->is_modified(ports->dbase);
|
|
Packit Service |
102278 |
ibpkeys_modified = ibpkeys->dtable->is_modified(ibpkeys->dbase);
|
|
Packit Service |
102278 |
ibendports_modified = ibendports->dtable->is_modified(ibendports->dbase);
|
|
Packit Service |
102278 |
seusers_modified = seusers->dtable->is_modified(seusers->dbase);
|
|
Packit Service |
102278 |
fcontexts_modified = fcontexts->dtable->is_modified(fcontexts->dbase);
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* Rebuild if explicitly requested or any module changes occurred. */
|
|
Packit Service |
102278 |
do_rebuild = sh->do_rebuild | sh->modules_modified;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* Create or remove the disable_dontaudit flag file. */
|
|
Packit Service |
102278 |
path = semanage_path(SEMANAGE_TMP, SEMANAGE_DISABLE_DONTAUDIT);
|
|
Packit Service |
102278 |
if (stat(path, &sb) == 0)
|
|
Packit Service |
102278 |
do_rebuild |= !(sepol_get_disable_dontaudit(sh->sepolh) == 1);
|
|
Packit Service |
102278 |
else if (errno == ENOENT) {
|
|
Packit Service |
102278 |
/* The file does not exist */
|
|
Packit Service |
102278 |
do_rebuild |= (sepol_get_disable_dontaudit(sh->sepolh) == 1);
|
|
Packit Service |
102278 |
} else {
|
|
Packit Service |
102278 |
ERR(sh, "Unable to access %s: %s\n", path, strerror(errno));
|
|
Packit Service |
102278 |
retval = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
if (sepol_get_disable_dontaudit(sh->sepolh) == 1) {
|
|
Packit Service |
102278 |
FILE *touch;
|
|
Packit Service |
102278 |
touch = fopen(path, "w");
|
|
Packit Service |
102278 |
if (touch != NULL) {
|
|
Packit Service |
102278 |
if (fclose(touch) != 0) {
|
|
Packit Service |
102278 |
ERR(sh, "Error attempting to create disable_dontaudit flag.");
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
} else {
|
|
Packit Service |
102278 |
ERR(sh, "Error attempting to create disable_dontaudit flag.");
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
} else {
|
|
Packit Service |
102278 |
if (remove(path) == -1 && errno != ENOENT) {
|
|
Packit Service |
102278 |
ERR(sh, "Error removing the disable_dontaudit flag.");
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* Create or remove the preserve_tunables flag file. */
|
|
Packit Service |
102278 |
path = semanage_path(SEMANAGE_TMP, SEMANAGE_PRESERVE_TUNABLES);
|
|
Packit Service |
102278 |
if (stat(path, &sb) == 0)
|
|
Packit Service |
102278 |
do_rebuild |= !(sepol_get_preserve_tunables(sh->sepolh) == 1);
|
|
Packit Service |
102278 |
else if (errno == ENOENT) {
|
|
Packit Service |
102278 |
/* The file does not exist */
|
|
Packit Service |
102278 |
do_rebuild |= (sepol_get_preserve_tunables(sh->sepolh) == 1);
|
|
Packit Service |
102278 |
} else {
|
|
Packit Service |
102278 |
ERR(sh, "Unable to access %s: %s\n", path, strerror(errno));
|
|
Packit Service |
102278 |
retval = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (sepol_get_preserve_tunables(sh->sepolh) == 1) {
|
|
Packit Service |
102278 |
FILE *touch;
|
|
Packit Service |
102278 |
touch = fopen(path, "w");
|
|
Packit Service |
102278 |
if (touch != NULL) {
|
|
Packit Service |
102278 |
if (fclose(touch) != 0) {
|
|
Packit Service |
102278 |
ERR(sh, "Error attempting to create preserve_tunable flag.");
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
} else {
|
|
Packit Service |
102278 |
ERR(sh, "Error attempting to create preserve_tunable flag.");
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
} else {
|
|
Packit Service |
102278 |
if (remove(path) == -1 && errno != ENOENT) {
|
|
Packit Service |
102278 |
ERR(sh, "Error removing the preserve_tunables flag.");
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* Before we do anything else, flush the join to its component parts.
|
|
Packit Service |
102278 |
* This *does not* flush to disk automatically */
|
|
Packit Service |
102278 |
if (users->dtable->is_modified(users->dbase)) {
|
|
Packit Service |
102278 |
retval = users->dtable->flush(sh, users->dbase);
|
|
Packit Service |
102278 |
if (retval < 0)
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/*
|
|
Packit Service |
102278 |
* This is for systems that have already migrated with an older version
|
|
Packit Service |
102278 |
* of semanage_migrate_store. The older version did not copy
|
|
Packit Service |
102278 |
* policy.kern so the policy binary must be rebuilt here.
|
|
Packit Service |
102278 |
* This also ensures that any linked files that are required
|
|
Packit Service |
102278 |
* in order to skip re-linking are present; otherwise, we force
|
|
Packit Service |
102278 |
* a rebuild.
|
|
Packit Service |
102278 |
*/
|
|
Packit Service |
102278 |
if (!do_rebuild) {
|
|
Packit Service |
102278 |
int files[] = {SEMANAGE_STORE_KERNEL,
|
|
Packit Service |
102278 |
SEMANAGE_STORE_FC,
|
|
Packit Service |
102278 |
SEMANAGE_STORE_SEUSERS,
|
|
Packit Service |
102278 |
SEMANAGE_LINKED,
|
|
Packit Service |
102278 |
SEMANAGE_SEUSERS_LINKED,
|
|
Packit Service |
102278 |
SEMANAGE_USERS_EXTRA_LINKED};
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
for (i = 0; i < (int) ARRAY_SIZE(files); i++) {
|
|
Packit Service |
102278 |
path = semanage_path(SEMANAGE_TMP, files[i]);
|
|
Packit Service |
102278 |
if (stat(path, &sb) != 0) {
|
|
Packit Service |
102278 |
if (errno != ENOENT) {
|
|
Packit Service |
102278 |
ERR(sh, "Unable to access %s: %s\n", path, strerror(errno));
|
|
Packit Service |
102278 |
retval = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
do_rebuild = 1;
|
|
Packit Service |
102278 |
goto rebuild;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
rebuild:
|
|
Packit Service |
102278 |
/*
|
|
Packit Service |
102278 |
* Now that we know whether or not a rebuild is required,
|
|
Packit Service |
102278 |
* we can determine what else needs to be done.
|
|
Packit Service |
102278 |
* We need to write the kernel policy if we are rebuilding
|
|
Packit Service |
102278 |
* or if any other policy component that lives in the kernel
|
|
Packit Service |
102278 |
* policy has been modified.
|
|
Packit Service |
102278 |
* We need to install the policy files if any of the managed files
|
|
Packit Service |
102278 |
* that live under /etc/selinux (kernel policy, seusers, file contexts)
|
|
Packit Service |
102278 |
* will be modified.
|
|
Packit Service |
102278 |
*/
|
|
Packit Service |
102278 |
do_write_kernel = do_rebuild | ports_modified | ibpkeys_modified |
|
|
Packit Service |
102278 |
ibendports_modified |
|
|
Packit Service |
102278 |
bools->dtable->is_modified(bools->dbase) |
|
|
Packit Service |
102278 |
ifaces->dtable->is_modified(ifaces->dbase) |
|
|
Packit Service |
102278 |
nodes->dtable->is_modified(nodes->dbase) |
|
|
Packit Service |
102278 |
users->dtable->is_modified(users_base->dbase);
|
|
Packit Service |
102278 |
do_install = do_write_kernel | seusers_modified | fcontexts_modified;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/*
|
|
Packit Service |
102278 |
* If there were policy changes, or explicitly requested, or
|
|
Packit Service |
102278 |
* any required files are missing, rebuild the policy.
|
|
Packit Service |
102278 |
*/
|
|
Packit Service |
102278 |
if (do_rebuild) {
|
|
Packit Service |
102278 |
/* =================== Module expansion =============== */
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
retval = semanage_get_active_modules(sh, &modinfos, &num_modinfos);
|
|
Packit Service |
102278 |
if (retval < 0) {
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (num_modinfos == 0) {
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
retval = semanage_compile_hll_modules(sh, modinfos, num_modinfos);
|
|
Packit Service |
102278 |
if (retval < 0) {
|
|
Packit Service |
102278 |
ERR(sh, "Failed to compile hll files into cil files.\n");
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
retval = semanage_get_cil_paths(sh, modinfos, num_modinfos, &mod_filenames);
|
|
Packit Service |
102278 |
if (retval < 0)
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
retval = semanage_verify_modules(sh, mod_filenames, num_modinfos);
|
|
Packit Service |
102278 |
if (retval < 0)
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
cil_db_init(&cildb);
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
disable_dontaudit = sepol_get_disable_dontaudit(sh->sepolh);
|
|
Packit Service |
102278 |
preserve_tunables = sepol_get_preserve_tunables(sh->sepolh);
|
|
Packit Service |
102278 |
cil_set_disable_dontaudit(cildb, disable_dontaudit);
|
|
Packit Service |
102278 |
cil_set_disable_neverallow(cildb, !(sh->conf->expand_check));
|
|
Packit Service |
102278 |
cil_set_preserve_tunables(cildb, preserve_tunables);
|
|
Packit Service |
102278 |
cil_set_target_platform(cildb, sh->conf->target_platform);
|
|
Packit Service |
102278 |
cil_set_policy_version(cildb, sh->conf->policyvers);
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (sh->conf->handle_unknown != -1) {
|
|
Packit Service |
102278 |
cil_set_handle_unknown(cildb, sh->conf->handle_unknown);
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
retval = semanage_load_files(sh, cildb, mod_filenames, num_modinfos);
|
|
Packit Service |
102278 |
if (retval < 0) {
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
retval = cil_compile(cildb);
|
|
Packit Service |
102278 |
if (retval < 0)
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
retval = cil_build_policydb(cildb, &out;;
|
|
Packit Service |
102278 |
if (retval < 0)
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* File Contexts */
|
|
Packit Service |
102278 |
retval = cil_filecons_to_string(cildb, &fc_buffer, &fc_buffer_len);
|
|
Packit Service |
102278 |
if (retval < 0)
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* Write the contexts (including template contexts) to a single file. */
|
|
Packit Service |
102278 |
ofilename = semanage_path(SEMANAGE_TMP, SEMANAGE_FC_TMPL);
|
|
Packit Service |
102278 |
if (ofilename == NULL) {
|
|
Packit Service |
102278 |
retval = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
retval = write_file(sh, ofilename, fc_buffer, fc_buffer_len);
|
|
Packit Service |
102278 |
if (retval < 0)
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* Split complete and template file contexts into their separate files. */
|
|
Packit Service |
102278 |
retval = semanage_split_fc(sh);
|
|
Packit Service |
102278 |
if (retval < 0)
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* remove FC_TMPL now that it is now longer needed */
|
|
Packit Service |
102278 |
unlink(semanage_path(SEMANAGE_TMP, SEMANAGE_FC_TMPL));
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
pfcontexts->dtable->drop_cache(pfcontexts->dbase);
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* SEUsers */
|
|
Packit Service |
102278 |
retval = semanage_direct_update_seuser(sh, cildb);
|
|
Packit Service |
102278 |
if (retval < 0)
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* User Extra */
|
|
Packit Service |
102278 |
retval = semanage_direct_update_user_extra(sh, cildb);
|
|
Packit Service |
102278 |
if (retval < 0)
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
cil_db_destroy(&cildb);
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* Write the linked policy before merging local changes. */
|
|
Packit Service |
102278 |
retval = semanage_write_policydb(sh, out,
|
|
Packit Service |
102278 |
SEMANAGE_LINKED);
|
|
Packit Service |
102278 |
if (retval < 0)
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
} else {
|
|
Packit Service |
102278 |
/* Load the existing linked policy, w/o local changes */
|
|
Packit Service |
102278 |
retval = sepol_policydb_create(&out;;
|
|
Packit Service |
102278 |
if (retval < 0)
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
retval = semanage_read_policydb(sh, out, SEMANAGE_LINKED);
|
|
Packit Service |
102278 |
if (retval < 0)
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
path = semanage_path(SEMANAGE_TMP, SEMANAGE_SEUSERS_LINKED);
|
|
Packit Service |
102278 |
if (stat(path, &sb) == 0) {
|
|
Packit Service |
102278 |
retval = semanage_copy_file(path,
|
|
Packit Service |
102278 |
semanage_path(SEMANAGE_TMP,
|
|
Packit Service |
102278 |
SEMANAGE_STORE_SEUSERS),
|
|
Packit Service |
102278 |
0, false);
|
|
Packit Service |
102278 |
if (retval < 0)
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
pseusers->dtable->drop_cache(pseusers->dbase);
|
|
Packit Service |
102278 |
} else if (errno == ENOENT) {
|
|
Packit Service |
102278 |
/* The file does not exist */
|
|
Packit Service |
102278 |
pseusers->dtable->clear(sh, pseusers->dbase);
|
|
Packit Service |
102278 |
} else {
|
|
Packit Service |
102278 |
ERR(sh, "Unable to access %s: %s\n", path, strerror(errno));
|
|
Packit Service |
102278 |
retval = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
path = semanage_path(SEMANAGE_TMP, SEMANAGE_USERS_EXTRA_LINKED);
|
|
Packit Service |
102278 |
if (stat(path, &sb) == 0) {
|
|
Packit Service |
102278 |
retval = semanage_copy_file(path,
|
|
Packit Service |
102278 |
semanage_path(SEMANAGE_TMP,
|
|
Packit Service |
102278 |
SEMANAGE_USERS_EXTRA),
|
|
Packit Service |
102278 |
0, false);
|
|
Packit Service |
102278 |
if (retval < 0)
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
pusers_extra->dtable->drop_cache(pusers_extra->dbase);
|
|
Packit Service |
102278 |
} else if (errno == ENOENT) {
|
|
Packit Service |
102278 |
/* The file does not exist */
|
|
Packit Service |
102278 |
pusers_extra->dtable->clear(sh, pusers_extra->dbase);
|
|
Packit Service |
102278 |
} else {
|
|
Packit Service |
102278 |
ERR(sh, "Unable to access %s: %s\n", path, strerror(errno));
|
|
Packit Service |
102278 |
retval = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* Attach our databases to the policydb we just created or loaded. */
|
|
Packit Service |
102278 |
dbase_policydb_attach((dbase_policydb_t *) pusers_base->dbase, out);
|
|
Packit Service |
102278 |
dbase_policydb_attach((dbase_policydb_t *) pports->dbase, out);
|
|
Packit Service |
102278 |
dbase_policydb_attach((dbase_policydb_t *) pibpkeys->dbase, out);
|
|
Packit Service |
102278 |
dbase_policydb_attach((dbase_policydb_t *) pibendports->dbase, out);
|
|
Packit Service |
102278 |
dbase_policydb_attach((dbase_policydb_t *) pifaces->dbase, out);
|
|
Packit Service |
102278 |
dbase_policydb_attach((dbase_policydb_t *) pbools->dbase, out);
|
|
Packit Service |
102278 |
dbase_policydb_attach((dbase_policydb_t *) pnodes->dbase, out);
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* Merge local changes */
|
|
Packit Service |
102278 |
retval = semanage_base_merge_components(sh);
|
|
Packit Service |
102278 |
if (retval < 0)
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (do_write_kernel) {
|
|
Packit Service |
102278 |
/* Write new kernel policy. */
|
|
Packit Service |
102278 |
retval = semanage_write_policydb(sh, out,
|
|
Packit Service |
102278 |
SEMANAGE_STORE_KERNEL);
|
|
Packit Service |
102278 |
if (retval < 0)
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* Run the kernel policy verifier, if any. */
|
|
Packit Service |
102278 |
retval = semanage_verify_kernel(sh);
|
|
Packit Service |
102278 |
if (retval < 0)
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* ======= Post-process: Validate non-policydb components ===== */
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* Validate local modifications to file contexts.
|
|
Packit Service |
102278 |
* Note: those are still cached, even though they've been
|
|
Packit Service |
102278 |
* merged into the main file_contexts. We won't check the
|
|
Packit Service |
102278 |
* large file_contexts - checked at compile time */
|
|
Packit Service |
102278 |
if (do_rebuild || fcontexts_modified) {
|
|
Packit Service |
102278 |
retval = semanage_fcontext_validate_local(sh, out);
|
|
Packit Service |
102278 |
if (retval < 0)
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* Validate local seusers against policy */
|
|
Packit Service |
102278 |
if (do_rebuild || seusers_modified) {
|
|
Packit Service |
102278 |
retval = semanage_seuser_validate_local(sh, out);
|
|
Packit Service |
102278 |
if (retval < 0)
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* Validate local ports for overlap */
|
|
Packit Service |
102278 |
if (do_rebuild || ports_modified) {
|
|
Packit Service |
102278 |
retval = semanage_port_validate_local(sh);
|
|
Packit Service |
102278 |
if (retval < 0)
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* Validate local ibpkeys for overlap */
|
|
Packit Service |
102278 |
if (do_rebuild || ibpkeys_modified) {
|
|
Packit Service |
102278 |
retval = semanage_ibpkey_validate_local(sh);
|
|
Packit Service |
102278 |
if (retval < 0)
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* Validate local ibendports */
|
|
Packit Service |
102278 |
if (do_rebuild || ibendports_modified) {
|
|
Packit Service |
102278 |
retval = semanage_ibendport_validate_local(sh);
|
|
Packit Service |
102278 |
if (retval < 0)
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
/* ================== Write non-policydb components ========= */
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* Commit changes to components */
|
|
Packit Service |
102278 |
retval = semanage_commit_components(sh);
|
|
Packit Service |
102278 |
if (retval < 0)
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
retval = semanage_copy_file(semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_KERNEL),
|
|
Packit Service |
102278 |
semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_KERNEL),
|
|
Packit Service |
102278 |
sh->conf->file_mode, false);
|
|
Packit Service |
102278 |
if (retval < 0) {
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
retval = copy_file_if_exists(semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC_LOCAL),
|
|
Packit Service |
102278 |
semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC_LOCAL),
|
|
Packit Service |
102278 |
sh->conf->file_mode);
|
|
Packit Service |
102278 |
if (retval < 0) {
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
retval = copy_file_if_exists(semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC),
|
|
Packit Service |
102278 |
semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC),
|
|
Packit Service |
102278 |
sh->conf->file_mode);
|
|
Packit Service |
102278 |
if (retval < 0) {
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
retval = copy_file_if_exists(semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_SEUSERS),
|
|
Packit Service |
102278 |
semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_SEUSERS),
|
|
Packit Service |
102278 |
sh->conf->file_mode);
|
|
Packit Service |
102278 |
if (retval < 0) {
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* run genhomedircon if its enabled, this should be the last operation
|
|
Packit Service |
102278 |
* which requires the out policydb */
|
|
Packit Service |
102278 |
if (!sh->conf->disable_genhomedircon) {
|
|
Packit Service |
102278 |
if (out){
|
|
Packit Service |
102278 |
if ((retval = semanage_genhomedircon(sh, out, sh->conf->usepasswd,
|
|
Packit Service |
102278 |
sh->conf->ignoredirs)) != 0) {
|
|
Packit Service |
102278 |
ERR(sh, "semanage_genhomedircon returned error code %d.", retval);
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
/* file_contexts.homedirs was created in SEMANAGE_TMP store */
|
|
Packit Service |
102278 |
retval = semanage_copy_file(
|
|
Packit Service |
102278 |
semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC_HOMEDIRS),
|
|
Packit Service |
102278 |
semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC_HOMEDIRS),
|
|
Packit Service |
102278 |
sh->conf->file_mode, false);
|
|
Packit Service |
102278 |
if (retval < 0) {
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
} else {
|
|
Packit Service |
102278 |
WARN(sh, "WARNING: genhomedircon is disabled. \
|
|
Packit Service |
102278 |
See /etc/selinux/semanage.conf if you need to enable it.");
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* free out, if we don't free it before calling semanage_install_sandbox
|
|
Packit Service |
102278 |
* then fork() may fail on low memory machines */
|
|
Packit Service |
102278 |
sepol_policydb_free(out);
|
|
Packit Service |
102278 |
out = NULL;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (do_install)
|
|
Packit Service |
102278 |
retval = semanage_install_sandbox(sh);
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
cleanup:
|
|
Packit Service |
102278 |
for (i = 0; i < num_modinfos; i++) {
|
|
Packit Service |
102278 |
semanage_module_info_destroy(sh, &modinfos[i]);
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
free(modinfos);
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
for (i = 0; mod_filenames != NULL && i < num_modinfos; i++) {
|
|
Packit Service |
102278 |
free(mod_filenames[i]);
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* Detach from policydb, so it can be freed */
|
|
Packit Service |
102278 |
dbase_policydb_detach((dbase_policydb_t *) pusers_base->dbase);
|
|
Packit Service |
102278 |
dbase_policydb_detach((dbase_policydb_t *) pports->dbase);
|
|
Packit Service |
102278 |
dbase_policydb_detach((dbase_policydb_t *) pibpkeys->dbase);
|
|
Packit Service |
102278 |
dbase_policydb_detach((dbase_policydb_t *) pibendports->dbase);
|
|
Packit Service |
102278 |
dbase_policydb_detach((dbase_policydb_t *) pifaces->dbase);
|
|
Packit Service |
102278 |
dbase_policydb_detach((dbase_policydb_t *) pnodes->dbase);
|
|
Packit Service |
102278 |
dbase_policydb_detach((dbase_policydb_t *) pbools->dbase);
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
free(mod_filenames);
|
|
Packit Service |
102278 |
sepol_policydb_free(out);
|
|
Packit Service |
102278 |
cil_db_destroy(&cildb);
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
free(fc_buffer);
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* Set commit_err so other functions can detect any errors. Note that
|
|
Packit Service |
102278 |
* retval > 0 will be the commit number.
|
|
Packit Service |
102278 |
*/
|
|
Packit Service |
102278 |
if (retval < 0)
|
|
Packit Service |
102278 |
sh->commit_err = retval;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (semanage_remove_tmps(sh) != 0)
|
|
Packit Service |
102278 |
retval = -1;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
semanage_release_trans_lock(sh);
|
|
Packit Service |
102278 |
umask(mask);
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
return retval;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* Writes a module to the sandbox's module directory, overwriting any
|
|
Packit Service |
102278 |
* previous module stored within. Note that module data are not
|
|
Packit Service |
102278 |
* free()d by this function; caller is responsible for deallocating it
|
|
Packit Service |
102278 |
* if necessary. Returns 0 on success, -1 if out of memory, -2 if the
|
|
Packit Service |
102278 |
* data does not represent a valid module file, -3 if error while
|
|
Packit Service |
102278 |
* writing file. */
|
|
Packit Service |
102278 |
static int semanage_direct_install(semanage_handle_t * sh,
|
|
Packit Service |
102278 |
char *data, size_t data_len,
|
|
Packit Service |
102278 |
const char *module_name, const char *lang_ext)
|
|
Packit Service |
102278 |
{
|
|
Packit Service |
102278 |
int status = 0;
|
|
Packit Service |
102278 |
int ret = 0;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
semanage_module_info_t modinfo;
|
|
Packit Service |
102278 |
ret = semanage_module_info_init(sh, &modinfo);
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
ret = semanage_module_info_set_priority(sh, &modinfo, sh->priority);
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
ret = semanage_module_info_set_name(sh, &modinfo, module_name);
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
ret = semanage_module_info_set_lang_ext(sh, &modinfo, lang_ext);
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
ret = semanage_module_info_set_enabled(sh, &modinfo, -1);
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
status = semanage_direct_install_info(sh, &modinfo, data, data_len);
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
cleanup:
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
semanage_module_info_destroy(sh, &modinfo);
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
return status;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* Attempts to link a module to the sandbox's module directory, unlinking any
|
|
Packit Service |
102278 |
* previous module stored within. Returns 0 on success, -1 if out of memory, -2 if the
|
|
Packit Service |
102278 |
* data does not represent a valid module file, -3 if error while
|
|
Packit Service |
102278 |
* writing file. */
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
static int semanage_direct_install_file(semanage_handle_t * sh,
|
|
Packit Service |
102278 |
const char *install_filename)
|
|
Packit Service |
102278 |
{
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
int retval = -1;
|
|
Packit Service |
102278 |
char *data = NULL;
|
|
Packit Service |
102278 |
ssize_t data_len = 0;
|
|
Packit Service |
102278 |
int compressed = 0;
|
|
Packit Service |
102278 |
char *path = NULL;
|
|
Packit Service |
102278 |
char *filename;
|
|
Packit Service |
102278 |
char *lang_ext = NULL;
|
|
Packit Service |
102278 |
char *module_name = NULL;
|
|
Packit Service |
102278 |
char *separator;
|
|
Packit Service |
102278 |
char *version = NULL;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if ((data_len = map_file(sh, install_filename, &data, &compressed)) <= 0) {
|
|
Packit Service |
102278 |
ERR(sh, "Unable to read file %s\n", install_filename);
|
|
Packit Service |
102278 |
retval = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
path = strdup(install_filename);
|
|
Packit Service |
102278 |
if (path == NULL) {
|
|
Packit Service |
102278 |
ERR(sh, "No memory available for strdup.\n");
|
|
Packit Service |
102278 |
retval = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
filename = basename(path);
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (compressed) {
|
|
Packit Service |
102278 |
separator = strrchr(filename, '.');
|
|
Packit Service |
102278 |
if (separator == NULL) {
|
|
Packit Service |
102278 |
ERR(sh, "Compressed module does not have a valid extension.");
|
|
Packit Service |
102278 |
retval = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
*separator = '\0';
|
|
Packit Service |
102278 |
lang_ext = separator + 1;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
separator = strrchr(filename, '.');
|
|
Packit Service |
102278 |
if (separator == NULL) {
|
|
Packit Service |
102278 |
if (lang_ext == NULL) {
|
|
Packit Service |
102278 |
ERR(sh, "Module does not have a valid extension.");
|
|
Packit Service |
102278 |
retval = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
} else {
|
|
Packit Service |
102278 |
*separator = '\0';
|
|
Packit Service |
102278 |
lang_ext = separator + 1;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (strcmp(lang_ext, "pp") == 0) {
|
|
Packit Service |
102278 |
retval = parse_module_headers(sh, data, data_len, &module_name, &version);
|
|
Packit Service |
102278 |
free(version);
|
|
Packit Service |
102278 |
if (retval != 0)
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (module_name == NULL) {
|
|
Packit Service |
102278 |
module_name = strdup(filename);
|
|
Packit Service |
102278 |
if (module_name == NULL) {
|
|
Packit Service |
102278 |
ERR(sh, "No memory available for module_name.\n");
|
|
Packit Service |
102278 |
retval = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
} else if (strcmp(module_name, filename) != 0) {
|
|
Packit Service |
102278 |
fprintf(stderr, "Warning: SELinux userspace will refer to the module from %s as %s rather than %s\n", install_filename, module_name, filename);
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
retval = semanage_direct_install(sh, data, data_len, module_name, lang_ext);
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
cleanup:
|
|
Packit Service |
102278 |
if (data_len > 0) munmap(data, data_len);
|
|
Packit Service |
102278 |
free(module_name);
|
|
Packit Service |
102278 |
free(path);
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
return retval;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
static int semanage_direct_extract(semanage_handle_t * sh,
|
|
Packit Service |
102278 |
semanage_module_key_t *modkey,
|
|
Packit Service |
102278 |
int extract_cil,
|
|
Packit Service |
102278 |
void **mapped_data,
|
|
Packit Service |
102278 |
size_t *data_len,
|
|
Packit Service |
102278 |
semanage_module_info_t **modinfo)
|
|
Packit Service |
102278 |
{
|
|
Packit Service |
102278 |
char module_path[PATH_MAX];
|
|
Packit Service |
102278 |
char input_file[PATH_MAX];
|
|
Packit Service |
102278 |
enum semanage_module_path_type file_type;
|
|
Packit Service |
102278 |
int rc = -1;
|
|
Packit Service |
102278 |
semanage_module_info_t *_modinfo = NULL;
|
|
Packit Service |
102278 |
ssize_t _data_len;
|
|
Packit Service |
102278 |
char *_data;
|
|
Packit Service |
102278 |
int compressed;
|
|
Packit Service |
102278 |
struct stat sb;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* get path of module */
|
|
Packit Service |
102278 |
rc = semanage_module_get_path(
|
|
Packit Service |
102278 |
sh,
|
|
Packit Service |
102278 |
(const semanage_module_info_t *)modkey,
|
|
Packit Service |
102278 |
SEMANAGE_MODULE_PATH_NAME,
|
|
Packit Service |
102278 |
module_path,
|
|
Packit Service |
102278 |
sizeof(module_path));
|
|
Packit Service |
102278 |
if (rc != 0) {
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (stat(module_path, &sb) != 0) {
|
|
Packit Service |
102278 |
ERR(sh, "Unable to access %s: %s\n", module_path, strerror(errno));
|
|
Packit Service |
102278 |
rc = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
rc = semanage_module_get_module_info(sh,
|
|
Packit Service |
102278 |
modkey,
|
|
Packit Service |
102278 |
&_modinfo);
|
|
Packit Service |
102278 |
if (rc != 0) {
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (extract_cil || strcmp(_modinfo->lang_ext, "cil") == 0) {
|
|
Packit Service |
102278 |
file_type = SEMANAGE_MODULE_PATH_CIL;
|
|
Packit Service |
102278 |
} else {
|
|
Packit Service |
102278 |
file_type = SEMANAGE_MODULE_PATH_HLL;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* get path of what to extract */
|
|
Packit Service |
102278 |
rc = semanage_module_get_path(
|
|
Packit Service |
102278 |
sh,
|
|
Packit Service |
102278 |
_modinfo,
|
|
Packit Service |
102278 |
file_type,
|
|
Packit Service |
102278 |
input_file,
|
|
Packit Service |
102278 |
sizeof(input_file));
|
|
Packit Service |
102278 |
if (rc != 0) {
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (extract_cil == 1 && strcmp(_modinfo->lang_ext, "cil") && stat(input_file, &sb) != 0) {
|
|
Packit Service |
102278 |
if (errno != ENOENT) {
|
|
Packit Service |
102278 |
ERR(sh, "Unable to access %s: %s\n", input_file, strerror(errno));
|
|
Packit Service |
102278 |
rc = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
rc = semanage_compile_module(sh, _modinfo);
|
|
Packit Service |
102278 |
if (rc < 0) {
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
_data_len = map_file(sh, input_file, &_data, &compressed);
|
|
Packit Service |
102278 |
if (_data_len <= 0) {
|
|
Packit Service |
102278 |
ERR(sh, "Error mapping file: %s", input_file);
|
|
Packit Service |
102278 |
rc = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
*modinfo = _modinfo;
|
|
Packit Service |
102278 |
*data_len = (size_t)_data_len;
|
|
Packit Service |
102278 |
*mapped_data = _data;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
cleanup:
|
|
Packit Service |
102278 |
if (rc != 0) {
|
|
Packit Service |
102278 |
semanage_module_info_destroy(sh, _modinfo);
|
|
Packit Service |
102278 |
free(_modinfo);
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
return rc;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* Removes a module from the sandbox. Returns 0 on success, -1 if out
|
|
Packit Service |
102278 |
* of memory, -2 if module not found or could not be removed. */
|
|
Packit Service |
102278 |
static int semanage_direct_remove(semanage_handle_t * sh, char *module_name)
|
|
Packit Service |
102278 |
{
|
|
Packit Service |
102278 |
int status = 0;
|
|
Packit Service |
102278 |
int ret = 0;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
semanage_module_key_t modkey;
|
|
Packit Service |
102278 |
ret = semanage_module_key_init(sh, &modkey);
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
ret = semanage_module_key_set_priority(sh, &modkey, sh->priority);
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
ret = semanage_module_key_set_name(sh, &modkey, module_name);
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
status = semanage_direct_remove_key(sh, &modkey);
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
cleanup:
|
|
Packit Service |
102278 |
return status;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* Allocate an array of module_info structures for each readable
|
|
Packit Service |
102278 |
* module within the store. Note that if the calling program has
|
|
Packit Service |
102278 |
* already begun a transaction then this function will get a list of
|
|
Packit Service |
102278 |
* modules within the sandbox. The caller is responsible for calling
|
|
Packit Service |
102278 |
* semanage_module_info_datum_destroy() on each element of the array
|
|
Packit Service |
102278 |
* as well as free()ing the entire list.
|
|
Packit Service |
102278 |
*/
|
|
Packit Service |
102278 |
static int semanage_direct_list(semanage_handle_t * sh,
|
|
Packit Service |
102278 |
semanage_module_info_t ** modinfo,
|
|
Packit Service |
102278 |
int *num_modules)
|
|
Packit Service |
102278 |
{
|
|
Packit Service |
102278 |
int i, retval = -1;
|
|
Packit Service |
102278 |
*modinfo = NULL;
|
|
Packit Service |
102278 |
*num_modules = 0;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* get the read lock when reading from the active
|
|
Packit Service |
102278 |
(non-transaction) directory */
|
|
Packit Service |
102278 |
if (!sh->is_in_transaction)
|
|
Packit Service |
102278 |
if (semanage_get_active_lock(sh) < 0)
|
|
Packit Service |
102278 |
return -1;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (semanage_get_active_modules(sh, modinfo, num_modules) == -1) {
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (num_modules == 0) {
|
|
Packit Service |
102278 |
retval = semanage_direct_get_serial(sh);
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
retval = semanage_direct_get_serial(sh);
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
cleanup:
|
|
Packit Service |
102278 |
if (retval < 0) {
|
|
Packit Service |
102278 |
for (i = 0; i < *num_modules; i++) {
|
|
Packit Service |
102278 |
semanage_module_info_destroy(sh, &(*modinfo[i]));
|
|
Packit Service |
102278 |
modinfo[i] = NULL;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
free(*modinfo);
|
|
Packit Service |
102278 |
*modinfo = NULL;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (!sh->is_in_transaction) {
|
|
Packit Service |
102278 |
semanage_release_active_lock(sh);
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
return retval;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
static int semanage_direct_get_enabled(semanage_handle_t *sh,
|
|
Packit Service |
102278 |
const semanage_module_key_t *modkey,
|
|
Packit Service |
102278 |
int *enabled)
|
|
Packit Service |
102278 |
{
|
|
Packit Service |
102278 |
assert(sh);
|
|
Packit Service |
102278 |
assert(modkey);
|
|
Packit Service |
102278 |
assert(enabled);
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
int status = 0;
|
|
Packit Service |
102278 |
int ret = 0;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
char path[PATH_MAX];
|
|
Packit Service |
102278 |
struct stat sb;
|
|
Packit Service |
102278 |
semanage_module_info_t *modinfo = NULL;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* get module info */
|
|
Packit Service |
102278 |
ret = semanage_module_get_module_info(
|
|
Packit Service |
102278 |
sh,
|
|
Packit Service |
102278 |
modkey,
|
|
Packit Service |
102278 |
&modinfo);
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* get disabled file path */
|
|
Packit Service |
102278 |
ret = semanage_module_get_path(
|
|
Packit Service |
102278 |
sh,
|
|
Packit Service |
102278 |
modinfo,
|
|
Packit Service |
102278 |
SEMANAGE_MODULE_PATH_DISABLED,
|
|
Packit Service |
102278 |
path,
|
|
Packit Service |
102278 |
sizeof(path));
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (stat(path, &sb) < 0) {
|
|
Packit Service |
102278 |
if (errno != ENOENT) {
|
|
Packit Service |
102278 |
ERR(sh, "Unable to access %s: %s\n", path, strerror(errno));
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
*enabled = 1;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
else {
|
|
Packit Service |
102278 |
*enabled = 0;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
cleanup:
|
|
Packit Service |
102278 |
semanage_module_info_destroy(sh, modinfo);
|
|
Packit Service |
102278 |
free(modinfo);
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
return status;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
static int semanage_direct_set_enabled(semanage_handle_t *sh,
|
|
Packit Service |
102278 |
const semanage_module_key_t *modkey,
|
|
Packit Service |
102278 |
int enabled)
|
|
Packit Service |
102278 |
{
|
|
Packit Service |
102278 |
assert(sh);
|
|
Packit Service |
102278 |
assert(modkey);
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
int status = 0;
|
|
Packit Service |
102278 |
int ret = 0;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
char fn[PATH_MAX];
|
|
Packit Service |
102278 |
const char *path = NULL;
|
|
Packit Service |
102278 |
FILE *fp = NULL;
|
|
Packit Service |
102278 |
semanage_module_info_t *modinfo = NULL;
|
|
Packit Service |
102278 |
mode_t mask;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* check transaction */
|
|
Packit Service |
102278 |
if (!sh->is_in_transaction) {
|
|
Packit Service |
102278 |
if (semanage_begin_transaction(sh) < 0) {
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* validate name */
|
|
Packit Service |
102278 |
ret = semanage_module_validate_name(modkey->name);
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
errno = 0;
|
|
Packit Service |
102278 |
ERR(sh, "Name %s is invalid.", modkey->name);
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* validate enabled */
|
|
Packit Service |
102278 |
ret = semanage_module_validate_enabled(enabled);
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
errno = 0;
|
|
Packit Service |
102278 |
ERR(sh, "Enabled status %d is invalid.", enabled);
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* check for disabled path, create if missing */
|
|
Packit Service |
102278 |
path = semanage_path(SEMANAGE_TMP, SEMANAGE_MODULES_DISABLED);
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
ret = semanage_mkdir(sh, path);
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* get module info */
|
|
Packit Service |
102278 |
ret = semanage_module_get_module_info(
|
|
Packit Service |
102278 |
sh,
|
|
Packit Service |
102278 |
modkey,
|
|
Packit Service |
102278 |
&modinfo);
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* get module disabled file */
|
|
Packit Service |
102278 |
ret = semanage_module_get_path(
|
|
Packit Service |
102278 |
sh,
|
|
Packit Service |
102278 |
modinfo,
|
|
Packit Service |
102278 |
SEMANAGE_MODULE_PATH_DISABLED,
|
|
Packit Service |
102278 |
fn,
|
|
Packit Service |
102278 |
sizeof(fn));
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
switch (enabled) {
|
|
Packit Service |
102278 |
case 0: /* disable the module */
|
|
Packit Service |
102278 |
mask = umask(0077);
|
|
Packit Service |
102278 |
fp = fopen(fn, "w");
|
|
Packit Service |
102278 |
umask(mask);
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (fp == NULL) {
|
|
Packit Service |
102278 |
ERR(sh,
|
|
Packit Service |
102278 |
"Unable to disable module %s",
|
|
Packit Service |
102278 |
modkey->name);
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (fclose(fp) != 0) {
|
|
Packit Service |
102278 |
ERR(sh,
|
|
Packit Service |
102278 |
"Unable to close disabled file for module %s",
|
|
Packit Service |
102278 |
modkey->name);
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
fp = NULL;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
break;
|
|
Packit Service |
102278 |
case 1: /* enable the module */
|
|
Packit Service |
102278 |
if (unlink(fn) < 0) {
|
|
Packit Service |
102278 |
if (errno != ENOENT) {
|
|
Packit Service |
102278 |
ERR(sh,
|
|
Packit Service |
102278 |
"Unable to enable module %s",
|
|
Packit Service |
102278 |
modkey->name);
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
else {
|
|
Packit Service |
102278 |
/* module already enabled */
|
|
Packit Service |
102278 |
errno = 0;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
break;
|
|
Packit Service |
102278 |
case -1: /* warn about ignored setting to default */
|
|
Packit Service |
102278 |
WARN(sh,
|
|
Packit Service |
102278 |
"Setting module %s to 'default' state has no effect",
|
|
Packit Service |
102278 |
modkey->name);
|
|
Packit Service |
102278 |
break;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
cleanup:
|
|
Packit Service |
102278 |
semanage_module_info_destroy(sh, modinfo);
|
|
Packit Service |
102278 |
free(modinfo);
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
return status;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
int semanage_direct_access_check(semanage_handle_t * sh)
|
|
Packit Service |
102278 |
{
|
|
Packit Service |
102278 |
if (semanage_check_init(sh, sh->conf->store_root_path))
|
|
Packit Service |
102278 |
return -1;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
return semanage_store_access_check();
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
int semanage_direct_mls_enabled(semanage_handle_t * sh)
|
|
Packit Service |
102278 |
{
|
|
Packit Service |
102278 |
sepol_policydb_t *p = NULL;
|
|
Packit Service |
102278 |
int retval;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
retval = sepol_policydb_create(&p);
|
|
Packit Service |
102278 |
if (retval < 0)
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
retval = semanage_read_policydb(sh, p, SEMANAGE_STORE_KERNEL);
|
|
Packit Service |
102278 |
if (retval < 0)
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
retval = sepol_policydb_mls_enabled(p);
|
|
Packit Service |
102278 |
cleanup:
|
|
Packit Service |
102278 |
sepol_policydb_free(p);
|
|
Packit Service |
102278 |
return retval;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
static int semanage_direct_get_module_info(semanage_handle_t *sh,
|
|
Packit Service |
102278 |
const semanage_module_key_t *modkey,
|
|
Packit Service |
102278 |
semanage_module_info_t **modinfo)
|
|
Packit Service |
102278 |
{
|
|
Packit Service |
102278 |
assert(sh);
|
|
Packit Service |
102278 |
assert(modkey);
|
|
Packit Service |
102278 |
assert(modinfo);
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
int status = 0;
|
|
Packit Service |
102278 |
int ret = 0;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
char fn[PATH_MAX];
|
|
Packit Service |
102278 |
FILE *fp = NULL;
|
|
Packit Service |
102278 |
size_t size = 0;
|
|
Packit Service |
102278 |
struct stat sb;
|
|
Packit Service |
102278 |
char *tmp = NULL;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
int i = 0;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
semanage_module_info_t *modinfos = NULL;
|
|
Packit Service |
102278 |
int modinfos_len = 0;
|
|
Packit Service |
102278 |
semanage_module_info_t *highest = NULL;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* check module name */
|
|
Packit Service |
102278 |
ret = semanage_module_validate_name(modkey->name);
|
|
Packit Service |
102278 |
if (ret < 0) {
|
|
Packit Service |
102278 |
errno = 0;
|
|
Packit Service |
102278 |
ERR(sh, "Name %s is invalid.", modkey->name);
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* if priority == 0, then find the highest priority available */
|
|
Packit Service |
102278 |
if (modkey->priority == 0) {
|
|
Packit Service |
102278 |
ret = semanage_direct_list_all(sh, &modinfos, &modinfos_len);
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
for (i = 0; i < modinfos_len; i++) {
|
|
Packit Service |
102278 |
ret = strcmp(modinfos[i].name, modkey->name);
|
|
Packit Service |
102278 |
if (ret == 0) {
|
|
Packit Service |
102278 |
highest = &modinfos[i];
|
|
Packit Service |
102278 |
break;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (highest == NULL) {
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
ret = semanage_module_info_create(sh, modinfo);
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
ret = semanage_module_info_clone(sh, highest, *modinfo);
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* skip to cleanup, module was found */
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* check module priority */
|
|
Packit Service |
102278 |
ret = semanage_module_validate_priority(modkey->priority);
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
errno = 0;
|
|
Packit Service |
102278 |
ERR(sh, "Priority %d is invalid.", modkey->priority);
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* copy in key values */
|
|
Packit Service |
102278 |
ret = semanage_module_info_create(sh, modinfo);
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
ret = semanage_module_info_set_priority(sh, *modinfo, modkey->priority);
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
ret = semanage_module_info_set_name(sh, *modinfo, modkey->name);
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* lookup module ext */
|
|
Packit Service |
102278 |
ret = semanage_module_get_path(sh,
|
|
Packit Service |
102278 |
*modinfo,
|
|
Packit Service |
102278 |
SEMANAGE_MODULE_PATH_LANG_EXT,
|
|
Packit Service |
102278 |
fn,
|
|
Packit Service |
102278 |
sizeof(fn));
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
fp = fopen(fn, "r");
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (fp == NULL) {
|
|
Packit Service |
102278 |
ERR(sh,
|
|
Packit Service |
102278 |
"Unable to open %s module lang ext file at %s.",
|
|
Packit Service |
102278 |
(*modinfo)->name, fn);
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* set module ext */
|
|
Packit Service |
102278 |
if (getline(&tmp, &size, fp) < 0) {
|
|
Packit Service |
102278 |
ERR(sh,
|
|
Packit Service |
102278 |
"Unable to read %s module lang ext file.",
|
|
Packit Service |
102278 |
(*modinfo)->name);
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
ret = semanage_module_info_set_lang_ext(sh, *modinfo, tmp);
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
free(tmp);
|
|
Packit Service |
102278 |
tmp = NULL;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* lookup enabled/disabled status */
|
|
Packit Service |
102278 |
ret = semanage_module_get_path(sh,
|
|
Packit Service |
102278 |
*modinfo,
|
|
Packit Service |
102278 |
SEMANAGE_MODULE_PATH_DISABLED,
|
|
Packit Service |
102278 |
fn,
|
|
Packit Service |
102278 |
sizeof(fn));
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* set enabled/disabled status */
|
|
Packit Service |
102278 |
if (stat(fn, &sb) < 0) {
|
|
Packit Service |
102278 |
if (errno != ENOENT) {
|
|
Packit Service |
102278 |
ERR(sh, "Unable to access %s: %s\n", fn, strerror(errno));
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
ret = semanage_module_info_set_enabled(sh, *modinfo, 1);
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
else {
|
|
Packit Service |
102278 |
ret = semanage_module_info_set_enabled(sh, *modinfo, 0);
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
cleanup:
|
|
Packit Service |
102278 |
free(tmp);
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (modinfos != NULL) {
|
|
Packit Service |
102278 |
for (i = 0; i < modinfos_len; i++) {
|
|
Packit Service |
102278 |
semanage_module_info_destroy(sh, &modinfos[i]);
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
free(modinfos);
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (fp != NULL && fclose(fp) != 0) {
|
|
Packit Service |
102278 |
ERR(sh,
|
|
Packit Service |
102278 |
"Unable to close %s module lang ext file.",
|
|
Packit Service |
102278 |
(*modinfo)->name);
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
return status;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
static int semanage_direct_set_module_info(semanage_handle_t *sh,
|
|
Packit Service |
102278 |
const semanage_module_info_t *modinfo)
|
|
Packit Service |
102278 |
{
|
|
Packit Service |
102278 |
int status = 0;
|
|
Packit Service |
102278 |
int ret = 0;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
char fn[PATH_MAX];
|
|
Packit Service |
102278 |
const char *path = NULL;
|
|
Packit Service |
102278 |
int enabled = 0;
|
|
Packit Service |
102278 |
semanage_module_info_t *modinfo_tmp = NULL;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
semanage_module_key_t modkey;
|
|
Packit Service |
102278 |
ret = semanage_module_key_init(sh, &modkey);
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* check transaction */
|
|
Packit Service |
102278 |
if (!sh->is_in_transaction) {
|
|
Packit Service |
102278 |
if (semanage_begin_transaction(sh) < 0) {
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* validate module */
|
|
Packit Service |
102278 |
ret = semanage_module_info_validate(modinfo);
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
sh->modules_modified = 1;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* check for modules path, create if missing */
|
|
Packit Service |
102278 |
path = semanage_path(SEMANAGE_TMP, SEMANAGE_MODULES);
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
ret = semanage_mkdir(sh, path);
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* write priority */
|
|
Packit Service |
102278 |
ret = semanage_module_get_path(sh,
|
|
Packit Service |
102278 |
modinfo,
|
|
Packit Service |
102278 |
SEMANAGE_MODULE_PATH_PRIORITY,
|
|
Packit Service |
102278 |
fn,
|
|
Packit Service |
102278 |
sizeof(fn));
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
ret = semanage_mkdir(sh, fn);
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* write name */
|
|
Packit Service |
102278 |
ret = semanage_module_get_path(sh,
|
|
Packit Service |
102278 |
modinfo,
|
|
Packit Service |
102278 |
SEMANAGE_MODULE_PATH_NAME,
|
|
Packit Service |
102278 |
fn,
|
|
Packit Service |
102278 |
sizeof(fn));
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
ret = semanage_mkdir(sh, fn);
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* write ext */
|
|
Packit Service |
102278 |
ret = semanage_direct_write_langext(sh, modinfo->lang_ext, modinfo);
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* write enabled/disabled status */
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* check for disabled path, create if missing */
|
|
Packit Service |
102278 |
path = semanage_path(SEMANAGE_TMP, SEMANAGE_MODULES_DISABLED);
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
ret = semanage_mkdir(sh, path);
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
ret = semanage_module_get_path(sh,
|
|
Packit Service |
102278 |
modinfo,
|
|
Packit Service |
102278 |
SEMANAGE_MODULE_PATH_DISABLED,
|
|
Packit Service |
102278 |
fn,
|
|
Packit Service |
102278 |
sizeof(fn));
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
ret = semanage_module_key_set_name(sh, &modkey, modinfo->name);
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (modinfo->enabled == -1) {
|
|
Packit Service |
102278 |
/* default to enabled */
|
|
Packit Service |
102278 |
enabled = 1;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* check if a module is already installed */
|
|
Packit Service |
102278 |
ret = semanage_module_get_module_info(sh,
|
|
Packit Service |
102278 |
&modkey,
|
|
Packit Service |
102278 |
&modinfo_tmp);
|
|
Packit Service |
102278 |
if (ret == 0) {
|
|
Packit Service |
102278 |
/* set enabled status to current one */
|
|
Packit Service |
102278 |
enabled = modinfo_tmp->enabled;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
else {
|
|
Packit Service |
102278 |
enabled = modinfo->enabled;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
ret = semanage_module_set_enabled(sh, &modkey, enabled);
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
cleanup:
|
|
Packit Service |
102278 |
semanage_module_key_destroy(sh, &modkey);
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
semanage_module_info_destroy(sh, modinfo_tmp);
|
|
Packit Service |
102278 |
free(modinfo_tmp);
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
return status;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
static int semanage_priorities_filename_select(const struct dirent *d)
|
|
Packit Service |
102278 |
{
|
|
Packit Service |
102278 |
if (d->d_name[0] == '.' ||
|
|
Packit Service |
102278 |
strcmp(d->d_name, "disabled") == 0)
|
|
Packit Service |
102278 |
return 0;
|
|
Packit Service |
102278 |
return 1;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
static int semanage_modules_filename_select(const struct dirent *d)
|
|
Packit Service |
102278 |
{
|
|
Packit Service |
102278 |
if (d->d_name[0] == '.')
|
|
Packit Service |
102278 |
return 0;
|
|
Packit Service |
102278 |
return 1;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
static int semanage_direct_list_all(semanage_handle_t *sh,
|
|
Packit Service |
102278 |
semanage_module_info_t **modinfos,
|
|
Packit Service |
102278 |
int *modinfos_len)
|
|
Packit Service |
102278 |
{
|
|
Packit Service |
102278 |
assert(sh);
|
|
Packit Service |
102278 |
assert(modinfos);
|
|
Packit Service |
102278 |
assert(modinfos_len);
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
int status = 0;
|
|
Packit Service |
102278 |
int ret = 0;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
int i = 0;
|
|
Packit Service |
102278 |
int j = 0;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
*modinfos = NULL;
|
|
Packit Service |
102278 |
*modinfos_len = 0;
|
|
Packit Service |
102278 |
void *tmp = NULL;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
const char *toplevel = NULL;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
struct dirent **priorities = NULL;
|
|
Packit Service |
102278 |
int priorities_len = 0;
|
|
Packit Service |
102278 |
char priority_path[PATH_MAX];
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
struct dirent **modules = NULL;
|
|
Packit Service |
102278 |
int modules_len = 0;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
uint16_t priority = 0;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
semanage_module_info_t *modinfo_tmp = NULL;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
semanage_module_info_t modinfo;
|
|
Packit Service |
102278 |
ret = semanage_module_info_init(sh, &modinfo);
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (sh->is_in_transaction) {
|
|
Packit Service |
102278 |
toplevel = semanage_path(SEMANAGE_TMP, SEMANAGE_MODULES);
|
|
Packit Service |
102278 |
} else {
|
|
Packit Service |
102278 |
toplevel = semanage_path(SEMANAGE_ACTIVE, SEMANAGE_MODULES);
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* find priorities */
|
|
Packit Service |
102278 |
priorities_len = scandir(toplevel,
|
|
Packit Service |
102278 |
&priorities,
|
|
Packit Service |
102278 |
semanage_priorities_filename_select,
|
|
Packit Service |
102278 |
versionsort);
|
|
Packit Service |
102278 |
if (priorities_len == -1) {
|
|
Packit Service |
102278 |
ERR(sh, "Error while scanning directory %s.", toplevel);
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* for each priority directory */
|
|
Packit Service |
102278 |
/* loop through in reverse so that highest priority is first */
|
|
Packit Service |
102278 |
for (i = priorities_len - 1; i >= 0; i--) {
|
|
Packit Service |
102278 |
/* convert priority string to uint16_t */
|
|
Packit Service |
102278 |
ret = semanage_string_to_priority(priorities[i]->d_name,
|
|
Packit Service |
102278 |
&priority);
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* set our priority */
|
|
Packit Service |
102278 |
ret = semanage_module_info_set_priority(sh,
|
|
Packit Service |
102278 |
&modinfo,
|
|
Packit Service |
102278 |
priority);
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* get the priority path */
|
|
Packit Service |
102278 |
ret = semanage_module_get_path(sh,
|
|
Packit Service |
102278 |
&modinfo,
|
|
Packit Service |
102278 |
SEMANAGE_MODULE_PATH_PRIORITY,
|
|
Packit Service |
102278 |
priority_path,
|
|
Packit Service |
102278 |
sizeof(priority_path));
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* cleanup old modules */
|
|
Packit Service |
102278 |
if (modules != NULL) {
|
|
Packit Service |
102278 |
for (j = 0; j < modules_len; j++) {
|
|
Packit Service |
102278 |
free(modules[j]);
|
|
Packit Service |
102278 |
modules[j] = NULL;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
free(modules);
|
|
Packit Service |
102278 |
modules = NULL;
|
|
Packit Service |
102278 |
modules_len = 0;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* find modules at this priority */
|
|
Packit Service |
102278 |
modules_len = scandir(priority_path,
|
|
Packit Service |
102278 |
&modules,
|
|
Packit Service |
102278 |
semanage_modules_filename_select,
|
|
Packit Service |
102278 |
versionsort);
|
|
Packit Service |
102278 |
if (modules_len == -1) {
|
|
Packit Service |
102278 |
ERR(sh,
|
|
Packit Service |
102278 |
"Error while scanning directory %s.",
|
|
Packit Service |
102278 |
priority_path);
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (modules_len == 0) continue;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* add space for modules */
|
|
Packit Service |
102278 |
tmp = realloc(*modinfos,
|
|
Packit Service |
102278 |
sizeof(semanage_module_info_t) *
|
|
Packit Service |
102278 |
(*modinfos_len + modules_len));
|
|
Packit Service |
102278 |
if (tmp == NULL) {
|
|
Packit Service |
102278 |
ERR(sh, "Error allocating memory for module array.");
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
*modinfos = tmp;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* for each module directory */
|
|
Packit Service |
102278 |
for(j = 0; j < modules_len; j++) {
|
|
Packit Service |
102278 |
/* set module name */
|
|
Packit Service |
102278 |
ret = semanage_module_info_set_name(
|
|
Packit Service |
102278 |
sh,
|
|
Packit Service |
102278 |
&modinfo,
|
|
Packit Service |
102278 |
modules[j]->d_name);
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* get module values */
|
|
Packit Service |
102278 |
ret = semanage_direct_get_module_info(
|
|
Packit Service |
102278 |
sh,
|
|
Packit Service |
102278 |
(const semanage_module_key_t *)
|
|
Packit Service |
102278 |
(&modinfo),
|
|
Packit Service |
102278 |
&modinfo_tmp);
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* copy into array */
|
|
Packit Service |
102278 |
ret = semanage_module_info_init(
|
|
Packit Service |
102278 |
sh,
|
|
Packit Service |
102278 |
&((*modinfos)[*modinfos_len]));
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
ret = semanage_module_info_clone(
|
|
Packit Service |
102278 |
sh,
|
|
Packit Service |
102278 |
modinfo_tmp,
|
|
Packit Service |
102278 |
&((*modinfos)[*modinfos_len]));
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
semanage_module_info_destroy(sh, modinfo_tmp);
|
|
Packit Service |
102278 |
free(modinfo_tmp);
|
|
Packit Service |
102278 |
modinfo_tmp = NULL;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
*modinfos_len += 1;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
cleanup:
|
|
Packit Service |
102278 |
semanage_module_info_destroy(sh, &modinfo);
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (priorities != NULL) {
|
|
Packit Service |
102278 |
for (i = 0; i < priorities_len; i++) {
|
|
Packit Service |
102278 |
free(priorities[i]);
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
free(priorities);
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (modules != NULL) {
|
|
Packit Service |
102278 |
for (i = 0; i < modules_len; i++) {
|
|
Packit Service |
102278 |
free(modules[i]);
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
free(modules);
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
semanage_module_info_destroy(sh, modinfo_tmp);
|
|
Packit Service |
102278 |
free(modinfo_tmp);
|
|
Packit Service |
102278 |
modinfo_tmp = NULL;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (status != 0) {
|
|
Packit Service |
102278 |
if (modinfos != NULL) {
|
|
Packit Service |
102278 |
for (i = 0; i < *modinfos_len; i++) {
|
|
Packit Service |
102278 |
semanage_module_info_destroy(
|
|
Packit Service |
102278 |
sh,
|
|
Packit Service |
102278 |
&(*modinfos)[i]);
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
free(*modinfos);
|
|
Packit Service |
102278 |
*modinfos = NULL;
|
|
Packit Service |
102278 |
*modinfos_len = 0;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
return status;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
static int semanage_direct_install_info(semanage_handle_t *sh,
|
|
Packit Service |
102278 |
const semanage_module_info_t *modinfo,
|
|
Packit Service |
102278 |
char *data,
|
|
Packit Service |
102278 |
size_t data_len)
|
|
Packit Service |
102278 |
{
|
|
Packit Service |
102278 |
assert(sh);
|
|
Packit Service |
102278 |
assert(modinfo);
|
|
Packit Service |
102278 |
assert(data);
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
int status = 0;
|
|
Packit Service |
102278 |
int ret = 0;
|
|
Packit Service |
102278 |
int type;
|
|
Packit Service |
102278 |
struct stat sb;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
char path[PATH_MAX];
|
|
Packit Service |
102278 |
mode_t mask = umask(0077);
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
semanage_module_info_t *higher_info = NULL;
|
|
Packit Service |
102278 |
semanage_module_key_t higher_key;
|
|
Packit Service |
102278 |
ret = semanage_module_key_init(sh, &higher_key);
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* validate module info */
|
|
Packit Service |
102278 |
ret = semanage_module_info_validate(modinfo);
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
ERR(sh, "%s failed module validation.\n", modinfo->name);
|
|
Packit Service |
102278 |
status = -2;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* Check for higher priority module and warn if there is one as
|
|
Packit Service |
102278 |
* it will override the module currently being installed.
|
|
Packit Service |
102278 |
*/
|
|
Packit Service |
102278 |
ret = semanage_module_key_set_name(sh, &higher_key, modinfo->name);
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
ret = semanage_direct_get_module_info(sh, &higher_key, &higher_info);
|
|
Packit Service |
102278 |
if (ret == 0) {
|
|
Packit Service |
102278 |
if (higher_info->priority > modinfo->priority) {
|
|
Packit Service |
102278 |
errno = 0;
|
|
Packit Service |
102278 |
WARN(sh,
|
|
Packit Service |
102278 |
"A higher priority %s module exists at priority %d and will override the module currently being installed at priority %d.",
|
|
Packit Service |
102278 |
modinfo->name,
|
|
Packit Service |
102278 |
higher_info->priority,
|
|
Packit Service |
102278 |
modinfo->priority);
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
else if (higher_info->priority < modinfo->priority) {
|
|
Packit Service |
102278 |
errno = 0;
|
|
Packit Service |
102278 |
INFO(sh,
|
|
Packit Service |
102278 |
"Overriding %s module at lower priority %d with module at priority %d.",
|
|
Packit Service |
102278 |
modinfo->name,
|
|
Packit Service |
102278 |
higher_info->priority,
|
|
Packit Service |
102278 |
modinfo->priority);
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (higher_info->enabled == 0 && modinfo->enabled == -1) {
|
|
Packit Service |
102278 |
errno = 0;
|
|
Packit Service |
102278 |
WARN(sh,
|
|
Packit Service |
102278 |
"%s module will be disabled after install as there is a disabled instance of this module present in the system.",
|
|
Packit Service |
102278 |
modinfo->name);
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* set module meta data */
|
|
Packit Service |
102278 |
ret = semanage_direct_set_module_info(sh, modinfo);
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
status = -2;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* install module source file */
|
|
Packit Service |
102278 |
if (!strcasecmp(modinfo->lang_ext, "cil")) {
|
|
Packit Service |
102278 |
type = SEMANAGE_MODULE_PATH_CIL;
|
|
Packit Service |
102278 |
} else {
|
|
Packit Service |
102278 |
type = SEMANAGE_MODULE_PATH_HLL;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
ret = semanage_module_get_path(
|
|
Packit Service |
102278 |
sh,
|
|
Packit Service |
102278 |
modinfo,
|
|
Packit Service |
102278 |
type,
|
|
Packit Service |
102278 |
path,
|
|
Packit Service |
102278 |
sizeof(path));
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
status = -3;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
ret = bzip(sh, path, data, data_len);
|
|
Packit Service |
102278 |
if (ret <= 0) {
|
|
Packit Service |
102278 |
ERR(sh, "Error while writing to %s.", path);
|
|
Packit Service |
102278 |
status = -3;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* if this is an HLL, delete the CIL cache if it exists so it will get recompiled */
|
|
Packit Service |
102278 |
if (type == SEMANAGE_MODULE_PATH_HLL) {
|
|
Packit Service |
102278 |
ret = semanage_module_get_path(
|
|
Packit Service |
102278 |
sh,
|
|
Packit Service |
102278 |
modinfo,
|
|
Packit Service |
102278 |
SEMANAGE_MODULE_PATH_CIL,
|
|
Packit Service |
102278 |
path,
|
|
Packit Service |
102278 |
sizeof(path));
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
status = -3;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
if (stat(path, &sb) == 0) {
|
|
Packit Service |
102278 |
ret = unlink(path);
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
ERR(sh, "Error while removing cached CIL file %s: %s", path, strerror(errno));
|
|
Packit Service |
102278 |
status = -3;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
cleanup:
|
|
Packit Service |
102278 |
semanage_module_key_destroy(sh, &higher_key);
|
|
Packit Service |
102278 |
semanage_module_info_destroy(sh, higher_info);
|
|
Packit Service |
102278 |
free(higher_info);
|
|
Packit Service |
102278 |
umask(mask);
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
return status;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
static int semanage_direct_remove_key(semanage_handle_t *sh,
|
|
Packit Service |
102278 |
const semanage_module_key_t *modkey)
|
|
Packit Service |
102278 |
{
|
|
Packit Service |
102278 |
assert(sh);
|
|
Packit Service |
102278 |
assert(modkey);
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
int status = 0;
|
|
Packit Service |
102278 |
int ret = 0;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
char path[PATH_MAX];
|
|
Packit Service |
102278 |
semanage_module_info_t *modinfo = NULL;
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
semanage_module_key_t modkey_tmp;
|
|
Packit Service |
102278 |
ret = semanage_module_key_init(sh, &modkey_tmp);
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* validate module key */
|
|
Packit Service |
102278 |
ret = semanage_module_validate_priority(modkey->priority);
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
errno = 0;
|
|
Packit Service |
102278 |
ERR(sh, "Priority %d is invalid.", modkey->priority);
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
ret = semanage_module_validate_name(modkey->name);
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
errno = 0;
|
|
Packit Service |
102278 |
ERR(sh, "Name %s is invalid.", modkey->name);
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
ret = semanage_module_key_set_name(sh, &modkey_tmp, modkey->name);
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* get module path */
|
|
Packit Service |
102278 |
ret = semanage_module_get_path(
|
|
Packit Service |
102278 |
sh,
|
|
Packit Service |
102278 |
(const semanage_module_info_t *)modkey,
|
|
Packit Service |
102278 |
SEMANAGE_MODULE_PATH_NAME,
|
|
Packit Service |
102278 |
path,
|
|
Packit Service |
102278 |
sizeof(path));
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
status = -2;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* remove directory */
|
|
Packit Service |
102278 |
ret = semanage_remove_directory(path);
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
ERR(sh, "Unable to remove module %s at priority %d.", modkey->name, modkey->priority);
|
|
Packit Service |
102278 |
status = -2;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* check if its the last module at any priority */
|
|
Packit Service |
102278 |
ret = semanage_module_get_module_info(sh, &modkey_tmp, &modinfo);
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
/* info that no other module will override */
|
|
Packit Service |
102278 |
errno = 0;
|
|
Packit Service |
102278 |
INFO(sh,
|
|
Packit Service |
102278 |
"Removing last %s module (no other %s module exists at another priority).",
|
|
Packit Service |
102278 |
modkey->name,
|
|
Packit Service |
102278 |
modkey->name);
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
/* remove disabled status file */
|
|
Packit Service |
102278 |
ret = semanage_module_get_path(
|
|
Packit Service |
102278 |
sh,
|
|
Packit Service |
102278 |
(const semanage_module_info_t *)modkey,
|
|
Packit Service |
102278 |
SEMANAGE_MODULE_PATH_DISABLED,
|
|
Packit Service |
102278 |
path,
|
|
Packit Service |
102278 |
sizeof(path));
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
struct stat sb;
|
|
Packit Service |
102278 |
if (stat(path, &sb) == 0) {
|
|
Packit Service |
102278 |
ret = unlink(path);
|
|
Packit Service |
102278 |
if (ret != 0) {
|
|
Packit Service |
102278 |
status = -1;
|
|
Packit Service |
102278 |
goto cleanup;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
else {
|
|
Packit Service |
102278 |
/* if a lower priority module is going to become active */
|
|
Packit Service |
102278 |
if (modkey->priority > modinfo->priority) {
|
|
Packit Service |
102278 |
/* inform what the new active module will be */
|
|
Packit Service |
102278 |
errno = 0;
|
|
Packit Service |
102278 |
INFO(sh,
|
|
Packit Service |
102278 |
"%s module at priority %d is now active.",
|
|
Packit Service |
102278 |
modinfo->name,
|
|
Packit Service |
102278 |
modinfo->priority);
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
cleanup:
|
|
Packit Service |
102278 |
semanage_module_key_destroy(sh, &modkey_tmp);
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
semanage_module_info_destroy(sh, modinfo);
|
|
Packit Service |
102278 |
free(modinfo);
|
|
Packit Service |
102278 |
|
|
Packit Service |
102278 |
return status;
|
|
Packit Service |
102278 |
}
|
|
Packit Service |
102278 |
|