#include <stdlib.h>
|
#include <string.h>
|
#include <netinet/in.h>
|
#include <arpa/inet.h>
|
#include <errno.h>
|
|
#include "sepol/policydb/policydb.h"
|
#include "ibendport_internal.h"
|
#include "context_internal.h"
|
#include "debug.h"
|
|
struct sepol_ibendport {
|
/* Device Name */
|
char *ibdev_name;
|
|
/* Port number */
|
int port;
|
|
/* Context */
|
sepol_context_t *con;
|
};
|
|
struct sepol_ibendport_key {
|
/* Device Name */
|
char *ibdev_name;
|
|
/* Port number */
|
int port;
|
};
|
|
/* Allocates a sufficiently large string (ibdev_name) */
|
int sepol_ibendport_alloc_ibdev_name(sepol_handle_t *handle,
|
char **ibdev_name)
|
{
|
*ibdev_name = calloc(1, IB_DEVICE_NAME_MAX);
|
|
if (!*ibdev_name)
|
goto omem;
|
|
return STATUS_SUCCESS;
|
|
omem:
|
ERR(handle, "out of memory");
|
ERR(handle, "could not allocate string buffer for ibdev_name");
|
return STATUS_ERR;
|
}
|
|
/* Key */
|
int sepol_ibendport_key_create(sepol_handle_t *handle,
|
const char *ibdev_name,
|
int port,
|
sepol_ibendport_key_t **key_ptr)
|
{
|
sepol_ibendport_key_t *tmp_key =
|
(sepol_ibendport_key_t *)malloc(sizeof(sepol_ibendport_key_t));
|
|
if (!tmp_key) {
|
ERR(handle, "out of memory, could not create ibendport key");
|
goto omem;
|
}
|
|
if (sepol_ibendport_alloc_ibdev_name(handle, &tmp_key->ibdev_name) < 0)
|
goto err;
|
|
strncpy(tmp_key->ibdev_name, ibdev_name, IB_DEVICE_NAME_MAX);
|
tmp_key->port = port;
|
|
*key_ptr = tmp_key;
|
return STATUS_SUCCESS;
|
|
omem:
|
ERR(handle, "out of memory");
|
|
err:
|
sepol_ibendport_key_free(tmp_key);
|
ERR(handle, "could not create ibendport key for IB device %s, port %u",
|
ibdev_name, port);
|
return STATUS_ERR;
|
}
|
|
hidden_def(sepol_ibendport_key_create)
|
|
void sepol_ibendport_key_unpack(const sepol_ibendport_key_t *key,
|
const char **ibdev_name, int *port)
|
{
|
*ibdev_name = key->ibdev_name;
|
*port = key->port;
|
}
|
|
hidden_def(sepol_ibendport_key_unpack)
|
|
int sepol_ibendport_key_extract(sepol_handle_t *handle,
|
const sepol_ibendport_t *ibendport,
|
sepol_ibendport_key_t **key_ptr)
|
{
|
if (sepol_ibendport_key_create
|
(handle, ibendport->ibdev_name, ibendport->port, key_ptr) < 0) {
|
ERR(handle, "could not extract key from ibendport device %s port %d",
|
ibendport->ibdev_name,
|
ibendport->port);
|
|
return STATUS_ERR;
|
}
|
|
return STATUS_SUCCESS;
|
}
|
|
void sepol_ibendport_key_free(sepol_ibendport_key_t *key)
|
{
|
if (!key)
|
return;
|
free(key->ibdev_name);
|
free(key);
|
}
|
|
int sepol_ibendport_compare(const sepol_ibendport_t *ibendport, const sepol_ibendport_key_t *key)
|
{
|
int rc;
|
|
rc = strcmp(ibendport->ibdev_name, key->ibdev_name);
|
|
if ((ibendport->port == key->port) && !rc)
|
return 0;
|
|
if (ibendport->port < key->port)
|
return -1;
|
else if (key->port < ibendport->port)
|
return 1;
|
else
|
return rc;
|
}
|
|
int sepol_ibendport_compare2(const sepol_ibendport_t *ibendport, const sepol_ibendport_t *ibendport2)
|
{
|
int rc;
|
|
rc = strcmp(ibendport->ibdev_name, ibendport2->ibdev_name);
|
|
if ((ibendport->port == ibendport2->port) && !rc)
|
return 0;
|
|
if (ibendport->port < ibendport2->port)
|
return -1;
|
else if (ibendport2->port < ibendport->port)
|
return 1;
|
else
|
return rc;
|
}
|
|
int sepol_ibendport_get_port(const sepol_ibendport_t *ibendport)
|
{
|
return ibendport->port;
|
}
|
|
hidden_def(sepol_ibendport_get_port)
|
|
void sepol_ibendport_set_port(sepol_ibendport_t *ibendport, int port)
|
{
|
ibendport->port = port;
|
}
|
|
hidden_def(sepol_ibendport_set_port)
|
|
int sepol_ibendport_get_ibdev_name(sepol_handle_t *handle,
|
const sepol_ibendport_t *ibendport,
|
char **ibdev_name)
|
{
|
char *tmp_ibdev_name = NULL;
|
|
if (sepol_ibendport_alloc_ibdev_name(handle, &tmp_ibdev_name) < 0)
|
goto err;
|
|
strncpy(tmp_ibdev_name, ibendport->ibdev_name, IB_DEVICE_NAME_MAX);
|
*ibdev_name = tmp_ibdev_name;
|
return STATUS_SUCCESS;
|
|
err:
|
free(tmp_ibdev_name);
|
ERR(handle, "could not get ibendport ibdev_name");
|
return STATUS_ERR;
|
}
|
|
hidden_def(sepol_ibendport_get_ibdev_name)
|
|
int sepol_ibendport_set_ibdev_name(sepol_handle_t *handle,
|
sepol_ibendport_t *ibendport,
|
const char *ibdev_name)
|
{
|
char *tmp = NULL;
|
|
if (sepol_ibendport_alloc_ibdev_name(handle, &tmp) < 0)
|
goto err;
|
|
strncpy(tmp, ibdev_name, IB_DEVICE_NAME_MAX);
|
free(ibendport->ibdev_name);
|
ibendport->ibdev_name = tmp;
|
return STATUS_SUCCESS;
|
|
err:
|
free(tmp);
|
ERR(handle, "could not set ibendport subnet prefix to %s", ibdev_name);
|
return STATUS_ERR;
|
}
|
|
hidden_def(sepol_ibendport_set_ibdev_name)
|
|
/* Create */
|
int sepol_ibendport_create(sepol_handle_t *handle, sepol_ibendport_t **ibendport)
|
{
|
sepol_ibendport_t *tmp_ibendport = (sepol_ibendport_t *)malloc(sizeof(sepol_ibendport_t));
|
|
if (!tmp_ibendport) {
|
ERR(handle, "out of memory, could not create ibendport record");
|
return STATUS_ERR;
|
}
|
|
tmp_ibendport->ibdev_name = NULL;
|
tmp_ibendport->port = 0;
|
tmp_ibendport->con = NULL;
|
*ibendport = tmp_ibendport;
|
|
return STATUS_SUCCESS;
|
}
|
|
hidden_def(sepol_ibendport_create)
|
|
/* Deep copy clone */
|
int sepol_ibendport_clone(sepol_handle_t *handle,
|
const sepol_ibendport_t *ibendport,
|
sepol_ibendport_t **ibendport_ptr)
|
{
|
sepol_ibendport_t *new_ibendport = NULL;
|
|
if (sepol_ibendport_create(handle, &new_ibendport) < 0)
|
goto err;
|
|
if (sepol_ibendport_alloc_ibdev_name(handle, &new_ibendport->ibdev_name) < 0)
|
goto omem;
|
|
strncpy(new_ibendport->ibdev_name, ibendport->ibdev_name, IB_DEVICE_NAME_MAX);
|
new_ibendport->port = ibendport->port;
|
|
if (ibendport->con &&
|
(sepol_context_clone(handle, ibendport->con, &new_ibendport->con) < 0))
|
goto err;
|
|
*ibendport_ptr = new_ibendport;
|
return STATUS_SUCCESS;
|
|
omem:
|
ERR(handle, "out of memory");
|
|
err:
|
ERR(handle, "could not clone ibendport record");
|
sepol_ibendport_free(new_ibendport);
|
return STATUS_ERR;
|
}
|
|
/* Destroy */
|
void sepol_ibendport_free(sepol_ibendport_t *ibendport)
|
{
|
if (!ibendport)
|
return;
|
|
free(ibendport->ibdev_name);
|
sepol_context_free(ibendport->con);
|
free(ibendport);
|
}
|
|
hidden_def(sepol_ibendport_free)
|
|
/* Context */
|
sepol_context_t *sepol_ibendport_get_con(const sepol_ibendport_t *ibendport)
|
{
|
return ibendport->con;
|
}
|
|
hidden_def(sepol_ibendport_get_con)
|
|
int sepol_ibendport_set_con(sepol_handle_t *handle,
|
sepol_ibendport_t *ibendport, sepol_context_t *con)
|
{
|
sepol_context_t *newcon;
|
|
if (sepol_context_clone(handle, con, &newcon) < 0) {
|
ERR(handle, "out of memory, could not set ibendport context");
|
return STATUS_ERR;
|
}
|
|
sepol_context_free(ibendport->con);
|
ibendport->con = newcon;
|
return STATUS_SUCCESS;
|
}
|
|
hidden_def(sepol_ibendport_set_con)
|