* [PATCH 00/33] libsemanage/libsepol object serialization and ps-api
@ 2007-04-23 21:34 jbrindle
2007-04-23 21:34 ` [PATCH 01/33] libsepol: basic serilization support jbrindle
` (34 more replies)
0 siblings, 35 replies; 58+ messages in thread
From: jbrindle @ 2007-04-23 21:34 UTC (permalink / raw)
To: selinux
This is the majority of the patches from the policy server release a few months ago. This implements object serialization to send objects (eg., booleans, file contexts, etc) across the line to the policy server. It also implements the line protocol to connect to the policy server and the backend for libsemanage so that semodule, semanage, etc will talk to a policy server instead of doing local operations.
The object serialization will also be necessary for the policy representation branch as we will use this infrastructure to serialize the policy tree for module reading and writing.
The only part left for the policy server is the hooks that were implemented in the expander. As the policy representation work is going on and should remove the expander entirely these patches will have to wait until we have enough of the new representation work to implement them there.
This is obviously meant only for trunk and the policyrep branch.
--
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH 01/33] libsepol: basic serilization support
2007-04-23 21:34 [PATCH 00/33] libsemanage/libsepol object serialization and ps-api jbrindle
@ 2007-04-23 21:34 ` jbrindle
2007-04-24 20:00 ` Karl MacMillan
2007-04-23 21:34 ` [PATCH 02/33] libsepol: boolean serialization jbrindle
` (33 subsequent siblings)
34 siblings, 1 reply; 58+ messages in thread
From: jbrindle @ 2007-04-23 21:34 UTC (permalink / raw)
To: selinux
Serialization versioning added to the sepol handle.
Serialization utility functions added in serialize.[ch]
---
libsepol/include/sepol/handle.h | 17 +
libsepol/src/handle.c | 89 +++++++++
libsepol/src/handle.h | 5
libsepol/src/libsepol.map | 1
libsepol/src/serialize.c | 389 ++++++++++++++++++++++++++++++++++++++++
libsepol/src/serialize.h | 45 ++++
6 files changed, 546 insertions(+)
Index: selinux-pms-support/libsepol/include/sepol/handle.h
===================================================================
--- selinux-pms-support.orig/libsepol/include/sepol/handle.h
+++ selinux-pms-support/libsepol/include/sepol/handle.h
@@ -1,6 +1,11 @@
#ifndef _SEPOL_HANDLE_H_
#define _SEPOL_HANDLE_H_
+#include <inttypes.h>
+
+#define SEPOL_SERIAL_VERSION_MAJOR 1
+#define SEPOL_SERIAL_VERSION_MINOR 0
+
struct sepol_handle;
typedef struct sepol_handle sepol_handle_t;
@@ -10,4 +15,16 @@ sepol_handle_t *sepol_handle_create(void
/* Destroy a sepol handle. */
void sepol_handle_destroy(sepol_handle_t *);
+/* Serialize the serialization version. */
+int sepol_handle_version_serialize(sepol_handle_t * sh, char **data, uint64_t *size);
+
+/* Unserialize the serialization version. */
+int sepol_handle_version_unserialize(sepol_handle_t * sh, char **data, uint64_t *size);
+
+/* Get the serialization version. */
+int sepol_handle_get_version(sepol_handle_t *sh, uint32_t * major, uint32_t * minor);
+
+/* Set the serialization version. */
+int sepol_handle_set_version(sepol_handle_t *sh, uint32_t major, uint32_t minor);
+
#endif
Index: selinux-pms-support/libsepol/src/handle.c
===================================================================
--- selinux-pms-support.orig/libsepol/src/handle.c
+++ selinux-pms-support/libsepol/src/handle.c
@@ -1,6 +1,7 @@
#include <stdlib.h>
#include "handle.h"
#include "debug.h"
+#include "serialize.h"
sepol_handle_t *sepol_handle_create(void)
{
@@ -9,6 +10,10 @@ sepol_handle_t *sepol_handle_create(void
if (sh == NULL)
return NULL;
+ /* Set default serialization version. */
+ sh->version_major = 0;
+ sh->version_minor = 0;
+
/* Set callback */
sh->msg_callback = sepol_msg_default_handler;
sh->msg_callback_arg = NULL;
@@ -20,3 +25,87 @@ void sepol_handle_destroy(sepol_handle_t
{
free(sh);
}
+
+int sepol_handle_get_version(sepol_handle_t *sh, uint32_t * major, uint32_t * minor)
+{
+ *major = sh->version_major;
+ *minor = sh->version_minor;
+ return STATUS_SUCCESS;
+}
+
+int sepol_handle_set_version(sepol_handle_t *sh, uint32_t major, uint32_t minor)
+{
+ sh->version_major = major;
+ sh->version_minor = minor;
+ return STATUS_SUCCESS;
+}
+
+int sepol_handle_version_serialize(sepol_handle_t * sh, char **data, uint64_t *size)
+{
+ int status = STATUS_SUCCESS;
+ char *ptr;
+
+ /* Sundry sanity checks. */
+ if (data == NULL || size == NULL) {
+ status = STATUS_ERR;
+ goto cleanup;
+ }
+
+ /* Calculate size. */
+ status = sepol_serialize(sh, &(sh->version_major), 0, SEPOL_SERIAL_UINT32_T, NULL, size);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+ status = sepol_serialize(sh, &(sh->version_minor), 0, SEPOL_SERIAL_UINT32_T, NULL, size);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Allocate memory. */
+ ptr = *data = calloc(*size, sizeof(char));
+ if (*data == NULL) {
+ status = STATUS_ERR;
+ goto cleanup;
+ }
+
+ /* Serialize. */
+ status = sepol_serialize(sh, &(sh->version_major), 0, SEPOL_SERIAL_UINT32_T, &ptr, NULL);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+ status = sepol_serialize(sh, &(sh->version_minor), 0, SEPOL_SERIAL_UINT32_T, &ptr, NULL);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+cleanup:
+ return status;
+}
+
+int sepol_handle_version_unserialize(sepol_handle_t * sh, char **data, uint64_t *size)
+{
+ int status = STATUS_SUCCESS;
+ uint32_t *major = NULL;
+ uint32_t *minor = NULL;
+ size_t *datum_length = NULL;
+ char *ptr = *data;
+
+ /* Sundry sanity checks. */
+ if (data == NULL || *data == NULL || size == NULL) {
+ status = STATUS_ERR;
+ goto cleanup;
+ }
+
+ status = sepol_unserialize(sh, &ptr, size, (void **)&major, &datum_length, SEPOL_SERIAL_UINT32_T);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ status = sepol_unserialize(sh, &ptr, size, (void **)&minor, &datum_length, SEPOL_SERIAL_UINT32_T);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ sh->version_major = *major;
+ sh->version_minor = *minor;
+
+cleanup:
+ free(major);
+ free(minor);
+ free(datum_length);
+ return status;
+}
Index: selinux-pms-support/libsepol/src/handle.h
===================================================================
--- selinux-pms-support.orig/libsepol/src/handle.h
+++ selinux-pms-support/libsepol/src/handle.h
@@ -1,9 +1,14 @@
#ifndef _SEPOL_INTERNAL_HANDLE_H_
#define _SEPOL_INTERNAL_HANDLE_H_
+#include <inttypes.h>
#include <sepol/handle.h>
struct sepol_handle {
+ /* Serialization version. */
+ uint32_t version_major;
+ uint32_t version_minor;
+
/* Error handling */
int msg_level;
const char *msg_channel;
Index: selinux-pms-support/libsepol/src/libsepol.map
===================================================================
--- selinux-pms-support.orig/libsepol/src/libsepol.map
+++ selinux-pms-support/libsepol/src/libsepol.map
@@ -12,5 +12,6 @@
sepol_policydb_*; sepol_set_policydb_from_file;
sepol_policy_kern_*;
sepol_policy_file_*;
+ sepol_*_serialize; sepol_*_unserialize;
local: *;
};
Index: selinux-pms-support/libsepol/src/serialize.c
===================================================================
--- /dev/null
+++ selinux-pms-support/libsepol/src/serialize.c
@@ -0,0 +1,389 @@
+/* Author: Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2004-2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+
+#include "handle.h"
+#include "debug.h"
+#include "serialize.h"
+#include "private.h"
+
+/* This file provides general serialize and unserialize functions. */
+
+/** Serializes various kinds of datum.
+ *
+ * Two use cases:
+ * 1) Calling serialize with a non-NULL size.
+ * This causes serialize to calculate the expected
+ * size of serializing. No serialization occurs.
+ * Destructively modifies size. Data may be NULL.
+ * 2) Calling serialize with a NULL size.
+ * This results in data being filled with the
+ * serialized information. Caller must pre-allocate
+ * space for data. Destructively modifies data.
+ *
+ * This function acts iteratively moving the *data or size values.
+ *
+ * Supported datum_types (defined in serialize.h):
+ *
+ * SEPOL_SERIAL_INT32_T
+ * Serializes datum to a int32_t as defined in inttypes.h
+ * datum may NOT be NULL.
+ * datum_length is not utilized.
+ * SEPOL_SERIAL_UINT32_T
+ * Serializes datum to a uint32_t as defined in inttypes.h
+ * datum may NOT be NULL.
+ * datum_length is not utilized.
+ * SEPOL_SERIAL_SIZE_T
+ * Serializes datum to a size_t as defined in stddef.h
+ * datum may NOT be NULL.
+ * datum_length is not utilized.
+ * SEPOL_SERIAL_STRING
+ * Serializes a char*.
+ * datum may be NULL.
+ * datum_length should be the length of the string as returned by strlen.
+ * SEPOL_SERIAL_STRING_ARRAY
+ * Serializes a char**.
+ * datum may be NULL.
+ * datum_length should be the size of the array.
+ * Each string will be serialized as per SEPOL_SERIAL_STRING and its size
+ * determined via strlen.
+ *
+ * NULL pointers are distinguished (where they are allowed at all).
+ * In the case of strings this means that a NULL char* has a different
+ * serialization from the empty string "".
+ *
+ */
+int sepol_serialize(sepol_handle_t * handle,
+ const void *datum,
+ size_t datum_length,
+ unsigned int datum_type, char **data, uint64_t * size)
+{
+ int status;
+ unsigned int flags;
+ uint32_t i;
+ void *temp = NULL;
+
+ switch (datum_type) {
+ case SEPOL_SERIAL_INT32_T:
+ case SEPOL_SERIAL_UINT32_T:
+ if (size == NULL) {
+ temp = calloc(1, sizeof(int32_t));
+ if (temp == NULL) {
+ status = STATUS_ERR;
+ goto cleanup;
+ }
+
+ *((int32_t *)temp) = cpu_to_le32(*((int32_t *) datum));
+ memcpy(*data, temp, sizeof(int32_t));
+ *data += sizeof(int32_t);
+ }
+ else
+ *size += sizeof(int32_t);
+ break;
+ case SEPOL_SERIAL_SIZE_T:
+ if (size == NULL) {
+ temp = calloc(1, sizeof(uint64_t));
+ if (temp == NULL) {
+ status = STATUS_ERR;
+ goto cleanup;
+ }
+
+ *((uint64_t *)temp) = cpu_to_le64(*((size_t *) datum));
+
+ memcpy(*data, temp, sizeof(uint64_t));
+ *data += sizeof(uint64_t);
+ }
+ else
+ *size += sizeof(uint64_t);
+ break;
+ case SEPOL_SERIAL_STRING:
+ /* Flags (intended as a bitmap):
+ * 0 == NULL
+ * 1 == Non NULL
+ */
+ flags = (datum == NULL) ? 0 : 1;
+
+ status =
+ sepol_serialize(handle, &flags, 0, SEPOL_SERIAL_UINT32_T, data,
+ size);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Write if not null. */
+ if (flags & 1) {
+ /* Size. */
+ status =
+ sepol_serialize(handle, &datum_length, 0,
+ SEPOL_SERIAL_SIZE_T, data, size);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Datum. */
+ if (size == NULL) {
+ status =
+ snprintf(*data, datum_length + 1, "%s",
+ (char *)datum);
+ if (status < 0 || (unsigned)status > datum_length)
+ goto cleanup;
+ else {
+ *data += status + 1;
+ status = STATUS_SUCCESS;
+ }
+ } else {
+ *size += datum_length + 1;
+ }
+ }
+ break;
+ case SEPOL_SERIAL_STRING_ARRAY:
+ /* Flags (intended as a bitmap):
+ * 0 == NULL
+ * 1 == Non NULL
+ */
+ flags = (datum == NULL) ? 0 : 1;
+
+ status =
+ sepol_serialize(handle, &flags, 0, SEPOL_SERIAL_UINT32_T, data,
+ size);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Write if not null. */
+ if (flags & 1) {
+ /* Size. */
+ status =
+ sepol_serialize(handle, &datum_length, 0,
+ SEPOL_SERIAL_UINT32_T, data, size);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Datum. */
+ for (i = 0; i < datum_length; i++) {
+ status =
+ sepol_serialize(handle, ((char **)datum)[i],
+ strlen(((char **)datum)[i]),
+ SEPOL_SERIAL_STRING, data, size);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+ }
+ }
+ break;
+ default:
+ status = STATUS_ERR;
+ goto cleanup;
+ }
+
+ /* Cleanup. */
+ status = STATUS_SUCCESS;
+cleanup:
+ free(temp);
+ return status;
+}
+
+/** Unserializes various kinds of datum as serialized by sepol_serialize.
+ *
+ * This function acts iteratively moving the *data AND size values.
+ * size is decremented as data is unserialized.
+ *
+ * It also allocates memory for datum and, depending on datum_type, datum_length.
+ * Caller must free.
+ *
+ * Supported datum_types (defined in serialize.h):
+ *
+ * SEPOL_SERIAL_INT32_T
+ * Unserializes data into an int32_t as defined in inttypes.h.
+ * datum_length may be NULL.
+ * SEPOL_SERIAL_UINT32_T
+ * Unserializes data into an uint32_t as defined in inttypes.h.
+ * datum_length may be NULL.
+ * SEPOL_SERIAL_SIZE_T
+ * Unserializes data into an size_t as defined in stddef.h.
+ * datum_length may be NULL.
+ * SEPOL_SERIAL_STRING
+ * Unserializes data into a NULL terminated char*.
+ * datum_length may NOT be NULL and will be the size of the string.
+ * SEPOL_SERIAL_STRING_ARRAY
+ * Unserializes data into a char**.
+ * Each entry in the array will be unserialized as per SEPOL_SERIAL_STRING.
+ * datum_length may NOT be NULL and will be the size of the array.
+ */
+int sepol_unserialize(sepol_handle_t * handle,
+ char **data, uint64_t * size,
+ void **datum,
+ size_t ** datum_length,
+ unsigned int datum_type)
+{
+ int status;
+ unsigned int *flags = NULL;
+ uint32_t i;
+ void *temp = NULL;
+ size_t *temp_length = NULL;
+
+ switch (datum_type) {
+ case SEPOL_SERIAL_INT32_T:
+ case SEPOL_SERIAL_UINT32_T:
+ *datum = calloc(1, sizeof(int32_t));
+ if (*datum == NULL) {
+ status = STATUS_ERR;
+ goto cleanup;
+ }
+
+ memcpy(*datum, *data, sizeof(int32_t));
+ **((int32_t **)datum) = le32_to_cpu(**((int32_t **) datum));
+
+ *size -= sizeof(int32_t);
+ *data += sizeof(int32_t);
+ break;
+ case SEPOL_SERIAL_SIZE_T:
+ temp = calloc(1, sizeof(uint64_t));
+ if (temp == NULL) {
+ status = STATUS_ERR;
+ goto cleanup;
+ }
+
+ memcpy(temp, *data, sizeof(uint64_t));
+
+ *((uint64_t *) temp) = le64_to_cpu(*((uint64_t *) temp));
+
+ if (*((uint64_t *) temp) > UINT_MAX) {
+ status = STATUS_ERR;
+ goto cleanup;
+ }
+
+ *datum = calloc(1, sizeof(size_t));
+ if (datum == NULL) {
+ status = STATUS_ERR;
+ goto cleanup;
+ }
+
+ **((size_t **)datum) = *((uint64_t *) temp);
+
+ *size -= sizeof(uint64_t);
+ *data += sizeof(uint64_t);
+ break;
+ case SEPOL_SERIAL_STRING:
+ /* Flags (intended as a bitmap):
+ * 0 == NULL
+ * 1 == Non NULL
+ */
+ status =
+ sepol_unserialize(handle,
+ data, size,
+ (void **)(&flags), NULL,
+ SEPOL_SERIAL_UINT32_T);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ if (*flags & 1) {
+ /* Size. */
+ status =
+ sepol_unserialize(handle,
+ data, size,
+ (void **)datum_length, NULL,
+ SEPOL_SERIAL_SIZE_T);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Datum. */
+ *datum = calloc(**datum_length + 1, sizeof(char));
+ if (*datum == NULL) {
+ status = STATUS_ERR;
+ goto cleanup;
+ }
+
+ memcpy(*datum, *data, **datum_length + 1);
+
+ *size -= **datum_length + 1;
+ *data += **datum_length + 1;
+ } else {
+ *datum = NULL;
+ *datum_length = NULL;
+ }
+
+ free(flags);
+ flags = NULL;
+ break;
+ case SEPOL_SERIAL_STRING_ARRAY:
+ /* Flags (intended as a bitmap):
+ * 0 == NULL
+ * 1 == Non NULL
+ */
+ status =
+ sepol_unserialize(handle,
+ data, size,
+ (void **)(&flags), NULL,
+ SEPOL_SERIAL_UINT32_T);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Write if not null. */
+ if (*flags & 1) {
+ /* Size. */
+ status =
+ sepol_unserialize(handle,
+ data, size,
+ (void **)datum_length, NULL,
+ SEPOL_SERIAL_UINT32_T);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Datum. */
+ *datum =
+ calloc(sizeof(char *),
+ sizeof(char *) * (**datum_length));
+ if (*datum == NULL) {
+ status = STATUS_ERR;
+ goto cleanup;
+ }
+
+ for (i = 0; i < **datum_length; i++) {
+ status = sepol_unserialize(handle,
+ data,
+ size,
+ (void **)&(((char **)(*datum))[i]),
+ &temp_length,
+ SEPOL_SERIAL_STRING);
+
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ free(temp_length);
+ temp_length = NULL;
+ }
+ }
+
+ free(flags);
+ flags = NULL;
+ break;
+ default:
+ status = STATUS_ERR;
+ goto cleanup;
+ }
+
+ /* Cleanup. */
+ status = STATUS_SUCCESS;
+cleanup:
+ free(flags);
+ free(temp);
+ free(temp_length);
+ return status;
+}
+
Index: selinux-pms-support/libsepol/src/serialize.h
===================================================================
--- /dev/null
+++ selinux-pms-support/libsepol/src/serialize.h
@@ -0,0 +1,45 @@
+/* Author: Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2005-2007 Tresys Technology, LLC
+ * Copyright (C) 2005 Red Hat Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _SEPOL_SERIALIZE_INTERNAL_H_
+#define _SEPOL_SERIALIZE_INTERNAL_H_
+
+#include <inttypes.h>
+#include "handle.h"
+
+/* Datum types. */
+#define SEPOL_SERIAL_INT32_T 0
+#define SEPOL_SERIAL_UINT32_T 1
+#define SEPOL_SERIAL_SIZE_T 2
+#define SEPOL_SERIAL_STRING 3
+#define SEPOL_SERIAL_STRING_ARRAY 4
+
+extern int sepol_serialize(sepol_handle_t * handle,
+ const void *datum,
+ size_t datum_size,
+ unsigned int datum_type, char **data, uint64_t * size);
+
+extern int sepol_unserialize(sepol_handle_t * handle,
+ char **data, uint64_t * size,
+ void **datum,
+ size_t ** datum_length,
+ unsigned int datum_type);
+
+#endif
--
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH 02/33] libsepol: boolean serialization
2007-04-23 21:34 [PATCH 00/33] libsemanage/libsepol object serialization and ps-api jbrindle
2007-04-23 21:34 ` [PATCH 01/33] libsepol: basic serilization support jbrindle
@ 2007-04-23 21:34 ` jbrindle
2007-04-25 4:56 ` Karl MacMillan
2007-04-23 21:34 ` [PATCH 03/33] libsepol: context serialization jbrindle
` (32 subsequent siblings)
34 siblings, 1 reply; 58+ messages in thread
From: jbrindle @ 2007-04-23 21:34 UTC (permalink / raw)
To: selinux
This adds serialize/unserialize methods for boolean records.
---
libsepol/include/sepol/boolean_record.h | 10 +++
libsepol/src/boolean_internal.h | 2
libsepol/src/boolean_record.c | 96 ++++++++++++++++++++++++++++++++
3 files changed, 108 insertions(+)
Index: selinux-pms-support/libsepol/include/sepol/boolean_record.h
===================================================================
--- selinux-pms-support.orig/libsepol/include/sepol/boolean_record.h
+++ selinux-pms-support/libsepol/include/sepol/boolean_record.h
@@ -1,6 +1,7 @@
#ifndef _SEPOL_BOOLEAN_RECORD_H_
#define _SEPOL_BOOLEAN_RECORD_H_
+#include <inttypes.h>
#include <stddef.h>
#include <sepol/handle.h>
@@ -48,4 +49,13 @@ extern int sepol_bool_clone(sepol_handle
extern void sepol_bool_free(sepol_bool_t * boolean);
+/* Serialize/Unserialize */
+extern int sepol_bool_serialize(sepol_handle_t * handle,
+ const sepol_bool_t * boolean,
+ char **data, uint64_t * size);
+
+extern int sepol_bool_unserialize(sepol_handle_t * handle,
+ char **data, uint64_t * size,
+ sepol_bool_t ** boolean);
+
#endif
Index: selinux-pms-support/libsepol/src/boolean_internal.h
===================================================================
--- selinux-pms-support.orig/libsepol/src/boolean_internal.h
+++ selinux-pms-support/libsepol/src/boolean_internal.h
@@ -13,4 +13,6 @@ hidden_proto(sepol_bool_key_create)
hidden_proto(sepol_bool_set_value)
hidden_proto(sepol_bool_create)
hidden_proto(sepol_bool_free)
+ hidden_proto(sepol_bool_serialize)
+ hidden_proto(sepol_bool_unserialize)
#endif
Index: selinux-pms-support/libsepol/src/boolean_record.c
===================================================================
--- selinux-pms-support.orig/libsepol/src/boolean_record.c
+++ selinux-pms-support/libsepol/src/boolean_record.c
@@ -1,9 +1,11 @@
+#include <assert.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include "boolean_internal.h"
#include "debug.h"
+#include "serialize.h"
struct sepol_bool {
/* This boolean's name */
@@ -178,3 +180,97 @@ void sepol_bool_free(sepol_bool_t * bool
}
hidden_def(sepol_bool_free)
+
+/* Serialize/Unserialize */
+/** Destructively modifies data and size.
+ * Caller must pre-allocate space for data.
+ * Use sepol_bool_calculate_serialized_size(). */
+int sepol_bool_serialize(sepol_handle_t * handle,
+ const sepol_bool_t * boolean,
+ char **data, uint64_t * size)
+{
+ int status = STATUS_SUCCESS;
+ const char *name = NULL;
+ int value;
+
+ /* Sundry sanity checks. */
+ if (handle == NULL || boolean == NULL) {
+ status = STATUS_ERR;
+ goto cleanup;
+ }
+
+ /* Boolean name. */
+ name = sepol_bool_get_name(boolean);
+ status =
+ sepol_serialize(handle, name, (name == NULL) ? 0 : strlen(name),
+ SEPOL_SERIAL_STRING, data, size);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Value of boolean. */
+ value = sepol_bool_get_value(boolean);
+ status = sepol_serialize(handle, &value, 0, SEPOL_SERIAL_INT32_T, data, size);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Cleanup. */
+ cleanup:
+ return status;
+}
+
+hidden_def(sepol_bool_serialize)
+
+/** Destructively modifies boolean, data and size.
+ * Allocates space for boolean.
+ * Caller must free. */
+int sepol_bool_unserialize(sepol_handle_t * handle,
+ char **data, uint64_t * size,
+ sepol_bool_t ** boolean)
+{
+ int status = STATUS_SUCCESS;
+ char *name = NULL;
+ size_t *name_size = NULL;
+ int *value = NULL;
+
+ /* Sundry sanity checks. */
+ if (handle == NULL || data == NULL || *data == NULL || size == NULL) {
+ status = STATUS_ERR;
+ goto cleanup;
+ }
+
+ /* Allocate space. */
+ status = sepol_bool_create(handle, boolean);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Boolean name. */
+ status =
+ sepol_unserialize(handle,
+ data, size,
+ (void **)&name, &name_size, SEPOL_SERIAL_STRING);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+ if (name != NULL) {
+ status = sepol_bool_set_name(handle, *boolean, name);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+ }
+
+ /* Value of boolean. */
+ status =
+ sepol_unserialize(handle,
+ data, size,
+ (void **)&value, NULL, SEPOL_SERIAL_INT32_T);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+ sepol_bool_set_value(*boolean, *value);
+
+ /* Cleanup. */
+ cleanup:
+ free(name);
+ free(name_size);
+ free(value);
+ return status;
+}
+
+hidden_def(sepol_bool_unserialize)
--
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH 03/33] libsepol: context serialization
2007-04-23 21:34 [PATCH 00/33] libsemanage/libsepol object serialization and ps-api jbrindle
2007-04-23 21:34 ` [PATCH 01/33] libsepol: basic serilization support jbrindle
2007-04-23 21:34 ` [PATCH 02/33] libsepol: boolean serialization jbrindle
@ 2007-04-23 21:34 ` jbrindle
2007-04-23 21:34 ` [PATCH 04/33] libsepol: interface serialization jbrindle
` (31 subsequent siblings)
34 siblings, 0 replies; 58+ messages in thread
From: jbrindle @ 2007-04-23 21:34 UTC (permalink / raw)
To: selinux
This adds serialize/unserialize methods for context records.
---
libsepol/include/sepol/context_record.h | 10 +++
libsepol/src/context_internal.h | 2
libsepol/src/context_record.c | 84 ++++++++++++++++++++++++++++++++
3 files changed, 96 insertions(+)
Index: selinux-pms-support/libsepol/include/sepol/context_record.h
===================================================================
--- selinux-pms-support.orig/libsepol/include/sepol/context_record.h
+++ selinux-pms-support/libsepol/include/sepol/context_record.h
@@ -1,6 +1,7 @@
#ifndef _SEPOL_CONTEXT_RECORD_H_
#define _SEPOL_CONTEXT_RECORD_H_
+#include <inttypes.h>
#include <sepol/handle.h>
struct sepol_context;
@@ -43,6 +44,15 @@ extern int sepol_context_clone(sepol_han
extern void sepol_context_free(sepol_context_t * con);
+/* Serialize/Unserialize */
+extern int sepol_context_serialize(sepol_handle_t * handle,
+ const sepol_context_t * context,
+ char **data, uint64_t * size);
+
+extern int sepol_context_unserialize(sepol_handle_t * handle,
+ char **data, uint64_t * size,
+ sepol_context_t ** context);
+
/* Parse to/from string */
extern int sepol_context_from_string(sepol_handle_t * handle,
const char *str, sepol_context_t ** con);
Index: selinux-pms-support/libsepol/src/context_internal.h
===================================================================
--- selinux-pms-support.orig/libsepol/src/context_internal.h
+++ selinux-pms-support/libsepol/src/context_internal.h
@@ -16,4 +16,6 @@ hidden_proto(sepol_context_clone)
hidden_proto(sepol_context_set_role)
hidden_proto(sepol_context_set_type)
hidden_proto(sepol_context_set_user)
+ hidden_proto(sepol_context_serialize)
+ hidden_proto(sepol_context_unserialize)
#endif
Index: selinux-pms-support/libsepol/src/context_record.c
===================================================================
--- selinux-pms-support.orig/libsepol/src/context_record.c
+++ selinux-pms-support/libsepol/src/context_record.c
@@ -1,9 +1,11 @@
+#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "context_internal.h"
#include "debug.h"
+#include "serialize.h"
struct sepol_context {
@@ -198,6 +200,88 @@ void sepol_context_free(sepol_context_t
hidden_def(sepol_context_free)
+/* Serialize/Unserialize */
+/** Destructively modifies data and size.
+ * Caller must pre-allocate space for data.
+ * Use sepol_context_calculate_serialized_size(). */
+int sepol_context_serialize(sepol_handle_t * handle,
+ const sepol_context_t * context,
+ char **data, uint64_t * size)
+{
+ int status = STATUS_SUCCESS;
+ char *context_string = NULL;
+
+ /* Sundry sanity checks. */
+ if (handle == NULL || context == NULL) {
+ status = STATUS_ERR;
+ goto cleanup;
+ }
+
+ /* Context. */
+ status = sepol_context_to_string(handle, context, &context_string);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ status =
+ sepol_serialize(handle, context_string,
+ (context_string ==
+ NULL) ? 0 : strlen(context_string), SEPOL_SERIAL_STRING,
+ data, size);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Cleanup. */
+ cleanup:
+ free(context_string);
+ return status;
+}
+
+hidden_def(sepol_context_serialize)
+
+/** Destructively modifies context, data and size.
+ * Allocates space for context.
+ * Caller must free. */
+int sepol_context_unserialize(sepol_handle_t * handle,
+ char **data, uint64_t * size,
+ sepol_context_t ** context)
+{
+ int status = STATUS_SUCCESS;
+ char *context_string = NULL;
+ size_t *context_string_size = NULL;
+
+ /* Sundry sanity checks. */
+ if (handle == NULL || data == NULL || *data == NULL || size == NULL) {
+ status = STATUS_ERR;
+ goto cleanup;
+ }
+
+ /* Context. */
+ status =
+ sepol_unserialize(handle,
+ data, size,
+ (void **)&context_string, &context_string_size, SEPOL_SERIAL_STRING);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+ if (context_string != NULL) {
+ status =
+ sepol_context_from_string(handle, context_string, context);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+ } else {
+ status = sepol_context_create(handle, context);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+ }
+
+ /* Cleanup. */
+ cleanup:
+ free(context_string);
+ free(context_string_size);
+ return status;
+}
+
+hidden_def(sepol_context_unserialize)
+
int sepol_context_from_string(sepol_handle_t * handle,
const char *str, sepol_context_t ** con)
{
--
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH 04/33] libsepol: interface serialization
2007-04-23 21:34 [PATCH 00/33] libsemanage/libsepol object serialization and ps-api jbrindle
` (2 preceding siblings ...)
2007-04-23 21:34 ` [PATCH 03/33] libsepol: context serialization jbrindle
@ 2007-04-23 21:34 ` jbrindle
2007-04-23 21:35 ` [PATCH 05/33] libsepol: node serialization jbrindle
` (30 subsequent siblings)
34 siblings, 0 replies; 58+ messages in thread
From: jbrindle @ 2007-04-23 21:34 UTC (permalink / raw)
To: selinux
This adds serialize/unserialize methods for iface records.
---
libsepol/include/sepol/iface_record.h | 10 ++
libsepol/src/iface_internal.h | 2
libsepol/src/iface_record.c | 115 ++++++++++++++++++++++++++++++++++
3 files changed, 127 insertions(+)
Index: selinux-pms-support/libsepol/include/sepol/iface_record.h
===================================================================
--- selinux-pms-support.orig/libsepol/include/sepol/iface_record.h
+++ selinux-pms-support/libsepol/include/sepol/iface_record.h
@@ -1,6 +1,7 @@
#ifndef _SEPOL_IFACE_RECORD_H_
#define _SEPOL_IFACE_RECORD_H_
+#include <inttypes.h>
#include <sepol/handle.h>
#include <sepol/context_record.h>
@@ -56,4 +57,13 @@ extern int sepol_iface_clone(sepol_handl
extern void sepol_iface_free(sepol_iface_t * iface);
+/* Serialize/Unserialize */
+extern int sepol_iface_serialize(sepol_handle_t * handle,
+ const sepol_iface_t * iface,
+ char **data, uint64_t * size);
+
+extern int sepol_iface_unserialize(sepol_handle_t * handle,
+ char **data, uint64_t * size,
+ sepol_iface_t ** iface);
+
#endif
Index: selinux-pms-support/libsepol/src/iface_internal.h
===================================================================
--- selinux-pms-support.orig/libsepol/src/iface_internal.h
+++ selinux-pms-support/libsepol/src/iface_internal.h
@@ -15,4 +15,6 @@ hidden_proto(sepol_iface_create)
hidden_proto(sepol_iface_set_ifcon)
hidden_proto(sepol_iface_set_msgcon)
hidden_proto(sepol_iface_set_name)
+ hidden_proto(sepol_iface_serialize)
+ hidden_proto(sepol_iface_unserialize)
#endif
Index: selinux-pms-support/libsepol/src/iface_record.c
===================================================================
--- selinux-pms-support.orig/libsepol/src/iface_record.c
+++ selinux-pms-support/libsepol/src/iface_record.c
@@ -1,9 +1,11 @@
+#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "iface_internal.h"
#include "context_internal.h"
#include "debug.h"
+#include "serialize.h"
struct sepol_iface {
@@ -231,3 +233,116 @@ void sepol_iface_free(sepol_iface_t * if
}
hidden_def(sepol_iface_free)
+
+/* Serialize/Unserialize */
+/** Destructively modifies data and size.
+ * Caller must pre-allocate space for data.
+ * Use sepol_iface_calculate_serialized_size(). */
+int sepol_iface_serialize(sepol_handle_t * handle,
+ const sepol_iface_t * iface,
+ char **data, uint64_t * size)
+{
+ int status = STATUS_SUCCESS;
+ const char *name = NULL;
+
+ /* Sundry sanity checks. */
+ if (handle == NULL || iface == NULL) {
+ status = STATUS_ERR;
+ goto cleanup;
+ }
+
+ /* Iface name. */
+ name = sepol_iface_get_name(iface);
+ status =
+ sepol_serialize(handle, name, (name == NULL) ? 0 : strlen(name),
+ SEPOL_SERIAL_STRING, data, size);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Interface context. */
+ status =
+ sepol_context_serialize(handle, sepol_iface_get_ifcon(iface), data,
+ size);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Message context. */
+ status =
+ sepol_context_serialize(handle, sepol_iface_get_msgcon(iface), data,
+ size);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Cleanup. */
+ cleanup:
+ return status;
+}
+
+hidden_def(sepol_iface_serialize)
+
+/** Destructively modifies iface, data and size.
+ * Allocates space for iface.
+ * Caller must free. */
+int sepol_iface_unserialize(sepol_handle_t * handle,
+ char **data, uint64_t * size,
+ sepol_iface_t ** iface)
+{
+ int status = STATUS_SUCCESS;
+ char *name = NULL;
+ size_t *name_size = NULL;
+ sepol_context_t *ifcon = NULL;
+ sepol_context_t *msgcon = NULL;
+
+ /* Sundry sanity checks. */
+ if (handle == NULL || data == NULL || *data == NULL || size == NULL) {
+ status = STATUS_ERR;
+ goto cleanup;
+ }
+
+ /* Allocate space. */
+ status = sepol_iface_create(handle, iface);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Iface name. */
+ status =
+ sepol_unserialize(handle,
+ data, size,
+ (void **)&name, &name_size, SEPOL_SERIAL_STRING);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+ if (name != NULL) {
+ /* Note that sepol_*_set* calls typically create space. */
+ status = sepol_iface_set_name(handle, *iface, name);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+ }
+
+ /* Interface context. */
+ status = sepol_context_unserialize(handle, data, size, &ifcon);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+ /* Note that sepol_*_set* calls typically create space. */
+ status = sepol_iface_set_ifcon(handle, *iface, ifcon);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Message context. */
+ status = sepol_context_unserialize(handle, data, size, &msgcon);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+ /* Note that sepol_*_set* calls typically create space. */
+ status = sepol_iface_set_msgcon(handle, *iface, msgcon);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Cleanup. */
+ cleanup:
+ free(name);
+ free(name_size);
+ sepol_context_free(ifcon);
+ sepol_context_free(msgcon);
+ return status;
+}
+
+hidden_def(sepol_iface_unserialize)
--
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH 05/33] libsepol: node serialization
2007-04-23 21:34 [PATCH 00/33] libsemanage/libsepol object serialization and ps-api jbrindle
` (3 preceding siblings ...)
2007-04-23 21:34 ` [PATCH 04/33] libsepol: interface serialization jbrindle
@ 2007-04-23 21:35 ` jbrindle
2007-04-23 21:35 ` [PATCH 06/33] libsepol: port serialization jbrindle
` (29 subsequent siblings)
34 siblings, 0 replies; 58+ messages in thread
From: jbrindle @ 2007-04-23 21:35 UTC (permalink / raw)
To: selinux
This adds serialize/unserialize methods for node records.
---
libsepol/include/sepol/node_record.h | 10 ++
libsepol/src/node_internal.h | 2
libsepol/src/node_record.c | 155 +++++++++++++++++++++++++++++++++++
3 files changed, 167 insertions(+)
Index: selinux-pms-support/libsepol/include/sepol/node_record.h
===================================================================
--- selinux-pms-support.orig/libsepol/include/sepol/node_record.h
+++ selinux-pms-support/libsepol/include/sepol/node_record.h
@@ -1,6 +1,7 @@
#ifndef _SEPOL_NODE_RECORD_H_
#define _SEPOL_NODE_RECORD_H_
+#include <inttypes.h>
#include <stddef.h>
#include <sepol/context_record.h>
#include <sepol/handle.h>
@@ -89,4 +90,13 @@ extern int sepol_node_clone(sepol_handle
extern void sepol_node_free(sepol_node_t * node);
+/* Serialize/Unserialize */
+extern int sepol_node_serialize(sepol_handle_t * handle,
+ const sepol_node_t * node,
+ char **data, uint64_t * size);
+
+extern int sepol_node_unserialize(sepol_handle_t * handle,
+ char **data, uint64_t * size,
+ sepol_node_t ** node);
+
#endif
Index: selinux-pms-support/libsepol/src/node_internal.h
===================================================================
--- selinux-pms-support.orig/libsepol/src/node_internal.h
+++ selinux-pms-support/libsepol/src/node_internal.h
@@ -23,4 +23,6 @@ hidden_proto(sepol_node_create)
hidden_proto(sepol_node_set_mask)
hidden_proto(sepol_node_set_mask_bytes)
hidden_proto(sepol_node_set_proto)
+ hidden_proto(sepol_node_serialize)
+ hidden_proto(sepol_node_unserialize)
#endif
Index: selinux-pms-support/libsepol/src/node_record.c
===================================================================
--- selinux-pms-support.orig/libsepol/src/node_record.c
+++ selinux-pms-support/libsepol/src/node_record.c
@@ -1,3 +1,4 @@
+#include <assert.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
@@ -8,6 +9,7 @@
#include "node_internal.h"
#include "context_internal.h"
#include "debug.h"
+#include "serialize.h"
struct sepol_node {
@@ -666,3 +668,156 @@ int sepol_node_set_con(sepol_handle_t *
}
hidden_def(sepol_node_set_con)
+
+/* Serialize/Unserialize */
+/** Destructively modifies data and size.
+ * Caller must pre-allocate space for data.
+ * Use sepol_node_calculate_serialized_size(). */
+int sepol_node_serialize(sepol_handle_t * handle,
+ const sepol_node_t * node,
+ char **data, uint64_t * size)
+{
+ int status = STATUS_SUCCESS;
+ char *addr = NULL;
+ char *mask = NULL;
+ int proto;
+
+ /* Sundry sanity checks. */
+ if (handle == NULL || node == NULL) {
+ status = STATUS_ERR;
+ goto cleanup;
+ }
+
+ /* Node address. */
+ /* Note that these getters allocate space. */
+ status = sepol_node_get_addr(handle, node, &addr);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+ status =
+ sepol_serialize(handle, addr, (addr == NULL) ? 0 : strlen(addr),
+ SEPOL_SERIAL_STRING, data, size);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Node mask. */
+ /* Note that these getters allocate space. */
+ status = sepol_node_get_mask(handle, node, &mask);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+ status =
+ sepol_serialize(handle, mask, (mask == NULL) ? 0 : strlen(mask),
+ SEPOL_SERIAL_STRING, data, size);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Node protocol. */
+ proto = sepol_node_get_proto(node);
+ status = sepol_serialize(handle, &proto, 0, SEPOL_SERIAL_INT32_T, data, size);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Node context. */
+ status =
+ sepol_context_serialize(handle, sepol_node_get_con(node), data,
+ size);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Cleanup. */
+ cleanup:
+ free(addr);
+ free(mask);
+ return status;
+}
+
+hidden_def(sepol_node_serialize)
+
+/** Destructively modifies node, data and size.
+ * Allocates space for node.
+ * Caller must free. */
+int sepol_node_unserialize(sepol_handle_t * handle,
+ char **data, uint64_t * size,
+ sepol_node_t ** node)
+{
+ int status = STATUS_SUCCESS;
+ char *addr = NULL;
+ size_t *addr_size = NULL;
+ char *mask = NULL;
+ size_t *mask_size = NULL;
+ int *proto = NULL;
+ sepol_context_t *con = NULL;
+
+ /* Sundry sanity checks. */
+ if (handle == NULL || data == NULL || *data == NULL || size == NULL) {
+ status = STATUS_ERR;
+ goto cleanup;
+ }
+
+ /* Allocate space. */
+ status = sepol_node_create(handle, node);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Node address. */
+ status =
+ sepol_unserialize(handle,
+ data, size,
+ (void **)&addr, &addr_size, SEPOL_SERIAL_STRING);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+ /* Waiting for protocol before setting. */
+
+ /* Node mask size. */
+ status =
+ sepol_unserialize(handle,
+ data, size,
+ (void **)&mask, &mask_size, SEPOL_SERIAL_STRING);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+ /* Waiting for protocol before setting. */
+
+ /* Node protocol. */
+ status =
+ sepol_unserialize(handle,
+ data, size,
+ (void **)&proto, NULL, SEPOL_SERIAL_INT32_T);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+ sepol_node_set_proto(*node, *proto);
+
+ /* Setting address and mask now that we know the protocol. */
+ if (addr != NULL) {
+ /* Note that sepol_*_set* calls typically create space. */
+ status = sepol_node_set_addr(handle, *node, *proto, addr);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+ }
+
+ if (mask != NULL) {
+ /* Note that sepol_*_set* calls typically create space. */
+ status = sepol_node_set_mask(handle, *node, *proto, mask);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+ }
+
+ /* Node context. */
+ status = sepol_context_unserialize(handle, data, size, &con);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+ /* Note that sepol_*_set* calls typically create space. */
+ status = sepol_node_set_con(handle, *node, con);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Cleanup. */
+ cleanup:
+ free(addr);
+ free(addr_size);
+ free(mask);
+ free(mask_size);
+ free(proto);
+ sepol_context_free(con);
+ return status;
+}
+
+hidden_def(sepol_node_unserialize)
--
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH 06/33] libsepol: port serialization
2007-04-23 21:34 [PATCH 00/33] libsemanage/libsepol object serialization and ps-api jbrindle
` (4 preceding siblings ...)
2007-04-23 21:35 ` [PATCH 05/33] libsepol: node serialization jbrindle
@ 2007-04-23 21:35 ` jbrindle
2007-04-23 21:35 ` [PATCH 07/33] libsepol: user serialization jbrindle
` (28 subsequent siblings)
34 siblings, 0 replies; 58+ messages in thread
From: jbrindle @ 2007-04-23 21:35 UTC (permalink / raw)
To: selinux
This adds serialize/unserialize methods for port records.
---
libsepol/include/sepol/port_record.h | 10 ++
libsepol/src/port_internal.h | 2
libsepol/src/port_record.c | 125 +++++++++++++++++++++++++++++++++++
3 files changed, 137 insertions(+)
Index: selinux-pms-support/libsepol/include/sepol/port_record.h
===================================================================
--- selinux-pms-support.orig/libsepol/include/sepol/port_record.h
+++ selinux-pms-support/libsepol/include/sepol/port_record.h
@@ -1,6 +1,7 @@
#ifndef _SEPOL_PORT_RECORD_H_
#define _SEPOL_PORT_RECORD_H_
+#include <inttypes.h>
#include <sepol/context_record.h>
#include <sepol/handle.h>
@@ -63,4 +64,13 @@ extern int sepol_port_clone(sepol_handle
extern void sepol_port_free(sepol_port_t * port);
+/* Serialize/Unserialize */
+extern int sepol_port_serialize(sepol_handle_t * handle,
+ const sepol_port_t * port,
+ char **data, uint64_t * size);
+
+extern int sepol_port_unserialize(sepol_handle_t * handle,
+ char **data, uint64_t * size,
+ sepol_port_t ** port);
+
#endif
Index: selinux-pms-support/libsepol/src/port_internal.h
===================================================================
--- selinux-pms-support.orig/libsepol/src/port_internal.h
+++ selinux-pms-support/libsepol/src/port_internal.h
@@ -17,4 +17,6 @@ hidden_proto(sepol_port_create)
hidden_proto(sepol_port_set_con)
hidden_proto(sepol_port_set_proto)
hidden_proto(sepol_port_set_range)
+ hidden_proto(sepol_port_serialize)
+ hidden_proto(sepol_port_unserialize)
#endif
Index: selinux-pms-support/libsepol/src/port_record.c
===================================================================
--- selinux-pms-support.orig/libsepol/src/port_record.c
+++ selinux-pms-support/libsepol/src/port_record.c
@@ -1,9 +1,11 @@
+#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "port_internal.h"
#include "context_internal.h"
#include "debug.h"
+#include "serialize.h"
struct sepol_port {
/* Low - High range. Same for single ports. */
@@ -286,3 +288,126 @@ int sepol_port_set_con(sepol_handle_t *
}
hidden_def(sepol_port_set_con)
+
+/* Serialize/Unserialize */
+/** Destructively modifies data and size.
+ * Caller must pre-allocate space for data.
+ * Use sepol_port_calculate_serialized_size(). */
+int sepol_port_serialize(sepol_handle_t * handle,
+ const sepol_port_t * port,
+ char **data, uint64_t * size)
+{
+ int status = STATUS_SUCCESS;
+ int low;
+ int high;
+ int proto;
+
+ /* Sundry sanity checks. */
+ if (handle == NULL || port == NULL) {
+ status = STATUS_ERR;
+ goto cleanup;
+ }
+
+ /* Port low. */
+ low = sepol_port_get_low(port);
+ status = sepol_serialize(handle, &low, 0, SEPOL_SERIAL_INT32_T, data, size);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Port high. */
+ high = sepol_port_get_high(port);
+ status = sepol_serialize(handle, &high, 0, SEPOL_SERIAL_INT32_T, data, size);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Port protocol. */
+ proto = sepol_port_get_proto(port);
+ status = sepol_serialize(handle, &proto, 0, SEPOL_SERIAL_INT32_T, data, size);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Port context. */
+ status =
+ sepol_context_serialize(handle, sepol_port_get_con(port), data,
+ size);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Cleanup. */
+ cleanup:
+ return status;
+}
+
+hidden_def(sepol_port_serialize)
+
+/** Destructively modifies port, data and size.
+ * Allocates space for port.
+ * Caller must free. */
+int sepol_port_unserialize(sepol_handle_t * handle,
+ char **data, uint64_t * size,
+ sepol_port_t ** port)
+{
+ int status = STATUS_SUCCESS;
+ int *low = NULL;
+ int *high = NULL;
+ int *proto = NULL;
+ sepol_context_t *con = NULL;
+
+ /* Sundry sanity checks. */
+ if (handle == NULL || data == NULL || *data == NULL || size == NULL) {
+ status = STATUS_ERR;
+ goto cleanup;
+ }
+
+ /* Allocate space. */
+ status = sepol_port_create(handle, port);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Port low. */
+ status =
+ sepol_unserialize(handle,
+ data,
+ size,
+ (void **)&low, NULL, SEPOL_SERIAL_INT32_T);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+ /* Note that there is no set_low/set_high only set_range (used below) */
+
+ /* Port high. */
+ status =
+ sepol_unserialize(handle,
+ data, size,
+ (void **)&high, NULL, SEPOL_SERIAL_INT32_T);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+ sepol_port_set_range(*port, *low, *high);
+
+ /* Port protocol. */
+ status =
+ sepol_unserialize(handle,
+ data, size,
+ (void **)&proto, NULL, SEPOL_SERIAL_INT32_T);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+ sepol_port_set_proto(*port, *proto);
+
+ /* Port context. */
+ status = sepol_context_unserialize(handle, data, size, &con);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+ /* Note that sepol_*_set* calls typically create space. */
+ status = sepol_port_set_con(handle, *port, con);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Cleanup. */
+ cleanup:
+ free(low);
+ free(high);
+ free(proto);
+ sepol_context_free(con);
+ return status;
+}
+
+hidden_def(sepol_port_unserialize)
--
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH 07/33] libsepol: user serialization
2007-04-23 21:34 [PATCH 00/33] libsemanage/libsepol object serialization and ps-api jbrindle
` (5 preceding siblings ...)
2007-04-23 21:35 ` [PATCH 06/33] libsepol: port serialization jbrindle
@ 2007-04-23 21:35 ` jbrindle
2007-04-23 21:35 ` [PATCH 08/33] libsemanage: DESTDIR support in INCLUDE and safe test target jbrindle
` (27 subsequent siblings)
34 siblings, 0 replies; 58+ messages in thread
From: jbrindle @ 2007-04-23 21:35 UTC (permalink / raw)
To: selinux
This adds serialize/unserialize methods for user records.
---
libsepol/include/sepol/user_record.h | 10 +
libsepol/src/user_internal.h | 2
libsepol/src/user_record.c | 178 +++++++++++++++++++++++++++++++++++
3 files changed, 190 insertions(+)
Index: selinux-pms-support/libsepol/include/sepol/user_record.h
===================================================================
--- selinux-pms-support.orig/libsepol/include/sepol/user_record.h
+++ selinux-pms-support/libsepol/include/sepol/user_record.h
@@ -1,6 +1,7 @@
#ifndef _SEPOL_USER_RECORD_H_
#define _SEPOL_USER_RECORD_H_
+#include <inttypes.h>
#include <stddef.h>
#include <sepol/handle.h>
@@ -73,4 +74,13 @@ extern int sepol_user_clone(sepol_handle
extern void sepol_user_free(sepol_user_t * user);
+/* Serialize/Unserialize */
+extern int sepol_user_serialize(sepol_handle_t * handle,
+ const sepol_user_t * user,
+ char **data, uint64_t * size);
+
+extern int sepol_user_unserialize(sepol_handle_t * handle,
+ char **data, uint64_t * size,
+ sepol_user_t ** user);
+
#endif
Index: selinux-pms-support/libsepol/src/user_internal.h
===================================================================
--- selinux-pms-support.orig/libsepol/src/user_internal.h
+++ selinux-pms-support/libsepol/src/user_internal.h
@@ -17,4 +17,6 @@ hidden_proto(sepol_user_add_role)
hidden_proto(sepol_user_set_mlslevel)
hidden_proto(sepol_user_set_mlsrange)
hidden_proto(sepol_user_set_name)
+ hidden_proto(sepol_user_serialize)
+ hidden_proto(sepol_user_unserialize)
#endif
Index: selinux-pms-support/libsepol/src/user_record.c
===================================================================
--- selinux-pms-support.orig/libsepol/src/user_record.c
+++ selinux-pms-support/libsepol/src/user_record.c
@@ -1,9 +1,11 @@
+#include <assert.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include "user_internal.h"
#include "debug.h"
+#include "serialize.h"
struct sepol_user {
/* This user's name */
@@ -377,3 +379,179 @@ void sepol_user_free(sepol_user_t * user
}
hidden_def(sepol_user_free)
+
+/* Serialize/Unserialize */
+/** Destructively modifies rec_data and size.
+ * Caller must pre-allocate space for rec_data.
+ * Use sepol_user_calculate_serialized_size(). */
+int sepol_user_serialize(sepol_handle_t * handle,
+ const sepol_user_t * user,
+ char **data, uint64_t * size)
+{
+ int status = STATUS_SUCCESS;
+ const char *name = NULL;
+ const char *mlslevel = NULL;
+ const char *mlsrange = NULL;
+ const char **roles_array = NULL;
+ unsigned int roles_array_size;
+
+ /* Sundry sanity checks. */
+ if (handle == NULL || user == NULL) {
+ status = STATUS_ERR;
+ goto cleanup;
+ }
+
+ /* User name. */
+ name = sepol_user_get_name(user);
+ status =
+ sepol_serialize(handle, name, (name == NULL) ? 0 : strlen(name),
+ SEPOL_SERIAL_STRING, data, size);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* User mls level. */
+ mlslevel = sepol_user_get_mlslevel(user);
+ status =
+ sepol_serialize(handle, mlslevel,
+ (mlslevel == NULL) ? 0 : strlen(mlslevel),
+ SEPOL_SERIAL_STRING, data, size);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* User mls range. */
+ mlsrange = sepol_user_get_mlsrange(user);
+ status =
+ sepol_serialize(handle, mlsrange,
+ (mlsrange == NULL) ? 0 : strlen(mlsrange),
+ SEPOL_SERIAL_STRING, data, size);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* User roles. */
+ status =
+ sepol_user_get_roles(handle, user, &roles_array, &roles_array_size);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ status =
+ sepol_serialize(handle, (void *)roles_array, roles_array_size,
+ SEPOL_SERIAL_STRING_ARRAY, data, size);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Cleanup. */
+ cleanup:
+ free(roles_array);
+ return status;
+}
+
+hidden_def(sepol_user_serialize)
+
+/** Destructively modifies user, rec_data and size.
+ * Allocates space for user.
+ * Caller must free. */
+int sepol_user_unserialize(sepol_handle_t * handle,
+ char **data, uint64_t * size,
+ sepol_user_t ** user)
+{
+ int status = STATUS_SUCCESS;
+ char *name = NULL;
+ size_t *name_size = NULL;
+ char *mlslevel = NULL;
+ size_t *mlslevel_size = NULL;
+ char *mlsrange = NULL;
+ size_t *mlsrange_size = NULL;
+ char **roles_array = NULL;
+ size_t *roles_array_size = NULL;
+
+ /* Sundry sanity checks. */
+ if (handle == NULL || data == NULL || *data == NULL || size == NULL) {
+ status = STATUS_ERR;
+ goto cleanup;
+ }
+
+ /* Allocate space. */
+ status = sepol_user_create(handle, user);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* User name. */
+ status =
+ sepol_unserialize(handle,
+ data, size,
+ (void **)&name, &name_size, SEPOL_SERIAL_STRING);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+ if (name != NULL) {
+ status = sepol_user_set_name(handle, *user, name);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+ }
+
+ /* User mls level. */
+ status =
+ sepol_unserialize(handle,
+ data, size,
+ (void **)&mlslevel, &mlslevel_size,
+ SEPOL_SERIAL_STRING);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+ if (mlslevel != NULL) {
+ status = sepol_user_set_mlslevel(handle, *user, mlslevel);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+ }
+
+ /* User mls range. */
+ status =
+ sepol_unserialize(handle,
+ data, size,
+ (void **)&mlsrange, &mlsrange_size, SEPOL_SERIAL_STRING);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+ if (mlsrange != NULL) {
+ status = sepol_user_set_mlsrange(handle, *user, mlsrange);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+ }
+
+ /* User roles. */
+ status =
+ sepol_unserialize(handle,
+ data, size,
+ (void **)&roles_array, &roles_array_size, SEPOL_SERIAL_STRING_ARRAY);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+ if (roles_array != NULL) {
+ status =
+ sepol_user_set_roles(handle, *user,
+ (const char **)roles_array,
+ *roles_array_size);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+ }
+
+ /* Cleanup. */
+cleanup:
+
+ if (roles_array != NULL) {
+ unsigned int i;
+ for (i = 0; i < *roles_array_size; i++) {
+ if (!roles_array[i])
+ break;
+ free(roles_array[i]);
+ }
+ }
+
+ free(name);
+ free(name_size);
+ free(mlslevel);
+ free(mlslevel_size);
+ free(mlsrange);
+ free(mlsrange_size);
+ free(roles_array);
+ free(roles_array_size);
+ return status;
+}
+
+hidden_def(sepol_user_unserialize)
--
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH 08/33] libsemanage: DESTDIR support in INCLUDE and safe test target
2007-04-23 21:34 [PATCH 00/33] libsemanage/libsepol object serialization and ps-api jbrindle
` (6 preceding siblings ...)
2007-04-23 21:35 ` [PATCH 07/33] libsepol: user serialization jbrindle
@ 2007-04-23 21:35 ` jbrindle
2007-04-23 21:35 ` [PATCH 09/33] libsemanage: dbase/dconfig cleanup jbrindle
` (26 subsequent siblings)
34 siblings, 0 replies; 58+ messages in thread
From: jbrindle @ 2007-04-23 21:35 UTC (permalink / raw)
To: selinux
Added DESTDIR support for the INCLUDE variable. Tests will now properly use the DESTDIR headers instead of the system headers.
Tests are always cleaned before they are remade.
---
libsemanage/tests/Makefile | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
Index: selinux-pms-support/libsemanage/tests/Makefile
===================================================================
--- selinux-pms-support.orig/libsemanage/tests/Makefile
+++ selinux-pms-support/libsemanage/tests/Makefile
@@ -12,7 +12,7 @@ LIBS = ../src/libsemanage.a ../../libsel
EXECUTABLE = libsemanage-tests
CC = gcc
CFLAGS = -c -g -o0 -Wall -W -Wundef -Wmissing-noreturn -Wmissing-format-attribute -Wno-unused-parameter
-INCLUDE = -I$(TESTSRC) -I$(TESTSRC)/../include/semanage
+INCLUDE = -I$(TESTSRC) -I$(TESTSRC)/../include/semanage -I$(DESTDIR)/usr/include
LDFLAGS = -lcunit
OBJECTS = $(SOURCES:.c=.o)
@@ -27,6 +27,6 @@ $(EXECUTABLE): $(OBJECTS)
clean distclean:
rm -rf $(OBJECTS) $(EXECUTABLE)
-test: all
+test: clean all
./$(EXECUTABLE)
--
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH 09/33] libsemanage: dbase/dconfig cleanup
2007-04-23 21:34 [PATCH 00/33] libsemanage/libsepol object serialization and ps-api jbrindle
` (7 preceding siblings ...)
2007-04-23 21:35 ` [PATCH 08/33] libsemanage: DESTDIR support in INCLUDE and safe test target jbrindle
@ 2007-04-23 21:35 ` jbrindle
2007-04-23 21:35 ` [PATCH 10/33] libsemanage: database serialization jbrindle
` (25 subsequent siblings)
34 siblings, 0 replies; 58+ messages in thread
From: jbrindle @ 2007-04-23 21:35 UTC (permalink / raw)
To: selinux
This passes the entire dconfig for all calls which is necessary to serialize the databases.
---
libsemanage/src/booleans_policydb.c | 2
libsemanage/src/database.c | 42 +++++++--
libsemanage/src/database.h | 58 +++++++++----
libsemanage/src/database_activedb.c | 17 ++-
libsemanage/src/database_file.c | 12 +-
libsemanage/src/database_join.c | 24 +++--
libsemanage/src/database_llist.c | 70 ++++++++++++----
libsemanage/src/database_llist.h | 55 ++++++++----
libsemanage/src/database_policydb.c | 145 +++++++++++++++++++++-------------
libsemanage/src/database_policydb.h | 61 +++++++++++++-
libsemanage/src/direct_api.c | 35 +++-----
libsemanage/src/interfaces_policydb.c | 2
libsemanage/src/nodes_policydb.c | 2
libsemanage/src/policy_components.c | 32 +++----
libsemanage/src/ports_policydb.c | 2
libsemanage/src/users_base_policydb.c | 2
16 files changed, 381 insertions(+), 180 deletions(-)
Index: selinux-pms-support/libsemanage/src/booleans_policydb.c
===================================================================
--- selinux-pms-support.orig/libsemanage/src/booleans_policydb.c
+++ selinux-pms-support/libsemanage/src/booleans_policydb.c
@@ -67,5 +67,5 @@ int bool_policydb_dbase_init(semanage_ha
void bool_policydb_dbase_release(dbase_config_t * dconfig)
{
- dbase_policydb_release(dconfig->dbase);
+ dbase_policydb_release(dconfig);
}
Index: selinux-pms-support/libsemanage/src/database.c
===================================================================
--- selinux-pms-support.orig/libsemanage/src/database.c
+++ selinux-pms-support/libsemanage/src/database.c
@@ -1,4 +1,24 @@
-/* Copyright (C) 2005 Red Hat, Inc. */
+/* Authors: Ivan Gyurdiev <ivg2@cornell.edu>
+ * Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2005 Red Hat, Inc.
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
#include <semanage/handle.h>
#include "semanage_store.h"
@@ -36,7 +56,7 @@ static int enter_ro(semanage_handle_t *
}
}
- if (dconfig->dtable->cache(handle, dconfig->dbase) < 0)
+ if (dconfig->dtable->cache(handle, dconfig) < 0)
goto err;
return STATUS_SUCCESS;
@@ -69,7 +89,7 @@ static int enter_rw(semanage_handle_t *
goto err;
}
- if (dconfig->dtable->cache(handle, dconfig->dbase) < 0)
+ if (dconfig->dtable->cache(handle, dconfig) < 0)
goto err;
return STATUS_SUCCESS;
@@ -87,7 +107,7 @@ int dbase_modify(semanage_handle_t * han
if (enter_rw(handle, dconfig) < 0)
return STATUS_ERR;
- if (dconfig->dtable->modify(handle, dconfig->dbase, key, data) < 0)
+ if (dconfig->dtable->modify(handle, dconfig, key, data) < 0)
return STATUS_ERR;
return STATUS_SUCCESS;
@@ -101,7 +121,7 @@ int dbase_set(semanage_handle_t * handle
if (enter_rw(handle, dconfig) < 0)
return STATUS_ERR;
- if (dconfig->dtable->set(handle, dconfig->dbase, key, data) < 0)
+ if (dconfig->dtable->set(handle, dconfig, key, data) < 0)
return STATUS_ERR;
return STATUS_SUCCESS;
@@ -114,7 +134,7 @@ int dbase_del(semanage_handle_t * handle
if (enter_rw(handle, dconfig) < 0)
return STATUS_ERR;
- if (dconfig->dtable->del(handle, dconfig->dbase, key) < 0)
+ if (dconfig->dtable->del(handle, dconfig, key) < 0)
return STATUS_ERR;
return STATUS_SUCCESS;
@@ -128,7 +148,7 @@ int dbase_query(semanage_handle_t * hand
if (enter_ro(handle, dconfig) < 0)
return STATUS_ERR;
- if (dconfig->dtable->query(handle, dconfig->dbase, key, response) < 0) {
+ if (dconfig->dtable->query(handle, dconfig, key, response) < 0) {
exit_ro(handle, dconfig);
return STATUS_ERR;
}
@@ -144,7 +164,7 @@ int dbase_exists(semanage_handle_t * han
if (enter_ro(handle, dconfig) < 0)
return STATUS_ERR;
- if (dconfig->dtable->exists(handle, dconfig->dbase, key, response) < 0) {
+ if (dconfig->dtable->exists(handle, dconfig, key, response) < 0) {
exit_ro(handle, dconfig);
return STATUS_ERR;
}
@@ -159,7 +179,7 @@ int dbase_count(semanage_handle_t * hand
if (enter_ro(handle, dconfig) < 0)
return STATUS_ERR;
- if (dconfig->dtable->count(handle, dconfig->dbase, response) < 0) {
+ if (dconfig->dtable->count(handle, dconfig, response) < 0) {
exit_ro(handle, dconfig);
return STATUS_ERR;
}
@@ -176,7 +196,7 @@ int dbase_iterate(semanage_handle_t * ha
if (enter_ro(handle, dconfig) < 0)
return STATUS_ERR;
- if (dconfig->dtable->iterate(handle, dconfig->dbase, fn, fn_arg) < 0) {
+ if (dconfig->dtable->iterate(handle, dconfig, fn, fn_arg) < 0) {
exit_ro(handle, dconfig);
return STATUS_ERR;
}
@@ -192,7 +212,7 @@ int dbase_list(semanage_handle_t * handl
if (enter_ro(handle, dconfig) < 0)
return STATUS_ERR;
- if (dconfig->dtable->list(handle, dconfig->dbase, records, count) < 0) {
+ if (dconfig->dtable->list(handle, dconfig, records, count) < 0) {
exit_ro(handle, dconfig);
return STATUS_ERR;
}
Index: selinux-pms-support/libsemanage/src/database.h
===================================================================
--- selinux-pms-support.orig/libsemanage/src/database.h
+++ selinux-pms-support/libsemanage/src/database.h
@@ -1,4 +1,24 @@
-/* Copyright (C) 2005 Red Hat, Inc. */
+/* Authors: Ivan Gyurdiev <ivg2@cornell.edu>
+ * Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2005 Red Hat, Inc.
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
#ifndef _SEMANAGE_DATABASE_H_
#define _SEMANAGE_DATABASE_H_
@@ -14,8 +34,9 @@ typedef void *dbase_t;
#define DBASE_DEFINED
#endif
-/* Circular dependency */
+/* Circular dependencies */
struct semanage_handle;
+struct dbase_config;
/* RECORD interface - method table */
typedef struct record_table {
@@ -66,7 +87,7 @@ typedef struct dbase_table {
/* Add the specified record to
* the database. No check for duplicates is performed */
int (*add) (struct semanage_handle * handle,
- dbase_t * dbase,
+ struct dbase_config * dconfig,
const record_key_t * key, const record_t * data);
/* Add the specified record to the
@@ -74,24 +95,25 @@ typedef struct dbase_table {
* If it's present, replace it
*/
int (*modify) (struct semanage_handle * handle,
- dbase_t * dbase,
+ struct dbase_config * dconfig,
const record_key_t * key, const record_t * data);
/* Modify the specified record in the database
* if it is present. Fail if it does not yet exist
*/
int (*set) (struct semanage_handle * handle,
- dbase_t * dbase,
+ struct dbase_config * dconfig,
const record_key_t * key, const record_t * data);
/* Delete a record */
int (*del) (struct semanage_handle * handle,
- dbase_t * dbase, const record_key_t * key);
+ struct dbase_config * dconfig, const record_key_t * key);
/* Clear all records, and leave the database in
* cached, modified state. This function does
* not require a call to cache() */
- int (*clear) (struct semanage_handle * handle, dbase_t * dbase);
+ int (*clear) (struct semanage_handle * handle,
+ struct dbase_config * dconfig);
/* Retrieve a record
*
@@ -100,17 +122,17 @@ typedef struct dbase_table {
* must be freed accordingly */
int (*query) (struct semanage_handle * handle,
- dbase_t * dbase,
+ struct dbase_config * dconfig,
const record_key_t * key, record_t ** response);
/* Check if a record exists */
int (*exists) (struct semanage_handle * handle,
- dbase_t * dbase,
+ struct dbase_config * dconfig,
const record_key_t * key, int *response);
/* Count the number of records */
int (*count) (struct semanage_handle * handle,
- dbase_t * dbase, unsigned int *response);
+ struct dbase_config * dconfig, unsigned int *response);
/* Execute the specified handler over
* the records of this database. The handler
@@ -129,7 +151,7 @@ typedef struct dbase_table {
* not modify the underlying database.
*/
int (*iterate) (struct semanage_handle * handle,
- dbase_t * dbase,
+ struct dbase_config * dconfig,
int (*fn) (const record_t * record,
void *varg), void *fn_arg);
@@ -139,7 +161,7 @@ typedef struct dbase_table {
* and must be freed accordingly.
*/
int (*list) (struct semanage_handle * handle,
- dbase_t * dbase,
+ struct dbase_config * dconfig,
record_t *** records, unsigned int *count);
/* ---------- Cache/Transaction Management ---------- */
@@ -149,24 +171,28 @@ typedef struct dbase_table {
* any of the database functions above. It may be invoked
* multiple times, and will update the cache if a commit
* occured between invocations */
- int (*cache) (struct semanage_handle * handle, dbase_t * dbase);
+ int (*cache) (struct semanage_handle * handle,
+ struct dbase_config * dconfig);
/* Forgets all changes that haven't been written
* to the database backend */
+ /* FIXME: Why not a dconfig here? */
+ //void (*drop_cache) (struct dbase_config * dconfig);
void (*drop_cache) (dbase_t * dbase);
/* Checks if there are any changes not written to the backend */
- int (*is_modified) (dbase_t * dbase);
+ int (*is_modified) (struct dbase_config * dconfig);
/* Writes the database changes to its backend */
- int (*flush) (struct semanage_handle * handle, dbase_t * dbase);
+ int (*flush) (struct semanage_handle * handle,
+ struct dbase_config * dconfig);
/* ------------- Polymorphism ----------------------- */
/* Retrieves the record table for this database,
* which specifies how to perform basic operations
* on each record. */
- record_table_t *(*get_rtable) (dbase_t * dbase);
+ record_table_t *(*get_rtable) (struct dbase_config * dconfig);
} dbase_table_t;
Index: selinux-pms-support/libsemanage/src/database_activedb.c
===================================================================
--- selinux-pms-support.orig/libsemanage/src/database_activedb.c
+++ selinux-pms-support/libsemanage/src/database_activedb.c
@@ -30,10 +30,11 @@ struct dbase_activedb {
};
static int dbase_activedb_cache(semanage_handle_t * handle,
- dbase_activedb_t * dbase)
+ dbase_config_t * dconfig)
{
- record_table_t *rtable = dbase_llist_get_rtable(&dbase->llist);
+ dbase_activedb_t *dbase = dconfig->dbase;
+ record_table_t *rtable = dbase_llist_get_rtable(dconfig);
record_activedb_table_t *ratable = dbase->ratable;
record_t **records = NULL;
@@ -74,10 +75,11 @@ static int dbase_activedb_cache(semanage
}
static int dbase_activedb_flush(semanage_handle_t * handle,
- dbase_activedb_t * dbase)
+ dbase_config_t * dconfig)
{
-
- record_table_t *rtable = dbase_llist_get_rtable(&dbase->llist);
+ int status = STATUS_SUCCESS;
+ dbase_activedb_t *dbase = dconfig->dbase;
+ record_table_t *rtable = dbase_llist_get_rtable(dconfig);
record_activedb_table_t *ratable = dbase->ratable;
record_t **records = NULL;
@@ -89,7 +91,8 @@ static int dbase_activedb_flush(semanage
return STATUS_SUCCESS;
/* Fetch list */
- if (dbase_llist_list(handle, &dbase->llist, &records, &rcount) < 0)
+ status = dbase_llist_list(handle, dconfig, &records, &rcount);
+ if (status != STATUS_SUCCESS)
goto err;
/* Commit */
@@ -123,7 +126,7 @@ int dbase_activedb_init(semanage_handle_
goto omem;
tmp_dbase->ratable = ratable;
- dbase_llist_init(&tmp_dbase->llist, rtable, &SEMANAGE_ACTIVEDB_DTABLE);
+ dbase_llist_init(&tmp_dbase->llist, rtable);
*dbase = tmp_dbase;
Index: selinux-pms-support/libsemanage/src/database_file.c
===================================================================
--- selinux-pms-support.orig/libsemanage/src/database_file.c
+++ selinux-pms-support/libsemanage/src/database_file.c
@@ -58,10 +58,12 @@ static int construct_filename(semanage_h
return STATUS_SUCCESS;
}
-static int dbase_file_cache(semanage_handle_t * handle, dbase_file_t * dbase)
+static int dbase_file_cache(semanage_handle_t * handle,
+ dbase_config_t * dconfig)
{
- record_table_t *rtable = dbase_llist_get_rtable(&dbase->llist);
+ dbase_file_t *dbase = dconfig->dbase;
+ record_table_t *rtable = dbase_llist_get_rtable(dconfig);
record_file_table_t *rftable = dbase->rftable;
record_t *process_record = NULL;
@@ -135,9 +137,11 @@ static int dbase_file_cache(semanage_han
}
/* Flush database to file */
-static int dbase_file_flush(semanage_handle_t * handle, dbase_file_t * dbase)
+static int dbase_file_flush(semanage_handle_t * handle,
+ dbase_config_t * dconfig)
{
+ dbase_file_t *dbase = dconfig->dbase;
record_file_table_t *rftable = dbase->rftable;
cache_entry_t *ptr;
@@ -197,7 +201,7 @@ int dbase_file_init(semanage_handle_t *
tmp_dbase->suffix = suffix;
tmp_dbase->rftable = rftable;
- dbase_llist_init(&tmp_dbase->llist, rtable, &SEMANAGE_FILE_DTABLE);
+ dbase_llist_init(&tmp_dbase->llist, rtable);
*dbase = tmp_dbase;
Index: selinux-pms-support/libsemanage/src/database_join.c
===================================================================
--- selinux-pms-support.orig/libsemanage/src/database_join.c
+++ selinux-pms-support/libsemanage/src/database_join.c
@@ -34,15 +34,18 @@ struct dbase_join {
record_join_table_t *rjtable;
};
-static int dbase_join_cache(semanage_handle_t * handle, dbase_join_t * dbase)
+static int dbase_join_cache(semanage_handle_t * handle,
+ dbase_config_t * dconfig)
{
+ dbase_join_t *dbase = dconfig->dbase;
+
/* Extract all the object tables information */
- dbase_t *dbase1 = dbase->join1->dbase;
- dbase_t *dbase2 = dbase->join2->dbase;
+ dbase_config_t *dbase1 = dbase->join1;
+ dbase_config_t *dbase2 = dbase->join2;
dbase_table_t *dtable1 = dbase->join1->dtable;
dbase_table_t *dtable2 = dbase->join2->dtable;
- record_table_t *rtable = dbase_llist_get_rtable(&dbase->llist);
+ record_table_t *rtable = dbase_llist_get_rtable(dconfig);
record_join_table_t *rjtable = dbase->rjtable;
record_table_t *rtable1 = dtable1->get_rtable(dbase1);
record_table_t *rtable2 = dtable2->get_rtable(dbase2);
@@ -166,15 +169,18 @@ static int dbase_join_cache(semanage_han
}
/* Flush database */
-static int dbase_join_flush(semanage_handle_t * handle, dbase_join_t * dbase)
+static int dbase_join_flush(semanage_handle_t * handle,
+ dbase_config_t * dconfig)
{
+ dbase_join_t *dbase = dconfig->dbase;
+
/* Extract all the object tables information */
- dbase_t *dbase1 = dbase->join1->dbase;
- dbase_t *dbase2 = dbase->join2->dbase;
+ dbase_config_t *dbase1 = dbase->join1;
+ dbase_config_t *dbase2 = dbase->join2;
dbase_table_t *dtable1 = dbase->join1->dtable;
dbase_table_t *dtable2 = dbase->join2->dtable;
- record_table_t *rtable = dbase_llist_get_rtable(&dbase->llist);
+ record_table_t *rtable = dbase_llist_get_rtable(dconfig);
record_join_table_t *rjtable = dbase->rjtable;
record_table_t *rtable1 = dtable1->get_rtable(dbase1);
record_table_t *rtable2 = dtable2->get_rtable(dbase2);
@@ -247,7 +253,7 @@ int dbase_join_init(semanage_handle_t *
if (!tmp_dbase)
goto omem;
- dbase_llist_init(&tmp_dbase->llist, rtable, &SEMANAGE_JOIN_DTABLE);
+ dbase_llist_init(&tmp_dbase->llist, rtable);
tmp_dbase->rjtable = rjtable;
tmp_dbase->join1 = join1;
Index: selinux-pms-support/libsemanage/src/database_llist.c
===================================================================
--- selinux-pms-support.orig/libsemanage/src/database_llist.c
+++ selinux-pms-support/libsemanage/src/database_llist.c
@@ -1,4 +1,24 @@
-/* Copyright (C) 2005 Red Hat, Inc. */
+/* Authors: Ivan Gyurdiev <ivg2@cornell.edu>
+ * Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ * Copyright (C) 2005 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
/* Object: dbase_llist_t (Linked List)
* Partially Implements: dbase_t (Database)
@@ -100,15 +120,17 @@ int dbase_llist_set_serial(semanage_hand
/* Helper for finding records in the cache */
static int dbase_llist_cache_locate(semanage_handle_t * handle,
- dbase_llist_t * dbase,
+ dbase_config_t * dconfig,
const record_key_t * key,
cache_entry_t ** entry)
{
-
+ int status = STATUS_SUCCESS;
+ dbase_llist_t *dbase = dconfig->dbase;
cache_entry_t *ptr;
/* Implemented in parent */
- if (dbase->dtable->cache(handle, dbase) < 0)
+ status = dconfig->dtable->cache(handle, dconfig);
+ if (status != STATUS_SUCCESS)
goto err;
for (ptr = dbase->cache; ptr != NULL; ptr = ptr->next) {
@@ -126,14 +148,14 @@ static int dbase_llist_cache_locate(sema
}
int dbase_llist_exists(semanage_handle_t * handle,
- dbase_llist_t * dbase,
+ dbase_config_t * dconfig,
const record_key_t * key, int *response)
{
cache_entry_t *entry;
int status;
- status = dbase_llist_cache_locate(handle, dbase, key, &entry);
+ status = dbase_llist_cache_locate(handle, dconfig, key, &entry);
if (status < 0)
goto err;
@@ -146,10 +168,12 @@ int dbase_llist_exists(semanage_handle_t
}
int dbase_llist_add(semanage_handle_t * handle,
- dbase_llist_t * dbase,
+ dbase_config_t * dconfig,
const record_key_t * key, const record_t * data)
{
+ dbase_llist_t *dbase = dconfig->dbase;
+
if (dbase_llist_cache_prepend(handle, dbase, data) < 0)
goto err;
@@ -163,14 +187,15 @@ int dbase_llist_add(semanage_handle_t *
}
int dbase_llist_set(semanage_handle_t * handle,
- dbase_llist_t * dbase,
+ dbase_config_t * dconfig,
const record_key_t * key, const record_t * data)
{
+ dbase_llist_t *dbase = dconfig->dbase;
cache_entry_t *entry;
int status;
- status = dbase_llist_cache_locate(handle, dbase, key, &entry);
+ status = dbase_llist_cache_locate(handle, dconfig, key, &entry);
if (status < 0)
goto err;
if (status == STATUS_NODATA) {
@@ -191,14 +216,15 @@ int dbase_llist_set(semanage_handle_t *
}
int dbase_llist_modify(semanage_handle_t * handle,
- dbase_llist_t * dbase,
+ dbase_config_t * dconfig,
const record_key_t * key, const record_t * data)
{
+ dbase_llist_t *dbase = dconfig->dbase;
cache_entry_t *entry;
int status;
- status = dbase_llist_cache_locate(handle, dbase, key, &entry);
+ status = dbase_llist_cache_locate(handle, dconfig, key, &entry);
if (status < 0)
goto err;
if (status == STATUS_NODATA) {
@@ -219,23 +245,26 @@ int dbase_llist_modify(semanage_handle_t
}
hidden int dbase_llist_count(semanage_handle_t * handle,
- dbase_llist_t * dbase, unsigned int *response)
+ dbase_config_t * dconfig, unsigned int *response)
{
+ dbase_llist_t *dbase = dconfig->dbase;
+
*response = dbase->cache_sz;
handle = NULL;
return STATUS_SUCCESS;
}
int dbase_llist_query(semanage_handle_t * handle,
- dbase_llist_t * dbase,
+ dbase_config_t * dconfig,
const record_key_t * key, record_t ** response)
{
+ dbase_llist_t *dbase = dconfig->dbase;
cache_entry_t *entry;
int status;
- status = dbase_llist_cache_locate(handle, dbase, key, &entry);
+ status = dbase_llist_cache_locate(handle, dconfig, key, &entry);
if (status < 0 || status == STATUS_NODATA)
goto err;
@@ -250,11 +279,12 @@ int dbase_llist_query(semanage_handle_t
}
int dbase_llist_iterate(semanage_handle_t * handle,
- dbase_llist_t * dbase,
+ dbase_config_t * dconfig,
int (*fn) (const record_t * record,
void *fn_arg), void *arg)
{
+ dbase_llist_t *dbase = dconfig->dbase;
int rc;
cache_entry_t *ptr;
@@ -276,9 +306,10 @@ int dbase_llist_iterate(semanage_handle_
}
int dbase_llist_del(semanage_handle_t * handle,
- dbase_llist_t * dbase, const record_key_t * key)
+ dbase_config_t * dconfig, const record_key_t * key)
{
+ dbase_llist_t *dbase = dconfig->dbase;
cache_entry_t *ptr, *prev = NULL;
for (ptr = dbase->cache; ptr != NULL; ptr = ptr->next) {
@@ -306,9 +337,11 @@ int dbase_llist_del(semanage_handle_t *
return STATUS_SUCCESS;
}
-int dbase_llist_clear(semanage_handle_t * handle, dbase_llist_t * dbase)
+int dbase_llist_clear(semanage_handle_t * handle, dbase_config_t * dconfig)
{
+ dbase_llist_t *dbase = dconfig->dbase;
+
int old_serial = dbase->cache_serial;
if (dbase_llist_set_serial(handle, dbase) < 0) {
@@ -334,10 +367,11 @@ int dbase_llist_clear(semanage_handle_t
}
int dbase_llist_list(semanage_handle_t * handle,
- dbase_llist_t * dbase,
+ dbase_config_t * dconfig,
record_t *** records, unsigned int *count)
{
+ dbase_llist_t *dbase = dconfig->dbase;
cache_entry_t *ptr;
record_t **tmp_records = NULL;
unsigned int tmp_count;
Index: selinux-pms-support/libsemanage/src/database_llist.h
===================================================================
--- selinux-pms-support.orig/libsemanage/src/database_llist.h
+++ selinux-pms-support/libsemanage/src/database_llist.h
@@ -1,4 +1,24 @@
-/* Copyright (C) 2005 Red Hat, Inc. */
+/* Authors: Ivan Gyurdiev <ivg2@cornell.edu>
+ * Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ * Copyright (C) 2005 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
#ifndef _SEMANAGE_DATABASE_LLIST_INTERNAL_H_
#define _SEMANAGE_DATABASE_LLIST_INTERNAL_H_
@@ -16,9 +36,8 @@ typedef struct cache_entry {
/* LLIST dbase */
typedef struct dbase_llist {
- /* Method tables */
+ /* Method table */
record_table_t *rtable;
- dbase_table_t *dtable;
/* In-memory representation (cache) */
cache_entry_t *cache;
@@ -42,12 +61,10 @@ static inline void dbase_llist_cache_ini
}
static inline void dbase_llist_init(dbase_llist_t * dbase,
- record_table_t * rtable,
- dbase_table_t * dtable)
+ record_table_t * rtable)
{
dbase->rtable = rtable;
- dbase->dtable = dtable;
dbase_llist_cache_init(dbase);
}
@@ -76,47 +93,49 @@ static inline int dbase_llist_is_modifie
}
/* LLIST - polymorphism */
-static inline record_table_t *dbase_llist_get_rtable(dbase_llist_t * dbase)
+static inline record_table_t *dbase_llist_get_rtable(dbase_config_t * dconfig)
{
- return dbase->rtable;
+
+ return ((dbase_llist_t *) dconfig->dbase)->rtable;
}
/* LLIST - dbase API */
extern int dbase_llist_exists(semanage_handle_t * handle,
- dbase_llist_t * dbase,
+ dbase_config_t * dconfig,
const record_key_t * key, int *response);
extern int dbase_llist_add(semanage_handle_t * handle,
- dbase_llist_t * dbase,
+ dbase_config_t * dconfig,
const record_key_t * key, const record_t * data);
extern int dbase_llist_set(semanage_handle_t * handle,
- dbase_llist_t * dbase,
+ dbase_config_t * dconfig,
const record_key_t * key, const record_t * data);
extern int dbase_llist_modify(semanage_handle_t * handle,
- dbase_llist_t * dbase,
+ dbase_config_t * dconfig,
const record_key_t * key, const record_t * data);
extern int dbase_llist_count(semanage_handle_t * handle,
- dbase_llist_t * dbase, unsigned int *response);
+ dbase_config_t * dconfig, unsigned int *response);
extern int dbase_llist_query(semanage_handle_t * handle,
- dbase_llist_t * dbase,
+ dbase_config_t * dconfig,
const record_key_t * key, record_t ** response);
extern int dbase_llist_iterate(semanage_handle_t * handle,
- dbase_llist_t * dbase,
+ dbase_config_t * dconfig,
int (*fn) (const record_t * record,
void *fn_arg), void *arg);
extern int dbase_llist_del(semanage_handle_t * handle,
- dbase_llist_t * dbase, const record_key_t * key);
+ dbase_config_t * dconfig, const record_key_t * key);
-extern int dbase_llist_clear(semanage_handle_t * handle, dbase_llist_t * dbase);
+extern int dbase_llist_clear(semanage_handle_t * handle,
+ dbase_config_t * dconfig);
extern int dbase_llist_list(semanage_handle_t * handle,
- dbase_llist_t * dbase,
+ dbase_config_t * dconfig,
record_t *** records, unsigned int *count);
#endif
Index: selinux-pms-support/libsemanage/src/database_policydb.c
===================================================================
--- selinux-pms-support.orig/libsemanage/src/database_policydb.c
+++ selinux-pms-support/libsemanage/src/database_policydb.c
@@ -1,4 +1,24 @@
-/* Copyright (C) 2005 Red Hat, Inc. */
+/* Authors: Ivan Gyurdiev <ivg2@cornell.edu>
+ * Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ * Copyright (C) 2005 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
/* Object: dbase_policydb_t (Policy)
* Implements: dbase_t (Database)
@@ -41,7 +61,7 @@ struct dbase_policydb {
int attached;
};
-static void dbase_policydb_drop_cache(dbase_policydb_t * dbase)
+void dbase_policydb_drop_cache(dbase_t * dbase)
{
if (dbase->cache_serial >= 0) {
@@ -51,8 +71,8 @@ static void dbase_policydb_drop_cache(db
}
}
-static int dbase_policydb_set_serial(semanage_handle_t * handle,
- dbase_policydb_t * dbase)
+int dbase_policydb_set_serial(semanage_handle_t * handle,
+ dbase_policydb_t * dbase)
{
int cache_serial = handle->funcs->get_serial(handle);
@@ -65,10 +85,12 @@ static int dbase_policydb_set_serial(sem
return STATUS_SUCCESS;
}
-static int dbase_policydb_needs_resync(semanage_handle_t * handle,
- dbase_policydb_t * dbase)
+int dbase_policydb_needs_resync(semanage_handle_t * handle,
+ dbase_config_t * dconfig)
{
+ dbase_policydb_t *dbase = dconfig->dbase;
+
int cache_serial;
if (dbase->cache_serial < 0)
@@ -79,7 +101,7 @@ static int dbase_policydb_needs_resync(s
return 1;
if (cache_serial != dbase->cache_serial) {
- dbase_policydb_drop_cache(dbase);
+ dbase_policydb_drop_cache(dconfig->dbase);
dbase->cache_serial = -1;
return 1;
}
@@ -106,10 +128,11 @@ static int construct_filename(semanage_h
return STATUS_SUCCESS;
}
-static int dbase_policydb_cache(semanage_handle_t * handle,
- dbase_policydb_t * dbase)
+int dbase_policydb_cache(semanage_handle_t * handle, dbase_config_t * dconfig)
{
+ dbase_policydb_t *dbase = dconfig->dbase;
+
FILE *fp = NULL;
sepol_policydb_t *policydb = NULL;
sepol_policy_file_t *pf = NULL;
@@ -119,7 +142,7 @@ static int dbase_policydb_cache(semanage
if (dbase->attached)
return STATUS_SUCCESS;
- if (!dbase_policydb_needs_resync(handle, dbase))
+ if (!dbase_policydb_needs_resync(handle, dconfig))
return STATUS_SUCCESS;
if (construct_filename(handle, dbase, &fname) < 0)
@@ -177,10 +200,11 @@ static int dbase_policydb_cache(semanage
return STATUS_ERR;
}
-static int dbase_policydb_flush(semanage_handle_t * handle,
- dbase_policydb_t * dbase)
+int dbase_policydb_flush(semanage_handle_t * handle, dbase_config_t * dconfig)
{
+ dbase_policydb_t *dbase = dconfig->dbase;
+
if (!dbase->modified)
return STATUS_SUCCESS;
@@ -192,10 +216,10 @@ static int dbase_policydb_flush(semanage
}
/* Check if modified */
-static int dbase_policydb_is_modified(dbase_policydb_t * dbase)
+int dbase_policydb_is_modified(dbase_config_t * dconfig)
{
- return dbase->modified;
+ return ((dbase_policydb_t *) dconfig->dbase)->modified;
}
int dbase_policydb_init(semanage_handle_t * handle,
@@ -230,21 +254,22 @@ int dbase_policydb_init(semanage_handle_
}
/* Release dbase resources */
-void dbase_policydb_release(dbase_policydb_t * dbase)
+void dbase_policydb_release(dbase_config_t * dconfig)
{
-
- dbase_policydb_drop_cache(dbase);
- free(dbase);
+ dbase_policydb_drop_cache(dconfig->dbase);
+ free(dconfig->dbase);
}
/* Attach to a shared policydb.
* This implies drop_cache(),
* and prevents flush() and drop_cache()
* until detached. */
-void dbase_policydb_attach(dbase_policydb_t * dbase,
+void dbase_policydb_attach(dbase_config_t * dconfig,
sepol_policydb_t * policydb)
{
+ dbase_policydb_t *dbase = dconfig->dbase;
+
dbase->attached = 1;
dbase_policydb_drop_cache(dbase);
dbase->policydb = policydb;
@@ -259,11 +284,13 @@ void dbase_policydb_detach(dbase_policyd
dbase->modified = 0;
}
-static int dbase_policydb_add(semanage_handle_t * handle,
- dbase_policydb_t * dbase,
- const record_key_t * key, const record_t * data)
+int dbase_policydb_add(semanage_handle_t * handle,
+ dbase_config_t * dconfig,
+ const record_key_t * key, const record_t * data)
{
+ dbase_policydb_t *dbase = dconfig->dbase;
+
if (dbase->rptable->add(handle->sepolh, dbase->policydb, key, data) < 0)
goto err;
@@ -275,11 +302,13 @@ static int dbase_policydb_add(semanage_h
return STATUS_ERR;
}
-static int dbase_policydb_set(semanage_handle_t * handle,
- dbase_policydb_t * dbase,
- const record_key_t * key, const record_t * data)
+int dbase_policydb_set(semanage_handle_t * handle,
+ dbase_config_t * dconfig,
+ const record_key_t * key, const record_t * data)
{
+ dbase_policydb_t *dbase = dconfig->dbase;
+
if (dbase->rptable->set(handle->sepolh, dbase->policydb, key, data) < 0)
goto err;
@@ -291,12 +320,13 @@ static int dbase_policydb_set(semanage_h
return STATUS_ERR;
}
-static int dbase_policydb_modify(semanage_handle_t * handle,
- dbase_policydb_t * dbase,
- const record_key_t * key,
- const record_t * data)
+int dbase_policydb_modify(semanage_handle_t * handle,
+ dbase_config_t * dconfig,
+ const record_key_t * key, const record_t * data)
{
+ dbase_policydb_t *dbase = dconfig->dbase;
+
if (dbase->rptable->modify(handle->sepolh,
dbase->policydb, key, data) < 0)
goto err;
@@ -309,33 +339,33 @@ static int dbase_policydb_modify(semanag
return STATUS_ERR;
}
-static int dbase_policydb_del(semanage_handle_t * handle,
- dbase_policydb_t * dbase,
- const record_key_t * key)
+int dbase_policydb_del(semanage_handle_t * handle,
+ dbase_config_t * dconfig, const record_key_t * key)
{
/* Stub */
key = NULL;
handle = NULL;
- dbase = NULL;
+ dconfig = NULL;
return STATUS_ERR;
}
-static int dbase_policydb_clear(semanage_handle_t * handle,
- dbase_policydb_t * dbase)
+int dbase_policydb_clear(semanage_handle_t * handle, dbase_config_t * dconfig)
{
/* Stub */
handle = NULL;
- dbase = NULL;
+ dconfig = NULL;
return STATUS_ERR;
}
-static int dbase_policydb_query(semanage_handle_t * handle,
- dbase_policydb_t * dbase,
- const record_key_t * key, record_t ** response)
+int dbase_policydb_query(semanage_handle_t * handle,
+ dbase_config_t * dconfig,
+ const record_key_t * key, record_t ** response)
{
+ dbase_policydb_t *dbase = dconfig->dbase;
+
if (dbase->rptable->query(handle->sepolh,
dbase->policydb, key, response) < 0)
goto err;
@@ -347,11 +377,13 @@ static int dbase_policydb_query(semanage
return STATUS_ERR;
}
-static int dbase_policydb_exists(semanage_handle_t * handle,
- dbase_policydb_t * dbase,
- const record_key_t * key, int *response)
+int dbase_policydb_exists(semanage_handle_t * handle,
+ dbase_config_t * dconfig,
+ const record_key_t * key, int *response)
{
+ dbase_policydb_t *dbase = dconfig->dbase;
+
if (dbase->rptable->exists(handle->sepolh,
dbase->policydb, key, response) < 0)
goto err;
@@ -363,11 +395,12 @@ static int dbase_policydb_exists(semanag
return STATUS_ERR;
}
-static int dbase_policydb_count(semanage_handle_t * handle,
- dbase_policydb_t * dbase,
- unsigned int *response)
+int dbase_policydb_count(semanage_handle_t * handle,
+ dbase_config_t * dconfig, unsigned int *response)
{
+ dbase_policydb_t *dbase = dconfig->dbase;
+
if (dbase->rptable->count(handle->sepolh,
dbase->policydb, response) < 0)
goto err;
@@ -379,12 +412,14 @@ static int dbase_policydb_count(semanage
return STATUS_ERR;
}
-static int dbase_policydb_iterate(semanage_handle_t * handle,
- dbase_policydb_t * dbase,
- int (*fn) (const record_t * record,
- void *fn_arg), void *arg)
+int dbase_policydb_iterate(semanage_handle_t * handle,
+ dbase_config_t * dconfig,
+ int (*fn) (const record_t * record,
+ void *fn_arg), void *arg)
{
+ dbase_policydb_t *dbase = dconfig->dbase;
+
if (dbase->rptable->iterate(handle->sepolh,
dbase->policydb, fn, arg) < 0)
goto err;
@@ -415,11 +450,13 @@ static int list_handler(const record_t *
return 0;
}
-static int dbase_policydb_list(semanage_handle_t * handle,
- dbase_t * dbase,
- record_t *** records, unsigned int *count)
+int dbase_policydb_list(semanage_handle_t * handle,
+ dbase_config_t * dconfig,
+ record_t *** records, unsigned int *count)
{
+ dbase_t *dbase = dconfig->dbase;
+
record_t **tmp_records = NULL;
unsigned int tmp_count;
struct list_handler_arg list_arg;
@@ -463,10 +500,10 @@ static int dbase_policydb_list(semanage_
return STATUS_ERR;
}
-static record_table_t *dbase_policydb_get_rtable(dbase_policydb_t * dbase)
+record_table_t *dbase_policydb_get_rtable(dbase_config_t * dconfig)
{
- return dbase->rtable;
+ return ((dbase_policydb_t *) dconfig->dbase)->rtable;
}
/* POLICYDB dbase - method table implementation */
Index: selinux-pms-support/libsemanage/src/database_policydb.h
===================================================================
--- selinux-pms-support.orig/libsemanage/src/database_policydb.h
+++ selinux-pms-support/libsemanage/src/database_policydb.h
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2005 Red Hat, Inc.
* Copyright (C) 2006 Tresys Technology, LLC
*
* This library is free software; you can redistribute it and/or
@@ -16,8 +17,6 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-/* Copyright (C) 2005 Red Hat, Inc. */
-
#ifndef _SEMANAGE_DATABASE_POLICYDB_INTERNAL_H_
#define _SEMANAGE_DATABASE_POLICYDB_INTERNAL_H_
@@ -95,7 +94,7 @@ extern int dbase_policydb_init(semanage_
* This implies drop_cache().
* and prevents flush() and drop_cache()
* until detached. */
-extern void dbase_policydb_attach(dbase_policydb_t * dbase,
+extern void dbase_policydb_attach(dbase_config_t * dconfig,
sepol_policydb_t * policydb);
/* Detach from a shared policdb.
@@ -103,7 +102,61 @@ extern void dbase_policydb_attach(dbase_
extern void dbase_policydb_detach(dbase_policydb_t * dbase);
/* Release allocated resources */
-extern void dbase_policydb_release(dbase_policydb_t * dbase);
+extern void dbase_policydb_release(dbase_config_t * dconfig);
+
+/* POLICYDB database methods */
+int dbase_policydb_cache(semanage_handle_t * handle, dbase_config_t * dconfig);
+
+void dbase_policydb_drop_cache(dbase_t * dbase);
+
+int dbase_policydb_flush(semanage_handle_t * handle, dbase_config_t * dconfig);
+
+int dbase_policydb_is_modified(dbase_config_t * dconfig);
+
+int dbase_policydb_iterate(semanage_handle_t * handle,
+ dbase_config_t * dconfig,
+ int (*fn) (const record_t * record, void *fn_arg),
+ void *arg);
+
+int dbase_policydb_exists(semanage_handle_t * handle,
+ dbase_config_t * dconfig,
+ const record_key_t * key, int *response);
+
+int dbase_policydb_list(semanage_handle_t * handle,
+ dbase_config_t * dconfig,
+ record_t *** records, unsigned int *count);
+
+int dbase_policydb_add(semanage_handle_t * handle,
+ dbase_config_t * dconfig,
+ const record_key_t * key, const record_t * data);
+
+int dbase_policydb_set(semanage_handle_t * handle,
+ dbase_config_t * dconfig,
+ const record_key_t * key, const record_t * data);
+
+int dbase_policydb_del(semanage_handle_t * handle,
+ dbase_config_t * dconfig, const record_key_t * key);
+
+int dbase_policydb_clear(semanage_handle_t * handle, dbase_config_t * dconfig);
+
+int dbase_policydb_modify(semanage_handle_t * handle,
+ dbase_config_t * dconfig,
+ const record_key_t * key, const record_t * data);
+
+int dbase_policydb_query(semanage_handle_t * handle,
+ dbase_config_t * dconfig,
+ const record_key_t * key, record_t ** response);
+
+int dbase_policydb_count(semanage_handle_t * handle,
+ dbase_config_t * dconfig, unsigned int *response);
+
+int dbase_policydb_set_serial(semanage_handle_t * handle,
+ dbase_policydb_t * dbase);
+
+int dbase_policydb_needs_resync(semanage_handle_t * handle,
+ dbase_config_t * dconfig);
+
+record_table_t *dbase_policydb_get_rtable(dbase_config_t * dconfig);
/* POLICYDB database - method table implementation */
extern dbase_table_t SEMANAGE_POLICYDB_DTABLE;
Index: selinux-pms-support/libsemanage/src/direct_api.c
===================================================================
--- selinux-pms-support.orig/libsemanage/src/direct_api.c
+++ selinux-pms-support/libsemanage/src/direct_api.c
@@ -467,25 +467,25 @@ static int semanage_direct_commit(semana
/* Before we do anything else, flush the join to its component parts.
* This *does not* flush to disk automatically */
- if (users->dtable->is_modified(users->dbase)) {
- retval = users->dtable->flush(sh, users->dbase);
+ if (users->dtable->is_modified(users)) {
+ retval = users->dtable->flush(sh, users);
if (retval < 0)
goto cleanup;
}
/* Decide if anything was modified */
- fcontexts_modified = fcontexts->dtable->is_modified(fcontexts->dbase);
- seusers_modified = seusers->dtable->is_modified(seusers->dbase);
+ fcontexts_modified = fcontexts->dtable->is_modified(fcontexts);
+ seusers_modified = seusers->dtable->is_modified(seusers);
users_extra_modified =
- users_extra->dtable->is_modified(users_extra->dbase);
- ports_modified = ports->dtable->is_modified(ports->dbase);
+ users_extra->dtable->is_modified(users_extra);
+ ports_modified = ports->dtable->is_modified(ports);
modified = sh->modules_modified;
modified |= ports_modified;
- modified |= users->dtable->is_modified(users_base->dbase);
- modified |= bools->dtable->is_modified(bools->dbase);
- modified |= ifaces->dtable->is_modified(ifaces->dbase);
- modified |= nodes->dtable->is_modified(nodes->dbase);
+ modified |= users->dtable->is_modified(users_base);
+ modified |= bools->dtable->is_modified(bools);
+ modified |= ifaces->dtable->is_modified(ifaces);
+ modified |= nodes->dtable->is_modified(nodes);
/* FIXME: get rid of these, once we support loading the existing policy,
* instead of rebuilding it */
@@ -588,7 +588,7 @@ static int semanage_direct_commit(semana
pseusers->dtable->drop_cache(pseusers->dbase);
} else {
- retval = pseusers->dtable->clear(sh, pseusers->dbase);
+ retval = pseusers->dtable->clear(sh, pseusers);
if (retval < 0)
goto cleanup;
}
@@ -608,7 +608,7 @@ static int semanage_direct_commit(semana
pusers_extra->dtable->drop_cache(pusers_extra->dbase);
} else {
- retval = pusers_extra->dtable->clear(sh, pusers_extra->dbase);
+ retval = pusers_extra->dtable->clear(sh, pusers_extra);
if (retval < 0)
goto cleanup;
}
@@ -641,12 +641,11 @@ static int semanage_direct_commit(semana
if (retval < 0)
goto cleanup;
- dbase_policydb_attach((dbase_policydb_t *) pusers_base->dbase,
- out);
- dbase_policydb_attach((dbase_policydb_t *) pports->dbase, out);
- dbase_policydb_attach((dbase_policydb_t *) pifaces->dbase, out);
- dbase_policydb_attach((dbase_policydb_t *) pbools->dbase, out);
- dbase_policydb_attach((dbase_policydb_t *) pnodes->dbase, out);
+ dbase_policydb_attach(pusers_base, out);
+ dbase_policydb_attach(pports, out);
+ dbase_policydb_attach(pifaces, out);
+ dbase_policydb_attach(pbools, out);
+ dbase_policydb_attach(pnodes, out);
/* ============= Apply changes, and verify =============== */
Index: selinux-pms-support/libsemanage/src/interfaces_policydb.c
===================================================================
--- selinux-pms-support.orig/libsemanage/src/interfaces_policydb.c
+++ selinux-pms-support/libsemanage/src/interfaces_policydb.c
@@ -63,5 +63,5 @@ int iface_policydb_dbase_init(semanage_h
void iface_policydb_dbase_release(dbase_config_t * dconfig)
{
- dbase_policydb_release(dconfig->dbase);
+ dbase_policydb_release(dconfig);
}
Index: selinux-pms-support/libsemanage/src/nodes_policydb.c
===================================================================
--- selinux-pms-support.orig/libsemanage/src/nodes_policydb.c
+++ selinux-pms-support/libsemanage/src/nodes_policydb.c
@@ -63,5 +63,5 @@ int node_policydb_dbase_init(semanage_ha
void node_policydb_dbase_release(dbase_config_t * dconfig)
{
- dbase_policydb_release(dconfig->dbase);
+ dbase_policydb_release(dconfig);
}
Index: selinux-pms-support/libsemanage/src/policy_components.c
===================================================================
--- selinux-pms-support.orig/libsemanage/src/policy_components.c
+++ selinux-pms-support/libsemanage/src/policy_components.c
@@ -17,25 +17,28 @@ static int clear_obsolete(semanage_handl
unsigned int nrecords,
dbase_config_t * src, dbase_config_t * dst)
{
-
+ int status = STATUS_SUCCESS;
record_key_t *key = NULL;
unsigned int i;
dbase_table_t *src_dtable = src->dtable;
dbase_table_t *dst_dtable = dst->dtable;
- record_table_t *rtable = src_dtable->get_rtable(src->dbase);
+ record_table_t *rtable = src_dtable->get_rtable(src);
for (i = 0; i < nrecords; i++) {
int exists;
- if (rtable->key_extract(handle, records[i], &key) < 0)
+ status = rtable->key_extract(handle, records[i], &key);
+ if (status != STATUS_SUCCESS)
goto err;
- if (dst_dtable->exists(handle, dst->dbase, key, &exists) < 0)
+ status = dst_dtable->exists(handle, dst, key, &exists);
+ if (status != STATUS_SUCCESS)
goto err;
if (!exists) {
- if (src_dtable->del(handle, src->dbase, key) < 0)
+ status = src_dtable->del(handle, src, key);
+ if (status != STATUS_SUCCESS)
goto err;
rtable->free(records[i]);
@@ -64,9 +67,8 @@ static int load_records(semanage_handle_
unsigned int i;
record_key_t *rkey = NULL;
- dbase_t *dbase = dst->dbase;
dbase_table_t *dtable = dst->dtable;
- record_table_t *rtable = dtable->get_rtable(dbase);
+ record_table_t *rtable = dtable->get_rtable(dst);
for (i = 0; i < nrecords; i++) {
@@ -78,11 +80,11 @@ static int load_records(semanage_handle_
goto err;
if (mode & MODE_SET &&
- dtable->set(handle, dbase, rkey, records[i]) < 0)
+ dtable->set(handle, dst, rkey, records[i]) < 0)
goto err;
else if (mode & MODE_MODIFY &&
- dtable->modify(handle, dbase, rkey, records[i]) < 0)
+ dtable->modify(handle, dst, rkey, records[i]) < 0)
goto err;
rtable->key_free(rkey);
@@ -149,17 +151,16 @@ int semanage_base_merge_components(seman
dbase_config_t *src = components[i].src;
dbase_config_t *dst = components[i].dst;
int mode = components[i].mode;
- record_table_t *rtable = src->dtable->get_rtable(src->dbase);
+ record_table_t *rtable = src->dtable->get_rtable(src);
/* Must invoke cache function first */
- if (src->dtable->cache(handle, src->dbase) < 0)
+ if (src->dtable->cache(handle, src) < 0)
goto err;
- if (dst->dtable->cache(handle, dst->dbase) < 0)
+ if (dst->dtable->cache(handle, dst) < 0)
goto err;
/* List all records */
- if (src->dtable->list(handle, src->dbase,
- &records, &nrecords) < 0)
+ if (src->dtable->list(handle, src, &records, &nrecords) < 0)
goto err;
/* Sort records on MODE_SORT */
@@ -223,8 +224,7 @@ int semanage_commit_components(semanage_
for (i = 0; i < CCOUNT; i++) {
/* Flush to disk */
- if (components[i]->dtable->flush(handle, components[i]->dbase) <
- 0)
+ if (components[i]->dtable->flush(handle, components[i]) < 0)
goto err;
}
Index: selinux-pms-support/libsemanage/src/ports_policydb.c
===================================================================
--- selinux-pms-support.orig/libsemanage/src/ports_policydb.c
+++ selinux-pms-support/libsemanage/src/ports_policydb.c
@@ -63,5 +63,5 @@ int port_policydb_dbase_init(semanage_ha
void port_policydb_dbase_release(dbase_config_t * dconfig)
{
- dbase_policydb_release(dconfig->dbase);
+ dbase_policydb_release(dconfig);
}
Index: selinux-pms-support/libsemanage/src/users_base_policydb.c
===================================================================
--- selinux-pms-support.orig/libsemanage/src/users_base_policydb.c
+++ selinux-pms-support/libsemanage/src/users_base_policydb.c
@@ -62,5 +62,5 @@ int user_base_policydb_dbase_init(semana
void user_base_policydb_dbase_release(dbase_config_t * dconfig)
{
- dbase_policydb_release(dconfig->dbase);
+ dbase_policydb_release(dconfig);
}
--
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH 10/33] libsemanage: database serialization
2007-04-23 21:34 [PATCH 00/33] libsemanage/libsepol object serialization and ps-api jbrindle
` (8 preceding siblings ...)
2007-04-23 21:35 ` [PATCH 09/33] libsemanage: dbase/dconfig cleanup jbrindle
@ 2007-04-23 21:35 ` jbrindle
2007-04-23 21:35 ` [PATCH 11/33] libsemanage: endianness macros jbrindle
` (24 subsequent siblings)
34 siblings, 0 replies; 58+ messages in thread
From: jbrindle @ 2007-04-23 21:35 UTC (permalink / raw)
To: selinux
This adds serialize/unserialize methods for databases
---
libsemanage/src/database.c | 153 ++++++++++++++++++++++++++++++++++++
libsemanage/src/database.h | 21 ++++
libsemanage/src/database_policydb.c | 10 ++
3 files changed, 184 insertions(+)
Index: selinux-pms-support/libsemanage/src/database.c
===================================================================
--- selinux-pms-support.orig/libsemanage/src/database.c
+++ selinux-pms-support/libsemanage/src/database.c
@@ -20,6 +20,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <limits.h>
+#include <stdlib.h>
#include <semanage/handle.h>
#include "semanage_store.h"
#include "semanage_conf.h"
@@ -219,3 +221,154 @@ int dbase_list(semanage_handle_t * handl
return exit_ro(handle, dconfig);
}
+
+/* Serialize the given database. */
+int dbase_serialize(struct semanage_handle *handle,
+ dbase_config_t * dconfig,
+ char **data, uint64_t * data_length)
+{
+ int status = 0;
+ unsigned int count = 0;
+ unsigned int completed_count = 0;
+ unsigned int i = 0;
+ uint64_t size = 0;
+ char *ptr = NULL;
+ record_t **records = NULL;
+
+ status = enter_ro(handle, dconfig);
+ if (status != STATUS_SUCCESS)
+ goto err;
+
+ record_table_t *rtable = dconfig->dtable->get_rtable(dconfig);
+
+ /* Initialize */
+ *data = NULL;
+ *data_length = 0;
+
+ /* Get a list of the records. */
+ status = dconfig->dtable->list(handle, dconfig, &records, &count);
+ if (status != STATUS_SUCCESS)
+ goto err;
+
+ /* Iterate over all records and calculate
+ * the size of the serialized data. */
+ for (i = 0; i < count; i++) {
+ status = rtable->serialize(handle, records[i], NULL, &size);
+ if (status != STATUS_SUCCESS) {
+ completed_count = i - 1;
+ goto err;
+ }
+ }
+
+ *data_length = size;
+
+ /* Allocate space for the serialized data. */
+ *data = calloc((size_t) size, sizeof(char));
+ if (data == NULL)
+ goto err;
+
+ /* Iterate over all records and serialize them. */
+ ptr = *data;
+ completed_count = 0;
+ for (i = 0; i < count; i++) {
+ status = rtable->serialize(handle, records[i], &ptr, NULL);
+ if (status != STATUS_SUCCESS) {
+ completed_count = i - 1;
+ goto err;
+ }
+ }
+
+ /* Clean up. */
+ for (i = 0; i < count; i++)
+ rtable->free(records[i]);
+ free(records);
+
+ if (exit_ro(handle, dconfig) < 0)
+ goto err;
+
+ return STATUS_SUCCESS;
+
+ err:
+ if (records) {
+ for (i = 0; i < completed_count; i++)
+ rtable->free(records[i]);
+ }
+ free(records);
+ free(*data);
+ *data = NULL;
+ *data_length = 0;
+
+ exit_ro(handle, dconfig);
+
+ return STATUS_ERR;
+}
+
+/* Unserialize the given database.
+ * This function DOES move the data pointer passed in.
+ */
+int dbase_unserialize(struct semanage_handle *handle,
+ dbase_config_t * dconfig,
+ char *data, uint64_t data_length)
+{
+ int status = 0;
+ char *ptr = data;
+ uint64_t current_length = data_length;
+ record_t *record = NULL;
+ record_key_t *key = NULL;
+ record_table_t *rtable = dconfig->dtable->get_rtable(dconfig);
+ unsigned int write = 0;
+
+ if ((data == NULL) || (data_length == 0)) {
+ status = dconfig->dtable->clear(handle, dconfig);
+ if (status < 0)
+ goto err;
+ return STATUS_SUCCESS;
+ }
+
+ /* Iterate over the serialized records, adding them
+ * to the database one by one. */
+ while (current_length > 0) {
+ status =
+ rtable->unserialize(handle, &ptr, ¤t_length, &record);
+ if (status != STATUS_SUCCESS)
+ goto err;
+
+ status = rtable->key_extract(handle, record, &key);
+ if (status != STATUS_SUCCESS)
+ goto err;
+
+ if (write == 1) {
+ status = dconfig->dtable->add(handle, dconfig, key, record);
+ if (status != STATUS_SUCCESS)
+ goto err;
+ }
+
+ rtable->key_free(key);
+ key = NULL;
+ rtable->free(record);
+ record = NULL;
+
+ if (current_length == 0 && write == 0) {
+ /* Remove all current entries to the database. */
+ status = dconfig->dtable->clear(handle, dconfig);
+ if (status < 0)
+ goto err;
+
+ /* Rerun and actually add the entries. */
+ write = 1;
+ ptr = data;
+ current_length = data_length;
+ }
+ }
+ /* Unserializing should move the pointer passed in */
+ data = ptr;
+
+ return STATUS_SUCCESS;
+
+err:
+ rtable->key_free(key);
+ key = NULL;
+ rtable->free(record);
+ record = NULL;
+ return STATUS_ERR;
+}
Index: selinux-pms-support/libsemanage/src/database.h
===================================================================
--- selinux-pms-support.orig/libsemanage/src/database.h
+++ selinux-pms-support/libsemanage/src/database.h
@@ -23,6 +23,8 @@
#ifndef _SEMANAGE_DATABASE_H_
#define _SEMANAGE_DATABASE_H_
+#include <inttypes.h>
+
#ifndef DBASE_RECORD_DEFINED
typedef void *record_t;
typedef void *record_key_t;
@@ -70,6 +72,17 @@ typedef struct record_table {
int (*clone) (struct semanage_handle * handle,
const record_t * rec, record_t ** new_rec);
+ /* Serialize this record. rec_data must be allocated
+ * and large enough to hold the result. */
+ int (*serialize) (struct semanage_handle * handle,
+ const record_t * rec,
+ char **rec_data, uint64_t * size);
+
+ /* Unserialize this record data */
+ int (*unserialize) (struct semanage_handle * handle,
+ char **rec_data, uint64_t * size,
+ record_t ** rec);
+
/* Deallocate record resources. Must sucessfully handle NULL. */
void (*free) (record_t * rec);
@@ -241,4 +254,12 @@ extern int dbase_list(struct semanage_ha
dbase_config_t * dconfig,
record_t *** records, unsigned int *count);
+extern int dbase_serialize(struct semanage_handle *handle,
+ dbase_config_t * dconfig,
+ char **data, uint64_t * data_length);
+
+extern int dbase_unserialize(struct semanage_handle *handle,
+ dbase_config_t * dconfig,
+ char *data, uint64_t data_length);
+
#endif
Index: selinux-pms-support/libsemanage/src/database_policydb.c
===================================================================
--- selinux-pms-support.orig/libsemanage/src/database_policydb.c
+++ selinux-pms-support/libsemanage/src/database_policydb.c
@@ -21,6 +21,7 @@
*/
/* Object: dbase_policydb_t (Policy)
+ * Extends: dbase_llist_t (Linked List)
* Implements: dbase_t (Database)
*/
@@ -38,6 +39,7 @@ typedef struct dbase_policydb dbase_t;
#include <sepol/policydb.h>
#include "database_policydb.h"
+#include "database_llist.h"
#include "semanage_store.h"
#include "handle.h"
#include "debug.h"
@@ -45,6 +47,11 @@ typedef struct dbase_policydb dbase_t;
/* POLICYDB dbase */
struct dbase_policydb {
+ /* Parent object - must always be
+ * the first field - here we are using
+ * a linked list to store the records */
+ dbase_llist_t llist;
+
/* Backing file suffix */
const char *suffix;
@@ -65,6 +72,7 @@ void dbase_policydb_drop_cache(dbase_t *
{
if (dbase->cache_serial >= 0) {
+ dbase_llist_drop_cache(&dbase->llist);
sepol_policydb_free(dbase->policydb);
dbase->cache_serial = -1;
dbase->modified = 0;
@@ -242,6 +250,8 @@ int dbase_policydb_init(semanage_handle_
tmp_dbase->cache_serial = -1;
tmp_dbase->modified = 0;
tmp_dbase->attached = 0;
+
+ dbase_llist_init(&tmp_dbase->llist, rtable);
*dbase = tmp_dbase;
return STATUS_SUCCESS;
--
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH 11/33] libsemanage: endianness macros
2007-04-23 21:34 [PATCH 00/33] libsemanage/libsepol object serialization and ps-api jbrindle
` (9 preceding siblings ...)
2007-04-23 21:35 ` [PATCH 10/33] libsemanage: database serialization jbrindle
@ 2007-04-23 21:35 ` jbrindle
2007-04-23 21:35 ` [PATCH 12/33] libsemanage: basic serialization jbrindle
` (23 subsequent siblings)
34 siblings, 0 replies; 58+ messages in thread
From: jbrindle @ 2007-04-23 21:35 UTC (permalink / raw)
To: selinux
---
libsemanage/src/byteswap.h | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
Index: selinux-pms-support/libsemanage/src/byteswap.h
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/src/byteswap.h
@@ -0,0 +1,20 @@
+/* Byte swap macros for libsemanage. */
+#ifndef __SEMANAGE_BYTESWAP_H__
+#define __SEMANAGE_BYTESWAP_H__
+
+#include <byteswap.h>
+#include <endian.h>
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define cpu_to_le32(x) (x)
+#define le32_to_cpu(x) (x)
+#define cpu_to_le64(x) (x)
+#define le64_to_cpu(x) (x)
+#else
+#define cpu_to_le32(x) bswap_32(x)
+#define le32_to_cpu(x) bswap_32(x)
+#define cpu_to_le64(x) bswap_64(x)
+#define le64_to_cpu(x) bswap_64(x)
+#endif
+
+#endif
--
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH 12/33] libsemanage: basic serialization
2007-04-23 21:34 [PATCH 00/33] libsemanage/libsepol object serialization and ps-api jbrindle
` (10 preceding siblings ...)
2007-04-23 21:35 ` [PATCH 11/33] libsemanage: endianness macros jbrindle
@ 2007-04-23 21:35 ` jbrindle
2007-04-24 21:16 ` Karl MacMillan
2007-04-23 21:35 ` [PATCH 13/33] libsemanage: testing infrastructure jbrindle
` (22 subsequent siblings)
34 siblings, 1 reply; 58+ messages in thread
From: jbrindle @ 2007-04-23 21:35 UTC (permalink / raw)
To: selinux
This is the serialization infrastructure for libsemanage.
---
libsemanage/include/semanage/handle.h | 17 +
libsemanage/src/handle.c | 28 ++
libsemanage/src/handle_internal.h | 5
libsemanage/src/libsemanage.map | 1
libsemanage/src/serialize.c | 389 ++++++++++++++++++++++++++++++++++
libsemanage/src/serialize.h | 45 +++
6 files changed, 485 insertions(+)
Index: selinux-pms-support/libsemanage/include/semanage/handle.h
===================================================================
--- selinux-pms-support.orig/libsemanage/include/semanage/handle.h
+++ selinux-pms-support/libsemanage/include/semanage/handle.h
@@ -21,6 +21,11 @@
#ifndef _SEMANAGE_HANDLE_H_
#define _SEMANAGE_HANDLE_H_
+#define SEMANAGE_SERIAL_VERSION_MAJOR 1
+#define SEMANAGE_SERIAL_VERSION_MINOR 0
+
+#include <inttypes.h>
+
/* All accesses with semanage are through a "semanage_handle". The
* handle may ultimately reference local config files,
* the binary policy file, a module store, or a policy management server.
@@ -38,6 +43,18 @@ semanage_handle_t *semanage_handle_creat
* previously called if the handle was connected. */
void semanage_handle_destroy(semanage_handle_t *);
+/* Get the serialization version. */
+int semanage_handle_get_version(semanage_handle_t *sh, uint32_t * major, uint32_t * minor);
+
+/* Set the serialization version. */
+int semanage_handle_set_version(semanage_handle_t *sh, uint32_t major, uint32_t minor);
+
+/* Serialize the serialization version. */
+int semanage_handle_version_serialize(semanage_handle_t *sh, char **data, uint64_t *size);
+
+/* Unserialize the serialization version. */
+int semanage_handle_version_unserialize(semanage_handle_t *sh, char **data, uint64_t *size);
+
/* This is the type of connection to the store, for now only
* direct is supported */
enum semanage_connect_type {
Index: selinux-pms-support/libsemanage/src/handle.c
===================================================================
--- selinux-pms-support.orig/libsemanage/src/handle.c
+++ selinux-pms-support/libsemanage/src/handle.c
@@ -82,6 +82,34 @@ semanage_handle_t *semanage_handle_creat
return NULL;
}
+int semanage_handle_get_version(semanage_handle_t *sh, uint32_t * major, uint32_t * minor)
+{
+ return sepol_handle_get_version(sh->sepolh, major, minor);
+}
+
+hidden_def(semanage_handle_get_version)
+
+int semanage_handle_set_version(semanage_handle_t *sh, uint32_t major, uint32_t minor)
+{
+ return sepol_handle_set_version(sh->sepolh, major, minor);
+}
+
+hidden_def(semanage_handle_set_version)
+
+int semanage_handle_version_serialize(semanage_handle_t *sh, char **data, uint64_t *size)
+{
+ return sepol_handle_version_serialize(sh->sepolh, data, size);
+}
+
+hidden_def(semanage_handle_version_serialize)
+
+int semanage_handle_version_unserialize(semanage_handle_t *sh, char **data, uint64_t *size)
+{
+ return sepol_handle_version_unserialize(sh->sepolh, data, size);
+}
+
+hidden_def(semanage_handle_version_unserialize)
+
void semanage_set_rebuild(semanage_handle_t * sh, int do_rebuild)
{
Index: selinux-pms-support/libsemanage/src/handle_internal.h
===================================================================
--- selinux-pms-support.orig/libsemanage/src/handle_internal.h
+++ selinux-pms-support/libsemanage/src/handle_internal.h
@@ -8,4 +8,9 @@ hidden_proto(semanage_begin_transaction)
hidden_proto(semanage_handle_destroy)
hidden_proto(semanage_reload_policy)
hidden_proto(semanage_access_check)
+hidden_proto(semanage_handle_get_version)
+hidden_proto(semanage_handle_set_version)
+hidden_proto(semanage_handle_version_serialize)
+hidden_proto(semanage_handle_version_unserialize)
+
#endif
Index: selinux-pms-support/libsemanage/src/libsemanage.map
===================================================================
--- selinux-pms-support.orig/libsemanage/src/libsemanage.map
+++ selinux-pms-support/libsemanage/src/libsemanage.map
@@ -13,6 +13,7 @@ LIBSEMANAGE_1.0 {
semanage_iface_*; semanage_port_*; semanage_context_*;
semanage_node_*;
semanage_fcontext_*; semanage_access_check; semanage_set_create_store;
+ semanage_*_serialize; semanage_*_unserialize;
semanage_is_connected;
local: *;
};
Index: selinux-pms-support/libsemanage/src/serialize.c
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/src/serialize.c
@@ -0,0 +1,389 @@
+/* Author: Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2004-2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+
+#include "handle.h"
+#include "debug.h"
+#include "serialize.h"
+#include "byteswap.h"
+
+/* This file provides general serialize and unserialize functions. */
+
+/** Serializes various kinds of datum.
+ *
+ * Two use cases:
+ * 1) Calling serialize with a non-NULL size.
+ * This causes serialize to calculate the expected
+ * size of serializing. No serialization occurs.
+ * Destructively modifies size. Data may be NULL.
+ * 2) Calling serialize with a NULL size.
+ * This results in data being filled with the
+ * serialized information. Caller must pre-allocate
+ * space for data. Destructively modifies data.
+ *
+ * This function acts iteratively moving the *data or size values.
+ *
+ * Supported datum_types (defined in serialize.h):
+ *
+ * SEMANAGE_SERIAL_INT32_T
+ * Serializes datum to a int32_t as defined in inttypes.h
+ * datum may NOT be NULL.
+ * datum_length is not utilized.
+ * SEMANAGE_SERIAL_UINT32_T
+ * Serializes datum to a uint32_t as defined in inttypes.h
+ * datum may NOT be NULL.
+ * datum_length is not utilized.
+ * SEMANAGE_SERIAL_SIZE_T
+ * Serializes datum to a size_t as defined in stddef.h
+ * datum may NOT be NULL.
+ * datum_length is not utilized.
+ * SEMANAGE_SERIAL_STRING
+ * Serializes a char*.
+ * datum may be NULL.
+ * datum_length should be the length of the string as returned by strlen.
+ * SEMANAGE_SERIAL_STRING_ARRAY
+ * Serializes a char**.
+ * datum may be NULL.
+ * datum_length should be the size of the array.
+ * Each string will be serialized as per SEMANAGE_SERIAL_STRING and its size
+ * determined via strlen.
+ *
+ * NULL pointers are distinguished (where they are allowed at all).
+ * In the case of strings this means that a NULL char* has a different
+ * serialization from the empty string "".
+ *
+ */
+int semanage_serialize(semanage_handle_t * handle,
+ const void *datum,
+ size_t datum_length,
+ unsigned int datum_type, char **data, uint64_t * size)
+{
+ int status;
+ unsigned int flags;
+ uint32_t i;
+ void *temp = NULL;
+
+ switch (datum_type) {
+ case SEMANAGE_SERIAL_INT32_T:
+ case SEMANAGE_SERIAL_UINT32_T:
+ if (size == NULL) {
+ temp = calloc(1, sizeof(int32_t));
+ if (temp == NULL) {
+ status = STATUS_ERR;
+ goto cleanup;
+ }
+
+ *((int32_t *)temp) = cpu_to_le32(*((int32_t *) datum));
+ memcpy(*data, temp, sizeof(int32_t));
+ *data += sizeof(int32_t);
+ }
+ else
+ *size += sizeof(int32_t);
+ break;
+ case SEMANAGE_SERIAL_SIZE_T:
+ if (size == NULL) {
+ temp = calloc(1, sizeof(uint64_t));
+ if (temp == NULL) {
+ status = STATUS_ERR;
+ goto cleanup;
+ }
+
+ *((uint64_t *)temp) = cpu_to_le64(*((size_t *) datum));
+
+ memcpy(*data, temp, sizeof(uint64_t));
+ *data += sizeof(uint64_t);
+ }
+ else
+ *size += sizeof(uint64_t);
+ break;
+ case SEMANAGE_SERIAL_STRING:
+ /* Flags (intended as a bitmap):
+ * 0 == NULL
+ * 1 == Non NULL
+ */
+ flags = (datum == NULL) ? 0 : 1;
+
+ status =
+ semanage_serialize(handle, &flags, 0, SEMANAGE_SERIAL_UINT32_T, data,
+ size);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Write if not null. */
+ if (flags & 1) {
+ /* Size. */
+ status =
+ semanage_serialize(handle, &datum_length, 0,
+ SEMANAGE_SERIAL_SIZE_T, data, size);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Datum. */
+ if (size == NULL) {
+ status =
+ snprintf(*data, datum_length + 1, "%s",
+ (char *)datum);
+ if (status < 0 || (unsigned)status > datum_length)
+ goto cleanup;
+ else {
+ *data += status + 1;
+ status = STATUS_SUCCESS;
+ }
+ } else {
+ *size += datum_length + 1;
+ }
+ }
+ break;
+ case SEMANAGE_SERIAL_STRING_ARRAY:
+ /* Flags (intended as a bitmap):
+ * 0 == NULL
+ * 1 == Non NULL
+ */
+ flags = (datum == NULL) ? 0 : 1;
+
+ status =
+ semanage_serialize(handle, &flags, 0, SEMANAGE_SERIAL_UINT32_T, data,
+ size);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Write if not null. */
+ if (flags & 1) {
+ /* Size. */
+ status =
+ semanage_serialize(handle, &datum_length, 0,
+ SEMANAGE_SERIAL_UINT32_T, data, size);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Datum. */
+ for (i = 0; i < datum_length; i++) {
+ status =
+ semanage_serialize(handle, ((char **)datum)[i],
+ strlen(((char **)datum)[i]),
+ SEMANAGE_SERIAL_STRING, data, size);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+ }
+ }
+ break;
+ default:
+ status = STATUS_ERR;
+ goto cleanup;
+ }
+
+ /* Cleanup. */
+ status = STATUS_SUCCESS;
+cleanup:
+ free(temp);
+ return status;
+}
+
+/** Unserializes various kinds of datum as serialized by semanage_serialize.
+ *
+ * This function acts iteratively moving the *data AND size values.
+ * size is decremented as data is unserialized.
+ *
+ * It also allocates memory for datum and, depending on datum_type, datum_length.
+ * Caller must free.
+ *
+ * Supported datum_types (defined in serialize.h):
+ *
+ * SEMANAGE_SERIAL_INT32_T
+ * Unserializes data into an int32_t as defined in inttypes.h.
+ * datum_length may be NULL.
+ * SEMANAGE_SERIAL_UINT32_T
+ * Unserializes data into an uint32_t as defined in inttypes.h.
+ * datum_length may be NULL.
+ * SEMANAGE_SERIAL_SIZE_T
+ * Unserializes data into an size_t as defined in stddef.h.
+ * datum_length may be NULL.
+ * SEMANAGE_SERIAL_STRING
+ * Unserializes data into a NULL terminated char*.
+ * datum_length may NOT be NULL and will be the size of the string.
+ * SEMANAGE_SERIAL_STRING_ARRAY
+ * Unserializes data into a char**.
+ * Each entry in the array will be unserialized as per SEMANAGE_SERIAL_STRING.
+ * datum_length may NOT be NULL and will be the size of the array.
+ */
+int semanage_unserialize(semanage_handle_t * handle,
+ char **data, uint64_t * size,
+ void **datum,
+ size_t ** datum_length,
+ unsigned int datum_type)
+{
+ int status;
+ unsigned int *flags = NULL;
+ uint32_t i;
+ void *temp = NULL;
+ size_t *temp_length = NULL;
+
+ switch (datum_type) {
+ case SEMANAGE_SERIAL_INT32_T:
+ case SEMANAGE_SERIAL_UINT32_T:
+ *datum = calloc(1, sizeof(int32_t));
+ if (*datum == NULL) {
+ status = STATUS_ERR;
+ goto cleanup;
+ }
+
+ memcpy(*datum, *data, sizeof(int32_t));
+ **((int32_t **)datum) = le32_to_cpu(**((int32_t **) datum));
+
+ *size -= sizeof(int32_t);
+ *data += sizeof(int32_t);
+ break;
+ case SEMANAGE_SERIAL_SIZE_T:
+ temp = calloc(1, sizeof(uint64_t));
+ if (temp == NULL) {
+ status = STATUS_ERR;
+ goto cleanup;
+ }
+
+ memcpy(temp, *data, sizeof(uint64_t));
+
+ *((uint64_t *) temp) = le64_to_cpu(*((uint64_t *) temp));
+
+ if (*((uint64_t *) temp) > UINT_MAX) {
+ status = STATUS_ERR;
+ goto cleanup;
+ }
+
+ *datum = calloc(1, sizeof(size_t));
+ if (datum == NULL) {
+ status = STATUS_ERR;
+ goto cleanup;
+ }
+
+ **((size_t **)datum) = *((uint64_t *) temp);
+
+ *size -= sizeof(uint64_t);
+ *data += sizeof(uint64_t);
+ break;
+ case SEMANAGE_SERIAL_STRING:
+ /* Flags (intended as a bitmap):
+ * 0 == NULL
+ * 1 == Non NULL
+ */
+ status =
+ semanage_unserialize(handle,
+ data, size,
+ (void **)(&flags), NULL,
+ SEMANAGE_SERIAL_UINT32_T);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ if (*flags & 1) {
+ /* Size. */
+ status =
+ semanage_unserialize(handle,
+ data, size,
+ (void **)datum_length, NULL,
+ SEMANAGE_SERIAL_SIZE_T);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Datum. */
+ *datum = calloc(**datum_length + 1, sizeof(char));
+ if (*datum == NULL) {
+ status = STATUS_ERR;
+ goto cleanup;
+ }
+
+ memcpy(*datum, *data, **datum_length + 1);
+
+ *size -= **datum_length + 1;
+ *data += **datum_length + 1;
+ } else {
+ *datum = NULL;
+ *datum_length = NULL;
+ }
+
+ free(flags);
+ flags = NULL;
+ break;
+ case SEMANAGE_SERIAL_STRING_ARRAY:
+ /* Flags (intended as a bitmap):
+ * 0 == NULL
+ * 1 == Non NULL
+ */
+ status =
+ semanage_unserialize(handle,
+ data, size,
+ (void **)(&flags), NULL,
+ SEMANAGE_SERIAL_UINT32_T);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Write if not null. */
+ if (*flags & 1) {
+ /* Size. */
+ status =
+ semanage_unserialize(handle,
+ data, size,
+ (void **)datum_length, NULL,
+ SEMANAGE_SERIAL_UINT32_T);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Datum. */
+ *datum =
+ calloc(sizeof(char *),
+ sizeof(char *) * (**datum_length));
+ if (*datum == NULL) {
+ status = STATUS_ERR;
+ goto cleanup;
+ }
+
+ for (i = 0; i < **datum_length; i++) {
+ status = semanage_unserialize(handle,
+ data,
+ size,
+ (void **)&(((char **)(*datum))[i]),
+ &temp_length,
+ SEMANAGE_SERIAL_STRING);
+
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ free(temp_length);
+ temp_length = NULL;
+ }
+ }
+
+ free(flags);
+ flags = NULL;
+ break;
+ default:
+ status = STATUS_ERR;
+ goto cleanup;
+ }
+
+ /* Cleanup. */
+ status = STATUS_SUCCESS;
+cleanup:
+ free(flags);
+ free(temp);
+ free(temp_length);
+ return status;
+}
+
Index: selinux-pms-support/libsemanage/src/serialize.h
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/src/serialize.h
@@ -0,0 +1,45 @@
+/* Author: Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2005-2007 Tresys Technology, LLC
+ * Copyright (C) 2005 Red Hat Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _SEMANAGE_SERIALIZE_INTERNAL_H_
+#define _SEMANAGE_SERIALIZE_INTERNAL_H_
+
+#include <inttypes.h>
+#include "handle.h"
+
+/* Datum types. */
+#define SEMANAGE_SERIAL_INT32_T 0
+#define SEMANAGE_SERIAL_UINT32_T 1
+#define SEMANAGE_SERIAL_SIZE_T 2
+#define SEMANAGE_SERIAL_STRING 3
+#define SEMANAGE_SERIAL_STRING_ARRAY 4
+
+int semanage_serialize(semanage_handle_t * handle,
+ const void *datum,
+ size_t datum_size,
+ unsigned int datum_type, char **data, uint64_t * size);
+
+int semanage_unserialize(semanage_handle_t * handle,
+ char **data, uint64_t * size,
+ void **datum,
+ size_t ** datum_length,
+ unsigned int datum_type);
+
+#endif
--
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH 13/33] libsemanage: testing infrastructure
2007-04-23 21:34 [PATCH 00/33] libsemanage/libsepol object serialization and ps-api jbrindle
` (11 preceding siblings ...)
2007-04-23 21:35 ` [PATCH 12/33] libsemanage: basic serialization jbrindle
@ 2007-04-23 21:35 ` jbrindle
2007-04-23 21:35 ` [PATCH 14/33] libsemanage: boolean serialization jbrindle
` (21 subsequent siblings)
34 siblings, 0 replies; 58+ messages in thread
From: jbrindle @ 2007-04-23 21:35 UTC (permalink / raw)
To: selinux
Adding a globals.h for tests to hold joint variables for all tests such as a shared semanage handle.
---
libsemanage/tests/globals.h | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
Index: selinux-pms-support/libsemanage/tests/globals.h
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/tests/globals.h
@@ -0,0 +1,27 @@
+/* Authors: Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __GLOBALS_H__
+#define __GLOBALS_H__
+
+#include "handle.h"
+
+semanage_handle_t *sh;
+
+#endif
--
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH 14/33] libsemanage: boolean serialization
2007-04-23 21:34 [PATCH 00/33] libsemanage/libsepol object serialization and ps-api jbrindle
` (12 preceding siblings ...)
2007-04-23 21:35 ` [PATCH 13/33] libsemanage: testing infrastructure jbrindle
@ 2007-04-23 21:35 ` jbrindle
2007-04-23 21:35 ` [PATCH 15/33] libsemanage: context serialization jbrindle
` (20 subsequent siblings)
34 siblings, 0 replies; 58+ messages in thread
From: jbrindle @ 2007-04-23 21:35 UTC (permalink / raw)
To: selinux
---
libsemanage/include/semanage/booleans_active.h | 28 ++++
libsemanage/include/semanage/booleans_local.h | 28 ++++
libsemanage/include/semanage/booleans_policy.h | 6 +
libsemanage/src/boolean_internal.h | 53 +++++++++
libsemanage/src/boolean_record.c | 48 ++++++++
libsemanage/src/booleans_active.c | 16 ++
libsemanage/src/booleans_local.c | 16 ++
libsemanage/src/booleans_policy.c | 16 ++
libsemanage/tests/libsemanage-tests.c | 4
libsemanage/tests/test_boolean_record.c | 142 +++++++++++++++++++++++++
libsemanage/tests/test_boolean_record.h | 32 +++++
11 files changed, 386 insertions(+), 3 deletions(-)
Index: selinux-pms-support/libsemanage/include/semanage/booleans_active.h
===================================================================
--- selinux-pms-support.orig/libsemanage/include/semanage/booleans_active.h
+++ selinux-pms-support/libsemanage/include/semanage/booleans_active.h
@@ -1,8 +1,28 @@
-/* Copyright (C) 2005 Red Hat, Inc. */
+/* Authors: Ivan Gyurdiev <ivg2@cornell.edu>
+ * Christopher Ashworth <cashworth@tresys.com>
+ *
+ * Copyright (C) 2005 Red Hat, Inc.
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
#ifndef _SEMANAGE_BOOLEANS_ACTIVE_H_
#define _SEMANAGE_BOOLEANS_ACTIVE_H_
+#include <inttypes.h>
#include <semanage/boolean_record.h>
#include <semanage/handle.h>
@@ -30,4 +50,10 @@ extern int semanage_bool_list_active(sem
semanage_bool_t *** records,
unsigned int *count);
+extern int semanage_bool_serialize_active(semanage_handle_t * handle,
+ char **data, uint64_t * data_length);
+
+extern int semanage_bool_unserialize_active(semanage_handle_t * handle,
+ char *data, uint64_t data_length);
+
#endif
Index: selinux-pms-support/libsemanage/include/semanage/booleans_local.h
===================================================================
--- selinux-pms-support.orig/libsemanage/include/semanage/booleans_local.h
+++ selinux-pms-support/libsemanage/include/semanage/booleans_local.h
@@ -1,8 +1,28 @@
-/* Copyright (C) 2005 Red Hat, Inc. */
+/* Authors: Ivan Gyurdiev <ivg2@cornell.edu>
+ * Christopher Ashworth <cashworth@tresys.com>
+ *
+ * Copyright (C) 2005 Red Hat, Inc.
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
#ifndef _SEMANAGE_BOOLEANS_LOCAL_H_
#define _SEMANAGE_BOOLEANS_LOCAL_H_
+#include <inttypes.h>
#include <semanage/boolean_record.h>
#include <semanage/handle.h>
@@ -33,4 +53,10 @@ extern int semanage_bool_list_local(sema
semanage_bool_t *** records,
unsigned int *count);
+extern int semanage_bool_serialize_local(semanage_handle_t * handle,
+ char **data, uint64_t * data_length);
+
+extern int semanage_bool_unserialize_local(semanage_handle_t * handle,
+ char *data, uint64_t data_length);
+
#endif
Index: selinux-pms-support/libsemanage/include/semanage/booleans_policy.h
===================================================================
--- selinux-pms-support.orig/libsemanage/include/semanage/booleans_policy.h
+++ selinux-pms-support/libsemanage/include/semanage/booleans_policy.h
@@ -24,4 +24,10 @@ extern int semanage_bool_iterate(semanag
extern int semanage_bool_list(semanage_handle_t * handle,
semanage_bool_t *** records, unsigned int *count);
+extern int semanage_bool_serialize_policy(semanage_handle_t * handle,
+ char **data, uint64_t * data_length);
+
+extern int semanage_bool_unserialize_policy(semanage_handle_t * handle,
+ char *data, uint64_t data_length);
+
#endif
Index: selinux-pms-support/libsemanage/src/boolean_internal.h
===================================================================
--- selinux-pms-support.orig/libsemanage/src/boolean_internal.h
+++ selinux-pms-support/libsemanage/src/boolean_internal.h
@@ -1,11 +1,36 @@
+/* Authors: Ivan Gyurdiev <ivg2@cornell.edu>
+ * Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2005 Red Hat, Inc.
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
#ifndef _SEMANAGE_BOOLEAN_INTERNAL_H_
#define _SEMANAGE_BOOLEAN_INTERNAL_H_
+#include <inttypes.h>
#include <semanage/boolean_record.h>
#include <semanage/booleans_local.h>
#include <semanage/booleans_policy.h>
#include <semanage/booleans_active.h>
#include "database.h"
+#include "database_policydb.h"
+#include "database_activedb.h"
#include "handle.h"
#include "dso.h"
@@ -23,6 +48,8 @@ hidden_proto(semanage_bool_clone)
/* BOOL RECORD: metod table */
extern record_table_t SEMANAGE_BOOL_RTABLE;
+extern record_policydb_table_t SEMANAGE_BOOL_POLICYDB_RTABLE;
+extern record_activedb_table_t SEMANAGE_BOOL_ACTIVEDB_RTABLE;
extern int bool_file_dbase_init(semanage_handle_t * handle,
const char *fname, dbase_config_t * dconfig);
@@ -39,4 +66,30 @@ extern int bool_activedb_dbase_init(sema
extern void bool_activedb_dbase_release(dbase_config_t * dconfig);
+extern int bool_ps_local_dbase_init(semanage_handle_t * handle,
+ uint32_t sandbox_id, dbase_config_t * dconfig);
+
+extern void bool_ps_local_dbase_release(dbase_config_t * dconfig);
+
+extern int bool_ps_policydb_dbase_init(semanage_handle_t * handle,
+ uint32_t sandbox_id,
+ dbase_config_t * dconfig);
+
+extern void bool_ps_policydb_dbase_release(dbase_config_t * dconfig);
+
+extern int bool_ps_activedb_dbase_init(semanage_handle_t * handle,
+ uint32_t sandbox_id,
+ dbase_config_t * dconfig);
+
+extern void bool_ps_activedb_dbase_release(dbase_config_t * dconfig);
+
+/*======== Internal API: Serialize/Unserialize ========== */
+hidden int semanage_bool_serialize(semanage_handle_t * handle,
+ const semanage_bool_t * boolean,
+ char **data, uint64_t * size);
+
+hidden int semanage_bool_unserialize(semanage_handle_t * handle,
+ char **data, uint64_t * size,
+ semanage_bool_t ** boolean);
+
#endif
Index: selinux-pms-support/libsemanage/src/boolean_record.c
===================================================================
--- selinux-pms-support.orig/libsemanage/src/boolean_record.c
+++ selinux-pms-support/libsemanage/src/boolean_record.c
@@ -1,4 +1,24 @@
-/* Copyright (C) 2005 Red Hat, Inc. */
+/* Authors: Ivan Gyurdiev <ivg2@cornell.edu>
+ * Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2005 Red Hat, Inc.
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
/* Object: semanage_bool_t (Policy Boolean)
* Object: semanage_bool_key_t (Policy Boolean Key)
@@ -6,6 +26,8 @@
* Implements: record_key_t (Database Record Key)
*/
+#include <stdlib.h>
+#include <string.h>
#include <sepol/boolean_record.h>
typedef sepol_bool_t semanage_bool_t;
@@ -19,6 +41,7 @@ typedef semanage_bool_key_t record_key_t
#include "boolean_internal.h"
#include "handle.h"
#include "database.h"
+#include "debug.h"
/* Key */
int semanage_bool_key_create(semanage_handle_t * handle,
@@ -133,6 +156,27 @@ void semanage_bool_free(semanage_bool_t
hidden_def(semanage_bool_free)
+/* Serialize/Unserialize */
+/** Destructively modifies data and size.
+ * Caller must pre-allocate space for data.
+ * Use semanage_bool_calculate_serialized_size(). */
+hidden int semanage_bool_serialize(semanage_handle_t * handle,
+ const semanage_bool_t * boolean,
+ char **data, uint64_t * size)
+{
+ return sepol_bool_serialize(handle->sepolh, boolean, data, size);
+}
+
+/** Destructively modifies boolean, data and size.
+ * Allocates space for boolean.
+ * Caller must free. */
+hidden int semanage_bool_unserialize(semanage_handle_t * handle,
+ char **data, uint64_t * size,
+ semanage_bool_t ** boolean)
+{
+ return sepol_bool_unserialize(handle->sepolh, data, size, boolean);
+}
+
/* Record base functions */
record_table_t SEMANAGE_BOOL_RTABLE = {
.create = semanage_bool_create,
@@ -143,4 +187,6 @@ record_table_t SEMANAGE_BOOL_RTABLE = {
.compare2 = semanage_bool_compare2,
.compare2_qsort = semanage_bool_compare2_qsort,
.free = semanage_bool_free,
+ .serialize = semanage_bool_serialize,
+ .unserialize = semanage_bool_unserialize,
};
Index: selinux-pms-support/libsemanage/src/booleans_active.c
===================================================================
--- selinux-pms-support.orig/libsemanage/src/booleans_active.c
+++ selinux-pms-support/libsemanage/src/booleans_active.c
@@ -60,3 +60,19 @@ int semanage_bool_list_active(semanage_h
dbase_config_t *dconfig = semanage_bool_dbase_active(handle);
return dbase_list(handle, dconfig, records, count);
}
+
+int semanage_bool_serialize_active(semanage_handle_t * handle,
+ char **data, uint64_t * data_length)
+{
+
+ dbase_config_t *dconfig = semanage_bool_dbase_active(handle);
+ return dbase_serialize(handle, dconfig, data, data_length);
+}
+
+int semanage_bool_unserialize_active(semanage_handle_t * handle,
+ char *data, uint64_t data_length)
+{
+
+ dbase_config_t *dconfig = semanage_bool_dbase_active(handle);
+ return dbase_unserialize(handle, dconfig, data, data_length);
+}
Index: selinux-pms-support/libsemanage/src/booleans_local.c
===================================================================
--- selinux-pms-support.orig/libsemanage/src/booleans_local.c
+++ selinux-pms-support/libsemanage/src/booleans_local.c
@@ -68,3 +68,19 @@ int semanage_bool_list_local(semanage_ha
dbase_config_t *dconfig = semanage_bool_dbase_local(handle);
return dbase_list(handle, dconfig, records, count);
}
+
+int semanage_bool_serialize_local(semanage_handle_t * handle,
+ char **data, uint64_t * data_length)
+{
+
+ dbase_config_t *dconfig = semanage_bool_dbase_local(handle);
+ return dbase_serialize(handle, dconfig, data, data_length);
+}
+
+int semanage_bool_unserialize_local(semanage_handle_t * handle,
+ char *data, uint64_t data_length)
+{
+
+ dbase_config_t *dconfig = semanage_bool_dbase_local(handle);
+ return dbase_unserialize(handle, dconfig, data, data_length);
+}
Index: selinux-pms-support/libsemanage/src/booleans_policy.c
===================================================================
--- selinux-pms-support.orig/libsemanage/src/booleans_policy.c
+++ selinux-pms-support/libsemanage/src/booleans_policy.c
@@ -50,3 +50,19 @@ int semanage_bool_list(semanage_handle_t
dbase_config_t *dconfig = semanage_bool_dbase_policy(handle);
return dbase_list(handle, dconfig, records, count);
}
+
+int semanage_bool_serialize_policy(semanage_handle_t * handle,
+ char **data, uint64_t * data_length)
+{
+
+ dbase_config_t *dconfig = semanage_bool_dbase_policy(handle);
+ return dbase_serialize(handle, dconfig, data, data_length);
+}
+
+int semanage_bool_unserialize_policy(semanage_handle_t * handle,
+ char *data, uint64_t data_length)
+{
+
+ dbase_config_t *dconfig = semanage_bool_dbase_policy(handle);
+ return dbase_unserialize(handle, dconfig, data, data_length);
+}
Index: selinux-pms-support/libsemanage/tests/libsemanage-tests.c
===================================================================
--- selinux-pms-support.orig/libsemanage/tests/libsemanage-tests.c
+++ selinux-pms-support/libsemanage/tests/libsemanage-tests.c
@@ -21,6 +21,8 @@
#include "test_semanage_store.h"
+#include "test_boolean_record.h"
+
#include <CUnit/Basic.h>
#include <CUnit/Console.h>
#include <CUnit/TestDB.h>
@@ -56,6 +58,8 @@ static int do_tests(int interactive, int
DECLARE_SUITE(semanage_store);
+ DECLARE_SUITE(boolean_record);
+
if (verbose)
CU_basic_set_mode(CU_BRM_VERBOSE);
else
Index: selinux-pms-support/libsemanage/tests/test_boolean_record.c
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/tests/test_boolean_record.c
@@ -0,0 +1,142 @@
+/* Authors: Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* The purpose of this file is to provide unit tests of the functions in:
+ *
+ * libsemanage/src/boolean_record.c
+ *
+ */
+
+#include "boolean_internal.h"
+#include "boolean_record.h"
+
+#include "globals.h"
+#include "utilities.h"
+#include "test_boolean_record.h"
+
+#include <libgen.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <CUnit/Basic.h>
+
+/* The suite initialization function.
+ * Returns zero on success, non-zero otherwise.
+ */
+int boolean_record_test_init(void)
+{
+ /* initialize the handle */
+ sh = semanage_handle_create();
+ if (sh == NULL)
+ return -1;
+
+ /* hide error messages */
+ sh->msg_callback = test_msg_handler;
+
+ return 0;
+}
+
+/* The suite cleanup function.
+ * Returns zero on success, non-zero otherwise.
+ */
+int boolean_record_test_cleanup(void)
+{
+ semanage_handle_destroy(sh);
+ return 0;
+}
+
+/* Adds all the tests needed for this suite.
+ */
+int boolean_record_add_tests(CU_pSuite suite)
+{
+ if (NULL ==
+ CU_add_test(suite, "semanage_bool_serialize",
+ test_semanage_bool_serialize)) {
+ CU_cleanup_registry();
+ return CU_get_error();
+ }
+
+ return 0;
+}
+
+/* Tests the semanage_boolean_serialize function in boolean_record.c
+ */
+void test_semanage_bool_serialize(void)
+{
+ int status;
+ char *data;
+ uint64_t data_length = 0;
+
+ /* serialize */
+
+ semanage_bool_t *boolean;
+ status = semanage_bool_create(sh, &boolean);
+
+ /* setup test fields */
+ const char *name = "testbool";
+ int value = 1;
+
+ status = semanage_bool_set_name(sh, boolean, name);
+ CU_ASSERT(status == 0);
+ semanage_bool_set_value(boolean, value);
+
+ /* set aside enough space... */
+ status = semanage_bool_serialize(sh, boolean, NULL, &data_length);
+ CU_ASSERT(status == 0);
+ data = calloc(data_length, sizeof(char));
+
+ char *data2;
+ data2 = data;
+ status = semanage_bool_serialize(sh, boolean, &data2, NULL);
+ CU_ASSERT(status == 0);
+ /* iterator/destructive effect check */
+ CU_ASSERT((unsigned)(data2 - data) == data_length);
+
+ /* unserialize */
+ semanage_bool_t *boolean2;
+ data2 = data;
+ uint64_t data_length2 = data_length;
+ status =
+ semanage_bool_unserialize(sh, &data2, &data_length2, &boolean2);
+ CU_ASSERT(status == 0);
+ /* iterator/destructive effect check */
+ CU_ASSERT((unsigned)(data2 - data) == data_length);
+
+ /* get results */
+ const char *name2;
+ int value2;
+
+ name2 = semanage_bool_get_name(boolean2);
+ value2 = semanage_bool_get_value(boolean2);
+
+ /* compare */
+ status = strcmp(name, name2);
+ CU_ASSERT(status == 0);
+
+ CU_ASSERT(value == value2);
+
+ /* cleanup */
+ semanage_bool_free(boolean);
+ semanage_bool_free(boolean2);
+ free(data);
+
+}
Index: selinux-pms-support/libsemanage/tests/test_boolean_record.h
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/tests/test_boolean_record.h
@@ -0,0 +1,32 @@
+/* Authors: Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __TEST_BOOLEAN_RECORD_H__
+#define __TEST_BOOLEAN_RECORD_H__
+
+#include <CUnit/Basic.h>
+
+int boolean_record_test_init(void);
+int boolean_record_test_cleanup(void);
+int boolean_record_add_tests(CU_pSuite suite);
+
+void test_semanage_bool_serialize(void);
+
+#endif
--
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH 15/33] libsemanage: context serialization
2007-04-23 21:34 [PATCH 00/33] libsemanage/libsepol object serialization and ps-api jbrindle
` (13 preceding siblings ...)
2007-04-23 21:35 ` [PATCH 14/33] libsemanage: boolean serialization jbrindle
@ 2007-04-23 21:35 ` jbrindle
2007-04-23 21:35 ` [PATCH 16/33] libsemanage: fcontext serialization jbrindle
` (19 subsequent siblings)
34 siblings, 0 replies; 58+ messages in thread
From: jbrindle @ 2007-04-23 21:35 UTC (permalink / raw)
To: selinux
---
libsemanage/src/context_internal.h | 38 +++++++
libsemanage/src/context_record.c | 48 +++++++++
libsemanage/tests/libsemanage-tests.c | 2
libsemanage/tests/test_context_record.c | 154 ++++++++++++++++++++++++++++++++
libsemanage/tests/test_context_record.h | 32 ++++++
5 files changed, 272 insertions(+), 2 deletions(-)
Index: selinux-pms-support/libsemanage/src/context_internal.h
===================================================================
--- selinux-pms-support.orig/libsemanage/src/context_internal.h
+++ selinux-pms-support/libsemanage/src/context_internal.h
@@ -1,6 +1,29 @@
+/* Authors: Ivan Gyurdiev <ivg2@cornell.edu>
+ * Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2005 Red Hat, Inc.
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
#ifndef _SEMANAGE_CONTEXT_INTERNAL_H_
#define _SEMANAGE_CONTEXT_INTERNAL_H_
+#include <inttypes.h>
#include <semanage/context_record.h>
#include "dso.h"
@@ -8,4 +31,19 @@ hidden_proto(semanage_context_clone)
hidden_proto(semanage_context_free)
hidden_proto(semanage_context_from_string)
hidden_proto(semanage_context_to_string)
+
+/*======== Internal API: Serialize/Unserialize ========== */
+hidden int semanage_context_calculate_serialized_size(semanage_handle_t *
+ handle,
+ const semanage_context_t *
+ context, uint64_t * size);
+
+hidden int semanage_context_serialize(semanage_handle_t * handle,
+ const semanage_context_t * context,
+ char **data, uint64_t * size);
+
+hidden int semanage_context_unserialize(semanage_handle_t * handle,
+ char **data, uint64_t * size,
+ semanage_context_t ** context);
+
#endif
Index: selinux-pms-support/libsemanage/src/context_record.c
===================================================================
--- selinux-pms-support.orig/libsemanage/src/context_record.c
+++ selinux-pms-support/libsemanage/src/context_record.c
@@ -1,12 +1,35 @@
-/* Copyright (C) 2005 Red Hat, Inc. */
+/* Authors: Ivan Gyurdiev <ivg2@cornell.edu>
+ * Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2005 Red Hat, Inc.
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <stdlib.h>
+#include <string.h>
#include <sepol/context_record.h>
-#include "handle.h"
typedef sepol_context_t semanage_context_t;
#define _SEMANAGE_CONTEXT_DEFINED_
#include "context_internal.h"
+#include "handle.h"
+#include "debug.h"
/* User */
const char *semanage_context_get_user(const semanage_context_t * con)
@@ -90,6 +113,27 @@ void semanage_context_free(semanage_cont
hidden_def(semanage_context_free)
+/* Serialize/Unserialize */
+/** Destructively modifies data and size.
+ * Caller must pre-allocate space for data.
+ * Use semanage_context_calculate_serialized_size(). */
+hidden int semanage_context_serialize(semanage_handle_t * handle,
+ const semanage_context_t * context,
+ char **data, uint64_t * size)
+{
+ return sepol_context_serialize(handle->sepolh, context, data, size);
+}
+
+/** Destructively modifies context, data and size.
+ * Allocates space for context.
+ * Caller must free. */
+hidden int semanage_context_unserialize(semanage_handle_t * handle,
+ char **data, uint64_t * size,
+ semanage_context_t ** context)
+{
+ return sepol_context_unserialize(handle->sepolh, data, size, context);
+}
+
/* Parse to/from string */
int semanage_context_from_string(semanage_handle_t * handle,
const char *str, semanage_context_t ** con)
Index: selinux-pms-support/libsemanage/tests/libsemanage-tests.c
===================================================================
--- selinux-pms-support.orig/libsemanage/tests/libsemanage-tests.c
+++ selinux-pms-support/libsemanage/tests/libsemanage-tests.c
@@ -22,6 +22,7 @@
#include "test_semanage_store.h"
#include "test_boolean_record.h"
+#include "test_context_record.h"
#include <CUnit/Basic.h>
#include <CUnit/Console.h>
@@ -59,6 +60,7 @@ static int do_tests(int interactive, int
DECLARE_SUITE(semanage_store);
DECLARE_SUITE(boolean_record);
+ DECLARE_SUITE(context_record);
if (verbose)
CU_basic_set_mode(CU_BRM_VERBOSE);
Index: selinux-pms-support/libsemanage/tests/test_context_record.c
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/tests/test_context_record.c
@@ -0,0 +1,154 @@
+/* Authors: Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* The purpose of this file is to provide unit tests of the functions in:
+ *
+ * libsemanage/src/semanage_store.c
+ *
+ */
+
+#include "context_internal.h"
+#include "context_record.h"
+
+#include "globals.h"
+#include "utilities.h"
+#include "test_context_record.h"
+
+#include <libgen.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <CUnit/Basic.h>
+
+/* The suite initialization function.
+ * Returns zero on success, non-zero otherwise.
+ */
+int context_record_test_init(void)
+{
+ /* initialize the handle */
+ sh = semanage_handle_create();
+ if (sh == NULL)
+ return -1;
+
+ /* hide error messages */
+ sh->msg_callback = test_msg_handler;
+
+ return 0;
+}
+
+/* The suite cleanup function.
+ * Returns zero on success, non-zero otherwise.
+ */
+int context_record_test_cleanup(void)
+{
+ semanage_handle_destroy(sh);
+ return 0;
+}
+
+/* Adds all the tests needed for this suite.
+ */
+int context_record_add_tests(CU_pSuite suite)
+{
+ if (NULL ==
+ CU_add_test(suite, "semanage_context_serialize",
+ test_semanage_context_serialize)) {
+ CU_cleanup_registry();
+ return CU_get_error();
+ }
+
+ return 0;
+}
+
+/* Tests the semanage_context_serialize function in context_record.c
+ */
+void test_semanage_context_serialize(void)
+{
+ int status;
+ char *data;
+ uint64_t data_length = 0;
+
+ /* serialize */
+
+ semanage_context_t *context;
+ status = semanage_context_create(sh, &context);
+
+ /* setup test fields */
+ const char *user = "testuser";
+ const char *role = "testrole";
+ const char *type = "testtype";
+
+ status = semanage_context_set_user(sh, context, user);
+ CU_ASSERT(status == 0);
+ status = semanage_context_set_role(sh, context, role);
+ CU_ASSERT(status == 0);
+ status = semanage_context_set_type(sh, context, type);
+ CU_ASSERT(status == 0);
+
+ /* set aside enough space... */
+ status = semanage_context_serialize(sh, context, NULL, &data_length);
+ CU_ASSERT(status == 0);
+ data = calloc(data_length, sizeof(char));
+
+ char *data2;
+ data2 = data;
+ status = semanage_context_serialize(sh, context, &data2, NULL);
+ CU_ASSERT(status == 0);
+ /* iterator/destructive effect check */
+ CU_ASSERT((unsigned)(data2 - data) == data_length);
+
+ /* unserialize */
+ semanage_context_t *context2;
+ data2 = data;
+ uint64_t data_length2 = data_length;
+ status =
+ semanage_context_unserialize(sh, &data2, &data_length2, &context2);
+ CU_ASSERT(status == 0);
+ /* iterator/destructive effect check */
+ CU_ASSERT((unsigned)(data2 - data) == data_length);
+ /* unserialize should create space */
+ CU_ASSERT(context2 != NULL);
+
+ /* get results */
+ const char *user2;
+ const char *role2;
+ const char *type2;
+
+ user2 = semanage_context_get_user(context2);
+ role2 = semanage_context_get_role(context2);
+ type2 = semanage_context_get_type(context2);
+
+ /* compare */
+ status = strcmp(user, user2);
+ CU_ASSERT(status == 0);
+
+ status = strcmp(role, role2);
+ CU_ASSERT(status == 0);
+
+ status = strcmp(type, type2);
+ CU_ASSERT(status == 0);
+
+ /* cleanup */
+ semanage_context_free(context);
+ semanage_context_free(context2);
+ free(data);
+
+}
Index: selinux-pms-support/libsemanage/tests/test_context_record.h
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/tests/test_context_record.h
@@ -0,0 +1,32 @@
+/* Authors: Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __TEST_CONTEXT_RECORD_H__
+#define __TEST_CONTEXT_RECORD_H__
+
+#include <CUnit/Basic.h>
+
+int context_record_test_init(void);
+int context_record_test_cleanup(void);
+int context_record_add_tests(CU_pSuite suite);
+
+void test_semanage_context_serialize(void);
+
+#endif
--
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH 16/33] libsemanage: fcontext serialization
2007-04-23 21:34 [PATCH 00/33] libsemanage/libsepol object serialization and ps-api jbrindle
` (14 preceding siblings ...)
2007-04-23 21:35 ` [PATCH 15/33] libsemanage: context serialization jbrindle
@ 2007-04-23 21:35 ` jbrindle
2007-04-23 21:35 ` [PATCH 17/33] libsemanage: interface serialization jbrindle
` (18 subsequent siblings)
34 siblings, 0 replies; 58+ messages in thread
From: jbrindle @ 2007-04-23 21:35 UTC (permalink / raw)
To: selinux
---
libsemanage/include/semanage/fcontexts_local.h | 30 ++++
libsemanage/include/semanage/fcontexts_policy.h | 8 +
libsemanage/src/fcontext_internal.h | 46 ++++++
libsemanage/src/fcontext_record.c | 164 +++++++++++++++++++++++
libsemanage/src/fcontexts_local.c | 37 +++++
libsemanage/src/fcontexts_policy.c | 16 ++
libsemanage/tests/libsemanage-tests.c | 2
libsemanage/tests/test_fcontext_record.c | 171 ++++++++++++++++++++++++
libsemanage/tests/test_fcontext_record.h | 32 ++++
9 files changed, 503 insertions(+), 3 deletions(-)
Index: selinux-pms-support/libsemanage/include/semanage/fcontexts_local.h
===================================================================
--- selinux-pms-support.orig/libsemanage/include/semanage/fcontexts_local.h
+++ selinux-pms-support/libsemanage/include/semanage/fcontexts_local.h
@@ -1,8 +1,28 @@
-/* Copyright (C) 2005 Red Hat, Inc. */
+/* Authors: Ivan Gyurdiev <ivg2@cornell.edu>
+ * Christopher Ashworth <cashworth@tresys.com>
+ *
+ * Copyright (C) 2005 Red Hat, Inc.
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
#ifndef _SEMANAGE_FCONTEXTS_LOCAL_H_
#define _SEMANAGE_FCONTEXTS_LOCAL_H_
+#include <inttypes.h>
#include <semanage/fcontext_record.h>
#include <semanage/handle.h>
@@ -34,4 +54,12 @@ extern int semanage_fcontext_list_local(
semanage_fcontext_t *** records,
unsigned int *count);
+extern int semanage_fcontext_serialize_local(semanage_handle_t * handle,
+ char **data,
+ uint64_t * data_length);
+
+extern int semanage_fcontext_unserialize_local(semanage_handle_t * handle,
+ char *data,
+ uint64_t data_length);
+
#endif
Index: selinux-pms-support/libsemanage/include/semanage/fcontexts_policy.h
===================================================================
--- selinux-pms-support.orig/libsemanage/include/semanage/fcontexts_policy.h
+++ selinux-pms-support/libsemanage/include/semanage/fcontexts_policy.h
@@ -26,4 +26,12 @@ extern int semanage_fcontext_list(semana
semanage_fcontext_t *** records,
unsigned int *count);
+extern int semanage_fcontext_serialize_policy(semanage_handle_t * handle,
+ char **data,
+ uint64_t * data_length);
+
+extern int semanage_fcontext_unserialize_policy(semanage_handle_t * handle,
+ char *data,
+ uint64_t data_length);
+
#endif
Index: selinux-pms-support/libsemanage/src/fcontext_internal.h
===================================================================
--- selinux-pms-support.orig/libsemanage/src/fcontext_internal.h
+++ selinux-pms-support/libsemanage/src/fcontext_internal.h
@@ -1,6 +1,29 @@
+/* Authors: Ivan Gyurdiev <ivg2@cornell.edu>
+ * Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2005 Red Hat, Inc.
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
#ifndef _SEMANAGE_FCONTEXT_INTERNAL_H_
#define _SEMANAGE_FCONTEXT_INTERNAL_H_
+#include <inttypes.h>
#include <semanage/fcontext_record.h>
#include <semanage/fcontexts_local.h>
#include <semanage/fcontexts_policy.h>
@@ -26,7 +49,7 @@ hidden_proto(semanage_fcontext_key_creat
hidden_proto(semanage_fcontext_free)
hidden_proto(semanage_fcontext_iterate_local)
-/* FCONTEXT RECORD: metod table */
+/* FCONTEXT RECORD: method table */
extern record_table_t SEMANAGE_FCONTEXT_RTABLE;
extern int fcontext_file_dbase_init(semanage_handle_t * handle,
@@ -35,8 +58,29 @@ extern int fcontext_file_dbase_init(sema
extern void fcontext_file_dbase_release(dbase_config_t * dconfig);
+extern int fcontext_ps_local_dbase_init(semanage_handle_t * handle,
+ uint32_t sandbox_id,
+ dbase_config_t * dconfig);
+
+extern void fcontext_ps_local_dbase_release(dbase_config_t * dconfig);
+
extern int hidden semanage_fcontext_validate_local(semanage_handle_t * handle,
const sepol_policydb_t *
policydb);
+/*======== Internal API: Serialize/Unserialize ========== */
+hidden int semanage_fcontext_calculate_serialized_size(semanage_handle_t *
+ handle,
+ const semanage_fcontext_t
+ * fcontext,
+ uint64_t * size);
+
+hidden int semanage_fcontext_serialize(semanage_handle_t * handle,
+ const semanage_fcontext_t * fcontext,
+ char **data, uint64_t * size);
+
+hidden int semanage_fcontext_unserialize(semanage_handle_t * handle,
+ char **data, uint64_t * size,
+ semanage_fcontext_t ** fcontext);
+
#endif
Index: selinux-pms-support/libsemanage/src/fcontext_record.c
===================================================================
--- selinux-pms-support.orig/libsemanage/src/fcontext_record.c
+++ selinux-pms-support/libsemanage/src/fcontext_record.c
@@ -1,14 +1,38 @@
+/* Authors: Ivan Gyurdiev <ivg2@cornell.edu>
+ * Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2005 Red Hat, Inc.
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
struct semanage_fcontext;
struct semanage_fcontext_key;
typedef struct semanage_fcontext record_t;
typedef struct semanage_fcontext_key record_key_t;
#define DBASE_RECORD_DEFINED
+#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "fcontext_internal.h"
#include "context_internal.h"
#include "debug.h"
+#include "serialize.h"
struct semanage_fcontext {
@@ -298,6 +322,144 @@ void semanage_fcontext_free(semanage_fco
hidden_def(semanage_fcontext_free)
+/* Serialize/Unserialize */
+/** Destructively modifies data and size.
+ * Caller must pre-allocate space for data.
+ * Use semanage_fcontext_calculate_serialized_size(). */
+hidden int semanage_fcontext_serialize(semanage_handle_t * handle,
+ const semanage_fcontext_t * fcontext,
+ char **data, uint64_t * size)
+{
+ int status = STATUS_SUCCESS;
+ const char *expr;
+ int32_t type;
+ semanage_context_t *con;
+ int32_t flag;
+
+ /* Sundry sanity checks. */
+ assert(handle != NULL && fcontext != NULL);
+
+ /* Fcontext regex. */
+ expr = semanage_fcontext_get_expr(fcontext);
+ status =
+ semanage_serialize(handle,
+ expr,
+ (expr == NULL) ? 0 : strlen(expr),
+ SEMANAGE_SERIAL_STRING, data, size);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Fcontext type. */
+ type = semanage_fcontext_get_type(fcontext);
+ status =
+ semanage_serialize(handle, &type, 0, SEMANAGE_SERIAL_INT32_T, data, size);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Fcontext context. */
+ con = semanage_fcontext_get_con(fcontext);
+ flag = (con == NULL) ? 0 : 1;
+ status = semanage_serialize(
+ handle,
+ &flag,
+ 0,
+ SEMANAGE_SERIAL_INT32_T,
+ data,
+ size);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ if (flag == 1) {
+ status =
+ semanage_context_serialize(handle,
+ semanage_fcontext_get_con(fcontext),
+ data, size);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+ }
+
+ /* Cleanup. */
+ cleanup:
+ return status;
+}
+
+/** Destructively modifies fcontext, data and size.
+ * Allocates space for fcontext.
+ * Caller must free. */
+hidden int semanage_fcontext_unserialize(semanage_handle_t * handle,
+ char **data, uint64_t * size,
+ semanage_fcontext_t ** fcontext)
+{
+ int status = STATUS_SUCCESS;
+ char *expr = NULL;
+ size_t *expr_size = NULL;
+ int32_t *type = NULL;
+ semanage_context_t *context = NULL;
+ int32_t *flag = NULL;
+
+ /* Sundry sanity checks. */
+ assert(handle != NULL && data != NULL && *data != NULL && size != NULL);
+
+ /* Allocate space. */
+ status = semanage_fcontext_create(handle, fcontext);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Fcontext regex. */
+ status =
+ semanage_unserialize(handle,
+ data, size,
+ (void **)&expr,
+ &expr_size, SEMANAGE_SERIAL_STRING);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+ if (expr != NULL) {
+ status = semanage_fcontext_set_expr(handle, *fcontext, expr);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+ }
+
+ /* Fcontext type. */
+ status =
+ semanage_unserialize(handle,
+ data, size,
+ (void **)&type,
+ NULL, SEMANAGE_SERIAL_INT32_T);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+ semanage_fcontext_set_type(*fcontext, *type);
+
+ /* Fcontext context. */
+ status = semanage_unserialize(
+ handle,
+ data,
+ size,
+ (void **)&flag,
+ NULL,
+ SEMANAGE_SERIAL_INT32_T);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ if (*flag == 1) {
+ status = semanage_context_unserialize(handle, data, size, &context);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+ /* Note that semanage_*_set* calls typically create space. */
+ status = semanage_fcontext_set_con(handle, *fcontext, context);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+ }
+
+ /* Cleanup. */
+ cleanup:
+ free(expr);
+ free(expr_size);
+ free(type);
+ semanage_context_free(context);
+ free(flag);
+ return status;
+}
+
/* Record base functions */
record_table_t SEMANAGE_FCONTEXT_RTABLE = {
.create = semanage_fcontext_create,
@@ -307,5 +469,7 @@ record_table_t SEMANAGE_FCONTEXT_RTABLE
.compare = semanage_fcontext_compare,
.compare2 = semanage_fcontext_compare2,
.compare2_qsort = semanage_fcontext_compare2_qsort,
+ .serialize = semanage_fcontext_serialize,
+ .unserialize = semanage_fcontext_unserialize,
.free = semanage_fcontext_free,
};
Index: selinux-pms-support/libsemanage/src/fcontexts_local.c
===================================================================
--- selinux-pms-support.orig/libsemanage/src/fcontexts_local.c
+++ selinux-pms-support/libsemanage/src/fcontexts_local.c
@@ -1,4 +1,23 @@
-/* Copyright (C) 2005 Red Hat, Inc. */
+/* Authors: Ivan Gyurdiev <ivg2@cornell.edu>
+ * Christopher Ashworth <cashworth@tresys.com>
+ *
+ * Copyright (C) 2005 Red Hat, Inc.
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
struct semanage_fcontext;
struct semanage_fcontext_key;
@@ -79,6 +98,22 @@ int semanage_fcontext_list_local(semanag
return dbase_list(handle, dconfig, records, count);
}
+int semanage_fcontext_serialize_local(semanage_handle_t * handle,
+ char **data, uint64_t * data_length)
+{
+
+ dbase_config_t *dconfig = semanage_fcontext_dbase_local(handle);
+ return dbase_serialize(handle, dconfig, data, data_length);
+}
+
+int semanage_fcontext_unserialize_local(semanage_handle_t * handle,
+ char *data, uint64_t data_length)
+{
+
+ dbase_config_t *dconfig = semanage_fcontext_dbase_local(handle);
+ return dbase_unserialize(handle, dconfig, data, data_length);
+}
+
struct validate_handler_arg {
semanage_handle_t *handle;
const sepol_policydb_t *policydb;
Index: selinux-pms-support/libsemanage/src/fcontexts_policy.c
===================================================================
--- selinux-pms-support.orig/libsemanage/src/fcontexts_policy.c
+++ selinux-pms-support/libsemanage/src/fcontexts_policy.c
@@ -51,3 +51,19 @@ int semanage_fcontext_list(semanage_hand
dbase_config_t *dconfig = semanage_fcontext_dbase_policy(handle);
return dbase_list(handle, dconfig, records, count);
}
+
+int semanage_fcontext_serialize_policy(semanage_handle_t * handle,
+ char **data, uint64_t * data_length)
+{
+
+ dbase_config_t *dconfig = semanage_fcontext_dbase_policy(handle);
+ return dbase_serialize(handle, dconfig, data, data_length);
+}
+
+int semanage_fcontext_unserialize_policy(semanage_handle_t * handle,
+ char *data, uint64_t data_length)
+{
+
+ dbase_config_t *dconfig = semanage_fcontext_dbase_policy(handle);
+ return dbase_unserialize(handle, dconfig, data, data_length);
+}
Index: selinux-pms-support/libsemanage/tests/libsemanage-tests.c
===================================================================
--- selinux-pms-support.orig/libsemanage/tests/libsemanage-tests.c
+++ selinux-pms-support/libsemanage/tests/libsemanage-tests.c
@@ -23,6 +23,7 @@
#include "test_boolean_record.h"
#include "test_context_record.h"
+#include "test_fcontext_record.h"
#include <CUnit/Basic.h>
#include <CUnit/Console.h>
@@ -61,6 +62,7 @@ static int do_tests(int interactive, int
DECLARE_SUITE(boolean_record);
DECLARE_SUITE(context_record);
+ DECLARE_SUITE(fcontext_record);
if (verbose)
CU_basic_set_mode(CU_BRM_VERBOSE);
Index: selinux-pms-support/libsemanage/tests/test_fcontext_record.c
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/tests/test_fcontext_record.c
@@ -0,0 +1,171 @@
+/* Authors: Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* The purpose of this file is to provide unit tests of the functions in:
+ *
+ * libsemanage/src/semanage_store.c
+ *
+ */
+
+#include "fcontext_internal.h"
+#include "fcontext_record.h"
+#include <sepol/context_record.h>
+
+#include "globals.h"
+#include "utilities.h"
+#include "test_fcontext_record.h"
+
+#include <libgen.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <CUnit/Basic.h>
+
+/* The suite initialization function.
+ * Returns zero on success, non-zero otherwise.
+ */
+int fcontext_record_test_init(void)
+{
+ /* initialize the handle */
+ sh = semanage_handle_create();
+ if (sh == NULL)
+ return -1;
+
+ /* hide error messages */
+ sh->msg_callback = test_msg_handler;
+
+ return 0;
+}
+
+/* The suite cleanup function.
+ * Returns zero on success, non-zero otherwise.
+ */
+int fcontext_record_test_cleanup(void)
+{
+ semanage_handle_destroy(sh);
+ return 0;
+}
+
+/* Adds all the tests needed for this suite.
+ */
+int fcontext_record_add_tests(CU_pSuite suite)
+{
+ if (NULL ==
+ CU_add_test(suite, "semanage_fcontext_serialize",
+ test_semanage_fcontext_serialize)) {
+ CU_cleanup_registry();
+ return CU_get_error();
+ }
+
+ return 0;
+}
+
+/* Tests the semanage_fcontext_serialize function in fcontext_record.c
+ */
+void test_semanage_fcontext_serialize(void)
+{
+ int status;
+ char *data;
+ uint64_t data_length = 0;
+
+ /* serialize */
+
+ semanage_fcontext_t *fcontext;
+ status = semanage_fcontext_create(sh, &fcontext);
+ semanage_context_t *context;
+ status = semanage_context_create(sh, &context);
+
+ /* setup test fields */
+ const char *user = "testuser";
+ const char *role = "testrole";
+ const char *type = "testtype";
+
+ status = semanage_context_set_user(sh, context, user);
+ CU_ASSERT(status == 0);
+ status = semanage_context_set_role(sh, context, role);
+ CU_ASSERT(status == 0);
+ status = semanage_context_set_type(sh, context, type);
+ CU_ASSERT(status == 0);
+ status = semanage_fcontext_set_con(sh, fcontext, context);
+ CU_ASSERT(status == 0);
+
+ const char *expr = "/testlocation/*";
+ status = semanage_fcontext_set_expr(sh, fcontext, expr);
+ CU_ASSERT(status == 0);
+
+ /* set aside enough space... */
+ status = semanage_fcontext_serialize(sh, fcontext, NULL, &data_length);
+ CU_ASSERT(status == 0);
+ data = calloc(data_length, sizeof(char));
+
+ char *data2;
+ data2 = data;
+ status = semanage_fcontext_serialize(sh, fcontext, &data2, NULL);
+ CU_ASSERT(status == 0);
+ /* iterator/destructive effect check */
+ CU_ASSERT((unsigned)(data2 - data) == data_length);
+
+ /* unserialize */
+ semanage_fcontext_t *fcontext2;
+ data2 = data;
+ uint64_t data_length2 = data_length;
+ status =
+ semanage_fcontext_unserialize(sh, &data2,
+ &data_length2, &fcontext2);
+ CU_ASSERT(status == 0);
+ /* iterator/destructive effect check */
+ CU_ASSERT((unsigned)(data2 - data) == data_length);
+
+ /* get results */
+ semanage_context_t *context2 = semanage_fcontext_get_con(fcontext2);
+ const char *user2;
+ const char *role2;
+ const char *type2;
+
+ user2 = semanage_context_get_user(context2);
+ role2 = semanage_context_get_role(context2);
+ type2 = semanage_context_get_type(context2);
+
+ const char *expr2;
+
+ expr2 = semanage_fcontext_get_expr(fcontext2);
+
+ /* compare */
+ status = strcmp(user, user2);
+ CU_ASSERT(status == 0);
+
+ status = strcmp(role, role2);
+ CU_ASSERT(status == 0);
+
+ status = strcmp(type, type2);
+ CU_ASSERT(status == 0);
+
+ status = strcmp(expr, expr2);
+ CU_ASSERT(status == 0);
+
+ /* cleanup */
+ semanage_fcontext_free(fcontext);
+ semanage_context_free(context);
+ semanage_fcontext_free(fcontext2);
+ free(data);
+
+}
Index: selinux-pms-support/libsemanage/tests/test_fcontext_record.h
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/tests/test_fcontext_record.h
@@ -0,0 +1,32 @@
+/* Authors: Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __TEST_FCONTEXT_RECORD_H__
+#define __TEST_FCONTEXT_RECORD_H__
+
+#include <CUnit/Basic.h>
+
+int fcontext_record_test_init(void);
+int fcontext_record_test_cleanup(void);
+int fcontext_record_add_tests(CU_pSuite suite);
+
+void test_semanage_fcontext_serialize(void);
+
+#endif
--
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH 17/33] libsemanage: interface serialization
2007-04-23 21:34 [PATCH 00/33] libsemanage/libsepol object serialization and ps-api jbrindle
` (15 preceding siblings ...)
2007-04-23 21:35 ` [PATCH 16/33] libsemanage: fcontext serialization jbrindle
@ 2007-04-23 21:35 ` jbrindle
2007-04-23 21:35 ` [PATCH 18/33] libsemanage: node serialization jbrindle
` (17 subsequent siblings)
34 siblings, 0 replies; 58+ messages in thread
From: jbrindle @ 2007-04-23 21:35 UTC (permalink / raw)
To: selinux
---
libsemanage/include/semanage/interfaces_local.h | 28 +++
libsemanage/include/semanage/interfaces_policy.h | 6
libsemanage/src/iface_internal.h | 49 ++++++
libsemanage/src/iface_record.c | 48 ++++++
libsemanage/src/interfaces_local.c | 16 ++
libsemanage/src/interfaces_policy.c | 16 ++
libsemanage/tests/libsemanage-tests.c | 2
libsemanage/tests/test_iface_record.c | 172 +++++++++++++++++++++++
libsemanage/tests/test_iface_record.h | 32 ++++
9 files changed, 367 insertions(+), 2 deletions(-)
Index: selinux-pms-support/libsemanage/include/semanage/interfaces_local.h
===================================================================
--- selinux-pms-support.orig/libsemanage/include/semanage/interfaces_local.h
+++ selinux-pms-support/libsemanage/include/semanage/interfaces_local.h
@@ -1,8 +1,28 @@
-/* Copyright (C) 2005 Red Hat, Inc. */
+/* Authors: Ivan Gyurdiev <ivg2@cornell.edu>
+ * Christopher Ashworth <cashworth@tresys.com>
+ *
+ * Copyright (C) 2005 Red Hat, Inc.
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
#ifndef _SEMANAGE_INTERFACES_LOCAL_H_
#define _SEMANAGE_INTERFACES_LOCAL_H_
+#include <inttypes.h>
#include <semanage/iface_record.h>
#include <semanage/handle.h>
@@ -33,4 +53,10 @@ extern int semanage_iface_list_local(sem
semanage_iface_t *** records,
unsigned int *count);
+extern int semanage_iface_serialize_local(semanage_handle_t * handle,
+ char **data, uint64_t * data_length);
+
+extern int semanage_iface_unserialize_local(semanage_handle_t * handle,
+ char *data, uint64_t data_length);
+
#endif
Index: selinux-pms-support/libsemanage/include/semanage/interfaces_policy.h
===================================================================
--- selinux-pms-support.orig/libsemanage/include/semanage/interfaces_policy.h
+++ selinux-pms-support/libsemanage/include/semanage/interfaces_policy.h
@@ -26,4 +26,10 @@ extern int semanage_iface_list(semanage_
semanage_iface_t *** records,
unsigned int *count);
+extern int semanage_iface_serialize_policy(semanage_handle_t * handle,
+ char **data, uint64_t * data_length);
+
+extern int semanage_iface_unserialize_policy(semanage_handle_t * handle,
+ char *data, uint64_t data_length);
+
#endif
Index: selinux-pms-support/libsemanage/src/iface_internal.h
===================================================================
--- selinux-pms-support.orig/libsemanage/src/iface_internal.h
+++ selinux-pms-support/libsemanage/src/iface_internal.h
@@ -1,10 +1,34 @@
+/* Authors: Ivan Gyurdiev <ivg2@cornell.edu>
+ * Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2005 Red Hat, Inc.
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
#ifndef _SEMANAGE_IFACE_INTERNAL_H_
#define _SEMANAGE_IFACE_INTERNAL_H_
+#include <inttypes.h>
#include <semanage/iface_record.h>
#include <semanage/interfaces_local.h>
#include <semanage/interfaces_policy.h>
#include "database.h"
+#include "database_policydb.h"
#include "handle.h"
#include "dso.h"
@@ -24,6 +48,7 @@ hidden_proto(semanage_iface_create)
/* IFACE RECORD: metod table */
extern record_table_t SEMANAGE_IFACE_RTABLE;
+extern record_policydb_table_t SEMANAGE_IFACE_POLICYDB_RTABLE;
extern int iface_policydb_dbase_init(semanage_handle_t * handle,
dbase_config_t * dconfig);
@@ -35,4 +60,28 @@ extern int iface_file_dbase_init(semanag
extern void iface_file_dbase_release(dbase_config_t * dconfig);
+extern int iface_ps_local_dbase_init(semanage_handle_t * handle,
+ uint32_t sandbox_id, dbase_config_t * dconfig);
+
+extern void iface_ps_local_dbase_release(dbase_config_t * dconfig);
+
+extern int iface_ps_policydb_dbase_init(semanage_handle_t * handle,
+ uint32_t sandbox_id,
+ dbase_config_t * dconfig);
+
+extern void iface_ps_policydb_dbase_release(dbase_config_t * dconfig);
+
+/*======== Internal API: Serialize/Unserialize ========== */
+hidden int semanage_iface_calculate_serialized_size(semanage_handle_t * handle,
+ const semanage_iface_t *
+ iface, uint64_t * size);
+
+hidden int semanage_iface_serialize(semanage_handle_t * handle,
+ const semanage_iface_t * iface,
+ char **data, uint64_t * size);
+
+hidden int semanage_iface_unserialize(semanage_handle_t * handle,
+ char **data, uint64_t * size,
+ semanage_iface_t ** iface);
+
#endif
Index: selinux-pms-support/libsemanage/src/iface_record.c
===================================================================
--- selinux-pms-support.orig/libsemanage/src/iface_record.c
+++ selinux-pms-support/libsemanage/src/iface_record.c
@@ -1,4 +1,24 @@
-/* Copyright (C) 2005 Red Hat, Inc. */
+/* Authors: Ivan Gyurdiev <ivg2@cornell.edu>
+ * Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2005 Red Hat, Inc.
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
/* Object: semanage_iface_t (Network Interface)
* Object: semanage_iface_key_t (Network Interface Key)
@@ -19,9 +39,12 @@ typedef sepol_iface_t record_t;
typedef sepol_iface_key_t record_key_t;
#define DBASE_RECORD_DEFINED
+#include <stdlib.h>
+#include <string.h>
#include "iface_internal.h"
#include "handle.h"
#include "database.h"
+#include "debug.h"
/* Key */
int semanage_iface_compare(const semanage_iface_t * iface,
@@ -156,6 +179,27 @@ void semanage_iface_free(semanage_iface_
hidden_def(semanage_iface_free)
+/* Serialize/Unserialize */
+/** Destructively modifies data and size.
+ * Caller must pre-allocate space for data.
+ * Use semanage_iface_calculate_serialized_size(). */
+hidden int semanage_iface_serialize(semanage_handle_t * handle,
+ const semanage_iface_t * iface,
+ char **data, uint64_t * size)
+{
+ return sepol_iface_serialize(handle->sepolh, iface, data, size);
+}
+
+/** Destructively modifies iface, data and size.
+ * Allocates space for iface.
+ * Caller must free. */
+hidden int semanage_iface_unserialize(semanage_handle_t * handle,
+ char **data, uint64_t * size,
+ semanage_iface_t ** iface)
+{
+ return sepol_iface_unserialize(handle->sepolh, data, size, iface);
+}
+
/* Record base functions */
record_table_t SEMANAGE_IFACE_RTABLE = {
.create = semanage_iface_create,
@@ -166,4 +210,6 @@ record_table_t SEMANAGE_IFACE_RTABLE = {
.compare2 = semanage_iface_compare2,
.compare2_qsort = semanage_iface_compare2_qsort,
.free = semanage_iface_free,
+ .serialize = semanage_iface_serialize,
+ .unserialize = semanage_iface_unserialize,
};
Index: selinux-pms-support/libsemanage/src/interfaces_local.c
===================================================================
--- selinux-pms-support.orig/libsemanage/src/interfaces_local.c
+++ selinux-pms-support/libsemanage/src/interfaces_local.c
@@ -69,3 +69,19 @@ int semanage_iface_list_local(semanage_h
dbase_config_t *dconfig = semanage_iface_dbase_local(handle);
return dbase_list(handle, dconfig, records, count);
}
+
+int semanage_iface_serialize_local(semanage_handle_t * handle,
+ char **data, uint64_t * data_length)
+{
+
+ dbase_config_t *dconfig = semanage_iface_dbase_local(handle);
+ return dbase_serialize(handle, dconfig, data, data_length);
+}
+
+int semanage_iface_unserialize_local(semanage_handle_t * handle,
+ char *data, uint64_t data_length)
+{
+
+ dbase_config_t *dconfig = semanage_iface_dbase_local(handle);
+ return dbase_unserialize(handle, dconfig, data, data_length);
+}
Index: selinux-pms-support/libsemanage/src/interfaces_policy.c
===================================================================
--- selinux-pms-support.orig/libsemanage/src/interfaces_policy.c
+++ selinux-pms-support/libsemanage/src/interfaces_policy.c
@@ -50,3 +50,19 @@ int semanage_iface_list(semanage_handle_
dbase_config_t *dconfig = semanage_iface_dbase_policy(handle);
return dbase_list(handle, dconfig, records, count);
}
+
+int semanage_iface_serialize_policy(semanage_handle_t * handle,
+ char **data, uint64_t * data_length)
+{
+
+ dbase_config_t *dconfig = semanage_iface_dbase_policy(handle);
+ return dbase_serialize(handle, dconfig, data, data_length);
+}
+
+int semanage_iface_unserialize_policy(semanage_handle_t * handle,
+ char *data, uint64_t data_length)
+{
+
+ dbase_config_t *dconfig = semanage_iface_dbase_policy(handle);
+ return dbase_unserialize(handle, dconfig, data, data_length);
+}
Index: selinux-pms-support/libsemanage/tests/libsemanage-tests.c
===================================================================
--- selinux-pms-support.orig/libsemanage/tests/libsemanage-tests.c
+++ selinux-pms-support/libsemanage/tests/libsemanage-tests.c
@@ -24,6 +24,7 @@
#include "test_boolean_record.h"
#include "test_context_record.h"
#include "test_fcontext_record.h"
+#include "test_iface_record.h"
#include <CUnit/Basic.h>
#include <CUnit/Console.h>
@@ -63,6 +64,7 @@ static int do_tests(int interactive, int
DECLARE_SUITE(boolean_record);
DECLARE_SUITE(context_record);
DECLARE_SUITE(fcontext_record);
+ DECLARE_SUITE(iface_record);
if (verbose)
CU_basic_set_mode(CU_BRM_VERBOSE);
Index: selinux-pms-support/libsemanage/tests/test_iface_record.c
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/tests/test_iface_record.c
@@ -0,0 +1,172 @@
+/* Authors: Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* The purpose of this file is to provide unit tests of the functions in:
+ *
+ * libsemanage/src/semanage_store.c
+ *
+ */
+
+#include "iface_internal.h"
+#include "iface_record.h"
+#include <sepol/context_record.h>
+
+#include "globals.h"
+#include "utilities.h"
+#include "test_iface_record.h"
+
+#include <libgen.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <CUnit/Basic.h>
+
+/* The suite initialization function.
+ * Returns zero on success, non-zero otherwise.
+ */
+int iface_record_test_init(void)
+{
+ /* initialize the handle */
+ sh = semanage_handle_create();
+ if (sh == NULL)
+ return -1;
+
+ /* hide error messages */
+ sh->msg_callback = test_msg_handler;
+
+ return 0;
+}
+
+/* The suite cleanup function.
+ * Returns zero on success, non-zero otherwise.
+ */
+int iface_record_test_cleanup(void)
+{
+ semanage_handle_destroy(sh);
+ return 0;
+}
+
+/* Adds all the tests needed for this suite.
+ */
+int iface_record_add_tests(CU_pSuite suite)
+{
+ if (NULL ==
+ CU_add_test(suite, "semanage_iface_serialize",
+ test_semanage_iface_serialize)) {
+ CU_cleanup_registry();
+ return CU_get_error();
+ }
+
+ return 0;
+}
+
+/* Tests the semanage_iface_serialize function in iface_record.c
+ */
+void test_semanage_iface_serialize(void)
+{
+ int status;
+ char *data;
+ uint64_t data_length = 0;
+
+ /* serialize */
+
+ semanage_iface_t *iface;
+ status = semanage_iface_create(sh, &iface);
+ semanage_context_t *ifcon;
+ semanage_context_t *msgcon;
+
+ /* setup test fields */
+ const char *name = "testname";
+ const char *ifcon_str = "iftestuser:iftestrole:iftesttype";
+ const char *msgcon_str = "msgtestuser:msgtestrole:msgtesttype";
+
+ status = semanage_iface_set_name(sh, iface, name);
+ CU_ASSERT(status == 0);
+
+ status = semanage_context_from_string(sh, ifcon_str, &ifcon);
+ CU_ASSERT(status == 0);
+ status = semanage_iface_set_ifcon(sh, iface, ifcon);
+ CU_ASSERT(status == 0);
+
+ status = semanage_context_from_string(sh, msgcon_str, &msgcon);
+ CU_ASSERT(status == 0);
+ status = semanage_iface_set_msgcon(sh, iface, msgcon);
+ CU_ASSERT(status == 0);
+
+ /* set aside enough space... */
+ status = semanage_iface_serialize(sh, iface, NULL, &data_length);
+ CU_ASSERT(status == 0);
+ data = calloc(data_length, sizeof(char));
+
+ char *data2;
+ data2 = data;
+ status = semanage_iface_serialize(sh, iface, &data2, NULL);
+ CU_ASSERT(status == 0);
+ /* iterator/destructive effect check */
+ CU_ASSERT((unsigned)(data2 - data) == data_length);
+
+ /* unserialize */
+ semanage_iface_t *iface2;
+ data2 = data;
+ uint64_t data_length2 = data_length;
+ status = semanage_iface_unserialize(sh, &data2, &data_length2, &iface2);
+ CU_ASSERT(status == 0);
+ /* iterator/destructive effect check */
+ CU_ASSERT((unsigned)(data2 - data) == data_length);
+
+ /* get results */
+ const char *name2;
+ const semanage_context_t *ifcon2;
+ const semanage_context_t *msgcon2;
+ char *ifcon_str2;
+ char *msgcon_str2;
+
+ name2 = semanage_iface_get_name(iface2);
+
+ ifcon2 = semanage_iface_get_ifcon(iface2);
+ status = semanage_context_to_string(sh, ifcon2, &ifcon_str2);
+ CU_ASSERT(status == 0);
+
+ msgcon2 = semanage_iface_get_msgcon(iface2);
+ status = semanage_context_to_string(sh, msgcon2, &msgcon_str2);
+ CU_ASSERT(status == 0);
+
+ /* compare */
+ status = strcmp(name, name2);
+ CU_ASSERT(status == 0);
+
+ status = strcmp(ifcon_str, ifcon_str2);
+ CU_ASSERT(status == 0);
+
+ status = strcmp(msgcon_str, msgcon_str2);
+ CU_ASSERT(status == 0);
+
+ /* cleanup */
+ semanage_iface_free(iface);
+ semanage_iface_free(iface2);
+ semanage_context_free(ifcon);
+ semanage_context_free(msgcon);
+ free(ifcon_str2);
+ free(msgcon_str2);
+ free(data);
+
+}
Index: selinux-pms-support/libsemanage/tests/test_iface_record.h
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/tests/test_iface_record.h
@@ -0,0 +1,32 @@
+/* Authors: Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __TEST_IFACE_RECORD_H__
+#define __TEST_IFACE_RECORD_H__
+
+#include <CUnit/Basic.h>
+
+int iface_record_test_init(void);
+int iface_record_test_cleanup(void);
+int iface_record_add_tests(CU_pSuite suite);
+
+void test_semanage_iface_serialize(void);
+
+#endif
--
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH 18/33] libsemanage: node serialization
2007-04-23 21:34 [PATCH 00/33] libsemanage/libsepol object serialization and ps-api jbrindle
` (16 preceding siblings ...)
2007-04-23 21:35 ` [PATCH 17/33] libsemanage: interface serialization jbrindle
@ 2007-04-23 21:35 ` jbrindle
2007-04-23 21:35 ` [PATCH 19/33] libsemanage: port serialization jbrindle
` (16 subsequent siblings)
34 siblings, 0 replies; 58+ messages in thread
From: jbrindle @ 2007-04-23 21:35 UTC (permalink / raw)
To: selinux
---
libsemanage/include/semanage/nodes_local.h | 28 ++++
libsemanage/include/semanage/nodes_policy.h | 6
libsemanage/src/node_internal.h | 49 +++++++
libsemanage/src/node_record.c | 48 +++++++
libsemanage/src/nodes_local.c | 16 ++
libsemanage/src/nodes_policy.c | 16 ++
libsemanage/tests/libsemanage-tests.c | 2
libsemanage/tests/test_node_record.c | 173 ++++++++++++++++++++++++++++
libsemanage/tests/test_node_record.h | 32 +++++
9 files changed, 368 insertions(+), 2 deletions(-)
Index: selinux-pms-support/libsemanage/include/semanage/nodes_local.h
===================================================================
--- selinux-pms-support.orig/libsemanage/include/semanage/nodes_local.h
+++ selinux-pms-support/libsemanage/include/semanage/nodes_local.h
@@ -1,8 +1,28 @@
-/* Copyright (C) 2005 Red Hat, Inc. */
+/* Authors: Ivan Gyurdiev <ivg2@cornell.edu>
+ * Christopher Ashworth <cashworth@tresys.com>
+ *
+ * Copyright (C) 2005 Red Hat, Inc.
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
#ifndef _SEMANAGE_NODES_LOCAL_H_
#define _SEMANAGE_NODES_LOCAL_H_
+#include <inttypes.h>
#include <semanage/node_record.h>
#include <semanage/handle.h>
@@ -33,4 +53,10 @@ extern int semanage_node_list_local(sema
semanage_node_t *** records,
unsigned int *count);
+extern int semanage_node_serialize_local(semanage_handle_t * handle,
+ char **data, uint64_t * data_length);
+
+extern int semanage_node_unserialize_local(semanage_handle_t * handle,
+ char *data, uint64_t data_length);
+
#endif
Index: selinux-pms-support/libsemanage/include/semanage/nodes_policy.h
===================================================================
--- selinux-pms-support.orig/libsemanage/include/semanage/nodes_policy.h
+++ selinux-pms-support/libsemanage/include/semanage/nodes_policy.h
@@ -24,4 +24,10 @@ extern int semanage_node_iterate(semanag
extern int semanage_node_list(semanage_handle_t * handle,
semanage_node_t *** records, unsigned int *count);
+extern int semanage_node_serialize_policy(semanage_handle_t * handle,
+ char **data, uint64_t * data_length);
+
+extern int semanage_node_unserialize_policy(semanage_handle_t * handle,
+ char *data, uint64_t data_length);
+
#endif
Index: selinux-pms-support/libsemanage/src/node_internal.h
===================================================================
--- selinux-pms-support.orig/libsemanage/src/node_internal.h
+++ selinux-pms-support/libsemanage/src/node_internal.h
@@ -1,10 +1,34 @@
+/* Authors: Ivan Gyurdiev <ivg2@cornell.edu>
+ * Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2005 Red Hat, Inc.
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
#ifndef _SEMANAGE_NODE_INTERNAL_H_
#define _SEMANAGE_NODE_INTERNAL_H_
+#include <inttypes.h>
#include <semanage/node_record.h>
#include <semanage/nodes_local.h>
#include <semanage/nodes_policy.h>
#include "database.h"
+#include "database_policydb.h"
#include "handle.h"
#include "dso.h"
@@ -32,6 +56,7 @@ hidden_proto(semanage_node_create)
/* NODE RECORD: method table */
extern record_table_t SEMANAGE_NODE_RTABLE;
+extern record_policydb_table_t SEMANAGE_NODE_POLICYDB_RTABLE;
extern int node_file_dbase_init(semanage_handle_t * handle,
const char *fname, dbase_config_t * dconfig);
@@ -43,6 +68,17 @@ extern int node_policydb_dbase_init(sema
extern void node_policydb_dbase_release(dbase_config_t * dconfig);
+extern int node_ps_local_dbase_init(semanage_handle_t * handle,
+ uint32_t sandbox_id, dbase_config_t * dconfig);
+
+extern void node_ps_local_dbase_release(dbase_config_t * dconfig);
+
+extern int node_ps_policydb_dbase_init(semanage_handle_t * handle,
+ uint32_t sandbox_id,
+ dbase_config_t * dconfig);
+
+extern void node_ps_policydb_dbase_release(dbase_config_t * dconfig);
+
extern int hidden semanage_node_validate_local(semanage_handle_t * handle);
/* ==== Internal (to nodes) API === */
@@ -50,4 +86,17 @@ extern int hidden semanage_node_validate
hidden int semanage_node_compare2_qsort(const semanage_node_t ** node,
const semanage_node_t ** node2);
+/*======== Internal API: Serialize/Unserialize ========== */
+hidden int semanage_node_calculate_serialized_size(semanage_handle_t * handle,
+ const semanage_node_t * node,
+ uint64_t * size);
+
+hidden int semanage_node_serialize(semanage_handle_t * handle,
+ const semanage_node_t * node,
+ char **data, uint64_t * size);
+
+hidden int semanage_node_unserialize(semanage_handle_t * handle,
+ char **data, uint64_t * size,
+ semanage_node_t ** node);
+
#endif
Index: selinux-pms-support/libsemanage/src/node_record.c
===================================================================
--- selinux-pms-support.orig/libsemanage/src/node_record.c
+++ selinux-pms-support/libsemanage/src/node_record.c
@@ -1,4 +1,24 @@
-/* Copyright (C) 2005 Red Hat, Inc. */
+/* Authors: Ivan Gyurdiev <ivg2@cornell.edu>
+ * Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2005 Red Hat, Inc.
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
/* Object: semanage_node_t (Network Port)
* Object: semanage_node_key_t (Network Port Key)
@@ -6,6 +26,8 @@
* Implements: record_key_t (Database Record Key)
*/
+#include <stdlib.h>
+#include <string.h>
#include <sepol/context_record.h>
#include <sepol/node_record.h>
#include <stddef.h>
@@ -23,6 +45,7 @@ typedef semanage_node_key_t record_key_t
#include "node_internal.h"
#include "handle.h"
#include "database.h"
+#include "debug.h"
/* Key */
int semanage_node_compare(const semanage_node_t * node,
@@ -227,6 +250,27 @@ void semanage_node_free(semanage_node_t
hidden_def(semanage_node_free)
+/* Serialize/Unserialize */
+/** Destructively modifies data and size.
+ * Caller must pre-allocate space for data.
+ * Use semanage_node_calculate_serialized_size(). */
+hidden int semanage_node_serialize(semanage_handle_t * handle,
+ const semanage_node_t * node,
+ char **data, uint64_t * size)
+{
+ return sepol_node_serialize(handle->sepolh, node, data, size);
+}
+
+/** Destructively modifies node, data and size.
+ * Allocates space for node.
+ * Caller must free. */
+hidden int semanage_node_unserialize(semanage_handle_t * handle,
+ char **data, uint64_t * size,
+ semanage_node_t ** node)
+{
+ return sepol_node_unserialize(handle->sepolh, data, size, node);
+}
+
/* Port base functions */
record_table_t SEMANAGE_NODE_RTABLE = {
.create = semanage_node_create,
@@ -237,4 +281,6 @@ record_table_t SEMANAGE_NODE_RTABLE = {
.compare2 = semanage_node_compare2,
.compare2_qsort = semanage_node_compare2_qsort,
.free = semanage_node_free,
+ .serialize = semanage_node_serialize,
+ .unserialize = semanage_node_unserialize,
};
Index: selinux-pms-support/libsemanage/src/nodes_local.c
===================================================================
--- selinux-pms-support.orig/libsemanage/src/nodes_local.c
+++ selinux-pms-support/libsemanage/src/nodes_local.c
@@ -70,3 +70,19 @@ int semanage_node_list_local(semanage_ha
}
hidden_def(semanage_node_list_local)
+
+int semanage_node_serialize_local(semanage_handle_t * handle,
+ char **data, uint64_t * data_length)
+{
+
+ dbase_config_t *dconfig = semanage_node_dbase_local(handle);
+ return dbase_serialize(handle, dconfig, data, data_length);
+}
+
+int semanage_node_unserialize_local(semanage_handle_t * handle,
+ char *data, uint64_t data_length)
+{
+
+ dbase_config_t *dconfig = semanage_node_dbase_local(handle);
+ return dbase_unserialize(handle, dconfig, data, data_length);
+}
Index: selinux-pms-support/libsemanage/src/nodes_policy.c
===================================================================
--- selinux-pms-support.orig/libsemanage/src/nodes_policy.c
+++ selinux-pms-support/libsemanage/src/nodes_policy.c
@@ -50,3 +50,19 @@ int semanage_node_list(semanage_handle_t
dbase_config_t *dconfig = semanage_node_dbase_policy(handle);
return dbase_list(handle, dconfig, records, count);
}
+
+int semanage_node_serialize_policy(semanage_handle_t * handle,
+ char **data, uint64_t * data_length)
+{
+
+ dbase_config_t *dconfig = semanage_node_dbase_policy(handle);
+ return dbase_serialize(handle, dconfig, data, data_length);
+}
+
+int semanage_node_unserialize_policy(semanage_handle_t * handle,
+ char *data, uint64_t data_length)
+{
+
+ dbase_config_t *dconfig = semanage_node_dbase_policy(handle);
+ return dbase_unserialize(handle, dconfig, data, data_length);
+}
Index: selinux-pms-support/libsemanage/tests/libsemanage-tests.c
===================================================================
--- selinux-pms-support.orig/libsemanage/tests/libsemanage-tests.c
+++ selinux-pms-support/libsemanage/tests/libsemanage-tests.c
@@ -25,6 +25,7 @@
#include "test_context_record.h"
#include "test_fcontext_record.h"
#include "test_iface_record.h"
+#include "test_node_record.h"
#include <CUnit/Basic.h>
#include <CUnit/Console.h>
@@ -65,6 +66,7 @@ static int do_tests(int interactive, int
DECLARE_SUITE(context_record);
DECLARE_SUITE(fcontext_record);
DECLARE_SUITE(iface_record);
+ DECLARE_SUITE(node_record);
if (verbose)
CU_basic_set_mode(CU_BRM_VERBOSE);
Index: selinux-pms-support/libsemanage/tests/test_node_record.c
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/tests/test_node_record.c
@@ -0,0 +1,173 @@
+/* Authors: Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* The purpose of this file is to provide unit tests of the functions in:
+ *
+ * libsemanage/src/semanage_store.c
+ *
+ */
+
+#include "node_internal.h"
+#include "node_record.h"
+#include <sepol/context_record.h>
+#include <sepol/node_record.h>
+
+#include "globals.h"
+#include "utilities.h"
+#include "test_node_record.h"
+
+#include <libgen.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <CUnit/Basic.h>
+
+/* The suite initialization function.
+ * Returns zero on success, non-zero otherwise.
+ */
+int node_record_test_init(void)
+{
+ /* initialize the handle */
+ sh = semanage_handle_create();
+ if (sh == NULL)
+ return -1;
+
+ /* hide error messages */
+ sh->msg_callback = test_msg_handler;
+
+ return 0;
+}
+
+/* The suite cleanup function.
+ * Returns zero on success, non-zero otherwise.
+ */
+int node_record_test_cleanup(void)
+{
+ semanage_handle_destroy(sh);
+ return 0;
+}
+
+/* Adds all the tests needed for this suite.
+ */
+int node_record_add_tests(CU_pSuite suite)
+{
+ if (NULL ==
+ CU_add_test(suite, "semanage_node_serialize",
+ test_semanage_node_serialize)) {
+ CU_cleanup_registry();
+ return CU_get_error();
+ }
+
+ return 0;
+}
+
+/* Tests the semanage_node_serialize function in node_record.c
+ */
+void test_semanage_node_serialize(void)
+{
+ int status;
+ char *data;
+ uint64_t data_length = 0;
+
+ /* serialize */
+
+ semanage_node_t *node;
+ status = semanage_node_create(sh, &node);
+ semanage_context_t *con;
+
+ /* setup test fields */
+ int proto = SEMANAGE_PROTO_IP4;
+ const char *addr = "10.10.10.10";
+ const char *mask = "255.255.255.255";
+ const char *con_str = "testuser:testrole:testtype";
+
+ status = semanage_node_set_addr(sh, node, proto, addr);
+ CU_ASSERT(status == 0);
+
+ status = semanage_node_set_mask(sh, node, proto, mask);
+ CU_ASSERT(status == 0);
+
+ status = semanage_context_from_string(sh, con_str, &con);
+ CU_ASSERT(status == 0);
+ status = semanage_node_set_con(sh, node, con);
+ CU_ASSERT(status == 0);
+
+ /* set aside enough space... */
+ status = semanage_node_serialize(sh, node, NULL, &data_length);
+ CU_ASSERT(status == 0);
+ data = calloc(data_length, sizeof(char));
+
+ char *data2;
+ data2 = data;
+ status = semanage_node_serialize(sh, node, &data2, NULL);
+ CU_ASSERT(status == 0);
+ /* iterator/destructive effect check */
+ CU_ASSERT((unsigned)(data2 - data) == data_length);
+
+ /* unserialize */
+ semanage_node_t *node2;
+ data2 = data;
+ uint64_t data_length2 = data_length;
+ status = semanage_node_unserialize(sh, &data2, &data_length2, &node2);
+ CU_ASSERT(status == 0);
+ /* iterator/destructive effect check */
+ CU_ASSERT((unsigned)(data2 - data) == data_length);
+
+ /* get results */
+ int proto2;
+ char *addr2;
+ char *mask2;
+ semanage_context_t *con2;
+ char *con_str2;
+
+ proto2 = semanage_node_get_proto(node2);
+ status = semanage_node_get_addr(sh, node2, &addr2);
+ CU_ASSERT(status == 0);
+ status = semanage_node_get_mask(sh, node2, &mask2);
+ CU_ASSERT(status == 0);
+
+ con2 = semanage_node_get_con(node2);
+ status = semanage_context_to_string(sh, con2, &con_str2);
+ CU_ASSERT(status == 0);
+
+ /* compare */
+ CU_ASSERT(proto == proto2);
+
+ status = strcmp(addr, addr2);
+ CU_ASSERT(status == 0);
+
+ status = strcmp(mask, mask2);
+ CU_ASSERT(status == 0);
+
+ status = strcmp(con_str, con_str2);
+ CU_ASSERT(status == 0);
+
+ /* cleanup */
+ semanage_node_free(node);
+ semanage_node_free(node2);
+ semanage_context_free(con);
+ free(addr2);
+ free(mask2);
+ free(con_str2);
+ free(data);
+
+}
Index: selinux-pms-support/libsemanage/tests/test_node_record.h
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/tests/test_node_record.h
@@ -0,0 +1,32 @@
+/* Authors: Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __TEST_NODE_RECORD_H__
+#define __TEST_NODE_RECORD_H__
+
+#include <CUnit/Basic.h>
+
+int node_record_test_init(void);
+int node_record_test_cleanup(void);
+int node_record_add_tests(CU_pSuite suite);
+
+void test_semanage_node_serialize(void);
+
+#endif
--
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH 19/33] libsemanage: port serialization
2007-04-23 21:34 [PATCH 00/33] libsemanage/libsepol object serialization and ps-api jbrindle
` (17 preceding siblings ...)
2007-04-23 21:35 ` [PATCH 18/33] libsemanage: node serialization jbrindle
@ 2007-04-23 21:35 ` jbrindle
2007-04-23 21:35 ` [PATCH 20/33] libsemanage: seuser serialization jbrindle
` (15 subsequent siblings)
34 siblings, 0 replies; 58+ messages in thread
From: jbrindle @ 2007-04-23 21:35 UTC (permalink / raw)
To: selinux
---
libsemanage/include/semanage/ports_local.h | 28 ++++
libsemanage/include/semanage/ports_policy.h | 6 +
libsemanage/src/port_internal.h | 49 ++++++++
libsemanage/src/port_record.c | 48 ++++++++
libsemanage/src/ports_local.c | 16 ++
libsemanage/src/ports_policy.c | 16 ++
libsemanage/tests/libsemanage-tests.c | 2
libsemanage/tests/test_port_record.c | 162 ++++++++++++++++++++++++++++
libsemanage/tests/test_port_record.h | 32 +++++
9 files changed, 357 insertions(+), 2 deletions(-)
Index: selinux-pms-support/libsemanage/include/semanage/ports_local.h
===================================================================
--- selinux-pms-support.orig/libsemanage/include/semanage/ports_local.h
+++ selinux-pms-support/libsemanage/include/semanage/ports_local.h
@@ -1,8 +1,28 @@
-/* Copyright (C) 2005 Red Hat, Inc. */
+/* Authors: Ivan Gyurdiev <ivg2@cornell.edu>
+ * Christopher Ashworth <cashworth@tresys.com>
+ *
+ * Copyright (C) 2005 Red Hat, Inc.
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
#ifndef _SEMANAGE_PORTS_LOCAL_H_
#define _SEMANAGE_PORTS_LOCAL_H_
+#include <inttypes.h>
#include <semanage/port_record.h>
#include <semanage/handle.h>
@@ -33,4 +53,10 @@ extern int semanage_port_list_local(sema
semanage_port_t *** records,
unsigned int *count);
+extern int semanage_port_serialize_local(semanage_handle_t * handle,
+ char **data, uint64_t * data_length);
+
+extern int semanage_port_unserialize_local(semanage_handle_t * handle,
+ char *data, uint64_t data_length);
+
#endif
Index: selinux-pms-support/libsemanage/include/semanage/ports_policy.h
===================================================================
--- selinux-pms-support.orig/libsemanage/include/semanage/ports_policy.h
+++ selinux-pms-support/libsemanage/include/semanage/ports_policy.h
@@ -24,4 +24,10 @@ extern int semanage_port_iterate(semanag
extern int semanage_port_list(semanage_handle_t * handle,
semanage_port_t *** records, unsigned int *count);
+extern int semanage_port_serialize_policy(semanage_handle_t * handle,
+ char **data, uint64_t * data_length);
+
+extern int semanage_port_unserialize_policy(semanage_handle_t * handle,
+ char *data, uint64_t data_length);
+
#endif
Index: selinux-pms-support/libsemanage/src/port_internal.h
===================================================================
--- selinux-pms-support.orig/libsemanage/src/port_internal.h
+++ selinux-pms-support/libsemanage/src/port_internal.h
@@ -1,10 +1,34 @@
+/* Authors: Ivan Gyurdiev <ivg2@cornell.edu>
+ * Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2005 Red Hat, Inc.
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
#ifndef _SEMANAGE_PORT_INTERNAL_H_
#define _SEMANAGE_PORT_INTERNAL_H_
+#include <inttypes.h>
#include <semanage/port_record.h>
#include <semanage/ports_local.h>
#include <semanage/ports_policy.h>
#include "database.h"
+#include "database_policydb.h"
#include "handle.h"
#include "dso.h"
@@ -28,6 +52,7 @@ hidden_proto(semanage_port_create)
/* PORT RECORD: method table */
extern record_table_t SEMANAGE_PORT_RTABLE;
+extern record_policydb_table_t SEMANAGE_PORT_POLICYDB_RTABLE;
extern int port_file_dbase_init(semanage_handle_t * handle,
const char *fname, dbase_config_t * dconfig);
@@ -41,9 +66,33 @@ extern void port_policydb_dbase_release(
extern int hidden semanage_port_validate_local(semanage_handle_t * handle);
+extern int port_ps_local_dbase_init(semanage_handle_t * handle,
+ uint32_t sandbox_id, dbase_config_t * dconfig);
+
+extern void port_ps_local_dbase_release(dbase_config_t * dconfig);
+
+extern int port_ps_policydb_dbase_init(semanage_handle_t * handle,
+ uint32_t sandbox_id,
+ dbase_config_t * dconfig);
+
+extern void port_ps_policydb_dbase_release(dbase_config_t * dconfig);
+
/* ==== Internal (to ports) API === */
hidden int semanage_port_compare2_qsort(const semanage_port_t ** port,
const semanage_port_t ** port2);
+/*======== Internal API: Serialize/Unserialize ========== */
+hidden int semanage_port_calculate_serialized_size(semanage_handle_t * handle,
+ const semanage_port_t * port,
+ uint64_t * size);
+
+hidden int semanage_port_serialize(semanage_handle_t * handle,
+ const semanage_port_t * port,
+ char **data, uint64_t * size);
+
+hidden int semanage_port_unserialize(semanage_handle_t * handle,
+ char **data, uint64_t * size,
+ semanage_port_t ** port);
+
#endif
Index: selinux-pms-support/libsemanage/src/port_record.c
===================================================================
--- selinux-pms-support.orig/libsemanage/src/port_record.c
+++ selinux-pms-support/libsemanage/src/port_record.c
@@ -1,4 +1,24 @@
-/* Copyright (C) 2005 Red Hat, Inc. */
+/* Authors: Ivan Gyurdiev <ivg2@cornell.edu>
+ * Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2005 Red Hat, Inc.
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
/* Object: semanage_port_t (Network Port)
* Object: semanage_port_key_t (Network Port Key)
@@ -6,6 +26,8 @@
* Implements: record_key_t (Database Record Key)
*/
+#include <stdlib.h>
+#include <string.h>
#include <sepol/context_record.h>
#include <sepol/port_record.h>
@@ -22,6 +44,7 @@ typedef semanage_port_key_t record_key_t
#include "port_internal.h"
#include "handle.h"
#include "database.h"
+#include "debug.h"
/* Key */
int semanage_port_compare(const semanage_port_t * port,
@@ -179,6 +202,27 @@ void semanage_port_free(semanage_port_t
hidden_def(semanage_port_free)
+/* Serialize/Unserialize */
+/** Destructively modifies data and size.
+ * Caller must pre-allocate space for data.
+ * Use semanage_port_calculate_serialized_size(). */
+hidden int semanage_port_serialize(semanage_handle_t * handle,
+ const semanage_port_t * port,
+ char **data, uint64_t * size)
+{
+ return sepol_port_serialize(handle->sepolh, port, data, size);
+}
+
+/** Destructively modifies port, data and size.
+ * Allocates space for port.
+ * Caller must free. */
+hidden int semanage_port_unserialize(semanage_handle_t * handle,
+ char **data, uint64_t * size,
+ semanage_port_t ** port)
+{
+ return sepol_port_unserialize(handle->sepolh, data, size, port);
+}
+
/* Port base functions */
record_table_t SEMANAGE_PORT_RTABLE = {
.create = semanage_port_create,
@@ -189,4 +233,6 @@ record_table_t SEMANAGE_PORT_RTABLE = {
.compare2 = semanage_port_compare2,
.compare2_qsort = semanage_port_compare2_qsort,
.free = semanage_port_free,
+ .serialize = semanage_port_serialize,
+ .unserialize = semanage_port_unserialize,
};
Index: selinux-pms-support/libsemanage/src/ports_local.c
===================================================================
--- selinux-pms-support.orig/libsemanage/src/ports_local.c
+++ selinux-pms-support/libsemanage/src/ports_local.c
@@ -142,3 +142,19 @@ int hidden semanage_port_validate_local(
free(ports);
return STATUS_ERR;
}
+
+int semanage_port_serialize_local(semanage_handle_t * handle,
+ char **data, uint64_t * data_length)
+{
+
+ dbase_config_t *dconfig = semanage_port_dbase_local(handle);
+ return dbase_serialize(handle, dconfig, data, data_length);
+}
+
+int semanage_port_unserialize_local(semanage_handle_t * handle,
+ char *data, uint64_t data_length)
+{
+
+ dbase_config_t *dconfig = semanage_port_dbase_local(handle);
+ return dbase_unserialize(handle, dconfig, data, data_length);
+}
Index: selinux-pms-support/libsemanage/src/ports_policy.c
===================================================================
--- selinux-pms-support.orig/libsemanage/src/ports_policy.c
+++ selinux-pms-support/libsemanage/src/ports_policy.c
@@ -50,3 +50,19 @@ int semanage_port_list(semanage_handle_t
dbase_config_t *dconfig = semanage_port_dbase_policy(handle);
return dbase_list(handle, dconfig, records, count);
}
+
+int semanage_port_serialize_policy(semanage_handle_t * handle,
+ char **data, uint64_t * data_length)
+{
+
+ dbase_config_t *dconfig = semanage_port_dbase_policy(handle);
+ return dbase_serialize(handle, dconfig, data, data_length);
+}
+
+int semanage_port_unserialize_policy(semanage_handle_t * handle,
+ char *data, uint64_t data_length)
+{
+
+ dbase_config_t *dconfig = semanage_port_dbase_policy(handle);
+ return dbase_unserialize(handle, dconfig, data, data_length);
+}
Index: selinux-pms-support/libsemanage/tests/libsemanage-tests.c
===================================================================
--- selinux-pms-support.orig/libsemanage/tests/libsemanage-tests.c
+++ selinux-pms-support/libsemanage/tests/libsemanage-tests.c
@@ -26,6 +26,7 @@
#include "test_fcontext_record.h"
#include "test_iface_record.h"
#include "test_node_record.h"
+#include "test_port_record.h"
#include <CUnit/Basic.h>
#include <CUnit/Console.h>
@@ -67,6 +68,7 @@ static int do_tests(int interactive, int
DECLARE_SUITE(fcontext_record);
DECLARE_SUITE(iface_record);
DECLARE_SUITE(node_record);
+ DECLARE_SUITE(port_record);
if (verbose)
CU_basic_set_mode(CU_BRM_VERBOSE);
Index: selinux-pms-support/libsemanage/tests/test_port_record.c
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/tests/test_port_record.c
@@ -0,0 +1,162 @@
+/* Authors: Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* The purpose of this file is to provide unit tests of the functions in:
+ *
+ * libsemanage/src/semanage_store.c
+ *
+ */
+
+#include "port_internal.h"
+#include "port_record.h"
+#include <sepol/context_record.h>
+#include <sepol/port_record.h>
+
+#include "globals.h"
+#include "utilities.h"
+#include "test_port_record.h"
+
+#include <libgen.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <CUnit/Basic.h>
+
+/* The suite initialization function.
+ * Returns zero on success, non-zero otherwise.
+ */
+int port_record_test_init(void)
+{
+ /* initialize the handle */
+ sh = semanage_handle_create();
+ if (sh == NULL)
+ return -1;
+
+ /* hide error messages */
+ sh->msg_callback = test_msg_handler;
+
+ return 0;
+}
+
+/* The suite cleanup function.
+ * Returns zero on success, non-zero otherwise.
+ */
+int port_record_test_cleanup(void)
+{
+ semanage_handle_destroy(sh);
+ return 0;
+}
+
+/* Adds all the tests needed for this suite.
+ */
+int port_record_add_tests(CU_pSuite suite)
+{
+ if (NULL ==
+ CU_add_test(suite, "semanage_port_serialize",
+ test_semanage_port_serialize)) {
+ CU_cleanup_registry();
+ return CU_get_error();
+ }
+
+ return 0;
+}
+
+/* Tests the semanage_port_serialize function in port_record.c
+ */
+void test_semanage_port_serialize(void)
+{
+ int status;
+ char *data;
+ uint64_t data_length = 0;
+
+ /* serialize */
+
+ semanage_port_t *port;
+ status = semanage_port_create(sh, &port);
+ semanage_context_t *con;
+
+ /* setup test fields */
+ int low = 1;
+ int high = 65535;
+ int proto = SEMANAGE_PROTO_TCP;
+ const char *con_str = "testuser:testrole:testtype";
+
+ semanage_port_set_range(port, low, high);
+ semanage_port_set_proto(port, proto);
+
+ status = semanage_context_from_string(sh, con_str, &con);
+ CU_ASSERT(status == 0);
+ status = semanage_port_set_con(sh, port, con);
+ CU_ASSERT(status == 0);
+
+ /* set aside enough space... */
+ status = semanage_port_serialize(sh, port, NULL, &data_length);
+ CU_ASSERT(status == 0);
+ data = calloc(data_length, sizeof(char));
+
+ char *data2;
+ data2 = data;
+ status = semanage_port_serialize(sh, port, &data2, NULL);
+ CU_ASSERT(status == 0);
+ /* iterator/destructive effect check */
+ CU_ASSERT((unsigned)(data2 - data) == data_length);
+
+ /* unserialize */
+ semanage_port_t *port2;
+ data2 = data;
+ uint64_t data_length2 = data_length;
+ status = semanage_port_unserialize(sh, &data2, &data_length2, &port2);
+ CU_ASSERT(status == 0);
+ /* iterator/destructive effect check */
+ CU_ASSERT((unsigned)(data2 - data) == data_length);
+
+ /* get results */
+ int low2;
+ int high2;
+ int proto2;
+ semanage_context_t *con2;
+ char *con_str2;
+
+ low2 = semanage_port_get_low(port2);
+ high2 = semanage_port_get_high(port2);
+ proto2 = semanage_port_get_proto(port2);
+
+ con2 = semanage_port_get_con(port2);
+ status = semanage_context_to_string(sh, con2, &con_str2);
+ CU_ASSERT(status == 0);
+
+ /* compare */
+ CU_ASSERT(low == low2);
+ CU_ASSERT(high == high2);
+ CU_ASSERT(proto == proto2);
+
+ status = strcmp(con_str, con_str2);
+ CU_ASSERT(status == 0);
+
+ /* cleanup */
+ semanage_port_free(port);
+ semanage_port_free(port2);
+ semanage_context_free(con);
+ free(con_str2);
+ free(data);
+
+}
Index: selinux-pms-support/libsemanage/tests/test_port_record.h
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/tests/test_port_record.h
@@ -0,0 +1,32 @@
+/* Authors: Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __TEST_PORT_RECORD_H__
+#define __TEST_PORT_RECORD_H__
+
+#include <CUnit/Basic.h>
+
+int port_record_test_init(void);
+int port_record_test_cleanup(void);
+int port_record_add_tests(CU_pSuite suite);
+
+void test_semanage_port_serialize(void);
+
+#endif
--
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH 20/33] libsemanage: seuser serialization
2007-04-23 21:34 [PATCH 00/33] libsemanage/libsepol object serialization and ps-api jbrindle
` (18 preceding siblings ...)
2007-04-23 21:35 ` [PATCH 19/33] libsemanage: port serialization jbrindle
@ 2007-04-23 21:35 ` jbrindle
2007-04-23 21:35 ` [PATCH 21/33] libsemanage: user serialization jbrindle
` (14 subsequent siblings)
34 siblings, 0 replies; 58+ messages in thread
From: jbrindle @ 2007-04-23 21:35 UTC (permalink / raw)
To: selinux
---
libsemanage/include/semanage/seusers_local.h | 28 ++++
libsemanage/include/semanage/seusers_policy.h | 7 +
libsemanage/src/seuser_internal.h | 40 ++++++
libsemanage/src/seuser_record.c | 149 +++++++++++++++++++++++++-
libsemanage/src/seusers_local.c | 16 ++
libsemanage/src/seusers_policy.c | 16 ++
libsemanage/tests/libsemanage-tests.c | 2
libsemanage/tests/test_seuser_record.c | 143 ++++++++++++++++++++++++
libsemanage/tests/test_seuser_record.h | 32 +++++
9 files changed, 429 insertions(+), 4 deletions(-)
Index: selinux-pms-support/libsemanage/include/semanage/seusers_local.h
===================================================================
--- selinux-pms-support.orig/libsemanage/include/semanage/seusers_local.h
+++ selinux-pms-support/libsemanage/include/semanage/seusers_local.h
@@ -1,8 +1,28 @@
-/* Copyright (C) 2005 Red Hat, Inc. */
+/* Authors: Ivan Gyurdiev <ivg2@cornell.edu>
+ * Christopher Ashworth <cashworth@tresys.com>
+ *
+ * Copyright (C) 2005 Red Hat, Inc.
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
#ifndef _SEMANAGE_SEUSERS_LOCAL_H_
#define _SEMANAGE_SEUSERS_LOCAL_H_
+#include <inttypes.h>
#include <semanage/seuser_record.h>
#include <semanage/handle.h>
@@ -33,4 +53,10 @@ extern int semanage_seuser_list_local(se
semanage_seuser_t *** records,
unsigned int *count);
+extern int semanage_seuser_serialize_local(semanage_handle_t * handle,
+ char **data, uint64_t * data_length);
+
+extern int semanage_seuser_unserialize_local(semanage_handle_t * handle,
+ char *data, uint64_t data_length);
+
#endif
Index: selinux-pms-support/libsemanage/include/semanage/seusers_policy.h
===================================================================
--- selinux-pms-support.orig/libsemanage/include/semanage/seusers_policy.h
+++ selinux-pms-support/libsemanage/include/semanage/seusers_policy.h
@@ -26,4 +26,11 @@ extern int semanage_seuser_list(semanage
semanage_seuser_t *** records,
unsigned int *count);
+extern int semanage_seuser_serialize_policy(semanage_handle_t * handle,
+ char **data,
+ uint64_t * data_length);
+
+extern int semanage_seuser_unserialize_policy(semanage_handle_t * handle,
+ char *data, uint64_t data_length);
+
#endif
Index: selinux-pms-support/libsemanage/src/seuser_internal.h
===================================================================
--- selinux-pms-support.orig/libsemanage/src/seuser_internal.h
+++ selinux-pms-support/libsemanage/src/seuser_internal.h
@@ -1,3 +1,25 @@
+/* Authors: Ivan Gyurdiev <ivg2@cornell.edu>
+ * Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2005 Red Hat, Inc.
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
#ifndef _SEMANAGE_SEUSER_INTERNAL_H_
#define _SEMANAGE_SEUSER_INTERNAL_H_
@@ -34,8 +56,26 @@ extern int seuser_file_dbase_init(semana
extern void seuser_file_dbase_release(dbase_config_t * dconfig);
+extern int seuser_ps_local_dbase_init(semanage_handle_t * handle,
+ uint32_t sandbox_id, dbase_config_t * dconfig);
+
+extern void seuser_ps_local_dbase_release(dbase_config_t * dconfig);
+
extern int hidden semanage_seuser_validate_local(semanage_handle_t * handle,
const sepol_policydb_t *
policydb);
+/*======== Internal API: Serialize/Unserialize ========== */
+hidden int semanage_seuser_calculate_serialized_size(semanage_handle_t * handle,
+ const semanage_seuser_t *
+ seuser, uint64_t * size);
+
+hidden int semanage_seuser_serialize(semanage_handle_t * handle,
+ const semanage_seuser_t * seuser,
+ char **data, uint64_t * size);
+
+hidden int semanage_seuser_unserialize(semanage_handle_t * handle,
+ char **data, uint64_t * size,
+ semanage_seuser_t ** seuser);
+
#endif
Index: selinux-pms-support/libsemanage/src/seuser_record.c
===================================================================
--- selinux-pms-support.orig/libsemanage/src/seuser_record.c
+++ selinux-pms-support/libsemanage/src/seuser_record.c
@@ -1,4 +1,24 @@
-/* Copyright (C) 2005 Red Hat, Inc. */
+/* Authors: Ivan Gyurdiev <ivg2@cornell.edu>
+ * Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2005 Red Hat, Inc.
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
/* Object: semanage_seuser_t (Unix User)
* Object: semanage_seuser_key_t (Unix User Key)
@@ -12,12 +32,14 @@ typedef struct semanage_seuser record_t;
typedef struct semanage_seuser_key record_key_t;
#define DBASE_RECORD_DEFINED
+#include <assert.h>
#include <stdlib.h>
#include <string.h>
-#include "seuser_internal.h"
-#include "debug.h"
#include <semanage/handle.h>
#include "database.h"
+#include "debug.h"
+#include "serialize.h"
+#include "seuser_internal.h"
struct semanage_seuser {
/* This user's name */
@@ -254,6 +276,125 @@ void semanage_seuser_free(semanage_seuse
hidden_def(semanage_seuser_free)
+/* Serialize/Unserialize */
+/** Destructively modifies data and size.
+ * Caller must pre-allocate space for data.
+ * Use semanage_seuser_calculate_serialized_size(). */
+hidden int semanage_seuser_serialize(semanage_handle_t * handle,
+ const semanage_seuser_t * seuser,
+ char **data, uint64_t * size)
+{
+ int status = STATUS_SUCCESS;
+ const char *name = NULL;
+ const char *sename = NULL;
+ const char *mlsrange = NULL;
+
+ /* Sundry sanity checks. */
+ assert(handle != NULL && seuser != NULL);
+
+ /* Seuser user name. */
+ name = semanage_seuser_get_name(seuser);
+ if ((status =
+ semanage_serialize(handle,
+ name,
+ (name == NULL) ? 0 : strlen(name),
+ SEMANAGE_SERIAL_STRING, data, size)))
+ goto cleanup;
+
+ /* Seuser name. */
+ sename = semanage_seuser_get_sename(seuser);
+ if ((status =
+ semanage_serialize(handle,
+ sename,
+ (sename == NULL) ? 0 : strlen(sename),
+ SEMANAGE_SERIAL_STRING, data, size)))
+ goto cleanup;
+
+ /* Seuser mls range. */
+ mlsrange = semanage_seuser_get_mlsrange(seuser);
+ if ((status =
+ semanage_serialize(handle,
+ mlsrange,
+ (mlsrange == NULL) ? 0 : strlen(mlsrange),
+ SEMANAGE_SERIAL_STRING, data, size)))
+ goto cleanup;
+
+ /* Cleanup. */
+ cleanup:
+ return status;
+}
+
+/** Destructively modifies seuser, data and size.
+ * Allocates space for seuser.
+ * Caller must free. */
+hidden int semanage_seuser_unserialize(semanage_handle_t * handle,
+ char **data, uint64_t * size,
+ semanage_seuser_t ** seuser)
+{
+ int status = STATUS_SUCCESS;
+ char *name = NULL;
+ size_t *name_size = NULL;
+ char *sename = NULL;
+ size_t *sename_size = NULL;
+ char *mlsrange = NULL;
+ size_t *mlsrange_size = NULL;
+
+ /* Sundry sanity checks. */
+ assert(handle != NULL && data != NULL && *data != NULL && size != NULL);
+
+ /* Allocate space. */
+ if ((status = semanage_seuser_create(handle, seuser)))
+ goto cleanup;
+
+ /* Seuser user name. */
+ status =
+ semanage_unserialize(handle,
+ data, size,
+ (void **)&name,
+ &name_size, SEMANAGE_SERIAL_STRING);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+ if (name != NULL)
+ if ((status = semanage_seuser_set_name(handle, *seuser, name)))
+ goto cleanup;
+
+ /* Seuser name. */
+ status =
+ semanage_unserialize(handle,
+ data, size,
+ (void **)&sename,
+ &sename_size, SEMANAGE_SERIAL_STRING);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+ if (sename != NULL)
+ if ((status =
+ semanage_seuser_set_sename(handle, *seuser, sename)))
+ goto cleanup;
+
+ /* Seuser mls range. */
+ status =
+ semanage_unserialize(handle,
+ data, size,
+ (void **)&mlsrange,
+ &mlsrange_size, SEMANAGE_SERIAL_STRING);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+ if (mlsrange != NULL)
+ if ((status =
+ semanage_seuser_set_mlsrange(handle, *seuser, mlsrange)))
+ goto cleanup;
+
+ /* Cleanup. */
+ cleanup:
+ free(name);
+ free(name_size);
+ free(sename);
+ free(sename_size);
+ free(mlsrange);
+ free(mlsrange_size);
+ return status;
+}
+
/* Record base functions */
record_table_t SEMANAGE_SEUSER_RTABLE = {
.create = semanage_seuser_create,
@@ -264,4 +405,6 @@ record_table_t SEMANAGE_SEUSER_RTABLE =
.compare2 = semanage_seuser_compare2,
.compare2_qsort = semanage_seuser_compare2_qsort,
.free = semanage_seuser_free,
+ .serialize = semanage_seuser_serialize,
+ .unserialize = semanage_seuser_unserialize,
};
Index: selinux-pms-support/libsemanage/src/seusers_local.c
===================================================================
--- selinux-pms-support.orig/libsemanage/src/seusers_local.c
+++ selinux-pms-support/libsemanage/src/seusers_local.c
@@ -173,3 +173,19 @@ int hidden semanage_seuser_validate_loca
arg.policydb = policydb;
return semanage_seuser_iterate_local(handle, validate_handler, &arg);
}
+
+int semanage_seuser_serialize_local(semanage_handle_t * handle,
+ char **data, uint64_t * data_length)
+{
+
+ dbase_config_t *dconfig = semanage_seuser_dbase_local(handle);
+ return dbase_serialize(handle, dconfig, data, data_length);
+}
+
+int semanage_seuser_unserialize_local(semanage_handle_t * handle,
+ char *data, uint64_t data_length)
+{
+
+ dbase_config_t *dconfig = semanage_seuser_dbase_local(handle);
+ return dbase_unserialize(handle, dconfig, data, data_length);
+}
Index: selinux-pms-support/libsemanage/src/seusers_policy.c
===================================================================
--- selinux-pms-support.orig/libsemanage/src/seusers_policy.c
+++ selinux-pms-support/libsemanage/src/seusers_policy.c
@@ -56,3 +56,19 @@ int semanage_seuser_list(semanage_handle
dbase_config_t *dconfig = semanage_seuser_dbase_policy(handle);
return dbase_list(handle, dconfig, records, count);
}
+
+int semanage_seuser_serialize_policy(semanage_handle_t * handle,
+ char **data, uint64_t * data_length)
+{
+
+ dbase_config_t *dconfig = semanage_seuser_dbase_policy(handle);
+ return dbase_serialize(handle, dconfig, data, data_length);
+}
+
+int semanage_seuser_unserialize_policy(semanage_handle_t * handle,
+ char *data, uint64_t data_length)
+{
+
+ dbase_config_t *dconfig = semanage_seuser_dbase_policy(handle);
+ return dbase_unserialize(handle, dconfig, data, data_length);
+}
Index: selinux-pms-support/libsemanage/tests/libsemanage-tests.c
===================================================================
--- selinux-pms-support.orig/libsemanage/tests/libsemanage-tests.c
+++ selinux-pms-support/libsemanage/tests/libsemanage-tests.c
@@ -27,6 +27,7 @@
#include "test_iface_record.h"
#include "test_node_record.h"
#include "test_port_record.h"
+#include "test_seuser_record.h"
#include <CUnit/Basic.h>
#include <CUnit/Console.h>
@@ -69,6 +70,7 @@ static int do_tests(int interactive, int
DECLARE_SUITE(iface_record);
DECLARE_SUITE(node_record);
DECLARE_SUITE(port_record);
+ DECLARE_SUITE(seuser_record);
if (verbose)
CU_basic_set_mode(CU_BRM_VERBOSE);
Index: selinux-pms-support/libsemanage/tests/test_seuser_record.c
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/tests/test_seuser_record.c
@@ -0,0 +1,143 @@
+/* Authors: Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* The purpose of this file is to provide unit tests of the functions in:
+ *
+ * libsemanage/src/semanage_store.c
+ *
+ */
+
+#include "seuser_internal.h"
+#include "seuser_record.h"
+#include <semanage/seuser_record.h>
+
+#include "globals.h"
+#include "utilities.h"
+#include "test_seuser_record.h"
+
+#include <libgen.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <CUnit/Basic.h>
+
+/* The suite initialization function.
+ * Returns zero on success, non-zero otherwise.
+ */
+int seuser_record_test_init(void)
+{
+ /* initialize the handle */
+ sh = semanage_handle_create();
+ if (sh == NULL)
+ return -1;
+
+ /* hide error messages */
+ sh->msg_callback = test_msg_handler;
+
+ return 0;
+}
+
+/* The suite cleanup function.
+ * Returns zero on success, non-zero otherwise.
+ */
+int seuser_record_test_cleanup(void)
+{
+ semanage_handle_destroy(sh);
+ return 0;
+}
+
+/* Adds all the tests needed for this suite.
+ */
+int seuser_record_add_tests(CU_pSuite suite)
+{
+ if (NULL ==
+ CU_add_test(suite, "semanage_seuser_serialize",
+ test_semanage_seuser_serialize)) {
+ CU_cleanup_registry();
+ return CU_get_error();
+ }
+
+ return 0;
+}
+
+/* Tests the semanage_seuser_serialize function in seuser_record.c
+ */
+void test_semanage_seuser_serialize(void)
+{
+ int status;
+ char *data;
+ uint64_t data_length = 0;
+
+ /* serialize */
+
+ semanage_seuser_t *seuser;
+ status = semanage_seuser_create(sh, &seuser);
+
+ /* setup test fields */
+ const char *name = "testname";
+ const char *sename = "testsename";
+
+ status = semanage_seuser_set_name(sh, seuser, name);
+ status = semanage_seuser_set_sename(sh, seuser, sename);
+
+ /* set aside enough space... */
+ status = semanage_seuser_serialize(sh, seuser, NULL, &data_length);
+ CU_ASSERT(status == 0);
+ data = calloc(data_length, sizeof(char));
+
+ char *data2;
+ data2 = data;
+ status = semanage_seuser_serialize(sh, seuser, &data2, NULL);
+ CU_ASSERT(status == 0);
+ /* iterator/destructive effect check */
+ CU_ASSERT((unsigned)(data2 - data) == data_length);
+
+ /* unserialize */
+ semanage_seuser_t *seuser2;
+ data2 = data;
+ uint64_t data_length2 = data_length;
+ status =
+ semanage_seuser_unserialize(sh, &data2, &data_length2, &seuser2);
+ CU_ASSERT(status == 0);
+ /* iterator/destructive effect check */
+ CU_ASSERT((unsigned)(data2 - data) == data_length);
+
+ /* get results */
+ const char *name2;
+ const char *sename2;
+
+ name2 = semanage_seuser_get_name(seuser2);
+ sename2 = semanage_seuser_get_sename(seuser2);
+
+ /* compare */
+ status = strcmp(name, name2);
+ CU_ASSERT(status == 0);
+
+ status = strcmp(sename, sename2);
+ CU_ASSERT(status == 0);
+
+ /* cleanup */
+ semanage_seuser_free(seuser);
+ semanage_seuser_free(seuser2);
+ free(data);
+
+}
Index: selinux-pms-support/libsemanage/tests/test_seuser_record.h
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/tests/test_seuser_record.h
@@ -0,0 +1,32 @@
+/* Authors: Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __TEST_SEUSER_RECORD_H__
+#define __TEST_SEUSER_RECORD_H__
+
+#include <CUnit/Basic.h>
+
+int seuser_record_test_init(void);
+int seuser_record_test_cleanup(void);
+int seuser_record_add_tests(CU_pSuite suite);
+
+void test_semanage_seuser_serialize(void);
+
+#endif
--
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH 21/33] libsemanage: user serialization
2007-04-23 21:34 [PATCH 00/33] libsemanage/libsepol object serialization and ps-api jbrindle
` (19 preceding siblings ...)
2007-04-23 21:35 ` [PATCH 20/33] libsemanage: seuser serialization jbrindle
@ 2007-04-23 21:35 ` jbrindle
2007-04-23 21:35 ` [PATCH 22/33] libsemanage: module serialization jbrindle
` (13 subsequent siblings)
34 siblings, 0 replies; 58+ messages in thread
From: jbrindle @ 2007-04-23 21:35 UTC (permalink / raw)
To: selinux
---
libsemanage/include/semanage/users_local.h | 28 ++++-
libsemanage/include/semanage/users_policy.h | 6 +
libsemanage/src/user_base_record.c | 46 ++++++++
libsemanage/src/user_extra_record.c | 127 +++++++++++++++++++++++
libsemanage/src/user_internal.h | 105 +++++++++++++++++++
libsemanage/src/user_record.c | 120 +++++++++++++++++++++
libsemanage/src/users_local.c | 16 ++
libsemanage/src/users_policy.c | 16 ++
libsemanage/tests/libsemanage-tests.c | 2
libsemanage/tests/test_user_record.c | 153 ++++++++++++++++++++++++++++
libsemanage/tests/test_user_record.h | 32 +++++
11 files changed, 647 insertions(+), 4 deletions(-)
Index: selinux-pms-support/libsemanage/include/semanage/users_local.h
===================================================================
--- selinux-pms-support.orig/libsemanage/include/semanage/users_local.h
+++ selinux-pms-support/libsemanage/include/semanage/users_local.h
@@ -1,8 +1,28 @@
-/* Copyright (C) 2005 Red Hat, Inc. */
+/* Authors: Ivan Gyurdiev <ivg2@cornell.edu>
+ * Christopher Ashworth <cashworth@tresys.com>
+ *
+ * Copyright (C) 2005 Red Hat, Inc.
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
#ifndef _SEMANAGE_USERS_LOCAL_H_
#define _SEMANAGE_USERS_LOCAL_H_
+#include <inttypes.h>
#include <semanage/user_record.h>
#include <semanage/handle.h>
@@ -33,4 +53,10 @@ extern int semanage_user_list_local(sema
semanage_user_t *** records,
unsigned int *count);
+extern int semanage_user_serialize_local(semanage_handle_t * handle,
+ char **data, uint64_t * data_length);
+
+extern int semanage_user_unserialize_local(semanage_handle_t * handle,
+ char *data, uint64_t data_length);
+
#endif
Index: selinux-pms-support/libsemanage/include/semanage/users_policy.h
===================================================================
--- selinux-pms-support.orig/libsemanage/include/semanage/users_policy.h
+++ selinux-pms-support/libsemanage/include/semanage/users_policy.h
@@ -24,4 +24,10 @@ extern int semanage_user_iterate(semanag
extern int semanage_user_list(semanage_handle_t * handle,
semanage_user_t *** records, unsigned int *count);
+extern int semanage_user_serialize_policy(semanage_handle_t * handle,
+ char **data, uint64_t * data_length);
+
+extern int semanage_user_unserialize_policy(semanage_handle_t * handle,
+ char *data, uint64_t data_length);
+
#endif
Index: selinux-pms-support/libsemanage/src/user_base_record.c
===================================================================
--- selinux-pms-support.orig/libsemanage/src/user_base_record.c
+++ selinux-pms-support/libsemanage/src/user_base_record.c
@@ -1,4 +1,24 @@
-/* Copyright (C) 2005 Red Hat, Inc. */
+/* Authors: Ivan Gyurdiev <ivg2@cornell.edu>
+ * Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2005 Red Hat, Inc.
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
/* Object: semanage_user_base_t (SELinux User/Class Policy Object)
* Object: semanage_user_key_t (SELinux User/Class Key)
@@ -171,6 +191,28 @@ hidden void semanage_user_base_free(sema
sepol_user_free(user);
}
+/* Serialize/Unserialize */
+
+/** Destructively modifies data and size.
+ * Caller must pre-allocate space for data.
+ * Use semanage_user_base_calculate_serialized_size(). */
+hidden int semanage_user_base_serialize(semanage_handle_t * handle,
+ const semanage_user_base_t * user_base,
+ char **data, uint64_t * size)
+{
+ return sepol_user_serialize(handle->sepolh, user_base, data, size);
+}
+
+/** Destructively modifies user_base, data and size.
+ * Allocates space for user_base.
+ * Caller must free. */
+hidden int semanage_user_base_unserialize(semanage_handle_t * handle,
+ char **data, uint64_t * size,
+ semanage_user_base_t ** user_base)
+{
+ return sepol_user_unserialize(handle->sepolh, data, size, user_base);
+}
+
/* Record base functions */
record_table_t SEMANAGE_USER_BASE_RTABLE = {
.create = semanage_user_base_create,
@@ -181,4 +223,6 @@ record_table_t SEMANAGE_USER_BASE_RTABLE
.compare2 = semanage_user_base_compare2,
.compare2_qsort = semanage_user_base_compare2_qsort,
.free = semanage_user_base_free,
+ .serialize = semanage_user_base_serialize,
+ .unserialize = semanage_user_base_unserialize,
};
Index: selinux-pms-support/libsemanage/src/user_extra_record.c
===================================================================
--- selinux-pms-support.orig/libsemanage/src/user_extra_record.c
+++ selinux-pms-support/libsemanage/src/user_extra_record.c
@@ -1,4 +1,24 @@
-/* Copyright (C) 2005 Red Hat, Inc. */
+/* Authors: Ivan Gyurdiev <ivg2@cornell.edu>
+ * Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2005 Red Hat, Inc.
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
/* Object: semanage_user_extra_t (SELinux User/Class Extra Data)
* Object: semanage_user_extra_key_t (SELinux User/Class Key)
@@ -16,12 +36,14 @@ typedef struct semanage_user_extra recor
typedef semanage_user_key_t record_key_t;
#define DBASE_RECORD_DEFINED
+#include <assert.h>
#include <semanage/handle.h>
#include <stdlib.h>
#include <string.h>
#include "user_internal.h"
#include "debug.h"
#include "database.h"
+#include "serialize.h"
struct semanage_user_extra {
/* This user's name */
@@ -184,6 +206,107 @@ hidden int semanage_user_extra_clone(sem
return STATUS_ERR;
}
+/* Serialize/Unserialize */
+
+/** Destructively modifies data and size.
+ * Caller must pre-allocate space for data.
+ * Use semanage_user_extra_calculate_serialized_size(). */
+hidden int semanage_user_extra_serialize(semanage_handle_t * handle,
+ const semanage_user_extra_t *
+ user_extra, char **data,
+ uint64_t * size)
+{
+ int status = STATUS_SUCCESS;
+ const char *name = NULL;
+ const char *prefix = NULL;
+
+ /* Sundry sanity checks. */
+ assert(handle != NULL && user_extra != NULL);
+
+ /* User extra name. */
+ name = semanage_user_extra_get_name(user_extra);
+ status =
+ semanage_serialize(handle,
+ name,
+ (name == NULL) ? 0 : strlen(name),
+ SEMANAGE_SERIAL_STRING, data, size);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* User extra prefix. */
+ prefix = semanage_user_extra_get_prefix(user_extra);
+ status =
+ semanage_serialize(handle,
+ prefix,
+ (prefix == NULL) ? 0 : strlen(prefix),
+ SEMANAGE_SERIAL_STRING, data, size);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Cleanup. */
+ cleanup:
+ return status;
+}
+
+/** Destructively modifies user_extra, data and size.
+ * Allocates space for user_extra.
+ * Caller must free. */
+hidden int semanage_user_extra_unserialize(semanage_handle_t * handle,
+ char **data, uint64_t * size,
+ semanage_user_extra_t ** user_extra)
+{
+ int status = STATUS_SUCCESS;
+ char *name = NULL;
+ size_t *name_size = NULL;
+ char *prefix = NULL;
+ size_t *prefix_size = NULL;
+
+ /* Sundry sanity checks. */
+ assert(handle != NULL && data != NULL && *data != NULL && size != NULL);
+
+ /* Allocate space. */
+ if ((status = semanage_user_extra_create(handle, user_extra)))
+ goto cleanup;
+
+ /* User extra name. */
+ status =
+ semanage_unserialize(handle,
+ data, size,
+ (void **)&name,
+ &name_size, SEMANAGE_SERIAL_STRING);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+ if (name != NULL) {
+ status =
+ semanage_user_extra_set_name(handle, *user_extra, name);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+ }
+
+ /* User extra name. */
+ status =
+ semanage_unserialize(handle,
+ data, size,
+ (void **)&prefix,
+ &prefix_size, SEMANAGE_SERIAL_STRING);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+ if (prefix != NULL) {
+ status =
+ semanage_user_extra_set_prefix(handle, *user_extra, prefix);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+ }
+
+ /* Cleanup. */
+ cleanup:
+ free(name);
+ free(name_size);
+ free(prefix);
+ free(prefix_size);
+ return status;
+}
+
/* Record base functions */
record_table_t SEMANAGE_USER_EXTRA_RTABLE = {
.create = semanage_user_extra_create,
@@ -194,4 +317,6 @@ record_table_t SEMANAGE_USER_EXTRA_RTABL
.compare2 = semanage_user_extra_compare2,
.compare2_qsort = semanage_user_extra_compare2_qsort,
.free = semanage_user_extra_free,
+ .serialize = semanage_user_extra_serialize,
+ .unserialize = semanage_user_extra_unserialize,
};
Index: selinux-pms-support/libsemanage/src/user_internal.h
===================================================================
--- selinux-pms-support.orig/libsemanage/src/user_internal.h
+++ selinux-pms-support/libsemanage/src/user_internal.h
@@ -1,11 +1,36 @@
+/* Authors: Ivan Gyurdiev <ivg2@cornell.edu>
+ * Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2005 Red Hat, Inc.
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
#ifndef _SEMANAGE_USER_INTERNAL_H_
#define _SEMANAGE_USER_INTERNAL_H_
+#include <inttypes.h>
#include <sepol/user_record.h>
#include <semanage/user_record.h>
#include <semanage/users_local.h>
#include <semanage/users_policy.h>
#include "database.h"
+#include "database_policydb.h"
+#include "database_join.h"
#include "handle.h"
#include "dso.h"
@@ -30,9 +55,11 @@ hidden_proto(semanage_user_add_role)
/* USER record: metod table */
extern record_table_t SEMANAGE_USER_RTABLE;
+extern record_join_table_t SEMANAGE_USER_JOIN_RTABLE;
/* USER BASE record: method table */
extern record_table_t SEMANAGE_USER_BASE_RTABLE;
+extern record_policydb_table_t SEMANAGE_USER_BASE_POLICYDB_RTABLE;
/* USER EXTRA record: method table */
extern record_table_t SEMANAGE_USER_EXTRA_RTABLE;
@@ -46,6 +73,13 @@ extern int user_base_file_dbase_init(sem
extern void user_base_file_dbase_release(dbase_config_t * dconfig);
+/* USER BASE record, PS backend */
+extern int user_base_ps_local_dbase_init(semanage_handle_t * handle,
+ uint32_t sandbox_id,
+ dbase_config_t * dconfig);
+
+extern void user_base_ps_local_dbase_release(dbase_config_t * dconfig);
+
/* USER EXTRA record, FILE backend */
extern int user_extra_file_dbase_init(semanage_handle_t * handle,
const char *fname,
@@ -53,12 +87,26 @@ extern int user_extra_file_dbase_init(se
extern void user_extra_file_dbase_release(dbase_config_t * dconfig);
+/* USER EXTRA record, PS backend */
+extern int user_extra_ps_local_dbase_init(semanage_handle_t * handle,
+ uint32_t sandbox_id,
+ dbase_config_t * dconfig);
+
+extern void user_extra_ps_local_dbase_release(dbase_config_t * dconfig);
+
/* USER BASE record, POLICYDB backend */
extern int user_base_policydb_dbase_init(semanage_handle_t * handle,
dbase_config_t * dconfig);
extern void user_base_policydb_dbase_release(dbase_config_t * dconfig);
+/* USER BASE record, PS POLICYDB backend */
+extern int user_base_ps_policydb_dbase_init(semanage_handle_t * handle,
+ uint32_t sandbox_id,
+ dbase_config_t * dconfig);
+
+extern void user_base_ps_policydb_dbase_release(dbase_config_t * dconfig);
+
/* USER record, JOIN backend */
extern int user_join_dbase_init(semanage_handle_t * handle,
dbase_config_t * join1,
@@ -67,6 +115,19 @@ extern int user_join_dbase_init(semanage
extern void user_join_dbase_release(dbase_config_t * dconfig);
+extern int user_ps_local_dbase_init(semanage_handle_t * handle,
+ uint32_t sandbox_id,
+ dbase_config_t * dconfig);
+
+extern void user_ps_local_dbase_release(dbase_config_t * dconfig);
+
+extern int user_ps_policydb_dbase_init(semanage_handle_t * handle,
+ uint32_t sandbox_id,
+ dbase_config_t * dconfig);
+
+extern void user_ps_policydb_dbase_release(dbase_config_t * dconfig);
+
+
/*======= Internal API: Base (Policy) User record ====== */
#ifndef _SEMANAGE_USER_BASE_DEFINED_
@@ -131,6 +192,21 @@ hidden int semanage_user_base_set_roles(
hidden void semanage_user_base_free(semanage_user_base_t * user);
+hidden int semanage_user_base_calculate_serialized_size(semanage_handle_t *
+ handle,
+ const
+ semanage_user_base_t *
+ user_base,
+ uint64_t * size);
+
+hidden int semanage_user_base_serialize(semanage_handle_t * handle,
+ const semanage_user_base_t * user_base,
+ char **data, uint64_t * size);
+
+hidden int semanage_user_base_unserialize(semanage_handle_t * handle,
+ char **data, uint64_t * size,
+ semanage_user_base_t ** user_base);
+
/*=========== Internal API: Extra User record ==========*/
struct semanage_user_extra;
typedef struct semanage_user_extra semanage_user_extra_t;
@@ -158,6 +234,22 @@ hidden int semanage_user_extra_set_prefi
hidden void semanage_user_extra_free(semanage_user_extra_t * user_extra);
+hidden int semanage_user_extra_calculate_serialized_size(semanage_handle_t *
+ handle,
+ const
+ semanage_user_extra_t *
+ user_extra,
+ uint64_t * size);
+
+hidden int semanage_user_extra_serialize(semanage_handle_t * handle,
+ const semanage_user_extra_t *
+ user_extra, char **data,
+ uint64_t * size);
+
+hidden int semanage_user_extra_unserialize(semanage_handle_t * handle,
+ char **data, uint64_t * size,
+ semanage_user_extra_t ** user_extra);
+
/*======== Internal API: Join record ========== */
hidden void semanage_user_key_unpack(const semanage_user_key_t * key,
const char **name);
@@ -172,4 +264,17 @@ hidden int semanage_user_split(semanage_
semanage_user_base_t ** split1,
semanage_user_extra_t ** split2);
+/*======== Internal API: Serialize/Unserialize ========== */
+hidden int semanage_user_calculate_serialized_size(semanage_handle_t * handle,
+ const semanage_user_t * user,
+ uint64_t * size);
+
+hidden int semanage_user_serialize(semanage_handle_t * handle,
+ const semanage_user_t * user,
+ char **data, uint64_t * size);
+
+hidden int semanage_user_unserialize(semanage_handle_t * handle,
+ char **data, uint64_t * size,
+ semanage_user_t ** user);
+
#endif
Index: selinux-pms-support/libsemanage/src/user_record.c
===================================================================
--- selinux-pms-support.orig/libsemanage/src/user_record.c
+++ selinux-pms-support/libsemanage/src/user_record.c
@@ -1,4 +1,24 @@
-/* Copyright (C) 2005 Red Hat, Inc. */
+/* Authors: Ivan Gyurdiev <ivg2@cornell.edu>
+ * Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2005 Red Hat, Inc.
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
/* Object: semanage_user_t (SELinux User/Class)
* Object: semanage_user_key_t (SELinux User/Class Key)
@@ -16,12 +36,14 @@ typedef struct semanage_user record_t;
typedef semanage_user_key_t record_key_t;
#define DBASE_RECORD_DEFINED
+#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "user_internal.h"
#include "handle.h"
#include "database.h"
#include "debug.h"
+#include "serialize.h"
struct semanage_user {
char *name;
@@ -305,6 +327,100 @@ void semanage_user_free(semanage_user_t
hidden_def(semanage_user_free)
+/* Serialize/Unserialize */
+/** Destructively modifies data and size.
+ * Caller must pre-allocate space for data.
+ * Use semanage_user_calculate_serialized_size(). */
+hidden int semanage_user_serialize(semanage_handle_t * handle,
+ const semanage_user_t * user,
+ char **data, uint64_t * size)
+{
+ int status = STATUS_SUCCESS;
+ const char *name = NULL;
+
+ /* Sundry sanity checks. */
+ assert(handle != NULL && user != NULL);
+
+ /* User name. */
+ name = semanage_user_get_name(user);
+ status =
+ semanage_serialize(handle,
+ name,
+ (name == NULL) ? 0 : strlen(name),
+ SEMANAGE_SERIAL_STRING, data, size);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* User base. */
+ status = semanage_user_base_serialize(handle, user->base, data, size);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* User extra. */
+ status = semanage_user_extra_serialize(handle, user->extra, data, size);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Cleanup. */
+ cleanup:
+ return status;
+}
+
+/** Destructively modifies user, data and size.
+ * Allocates space for user.
+ * Caller must free. */
+hidden int semanage_user_unserialize(semanage_handle_t * handle,
+ char **data, uint64_t * size,
+ semanage_user_t ** user)
+{
+ int status = STATUS_SUCCESS;
+ char *name = NULL;
+ size_t *name_size = NULL;
+
+ /* Sundry sanity checks. */
+ assert(handle != NULL && data != NULL && *data != NULL && size != NULL);
+
+ /* Allocate space. */
+ if ((status = semanage_user_create(handle, user)))
+ goto cleanup;
+
+ /* User name. */
+ status =
+ semanage_unserialize(handle,
+ data, size,
+ (void **)&name,
+ &name_size, SEMANAGE_SERIAL_STRING);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+ if (name != NULL) {
+ status = semanage_user_set_name(handle, *user, name);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+ }
+
+ /* User base. */
+ semanage_user_base_free((*user)->base);
+ status =
+ semanage_user_base_unserialize(handle,
+ data, size, &((*user)->base));
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* User extra. */
+ semanage_user_extra_free((*user)->extra);
+ status =
+ semanage_user_extra_unserialize(handle,
+ data, size, &((*user)->extra));
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Cleanup. */
+ cleanup:
+ free(name);
+ free(name_size);
+ return status;
+}
+
/* Join properties */
hidden int semanage_user_join(semanage_handle_t * handle,
const semanage_user_base_t * record1,
@@ -407,4 +523,6 @@ record_table_t SEMANAGE_USER_RTABLE = {
.compare2 = semanage_user_compare2,
.compare2_qsort = semanage_user_compare2_qsort,
.free = semanage_user_free,
+ .serialize = semanage_user_serialize,
+ .unserialize = semanage_user_unserialize,
};
Index: selinux-pms-support/libsemanage/src/users_local.c
===================================================================
--- selinux-pms-support.orig/libsemanage/src/users_local.c
+++ selinux-pms-support/libsemanage/src/users_local.c
@@ -68,3 +68,19 @@ int semanage_user_list_local(semanage_ha
dbase_config_t *dconfig = semanage_user_dbase_local(handle);
return dbase_list(handle, dconfig, records, count);
}
+
+int semanage_user_serialize_local(semanage_handle_t * handle,
+ char **data, uint64_t * data_length)
+{
+
+ dbase_config_t *dconfig = semanage_user_dbase_local(handle);
+ return dbase_serialize(handle, dconfig, data, data_length);
+}
+
+int semanage_user_unserialize_local(semanage_handle_t * handle,
+ char *data, uint64_t data_length)
+{
+
+ dbase_config_t *dconfig = semanage_user_dbase_local(handle);
+ return dbase_unserialize(handle, dconfig, data, data_length);
+}
Index: selinux-pms-support/libsemanage/src/users_policy.c
===================================================================
--- selinux-pms-support.orig/libsemanage/src/users_policy.c
+++ selinux-pms-support/libsemanage/src/users_policy.c
@@ -54,3 +54,19 @@ int semanage_user_list(semanage_handle_t
dbase_config_t *dconfig = semanage_user_dbase_policy(handle);
return dbase_list(handle, dconfig, records, count);
}
+
+int semanage_user_serialize_policy(semanage_handle_t * handle,
+ char **data, uint64_t * data_length)
+{
+
+ dbase_config_t *dconfig = semanage_user_dbase_policy(handle);
+ return dbase_serialize(handle, dconfig, data, data_length);
+}
+
+int semanage_user_unserialize_policy(semanage_handle_t * handle,
+ char *data, uint64_t data_length)
+{
+
+ dbase_config_t *dconfig = semanage_user_dbase_policy(handle);
+ return dbase_unserialize(handle, dconfig, data, data_length);
+}
Index: selinux-pms-support/libsemanage/tests/libsemanage-tests.c
===================================================================
--- selinux-pms-support.orig/libsemanage/tests/libsemanage-tests.c
+++ selinux-pms-support/libsemanage/tests/libsemanage-tests.c
@@ -28,6 +28,7 @@
#include "test_node_record.h"
#include "test_port_record.h"
#include "test_seuser_record.h"
+#include "test_user_record.h"
#include <CUnit/Basic.h>
#include <CUnit/Console.h>
@@ -71,6 +72,7 @@ static int do_tests(int interactive, int
DECLARE_SUITE(node_record);
DECLARE_SUITE(port_record);
DECLARE_SUITE(seuser_record);
+ DECLARE_SUITE(user_record);
if (verbose)
CU_basic_set_mode(CU_BRM_VERBOSE);
Index: selinux-pms-support/libsemanage/tests/test_user_record.c
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/tests/test_user_record.c
@@ -0,0 +1,153 @@
+/* Authors: Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "user_internal.h"
+#include "user_record.h"
+#include <semanage/user_record.h>
+
+#include "globals.h"
+#include "utilities.h"
+#include "test_user_record.h"
+
+#include <libgen.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <CUnit/Basic.h>
+
+/* The suite initialization function.
+ * Returns zero on success, non-zero otherwise.
+ */
+int user_record_test_init(void)
+{
+ /* initialize the handle */
+ sh = semanage_handle_create();
+ if (sh == NULL)
+ return -1;
+
+ /* hide error messages */
+ sh->msg_callback = test_msg_handler;
+
+ return 0;
+}
+
+/* The suite cleanup function.
+ * Returns zero on success, non-zero otherwise.
+ */
+int user_record_test_cleanup(void)
+{
+ semanage_handle_destroy(sh);
+ return 0;
+}
+
+/* Adds all the tests needed for this suite.
+ */
+int user_record_add_tests(CU_pSuite suite)
+{
+ if (NULL ==
+ CU_add_test(suite, "semanage_user_serialize",
+ test_semanage_user_serialize)) {
+ CU_cleanup_registry();
+ return CU_get_error();
+ }
+
+ return 0;
+}
+
+/* Tests the semanage_user_serialize function in user_record.c
+ */
+void test_semanage_user_serialize(void)
+{
+ int status;
+ char *data;
+ uint64_t data_length = 0;
+
+ /* serialize */
+
+ semanage_user_t *user;
+ status = semanage_user_create(sh, &user);
+
+ /* setup test fields */
+ const char *name = "testname";
+ /* const char *mlslevel = NULL; */
+ /* const char *mlsrange = NULL; */
+ const char *roles[] = { "testrole1", "testrole2" };
+ unsigned int roles_size = 2;
+ const char *prefix = "testprefix";
+
+ status = semanage_user_set_name(sh, user, name);
+ /* status = semanage_user_set_mlslevel(sh, user, mlslevel); */
+ /* status = semanage_user_set_mlsrange(sh, user, mlsrange); */
+ status = semanage_user_set_roles(sh, user, roles, roles_size);
+ status = semanage_user_set_prefix(sh, user, prefix);
+
+ /* set aside enough space... */
+ status = semanage_user_serialize(sh, user, NULL, &data_length);
+ CU_ASSERT(status == 0);
+ data = calloc(data_length, sizeof(char));
+
+ char *data2;
+ data2 = data;
+ status = semanage_user_serialize(sh, user, &data2, NULL);
+ CU_ASSERT(status == 0);
+ /* iterator/destructive effect check */
+ CU_ASSERT((unsigned)(data2 - data) == data_length);
+
+ /* unserialize */
+ semanage_user_t *user2;
+ data2 = data;
+ uint64_t data_length2 = data_length;
+ status = semanage_user_unserialize(sh, &data2, &data_length2, &user2);
+ CU_ASSERT(status == 0);
+ /* iterator/destructive effect check */
+ CU_ASSERT((unsigned)(data2 - data) == data_length);
+
+ /* get results */
+ const char *name2;
+ const char *mlslevel2;
+ const char *mlsrange2;
+ const char **roles2;
+ unsigned int roles_size2;
+ const char *prefix2;
+
+ name2 = semanage_user_get_name(user2);
+ mlslevel2 = semanage_user_get_mlslevel(user2);
+ mlsrange2 = semanage_user_get_mlsrange(user2);
+ status = semanage_user_get_roles(sh, user2, &roles2, &roles_size2);
+ CU_ASSERT(status == 0);
+ prefix2 = semanage_user_get_prefix(user2);
+
+ /* compare */
+ CU_ASSERT(strcmp(name, name2) == 0);
+ CU_ASSERT(mlslevel2 == NULL);
+ CU_ASSERT(mlsrange2 == NULL);
+ CU_ASSERT(roles_size == roles_size2);
+ CU_ASSERT(strcmp(roles[0], roles2[0]) == 0);
+ CU_ASSERT(strcmp(roles[1], roles2[1]) == 0);
+
+ /* cleanup */
+ semanage_user_free(user);
+ semanage_user_free(user2);
+ free(roles2);
+ free(data);
+
+}
Index: selinux-pms-support/libsemanage/tests/test_user_record.h
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/tests/test_user_record.h
@@ -0,0 +1,32 @@
+/* Authors: Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __TEST_USER_RECORD_H__
+#define __TEST_USER_RECORD_H__
+
+#include <CUnit/Basic.h>
+
+int user_record_test_init(void);
+int user_record_test_cleanup(void);
+int user_record_add_tests(CU_pSuite suite);
+
+void test_semanage_user_serialize(void);
+
+#endif
--
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH 22/33] libsemanage: module serialization
2007-04-23 21:34 [PATCH 00/33] libsemanage/libsepol object serialization and ps-api jbrindle
` (20 preceding siblings ...)
2007-04-23 21:35 ` [PATCH 21/33] libsemanage: user serialization jbrindle
@ 2007-04-23 21:35 ` jbrindle
2007-04-23 21:35 ` [PATCH 23/33] libsemanage: commit number serialization jbrindle
` (12 subsequent siblings)
34 siblings, 0 replies; 58+ messages in thread
From: jbrindle @ 2007-04-23 21:35 UTC (permalink / raw)
To: selinux
---
libsemanage/include/semanage/modules.h | 11 ++
libsemanage/src/libsemanage.map | 1
libsemanage/src/module_internal.h | 3
libsemanage/src/modules.c | 148 +++++++++++++++++++++++++++++++--
4 files changed, 155 insertions(+), 8 deletions(-)
Index: selinux-pms-support/libsemanage/include/semanage/modules.h
===================================================================
--- selinux-pms-support.orig/libsemanage/include/semanage/modules.h
+++ selinux-pms-support/libsemanage/include/semanage/modules.h
@@ -21,6 +21,7 @@
#ifndef _SEMANAGE_MODULES_H_
#define _SEMANAGE_MODULES_H_
+#include <inttypes.h>
#include <stddef.h>
#include <semanage/handle.h>
@@ -48,4 +49,14 @@ semanage_module_info_t *semanage_module_
const char *semanage_module_get_name(semanage_module_info_t *);
const char *semanage_module_get_version(semanage_module_info_t *);
+int semanage_module_list_serialize(semanage_handle_t * handle,
+ char **data,
+ uint64_t * size);
+
+int semanage_module_list_unserialize(semanage_handle_t * handle,
+ char **data,
+ uint64_t *size,
+ semanage_module_info_t ** modules,
+ int *num_modules);
+
#endif
Index: selinux-pms-support/libsemanage/src/libsemanage.map
===================================================================
--- selinux-pms-support.orig/libsemanage/src/libsemanage.map
+++ selinux-pms-support/libsemanage/src/libsemanage.map
@@ -7,6 +7,7 @@ LIBSEMANAGE_1.0 {
semanage_module_install_base; semanage_module_remove;
semanage_module_list; semanage_module_info_datum_destroy;
semanage_module_list_nth; semanage_module_get_name;
+ semanage_module_list_serialize; semanage_module_list_unserialize;
semanage_module_get_version; semanage_select_store;
semanage_reload_policy; semanage_set_reload; semanage_set_rebuild;
semanage_user_*; semanage_bool_*; semanage_seuser_*;
Index: selinux-pms-support/libsemanage/src/module_internal.h
===================================================================
--- selinux-pms-support.orig/libsemanage/src/module_internal.h
+++ selinux-pms-support/libsemanage/src/module_internal.h
@@ -8,4 +8,7 @@ hidden_proto(semanage_module_get_name)
hidden_proto(semanage_module_get_version)
hidden_proto(semanage_module_info_datum_destroy)
hidden_proto(semanage_module_list_nth)
+ hidden_proto(semanage_module_list_serialize)
+ hidden_proto(semanage_module_list_unserialize)
+
#endif
Index: selinux-pms-support/libsemanage/src/modules.c
===================================================================
--- selinux-pms-support.orig/libsemanage/src/modules.c
+++ selinux-pms-support/libsemanage/src/modules.c
@@ -1,7 +1,8 @@
-/* Author: Joshua Brindle <jbrindle@tresys.co
- * Jason Tang <jtang@tresys.com>
+/* Author: Joshua Brindle <jbrindle@tresys.com>
+ * Jason Tang <jtang@tresys.com>
+ * Christopher Ashworth <cashworth@tresys.com>
*
- * Copyright (C) 2004-2005 Tresys Technology, LLC
+ * Copyright (C) 2004-2007 Tresys Technology, LLC
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -20,18 +21,24 @@
/* This file implements only the publicly-visible module functions to libsemanage. */
-#include "direct_api.h"
-#include "semanage_conf.h"
-#include "semanage_store.h"
-
#include <stdarg.h>
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+#include <inttypes.h>
+#include <limits.h>
+#include "direct_api.h"
+#include "semanage_conf.h"
+#include "semanage_store.h"
+#include "handle_internal.h"
#include "handle.h"
#include "modules.h"
#include "debug.h"
+#include "byteswap.h"
+#include "serialize.h"
int semanage_module_install(semanage_handle_t * sh,
char *module_data, size_t data_len)
@@ -120,6 +127,131 @@ int semanage_module_list(semanage_handle
return sh->funcs->list(sh, modinfo, num_modules);
}
+/* serialize a list of modules into a string, for sending over the wire.
+ * this function (and the corresponding unserialize function) will have to be
+ * able to handle changes to semanage_module_info_t since it is opaque.
+ * caller is responsible for freeing results
+ */
+int semanage_module_list_serialize(semanage_handle_t * handle,
+ char **data,
+ uint64_t * size)
+{
+ int status = STATUS_SUCCESS;
+ const char *name = NULL;
+ const char *version = NULL;
+ int i;
+ semanage_module_info_t * modules = NULL;
+ semanage_module_info_t * module = NULL;
+ int modules_size;
+ char *ptr = NULL;
+
+ /* Get the modules. */
+ status = semanage_module_list(handle, &modules, &modules_size);
+ if (status < 0)
+ goto cleanup;
+
+ /* Number of modules. */
+ status = semanage_serialize(handle, &modules_size, 0, SEMANAGE_SERIAL_UINT32_T, data, size);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ for (i = 0; i < modules_size; i++) {
+ module = semanage_module_list_nth(modules, i);
+
+ /* Module name. */
+ name = semanage_module_get_name(module);
+ status = semanage_serialize(handle, name, (name == NULL) ? 0 : strlen(name), SEMANAGE_SERIAL_STRING, NULL, size);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Module version. */
+ version = semanage_module_get_version(module);
+ status = semanage_serialize(handle, version, (version == NULL) ? 0 : strlen(version), SEMANAGE_SERIAL_STRING, NULL, size);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+ }
+
+ *data = calloc(*size, sizeof(char));
+ if (*data == NULL) {
+ status = STATUS_ERR;
+ goto cleanup;
+ }
+
+ ptr = *data;
+
+ /* Number of modules. */
+ status = semanage_serialize(handle, &modules_size, 0, SEMANAGE_SERIAL_UINT32_T, &ptr, NULL);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ for (i = 0; i < modules_size; i++) {
+ module = semanage_module_list_nth(modules, i);
+
+ /* Module name. */
+ name = semanage_module_get_name(module);
+ status = semanage_serialize(handle, name, (name == NULL) ? 0 : strlen(name), SEMANAGE_SERIAL_STRING, &ptr, NULL);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Module version. */
+ version = semanage_module_get_version(module);
+ status = semanage_serialize(handle, version, (version == NULL) ? 0 : strlen(version), SEMANAGE_SERIAL_STRING, &ptr, NULL);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+ }
+
+ /* Cleanup. */
+cleanup:
+ free(modules);
+ return status;
+}
+
+hidden_def(semanage_module_list_serialize)
+
+ /* unserialize a list of modules from a string that has been received over the wire.
+ * caller is responsible for freeing modules.
+ * NOTE: *data is modified by this function.
+ */
+int semanage_module_list_unserialize(semanage_handle_t * handle,
+ char **data,
+ uint64_t *size,
+ semanage_module_info_t ** modules,
+ int *modules_size)
+{
+ int status = STATUS_SUCCESS;
+ int i;
+ size_t *temp_size = NULL;
+
+ /* Number of modules. */
+ status = semanage_unserialize(handle, data, size, (void **)&temp_size, NULL, SEMANAGE_SERIAL_UINT32_T);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+ *modules_size = *temp_size;
+
+ *modules = calloc(*modules_size, sizeof(**modules));
+ if (*modules == NULL)
+ goto cleanup;
+
+ for (i = 0; i < *modules_size; i++) {
+ /* Module name. */
+ status = semanage_unserialize(handle, data, size, (void **)&(*modules)[i].name, &temp_size, SEMANAGE_SERIAL_STRING);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Module version. */
+ status = semanage_unserialize(handle, data, size, (void **)&(*modules)[i].version, &temp_size, SEMANAGE_SERIAL_STRING);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+ }
+
+ /* Cleanup. */
+cleanup:
+ free(temp_size);
+ return status;
+}
+
+hidden_def(semanage_module_list_unserialize)
+
void semanage_module_info_datum_destroy(semanage_module_info_t * modinfo)
{
if (modinfo != NULL) {
@@ -131,7 +263,7 @@ void semanage_module_info_datum_destroy(
hidden_def(semanage_module_info_datum_destroy)
semanage_module_info_t *semanage_module_list_nth(semanage_module_info_t * list,
- int n)
+ int n)
{
return list + n;
}
--
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH 23/33] libsemanage: commit number serialization
2007-04-23 21:34 [PATCH 00/33] libsemanage/libsepol object serialization and ps-api jbrindle
` (21 preceding siblings ...)
2007-04-23 21:35 ` [PATCH 22/33] libsemanage: module serialization jbrindle
@ 2007-04-23 21:35 ` jbrindle
2007-04-23 21:35 ` [PATCH 24/33] libsemanage: networking support jbrindle
` (11 subsequent siblings)
34 siblings, 0 replies; 58+ messages in thread
From: jbrindle @ 2007-04-23 21:35 UTC (permalink / raw)
To: selinux
Adds support for un/serializing the database commit number.
---
libsemanage/include/semanage/policy.h | 31 +++++++++++
libsemanage/src/libsemanage.map | 1
libsemanage/src/policy.c | 91 ++++++++++++++++++++++++++++++++++
libsemanage/src/policy.h | 4 +
4 files changed, 127 insertions(+)
Index: selinux-pms-support/libsemanage/include/semanage/policy.h
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/include/semanage/policy.h
@@ -0,0 +1,31 @@
+/* Authors: Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _SEMANAGE_POLICY_H_
+#define _SEMANAGE_POLICY_H_
+
+#include <semanage/handle.h>
+#include <inttypes.h>
+
+int semanage_policy_table_serialize_serial(semanage_handle_t *handle, char **data, uint64_t *size);
+
+int semanage_policy_table_unserialize_serial(semanage_handle_t *handle,
+ char **data, uint64_t *size);
+
+#endif
Index: selinux-pms-support/libsemanage/src/libsemanage.map
===================================================================
--- selinux-pms-support.orig/libsemanage/src/libsemanage.map
+++ selinux-pms-support/libsemanage/src/libsemanage.map
@@ -16,5 +16,6 @@ LIBSEMANAGE_1.0 {
semanage_fcontext_*; semanage_access_check; semanage_set_create_store;
semanage_*_serialize; semanage_*_unserialize;
semanage_is_connected;
+ semanage_policy_table_serialize_serial;
local: *;
};
Index: selinux-pms-support/libsemanage/src/policy.c
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/src/policy.c
@@ -0,0 +1,91 @@
+/* Author: Caleb Case <ccase@tresys.com>
+ * Ryan Haggerty <rhaggerty@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdlib.h>
+#include "debug.h"
+#include "policy.h"
+#include "serialize.h"
+
+/* Serialize the serial number into data and store the size of it in size.
+ * Returns status.
+ */
+int semanage_policy_table_serialize_serial(semanage_handle_t *handle, char **data, uint64_t *size)
+{
+ int status = STATUS_SUCCESS;
+ int serial = handle->funcs->get_serial(handle);
+ char* ptr = NULL;
+
+ /* sanity checks */
+ if (data == NULL || size == NULL) {
+ status = STATUS_ERR;
+ goto cleanup;
+ }
+
+ /* calculate size */
+ status = semanage_serialize(handle, &serial, 0, SEMANAGE_SERIAL_INT32_T, NULL, size);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Allocate memory. */
+ ptr = *data = calloc(*size, sizeof(char));
+ if (*data == NULL) {
+ status = STATUS_ERR;
+ goto cleanup;
+ }
+
+ /* Serialize */
+ status = semanage_serialize(handle, &serial, 0, SEMANAGE_SERIAL_INT32_T, &ptr, NULL);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+cleanup:
+ return status;
+}
+
+hidden_def(semanage_policy_table_serialize_serial)
+
+/* Unserialize the serial number from data.
+ * Function will move data pointer.
+ * Returns status if status is not equal to STATUS_SUCCESS or returns serial number.
+ */
+int semanage_policy_table_unserialize_serial(semanage_handle_t *handle,
+ char **data, uint64_t *size)
+{
+ int status = STATUS_SUCCESS;
+ int *serial = NULL;
+ int ret_serial = -1; /* assume we did not get a good serial number */
+
+ /* Sundry sanity checks. */
+ if (data == NULL || *data == NULL || size == NULL) {
+ status = STATUS_ERR;
+ goto cleanup;
+ }
+
+ status = semanage_unserialize(handle, data, size, (void **)&serial, 0, SEMANAGE_SERIAL_INT32_T);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ ret_serial = *serial; /* capture value so we can free */
+cleanup:
+ free(serial);
+ return status == STATUS_SUCCESS ? ret_serial : status;
+}
+
+hidden_def(semanage_policy_table_unserialize_serial)
Index: selinux-pms-support/libsemanage/src/policy.h
===================================================================
--- selinux-pms-support.orig/libsemanage/src/policy.h
+++ selinux-pms-support/libsemanage/src/policy.h
@@ -22,6 +22,7 @@
#ifndef _SEMANAGE_POLICY_INTERNAL_H_
#define _SEMANAGE_POLICY_INTERNAL_H_
+#include <semanage/policy.h>
#include "modules.h"
/* Circular dependency */
@@ -68,4 +69,7 @@ extern int semanage_base_merge_component
extern int semanage_commit_components(struct semanage_handle *handle);
+hidden_proto(semanage_policy_table_serialize_serial)
+hidden_proto(semanage_policy_table_unserialize_serial)
+
#endif
--
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH 24/33] libsemanage: networking support
2007-04-23 21:34 [PATCH 00/33] libsemanage/libsepol object serialization and ps-api jbrindle
` (22 preceding siblings ...)
2007-04-23 21:35 ` [PATCH 23/33] libsemanage: commit number serialization jbrindle
@ 2007-04-23 21:35 ` jbrindle
2007-04-23 21:35 ` [PATCH 25/33] libsemanage: policy server database hooks jbrindle
` (10 subsequent siblings)
34 siblings, 0 replies; 58+ messages in thread
From: jbrindle @ 2007-04-23 21:35 UTC (permalink / raw)
To: selinux
Sending/receiving utilities in messages.[ch]. Additional exported defines to support message processing.
---
libsemanage/include/semanage/messages.h | 126 +++++++++++
libsemanage/include/semanage/semanage.h | 3
libsemanage/src/messages.c | 355 ++++++++++++++++++++++++++++++++
libsemanage/src/messages_internal.h | 39 +++
4 files changed, 523 insertions(+)
Index: selinux-pms-support/libsemanage/include/semanage/messages.h
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/include/semanage/messages.h
@@ -0,0 +1,126 @@
+/* Author: Caleb Case <ccase@tresys.com>
+ * Christopher Ashworth <cashworth@tresys.com>
+ *
+ * Copyright (C) 2004-2007 Tresys Technology, LLC
+ * Copyright (C) 2005 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#ifndef _SEMANAGE_MESSAGES_H_
+#define _SEMANAGE_MESSAGES_H_
+
+#ifndef SEMANAGE_PS_DEFAULT_TIMEOUT
+#define SEMANAGE_PS_DEFAULT_TIMEOUT 160
+#endif
+
+/* Message types in the client/server protocol.
+ */
+enum message_types {
+ PS_OK = 1, /* policy server response */
+ PS_ERR, /* policy server response */
+ PS_BUSY, /* policy server response */
+ PS_INFO, /* policy server response */
+ PS_CONNECT = 100,
+ PS_DISCONNECT,
+ PS_BEGIN_TRANSACTION,
+ PS_COMMIT,
+ PS_GET_COMMIT_NUMBER,
+ PS_INSTALL_MODULE,
+ PS_UPGRADE_MODULE,
+ PS_BASE_MODULE,
+ PS_REMOVE_MODULE,
+ PS_LIST_MODULES,
+ PS_GET_DATABASE,
+ PS_PUT_DATABASE
+};
+
+/* Database types in the client/server protocol.
+ */
+enum database_types {
+ DB_BOOLEAN_ACTIVE,
+ DB_BOOLEAN_LOCAL,
+ DB_BOOLEAN_POLICY,
+ DB_FCONTEXT_LOCAL,
+ DB_FCONTEXT_POLICY,
+ DB_INTERFACE_LOCAL,
+ DB_INTERFACE_POLICY,
+ DB_NODE_LOCAL,
+ DB_NODE_POLICY,
+ DB_PORT_LOCAL,
+ DB_PORT_POLICY,
+ DB_SEUSER_LOCAL,
+ DB_SEUSER_POLICY,
+ DB_USER_LOCAL,
+ DB_USER_POLICY,
+};
+
+/* Info and error message types and strings.
+ */
+#define PS_ERROR_MESSAGE_MAX_LENGTH 256
+
+#define PS_INFO_SERVER_CLOSING_NUM 100
+#define PS_INFO_SERVER_CLOSING_STR "Server is being shut down."
+#define PS_INFO_CHANGED_NUM 102
+#define PS_INFO_CHANGED_STR "Policy has been changed since session began."
+
+#define PS_BUSY_COMMIT_NUM 300
+#define PS_BUSY_COMMIT_STR "Another client is currently committing changes."
+#define PS_BUSY_WRITE_NUM 301
+#define PS_BUSY_WRITE_STR "Another client is currently writing."
+
+#define PS_ERROR_COULD_NOT_PARSE_NUM 400
+#define PS_ERROR_COULD_NOT_PARSE_STR "Could not parse request."
+#define PS_ERROR_NOTHING_TO_COMMIT_NUM 401
+#define PS_ERROR_NOTHING_TO_COMMIT_STR "There was nothing to commit."
+#define PS_ERROR_COULD_NOT_UPGRADE_NUM 402
+#define PS_ERROR_COULD_NOT_UPGRADE_STR "Module to be upgraded does not exist or is earlier than existing version."
+#define PS_ERROR_FORBIDDEN_NUM 403
+#define PS_ERROR_FORBIDDEN_STR "Could not access requested file or directory."
+#define PS_ERROR_NO_BASE_MODULE_NUM 404
+#define PS_ERROR_NO_BASE_MODULE_STR "Cannot execute command because no base module was found."
+#define PS_ERROR_METAVERIFY_FAILED_NUM 405
+#define PS_ERROR_METAVERIFY_FAILED_STR "The metapolicy did not accept a component."
+#define PS_ERROR_VERIFY_FAILED_NUM 406
+#define PS_ERROR_VERIFY_FAILED_STR "A verifier did not accept the new policy."
+#define PS_ERROR_COULD_NOT_EXPAND_NUM 409
+#define PS_ERROR_COULD_NOT_EXPAND_STR "Error while expanding policy."
+#define PS_ERROR_COULD_NOT_LINK_NUM 412
+#define PS_ERROR_COULD_NOT_LINK_STR "Error while linking modules."
+#define PS_ERROR_DATA_NOT_A_MODULE_NUM 415
+#define PS_ERROR_DATA_NOT_A_MODULE_STR "The supplied file was not a valid policy module."
+#define PS_ERROR_DATA_NOT_A_BASE_NUM 416
+#define PS_ERROR_DATA_NOT_A_BASE_STR "The supplied file was not a valid base policy module."
+#define PS_ERROR_COULD_NOT_LOAD_NUM 417
+#define PS_ERROR_COULD_NOT_LOAD_STR "Error while loading new policy."
+#define PS_ERROR_COULD_NOT_REMOVE_NUM 418
+#define PS_ERROR_COULD_NOT_REMOVE_STR "Error while removing policy."
+
+#define PS_ERROR_NOT_IMPLEMENTED_NUM 501
+#define PS_ERROR_NOT_IMPLEMENTED_STR "Function not implemented."
+#define PS_ERROR_BUSY_NUM 503
+#define PS_ERROR_BUSY_STR "Too many clients connected to server."
+#define PS_ERROR_UNSUPPORTED_VERSION_NUM 505
+#define PS_ERROR_UNSUPPORTED_VERSION_STR "That protocol version is not supported."
+#define PS_ERROR_MESSAGE_INVALID_NUM 506
+#define PS_ERROR_MESSAGE_INVALID_STR "The message was invalid."
+#define PS_ERROR_MESSAGE_TOO_BIG_NUM 507
+#define PS_ERROR_MESSAGE_TOO_BIG_STR "The message was longer than the supported maximum length."
+#define PS_ERROR_NO_SUCH_DATABASE_NUM 508
+#define PS_ERROR_NO_SUCH_DATABASE_STR "Database requested does not exist."
+
+
+#endif
Index: selinux-pms-support/libsemanage/include/semanage/semanage.h
===================================================================
--- selinux-pms-support.orig/libsemanage/include/semanage/semanage.h
+++ selinux-pms-support/libsemanage/include/semanage/semanage.h
@@ -52,4 +52,7 @@
#include <semanage/nodes_local.h>
#include <semanage/nodes_policy.h>
+/* Messaging */
+#include <semanage/messages.h>
+
#endif
Index: selinux-pms-support/libsemanage/src/messages.c
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/src/messages.c
@@ -0,0 +1,355 @@
+/* Author: Jason Tang <jtang@tresys.com>
+ * Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2004-2007 Tresys Technology, LLC
+ * Copyright (C) 2005 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+/*
+ * messages.c
+ *
+ * Implements basic network io functions for communicating with a
+ * policy server.
+ *
+ * All messages to and from the server take the following form:
+ *
+ * uint32_t message_type
+ * uint64_t data_length (may be zero)
+ * char *data (may be omitted, if data_length == 0)
+ *
+ */
+
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/un.h>
+
+#include <semanage/messages.h>
+
+#include "debug.h"
+#include "byteswap.h"
+#include "messages_internal.h"
+
+/* Reads a stream of bytes into the supplied buffer.
+ * Buffer must be large enough to hold the requested number of bytes.
+ * Returns 0 on success, if all the requested bytes have been read.
+ * Returns -1 on error.
+ */
+int read_n(semanage_handle_t *sh, int socket_fd, int timeout, char *buf, size_t n)
+{
+ size_t total_read = 0;
+ ssize_t amount_read = 0;
+ struct timeval timeout_spec;
+ time_t start_time;
+ time_t current_time;
+ fd_set read_fds;
+
+ if (n == 0) {
+ return 0;
+ }
+ if (buf == NULL) {
+ return -1;
+ }
+
+ if (time(&start_time) < 0) {
+ return -1;
+ }
+
+ while (total_read < n) {
+ if (timeout > 0) {
+ FD_ZERO(&read_fds);
+ FD_SET(socket_fd, &read_fds);
+ timeout_spec.tv_sec = timeout;
+ timeout_spec.tv_usec = 0;
+ switch (select
+ (socket_fd + 1, &read_fds, NULL, NULL,
+ &timeout_spec)) {
+ case -1:
+ if (errno == EINTR) {
+ /* signal delivered */
+ continue;
+ } else {
+ return -1;
+ }
+ case 0:
+ /* timed out */
+ ERR(sh, "Server timout");
+ return -1;
+ }
+ if (!FD_ISSET(socket_fd, &read_fds))
+ return -1;
+ }
+ amount_read = read(socket_fd, buf + total_read, n - total_read);
+ if (amount_read == -1 && (errno == EINTR || errno == EAGAIN)) {
+ continue;
+ } else if (amount_read > 0) {
+ total_read += amount_read;
+ } else if (amount_read == 0) {
+ if (time(¤t_time) < 0) {
+ return -1;
+ } else {
+ if (difftime(start_time, current_time) >
+ timeout) {
+ /* timed out */
+ ERR(sh, "Server timout");
+ return -1;
+ }
+ }
+ } else {
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+/* Similar to read_n in that it reads a bunch of bytes from a socket.
+ * However, instead of storing them this function discards the values.
+ * Returns 0 on success, if all the requested bytes have been flushed.
+ * Returns -1 on error.
+ */
+int flush_n(semanage_handle_t *sh, int socket_fd, int timeout, uint64_t n)
+{
+ ssize_t amount_read;
+ struct timeval timeout_spec;
+ time_t start_time;
+ time_t current_time;
+ fd_set read_fds;
+ char buf[1024];
+
+ if (time(&start_time) < 0) {
+ return -1;
+ }
+
+ while (n > 0) {
+ if (timeout > 0) {
+ FD_ZERO(&read_fds);
+ FD_SET(socket_fd, &read_fds);
+ timeout_spec.tv_sec = timeout;
+ timeout_spec.tv_usec = 0;
+ switch (select
+ (socket_fd + 1, &read_fds, NULL, NULL,
+ &timeout_spec)) {
+ case -1:
+ if (errno == EINTR) {
+ /* signal delivered */
+ continue;
+ } else {
+ return -1;
+ }
+ case 0:
+ /* timed out */
+ ERR(sh, "Server timout");
+ return -1;
+ }
+ if (!FD_ISSET(socket_fd, &read_fds))
+ return -1;
+ }
+ amount_read = read(socket_fd, buf,
+ (n > sizeof(buf) ? sizeof(buf) : n));
+ if (amount_read == -1 && (errno == EINTR || errno == EAGAIN)) {
+ continue;
+ } else if (amount_read > 0) {
+ n -= amount_read;
+ } else if (amount_read == 0) {
+ if (time(¤t_time) < 0) {
+ return -1;
+ } else {
+ if (difftime(start_time, current_time) >
+ timeout) {
+ /* time out */
+ return -1;
+ }
+ }
+ } else {
+ /* error; bail */
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+/* Reads a single message from the given socket.
+ * message_type, data_length, and data are all set upon success.
+ * data_length may be 0, in which case data will be NULL.
+ * Caller is responsible for freeing a non-NULL data.
+ *
+ * Returns 0 on success.
+ * Returns -1 if we get an error when trying to read.
+ * Returns -2 if we cannot handle a message of the size received.
+ */
+int read_msg(semanage_handle_t *sh, int socket_fd, int timeout, uint32_t * message_type,
+ uint64_t * data_length, char **data)
+{
+ char msg_header[sizeof(uint32_t) + sizeof(uint64_t)];
+
+ /* initially just read the message header.
+ * this header contains the message type and data length. */
+ if (read_n(sh, socket_fd, timeout, msg_header, sizeof(msg_header)) == -1) {
+ return -1;
+ }
+
+ /* extract the message type */
+ memcpy(message_type, msg_header, sizeof(*message_type));
+ *message_type = le32_to_cpu(*message_type);
+
+ /* extract the length of the message data */
+ memcpy(data_length, msg_header + sizeof(*message_type),
+ sizeof(*data_length));
+ *data_length = le64_to_cpu(*data_length);
+
+ /* check whether data_length will fit in a size_t
+ (according to the description of <sys/types.h>
+ size_t must be declared as an unsigned integer.) */
+ if (*data_length > UINT_MAX) {
+ /* flush message data */
+ flush_n(sh, socket_fd, timeout, *data_length);
+ return -2;
+ }
+
+ /* if data was sent with this message, read it */
+ if (*data_length > 0) {
+ *data = calloc(*data_length, sizeof(char));
+ if (read_n(sh, socket_fd, timeout, *data, *data_length) == -1) {
+ free(*data);
+ *data = NULL;
+ *data_length = 0;
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+/* Write a single message to the given socket.
+ *
+ * Returns 0 on success.
+ * Returns -1 for write errors.
+ * Returns -2 if we cannot handle a message of the given size.
+ */
+int write_msg(semanage_handle_t *sh, int socket_fd, uint32_t message_type,
+ uint64_t data_length, char *data)
+{
+ char msg_header[sizeof(uint32_t) + sizeof(uint64_t)];
+ size_t data_len = 0;
+ size_t amount_to_write = 0;
+ size_t amount_written = 0;
+ int rc = 0;
+
+ /* check whether data_length will fit in a size_t
+ (according to the description of <sys/types.h>
+ size_t must be declared as an unsigned integer.) */
+ if (data_length > UINT_MAX) {
+ return -2;
+ }
+ data_len = data_length;
+
+ /* prepare message header */
+ message_type = cpu_to_le32(message_type);
+ memcpy(msg_header, &message_type, sizeof(message_type));
+ data_length = cpu_to_le64(data_length);
+ memcpy(msg_header + sizeof(message_type), &data_length,
+ sizeof(data_length));
+
+ /* write message header */
+ rc = write(socket_fd, msg_header, sizeof(msg_header));
+ if (rc != sizeof(msg_header))
+ return -1;
+
+ /* write message data */
+ while (data_len > 0) {
+ amount_to_write = (data_len > 1024) ? 1024 : data_len;
+ rc = write(socket_fd, data, amount_to_write);
+ amount_written = (rc > 0) ? rc : 0;
+ if (rc < 0) {
+ if (errno != EAGAIN) {
+ return -1;
+ }
+ } else {
+ data_len -= amount_written;
+ data += amount_written;
+ }
+ }
+ return 0;
+}
+
+/* Reads a response from the server.
+ *
+ * Note that read_server will keep reading responses from the server until
+ * a PS_OK or PS_ERR message is received. It ignores all other messages.
+ * If a PS_ERR message is received, read_server extracts the error code
+ * and sets data to the error string received from the server.
+ *
+ * data is allocated to hold any data sent by the server, and may be NULL.
+ * data may also be set to an error message on failure.
+ * data_length is set to the size of the data, and may be zero.
+ * Caller is responsible for freeing data if it is not NULL when returned.
+ *
+ * Returns 0 if server said okay, otherwise returns the positive error number.
+ * Returns -1 for generic errors, or if the server gave no error number.
+ * Returns -2 if we cannot handle a message of the size received.
+ *
+ */
+int read_server(semanage_handle_t *sh, int socket_fd, uint32_t * message_type,
+ uint64_t * data_length, char **data)
+{
+ int err = 0;
+ uint32_t server_error = 0;
+
+ /* read message */
+ err =
+ read_msg(sh, socket_fd, SEMANAGE_PS_DEFAULT_TIMEOUT, message_type,
+ data_length, data);
+ if (err)
+ return err;
+
+ /* interpret message type */
+ if (*message_type == PS_OK) {
+ return 0;
+ }
+ if (*message_type == PS_ERR) {
+ /* an error message has data of the form:
+ * uint32_t error_code
+ * char * error_string */
+ memcpy(&server_error, *data, sizeof(server_error));
+ server_error = le32_to_cpu(server_error);
+ memmove(*data, *data + sizeof(server_error),
+ *data_length - sizeof(server_error));
+ return server_error > 0 ? (int)server_error : -1;
+ }
+
+ /* we didn't get a PS_OK or a PS_ERR; try again */
+ *message_type = 0;
+ free(*data);
+ *data = NULL;
+ *data_length = 0;
+ return read_server(sh, socket_fd, message_type, data_length, data);
+}
Index: selinux-pms-support/libsemanage/src/messages_internal.h
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/src/messages_internal.h
@@ -0,0 +1,39 @@
+/* Author: Caleb Case <ccase@tresys.com>
+ * Christopher Ashworth <cashworth@tresys.com>
+ *
+ * Copyright (C) 2004-2007 Tresys Technology, LLC
+ * Copyright (C) 2005 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#ifndef _SEMANAGE_MESSAGES_INTERNAL_H_
+#define _SEMANAGE_MESSAGES_INTERNAL_H_
+
+#include <sys/types.h>
+
+#include <semanage/messages.h>
+
+int read_n(semanage_handle_t *sh, int socket_fd, int timeout, char *buf, size_t n);
+int flush_n(semanage_handle_t *sh, int socket_fd, int timeout, uint64_t n);
+int read_msg(semanage_handle_t *sh, int socket_fd, int timeout, uint32_t * message_type,
+ uint64_t * data_length, char **data);
+int write_msg(semanage_handle_t *sh, int socket_fd, uint32_t message_type,
+ uint64_t data_length, char *data);
+int read_server(semanage_handle_t *sh, int socket_fd, uint32_t * message_type,
+ uint64_t * data_length, char **data);
+
+#endif
--
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH 25/33] libsemanage: policy server database hooks
2007-04-23 21:34 [PATCH 00/33] libsemanage/libsepol object serialization and ps-api jbrindle
` (23 preceding siblings ...)
2007-04-23 21:35 ` [PATCH 24/33] libsemanage: networking support jbrindle
@ 2007-04-23 21:35 ` jbrindle
2007-04-24 21:39 ` Karl MacMillan
2007-04-23 21:35 ` [PATCH 26/33] libsemanage: module serialization tests jbrindle
` (9 subsequent siblings)
34 siblings, 1 reply; 58+ messages in thread
From: jbrindle @ 2007-04-23 21:35 UTC (permalink / raw)
To: selinux
Implements all database functions for a policy server backend.
---
libsemanage/include/semanage/database_ps.h | 37 +
libsemanage/include/semanage/handle.h | 7
libsemanage/include/semanage/semanage.h | 4
libsemanage/src/booleans_ps.c | 100 ++++
libsemanage/src/database.h | 9
libsemanage/src/database_ps.c | 368 +++++++++++++++
libsemanage/src/database_ps.h | 55 ++
libsemanage/src/fcontexts_ps.c | 59 ++
libsemanage/src/handle.c | 41 +
libsemanage/src/handle.h | 2
libsemanage/src/handle_internal.h | 2
libsemanage/src/interfaces_ps.c | 78 +++
libsemanage/src/libsemanage.map | 2
libsemanage/src/nodes_ps.c | 78 +++
libsemanage/src/ports_ps.c | 78 +++
libsemanage/src/ps_api.c | 690 +++++++++++++++++++++++++++++
libsemanage/src/ps_api.h | 31 +
libsemanage/src/seusers_ps.c | 58 ++
libsemanage/src/users_ps.c | 82 +++
libsemanage/tests/globals.h | 39 +
libsemanage/tests/libsemanage-tests.c | 16
libsemanage/tests/test_ps_api_connect.c | 346 ++++++++++++++
libsemanage/tests/test_ps_api_connect.h | 33 +
libsemanage/tests/test_ps_api_disconnect.c | 178 +++++++
libsemanage/tests/test_ps_api_disconnect.h | 33 +
25 files changed, 2412 insertions(+), 14 deletions(-)
Index: selinux-pms-support/libsemanage/include/semanage/database_ps.h
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/include/semanage/database_ps.h
@@ -0,0 +1,37 @@
+/* Authors: Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _SEMANAGE_DATABASE_PS_H_
+#define _SEMANAGE_DATABASE_PS_H_
+
+#include <stdio.h>
+#include "handle.h"
+
+#ifndef DBASE_CONFIG
+#define DBASE_CONFIG
+typedef struct dbase_config dbase_config_t;
+#endif
+
+/* PS - database type handling */
+extern int semanage_dbase_ps_get_database_type(semanage_handle_t *sh, dbase_config_t *dconfig, uint32_t * database_type);
+extern int semanage_dbase_ps_set_database_type(semanage_handle_t *sh, dbase_config_t *dconfig, uint32_t database_type);
+extern int semanage_dbase_ps_database_type_serialize(semanage_handle_t *sh, uint32_t database_type, char **data, uint64_t *size);
+extern int semanage_dbase_ps_database_type_unserialize(semanage_handle_t *sh, char **data, uint64_t *size, uint32_t *database_type) ;
+
+#endif
Index: selinux-pms-support/libsemanage/include/semanage/handle.h
===================================================================
--- selinux-pms-support.orig/libsemanage/include/semanage/handle.h
+++ selinux-pms-support/libsemanage/include/semanage/handle.h
@@ -26,6 +26,8 @@
#include <inttypes.h>
+#include <sepol/handle.h>
+
/* All accesses with semanage are through a "semanage_handle". The
* handle may ultimately reference local config files,
* the binary policy file, a module store, or a policy management server.
@@ -66,7 +68,7 @@ enum semanage_connect_type {
* It must be called after semanage_handle_create but before
* semanage_connect. The argument should be the full path to the store.
*/
-void semanage_select_store(semanage_handle_t * handle, char *path,
+void semanage_select_store(semanage_handle_t * handle, const char *path,
enum semanage_connect_type storetype);
/* Just reload the policy */
@@ -81,6 +83,9 @@ void semanage_set_reload(semanage_handle
* 1 for yes, 0 for no (default) */
void semanage_set_rebuild(semanage_handle_t * handle, int do_rebuild);
+/* returns the sepol handle associated with this handle */
+sepol_handle_t *semanage_get_sepol_handle(semanage_handle_t * sh);
+
/* create the store if it does not exist, this only has an effect on
* direct connections and must be called before semanage_connect
* 1 for yes, 0 for no (default) */
Index: selinux-pms-support/libsemanage/include/semanage/semanage.h
===================================================================
--- selinux-pms-support.orig/libsemanage/include/semanage/semanage.h
+++ selinux-pms-support/libsemanage/include/semanage/semanage.h
@@ -24,6 +24,7 @@
#include <semanage/handle.h>
#include <semanage/modules.h>
+#include <semanage/policy.h>
#include <semanage/debug.h>
/* Records */
@@ -55,4 +56,7 @@
/* Messaging */
#include <semanage/messages.h>
+/* Database types */
+#include <semanage/database_ps.h>
+
#endif
Index: selinux-pms-support/libsemanage/src/booleans_ps.c
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/src/booleans_ps.c
@@ -0,0 +1,100 @@
+/* Authors: Ivan Gyurdiev <ivg2@cornell.edu>
+ * Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ * Copyright (C) 2005 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+struct semanage_boolean;
+struct semanage_boolean_key;
+typedef struct semanage_boolean record_t;
+typedef struct semanage_boolean_key record_key_t;
+#define DBASE_RECORD_DEFINED
+
+struct dbase_file;
+typedef struct dbase_file dbase_t;
+#define DBASE_DEFINED
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <strings.h>
+#include <semanage/handle.h>
+#include "boolean_internal.h"
+#include "database_ps.h"
+#include "debug.h"
+
+int bool_ps_local_dbase_init(semanage_handle_t * handle,
+ uint32_t sandbox_id, dbase_config_t * dconfig)
+{
+ if (dbase_ps_init(
+ handle,
+ sandbox_id,
+ &SEMANAGE_BOOL_RTABLE,
+ (dbase_ps_t **)(&dconfig->dbase)) < 0)
+ return STATUS_ERR;
+
+ dconfig->dtable = &SEMANAGE_PS_DTABLE;
+ return STATUS_SUCCESS;
+}
+
+void bool_ps_local_dbase_release(dbase_config_t * dconfig)
+{
+ dbase_ps_release((dbase_ps_t *) dconfig->dbase);
+}
+
+int bool_ps_policydb_dbase_init(semanage_handle_t * handle,
+ uint32_t sandbox_id,
+ dbase_config_t * dconfig)
+{
+
+ if (dbase_ps_init(
+ handle,
+ sandbox_id,
+ &SEMANAGE_BOOL_RTABLE,
+ (dbase_ps_t **)&dconfig->dbase) < 0)
+ return STATUS_ERR;
+
+ dconfig->dtable = &SEMANAGE_PS_POLICYDB_DTABLE;
+ return STATUS_SUCCESS;
+}
+
+void bool_ps_policydb_dbase_release(dbase_config_t * dconfig)
+{
+ dbase_ps_release((dbase_ps_t *) dconfig->dbase);
+}
+
+int bool_ps_activedb_dbase_init(semanage_handle_t * handle,
+ uint32_t sandbox_id,
+ dbase_config_t * dconfig)
+{
+ if (dbase_ps_init(
+ handle,
+ sandbox_id,
+ &SEMANAGE_BOOL_RTABLE,
+ (dbase_ps_t **)&dconfig->dbase) < 0)
+ return STATUS_ERR;
+
+ dconfig->dtable = &SEMANAGE_PS_ACTIVEDB_DTABLE;
+ return STATUS_SUCCESS;
+}
+
+void bool_ps_activedb_dbase_release(dbase_config_t * dconfig)
+{
+ dbase_ps_release((dbase_ps_t *) dconfig->dbase);
+}
+
Index: selinux-pms-support/libsemanage/src/database.h
===================================================================
--- selinux-pms-support.orig/libsemanage/src/database.h
+++ selinux-pms-support/libsemanage/src/database.h
@@ -209,7 +209,7 @@ typedef struct dbase_table {
} dbase_table_t;
-typedef struct dbase_config {
+struct dbase_config {
/* Database state */
dbase_t *dbase;
@@ -217,7 +217,12 @@ typedef struct dbase_config {
/* Database methods */
dbase_table_t *dtable;
-} dbase_config_t;
+};
+
+#ifndef DBASE_CONFIG
+#define DBASE_CONFIG
+typedef struct dbase_config dbase_config_t;
+#endif
extern int dbase_add(struct semanage_handle *handle,
dbase_config_t * dconfig,
Index: selinux-pms-support/libsemanage/src/database_ps.c
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/src/database_ps.c
@@ -0,0 +1,368 @@
+/* Authors: Ivan Gyurdiev <ivg2@cornell.edu>
+ * Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ * Copyright (C) 2005 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* Object: dbase_ps_t (Policy Server)
+ * Extends: dbase_llist_t (Linked List)
+ * Implements: dbase_t (Database)
+ */
+
+struct dbase_ps;
+typedef struct dbase_ps dbase_t;
+#define DBASE_DEFINED
+
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdio_ext.h>
+#include "debug.h"
+#include "handle.h"
+#include "database_ps.h"
+#include "database_llist.h"
+#include "database_policydb.h"
+#include "byteswap.h"
+#include "messages_internal.h"
+#include "semanage_store.h"
+#include "serialize.h"
+
+/* PS dbase */
+struct dbase_ps {
+
+ /* Parent object - must always be
+ * the first field. For example,
+ * the generic database "add" function
+ * passes the dbase_ps as a dbase_t,
+ * but the internal dbase_llist_add
+ * function treats it as a dbase_llist_t
+ * without dereferencing the llist field. */
+ dbase_llist_t llist;
+
+ /* Enumerated database type.
+ * (i.e. Which database is this?) */
+ uint32_t database_type;
+
+};
+
+/* Get database type. */
+int semanage_dbase_ps_get_database_type(semanage_handle_t *sh, dbase_config_t *dconfig, uint32_t * database_type)
+{
+ *database_type = dconfig->dbase->database_type;
+ return STATUS_SUCCESS;
+}
+
+hidden_def(semanage_dbase_ps_get_database_type)
+
+/* Set database type. */
+int semanage_dbase_ps_set_database_type(semanage_handle_t *sh, dbase_config_t *dconfig, uint32_t database_type)
+{
+ dconfig->dbase->database_type = database_type;
+ return STATUS_SUCCESS;
+}
+
+hidden_def(semanage_dbase_ps_set_database_type)
+
+/* Serialize database type. */
+int semanage_dbase_ps_database_type_serialize(semanage_handle_t *sh, uint32_t database_type, char **data, uint64_t *size)
+{
+ int status = STATUS_SUCCESS;
+ char *ptr = NULL;
+
+ /* Sundry sanity checks. */
+ if (data == NULL || size == NULL) {
+ status = STATUS_ERR;
+ goto cleanup;
+ }
+
+ /* Calculate size. */
+ status = semanage_serialize(sh, &database_type, 0, SEMANAGE_SERIAL_UINT32_T, NULL, size);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Allocate memory. */
+ ptr = *data = calloc(*size, sizeof(char));
+ if (*data == NULL) {
+ status = STATUS_ERR;
+ goto cleanup;
+ }
+
+ /* Serialize. */
+ status = semanage_serialize(sh, &database_type, 0, SEMANAGE_SERIAL_UINT32_T, &ptr, NULL);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+cleanup:
+ return status;
+
+}
+
+hidden_def(semanage_dbase_ps_database_type_serialize)
+
+/* Unserialize database type. */
+int semanage_dbase_ps_database_type_unserialize(semanage_handle_t *sh, char **data, uint64_t *size, uint32_t *database_type)
+{
+ int status = STATUS_SUCCESS;
+ uint32_t *datum = NULL;
+ size_t *datum_length = NULL;
+
+ /* Sundry sanity checks. */
+ if (data == NULL || *data == NULL || size == NULL) {
+ status = STATUS_ERR;
+ goto cleanup;
+ }
+
+ status = semanage_unserialize(sh, data, size, (void **)&datum, &datum_length, SEMANAGE_SERIAL_UINT32_T);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ *database_type = *datum;
+
+cleanup:
+ free(datum);
+ free(datum_length);
+ return status;
+}
+
+hidden_def(semanage_dbase_ps_database_type_unserialize)
+
+/* Load database from server. */
+static int dbase_ps_cache(semanage_handle_t * handle, dbase_config_t * dconfig)
+{
+ dbase_ps_t *dbase = dconfig->dbase;
+
+ int fd = handle->u.ps_handle.socket_fd;
+ uint32_t message_type = 0;
+ uint64_t data_length = 0;
+ char *data = NULL;
+
+ /* Already cached? */
+ if (!dbase_llist_needs_resync(handle, &dbase->llist))
+ return STATUS_SUCCESS;
+
+ /* Check that we're connected. */
+ if (fd < 0)
+ goto err;
+
+ /* Update cache serial. */
+ dbase_llist_cache_init(&dbase->llist);
+ if (dbase_llist_set_serial(handle, &dbase->llist) < 0)
+ goto err;
+
+ /* Retrieve serialized records from the server. */
+ /* The data sent with a GET_DATABASE message is
+ * the database_type of this database, so the server
+ * knows which one to send back. */
+ if (semanage_dbase_ps_database_type_serialize(handle, dbase->database_type, &data, &data_length) != STATUS_SUCCESS)
+ goto err;
+
+ if (write_msg(handle, fd, PS_GET_DATABASE, data_length, data))
+ goto err;
+
+ data = NULL;
+ data_length = 0;
+ if (read_server(handle, fd, &message_type, &data_length, &data))
+ goto err;
+
+ if (message_type != PS_OK)
+ goto err;
+
+ /* Unserialize the records into our database. */
+ if (dbase_unserialize(handle, dconfig, data, data_length))
+ goto err;
+
+ /* Clean up. */
+ free(data);
+ return STATUS_SUCCESS;
+
+ err:
+ ERR(handle, "could not cache file database");
+ free(data);
+ dbase_llist_drop_cache(&dbase->llist);
+ return STATUS_ERR;
+}
+
+/* Flush database to server */
+static int dbase_ps_flush(semanage_handle_t * handle, dbase_config_t * dconfig)
+{
+ int fd = handle->u.ps_handle.socket_fd;
+ uint32_t message_type = 0;
+ uint64_t data_length = 0;
+ char *data = NULL;
+ uint64_t records_length = 0;
+ char *records = NULL;
+ uint64_t type_length = 0;
+ char *type = NULL;
+ dbase_ps_t *dbase = dconfig->dbase;
+
+ /* Any changes to flush? */
+ if (!dbase_llist_is_modified(&dbase->llist))
+ return STATUS_SUCCESS;
+
+ /* Check that we're connected. */
+ if (fd < 0)
+ goto err;
+
+ /* Serialize the database type. */
+ if (semanage_dbase_ps_database_type_serialize(handle, dbase->database_type, &type, &type_length) != STATUS_SUCCESS)
+ goto err;
+
+ /* Serialize the database records. */
+ if (dbase_serialize(handle, dconfig, &records, &records_length))
+ goto err;
+
+ /* Combine the buffers. */
+ data_length = type_length + records_length;
+ data = calloc(data_length, sizeof(char));
+ if (data == NULL)
+ goto err;
+ memcpy(data, type, type_length);
+ memcpy(data + type_length, records, records_length);
+
+ /* Send serialized records to the server. */
+ if (write_msg(handle, fd, PS_PUT_DATABASE, data_length, data))
+ goto err;
+
+ /* Check response. */
+ if (read_server(handle, fd, &message_type, &data_length, &data))
+ goto err;
+
+ if (message_type != PS_OK)
+ goto err;
+
+ dbase_llist_set_modified(&dbase->llist, 0);
+
+ /* Clean up. */
+ free(data);
+
+ return STATUS_SUCCESS;
+
+ err:
+ ERR(handle, "could not flush database to policy server");
+ free(data);
+ free(type);
+ free(records);
+ return STATUS_ERR;
+}
+
+int dbase_ps_init(semanage_handle_t * handle,
+ uint32_t sandbox_id,
+ record_table_t * rtable, dbase_ps_t ** dbase)
+{
+ dbase_ps_t *tmp_dbase = (dbase_ps_t *) malloc(sizeof(dbase_ps_t));
+
+ if (!tmp_dbase)
+ goto omem;
+
+ tmp_dbase->database_type = sandbox_id;
+ dbase_llist_init(&tmp_dbase->llist, rtable);
+
+ *dbase = tmp_dbase;
+
+ return STATUS_SUCCESS;
+
+ omem:
+ ERR(handle,
+ "out of memory, could not initialize policy server database");
+ free(tmp_dbase);
+ return STATUS_ERR;
+}
+
+/* Release dbase resources */
+void dbase_ps_release(dbase_ps_t * dbase)
+{
+ dbase_llist_drop_cache(&dbase->llist);
+ free(dbase);
+}
+
+/* PS dbase - method table implementation */
+dbase_table_t SEMANAGE_PS_DTABLE = {
+
+ /* Cache/Transactions */
+ .cache = dbase_ps_cache,
+ .drop_cache = (void *)dbase_llist_drop_cache,
+ .flush = dbase_ps_flush,
+ .is_modified = (void *)dbase_llist_is_modified,
+
+ /* Database API */
+ .iterate = (void *)dbase_llist_iterate,
+ .exists = (void *)dbase_llist_exists,
+ .list = (void *)dbase_llist_list,
+ .add = (void *)dbase_llist_add,
+ .set = (void *)dbase_llist_set,
+ .del = (void *)dbase_llist_del,
+ .clear = (void *)dbase_llist_clear,
+ .modify = (void *)dbase_llist_modify,
+ .query = (void *)dbase_llist_query,
+ .count = (void *)dbase_llist_count,
+
+ /* Polymorphism */
+ .get_rtable = (void *)dbase_llist_get_rtable
+};
+
+/* PS POLICYDB dbase - method table implementation */
+dbase_table_t SEMANAGE_PS_POLICYDB_DTABLE = {
+ /* Cache/Transactions */
+ .cache = dbase_ps_cache,
+ .drop_cache = (void *)dbase_llist_drop_cache,
+ .flush = dbase_policydb_flush,
+ .is_modified = (void *)dbase_llist_is_modified,
+
+ /* Database API */
+ .iterate = (void *)dbase_llist_iterate,
+ .exists = (void *)dbase_llist_exists,
+ .list = (void *)dbase_llist_list,
+ .add = (void *)dbase_llist_add,
+ .set = (void *)dbase_llist_set,
+ .del = (void *)dbase_llist_del,
+ .clear = (void *)dbase_llist_clear,
+ .modify = (void *)dbase_llist_modify,
+ .query = (void *)dbase_llist_query,
+ .count = (void *)dbase_llist_count,
+
+ /* Polymorphism */
+ .get_rtable = (void *)dbase_llist_get_rtable
+};
+
+/* PS ACTIVEDB dbase - method table implementation */
+dbase_table_t SEMANAGE_PS_ACTIVEDB_DTABLE = {
+
+ /* Cache/Transactions */
+ .cache = dbase_ps_cache,
+ .drop_cache = (void *)dbase_llist_drop_cache,
+ .flush = dbase_ps_flush,
+ .is_modified = (void *)dbase_llist_is_modified,
+
+ /* Database API */
+ .iterate = (void *)dbase_llist_iterate,
+ .exists = (void *)dbase_llist_exists,
+ .list = (void *)dbase_llist_list,
+ .add = (void *)dbase_llist_add,
+ .set = (void *)dbase_llist_set,
+ .del = (void *)dbase_llist_del,
+ .clear = (void *)dbase_llist_clear,
+ .modify = (void *)dbase_llist_modify,
+ .query = (void *)dbase_llist_query,
+ .count = (void *)dbase_llist_count,
+
+ /* Polymorphism */
+ .get_rtable = (void *)dbase_llist_get_rtable
+};
Index: selinux-pms-support/libsemanage/src/database_ps.h
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/src/database_ps.h
@@ -0,0 +1,55 @@
+/* Authors: Ivan Gyurdiev <ivg2@cornell.edu>
+ * Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ * Copyright (C) 2005 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _SEMANAGE_DATABASE_PS_INTERNAL_H_
+#define _SEMANAGE_DATABASE_PS_INTERNAL_H_
+
+#include <stdio.h>
+
+#include <semanage/database_ps.h>
+
+#include "database.h"
+#include "handle.h"
+
+struct dbase_ps;
+typedef struct dbase_ps dbase_ps_t;
+
+/* PS - initialization */
+extern int dbase_ps_init(semanage_handle_t * handle,
+ uint32_t sandbox_id,
+ record_table_t * rtable, dbase_ps_t ** dbase);
+
+/* PS - release */
+extern void dbase_ps_release(dbase_ps_t * dbase);
+
+/* PS - method table implementation */
+extern dbase_table_t SEMANAGE_PS_DTABLE;
+extern dbase_table_t SEMANAGE_PS_POLICYDB_DTABLE;
+extern dbase_table_t SEMANAGE_PS_ACTIVEDB_DTABLE;
+
+/* PS - database type handling */
+hidden_proto(semanage_dbase_ps_get_database_type)
+hidden_proto(semanage_dbase_ps_set_database_type)
+hidden_proto(semanage_dbase_ps_database_type_serialize)
+hidden_proto(semanage_dbase_ps_database_type_unserialize)
+
+#endif
Index: selinux-pms-support/libsemanage/src/fcontexts_ps.c
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/src/fcontexts_ps.c
@@ -0,0 +1,59 @@
+/* Authors: Ivan Gyurdiev <ivg2@cornell.edu>
+ * Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ * Copyright (C) 2005 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+struct semanage_fcontext;
+struct semanage_fcontext_key;
+typedef struct semanage_fcontext record_t;
+typedef struct semanage_fcontext_key record_key_t;
+#define DBASE_RECORD_DEFINED
+
+struct dbase_file;
+typedef struct dbase_file dbase_t;
+#define DBASE_DEFINED
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <strings.h>
+#include <semanage/handle.h>
+#include "fcontext_internal.h"
+#include "context_internal.h"
+#include "database_ps.h"
+#include "debug.h"
+
+int fcontext_ps_local_dbase_init(semanage_handle_t * handle,
+ uint32_t sandbox_id, dbase_config_t * dconfig)
+{
+ if (dbase_ps_init(
+ handle,
+ sandbox_id,
+ &SEMANAGE_FCONTEXT_RTABLE,
+ (dbase_ps_t **)(&dconfig->dbase)) < 0)
+ return STATUS_ERR;
+
+ dconfig->dtable = &SEMANAGE_PS_DTABLE;
+ return STATUS_SUCCESS;
+}
+
+void fcontext_ps_local_dbase_release(dbase_config_t * dconfig)
+{
+ dbase_ps_release((dbase_ps_t *) dconfig->dbase);
+}
Index: selinux-pms-support/libsemanage/src/handle.c
===================================================================
--- selinux-pms-support.orig/libsemanage/src/handle.c
+++ selinux-pms-support/libsemanage/src/handle.c
@@ -26,11 +26,13 @@
#include <stdarg.h>
#include <assert.h>
#include <stdlib.h>
+#include <string.h>
#include <stdio.h>
#include <sys/time.h>
#include "direct_api.h"
#include "handle.h"
+#include "handle_internal.h"
#include "debug.h"
#include "semanage_conf.h"
#include "semanage_store.h"
@@ -143,7 +145,7 @@ int semanage_is_connected(semanage_handl
return sh->is_connected;
}
-void semanage_select_store(semanage_handle_t * sh, char *storename,
+void semanage_select_store(semanage_handle_t * sh, const char *storename,
enum semanage_connect_type storetype)
{
@@ -151,12 +153,20 @@ void semanage_select_store(semanage_hand
/* This just sets the storename to what the user requests, no
verification of existance will be done until connect */
- sh->conf->store_path = storename;
+ sh->conf->store_path = strdup(storename);
sh->conf->store_type = storetype;
return;
}
+sepol_handle_t *semanage_get_sepol_handle(semanage_handle_t * sh)
+{
+ assert(sh != NULL);
+ return sh->sepolh;
+}
+
+hidden_def(semanage_get_sepol_handle)
+
int semanage_is_managed(semanage_handle_t * sh)
{
assert(sh != NULL);
@@ -167,6 +177,9 @@ int semanage_is_managed(semanage_handle_
switch (sh->conf->store_type) {
case SEMANAGE_CON_DIRECT:
return semanage_direct_is_managed(sh);
+ case SEMANAGE_CON_POLSERV_REMOTE:
+ case SEMANAGE_CON_POLSERV_LOCAL:
+ return semanage_ps_is_managed(sh);
default:
ERR(sh,
"The connection type specified within your semanage.conf file has not been implemented yet.");
@@ -179,17 +192,21 @@ int semanage_connect(semanage_handle_t *
{
assert(sh != NULL);
switch (sh->conf->store_type) {
- case SEMANAGE_CON_DIRECT:{
- if (semanage_direct_connect(sh) < 0) {
- return -1;
- }
- break;
+ case SEMANAGE_CON_DIRECT:
+ if (semanage_direct_connect(sh) < 0) {
+ return -1;
}
- default:{
- ERR(sh,
- "The connection type specified within your semanage.conf file has not been implemented yet.");
+ break;
+ case SEMANAGE_CON_POLSERV_REMOTE:
+ case SEMANAGE_CON_POLSERV_LOCAL:
+ if (semanage_ps_connect(sh) < 0) {
return -1;
}
+ break;
+ default:
+ ERR(sh,
+ "The connection type specified within your semanage.conf file has not been implemented yet.");
+ return -1;
}
sh->is_connected = 1;
return 0;
@@ -201,6 +218,10 @@ int semanage_access_check(semanage_handl
switch (sh->conf->store_type) {
case SEMANAGE_CON_DIRECT:
return semanage_direct_access_check(sh);
+ case SEMANAGE_CON_POLSERV_REMOTE:
+ case SEMANAGE_CON_POLSERV_LOCAL:
+ /* FIXME: for now just say we have access */
+ return SEMANAGE_CAN_WRITE;
default:
return -1;
}
Index: selinux-pms-support/libsemanage/src/handle.h
===================================================================
--- selinux-pms-support.orig/libsemanage/src/handle.h
+++ selinux-pms-support/libsemanage/src/handle.h
@@ -30,6 +30,7 @@
#include "semanage_conf.h"
#include "database.h"
#include "direct_api.h"
+#include "ps_api.h"
#include "policy.h"
struct semanage_handle {
@@ -49,6 +50,7 @@ struct semanage_handle {
/* Direct vs Server specific handle */
union {
struct semanage_direct_handle direct;
+ struct semanage_ps_handle ps_handle;
} u;
/* Libsepol handle */
Index: selinux-pms-support/libsemanage/src/handle_internal.h
===================================================================
--- selinux-pms-support.orig/libsemanage/src/handle_internal.h
+++ selinux-pms-support/libsemanage/src/handle_internal.h
@@ -12,5 +12,5 @@ hidden_proto(semanage_handle_get_version
hidden_proto(semanage_handle_set_version)
hidden_proto(semanage_handle_version_serialize)
hidden_proto(semanage_handle_version_unserialize)
-
+hidden_proto(semanage_get_sepol_handle)
#endif
Index: selinux-pms-support/libsemanage/src/interfaces_ps.c
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/src/interfaces_ps.c
@@ -0,0 +1,78 @@
+/* Authors: Ivan Gyurdiev <ivg2@cornell.edu>
+ * Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ * Copyright (C) 2005 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+struct semanage_iface;
+struct semanage_iface_key;
+typedef struct semanage_iface record_t;
+typedef struct semanage_iface_key record_key_t;
+#define DBASE_RECORD_DEFINED
+
+struct dbase_file;
+typedef struct dbase_file dbase_t;
+#define DBASE_DEFINED
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <strings.h>
+#include <semanage/handle.h>
+#include "iface_internal.h"
+#include "database_ps.h"
+#include "debug.h"
+
+int iface_ps_local_dbase_init(semanage_handle_t * handle,
+ uint32_t sandbox_id, dbase_config_t * dconfig)
+{
+ if (dbase_ps_init(
+ handle,
+ sandbox_id,
+ &SEMANAGE_IFACE_RTABLE,
+ (dbase_ps_t **)(&dconfig->dbase)) < 0)
+ return STATUS_ERR;
+
+ dconfig->dtable = &SEMANAGE_PS_DTABLE;
+ return STATUS_SUCCESS;
+}
+
+void iface_ps_local_dbase_release(dbase_config_t * dconfig)
+{
+ dbase_ps_release((dbase_ps_t *) dconfig->dbase);
+}
+
+int iface_ps_policydb_dbase_init(semanage_handle_t * handle,
+ uint32_t sandbox_id,
+ dbase_config_t * dconfig)
+{
+ if (dbase_ps_init(
+ handle,
+ sandbox_id,
+ &SEMANAGE_IFACE_RTABLE,
+ (dbase_ps_t **)(&dconfig->dbase)) < 0)
+ return STATUS_ERR;
+
+ dconfig->dtable = &SEMANAGE_PS_POLICYDB_DTABLE;
+ return STATUS_SUCCESS;
+}
+
+void iface_ps_policydb_dbase_release(dbase_config_t * dconfig)
+{
+ dbase_ps_release((dbase_ps_t *) dconfig->dbase);
+}
Index: selinux-pms-support/libsemanage/src/libsemanage.map
===================================================================
--- selinux-pms-support.orig/libsemanage/src/libsemanage.map
+++ selinux-pms-support/libsemanage/src/libsemanage.map
@@ -1,5 +1,6 @@
LIBSEMANAGE_1.0 {
global: semanage_handle_create; semanage_handle_destroy;
+ semanage_get_sepol_handle;
semanage_is_managed; semanage_connect; semanage_disconnect;
semanage_msg_*;
semanage_begin_transaction; semanage_commit;
@@ -16,6 +17,7 @@ LIBSEMANAGE_1.0 {
semanage_fcontext_*; semanage_access_check; semanage_set_create_store;
semanage_*_serialize; semanage_*_unserialize;
semanage_is_connected;
+ semanage_handle_get_version; semanage_handle_set_version;
semanage_policy_table_serialize_serial;
local: *;
};
Index: selinux-pms-support/libsemanage/src/nodes_ps.c
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/src/nodes_ps.c
@@ -0,0 +1,78 @@
+/* Authors: Ivan Gyurdiev <ivg2@cornell.edu>
+ * Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ * Copyright (C) 2005 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+struct semanage_node;
+struct semanage_node_key;
+typedef struct semanage_node record_t;
+typedef struct semanage_node_key record_key_t;
+#define DBASE_RECORD_DEFINED
+
+struct dbase_file;
+typedef struct dbase_file dbase_t;
+#define DBASE_DEFINED
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <strings.h>
+#include <semanage/handle.h>
+#include "node_internal.h"
+#include "database_ps.h"
+#include "debug.h"
+
+int node_ps_local_dbase_init(semanage_handle_t * handle,
+ uint32_t sandbox_id, dbase_config_t * dconfig)
+{
+ if (dbase_ps_init(
+ handle,
+ sandbox_id,
+ &SEMANAGE_NODE_RTABLE,
+ (dbase_ps_t **)(&dconfig->dbase)) < 0)
+ return STATUS_ERR;
+
+ dconfig->dtable = &SEMANAGE_PS_DTABLE;
+ return STATUS_SUCCESS;
+}
+
+void node_ps_local_dbase_release(dbase_config_t * dconfig)
+{
+ dbase_ps_release((dbase_ps_t *) dconfig->dbase);
+}
+
+int node_ps_policydb_dbase_init(semanage_handle_t * handle,
+ uint32_t sandbox_id,
+ dbase_config_t * dconfig)
+{
+ if (dbase_ps_init(
+ handle,
+ sandbox_id,
+ &SEMANAGE_NODE_RTABLE,
+ (dbase_ps_t **)(&dconfig->dbase)) < 0)
+ return STATUS_ERR;
+
+ dconfig->dtable = &SEMANAGE_PS_POLICYDB_DTABLE;
+ return STATUS_SUCCESS;
+}
+
+void node_ps_policydb_dbase_release(dbase_config_t * dconfig)
+{
+ dbase_ps_release((dbase_ps_t *) dconfig->dbase);
+}
Index: selinux-pms-support/libsemanage/src/ports_ps.c
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/src/ports_ps.c
@@ -0,0 +1,78 @@
+/* Authors: Ivan Gyurdiev <ivg2@cornell.edu>
+ * Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ * Copyright (C) 2005 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+struct semanage_port;
+struct semanage_port_key;
+typedef struct semanage_port record_t;
+typedef struct semanage_port_key record_key_t;
+#define DBASE_RECORD_DEFINED
+
+struct dbase_file;
+typedef struct dbase_file dbase_t;
+#define DBASE_DEFINED
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <strings.h>
+#include <semanage/handle.h>
+#include "port_internal.h"
+#include "database_ps.h"
+#include "debug.h"
+
+int port_ps_local_dbase_init(semanage_handle_t * handle,
+ uint32_t sandbox_id, dbase_config_t * dconfig)
+{
+ if (dbase_ps_init(
+ handle,
+ sandbox_id,
+ &SEMANAGE_PORT_RTABLE,
+ (dbase_ps_t **)(&dconfig->dbase)) < 0)
+ return STATUS_ERR;
+
+ dconfig->dtable = &SEMANAGE_PS_DTABLE;
+ return STATUS_SUCCESS;
+}
+
+void port_ps_local_dbase_release(dbase_config_t * dconfig)
+{
+ dbase_ps_release((dbase_ps_t *) dconfig->dbase);
+}
+
+int port_ps_policydb_dbase_init(semanage_handle_t * handle,
+ uint32_t sandbox_id,
+ dbase_config_t * dconfig)
+{
+ if (dbase_ps_init(
+ handle,
+ sandbox_id,
+ &SEMANAGE_PORT_RTABLE,
+ (dbase_ps_t **)(&dconfig->dbase)) < 0)
+ return STATUS_ERR;
+
+ dconfig->dtable = &SEMANAGE_PS_POLICYDB_DTABLE;
+ return STATUS_SUCCESS;
+}
+
+void port_ps_policydb_dbase_release(dbase_config_t * dconfig)
+{
+ dbase_ps_release((dbase_ps_t *) dconfig->dbase);
+}
Index: selinux-pms-support/libsemanage/src/ps_api.c
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/src/ps_api.c
@@ -0,0 +1,690 @@
+/* Author: Jason Tang <jtang@tresys.com>
+ * Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2004-2007 Tresys Technology, LLC
+ * Copyright (C) 2005 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+/*
+ * ps_api.c
+ *
+ * Implements the module management functions that communicate
+ * with a remote policy server.
+ *
+ */
+
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <selinux/selinux.h>
+
+#include "debug.h"
+#include "byteswap.h"
+#include "handle.h"
+#include "modules.h"
+#include "policy.h"
+#include "ps_api.h"
+#include "messages_internal.h"
+#include "semanage_store.h"
+#include "database_policydb.h"
+#include "user_internal.h"
+#include "seuser_internal.h"
+#include "port_internal.h"
+#include "iface_internal.h"
+#include "boolean_internal.h"
+#include "fcontext_internal.h"
+#include "node_internal.h"
+#include "serialize.h"
+
+/* Policy server variants of the semanage functions.
+ */
+struct semanage_policy_table ps_funcs = {
+ .get_serial = semanage_ps_get_commit_number,
+ .destroy = semanage_ps_destroy,
+ .disconnect = semanage_ps_disconnect,
+ .begin_trans = semanage_ps_begintrans,
+ .commit = semanage_ps_commit,
+ .install = semanage_ps_install_module,
+ .upgrade = semanage_ps_upgrade_module,
+ .remove = semanage_ps_remove_module,
+ .list = semanage_ps_list_modules,
+ .install_base = semanage_ps_install_base_module
+};
+
+static int connect_local(semanage_handle_t * sh);
+static int connect_remote(semanage_handle_t * sh);
+static int set_file_control(semanage_handle_t * sh);
+
+/* Begin a transaction with the policy server.
+ * Returns 0 on success, negative value on error, or the
+ * positive error code received from the server.
+ */
+int semanage_ps_begintrans(semanage_handle_t * sh)
+{
+ int fd = sh->u.ps_handle.socket_fd;
+ uint32_t response_type = 0;
+ uint64_t response_length = 0;
+ char *response = NULL;
+ int err = 0;
+
+ err = write_msg(sh, fd, PS_BEGIN_TRANSACTION, 0, NULL);
+ if (err)
+ return err;
+
+ err = read_server(sh, fd, &response_type, &response_length, &response);
+ if (err) {
+ if (response)
+ ERR(sh, response);
+ else
+ ERR(sh, "Error beginning transaction.");
+ }
+
+ free(response);
+ return err;
+}
+
+/* Interacting with your policy via the policy server
+ * means that your policy is managed (by definition).
+ */
+int semanage_ps_is_managed(semanage_handle_t * sh)
+{
+ return 1;
+}
+
+/* Command the policy server to commit all changes.
+ * Returns 0 on success, negative value on error, or the
+ * positive error code received from the server.
+ */
+int semanage_ps_commit(semanage_handle_t * sh)
+{
+ int i = 0;
+ int fd = sh->u.ps_handle.socket_fd;
+ uint32_t response_type = 0;
+ uint64_t response_length = 0;
+ char *response = NULL;
+ int err = 0;
+ dbase_config_t *components[] = {
+ semanage_iface_dbase_local(sh),
+ semanage_bool_dbase_local(sh),
+ semanage_user_dbase_local(sh),
+ semanage_port_dbase_local(sh),
+ semanage_fcontext_dbase_local(sh),
+ semanage_fcontext_dbase_policy(sh),
+ semanage_seuser_dbase_local(sh),
+ semanage_seuser_dbase_policy(sh),
+ semanage_bool_dbase_active(sh),
+ semanage_node_dbase_local(sh),
+ };
+ const int CCOUNT = sizeof(components) / sizeof(components[0]);
+
+ for (i = 0; i < CCOUNT; i++) {
+ /* Flush to disk */
+ if(components[i]->dtable == NULL || components[i]->dtable->flush == NULL) {
+ printf("Flush method not implemented");
+ return err;
+ }
+ if (components[i]->dtable->flush(sh, components[i]) == STATUS_ERR){
+ ERR(sh, "Error flushing database");
+ return err;
+ }
+ }
+
+ err = write_msg(sh, fd, PS_COMMIT, 0, NULL);
+ if (err)
+ return err;
+
+ err = read_server(sh, fd, &response_type, &response_length, &response);
+ if (err) {
+ if (response)
+ ERR(sh, response);
+ else
+ ERR(sh, "Error committing.");
+ }
+
+ free(response);
+ return err;
+}
+
+/* Attempt to make a connection to the policy server specified within
+ * the given semod_module_store struct. If handshake_response is not
+ * NULL then write the message received from the server to the
+ * semanage handle.
+ * The file descriptor will be set to non-blocking mode.
+ * Return the file descriptor used, -1 if the server could not be
+ * found, -2 if the server rejected this connection, or -3 for all
+ * other errors.
+ */
+int semanage_ps_connect(semanage_handle_t * sh)
+{
+ char *handshake = NULL;
+ char *handshake_response = NULL;
+ uint32_t response_type = 0;
+ uint64_t data_length = 0;
+ int err = 0;
+
+ /* attempt to open connection */
+ if (sh->conf->store_type == SEMANAGE_CON_POLSERV_REMOTE) {
+ if (connect_remote(sh) == EXIT_FAILURE) {
+ return sh->u.ps_handle.socket_fd;
+ }
+ } else if (sh->conf->store_type == SEMANAGE_CON_POLSERV_LOCAL) {
+ if (connect_local(sh) == EXIT_FAILURE) {
+ return sh->u.ps_handle.socket_fd;
+ }
+ } else {
+ sh->u.ps_handle.socket_fd = -2;
+ return sh->u.ps_handle.socket_fd;
+ }
+
+ /* set up function table */
+ sh->funcs = &ps_funcs;
+
+ /* set file descriptor to non-blocking mode */
+ sh->is_connected = 1;
+ if (set_file_control(sh) == EXIT_FAILURE) {
+ return sh->u.ps_handle.socket_fd;
+ }
+
+ /* perform handshake with server. */
+ err = semanage_handle_set_version(sh, SEMANAGE_SERIAL_VERSION_MAJOR, SEMANAGE_SERIAL_VERSION_MINOR);
+
+ if (err != STATUS_SUCCESS) {
+ close(sh->u.ps_handle.socket_fd);
+ ERR(sh, "Error setting version during handshake with server.");
+ sh->u.ps_handle.socket_fd = -1;
+ return sh->u.ps_handle.socket_fd;
+ }
+
+ err = semanage_handle_version_serialize(sh, &handshake, &data_length);
+ if (err != STATUS_SUCCESS) {
+ close(sh->u.ps_handle.socket_fd);
+ ERR(sh, "Error serializing version during handshake with server.");
+ sh->u.ps_handle.socket_fd = -1;
+ return sh->u.ps_handle.socket_fd;
+ }
+
+ err = write_msg(sh, sh->u.ps_handle.socket_fd, PS_CONNECT,
+ data_length, handshake);
+ if (err) {
+ close(sh->u.ps_handle.socket_fd);
+ ERR(sh, "Error writing handshake to server.");
+ sh->u.ps_handle.socket_fd = -1;
+ return sh->u.ps_handle.socket_fd;
+ }
+ err = read_server(sh, sh->u.ps_handle.socket_fd, &response_type,
+ &data_length, &handshake_response);
+ if (err) {
+ // TODO: TESTME
+ close(sh->u.ps_handle.socket_fd);
+ if (handshake_response)
+ ERR(sh, handshake_response);
+ else
+ ERR(sh, "Error reading handshake from server.");
+ free(handshake_response);
+ sh->u.ps_handle.socket_fd = -2;
+ return sh->u.ps_handle.socket_fd;
+ }
+ free(handshake_response);
+
+ /* Object databases: local modifications */
+ if (user_ps_local_dbase_init(sh,
+ DB_USER_LOCAL,
+ semanage_user_dbase_local(sh)) < 0)
+ goto err;
+
+ if (port_ps_local_dbase_init(sh,
+ DB_PORT_LOCAL,
+ semanage_port_dbase_local(sh)) < 0)
+ goto err;
+
+ if (iface_ps_local_dbase_init(sh,
+ DB_INTERFACE_LOCAL,
+ semanage_iface_dbase_local(sh)) < 0)
+ goto err;
+
+ if (bool_ps_local_dbase_init(sh,
+ DB_BOOLEAN_LOCAL,
+ semanage_bool_dbase_local(sh)) < 0)
+ goto err;
+
+ if (fcontext_ps_local_dbase_init(sh,
+ DB_FCONTEXT_LOCAL,
+ semanage_fcontext_dbase_local(sh)) < 0)
+ goto err;
+
+ if (seuser_ps_local_dbase_init(sh,
+ DB_SEUSER_LOCAL,
+ semanage_seuser_dbase_local(sh)) < 0)
+ goto err;
+
+ if (node_ps_local_dbase_init(sh,
+ DB_NODE_LOCAL,
+ semanage_node_dbase_local(sh)) < 0)
+ goto err;
+
+ /* Object databases: local modifications + policy */
+ if (user_ps_policydb_dbase_init(sh, DB_USER_POLICY, semanage_user_dbase_policy(sh)) < 0)
+ goto err;
+
+ if (port_ps_policydb_dbase_init(sh, DB_PORT_POLICY, semanage_port_dbase_policy(sh)) < 0)
+ goto err;
+
+ if (iface_ps_policydb_dbase_init(sh, DB_INTERFACE_POLICY, semanage_iface_dbase_policy(sh)) < 0)
+ goto err;
+
+ if (bool_ps_policydb_dbase_init(sh, DB_BOOLEAN_POLICY, semanage_bool_dbase_policy(sh)) < 0)
+ goto err;
+
+ if (fcontext_ps_local_dbase_init(sh,
+ DB_FCONTEXT_POLICY,
+ semanage_fcontext_dbase_policy(sh)) < 0)
+ goto err;
+
+ if (seuser_ps_local_dbase_init(sh,
+ DB_SEUSER_POLICY,
+ semanage_seuser_dbase_policy(sh)) < 0)
+ goto err;
+
+ if (node_ps_policydb_dbase_init(sh, DB_NODE_POLICY, semanage_node_dbase_policy(sh)) < 0)
+ goto err;
+
+ /* Active kernel policy */
+ if (bool_ps_activedb_dbase_init(sh, DB_BOOLEAN_ACTIVE, semanage_bool_dbase_active(sh)) < 0)
+ goto err;
+
+ return sh->u.ps_handle.socket_fd;
+
+ err:
+ close(sh->u.ps_handle.socket_fd);
+ sh->u.ps_handle.socket_fd = -3;
+ return sh->u.ps_handle.socket_fd;
+}
+
+int semanage_ps_get_commit_number(semanage_handle_t * sh)
+{
+ int fd = sh->u.ps_handle.socket_fd;
+ uint32_t response_type = 0;
+ uint64_t response_length = 0;
+ char *response = NULL;
+ char *ptr = NULL;
+ int status = STATUS_SUCCESS;
+
+ /* Retrieve commit number. */
+ status = write_msg(sh, fd, PS_GET_COMMIT_NUMBER, 0, NULL);
+ if (status != 0) {
+ status = STATUS_ERR;
+ goto cleanup;
+ }
+
+ status = read_server(sh, fd, &response_type, &response_length, &response);
+ if (status != 0 || response_type != PS_OK) {
+ if (response != NULL)
+ ERR(sh, response);
+ else
+ ERR(sh, "Error getting commit number.");
+
+ status = STATUS_ERR;
+ goto cleanup;
+ }
+
+ ptr = response;
+ status = semanage_policy_table_unserialize_serial(sh, &ptr, &response_length);
+ if (status < 0)
+ goto cleanup;
+
+cleanup:
+ free(response);
+ return status;
+}
+
+/* Callback that allows us to do cleanup on destroy.
+ * Currently does nothing.
+ * NOTE: The destroy callback is explicitly not supposed
+ * to disconnect. The client MUST call disconnect
+ * before calling destroy, for example when handling
+ * errors during other parts of the transaction.
+ */
+void semanage_ps_destroy(semanage_handle_t * sh)
+{
+ sh = NULL;
+}
+
+/* Disconnect from the server.
+ * Returns 0 on success, -1 on error.
+ */
+int semanage_ps_disconnect(semanage_handle_t * sh)
+{
+ int err = 0;
+
+ write_msg(sh, sh->u.ps_handle.socket_fd, PS_DISCONNECT, 0, NULL);
+
+ /* Release object databases: local modifications */
+ user_ps_local_dbase_release(semanage_user_dbase_local(sh));
+ port_ps_local_dbase_release(semanage_port_dbase_local(sh));
+ iface_ps_local_dbase_release(semanage_iface_dbase_local(sh));
+ bool_ps_local_dbase_release(semanage_bool_dbase_local(sh));
+ fcontext_ps_local_dbase_release(semanage_fcontext_dbase_local(sh));
+ seuser_ps_local_dbase_release(semanage_seuser_dbase_local(sh));
+ node_ps_local_dbase_release(semanage_node_dbase_local(sh));
+
+ /* Release object databases: local modifications + policy */
+ user_ps_policydb_dbase_release(semanage_user_dbase_policy(sh));
+ port_ps_policydb_dbase_release(semanage_port_dbase_policy(sh));
+ iface_ps_policydb_dbase_release(semanage_iface_dbase_policy(sh));
+ bool_ps_policydb_dbase_release(semanage_bool_dbase_policy(sh));
+ fcontext_ps_local_dbase_release(semanage_fcontext_dbase_policy(sh));
+ seuser_ps_local_dbase_release(semanage_seuser_dbase_policy(sh));
+ node_ps_policydb_dbase_release(semanage_node_dbase_policy(sh));
+
+ /* Release object databases: active kernel policy */
+ bool_ps_activedb_dbase_release(semanage_bool_dbase_active(sh));
+
+ err = close(sh->u.ps_handle.socket_fd);
+ sh->u.ps_handle.socket_fd = err;
+ return err;
+}
+
+/* Command the policy server to install a new base module.
+ * Returns 0 on success, -1 if it could not send the command,
+ * or the positive error code received from the server.
+ */
+int semanage_ps_install_base_module(semanage_handle_t * sh,
+ char *base_data, size_t data_len)
+{
+ int fd = sh->u.ps_handle.socket_fd;
+ uint64_t data_length = data_len;
+ uint32_t response_type = 0;
+ char *response = NULL;
+ int err = 0;
+
+ err = write_msg(sh, fd, PS_BASE_MODULE, data_length, base_data);
+ if (err)
+ return err;
+
+ err = read_server(sh, fd, &response_type, &data_length, &response);
+ if (err) {
+ if (response)
+ ERR(sh, response);
+ else
+ ERR(sh, "Error installing base module.");
+ }
+
+ free(response);
+ return err;
+}
+
+/* Command the policy server to install a module.
+ * Returns 0 on success, -1 if it could not send the command,
+ * or the positive error code received from the server.
+ */
+int semanage_ps_install_module(semanage_handle_t * sh,
+ char *module_data, size_t data_len)
+{
+ int fd = sh->u.ps_handle.socket_fd;
+ uint64_t data_length = data_len;
+ uint32_t response_type = 0;
+ char *response = NULL;
+ int err = 0;
+
+ err = write_msg(sh, fd, PS_INSTALL_MODULE, data_length, module_data);
+ if (err)
+ return err;
+
+ err = read_server(sh, fd, &response_type, &data_length, &response);
+ if (err) {
+ if (response)
+ ERR(sh, response);
+ else
+ ERR(sh, "Error installing module.");
+ }
+
+ free(response);
+ return err;
+}
+
+/* Obtain from the policy server a list of active modules.
+ * Returns 0 on success, -1 if it could not send the command,
+ * or the positive error code received from the server.
+ * Caller is responsible for freeing modules.
+ */
+int semanage_ps_list_modules(semanage_handle_t * sh,
+ semanage_module_info_t ** modules, int *num_mods)
+{
+ int status = STATUS_SUCCESS;
+ int fd = sh->u.ps_handle.socket_fd;
+ uint32_t response_type = 0;
+ uint64_t response_length = 0;
+ char *response = NULL;
+
+ status = write_msg(sh, fd, PS_LIST_MODULES, 0, NULL);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ status = read_server(sh, fd, &response_type, &response_length, &response);
+ if (status != STATUS_SUCCESS) {
+ if (response != NULL)
+ ERR(sh, response);
+ else
+ ERR(sh, "Error listing modules.");
+ goto cleanup;
+ }
+
+ char *ptr = response;
+ uint64_t size = response_length;
+ status = semanage_module_list_unserialize(sh, &ptr, &size, modules, num_mods);
+ if (status != STATUS_SUCCESS) {
+ ERR(sh, "Error unserializing modules.");
+ goto cleanup;
+ }
+
+cleanup:
+ free(response);
+ return status;
+}
+
+/* Command the policy server to remove a module.
+ * Returns 0 on success, -1 if it could not send the command,
+ * or the positive error code received from the server.
+ */
+int semanage_ps_remove_module(semanage_handle_t * sh, char *module_name)
+{
+ int fd = sh->u.ps_handle.socket_fd;
+ uint64_t data_length = 0;
+ uint32_t response_type = 0;
+ char *response = NULL;
+ int err = 0;
+
+ data_length = strlen(module_name) + 1;
+ err = write_msg(sh, fd, PS_REMOVE_MODULE, data_length, module_name);
+ if (err)
+ return err;
+
+ err = read_server(sh, fd, &response_type, &data_length, &response);
+ if (err) {
+ if (response)
+ ERR(sh, response);
+ else
+ ERR(sh, "Error removing module.");
+ }
+
+ free(response);
+ return err;
+}
+
+/* Command the policy server to upgrade a module.
+ * Returns 0 on success, -1 if it could not send the command,
+ * or the positive error code received from the server.
+ */
+int semanage_ps_upgrade_module(semanage_handle_t * sh,
+ char *module_data, size_t data_len)
+{
+ int fd = sh->u.ps_handle.socket_fd;
+ uint64_t data_length = data_len;
+ uint32_t response_type = 0;
+ char *response = NULL;
+ int err = 0;
+
+ err = write_msg(sh, fd, PS_UPGRADE_MODULE, data_length, module_data);
+ if (err)
+ return err;
+
+ err = read_server(sh, fd, &response_type, &data_length, &response);
+ if (err) {
+ if (response)
+ ERR(sh, response);
+ else
+ ERR(sh, "Error upgrading module.");
+ }
+
+ free(response);
+ return err;
+}
+
+/********************* utility functions *********************/
+
+/* This function connects the policy management server to
+ * a local host. The information needed to connect to the
+ * host, and the information returned from this function,
+ * appear in the semange_handle pointed to by sh.
+ *
+ * If the function is successful, the socket descriptor is
+ * put in the semanage_handle structure, and EXIT_SUCCESS is returned.
+ *
+ * If the function fails, an error indicator (a negative number)
+ * is put in the socket descriptor field of the semanage_handle
+ * structure, and EXIT_FAILURE is returned.
+ */
+static int connect_local(semanage_handle_t * sh)
+{
+ char *server_path = sh->conf->store_path;
+ struct sockaddr_un sock;
+
+ sh->u.ps_handle.socket_fd = socket(PF_LOCAL, SOCK_STREAM, 0);
+ if (sh->u.ps_handle.socket_fd < 0) {
+ sh->u.ps_handle.socket_fd = -3;
+ return EXIT_FAILURE;
+ }
+ memset(&sock, 0, sizeof(sock));
+ sock.sun_family = AF_LOCAL;
+ strncpy(sock.sun_path, server_path, sizeof(sock.sun_path) - 1);
+ sock.sun_path[sizeof(sock.sun_path) - 1] = '\0';
+ if (connect(sh->u.ps_handle.socket_fd, (struct sockaddr *)&sock,
+ sizeof(sock)) < 0) {
+ close(sh->u.ps_handle.socket_fd);
+ sh->u.ps_handle.socket_fd = -1;
+ return EXIT_FAILURE;
+ }
+ return EXIT_SUCCESS;
+}
+
+/* This function connects the policy management server to
+ * a remote host. The information needed to connect to the
+ * host, and the information returned from this function,
+ * appear in the semange_handle pointed to by sh.
+ *
+ * If the function is successful, the socket descriptor is
+ * put in the semanage_handle structure, and EXIT_SUCCESS is returned.
+ *
+ * If the function fails, an error indicator (a negative number)
+ * is put in the socket descriptor field of the semanage_handle
+ * structure, the file descriptor is closed, and EXIT_FAILURE is returned.
+ */
+static int connect_remote(semanage_handle_t * sh)
+{
+ char *server_addr = sh->conf->store_path;
+ int server_port = sh->conf->server_port;
+ struct sockaddr_in sock;
+ struct hostent *host;
+ char address[INET_ADDRSTRLEN];
+ int status;
+
+ sh->u.ps_handle.socket_fd = socket(PF_INET, SOCK_STREAM, 0);
+ if (sh->u.ps_handle.socket_fd < 0) {
+ sh->u.ps_handle.socket_fd = -3;
+ return EXIT_FAILURE;
+ }
+ memset(&sock, 0, sizeof(sock));
+ sock.sin_family = AF_INET;
+ sock.sin_port = htons(server_port);
+
+ host = gethostbyname(server_addr);
+ if (host == NULL) {
+ close(sh->u.ps_handle.socket_fd);
+ sh->u.ps_handle.socket_fd = -2;
+ return EXIT_FAILURE;
+ }
+
+ inet_ntop(AF_INET, host->h_addr, address, INET_ADDRSTRLEN);
+ status = inet_pton(AF_INET, address, &sock.sin_addr);
+ if (status != 1) {
+ close(sh->u.ps_handle.socket_fd);
+ sh->u.ps_handle.socket_fd = -1;
+ return EXIT_FAILURE;
+ }
+
+ status = connect(sh->u.ps_handle.socket_fd, (struct sockaddr *)&sock, sizeof(sock));
+ if (status < 0) {
+ close(sh->u.ps_handle.socket_fd);
+ sh->u.ps_handle.socket_fd = -1;
+ return EXIT_FAILURE;
+ }
+ return EXIT_SUCCESS;
+}
+
+/* This function gets the current status flags from the socket
+ * file descriptor, sets file I/O to non-blocking, and rewrites
+ * the file status flag.
+ *
+ * The value EXIT_SUCCESS is returned if the operation is
+ * successful, otherwise the value EXIT_FAILURE is returned and
+ * the socket file descriptor is closed and set to -3.
+ */
+static int set_file_control(semanage_handle_t * sh)
+{
+ int flags;
+
+ flags = fcntl(sh->u.ps_handle.socket_fd, F_GETFL, 0);
+ if (flags < 0) {
+ close(sh->u.ps_handle.socket_fd);
+ ERR(sh, "F_GETFL error!");
+ sh->u.ps_handle.socket_fd = -3;
+ return EXIT_FAILURE;
+ }
+ flags |= O_NONBLOCK;
+ if (fcntl(sh->u.ps_handle.socket_fd, F_SETFL, flags) < 0) {
+ close(sh->u.ps_handle.socket_fd);
+ ERR(sh, "F_SETFL error!");
+ sh->u.ps_handle.socket_fd = -3;
+ return EXIT_FAILURE;
+ }
+ return EXIT_SUCCESS;
+}
Index: selinux-pms-support/libsemanage/src/ps_api.h
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/src/ps_api.h
@@ -0,0 +1,31 @@
+#ifndef _SEMANAGE_PS_API_H_
+#define _SEMANAGE_PS_API_H_
+
+#include <sys/types.h>
+
+struct semanage_handle;
+
+struct semanage_ps_handle {
+ int socket_fd;
+};
+
+int semanage_ps_begintrans(semanage_handle_t * sh);
+int semanage_ps_commit(semanage_handle_t * sh);
+int semanage_ps_connect(semanage_handle_t * sh);
+int semanage_ps_is_managed(semanage_handle_t * sh);
+int semanage_ps_disconnect(semanage_handle_t * sh);
+int semanage_ps_install_base_module(semanage_handle_t * sh, char *base_data,
+ size_t data_len);
+int semanage_ps_install_module(semanage_handle_t * sh, char *module_data,
+ size_t data_len);
+int semanage_ps_list_modules(semanage_handle_t * sh,
+ semanage_module_info_t ** mod_names,
+ int *num_mods);
+int semanage_ps_list_sandbox(semanage_handle_t * sh);
+int semanage_ps_remove_module(semanage_handle_t * sh, char *module_name);
+int semanage_ps_upgrade_module(semanage_handle_t * sh, char *module_data,
+ size_t data_len);
+int semanage_ps_get_commit_number(semanage_handle_t * sh);
+void semanage_ps_destroy(semanage_handle_t * sh);
+
+#endif
Index: selinux-pms-support/libsemanage/src/seusers_ps.c
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/src/seusers_ps.c
@@ -0,0 +1,58 @@
+/* Authors: Ivan Gyurdiev <ivg2@cornell.edu>
+ * Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ * Copyright (C) 2005 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+struct semanage_seuser;
+struct semanage_seuser_key;
+typedef struct semanage_seuser record_t;
+typedef struct semanage_seuser_key record_key_t;
+#define DBASE_RECORD_DEFINED
+
+struct dbase_file;
+typedef struct dbase_file dbase_t;
+#define DBASE_DEFINED
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <strings.h>
+#include <semanage/handle.h>
+#include "seuser_internal.h"
+#include "database_ps.h"
+#include "debug.h"
+
+int seuser_ps_local_dbase_init(semanage_handle_t * handle,
+ uint32_t sandbox_id, dbase_config_t * dconfig)
+{
+ if (dbase_ps_init(
+ handle,
+ sandbox_id,
+ &SEMANAGE_SEUSER_RTABLE,
+ (dbase_ps_t **)(&dconfig->dbase)) < 0)
+ return STATUS_ERR;
+
+ dconfig->dtable = &SEMANAGE_PS_DTABLE;
+ return STATUS_SUCCESS;
+}
+
+void seuser_ps_local_dbase_release(dbase_config_t * dconfig)
+{
+ dbase_ps_release((dbase_ps_t *) dconfig->dbase);
+}
Index: selinux-pms-support/libsemanage/src/users_ps.c
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/src/users_ps.c
@@ -0,0 +1,82 @@
+/* Authors: Ivan Gyurdiev <ivg2@cornell.edu>
+ * Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ * Copyright (C) 2005 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+struct semanage_user;
+struct semanage_user_key;
+typedef struct semanage_user record_t;
+typedef struct semanage_user_key record_key_t;
+#define DBASE_RECORD_DEFINED
+
+struct dbase_file;
+typedef struct dbase_file dbase_t;
+#define DBASE_DEFINED
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <strings.h>
+#include <semanage/handle.h>
+#include "user_internal.h"
+#include "database_ps.h"
+#include "database_join.h"
+#include "debug.h"
+
+int user_ps_local_dbase_init(
+ semanage_handle_t * handle,
+ uint32_t sandbox_id,
+ dbase_config_t * dconfig)
+{
+ if (dbase_ps_init(
+ handle,
+ sandbox_id,
+ &SEMANAGE_USER_RTABLE,
+ (dbase_ps_t **)(&dconfig->dbase)) < 0)
+ return STATUS_ERR;
+
+ dconfig->dtable = &SEMANAGE_PS_DTABLE;
+ return STATUS_SUCCESS;
+}
+
+void user_ps_local_dbase_release(dbase_config_t * dconfig)
+{
+ dbase_ps_release((dbase_ps_t *)dconfig->dbase);
+}
+
+int user_ps_policydb_dbase_init(
+ semanage_handle_t * handle,
+ uint32_t sandbox_id,
+ dbase_config_t * dconfig)
+{
+ if (dbase_ps_init(
+ handle,
+ sandbox_id,
+ &SEMANAGE_USER_RTABLE,
+ (dbase_ps_t **)(&dconfig->dbase)) < 0)
+ return STATUS_ERR;
+
+ dconfig->dtable = &SEMANAGE_PS_POLICYDB_DTABLE;
+ return STATUS_SUCCESS;
+}
+
+void user_ps_policydb_dbase_release(dbase_config_t * dconfig)
+{
+ dbase_ps_release((dbase_ps_t *)dconfig->dbase);
+}
Index: selinux-pms-support/libsemanage/tests/globals.h
===================================================================
--- selinux-pms-support.orig/libsemanage/tests/globals.h
+++ selinux-pms-support/libsemanage/tests/globals.h
@@ -24,4 +24,43 @@
semanage_handle_t *sh;
+/* ps_api */
+pid_t ps_pid;
+char *socket_path;
+int server_socket_fd;
+int client_socket_fd;
+
+typedef int (*create_f) (
+ struct semanage_handle * handle,
+ record_t ** rec);
+typedef int (*key_extract_f) (
+ struct semanage_handle * handle,
+ const record_t * rec,
+ record_key_t ** key);
+typedef void (*key_free_f) (record_key_t * key);
+typedef int (*compare_f) (
+ const record_t * rec,
+ const record_key_t * key);
+typedef int (*compare2_f) (
+ const record_t * rec,
+ const record_t * rec2);
+typedef int (*compare2_qsort_f) (
+ const record_t ** rec,
+ const record_t ** rec2);
+typedef int (*clone_f) (
+ struct semanage_handle * handle,
+ const record_t * rec,
+ record_t ** new_rec);
+typedef int (*serialize_f) (
+ struct semanage_handle* handle,
+ const record_t* rec,
+ char** rec_data,
+ uint64_t* size);
+typedef int (*unserialize_f) (
+ struct semanage_handle* handle,
+ char** rec_data,
+ uint64_t* size,
+ record_t** rec);
+typedef void (*free_f) (record_t * rec);
+
#endif
Index: selinux-pms-support/libsemanage/tests/libsemanage-tests.c
===================================================================
--- selinux-pms-support.orig/libsemanage/tests/libsemanage-tests.c
+++ selinux-pms-support/libsemanage/tests/libsemanage-tests.c
@@ -30,6 +30,9 @@
#include "test_seuser_record.h"
#include "test_user_record.h"
+#include "test_ps_api_connect.h"
+#include "test_ps_api_disconnect.h"
+
#include <CUnit/Basic.h>
#include <CUnit/Console.h>
#include <CUnit/TestDB.h>
@@ -74,6 +77,19 @@ static int do_tests(int interactive, int
DECLARE_SUITE(seuser_record);
DECLARE_SUITE(user_record);
+ /* The ps_api_connect test forks the
+ * tests into client and server variants.
+ */
+ DECLARE_SUITE(ps_api_connect);
+
+ /* These tests rely upon the policy server
+ * being properly connected via the
+ * ps_api_connect test.
+ */
+
+ /* The ps_api_disconnect test 'unforks'. */
+ DECLARE_SUITE(ps_api_disconnect);
+
if (verbose)
CU_basic_set_mode(CU_BRM_VERBOSE);
else
Index: selinux-pms-support/libsemanage/tests/test_ps_api_connect.c
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/tests/test_ps_api_connect.c
@@ -0,0 +1,346 @@
+/* Authors: Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* The purpose of this file is to provide unit tests of the functions in:
+ *
+ * libsemanage/src/ps_api.c
+ *
+ * test_ps_api_connect.c and test_ps_api_disconnect.c should be used
+ * together. The logic behind a seperate test file for connection
+ * and disconnection is that their seperation allows other tests which
+ * also rely on the policy server being connected to run in between
+ * the connect and disconnect tests.
+ *
+ */
+
+#include "globals.h"
+#include "utilities.h"
+#include "test_ps_api_connect.h"
+
+#include <libgen.h>
+#include <limits.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <CUnit/Basic.h>
+
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <selinux/selinux.h>
+
+#include "debug.h"
+#include "byteswap.h"
+#include "handle.h"
+#include "modules.h"
+#include "policy.h"
+#include "ps_api.h"
+#include "messages_internal.h"
+#include "semanage_store.h"
+#include "database_policydb.h"
+#include "user_internal.h"
+#include "seuser_internal.h"
+#include "port_internal.h"
+#include "iface_internal.h"
+#include "boolean_internal.h"
+#include "fcontext_internal.h"
+#include "node_internal.h"
+
+/* PS API stub functions. */
+
+int ps_api_test_get_serial(semanage_handle_t *sh)
+{
+ return 0;
+}
+
+void ps_api_test_destroy(semanage_handle_t *sh)
+{
+}
+
+int ps_api_test_disconnect(semanage_handle_t *sh)
+{
+ return 0;
+}
+
+int ps_api_test_begin_trans(semanage_handle_t *sh)
+{
+ return 0;
+}
+
+int ps_api_test_commit(semanage_handle_t *sh)
+{
+ return 0;
+}
+
+int ps_api_test_install(
+ semanage_handle_t *sh,
+ char *data,
+ size_t data_size)
+{
+ return 0;
+}
+
+int ps_api_test_upgrade(
+ semanage_handle_t *sh,
+ char *data,
+ size_t data_size)
+{
+ return 0;
+}
+
+int ps_api_test_remove(
+ semanage_handle_t *sh,
+ char *data)
+{
+ return 0;
+}
+
+int ps_api_test_list(
+ semanage_handle_t *sh,
+ semanage_module_info_t **modules,
+ int *modules_size)
+{
+ return 0;
+}
+
+int ps_api_test_install_base(
+ semanage_handle_t *sh,
+ char *data,
+ size_t data_size)
+{
+ return 0;
+}
+
+struct semanage_policy_table server_funcs = {
+ .get_serial = ps_api_test_get_serial,
+ .destroy = ps_api_test_destroy,
+ .disconnect = ps_api_test_disconnect,
+ .begin_trans = ps_api_test_begin_trans,
+ .commit = ps_api_test_commit,
+ .install = ps_api_test_install,
+ .upgrade = ps_api_test_upgrade,
+ .install_base = ps_api_test_install_base,
+ .remove = ps_api_test_remove,
+ .list = ps_api_test_list
+};
+
+struct semanage_policy_table client_funcs = {
+ .get_serial = semanage_ps_get_commit_number,
+ .destroy = semanage_ps_destroy,
+ .disconnect = semanage_ps_disconnect,
+ .begin_trans = semanage_ps_begintrans,
+ .commit = semanage_ps_commit,
+ .install = semanage_ps_install_module,
+ .upgrade = semanage_ps_upgrade_module,
+ .remove = semanage_ps_remove_module,
+ .list = semanage_ps_list_modules,
+ .install_base = semanage_ps_install_base_module
+};
+
+/* The suite initialization function.
+ * Returns zero on success, non-zero otherwise.
+ */
+int ps_api_connect_test_init(void)
+{
+ int status = 0;
+
+ /* initialize the handle */
+ sh = semanage_handle_create();
+ if (sh == NULL) {
+ status = -1;
+ goto cleanup;
+ }
+
+ /* hide error messages */
+ sh->msg_callback = test_msg_handler;
+
+ /* Decide where our socket path will be. */
+ socket_path = "/tmp/test-policy-server";
+ remove(socket_path);
+
+ /* Fork. */
+ if ((ps_pid = fork()) < 0) {
+ status = errno;
+ goto cleanup;
+ }
+
+ if (ps_pid == 0) {
+ /* Server code. */
+
+ /* Store setup. */
+ sh->funcs = &server_funcs;
+
+ /* Networking. */
+ struct sockaddr_un serv_addr;
+ int flags;
+
+ if ((server_socket_fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
+ status = errno;
+ goto cleanup;
+ }
+
+ serv_addr.sun_family = AF_UNIX;
+ strncpy(serv_addr.sun_path, socket_path, sizeof(serv_addr.sun_path));
+ serv_addr.sun_path[sizeof(serv_addr.sun_path) - 1] = '\0';
+
+ if (bind(server_socket_fd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) == -1) {
+ status = errno;
+ goto cleanup;
+ }
+
+ if (listen(server_socket_fd, 1) == -1) {
+ status = errno;
+ goto cleanup;
+ }
+
+ if ((flags = fcntl(server_socket_fd, F_GETFD)) == -1) {
+ status = errno;
+ goto cleanup;
+ }
+ flags |= FD_CLOEXEC;
+ if (fcntl(server_socket_fd, F_SETFD, flags) == -1) {
+ status = errno;
+ goto cleanup;
+ }
+
+ sh->is_connected = 1;
+ }
+ else {
+ /* Client code. */
+
+ sh->funcs = &client_funcs;
+ }
+
+cleanup:
+ if (status != 0) {
+ printf("\n\nReceived error code in %s: %d | %s\n", (ps_pid == 0) ? "server" : "client", status, strerror(status));
+ ps_api_connect_test_cleanup();
+ }
+
+ return status;
+}
+
+/* The suite cleanup function.
+ * Returns zero on success, non-zero otherwise.
+ */
+int ps_api_connect_test_cleanup(void)
+{
+ /* Do nothing. Cleanup will be done by ps_api_disconnect_test_cleanup() */
+ return 0;
+}
+
+/* Adds all the tests needed for this suite.
+*/
+int ps_api_connect_add_tests(CU_pSuite suite)
+{
+ CU_ErrorCode status;
+
+ if (NULL == CU_add_test(suite, "semanage_ps_connect", test_semanage_ps_connect))
+ goto cleanup;
+
+cleanup:
+ if (CUE_SUCCESS != (status = CU_get_error()))
+ CU_cleanup_registry();
+ return status;
+}
+
+/* Tests the semanage_ps_connect function in ps_api.c
+*/
+void test_semanage_ps_connect(void)
+{
+ int status = 0;
+
+ uint32_t message_type;
+ uint64_t data_length;
+ char *data = NULL;
+ int timeout = 0;
+
+ if (ps_pid == 0) {
+ /* Server code. */
+
+ /* Wait for client to connect. */
+ struct sockaddr client_addr;
+ socklen_t client_len = sizeof(struct sockaddr);
+ client_socket_fd = accept(server_socket_fd, &client_addr, &client_len);
+
+ CU_ASSERT( client_socket_fd >= 0 );
+ if (client_socket_fd < 0) {
+ status = errno;
+ goto cleanup;
+ }
+
+ /* Block waiting for a message. */
+
+ if ((status = read_msg(sh, client_socket_fd, timeout, &message_type, &data_length, &data)))
+ goto cleanup;
+
+ /* Perform handshake. */
+ CU_ASSERT( message_type == PS_CONNECT );
+ if (message_type != PS_CONNECT) {
+ status = -1;
+ goto cleanup;
+ }
+
+ char *motd = "MOTD: Hello.\0";
+ if ((status = write_msg(sh, client_socket_fd, PS_OK, strlen(motd) + 1, motd)))
+ goto cleanup;
+
+ }
+ else {
+ /* Client code. */
+
+ /* Fake store. */
+ sh->conf->store_type = SEMANAGE_CON_POLSERV_LOCAL;
+ sh->conf->store_path = strdup(socket_path);
+
+ /* FIXME: Waiting for server to finish setting up. */
+ sleep(1);
+
+ /* Connect to server. */
+ status = semanage_connect(sh);
+ CU_ASSERT( status == 0 );
+ }
+
+ /* cleanup */
+cleanup:
+ free(data);
+
+ CU_ASSERT( status == 0 );
+ if (status != 0) {
+ printf("\n\nReceived error code in %s: %d | %s\n", (ps_pid == 0) ? "server" : "client", status, strerror(status));
+ ps_api_connect_test_cleanup();
+ }
+}
+
Index: selinux-pms-support/libsemanage/tests/test_ps_api_connect.h
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/tests/test_ps_api_connect.h
@@ -0,0 +1,33 @@
+/* Authors: Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __TEST_PS_API_CONNECT_H__
+#define __TEST_PS_API_CONNECT_H__
+
+#include "handle.h"
+#include <CUnit/Basic.h>
+
+int ps_api_connect_test_init(void);
+int ps_api_connect_test_cleanup(void);
+int ps_api_connect_add_tests(CU_pSuite suite);
+
+void test_semanage_ps_connect(void);
+
+#endif
Index: selinux-pms-support/libsemanage/tests/test_ps_api_disconnect.c
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/tests/test_ps_api_disconnect.c
@@ -0,0 +1,178 @@
+/* Authors: Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* The purpose of this file is to provide unit tests of the functions in:
+ *
+ * libsemanage/src/ps_api.c
+ *
+ * test_ps_api_connect.c and test_ps_api_disconnect.c should be used
+ * together. The logic behind a seperate test file for connection
+ * and disconnection is that their seperation allows other tests which
+ * also rely on the policy server being connected to run in between
+ * the connect and disconnect tests.
+ *
+ */
+
+#include "globals.h"
+#include "utilities.h"
+#include "test_ps_api_disconnect.h"
+
+#include <libgen.h>
+#include <limits.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <CUnit/Basic.h>
+
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <selinux/selinux.h>
+
+#include "debug.h"
+#include "byteswap.h"
+#include "handle.h"
+#include "modules.h"
+#include "policy.h"
+#include "ps_api.h"
+#include "messages_internal.h"
+#include "semanage_store.h"
+#include "database_policydb.h"
+#include "user_internal.h"
+#include "seuser_internal.h"
+#include "port_internal.h"
+#include "iface_internal.h"
+#include "boolean_internal.h"
+#include "fcontext_internal.h"
+#include "node_internal.h"
+
+/* The suite initialization function.
+ * Returns zero on success, non-zero otherwise.
+ */
+int ps_api_disconnect_test_init(void)
+{
+ /* Do nothing. ps_api_connect_test_init should have set everything up. */
+ return 0;
+}
+
+/* The suite cleanup function.
+ * Returns zero on success, non-zero otherwise.
+ */
+int ps_api_disconnect_test_cleanup(void)
+{
+ semanage_handle_destroy(sh);
+
+ if (ps_pid > 0) {
+ /* Client code. */
+ }
+
+ if (ps_pid == 0) {
+ /* Policy server code. */
+
+ /* Close sockets. */
+ close(client_socket_fd);
+ close(server_socket_fd);
+ remove(socket_path);
+
+ exit(0);
+ }
+
+ return 0;
+}
+
+/* Adds all the tests needed for this suite.
+*/
+int ps_api_disconnect_add_tests(CU_pSuite suite)
+{
+ CU_ErrorCode status;
+
+ if (NULL == CU_add_test(suite, "semanage_ps_disconnect", test_semanage_ps_disconnect))
+ goto cleanup;
+
+cleanup:
+ if (CUE_SUCCESS != (status = CU_get_error()))
+ CU_cleanup_registry();
+ return status;
+}
+
+/* Tests the semanage_ps_disconnect function in ps_api.c
+*/
+void test_semanage_ps_disconnect(void)
+{
+ int status = 0;
+
+ uint32_t message_type;
+ uint64_t data_length;
+ char *data = NULL;
+ int timeout = 0;
+
+ if (ps_pid == 0) {
+ /* Policy server code. */
+
+ /* Block waiting for a message. */
+ if ((status = read_msg(sh, client_socket_fd, timeout, &message_type, &data_length, &data)))
+ goto cleanup;
+
+ /* Perform disconnect. */
+ CU_ASSERT( message_type == PS_DISCONNECT );
+ if (message_type != PS_DISCONNECT) {
+ status = -1;
+ goto cleanup;
+ }
+
+ if (sh->funcs != NULL) {
+ status = semanage_disconnect(sh);
+ CU_ASSERT( status == 0 );
+ }
+ }
+ else {
+ /* Client code. */
+
+ /* Disconnect from ps. */
+ if (sh->funcs != NULL) {
+ status = semanage_disconnect(sh);
+ CU_ASSERT( status == 0 );
+ }
+ }
+
+cleanup:
+ free(data);
+
+ CU_ASSERT( status == 0 );
+ if (status != 0) {
+ printf("\n\nReceived error code in %s: %d | %s\n", (ps_pid == 0) ? "server" : "client", status, strerror(status));
+ ps_api_disconnect_test_cleanup();
+ }
+}
Index: selinux-pms-support/libsemanage/tests/test_ps_api_disconnect.h
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/tests/test_ps_api_disconnect.h
@@ -0,0 +1,33 @@
+/* Authors: Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __TEST_PS_API_DISCONNECT_H__
+#define __TEST_PS_API_DISCONNECT_H__
+
+#include <CUnit/Basic.h>
+
+int ps_api_disconnect_test_init(void);
+int ps_api_disconnect_test_cleanup(void);
+int ps_api_disconnect_add_tests(CU_pSuite suite);
+
+void test_semanage_ps_connect(void);
+void test_semanage_ps_disconnect(void);
+
+#endif
--
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH 26/33] libsemanage: module serialization tests
2007-04-23 21:34 [PATCH 00/33] libsemanage/libsepol object serialization and ps-api jbrindle
` (24 preceding siblings ...)
2007-04-23 21:35 ` [PATCH 25/33] libsemanage: policy server database hooks jbrindle
@ 2007-04-23 21:35 ` jbrindle
2007-04-23 21:35 ` [PATCH 27/33] libsemanage: booleans " jbrindle
` (8 subsequent siblings)
34 siblings, 0 replies; 58+ messages in thread
From: jbrindle @ 2007-04-23 21:35 UTC (permalink / raw)
To: selinux
Index: selinux-pms-support/libsemanage/tests/libsemanage-tests.c
===================================================================
--- selinux-pms-support.orig/libsemanage/tests/libsemanage-tests.c
+++ selinux-pms-support/libsemanage/tests/libsemanage-tests.c
@@ -33,6 +33,8 @@
#include "test_ps_api_connect.h"
#include "test_ps_api_disconnect.h"
+#include "test_modules.h"
+
#include <CUnit/Basic.h>
#include <CUnit/Console.h>
#include <CUnit/TestDB.h>
@@ -82,6 +84,8 @@ static int do_tests(int interactive, int
*/
DECLARE_SUITE(ps_api_connect);
+ DECLARE_SUITE(modules);
+
/* These tests rely upon the policy server
* being properly connected via the
* ps_api_connect test.
Index: selinux-pms-support/libsemanage/tests/test_modules.c
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/tests/test_modules.c
@@ -0,0 +1,235 @@
+/* Authors: Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* The purpose of this file is to provide unit tests of the functions in:
+ *
+ * libsemanage/src/modules.c
+ *
+ */
+
+#include "globals.h"
+#include "utilities.h"
+#include "test_modules.h"
+
+#include <libgen.h>
+#include <limits.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <CUnit/Basic.h>
+
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <selinux/selinux.h>
+#include <modules.h>
+
+#include "debug.h"
+#include "byteswap.h"
+#include "handle.h"
+#include "modules.h"
+#include "policy.h"
+#include "ps_api.h"
+#include "messages_internal.h"
+#include "semanage_store.h"
+#include "database_policydb.h"
+#include "user_internal.h"
+#include "seuser_internal.h"
+#include "port_internal.h"
+#include "iface_internal.h"
+#include "boolean_internal.h"
+#include "fcontext_internal.h"
+#include "node_internal.h"
+
+/* Module test server functions. */
+
+int module_test_install(
+ semanage_handle_t *sh,
+ char *data,
+ size_t data_size)
+{
+ return 0;
+}
+
+int module_test_upgrade(
+ semanage_handle_t *sh,
+ char *data,
+ size_t data_size)
+{
+ return 0;
+}
+
+int module_test_remove(
+ semanage_handle_t *sh,
+ char *data)
+{
+ return 0;
+}
+
+int module_test_list(
+ semanage_handle_t *sh,
+ semanage_module_info_t **modules,
+ int *modules_size)
+{
+ /* Fabricate a module list. */
+ *modules_size = 2;
+
+ *modules = calloc(*modules_size, sizeof(**modules));
+
+ (*modules)[0].name = "testname0";
+ (*modules)[0].version = "testversion0";
+ (*modules)[1].name = "testname1";
+ (*modules)[1].version = "testversion1";
+
+ return 0;
+}
+
+int module_test_install_base(
+ semanage_handle_t *sh,
+ char *data,
+ size_t data_size)
+{
+ return 0;
+}
+
+/* The suite initialization function.
+ * Returns zero on success, non-zero otherwise.
+ */
+int modules_test_init(void)
+{
+ int status = 0;
+
+ if (ps_pid == 0) {
+ /* Server code. */
+
+ /* Reconfigure connection callbacks. */
+ sh->funcs->list = module_test_list;
+
+ }
+
+//cleanup:
+ if (status != 0) {
+ printf("\n\nReceived error code in %s: %d | %s\n", (ps_pid == 0) ? "server" : "client", status, strerror(status));
+ modules_test_cleanup();
+ }
+
+ return status;
+}
+
+/* The suite cleanup function.
+ * Returns zero on success, non-zero otherwise.
+ */
+int modules_test_cleanup(void)
+{
+ return 0;
+}
+
+/* Adds all the tests needed for this suite.
+*/
+int modules_add_tests(CU_pSuite suite)
+{
+ CU_ErrorCode status;
+
+ if (NULL == CU_add_test(suite, "semanage_module_list_serialize", test_semanage_module_list_serialize))
+ goto cleanup;
+
+cleanup:
+ if (CUE_SUCCESS != (status = CU_get_error()))
+ CU_cleanup_registry();
+ return status;
+}
+
+/* Tests the semanage_ps_connect function in modules.c
+*/
+void test_semanage_module_list_serialize(void)
+{
+ int status = 0;
+
+ uint32_t message_type;
+ uint64_t data_size;
+ char *data = NULL;
+ int timeout = 0;
+
+ semanage_module_info_t *modules = NULL;
+ int modules_size;
+
+ if (ps_pid == 0) {
+ /* Server code. */
+
+ /* Wait for message. */
+ if ((status = read_msg(sh, client_socket_fd, timeout, &message_type, &data_size, &data)))
+ goto cleanup;
+
+ CU_ASSERT( message_type == PS_LIST_MODULES );
+ if (message_type != PS_LIST_MODULES) {
+ status = -1;
+ goto cleanup;
+ }
+
+ /* Serialize the modules list. */
+ free(data);
+ data = NULL;
+
+ status = semanage_module_list_serialize(sh, &data, &data_size);
+
+
+ /* Send back the modules list. */
+ status = write_msg(sh, client_socket_fd, PS_OK, data_size, data);
+
+ }
+ else {
+ /* Client code. */
+
+ /* Get the list of modules. */
+ status = semanage_module_list(sh, &modules, &modules_size);
+ CU_ASSERT( status == STATUS_SUCCESS );
+
+ /* Verify data. */
+ CU_ASSERT_STRING_EQUAL( modules[0].name, "testname0" );
+ CU_ASSERT_STRING_EQUAL( modules[0].version, "testversion0" );
+ CU_ASSERT_STRING_EQUAL( modules[1].name, "testname1" );
+ CU_ASSERT_STRING_EQUAL( modules[1].version, "testversion1" );
+ }
+
+ /* cleanup */
+cleanup:
+ free(data);
+
+ CU_ASSERT( status == 0 );
+ if (status != 0) {
+ printf("\n\nReceived error code in %s: %d | %s\n", (ps_pid == 0) ? "server" : "client", status, strerror(status));
+ modules_test_cleanup();
+ }
+}
Index: selinux-pms-support/libsemanage/tests/test_modules.h
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/tests/test_modules.h
@@ -0,0 +1,32 @@
+/* Authors: Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __TEST_MODULES_H__
+#define __TEST_MODULES_H__
+
+#include <CUnit/Basic.h>
+
+int modules_test_init(void);
+int modules_test_cleanup(void);
+int modules_add_tests(CU_pSuite suite);
+
+void test_semanage_module_list_serialize(void);
+
+#endif
--
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH 27/33] libsemanage: booleans serialization tests
2007-04-23 21:34 [PATCH 00/33] libsemanage/libsepol object serialization and ps-api jbrindle
` (25 preceding siblings ...)
2007-04-23 21:35 ` [PATCH 26/33] libsemanage: module serialization tests jbrindle
@ 2007-04-23 21:35 ` jbrindle
2007-04-23 21:35 ` [PATCH 28/33] libsemanage: fcontexts " jbrindle
` (7 subsequent siblings)
34 siblings, 0 replies; 58+ messages in thread
From: jbrindle @ 2007-04-23 21:35 UTC (permalink / raw)
To: selinux
---
libsemanage/tests/libsemanage-tests.c | 7
libsemanage/tests/test_booleans_active.c | 461 +++++++++++++++++++++++++++++++
libsemanage/tests/test_booleans_active.h | 32 ++
libsemanage/tests/test_booleans_file.c | 457 ++++++++++++++++++++++++++++++
libsemanage/tests/test_booleans_file.h | 32 ++
libsemanage/tests/test_booleans_policy.c | 352 +++++++++++++++++++++++
libsemanage/tests/test_booleans_policy.h | 32 ++
libsemanage/tests/utilities.c | 58 +++
libsemanage/tests/utilities.h | 7
9 files changed, 1438 insertions(+)
Index: selinux-pms-support/libsemanage/tests/libsemanage-tests.c
===================================================================
--- selinux-pms-support.orig/libsemanage/tests/libsemanage-tests.c
+++ selinux-pms-support/libsemanage/tests/libsemanage-tests.c
@@ -35,6 +35,10 @@
#include "test_modules.h"
+#include "test_booleans_active.h"
+#include "test_booleans_file.h"
+#include "test_booleans_policy.h"
+
#include <CUnit/Basic.h>
#include <CUnit/Console.h>
#include <CUnit/TestDB.h>
@@ -90,6 +94,9 @@ static int do_tests(int interactive, int
* being properly connected via the
* ps_api_connect test.
*/
+ DECLARE_SUITE(booleans_active);
+ DECLARE_SUITE(booleans_file);
+ DECLARE_SUITE(booleans_policy);
/* The ps_api_disconnect test 'unforks'. */
DECLARE_SUITE(ps_api_disconnect);
Index: selinux-pms-support/libsemanage/tests/test_booleans_active.c
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/tests/test_booleans_active.c
@@ -0,0 +1,461 @@
+/* Authors: Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* The purpose of this file is to provide unit tests of the functions in:
+ *
+ * libsemanage/src/booleans_active.c
+ *
+ */
+
+#include "globals.h"
+#include "utilities.h"
+#include "test_booleans_active.h"
+
+#include <libgen.h>
+#include <limits.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <CUnit/Basic.h>
+
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <selinux/selinux.h>
+
+#include "debug.h"
+#include "byteswap.h"
+#include "handle.h"
+#include "modules.h"
+#include "policy.h"
+#include "booleans_active.h"
+#include "messages_internal.h"
+#include "semanage_store.h"
+#include "database_policydb.h"
+#include "user_internal.h"
+#include "seuser_internal.h"
+#include "port_internal.h"
+#include "iface_internal.h"
+#include "boolean_internal.h"
+#include "fcontext_internal.h"
+#include "node_internal.h"
+#include "database_llist.h"
+#include "serialize.h"
+
+/* Server table setup. */
+
+/* Record functions. */
+
+static record_table_t test_bool_rtable = {
+ .create = (create_f)semanage_bool_create,
+ .key_extract = (key_extract_f)semanage_bool_key_extract,
+ .key_free = (key_free_f)semanage_bool_key_free,
+ .clone = (clone_f)semanage_bool_clone,
+ .compare = (compare_f)semanage_bool_compare,
+ .compare2 = (compare2_f)semanage_bool_compare2,
+ .compare2_qsort = NULL,
+ .free = (free_f)semanage_bool_free,
+ .serialize = (serialize_f)semanage_bool_serialize,
+ .unserialize = (unserialize_f)semanage_bool_unserialize,
+};
+
+/* Table functions. */
+
+/* Test cache function. */
+static int test_dbase_activedb_cache(
+ semanage_handle_t *handle,
+ dbase_config_t *dconfig)
+{
+ int status = 0;
+
+ /* Add some test entries to the list. */
+ record_t *aboolean = NULL;
+ record_key_t *abooleankey = NULL;
+
+ record_table_t *rtable = dconfig->dtable->get_rtable(dconfig);
+
+ /* Create record. */
+ status = rtable->create(sh, &aboolean);
+ if (status) goto cleanup;
+
+ /* Populate record. */
+ status = semanage_bool_set_name(sh, (semanage_bool_t *)aboolean, "testbool");
+ if (status) goto cleanup;
+
+ semanage_bool_set_value((semanage_bool_t *)aboolean, 0);
+
+ status = rtable->key_extract(sh, aboolean, &abooleankey);
+ if (status) goto cleanup;
+
+ /* Add record. */
+ status = dconfig->dtable->add(
+ sh,
+ dconfig,
+ abooleankey,
+ aboolean);
+ if (status) goto cleanup;
+
+ /* Cleanup. */
+ rtable->free(aboolean);
+ aboolean = NULL;
+ rtable->key_free(abooleankey);
+ abooleankey = NULL;
+
+ /* Create record. */
+ status = rtable->create(sh, &aboolean);
+ if (status) goto cleanup;
+
+ /* Populate record. */
+ status = semanage_bool_set_name(sh, (semanage_bool_t *)aboolean, "testbool2");
+ semanage_bool_set_value((semanage_bool_t *)aboolean, 1);
+
+ status = rtable->key_extract(sh, aboolean, &abooleankey);
+
+ /* Add record. */
+ status = dconfig->dtable->add(
+ sh,
+ dconfig,
+ abooleankey,
+ aboolean);
+
+ /* Cleanup. */
+cleanup:
+ rtable->free(aboolean);
+ rtable->key_free(abooleankey);
+
+ return status;
+}
+
+/* Database callback table. */
+static dbase_table_t test_activedb_dtable = {
+
+ /* Cache/Transactions */
+ .cache = test_dbase_activedb_cache,
+ .drop_cache = (void *)dbase_llist_drop_cache,
+ .flush = NULL,
+ .is_modified = (void *)dbase_llist_is_modified,
+
+ /* Database API */
+ .iterate = (void *)dbase_llist_iterate,
+ .exists = (void *)dbase_llist_exists,
+ .list = (void *)dbase_llist_list,
+ .add = (void *)dbase_llist_add,
+ .set = (void *)dbase_llist_set,
+ .del = (void *)dbase_llist_del,
+ .clear = (void *)dbase_llist_clear,
+ .modify = (void *)dbase_llist_modify,
+ .query = (void *)dbase_llist_query,
+ .count = (void *)dbase_llist_count,
+
+ /* Polymorphism */
+ .get_rtable = (void *)dbase_llist_get_rtable
+};
+
+/* The suite initialization function.
+ * Returns zero on success, non-zero otherwise.
+ */
+int booleans_active_test_init(void)
+{
+ int status = 0;
+
+ if (ps_pid == 0) {
+ /* Server code. */
+
+ /* Reset locks status. */
+ sh->u.direct.activelock_file_fd = 0;
+ sh->u.ps_handle.socket_fd = 0;
+
+ /* Store setup. */
+ dbase_config_t *dconfig = semanage_bool_dbase_active(sh);
+
+ if ((status =
+ dbase_activedb_init(
+ sh,
+ &test_bool_rtable,
+ NULL,
+ (dbase_activedb_t **)&dconfig->dbase)))
+ goto cleanup;
+
+ dconfig->dtable = &test_activedb_dtable;
+
+ }
+
+ /* Cleanup. */
+cleanup:
+ return status;
+}
+
+/* The suite cleanup function.
+ * Returns zero on success, non-zero otherwise.
+ */
+int booleans_active_test_cleanup(void)
+{
+ return 0;
+}
+
+/* Adds all the tests needed for this suite.
+*/
+int booleans_active_add_tests(CU_pSuite suite)
+{
+ CU_ErrorCode status;
+
+ if (NULL == CU_add_test(suite, "semanage_bool_serialize_active", test_semanage_bool_serialize_active))
+ goto cleanup;
+
+cleanup:
+ if (CUE_SUCCESS != (status = CU_get_error()))
+ CU_cleanup_registry();
+ return status;
+}
+
+/* Tests the semanage_bool_serialize_active function in booleans_active.c
+ */
+void test_semanage_bool_serialize_active(void) {
+ int status;
+
+ uint32_t message_type;
+ uint64_t data_length;
+ char *data = NULL;
+ char *ptr = NULL;
+ int timeout = 0;
+ uint32_t database_type = 0;
+
+ semanage_bool_t **records = NULL;
+ unsigned int records_size;
+
+ dbase_config_t *dconfig = semanage_bool_dbase_active(sh);
+ record_table_t *rtable = dconfig->dtable->get_rtable(dconfig);
+
+ const char *name;
+ int value;
+
+ int commit_number = 7;
+
+ if (ps_pid == 0) {
+ /* Server code. */
+
+ /* On caching the client will ask for the commit number. */
+ status = test_semanage_ps_handle_get_commit_number(sh, commit_number);
+ CU_ASSERT( status == STATUS_SUCCESS );
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Wait for message. */
+ free(data);
+ data = NULL;
+
+ if ((status = read_msg(sh, client_socket_fd, timeout, &message_type, &data_length, &data)))
+ goto cleanup;
+
+ CU_ASSERT( message_type == PS_GET_DATABASE );
+ if (message_type != PS_GET_DATABASE) {
+ status = -1;
+ goto cleanup;
+ }
+
+ /* Serialize the database. */
+ free(data);
+ data = NULL;
+
+ if ((status = semanage_bool_serialize_active(sh, &data, &data_length)))
+ goto cleanup;
+
+ /* Send back the database. */
+ if ((status = write_msg(sh, client_socket_fd, PS_OK, data_length, data)))
+ goto cleanup;
+
+ /* On caching the client will ask for the commit number. */
+ status = test_semanage_ps_handle_get_commit_number(sh, commit_number);
+ CU_ASSERT( status == STATUS_SUCCESS );
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* On flushing the client will ask for the commit number. */
+ //FIXME: Why does the client ask for the commit number so many times here?
+ status = test_semanage_ps_handle_get_commit_number(sh, commit_number);
+ CU_ASSERT( status == STATUS_SUCCESS );
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ status = test_semanage_ps_handle_get_commit_number(sh, commit_number);
+ CU_ASSERT( status == STATUS_SUCCESS );
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Receive changed database. */
+ free(data);
+ data = NULL;
+
+ if ((status = read_msg(sh, client_socket_fd, timeout, &message_type, &data_length, &data)))
+ goto cleanup;
+
+ CU_ASSERT( message_type == PS_PUT_DATABASE );
+ if (message_type != PS_PUT_DATABASE) {
+ status = -1;
+ goto cleanup;
+ }
+
+ /* Say we got it ok. */
+ if ((status = write_msg(sh, client_socket_fd, PS_OK, 0, NULL)))
+ goto cleanup;
+
+ /* dont move data pointer so we can free it later */
+ ptr = data;
+ /* Unserialize the database type */
+ if(semanage_dbase_ps_database_type_unserialize(sh, &ptr, &data_length, &database_type))
+ goto cleanup;
+
+ /* Unserialize the database. */
+ if ((status = semanage_bool_unserialize_active(sh, ptr, data_length)))
+ goto cleanup;
+
+ /* Gather the database records. */
+ status = dconfig->dtable->list(sh, dconfig, (record_t ***)&records, &records_size);
+ CU_ASSERT( status == 0 );
+ CU_ASSERT( records != NULL );
+ CU_ASSERT( records_size == 3 );
+
+ /* Verify data. */
+ name = semanage_bool_get_name(records[0]);
+ value = semanage_bool_get_value(records[0]);
+
+ CU_ASSERT( strcmp(name, "testbool") == 0 );
+ CU_ASSERT( value == 0 );
+
+ name = semanage_bool_get_name(records[1]);
+ value = semanage_bool_get_value(records[1]);
+
+ CU_ASSERT( strcmp(name, "testbool2") == 0 );
+ CU_ASSERT( value == 1 );
+
+ name = semanage_bool_get_name(records[2]);
+ value = semanage_bool_get_value(records[2]);
+
+ CU_ASSERT( strcmp(name, "testbool3") == 0 );
+ CU_ASSERT( value == 0 );
+ }
+
+ if (ps_pid > 0) {
+ /* Client code. */
+
+ /* Cache database.
+ * This sends a message to the server requesting the database.
+ * The server serializes the database and sends it to us (the client).
+ * Internally the database is unserialized and loaded.
+ */
+ status = dconfig->dtable->cache(sh, dconfig);
+ CU_ASSERT( status == 0 );
+
+ /* Gather the database records. */
+ status = dconfig->dtable->list(sh, dconfig, (record_t ***)&records, &records_size);
+ CU_ASSERT( status == 0 );
+ CU_ASSERT( records != NULL );
+ CU_ASSERT( records_size == 2 );
+
+ /* Verify data was sent correctly. */
+ name = semanage_bool_get_name(records[0]);
+ value = semanage_bool_get_value(records[0]);
+
+ CU_ASSERT( strcmp(name, "testbool") == 0 );
+ CU_ASSERT( value == 0 );
+
+ name = semanage_bool_get_name(records[1]);
+ value = semanage_bool_get_value(records[1]);
+
+ CU_ASSERT( strcmp(name, "testbool2") == 0 );
+ CU_ASSERT( value == 1 );
+
+ /* Change something. */
+
+ /* Add some test entries to the list. */
+ record_t *aboolean = NULL;
+ record_key_t *abooleankey = NULL;
+
+ /* Create record. */
+ status = rtable->create(sh, &aboolean);
+ if (status) goto cleanup;
+
+ /* Populate record. */
+ status = semanage_bool_set_name(sh, (semanage_bool_t *)aboolean, "testbool3");
+ if (status) goto cleanup;
+
+ semanage_bool_set_value((semanage_bool_t *)aboolean, 0);
+
+ status = rtable->key_extract(sh, aboolean, &abooleankey);
+ if (status) goto cleanup;
+
+ /* Add record. */
+ status = dconfig->dtable->add(
+ sh,
+ dconfig,
+ abooleankey,
+ aboolean);
+ if (status) goto cleanup;
+
+ /* Cleanup. */
+ rtable->free(aboolean);
+ rtable->key_free(abooleankey);
+
+ /* Flush database.
+ * This sends a message to the server to replace its database
+ * with the one we are sending. Internally the flush serializes
+ * the database and sends it. The server then unserializes it,
+ * clears its old copy, and replaces it with the new one.
+ */
+ status = dconfig->dtable->flush(sh, dconfig);
+ CU_ASSERT( status == 0 );
+
+ }
+
+ /* Cleanup. */
+cleanup:
+ if (records != NULL) {
+ unsigned int i;
+ for (i = 0; i < records_size; i++) {
+ if (!records[i])
+ break;
+ rtable->free((record_t *)records[i]);
+ }
+ }
+
+ free(records);
+ free(data);
+
+ CU_ASSERT( status == 0 );
+ if (status != 0) {
+ printf("\n\nReceived error code in %s: %d | %s\n", (ps_pid == 0) ? "server" : "client", status, strerror(status));
+ }
+}
+
Index: selinux-pms-support/libsemanage/tests/test_booleans_active.h
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/tests/test_booleans_active.h
@@ -0,0 +1,32 @@
+/* Authors: Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __TEST_BOOLEANS_ACTIVE_H__
+#define __TEST_BOOLEANS_ACTIVE_H__
+
+#include <CUnit/Basic.h>
+
+int booleans_active_test_init(void);
+int booleans_active_test_cleanup(void);
+int booleans_active_add_tests(CU_pSuite suite);
+
+void test_semanage_bool_serialize_active(void);
+
+#endif
Index: selinux-pms-support/libsemanage/tests/test_booleans_file.c
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/tests/test_booleans_file.c
@@ -0,0 +1,457 @@
+/* Authors: Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* The purpose of this file is to provide unit tests of the functions in:
+ *
+ * libsemanage/src/booleans_file.c
+ *
+ */
+
+#include "globals.h"
+#include "utilities.h"
+#include "test_booleans_file.h"
+
+#include <libgen.h>
+#include <limits.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <CUnit/Basic.h>
+
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <selinux/selinux.h>
+
+#include "debug.h"
+#include "byteswap.h"
+#include "handle.h"
+#include "modules.h"
+#include "policy.h"
+#include "booleans_local.h"
+#include "messages_internal.h"
+#include "semanage_store.h"
+#include "database_file.h"
+#include "user_internal.h"
+#include "seuser_internal.h"
+#include "port_internal.h"
+#include "iface_internal.h"
+#include "boolean_internal.h"
+#include "fcontext_internal.h"
+#include "node_internal.h"
+
+#include "database_llist.h"
+
+/* Server table setup. */
+
+/* Record functions. */
+
+static record_table_t test_bool_rtable = {
+ .create = (create_f)semanage_bool_create,
+ .key_extract = (key_extract_f)semanage_bool_key_extract,
+ .key_free = (key_free_f)semanage_bool_key_free,
+ .clone = (clone_f)semanage_bool_clone,
+ .compare = (compare_f)semanage_bool_compare,
+ .compare2 = (compare2_f)semanage_bool_compare2,
+ .compare2_qsort = NULL,
+ .free = (free_f)semanage_bool_free,
+ .serialize = (serialize_f)semanage_bool_serialize,
+ .unserialize = (unserialize_f)semanage_bool_unserialize,
+};
+
+/* Table functions. */
+
+/* Test cache function. */
+static int test_dbase_file_cache(
+ semanage_handle_t *handle,
+ dbase_config_t *dconfig)
+{
+ int status = 0;
+
+ /* Add some test entries to the list. */
+ record_t *aboolean = NULL;
+ record_key_t *abooleankey = NULL;
+
+ record_table_t *rtable = dconfig->dtable->get_rtable(dconfig);
+
+ /* Create record. */
+ status = rtable->create(sh, &aboolean);
+ if (status) goto cleanup;
+
+ /* Populate record. */
+ status = semanage_bool_set_name(sh, (semanage_bool_t *)aboolean, "testbool");
+ if (status) goto cleanup;
+
+ semanage_bool_set_value((semanage_bool_t *)aboolean, 0);
+
+ status = rtable->key_extract(sh, aboolean, &abooleankey);
+ if (status) goto cleanup;
+
+ /* Add record. */
+ status = dconfig->dtable->add(
+ sh,
+ dconfig,
+ abooleankey,
+ aboolean);
+ if (status) goto cleanup;
+
+ /* Cleanup. */
+ rtable->free(aboolean);
+ aboolean = NULL;
+ rtable->key_free(abooleankey);
+ abooleankey = NULL;
+
+ /* Create record. */
+ status = rtable->create(sh, &aboolean);
+ if (status) goto cleanup;
+
+ /* Populate record. */
+ status = semanage_bool_set_name(sh, (semanage_bool_t *)aboolean, "testbool2");
+ semanage_bool_set_value((semanage_bool_t *)aboolean, 1);
+
+ status = rtable->key_extract(sh, aboolean, &abooleankey);
+
+ /* Add record. */
+ status = dconfig->dtable->add(
+ sh,
+ dconfig,
+ abooleankey,
+ aboolean);
+
+ /* Cleanup. */
+cleanup:
+ rtable->free(aboolean);
+ rtable->key_free(abooleankey);
+
+ return status;
+}
+
+/* Database callback table. */
+static dbase_table_t test_file_dtable = {
+
+ /* Cache/Transactions */
+ .cache = test_dbase_file_cache,
+ .drop_cache = (void *)dbase_llist_drop_cache,
+ .flush = NULL,
+ .is_modified = (void *)dbase_llist_is_modified,
+
+ /* Database API */
+ .iterate = (void *)dbase_llist_iterate,
+ .exists = (void *)dbase_llist_exists,
+ .list = (void *)dbase_llist_list,
+ .add = (void *)dbase_llist_add,
+ .set = (void *)dbase_llist_set,
+ .del = (void *)dbase_llist_del,
+ .clear = (void *)dbase_llist_clear,
+ .modify = (void *)dbase_llist_modify,
+ .query = (void *)dbase_llist_query,
+ .count = (void *)dbase_llist_count,
+
+ /* Polymorphism */
+ .get_rtable = (void *)dbase_llist_get_rtable
+};
+
+/* The suite initialization function.
+ * Returns zero on success, non-zero otherwise.
+ */
+int booleans_file_test_init(void)
+{
+ int status = 0;
+
+ if (ps_pid == 0) {
+ /* Server code. */
+
+ /* Reset locks status. */
+ sh->u.direct.activelock_file_fd = 0;
+ sh->u.ps_handle.socket_fd = 0;
+
+ /* Store setup. */
+ dbase_config_t *dconfig = semanage_bool_dbase_local(sh);
+
+ if ((status =
+ dbase_file_init(
+ sh,
+ "/tmp/test-fake-filedb",
+ &test_bool_rtable,
+ NULL,
+ (dbase_file_t **)&dconfig->dbase)))
+ goto cleanup;
+
+ dconfig->dtable = &test_file_dtable;
+ }
+
+ /* Cleanup. */
+cleanup:
+ return status;
+}
+
+/* The suite cleanup function.
+ * Returns zero on success, non-zero otherwise.
+ */
+int booleans_file_test_cleanup(void)
+{
+ return 0;
+}
+
+/* Adds all the tests needed for this suite.
+*/
+int booleans_file_add_tests(CU_pSuite suite)
+{
+ CU_ErrorCode status;
+
+ if (NULL == CU_add_test(suite, "semanage_bool_serialize_local", test_semanage_bool_serialize_local))
+ goto cleanup;
+
+cleanup:
+ if (CUE_SUCCESS != (status = CU_get_error()))
+ CU_cleanup_registry();
+ return status;
+}
+
+/* Tests the semanage_bool_serialize_local function in booleans_file.c
+ */
+void test_semanage_bool_serialize_local(void) {
+ int status;
+
+ uint32_t message_type;
+ uint64_t data_length;
+ char *data = NULL;
+ char *ptr = NULL;
+ int timeout = 0;
+ uint32_t database_type = 0;
+
+ semanage_bool_t **records = NULL;
+ unsigned int records_size;
+
+ dbase_config_t *dconfig = semanage_bool_dbase_local(sh);
+ record_table_t *rtable = dconfig->dtable->get_rtable(dconfig);
+
+ const char *name;
+ int value;
+
+ int commit_number = 7;
+
+ if (ps_pid == 0) {
+ /* Server code. */
+
+ /* On caching the client will ask for the commit number. */
+ status = test_semanage_ps_handle_get_commit_number(sh, commit_number);
+ CU_ASSERT( status == STATUS_SUCCESS );
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Wait for message. */
+ if ((status = read_msg(sh, client_socket_fd, timeout, &message_type, &data_length, &data)))
+ goto cleanup;
+
+ CU_ASSERT( message_type == PS_GET_DATABASE );
+ if (message_type != PS_GET_DATABASE) {
+ status = -1;
+ goto cleanup;
+ }
+
+ /* Get and serialize the database. */
+ free(data);
+ data = NULL;
+
+ if ((status = semanage_bool_serialize_local(sh, &data, &data_length)))
+ goto cleanup;
+
+ /* Send back the database. */
+ if ((status = write_msg(sh, client_socket_fd, PS_OK, data_length, data)))
+ goto cleanup;
+
+ /* On caching the client will ask for the commit number. */
+ status = test_semanage_ps_handle_get_commit_number(sh, commit_number);
+ CU_ASSERT( status == STATUS_SUCCESS );
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* On flushing the client will ask for the commit number. */
+ //FIXME: Why does the client ask for the commit number so many times here?
+ status = test_semanage_ps_handle_get_commit_number(sh, commit_number);
+ CU_ASSERT( status == STATUS_SUCCESS );
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ status = test_semanage_ps_handle_get_commit_number(sh, commit_number);
+ CU_ASSERT( status == STATUS_SUCCESS );
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Receive changed database. */
+ free(data);
+ data = NULL;
+
+ if ((status = read_msg(sh, client_socket_fd, timeout, &message_type, &data_length, &data)))
+ goto cleanup;
+
+ CU_ASSERT( message_type == PS_PUT_DATABASE );
+ if (message_type != PS_PUT_DATABASE) {
+ status = -1;
+ goto cleanup;
+ }
+
+ /* Say we got it ok. */
+ if ((status = write_msg(sh, client_socket_fd, PS_OK, 0, NULL)))
+ goto cleanup;
+
+ /* dont move data pointer so we can free it later */
+ ptr = data;
+ /* Unserialize the database type */
+ if(semanage_dbase_ps_database_type_unserialize(sh, &ptr, &data_length, &database_type))
+ goto cleanup;
+
+ /* Unserialize the database. and don't move the data pointer*/
+ if ((status = semanage_bool_unserialize_local(sh, ptr, data_length)))
+ goto cleanup;
+
+ /* Gather the database records. */
+ status = dconfig->dtable->list(sh, dconfig, (record_t ***)&records, &records_size);
+ CU_ASSERT( status == 0 );
+ CU_ASSERT( records != NULL );
+ CU_ASSERT( records_size == 3 );
+
+ /* Verify data. */
+ name = semanage_bool_get_name(records[0]);
+ value = semanage_bool_get_value(records[0]);
+
+ CU_ASSERT( strcmp(name, "testbool") == 0 );
+ CU_ASSERT( value == 0 );
+
+ name = semanage_bool_get_name(records[1]);
+ value = semanage_bool_get_value(records[1]);
+
+ CU_ASSERT( strcmp(name, "testbool2") == 0 );
+ CU_ASSERT( value == 1 );
+
+ name = semanage_bool_get_name(records[2]);
+ value = semanage_bool_get_value(records[2]);
+
+ CU_ASSERT( strcmp(name, "testbool3") == 0 );
+ CU_ASSERT( value == 0 );
+ }
+
+ if (ps_pid > 0) {
+ /* Client code. */
+
+ /* Cache database.
+ * This sends a message to the server requesting the database.
+ * The server serializes the database and sends it to us (the client).
+ * Internally the database is unserialized and loaded.
+ */
+ status = dconfig->dtable->cache(sh, dconfig);
+ CU_ASSERT( status == 0 );
+
+ /* Gather the database records. */
+ status = dconfig->dtable->list(sh, dconfig, (record_t ***)&records, &records_size);
+ CU_ASSERT( status == 0 );
+ CU_ASSERT( records != NULL );
+ CU_ASSERT( records_size == 2 );
+
+ /* Verify data was sent correctly. */
+ name = semanage_bool_get_name(records[0]);
+ value = semanage_bool_get_value(records[0]);
+
+ CU_ASSERT( strcmp(name, "testbool") == 0 );
+ CU_ASSERT( value == 0 );
+
+ name = semanage_bool_get_name(records[1]);
+ value = semanage_bool_get_value(records[1]);
+
+ CU_ASSERT( strcmp(name, "testbool2") == 0 );
+ CU_ASSERT( value == 1 );
+
+ /* Change something. */
+
+ /* Add some test entries to the list. */
+ record_t *aboolean = NULL;
+ record_key_t *abooleankey = NULL;
+
+ /* Create record. */
+ status = rtable->create(sh, &aboolean);
+ if (status) goto cleanup;
+
+ /* Populate record. */
+ status = semanage_bool_set_name(sh, (semanage_bool_t *)aboolean, "testbool3");
+ if (status) goto cleanup;
+
+ semanage_bool_set_value((semanage_bool_t *)aboolean, 0);
+
+ status = rtable->key_extract(sh, aboolean, &abooleankey);
+ if (status) goto cleanup;
+
+ /* Add record. */
+ status = dconfig->dtable->add(
+ sh,
+ dconfig,
+ abooleankey,
+ aboolean);
+ if (status) goto cleanup;
+
+ /* Cleanup. */
+ rtable->free(aboolean);
+ rtable->key_free(abooleankey);
+
+ /* Flush database.
+ * This sends a message to the server to replace its database
+ * with the one we are sending. Internally the flush serializes
+ * the database and sends it. The server then unserializes it,
+ * clears its old copy, and replaces it with the new one.
+ */
+ status = dconfig->dtable->flush(sh, dconfig);
+ CU_ASSERT( status == 0 );
+ }
+
+ /* Cleanup. */
+cleanup:
+ if (records != NULL) {
+ unsigned int i;
+ for (i = 0; i < records_size; i++) {
+ if (!records[i])
+ break;
+ rtable->free((record_t *)records[i]);
+ }
+ }
+
+ free(records);
+ free(data);
+
+ CU_ASSERT( status == 0 );
+ if (status != 0) {
+ printf("\n\nReceived error code in %s: %d | %s\n", (ps_pid == 0) ? "server" : "client", status, strerror(status));
+ }
+}
+
Index: selinux-pms-support/libsemanage/tests/test_booleans_file.h
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/tests/test_booleans_file.h
@@ -0,0 +1,32 @@
+/* Authors: Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __TEST_BOOLEANS_FILE_H__
+#define __TEST_BOOLEANS_FILE_H__
+
+#include <CUnit/Basic.h>
+
+int booleans_file_test_init(void);
+int booleans_file_test_cleanup(void);
+int booleans_file_add_tests(CU_pSuite suite);
+
+void test_semanage_bool_serialize_local(void);
+
+#endif
Index: selinux-pms-support/libsemanage/tests/test_booleans_policy.c
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/tests/test_booleans_policy.c
@@ -0,0 +1,352 @@
+/* Authors: Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* The purpose of this file is to provide unit tests of the functions in:
+ *
+ * libsemanage/src/booleans_policy.c
+ *
+ */
+
+#include "globals.h"
+#include "utilities.h"
+#include "test_booleans_policy.h"
+
+#include <libgen.h>
+#include <limits.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <CUnit/Basic.h>
+
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <selinux/selinux.h>
+
+#include "debug.h"
+#include "byteswap.h"
+#include "handle.h"
+#include "modules.h"
+#include "policy.h"
+#include "booleans_policy.h"
+#include "messages_internal.h"
+#include "semanage_store.h"
+#include "database_policydb.h"
+#include "user_internal.h"
+#include "seuser_internal.h"
+#include "port_internal.h"
+#include "iface_internal.h"
+#include "boolean_internal.h"
+#include "fcontext_internal.h"
+#include "node_internal.h"
+
+#include "database_llist.h"
+
+/* Server table setup. */
+
+/* Record functions. */
+
+static record_table_t test_bool_rtable = {
+ .create = (create_f)semanage_bool_create,
+ .key_extract = (key_extract_f)semanage_bool_key_extract,
+ .key_free = (key_free_f)semanage_bool_key_free,
+ .clone = (clone_f)semanage_bool_clone,
+ .compare = (compare_f)semanage_bool_compare,
+ .compare2 = (compare2_f)semanage_bool_compare2,
+ .compare2_qsort = NULL,
+ .free = (free_f)semanage_bool_free,
+ .serialize = (serialize_f)semanage_bool_serialize,
+ .unserialize = (unserialize_f)semanage_bool_unserialize,
+};
+
+/* Table functions. */
+
+/* Test cache function. */
+static int test_dbase_policydb_cache(
+ semanage_handle_t *handle,
+ dbase_config_t *dconfig)
+{
+ int status = 0;
+
+ /* Add some test entries to the list. */
+ record_t *aboolean = NULL;
+ record_key_t *abooleankey = NULL;
+
+ record_table_t *rtable = dconfig->dtable->get_rtable(dconfig);
+
+ /* Create record. */
+ status = rtable->create(sh, &aboolean);
+ if (status) goto cleanup;
+
+ /* Populate record. */
+ status = semanage_bool_set_name(sh, (semanage_bool_t *)aboolean, "testbool");
+ if (status) goto cleanup;
+
+ semanage_bool_set_value((semanage_bool_t *)aboolean, 0);
+
+ status = rtable->key_extract(sh, aboolean, &abooleankey);
+ if (status) goto cleanup;
+
+ /* Add record. */
+ status = dconfig->dtable->add(
+ sh,
+ dconfig,
+ abooleankey,
+ aboolean);
+ if (status) goto cleanup;
+
+ /* Cleanup. */
+ rtable->free(aboolean);
+ aboolean = NULL;
+ rtable->key_free(abooleankey);
+ abooleankey = NULL;
+
+ /* Create record. */
+ status = rtable->create(sh, &aboolean);
+ if (status) goto cleanup;
+
+ /* Populate record. */
+ status = semanage_bool_set_name(sh, (semanage_bool_t *)aboolean, "testbool2");
+ semanage_bool_set_value((semanage_bool_t *)aboolean, 1);
+
+ status = rtable->key_extract(sh, aboolean, &abooleankey);
+
+ /* Add record. */
+ status = dconfig->dtable->add(
+ sh,
+ dconfig,
+ abooleankey,
+ aboolean);
+
+ /* Cleanup. */
+cleanup:
+ rtable->free(aboolean);
+ rtable->key_free(abooleankey);
+
+ return status;
+}
+
+/* Database callback table. */
+static dbase_table_t test_policydb_dtable = {
+
+ /* Cache/Transactions */
+ .cache = test_dbase_policydb_cache,
+ .drop_cache = (void *)dbase_llist_drop_cache,
+ .flush = NULL,
+ .is_modified = (void *)dbase_llist_is_modified,
+
+ /* Database API */
+ .iterate = (void *)dbase_llist_iterate,
+ .exists = (void *)dbase_llist_exists,
+ .list = (void *)dbase_llist_list,
+ .add = (void *)dbase_llist_add,
+ .set = (void *)dbase_llist_set,
+ .del = (void *)dbase_llist_del,
+ .clear = (void *)dbase_llist_clear,
+ .modify = (void *)dbase_llist_modify,
+ .query = (void *)dbase_llist_query,
+ .count = (void *)dbase_llist_count,
+
+ /* Polymorphism */
+ .get_rtable = (void *)dbase_llist_get_rtable
+};
+
+/* The suite initialization function.
+ * Returns zero on success, non-zero otherwise.
+ */
+int booleans_policy_test_init(void)
+{
+ int status = 0;
+
+ if (ps_pid == 0) {
+ /* Server code. */
+
+ /* Reset locks status. */
+ sh->u.direct.activelock_file_fd = 0;
+ sh->u.ps_handle.socket_fd = 0;
+
+ /* Store setup. */
+ dbase_config_t *dconfig = semanage_bool_dbase_policy(sh);
+
+ if ((status =
+ dbase_policydb_init(
+ sh,
+ "policy.kern",
+ &test_bool_rtable,
+ NULL,
+ (dbase_policydb_t **)&dconfig->dbase)))
+ goto cleanup;
+
+ dconfig->dtable = &test_policydb_dtable;
+ }
+
+ /* Cleanup. */
+cleanup:
+ return status;
+}
+
+/* The suite cleanup function.
+ * Returns zero on success, non-zero otherwise.
+ */
+int booleans_policy_test_cleanup(void)
+{
+ return 0;
+}
+
+/* Adds all the tests needed for this suite.
+*/
+int booleans_policy_add_tests(CU_pSuite suite)
+{
+ CU_ErrorCode status;
+
+ if (NULL == CU_add_test(suite, "semanage_bool_serialize_policy", test_semanage_bool_serialize_policy))
+ goto cleanup;
+
+cleanup:
+ if (CUE_SUCCESS != (status = CU_get_error()))
+ CU_cleanup_registry();
+ return status;
+}
+
+/* Tests the semanage_bool_serialize_policy function in booleans_policy.c
+ */
+void test_semanage_bool_serialize_policy(void) {
+ int status;
+
+ uint32_t message_type;
+ uint64_t data_length;
+ char *data = NULL;
+ int timeout = 0;
+
+ semanage_bool_t **records = NULL;
+ unsigned int records_size;
+
+ dbase_config_t *dconfig = semanage_bool_dbase_policy(sh);
+ record_table_t *rtable = dconfig->dtable->get_rtable(dconfig);
+
+ const char *name;
+ int value;
+
+ int commit_number = 7;
+
+ if (ps_pid == 0) {
+ /* Server code. */
+
+ /* On caching the client will ask for the commit number. */
+ status = test_semanage_ps_handle_get_commit_number(sh, commit_number);
+ CU_ASSERT( status == STATUS_SUCCESS );
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Wait for message. */
+ if ((status = read_msg(sh, client_socket_fd, timeout, &message_type, &data_length, &data)))
+ goto cleanup;
+
+ CU_ASSERT( message_type == PS_GET_DATABASE );
+ if (message_type != PS_GET_DATABASE) {
+ status = -1;
+ goto cleanup;
+ }
+
+ /* Get and serialize the database. */
+ free(data);
+ data = NULL;
+
+ if ((status = semanage_bool_serialize_policy(sh, &data, &data_length)))
+ goto cleanup;
+
+ /* Send back the database. */
+ if ((status = write_msg(sh, client_socket_fd, PS_OK, data_length, data)))
+ goto cleanup;
+
+ /* On caching the client will ask for the commit number. */
+ status = test_semanage_ps_handle_get_commit_number(sh, commit_number);
+ CU_ASSERT( status == STATUS_SUCCESS );
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ }
+
+ if (ps_pid > 0) {
+ /* Client code. */
+
+ /* Cache database.
+ * This sends a message to the server requesting the database.
+ * The server serializes the database and sends it to us (the client).
+ * Internally the database is unserialized and loaded.
+ */
+ status = dconfig->dtable->cache(sh, dconfig);
+ CU_ASSERT( status == 0 );
+
+ /* Gather the database records. */
+ status = dconfig->dtable->list(sh, dconfig, (record_t ***)&records, &records_size);
+ CU_ASSERT( status == 0 );
+ CU_ASSERT( records != NULL );
+ CU_ASSERT( records_size == 2 );
+
+ /* Verify data was sent correctly. */
+ name = semanage_bool_get_name(records[0]);
+ value = semanage_bool_get_value(records[0]);
+
+ CU_ASSERT( strcmp(name, "testbool") == 0 );
+ CU_ASSERT( value == 0 );
+
+ name = semanage_bool_get_name(records[1]);
+ value = semanage_bool_get_value(records[1]);
+
+ CU_ASSERT( strcmp(name, "testbool2") == 0 );
+ CU_ASSERT( value == 1 );
+ }
+
+ /* Cleanup. */
+cleanup:
+ if (records != NULL) {
+ unsigned int i;
+ for (i = 0; i < records_size; i++) {
+ if (!records[i])
+ break;
+ rtable->free((record_t *)records[i]);
+ }
+ }
+
+ free(records);
+ free(data);
+
+ CU_ASSERT( status == 0 );
+ if (status != 0) {
+ printf("\n\nReceived error code in %s: %d | %s\n", (ps_pid == 0) ? "server" : "client", status, strerror(status));
+ }
+}
+
Index: selinux-pms-support/libsemanage/tests/test_booleans_policy.h
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/tests/test_booleans_policy.h
@@ -0,0 +1,32 @@
+/* Authors: Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __TEST_BOOLEANS_POLICY_H__
+#define __TEST_BOOLEANS_POLICY_H__
+
+#include <CUnit/Basic.h>
+
+int booleans_policy_test_init(void);
+int booleans_policy_test_cleanup(void);
+int booleans_policy_add_tests(CU_pSuite suite);
+
+void test_semanage_bool_serialize_policy(void);
+
+#endif
Index: selinux-pms-support/libsemanage/tests/utilities.c
===================================================================
--- selinux-pms-support.orig/libsemanage/tests/utilities.c
+++ selinux-pms-support/libsemanage/tests/utilities.c
@@ -21,6 +21,15 @@
* by our unit tests.
*/
+#include <inttypes.h>
+#include <stdlib.h>
+#include <CUnit/Basic.h>
+
+#include "debug.h"
+#include "globals.h"
+#include "handle.h"
+#include "messages_internal.h"
+#include "policy.h"
#include "utilities.h"
/* Silence any error output caused by our tests
@@ -30,3 +39,52 @@ void test_msg_handler(void *varg,
semanage_handle_t * handle, const char *fmt, ...)
{
}
+
+int test_semanage_serialize_serial(semanage_handle_t *sh, int commit_number, char **data, uint64_t *data_length)
+{
+ int status = STATUS_SUCCESS;
+
+ status = semanage_policy_table_serialize_serial(sh, data, data_length);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+cleanup:
+ return status;
+}
+
+int test_semanage_ps_handle_get_commit_number(semanage_handle_t *sh, int commit_number) {
+ int status;
+
+ uint32_t message_type;
+ uint64_t data_length;
+ char *data = NULL;
+ int timeout = 0;
+
+ /* Wait for message. */
+ if ((status = read_msg(sh, client_socket_fd, timeout, &message_type, &data_length, &data)))
+ goto cleanup;
+
+ CU_ASSERT( message_type == PS_GET_COMMIT_NUMBER );
+ if (message_type != PS_GET_COMMIT_NUMBER) {
+ status = STATUS_ERR;
+ goto cleanup;
+ }
+
+ /* Serialize the commit number. */
+ free(data);
+ data = NULL;
+
+ status = test_semanage_serialize_serial(sh, commit_number, &data, &data_length);
+ CU_ASSERT( status == STATUS_SUCCESS);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ status = write_msg(sh, client_socket_fd, PS_OK, data_length, data);
+ CU_ASSERT( status == STATUS_SUCCESS);
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+cleanup:
+ free(data);
+ return status;
+}
Index: selinux-pms-support/libsemanage/tests/utilities.h
===================================================================
--- selinux-pms-support.orig/libsemanage/tests/utilities.h
+++ selinux-pms-support/libsemanage/tests/utilities.h
@@ -17,7 +17,14 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <inttypes.h>
+
#include "handle.h"
void test_msg_handler(void *varg, semanage_handle_t * handle, const char *fmt,
...);
+
+int test_semanage_serialize_serial(semanage_handle_t *sh, int commit_number, char **data, uint64_t *data_length);
+
+int test_semanage_ps_handle_get_commit_number(semanage_handle_t *sh, int commit_number);
+
--
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH 28/33] libsemanage: fcontexts serialization tests
2007-04-23 21:34 [PATCH 00/33] libsemanage/libsepol object serialization and ps-api jbrindle
` (26 preceding siblings ...)
2007-04-23 21:35 ` [PATCH 27/33] libsemanage: booleans " jbrindle
@ 2007-04-23 21:35 ` jbrindle
2007-04-23 21:35 ` [PATCH 29/33] libsemanage: interface " jbrindle
` (6 subsequent siblings)
34 siblings, 0 replies; 58+ messages in thread
From: jbrindle @ 2007-04-23 21:35 UTC (permalink / raw)
To: selinux
---
libsemanage/tests/libsemanage-tests.c | 6
libsemanage/tests/test_fcontexts_file.c | 531 ++++++++++++++++++++++++++++++
libsemanage/tests/test_fcontexts_file.h | 32 +
libsemanage/tests/test_fcontexts_policy.c | 394 ++++++++++++++++++++++
libsemanage/tests/test_fcontexts_policy.h | 32 +
5 files changed, 995 insertions(+)
Index: selinux-pms-support/libsemanage/tests/libsemanage-tests.c
===================================================================
--- selinux-pms-support.orig/libsemanage/tests/libsemanage-tests.c
+++ selinux-pms-support/libsemanage/tests/libsemanage-tests.c
@@ -39,6 +39,9 @@
#include "test_booleans_file.h"
#include "test_booleans_policy.h"
+#include "test_fcontexts_file.h"
+#include "test_fcontexts_policy.h"
+
#include <CUnit/Basic.h>
#include <CUnit/Console.h>
#include <CUnit/TestDB.h>
@@ -98,6 +101,9 @@ static int do_tests(int interactive, int
DECLARE_SUITE(booleans_file);
DECLARE_SUITE(booleans_policy);
+ DECLARE_SUITE(fcontexts_file);
+ DECLARE_SUITE(fcontexts_policy);
+
/* The ps_api_disconnect test 'unforks'. */
DECLARE_SUITE(ps_api_disconnect);
Index: selinux-pms-support/libsemanage/tests/test_fcontexts_file.c
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/tests/test_fcontexts_file.c
@@ -0,0 +1,531 @@
+/* Authors: Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* The purpose of this file is to provide unit tests of the functions in:
+ *
+ * libsemanage/src/fcontexts_file.c
+ *
+ */
+
+#include "globals.h"
+#include "utilities.h"
+#include "test_fcontexts_file.h"
+
+#include <libgen.h>
+#include <limits.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <CUnit/Basic.h>
+
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <selinux/selinux.h>
+
+#include "debug.h"
+#include "byteswap.h"
+#include "handle.h"
+#include "modules.h"
+#include "policy.h"
+#include "fcontexts_local.h"
+#include "messages_internal.h"
+#include "semanage_store.h"
+#include "database_file.h"
+#include "user_internal.h"
+#include "seuser_internal.h"
+#include "port_internal.h"
+#include "iface_internal.h"
+#include "boolean_internal.h"
+#include "fcontext_internal.h"
+#include "node_internal.h"
+
+#include "database_llist.h"
+
+/* Server table setup. */
+
+/* Record functions. */
+
+static record_table_t test_fcontext_rtable = {
+ .create = (create_f)semanage_fcontext_create,
+ .key_extract = (key_extract_f)semanage_fcontext_key_extract,
+ .key_free = (key_free_f)semanage_fcontext_key_free,
+ .clone = (clone_f)semanage_fcontext_clone,
+ .compare = (compare_f)semanage_fcontext_compare,
+ .compare2 = (compare2_f)semanage_fcontext_compare2,
+ .compare2_qsort = NULL,
+ .free = (free_f)semanage_fcontext_free,
+ .serialize = (serialize_f)semanage_fcontext_serialize,
+ .unserialize = (unserialize_f)semanage_fcontext_unserialize,
+};
+
+/* Table functions. */
+
+/* Test cache function. */
+static int test_dbase_file_cache(
+ semanage_handle_t *handle,
+ dbase_config_t *dconfig)
+{
+ int status = 0;
+
+ /* Add some test entries to the list. */
+ record_t *fcontext = NULL;
+ record_key_t *fcontextkey = NULL;
+
+ record_table_t *rtable = dconfig->dtable->get_rtable(dconfig);
+
+ /* Create record. */
+ status = rtable->create(sh, &fcontext);
+ if (status) goto cleanup;
+
+ /* Populate record. */
+ semanage_context_t *context;
+ status = semanage_context_create(sh, &context);
+ if (status) goto cleanup;
+
+ status = semanage_context_set_user(sh, context, "testuser");
+ if (status) goto cleanup;
+ status = semanage_context_set_role(sh, context, "testrole");
+ if (status) goto cleanup;
+ status = semanage_context_set_type(sh, context, "testtype");
+ if (status) goto cleanup;
+ status = semanage_fcontext_set_con(sh, (semanage_fcontext_t *)fcontext, context);
+ if (status) goto cleanup;
+
+ semanage_fcontext_set_type((semanage_fcontext_t *)fcontext, 1);
+ status = semanage_fcontext_set_expr(sh, (semanage_fcontext_t *)fcontext, "/testlocation/*");
+ if (status) goto cleanup;
+
+ status = rtable->key_extract(sh, fcontext, &fcontextkey);
+ if (status) goto cleanup;
+
+ /* Add record. */
+ status = dconfig->dtable->add(
+ sh,
+ dconfig,
+ fcontextkey,
+ fcontext);
+ if (status) goto cleanup;
+
+ /* Cleanup. */
+ semanage_context_free(context);
+ context = NULL;
+ rtable->free(fcontext);
+ fcontext = NULL;
+ rtable->key_free(fcontextkey);
+ fcontextkey = NULL;
+
+ /* Create record. */
+ status = rtable->create(sh, &fcontext);
+ if (status) goto cleanup;
+
+ /* Populate record. */
+ status = semanage_context_create(sh, &context);
+ if (status) goto cleanup;
+
+ status = semanage_context_set_user(sh, context, "testuser2");
+ if (status) goto cleanup;
+ status = semanage_context_set_role(sh, context, "testrole2");
+ if (status) goto cleanup;
+ status = semanage_context_set_type(sh, context, "testtype2");
+ if (status) goto cleanup;
+ status = semanage_fcontext_set_con(sh, (semanage_fcontext_t *)fcontext, context);
+ if (status) goto cleanup;
+
+ semanage_fcontext_set_type((semanage_fcontext_t *)fcontext, 2);
+ status = semanage_fcontext_set_expr(sh, (semanage_fcontext_t *)fcontext, "/testlocation2/*");
+ if (status) goto cleanup;
+
+ status = rtable->key_extract(sh, fcontext, &fcontextkey);
+ if (status) goto cleanup;
+
+ /* Add record. */
+ status = dconfig->dtable->add(
+ sh,
+ dconfig,
+ fcontextkey,
+ fcontext);
+ if (status) goto cleanup;
+
+ /* Cleanup. */
+cleanup:
+ semanage_context_free(context);
+ rtable->free(fcontext);
+ rtable->key_free(fcontextkey);
+
+ CU_ASSERT( status == 0 );
+ return status;
+}
+
+/* Database callback table. */
+static dbase_table_t test_file_dtable = {
+
+ /* Cache/Transactions */
+ .cache = test_dbase_file_cache,
+ .drop_cache = (void *)dbase_llist_drop_cache,
+ .flush = NULL,
+ .is_modified = (void *)dbase_llist_is_modified,
+
+ /* Database API */
+ .iterate = (void *)dbase_llist_iterate,
+ .exists = (void *)dbase_llist_exists,
+ .list = (void *)dbase_llist_list,
+ .add = (void *)dbase_llist_add,
+ .set = (void *)dbase_llist_set,
+ .del = (void *)dbase_llist_del,
+ .clear = (void *)dbase_llist_clear,
+ .modify = (void *)dbase_llist_modify,
+ .query = (void *)dbase_llist_query,
+ .count = (void *)dbase_llist_count,
+
+ /* Polymorphism */
+ .get_rtable = (void *)dbase_llist_get_rtable
+};
+
+/* The suite initialization function.
+ * Returns zero on success, non-zero otherwise.
+ */
+int fcontexts_file_test_init(void)
+{
+ int status = 0;
+
+ if (ps_pid == 0) {
+ /* Server code. */
+
+ /* Reset locks status. */
+ sh->u.ps_handle.socket_fd = 0;
+
+ /* Store setup. */
+ dbase_config_t *dconfig = semanage_fcontext_dbase_local(sh);
+
+ if ((status =
+ dbase_file_init(
+ sh,
+ "fakesuffix",
+ &test_fcontext_rtable,
+ NULL,
+ (dbase_file_t **)&dconfig->dbase)))
+ goto cleanup;
+
+ dconfig->dtable = &test_file_dtable;
+
+ }
+
+ /* Cleanup. */
+cleanup:
+ return status;
+}
+
+/* The suite cleanup function.
+ * Returns zero on success, non-zero otherwise.
+ */
+int fcontexts_file_test_cleanup(void)
+{
+ return 0;
+}
+
+/* Adds all the tests needed for this suite.
+*/
+int fcontexts_file_add_tests(CU_pSuite suite)
+{
+ CU_ErrorCode status;
+
+ if (NULL == CU_add_test(suite, "semanage_fcontext_serialize_local", test_semanage_fcontext_serialize_local))
+ goto cleanup;
+
+cleanup:
+ if (CUE_SUCCESS != (status = CU_get_error()))
+ CU_cleanup_registry();
+ return status;
+}
+
+/* Tests the semanage_fcontext_serialize_local function in fcontexts_file.c
+ */
+void test_semanage_fcontext_serialize_local(void) {
+ int status;
+
+ uint32_t message_type;
+ uint64_t data_length;
+ char *data = NULL;
+ char *ptr = NULL;
+ int timeout = 0;
+ uint32_t database_type = 0;
+
+ semanage_fcontext_t **records = NULL;
+ unsigned int records_size;
+
+ dbase_config_t *dconfig = semanage_fcontext_dbase_local(sh);
+ record_table_t *rtable = dconfig->dtable->get_rtable(dconfig);
+
+ int commit_number = 7;
+
+ if (ps_pid == 0) {
+ /* Server code. */
+
+ /* On caching the client will ask for the commit number. */
+ status = test_semanage_ps_handle_get_commit_number(sh, commit_number);
+ CU_ASSERT( status == STATUS_SUCCESS );
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Wait for message. */
+ if ((status = read_msg(sh, client_socket_fd, timeout, &message_type, &data_length, &data)))
+ goto cleanup;
+
+ CU_ASSERT( message_type == PS_GET_DATABASE );
+ if (message_type != PS_GET_DATABASE) {
+ status = -1;
+ goto cleanup;
+ }
+
+ /* Get and serialize the database. */
+ free(data);
+ data = NULL;
+
+ if ((status = semanage_fcontext_serialize_local(sh, &data, &data_length)))
+ goto cleanup;
+
+ /* Send back the database. */
+ if ((status = write_msg(sh, client_socket_fd, PS_OK, data_length, data)))
+ goto cleanup;
+
+ /* On caching the client will ask for the commit number. */
+ status = test_semanage_ps_handle_get_commit_number(sh, commit_number);
+ CU_ASSERT( status == STATUS_SUCCESS );
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* On flushing the client will ask for the commit number. */
+ //FIXME: Why does the client ask for the commit number so many times here?
+ status = test_semanage_ps_handle_get_commit_number(sh, commit_number);
+ CU_ASSERT( status == STATUS_SUCCESS );
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ status = test_semanage_ps_handle_get_commit_number(sh, commit_number);
+ CU_ASSERT( status == STATUS_SUCCESS );
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Receive changed database. */
+ free(data);
+ data = NULL;
+
+ if ((status = read_msg(sh, client_socket_fd, timeout, &message_type, &data_length, &data)))
+ goto cleanup;
+
+ CU_ASSERT( message_type == PS_PUT_DATABASE );
+ if (message_type != PS_PUT_DATABASE) {
+ status = -1;
+ goto cleanup;
+ }
+
+ /* Say we got it ok. */
+ if ((status = write_msg(sh, client_socket_fd, PS_OK, 0, NULL)))
+ goto cleanup;
+
+ /* Unserialize the database type */
+ ptr = data;
+ if(semanage_dbase_ps_database_type_unserialize(sh, &ptr, &data_length, &database_type));
+ goto cleanup;
+
+ /* Unserialize the database. and don't move the data pointer.*/
+ if ((status = semanage_fcontext_unserialize_local(sh, ptr, data_length)))
+ goto cleanup;
+
+ /* Gather the database records. */
+ status = dconfig->dtable->list(sh, dconfig, (record_t ***)&records, &records_size);
+ CU_ASSERT( status == 0 );
+ CU_ASSERT( records != NULL );
+ CU_ASSERT( records_size == 3 );
+
+ /* Verify data. */
+ semanage_context_t *context = semanage_fcontext_get_con(records[0]);
+ char *user = (char *)semanage_context_get_user(context);
+ char *role = (char *)semanage_context_get_role(context);
+ char *type = (char *)semanage_context_get_type(context);
+ int ftype = semanage_fcontext_get_type(records[0]);
+ char *expr = (char *)semanage_fcontext_get_expr(records[0]);
+
+ CU_ASSERT( strcmp(user, "testuser") == 0 );
+ CU_ASSERT( strcmp(role, "testrole") == 0 );
+ CU_ASSERT( strcmp(type, "testtype") == 0 );
+ CU_ASSERT( ftype == 1 );
+ CU_ASSERT( strcmp(expr, "/testlocation/*") == 0 );
+
+ context = semanage_fcontext_get_con(records[1]);
+ user = (char *)semanage_context_get_user(context);
+ role = (char *)semanage_context_get_role(context);
+ type = (char *)semanage_context_get_type(context);
+ ftype = semanage_fcontext_get_type(records[1]);
+ expr = (char *)semanage_fcontext_get_expr(records[1]);
+
+ CU_ASSERT( strcmp(user, "testuser2") == 0 );
+ CU_ASSERT( strcmp(role, "testrole2") == 0 );
+ CU_ASSERT( strcmp(type, "testtype2") == 0 );
+ CU_ASSERT( ftype == 2 );
+ CU_ASSERT( strcmp(expr, "/testlocation2/*") == 0 );
+
+ context = semanage_fcontext_get_con(records[2]);
+ user = (char *)semanage_context_get_user(context);
+ role = (char *)semanage_context_get_role(context);
+ type = (char *)semanage_context_get_type(context);
+ ftype = semanage_fcontext_get_type(records[2]);
+ expr = (char *)semanage_fcontext_get_expr(records[2]);
+
+ CU_ASSERT( strcmp(user, "testuser3") == 0 );
+ CU_ASSERT( strcmp(role, "testrole3") == 0 );
+ CU_ASSERT( strcmp(type, "testtype3") == 0 );
+ CU_ASSERT( ftype == 3 );
+ CU_ASSERT( strcmp(expr, "/testlocation3/*") == 0 );
+ }
+
+ if (ps_pid > 0) {
+ /* Client code. */
+
+ /* Cache database.
+ * This sends a message to the server requesting the database.
+ * The server serializes the database and sends it to us (the client).
+ * Internally the database is unserialized and loaded.
+ */
+ status = dconfig->dtable->cache(sh, dconfig);
+ CU_ASSERT( status == 0 );
+
+ /* Gather the database records. */
+ status = dconfig->dtable->list(sh, dconfig, (record_t ***)&records, &records_size);
+ CU_ASSERT( status == 0 );
+ CU_ASSERT( records != NULL );
+ CU_ASSERT( records_size == 2 );
+
+ /* Verify data was sent correctly. */
+ semanage_context_t *context = semanage_fcontext_get_con(records[0]);
+ char *user = (char *)semanage_context_get_user(context);
+ char *role = (char *)semanage_context_get_role(context);
+ char *type = (char *)semanage_context_get_type(context);
+ int ftype = semanage_fcontext_get_type(records[0]);
+ char *expr = (char *)semanage_fcontext_get_expr(records[0]);
+
+ CU_ASSERT( strcmp(user, "testuser") == 0 );
+ CU_ASSERT( strcmp(role, "testrole") == 0 );
+ CU_ASSERT( strcmp(type, "testtype") == 0 );
+ CU_ASSERT( ftype == 1 );
+ CU_ASSERT( strcmp(expr, "/testlocation/*") == 0 );
+
+ context = semanage_fcontext_get_con(records[1]);
+ user = (char *)semanage_context_get_user(context);
+ role = (char *)semanage_context_get_role(context);
+ type = (char *)semanage_context_get_type(context);
+ ftype = semanage_fcontext_get_type(records[1]);
+ expr = (char *)semanage_fcontext_get_expr(records[1]);
+
+ CU_ASSERT( strcmp(user, "testuser2") == 0 );
+ CU_ASSERT( strcmp(role, "testrole2") == 0 );
+ CU_ASSERT( strcmp(type, "testtype2") == 0 );
+ CU_ASSERT( ftype == 2 );
+ CU_ASSERT( strcmp(expr, "/testlocation2/*") == 0 );
+
+ /* Change something. */
+
+ /* Add some test entries to the list. */
+ record_t *fcontext = NULL;
+ record_key_t *fcontextkey = NULL;
+
+ /* Create record. */
+ status = rtable->create(sh, &fcontext);
+ if (status) goto cleanup;
+
+ /* Populate record. */
+ status = semanage_context_create(sh, &context);
+ if (status) goto cleanup;
+
+ status = semanage_context_set_user(sh, context, "testuser3");
+ if (status) goto cleanup;
+ status = semanage_context_set_role(sh, context, "testrole3");
+ if (status) goto cleanup;
+ status = semanage_context_set_type(sh, context, "testtype3");
+ if (status) goto cleanup;
+ status = semanage_fcontext_set_con(sh, (semanage_fcontext_t *)fcontext, context);
+ if (status) goto cleanup;
+
+ semanage_fcontext_set_type((semanage_fcontext_t *)fcontext, 3);
+ status = semanage_fcontext_set_expr(sh, (semanage_fcontext_t *)fcontext, "/testlocation3/*");
+ if (status) goto cleanup;
+
+ status = rtable->key_extract(sh, fcontext, &fcontextkey);
+ if (status) goto cleanup;
+
+ /* Add record. */
+ status = dconfig->dtable->add(
+ sh,
+ dconfig,
+ fcontextkey,
+ fcontext);
+ if (status) goto cleanup;
+
+ /* Cleanup. */
+ semanage_context_free(context);
+ rtable->free(fcontext);
+ rtable->key_free(fcontextkey);
+
+ /* Flush database.
+ * This sends a message to the server to replace its database
+ * with the one we are sending. Internally the flush serializes
+ * the database and sends it. The server then unserializes it,
+ * clears its old copy, and replaces it with the new one.
+ */
+ status = dconfig->dtable->flush(sh, dconfig);
+ CU_ASSERT( status == 0 );
+ }
+
+ /* Cleanup. */
+cleanup:
+ if (records != NULL) {
+ unsigned int i;
+ for (i = 0; i < records_size; i++) {
+ if (!records[i])
+ break;
+ rtable->free((record_t *)records[i]);
+ }
+ }
+
+ free(records);
+ free(data);
+
+ CU_ASSERT( status == 0 );
+ if (status != 0) {
+ printf("\n\nReceived error code in %s: %d | %s\n", (ps_pid == 0) ? "server" : "client", status, strerror(status));
+ }
+}
+
Index: selinux-pms-support/libsemanage/tests/test_fcontexts_file.h
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/tests/test_fcontexts_file.h
@@ -0,0 +1,32 @@
+/* Authors: Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __TEST_FCONTEXTS_FILE_H__
+#define __TEST_FCONTEXTS_FILE_H__
+
+#include <CUnit/Basic.h>
+
+int fcontexts_file_test_init(void);
+int fcontexts_file_test_cleanup(void);
+int fcontexts_file_add_tests(CU_pSuite suite);
+
+void test_semanage_fcontext_serialize_local(void);
+
+#endif
Index: selinux-pms-support/libsemanage/tests/test_fcontexts_policy.c
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/tests/test_fcontexts_policy.c
@@ -0,0 +1,394 @@
+/* Authors: Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* The purpose of this file is to provide unit tests of the functions in:
+ *
+ * libsemanage/src/fcontexts_policy.c
+ *
+ */
+
+#include "globals.h"
+#include "utilities.h"
+#include "test_fcontexts_policy.h"
+
+#include <libgen.h>
+#include <limits.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <CUnit/Basic.h>
+
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <selinux/selinux.h>
+
+#include "debug.h"
+#include "byteswap.h"
+#include "handle.h"
+#include "modules.h"
+#include "policy.h"
+#include "fcontexts_policy.h"
+#include "messages_internal.h"
+#include "semanage_store.h"
+#include "database_policydb.h"
+#include "user_internal.h"
+#include "seuser_internal.h"
+#include "port_internal.h"
+#include "iface_internal.h"
+#include "boolean_internal.h"
+#include "fcontext_internal.h"
+#include "node_internal.h"
+
+#include "database_llist.h"
+
+/* Server table setup. */
+
+/* Record functions. */
+
+static record_table_t test_fcontext_rtable = {
+ .create = (create_f)semanage_fcontext_create,
+ .key_extract = (key_extract_f)semanage_fcontext_key_extract,
+ .key_free = (key_free_f)semanage_fcontext_key_free,
+ .clone = (clone_f)semanage_fcontext_clone,
+ .compare = (compare_f)semanage_fcontext_compare,
+ .compare2 = (compare2_f)semanage_fcontext_compare2,
+ .compare2_qsort = NULL,
+ .free = (free_f)semanage_fcontext_free,
+ .serialize = (serialize_f)semanage_fcontext_serialize,
+ .unserialize = (unserialize_f)semanage_fcontext_unserialize,
+};
+
+/* Table functions. */
+
+/* Test cache function. */
+static int test_dbase_policydb_cache(
+ semanage_handle_t *handle,
+ dbase_config_t *dconfig)
+{
+ int status = 0;
+
+ /* Add some test entries to the list. */
+ record_t *fcontext = NULL;
+ record_key_t *fcontextkey = NULL;
+
+ record_table_t *rtable = dconfig->dtable->get_rtable(dconfig);
+
+ /* Create record. */
+ status = rtable->create(sh, &fcontext);
+ if (status) goto cleanup;
+
+ /* Populate record. */
+ semanage_context_t *context;
+ status = semanage_context_create(sh, &context);
+ if (status) goto cleanup;
+
+ status = semanage_context_set_user(sh, context, "testuser");
+ if (status) goto cleanup;
+ status = semanage_context_set_role(sh, context, "testrole");
+ if (status) goto cleanup;
+ status = semanage_context_set_type(sh, context, "testtype");
+ if (status) goto cleanup;
+ status = semanage_fcontext_set_con(sh, (semanage_fcontext_t *)fcontext, context);
+ if (status) goto cleanup;
+
+ semanage_fcontext_set_type((semanage_fcontext_t *)fcontext, 1);
+ status = semanage_fcontext_set_expr(sh, (semanage_fcontext_t *)fcontext, "/testlocation/*");
+ if (status) goto cleanup;
+
+ status = rtable->key_extract(sh, fcontext, &fcontextkey);
+ if (status) goto cleanup;
+
+ /* Add record. */
+ status = dconfig->dtable->add(
+ sh,
+ dconfig,
+ fcontextkey,
+ fcontext);
+ if (status) goto cleanup;
+
+ /* Cleanup. */
+ semanage_context_free(context);
+ context = NULL;
+ rtable->free(fcontext);
+ fcontext = NULL;
+ rtable->key_free(fcontextkey);
+ fcontextkey = NULL;
+
+ /* Create record. */
+ status = rtable->create(sh, &fcontext);
+ if (status) goto cleanup;
+
+ /* Populate record. */
+ status = semanage_context_create(sh, &context);
+ if (status) goto cleanup;
+
+ status = semanage_context_set_user(sh, context, "testuser2");
+ if (status) goto cleanup;
+ status = semanage_context_set_role(sh, context, "testrole2");
+ if (status) goto cleanup;
+ status = semanage_context_set_type(sh, context, "testtype2");
+ if (status) goto cleanup;
+ status = semanage_fcontext_set_con(sh, (semanage_fcontext_t *)fcontext, context);
+ if (status) goto cleanup;
+
+ semanage_fcontext_set_type((semanage_fcontext_t *)fcontext, 2);
+ status = semanage_fcontext_set_expr(sh, (semanage_fcontext_t *)fcontext, "/testlocation2/*");
+ if (status) goto cleanup;
+
+ status = rtable->key_extract(sh, fcontext, &fcontextkey);
+ if (status) goto cleanup;
+
+ /* Add record. */
+ status = dconfig->dtable->add(
+ sh,
+ dconfig,
+ fcontextkey,
+ fcontext);
+ if (status) goto cleanup;
+
+ /* Cleanup. */
+cleanup:
+ semanage_context_free(context);
+ rtable->free(fcontext);
+ rtable->key_free(fcontextkey);
+
+ CU_ASSERT( status == 0 );
+ return status;
+}
+
+/* Database callback table. */
+static dbase_table_t test_policydb_dtable = {
+
+ /* Cache/Transactions */
+ .cache = test_dbase_policydb_cache,
+ .drop_cache = (void *)dbase_llist_drop_cache,
+ .flush = NULL,
+ .is_modified = (void *)dbase_llist_is_modified,
+
+ /* Database API */
+ .iterate = (void *)dbase_llist_iterate,
+ .exists = (void *)dbase_llist_exists,
+ .list = (void *)dbase_llist_list,
+ .add = (void *)dbase_llist_add,
+ .set = (void *)dbase_llist_set,
+ .del = (void *)dbase_llist_del,
+ .clear = (void *)dbase_llist_clear,
+ .modify = (void *)dbase_llist_modify,
+ .query = (void *)dbase_llist_query,
+ .count = (void *)dbase_llist_count,
+
+ /* Polymorphism */
+ .get_rtable = (void *)dbase_llist_get_rtable
+};
+
+/* The suite initialization function.
+ * Returns zero on success, non-zero otherwise.
+ */
+int fcontexts_policy_test_init(void)
+{
+ int status = 0;
+
+ if (ps_pid == 0) {
+ /* Server code. */
+
+ /* Reset locks status. */
+ sh->u.ps_handle.socket_fd = 0;
+
+ /* Store setup. */
+ dbase_config_t *dconfig = semanage_fcontext_dbase_policy(sh);
+
+ if ((status =
+ dbase_policydb_init(
+ sh,
+ "fakesuffix",
+ &test_fcontext_rtable,
+ NULL,
+ (dbase_policydb_t **)&dconfig->dbase)))
+ goto cleanup;
+
+ dconfig->dtable = &test_policydb_dtable;
+
+ }
+
+ /* Cleanup. */
+cleanup:
+ return status;
+}
+
+/* The suite cleanup function.
+ * Returns zero on success, non-zero otherwise.
+ */
+int fcontexts_policy_test_cleanup(void)
+{
+ return 0;
+}
+
+/* Adds all the tests needed for this suite.
+*/
+int fcontexts_policy_add_tests(CU_pSuite suite)
+{
+ CU_ErrorCode status;
+
+ if (NULL == CU_add_test(suite, "semanage_fcontext_serialize_policy", test_semanage_fcontext_serialize_policy))
+ goto cleanup;
+
+cleanup:
+ if (CUE_SUCCESS != (status = CU_get_error()))
+ CU_cleanup_registry();
+ return status;
+}
+
+/* Tests the semanage_fcontext_serialize_policy function in fcontexts_policy.c
+ */
+void test_semanage_fcontext_serialize_policy(void) {
+ int status;
+
+ uint32_t message_type;
+ uint64_t data_length;
+ char *data = NULL;
+ int timeout = 0;
+
+ semanage_fcontext_t **records = NULL;
+ unsigned int records_size;
+
+ dbase_config_t *dconfig = semanage_fcontext_dbase_policy(sh);
+ record_table_t *rtable = dconfig->dtable->get_rtable(dconfig);
+
+ int commit_number = 7;
+
+ if (ps_pid == 0) {
+ /* Server code. */
+
+ /* On caching the client will ask for the commit number. */
+ status = test_semanage_ps_handle_get_commit_number(sh, commit_number);
+ CU_ASSERT( status == STATUS_SUCCESS );
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Wait for message. */
+ if ((status = read_msg(sh, client_socket_fd, timeout, &message_type, &data_length, &data)))
+ goto cleanup;
+
+ CU_ASSERT( message_type == PS_GET_DATABASE );
+ if (message_type != PS_GET_DATABASE) {
+ status = -1;
+ goto cleanup;
+ }
+
+ /* Get and serialize the database. */
+ free(data);
+ data = NULL;
+
+ if ((status = semanage_fcontext_serialize_policy(sh, &data, &data_length)))
+ goto cleanup;
+
+ /* Send back the database. */
+ if ((status = write_msg(sh, client_socket_fd, PS_OK, data_length, data)))
+ goto cleanup;
+
+ /* On caching the client will ask for the commit number. */
+ status = test_semanage_ps_handle_get_commit_number(sh, commit_number);
+ CU_ASSERT( status == STATUS_SUCCESS );
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ }
+
+ if (ps_pid > 0) {
+ /* Client code. */
+
+ /* Cache database.
+ * This sends a message to the server requesting the database.
+ * The server serializes the database and sends it to us (the client).
+ * Internally the database is unserialized and loaded.
+ */
+ status = dconfig->dtable->cache(sh, dconfig);
+ CU_ASSERT( status == 0 );
+
+ /* Gather the database records. */
+ status = dconfig->dtable->list(sh, dconfig, (record_t ***)&records, &records_size);
+ CU_ASSERT( status == 0 );
+ CU_ASSERT( records != NULL );
+ CU_ASSERT( records_size == 2 );
+
+ /* Verify data was sent correctly. */
+ semanage_context_t *context = semanage_fcontext_get_con(records[0]);
+ char *user = (char *)semanage_context_get_user(context);
+ char *role = (char *)semanage_context_get_role(context);
+ char *type = (char *)semanage_context_get_type(context);
+ int ftype = semanage_fcontext_get_type(records[0]);
+ char *expr = (char *)semanage_fcontext_get_expr(records[0]);
+
+ CU_ASSERT( strcmp(user, "testuser") == 0 );
+ CU_ASSERT( strcmp(role, "testrole") == 0 );
+ CU_ASSERT( strcmp(type, "testtype") == 0 );
+ CU_ASSERT( ftype == 1 );
+ CU_ASSERT( strcmp(expr, "/testlocation/*") == 0 );
+
+ context = semanage_fcontext_get_con(records[1]);
+ user = (char *)semanage_context_get_user(context);
+ role = (char *)semanage_context_get_role(context);
+ type = (char *)semanage_context_get_type(context);
+ ftype = semanage_fcontext_get_type(records[1]);
+ expr = (char *)semanage_fcontext_get_expr(records[1]);
+
+ CU_ASSERT( strcmp(user, "testuser2") == 0 );
+ CU_ASSERT( strcmp(role, "testrole2") == 0 );
+ CU_ASSERT( strcmp(type, "testtype2") == 0 );
+ CU_ASSERT( ftype == 2 );
+ CU_ASSERT( strcmp(expr, "/testlocation2/*") == 0 );
+ }
+
+ /* Cleanup. */
+cleanup:
+ if (records != NULL) {
+ unsigned int i;
+ for (i = 0; i < records_size; i++) {
+ if (!records[i])
+ break;
+ rtable->free((record_t *)records[i]);
+ }
+ }
+
+ free(records);
+ free(data);
+
+ CU_ASSERT( status == 0 );
+ if (status != 0) {
+ printf("\n\nReceived error code in %s: %d | %s\n", (ps_pid == 0) ? "server" : "client", status, strerror(status));
+ }
+}
+
Index: selinux-pms-support/libsemanage/tests/test_fcontexts_policy.h
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/tests/test_fcontexts_policy.h
@@ -0,0 +1,32 @@
+/* Authors: Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __TEST_FCONTEXTS_POLICY_H__
+#define __TEST_FCONTEXTS_POLICY_H__
+
+#include <CUnit/Basic.h>
+
+int fcontexts_policy_test_init(void);
+int fcontexts_policy_test_cleanup(void);
+int fcontexts_policy_add_tests(CU_pSuite suite);
+
+void test_semanage_fcontext_serialize_policy(void);
+
+#endif
--
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH 29/33] libsemanage: interface serialization tests
2007-04-23 21:34 [PATCH 00/33] libsemanage/libsepol object serialization and ps-api jbrindle
` (27 preceding siblings ...)
2007-04-23 21:35 ` [PATCH 28/33] libsemanage: fcontexts " jbrindle
@ 2007-04-23 21:35 ` jbrindle
2007-04-23 21:35 ` [PATCH 30/33] libsemanage: node " jbrindle
` (5 subsequent siblings)
34 siblings, 0 replies; 58+ messages in thread
From: jbrindle @ 2007-04-23 21:35 UTC (permalink / raw)
To: selinux
---
libsemanage/tests/libsemanage-tests.c | 6
libsemanage/tests/test_interfaces_file.c | 548 +++++++++++++++++++++++++++++
libsemanage/tests/test_interfaces_file.h | 32 +
libsemanage/tests/test_interfaces_policy.c | 403 +++++++++++++++++++++
libsemanage/tests/test_interfaces_policy.h | 32 +
5 files changed, 1021 insertions(+)
Index: selinux-pms-support/libsemanage/tests/libsemanage-tests.c
===================================================================
--- selinux-pms-support.orig/libsemanage/tests/libsemanage-tests.c
+++ selinux-pms-support/libsemanage/tests/libsemanage-tests.c
@@ -42,6 +42,9 @@
#include "test_fcontexts_file.h"
#include "test_fcontexts_policy.h"
+#include "test_interfaces_file.h"
+#include "test_interfaces_policy.h"
+
#include <CUnit/Basic.h>
#include <CUnit/Console.h>
#include <CUnit/TestDB.h>
@@ -104,6 +107,9 @@ static int do_tests(int interactive, int
DECLARE_SUITE(fcontexts_file);
DECLARE_SUITE(fcontexts_policy);
+ DECLARE_SUITE(interfaces_file);
+ DECLARE_SUITE(interfaces_policy);
+
/* The ps_api_disconnect test 'unforks'. */
DECLARE_SUITE(ps_api_disconnect);
Index: selinux-pms-support/libsemanage/tests/test_interfaces_file.c
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/tests/test_interfaces_file.c
@@ -0,0 +1,548 @@
+/* Authors: Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* The purpose of this file is to provide unit tests of the functions in:
+ *
+ * libsemanage/src/interfaces_file.c
+ *
+ */
+
+#include "globals.h"
+#include "utilities.h"
+#include "test_interfaces_file.h"
+
+#include <libgen.h>
+#include <limits.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <CUnit/Basic.h>
+
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <selinux/selinux.h>
+
+#include "debug.h"
+#include "byteswap.h"
+#include "handle.h"
+#include "modules.h"
+#include "policy.h"
+#include "interfaces_local.h"
+#include "messages_internal.h"
+#include "semanage_store.h"
+#include "database_file.h"
+#include "user_internal.h"
+#include "seuser_internal.h"
+#include "port_internal.h"
+#include "iface_internal.h"
+#include "boolean_internal.h"
+#include "fcontext_internal.h"
+#include "node_internal.h"
+
+#include "database_llist.h"
+
+/* Server table setup. */
+
+/* Record functions. */
+
+static record_table_t test_iface_rtable = {
+ .create = (create_f)semanage_iface_create,
+ .key_extract = (key_extract_f)semanage_iface_key_extract,
+ .key_free = (key_free_f)semanage_iface_key_free,
+ .clone = (clone_f)semanage_iface_clone,
+ .compare = (compare_f)semanage_iface_compare,
+ .compare2 = (compare2_f)semanage_iface_compare2,
+ .compare2_qsort = NULL,
+ .free = (free_f)semanage_iface_free,
+ .serialize = (serialize_f)semanage_iface_serialize,
+ .unserialize = (unserialize_f)semanage_iface_unserialize,
+};
+
+/* Table functions. */
+
+/* Test cache function. */
+static int test_dbase_local_cache(
+ semanage_handle_t *handle,
+ dbase_config_t *dconfig)
+{
+ int status = 0;
+
+ /* Add some test entries to the list. */
+ record_t *iface = NULL;
+ record_key_t *ifacekey = NULL;
+
+ record_table_t *rtable = dconfig->dtable->get_rtable(dconfig);
+
+ /* Create record. */
+ status = rtable->create(sh, &iface);
+ if (status) goto cleanup;
+
+ /* Populate record. */
+ semanage_context_t *ifcon;
+ semanage_context_t *msgcon;
+
+ status = semanage_iface_set_name(sh, (semanage_iface_t *)iface, "testname");
+ if (status) goto cleanup;
+
+ status = semanage_context_from_string(sh, "iftestuser:iftestrole:iftesttype", &ifcon);
+ if (status) goto cleanup;
+ status = semanage_iface_set_ifcon(sh, (semanage_iface_t *)iface, ifcon);
+ if (status) goto cleanup;
+
+ status = semanage_context_from_string(sh, "msgtestuser:msgtestrole:msgtesttype", &msgcon);
+ if (status) goto cleanup;
+ status = semanage_iface_set_msgcon(sh, (semanage_iface_t *)iface, msgcon);
+ if (status) goto cleanup;
+
+ status = rtable->key_extract(sh, iface, &ifacekey);
+ if (status) goto cleanup;
+
+ /* Add record. */
+ status = dconfig->dtable->add(
+ sh,
+ dconfig,
+ ifacekey,
+ iface);
+ if (status) goto cleanup;
+
+ /* Cleanup. */
+ semanage_context_free(ifcon);
+ ifcon = NULL;
+ semanage_context_free(msgcon);
+ msgcon = NULL;
+ rtable->free(iface);
+ iface = NULL;
+ rtable->key_free(ifacekey);
+ ifacekey = NULL;
+
+ /* Create record. */
+ status = rtable->create(sh, &iface);
+ if (status) goto cleanup;
+
+ /* Populate record. */
+ status = semanage_iface_set_name(sh, (semanage_iface_t *)iface, "testname2");
+ if (status) goto cleanup;
+
+ status = semanage_context_from_string(sh, "iftestuser2:iftestrole2:iftesttype2", &ifcon);
+ if (status) goto cleanup;
+ status = semanage_iface_set_ifcon(sh, (semanage_iface_t *)iface, ifcon);
+ if (status) goto cleanup;
+
+ status = semanage_context_from_string(sh, "msgtestuser2:msgtestrole2:msgtesttype2", &msgcon);
+ if (status) goto cleanup;
+ status = semanage_iface_set_msgcon(sh, (semanage_iface_t *)iface, msgcon);
+ if (status) goto cleanup;
+
+ status = rtable->key_extract(sh, iface, &ifacekey);
+ if (status) goto cleanup;
+
+ /* Add record. */
+ status = dconfig->dtable->add(
+ sh,
+ dconfig,
+ ifacekey,
+ iface);
+ if (status) goto cleanup;
+
+ /* Cleanup. */
+cleanup:
+ semanage_context_free(ifcon);
+ semanage_context_free(msgcon);
+ rtable->free(iface);
+ rtable->key_free(ifacekey);
+
+ CU_ASSERT( status == 0 );
+ return status;
+}
+
+/* Database callback table. */
+static dbase_table_t test_file_dtable = {
+
+ /* Cache/Transactions */
+ .cache = test_dbase_local_cache,
+ .drop_cache = (void *)dbase_llist_drop_cache,
+ .flush = NULL,
+ .is_modified = (void *)dbase_llist_is_modified,
+
+ /* Database API */
+ .iterate = (void *)dbase_llist_iterate,
+ .exists = (void *)dbase_llist_exists,
+ .list = (void *)dbase_llist_list,
+ .add = (void *)dbase_llist_add,
+ .set = (void *)dbase_llist_set,
+ .del = (void *)dbase_llist_del,
+ .clear = (void *)dbase_llist_clear,
+ .modify = (void *)dbase_llist_modify,
+ .query = (void *)dbase_llist_query,
+ .count = (void *)dbase_llist_count,
+
+ /* Polymorphism */
+ .get_rtable = (void *)dbase_llist_get_rtable
+};
+
+/* The suite initialization function.
+ * Returns zero on success, non-zero otherwise.
+ */
+int interfaces_file_test_init(void)
+{
+ int status = 0;
+
+ if (ps_pid == 0) {
+ /* Server code. */
+
+ /* Reset locks status. */
+ sh->u.ps_handle.socket_fd = 0;
+
+ /* Store setup. */
+ dbase_config_t *dconfig = semanage_iface_dbase_local(sh);
+
+ if ((status =
+ dbase_file_init(
+ sh,
+ "fakesuffix",
+ &test_iface_rtable,
+ NULL,
+ (dbase_file_t **)&dconfig->dbase)))
+ goto cleanup;
+
+ dconfig->dtable = &test_file_dtable;
+
+ }
+
+ /* Cleanup. */
+cleanup:
+ return status;
+}
+
+/* The suite cleanup function.
+ * Returns zero on success, non-zero otherwise.
+ */
+int interfaces_file_test_cleanup(void)
+{
+ return 0;
+}
+
+/* Adds all the tests needed for this suite.
+*/
+int interfaces_file_add_tests(CU_pSuite suite)
+{
+ CU_ErrorCode status;
+
+ if (NULL == CU_add_test(suite, "semanage_iface_serialize_local", test_semanage_iface_serialize_local))
+ goto cleanup;
+
+cleanup:
+ if (CUE_SUCCESS != (status = CU_get_error()))
+ CU_cleanup_registry();
+ return status;
+}
+
+/* Tests the semanage_iface_serialize_local function in interfaces_file.c
+ */
+void test_semanage_iface_serialize_local(void) {
+ int status;
+
+ uint32_t message_type;
+ uint64_t data_length;
+ char *data = NULL;
+ char *ptr = NULL;
+ int timeout = 0;
+ uint32_t database_type = 0;
+
+ semanage_iface_t **records = NULL;
+ unsigned int records_size;
+
+ dbase_config_t *dconfig = semanage_iface_dbase_local(sh);
+ record_table_t *rtable = dconfig->dtable->get_rtable(dconfig);
+
+ char *ifcon_str = NULL;
+ char *msgcon_str = NULL;
+
+ int commit_number = 7;
+
+ if (ps_pid == 0) {
+ /* Server code. */
+
+ /* On caching the client will ask for the commit number. */
+ status = test_semanage_ps_handle_get_commit_number(sh, commit_number);
+ CU_ASSERT( status == STATUS_SUCCESS );
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Wait for message. */
+ if ((status = read_msg(sh, client_socket_fd, timeout, &message_type, &data_length, &data)))
+ goto cleanup;
+
+ CU_ASSERT( message_type == PS_GET_DATABASE );
+ if (message_type != PS_GET_DATABASE) {
+ status = -1;
+ goto cleanup;
+ }
+
+ /* Get and serialize the database. */
+ free(data);
+ data = NULL;
+
+ if ((status = semanage_iface_serialize_local(sh, &data, &data_length)))
+ goto cleanup;
+
+ /* Send back the database. */
+ if ((status = write_msg(sh, client_socket_fd, PS_OK, data_length, data)))
+ goto cleanup;
+
+ /* On caching the client will ask for the commit number. */
+ status = test_semanage_ps_handle_get_commit_number(sh, commit_number);
+ CU_ASSERT( status == STATUS_SUCCESS );
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* On flushing the client will ask for the commit number. */
+ //FIXME: Why does the client ask for the commit number so many times here?
+ status = test_semanage_ps_handle_get_commit_number(sh, commit_number);
+ CU_ASSERT( status == STATUS_SUCCESS );
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ status = test_semanage_ps_handle_get_commit_number(sh, commit_number);
+ CU_ASSERT( status == STATUS_SUCCESS );
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Receive changed database. */
+ free(data);
+ data = NULL;
+
+ if ((status = read_msg(sh, client_socket_fd, timeout, &message_type, &data_length, &data)))
+ goto cleanup;
+
+ CU_ASSERT( message_type == PS_PUT_DATABASE );
+ if (message_type != PS_PUT_DATABASE) {
+ status = -1;
+ goto cleanup;
+ }
+
+ /* Say we got it ok. */
+ if ((status = write_msg(sh, client_socket_fd, PS_OK, 0, NULL)))
+ goto cleanup;
+
+ /* Unserialize the database type */
+ ptr = data;
+ if(semanage_dbase_ps_database_type_unserialize(sh, &ptr, &data_length, &database_type));
+ goto cleanup;
+
+ /* Unserialize the database. and don't move the data pointer.*/
+ if ((status = semanage_iface_unserialize_local(sh, ptr, data_length)))
+ goto cleanup;
+
+ /* Gather the database records. */
+ status = dconfig->dtable->list(sh, dconfig, (record_t ***)&records, &records_size);
+ CU_ASSERT( status == 0 );
+ CU_ASSERT( records != NULL );
+ CU_ASSERT( records_size == 3 );
+
+ /* Verify data. */
+ char *name = (char *)semanage_iface_get_name(records[0]);
+
+ semanage_context_t *ifcon = semanage_iface_get_ifcon(records[0]);
+ status = semanage_context_to_string(sh, ifcon, &ifcon_str);
+
+ semanage_context_t *msgcon = semanage_iface_get_msgcon(records[0]);
+ status = semanage_context_to_string(sh, msgcon, &msgcon_str);
+
+ CU_ASSERT( strcmp(name, "testname") == 0 );
+ CU_ASSERT( strcmp(ifcon_str, "iftestuser:iftestrole:iftesttype") == 0 );
+ CU_ASSERT( strcmp(msgcon_str, "msgtestuser:msgtestrole:msgtesttype") == 0 );
+
+ /* Cleanup. */
+ free(ifcon_str);
+ free(msgcon_str);
+
+ name = (char *)semanage_iface_get_name(records[1]);
+
+ ifcon = semanage_iface_get_ifcon(records[1]);
+ ifcon_str = NULL;
+ status = semanage_context_to_string(sh, ifcon, &ifcon_str);
+
+ msgcon = semanage_iface_get_msgcon(records[1]);
+ msgcon_str = NULL;
+ status = semanage_context_to_string(sh, msgcon, &msgcon_str);
+
+ CU_ASSERT( strcmp(name, "testname2") == 0 );
+ CU_ASSERT( strcmp(ifcon_str, "iftestuser2:iftestrole2:iftesttype2") == 0 );
+ CU_ASSERT( strcmp(msgcon_str, "msgtestuser2:msgtestrole2:msgtesttype2") == 0 );
+
+ /* Cleanup. */
+ free(ifcon_str);
+ free(msgcon_str);
+
+ name = (char *)semanage_iface_get_name(records[2]);
+
+ ifcon = semanage_iface_get_ifcon(records[2]);
+ ifcon_str = NULL;
+ status = semanage_context_to_string(sh, ifcon, &ifcon_str);
+
+ msgcon = semanage_iface_get_msgcon(records[2]);
+ msgcon_str = NULL;
+ status = semanage_context_to_string(sh, msgcon, &msgcon_str);
+
+ CU_ASSERT( strcmp(name, "testname3") == 0 );
+ CU_ASSERT( strcmp(ifcon_str, "iftestuser3:iftestrole3:iftesttype3") == 0 );
+ CU_ASSERT( strcmp(msgcon_str, "msgtestuser3:msgtestrole3:msgtesttype3") == 0 );
+
+ }
+
+ if (ps_pid > 0) {
+ /* Client code. */
+
+ /* Cache database.
+ * This sends a message to the server requesting the database.
+ * The server serializes the database and sends it to us (the client).
+ * Internally the database is unserialized and loaded.
+ */
+ status = dconfig->dtable->cache(sh, dconfig);
+ CU_ASSERT( status == 0 );
+
+ /* Gather the database records. */
+ status = dconfig->dtable->list(sh, dconfig, (record_t ***)&records, &records_size);
+ CU_ASSERT( status == 0 );
+ CU_ASSERT( records != NULL );
+ CU_ASSERT( records_size == 2 );
+
+ /* Verify data was sent correctly. */
+ char *name = (char *)semanage_iface_get_name(records[0]);
+
+ semanage_context_t *ifcon = semanage_iface_get_ifcon(records[0]);
+ status = semanage_context_to_string(sh, ifcon, &ifcon_str);
+
+ semanage_context_t *msgcon = semanage_iface_get_msgcon(records[0]);
+ status = semanage_context_to_string(sh, msgcon, &msgcon_str);
+
+ CU_ASSERT( strcmp(name, "testname") == 0 );
+ CU_ASSERT( strcmp(ifcon_str, "iftestuser:iftestrole:iftesttype") == 0 );
+ CU_ASSERT( strcmp(msgcon_str, "msgtestuser:msgtestrole:msgtesttype") == 0 );
+
+ /* Cleanup. */
+ free(ifcon_str);
+ free(msgcon_str);
+
+ name = (char *)semanage_iface_get_name(records[1]);
+
+ ifcon = semanage_iface_get_ifcon(records[1]);
+ ifcon_str = NULL;
+ status = semanage_context_to_string(sh, ifcon, &ifcon_str);
+
+ msgcon = semanage_iface_get_msgcon(records[1]);
+ msgcon_str = NULL;
+ status = semanage_context_to_string(sh, msgcon, &msgcon_str);
+
+ CU_ASSERT( strcmp(name, "testname2") == 0 );
+ CU_ASSERT( strcmp(ifcon_str, "iftestuser2:iftestrole2:iftesttype2") == 0 );
+ CU_ASSERT( strcmp(msgcon_str, "msgtestuser2:msgtestrole2:msgtesttype2") == 0 );
+
+ /* Change something. */
+
+ /* Add some test entries to the list. */
+ record_t *iface = NULL;
+ record_key_t *ifacekey = NULL;
+
+ /* Create record. */
+ status = rtable->create(sh, &iface);
+ if (status) goto cleanup;
+
+ /* Populate record. */
+ status = semanage_iface_set_name(sh, (semanage_iface_t *)iface, "testname3");
+ if (status) goto cleanup;
+
+ status = semanage_context_from_string(sh, "iftestuser3:iftestrole3:iftesttype3", &ifcon);
+ if (status) goto cleanup;
+ status = semanage_iface_set_ifcon(sh, (semanage_iface_t *)iface, ifcon);
+ if (status) goto cleanup;
+
+ status = semanage_context_from_string(sh, "msgtestuser3:msgtestrole3:msgtesttype3", &msgcon);
+ if (status) goto cleanup;
+ status = semanage_iface_set_msgcon(sh, (semanage_iface_t *)iface, msgcon);
+ if (status) goto cleanup;
+
+ status = rtable->key_extract(sh, iface, &ifacekey);
+ if (status) goto cleanup;
+
+ /* Add record. */
+ status = dconfig->dtable->add(
+ sh,
+ dconfig,
+ ifacekey,
+ iface);
+ if (status) goto cleanup;
+
+ /* Cleanup. */
+ semanage_context_free(ifcon);
+ semanage_context_free(msgcon);
+ rtable->free(iface);
+ rtable->key_free(ifacekey);
+
+ /* Flush database.
+ * This sends a message to the server to replace its database
+ * with the one we are sending. Internally the flush serializes
+ * the database and sends it. The server then unserializes it,
+ * clears its old copy, and replaces it with the new one.
+ */
+ status = dconfig->dtable->flush(sh, dconfig);
+ CU_ASSERT( status == 0 );
+
+ }
+
+ /* Cleanup. */
+cleanup:
+ if (records != NULL) {
+ unsigned int i;
+ for (i = 0; i < records_size; i++) {
+ if (!records[i])
+ break;
+ rtable->free((record_t *)records[i]);
+ }
+ }
+
+ free(records);
+ free(data);
+ free(ifcon_str);
+ free(msgcon_str);
+
+ CU_ASSERT( status == 0 );
+ if (status != 0) {
+ printf("\n\nReceived error code in %s: %d | %s\n", (ps_pid == 0) ? "server" : "client", status, strerror(status));
+ }
+}
+
Index: selinux-pms-support/libsemanage/tests/test_interfaces_file.h
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/tests/test_interfaces_file.h
@@ -0,0 +1,32 @@
+/* Authors: Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __TEST_INTERFACES_FILE_H__
+#define __TEST_INTERFACES_FILE_H__
+
+#include <CUnit/Basic.h>
+
+int interfaces_file_test_init(void);
+int interfaces_file_test_cleanup(void);
+int interfaces_file_add_tests(CU_pSuite suite);
+
+void test_semanage_iface_serialize_local(void);
+
+#endif
Index: selinux-pms-support/libsemanage/tests/test_interfaces_policy.c
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/tests/test_interfaces_policy.c
@@ -0,0 +1,403 @@
+/* Authors: Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* The purpose of this file is to provide unit tests of the functions in:
+ *
+ * libsemanage/src/interfaces_policy.c
+ *
+ */
+
+#include "globals.h"
+#include "utilities.h"
+#include "test_interfaces_policy.h"
+
+#include <libgen.h>
+#include <limits.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <CUnit/Basic.h>
+
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <selinux/selinux.h>
+
+#include "debug.h"
+#include "byteswap.h"
+#include "handle.h"
+#include "modules.h"
+#include "policy.h"
+#include "interfaces_policy.h"
+#include "messages_internal.h"
+#include "semanage_store.h"
+#include "database_policydb.h"
+#include "user_internal.h"
+#include "seuser_internal.h"
+#include "port_internal.h"
+#include "iface_internal.h"
+#include "boolean_internal.h"
+#include "fcontext_internal.h"
+#include "node_internal.h"
+
+#include "database_llist.h"
+
+/* Server table setup. */
+
+/* Record functions. */
+
+static record_table_t test_iface_rtable = {
+ .create = (create_f)semanage_iface_create,
+ .key_extract = (key_extract_f)semanage_iface_key_extract,
+ .key_free = (key_free_f)semanage_iface_key_free,
+ .clone = (clone_f)semanage_iface_clone,
+ .compare = (compare_f)semanage_iface_compare,
+ .compare2 = (compare2_f)semanage_iface_compare2,
+ .compare2_qsort = NULL,
+ .free = (free_f)semanage_iface_free,
+ .serialize = (serialize_f)semanage_iface_serialize,
+ .unserialize = (unserialize_f)semanage_iface_unserialize,
+};
+
+/* Table functions. */
+
+/* Test cache function. */
+static int test_dbase_policydb_cache(
+ semanage_handle_t *handle,
+ dbase_config_t *dconfig)
+{
+ int status = 0;
+
+ /* Add some test entries to the list. */
+ record_t *iface = NULL;
+ record_key_t *ifacekey = NULL;
+
+ record_table_t *rtable = dconfig->dtable->get_rtable(dconfig);
+
+ /* Create record. */
+ status = rtable->create(sh, &iface);
+ if (status) goto cleanup;
+
+ /* Populate record. */
+ semanage_context_t *ifcon;
+ semanage_context_t *msgcon;
+
+ status = semanage_iface_set_name(sh, (semanage_iface_t *)iface, "testname");
+ if (status) goto cleanup;
+
+ status = semanage_context_from_string(sh, "iftestuser:iftestrole:iftesttype", &ifcon);
+ if (status) goto cleanup;
+ status = semanage_iface_set_ifcon(sh, (semanage_iface_t *)iface, ifcon);
+ if (status) goto cleanup;
+
+ status = semanage_context_from_string(sh, "msgtestuser:msgtestrole:msgtesttype", &msgcon);
+ if (status) goto cleanup;
+ status = semanage_iface_set_msgcon(sh, (semanage_iface_t *)iface, msgcon);
+ if (status) goto cleanup;
+
+ status = rtable->key_extract(sh, iface, &ifacekey);
+ if (status) goto cleanup;
+
+ /* Add record. */
+ status = dconfig->dtable->add(
+ sh,
+ dconfig,
+ ifacekey,
+ iface);
+ if (status) goto cleanup;
+
+ /* Cleanup. */
+ semanage_context_free(ifcon);
+ ifcon = NULL;
+ semanage_context_free(msgcon);
+ msgcon = NULL;
+ rtable->free(iface);
+ iface = NULL;
+ rtable->key_free(ifacekey);
+ ifacekey = NULL;
+
+ /* Create record. */
+ status = rtable->create(sh, &iface);
+ if (status) goto cleanup;
+
+ /* Populate record. */
+ status = semanage_iface_set_name(sh, (semanage_iface_t *)iface, "testname2");
+ if (status) goto cleanup;
+
+ status = semanage_context_from_string(sh, "iftestuser2:iftestrole2:iftesttype2", &ifcon);
+ if (status) goto cleanup;
+ status = semanage_iface_set_ifcon(sh, (semanage_iface_t *)iface, ifcon);
+ if (status) goto cleanup;
+
+ status = semanage_context_from_string(sh, "msgtestuser2:msgtestrole2:msgtesttype2", &msgcon);
+ if (status) goto cleanup;
+ status = semanage_iface_set_msgcon(sh, (semanage_iface_t *)iface, msgcon);
+ if (status) goto cleanup;
+
+ status = rtable->key_extract(sh, iface, &ifacekey);
+ if (status) goto cleanup;
+
+ /* Add record. */
+ status = dconfig->dtable->add(
+ sh,
+ dconfig,
+ ifacekey,
+ iface);
+ if (status) goto cleanup;
+
+ /* Cleanup. */
+cleanup:
+ semanage_context_free(ifcon);
+ semanage_context_free(msgcon);
+ rtable->free(iface);
+ rtable->key_free(ifacekey);
+
+ CU_ASSERT( status == 0 );
+ return status;
+}
+
+/* Database callback table. */
+static dbase_table_t test_policydb_dtable = {
+
+ /* Cache/Transactions */
+ .cache = test_dbase_policydb_cache,
+ .drop_cache = (void *)dbase_llist_drop_cache,
+ .flush = NULL,
+ .is_modified = (void *)dbase_llist_is_modified,
+
+ /* Database API */
+ .iterate = (void *)dbase_llist_iterate,
+ .exists = (void *)dbase_llist_exists,
+ .list = (void *)dbase_llist_list,
+ .add = (void *)dbase_llist_add,
+ .set = (void *)dbase_llist_set,
+ .del = (void *)dbase_llist_del,
+ .clear = (void *)dbase_llist_clear,
+ .modify = (void *)dbase_llist_modify,
+ .query = (void *)dbase_llist_query,
+ .count = (void *)dbase_llist_count,
+
+ /* Polymorphism */
+ .get_rtable = (void *)dbase_llist_get_rtable
+};
+
+/* The suite initialization function.
+ * Returns zero on success, non-zero otherwise.
+ */
+int interfaces_policy_test_init(void)
+{
+ int status = 0;
+
+ if (ps_pid == 0) {
+ /* Server code. */
+
+ /* Reset locks status. */
+ sh->u.ps_handle.socket_fd = 0;
+
+ /* Store setup. */
+ dbase_config_t *dconfig = semanage_iface_dbase_policy(sh);
+
+ if ((status =
+ dbase_policydb_init(
+ sh,
+ "fakesuffix",
+ &test_iface_rtable,
+ NULL,
+ (dbase_policydb_t **)&dconfig->dbase)))
+ goto cleanup;
+
+ dconfig->dtable = &test_policydb_dtable;
+
+ }
+
+ /* Cleanup. */
+cleanup:
+ return status;
+}
+
+/* The suite cleanup function.
+ * Returns zero on success, non-zero otherwise.
+ */
+int interfaces_policy_test_cleanup(void)
+{
+ return 0;
+}
+
+/* Adds all the tests needed for this suite.
+*/
+int interfaces_policy_add_tests(CU_pSuite suite)
+{
+ CU_ErrorCode status;
+
+ if (NULL == CU_add_test(suite, "semanage_iface_serialize_policy", test_semanage_iface_serialize_policy))
+ goto cleanup;
+
+cleanup:
+ if (CUE_SUCCESS != (status = CU_get_error()))
+ CU_cleanup_registry();
+ return status;
+}
+
+/* Tests the semanage_iface_serialize_policy function in interfaces_policy.c
+ */
+void test_semanage_iface_serialize_policy(void) {
+ int status;
+
+ uint32_t message_type;
+ uint64_t data_length;
+ char *data = NULL;
+ int timeout = 0;
+
+ semanage_iface_t **records = NULL;
+ unsigned int records_size;
+
+ dbase_config_t *dconfig = semanage_iface_dbase_policy(sh);
+ record_table_t *rtable = dconfig->dtable->get_rtable(dconfig);
+
+ char *ifcon_str = NULL;
+ char *msgcon_str = NULL;
+
+ int commit_number = 7;
+
+ if (ps_pid == 0) {
+ /* Server code. */
+
+ /* On caching the client will ask for the commit number. */
+ status = test_semanage_ps_handle_get_commit_number(sh, commit_number);
+ CU_ASSERT( status == STATUS_SUCCESS );
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Wait for message. */
+ if ((status = read_msg(sh, client_socket_fd, timeout, &message_type, &data_length, &data)))
+ goto cleanup;
+
+ CU_ASSERT( message_type == PS_GET_DATABASE );
+ if (message_type != PS_GET_DATABASE) {
+ status = -1;
+ goto cleanup;
+ }
+
+ /* Get and serialize the database. */
+ free(data);
+ data = NULL;
+
+ if ((status = semanage_iface_serialize_policy(sh, &data, &data_length)))
+ goto cleanup;
+
+ /* Send back the database. */
+ if ((status = write_msg(sh, client_socket_fd, PS_OK, data_length, data)))
+ goto cleanup;
+
+ /* On caching the client will ask for the commit number. */
+ status = test_semanage_ps_handle_get_commit_number(sh, commit_number);
+ CU_ASSERT( status == STATUS_SUCCESS );
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ }
+
+ if (ps_pid > 0) {
+ /* Client code. */
+
+ /* Cache database.
+ * This sends a message to the server requesting the database.
+ * The server serializes the database and sends it to us (the client).
+ * Internally the database is unserialized and loaded.
+ */
+ status = dconfig->dtable->cache(sh, dconfig);
+ CU_ASSERT( status == 0 );
+
+ /* Gather the database records. */
+ status = dconfig->dtable->list(sh, dconfig, (record_t ***)&records, &records_size);
+ CU_ASSERT( status == 0 );
+ CU_ASSERT( records != NULL );
+ CU_ASSERT( records_size == 2 );
+
+ /* Verify data was sent correctly. */
+ char *name = (char *)semanage_iface_get_name(records[0]);
+
+ semanage_context_t *ifcon = semanage_iface_get_ifcon(records[0]);
+ status = semanage_context_to_string(sh, ifcon, &ifcon_str);
+
+ semanage_context_t *msgcon = semanage_iface_get_msgcon(records[0]);
+ status = semanage_context_to_string(sh, msgcon, &msgcon_str);
+
+ CU_ASSERT( strcmp(name, "testname") == 0 );
+ CU_ASSERT( strcmp(ifcon_str, "iftestuser:iftestrole:iftesttype") == 0 );
+ CU_ASSERT( strcmp(msgcon_str, "msgtestuser:msgtestrole:msgtesttype") == 0 );
+
+ /* Cleanup. */
+ free(ifcon_str);
+ free(msgcon_str);
+
+ name = (char *)semanage_iface_get_name(records[1]);
+
+ ifcon = semanage_iface_get_ifcon(records[1]);
+ ifcon_str = NULL;
+ status = semanage_context_to_string(sh, ifcon, &ifcon_str);
+
+ msgcon = semanage_iface_get_msgcon(records[1]);
+ msgcon_str = NULL;
+ status = semanage_context_to_string(sh, msgcon, &msgcon_str);
+
+ CU_ASSERT( strcmp(name, "testname2") == 0 );
+ CU_ASSERT( strcmp(ifcon_str, "iftestuser2:iftestrole2:iftesttype2") == 0 );
+ CU_ASSERT( strcmp(msgcon_str, "msgtestuser2:msgtestrole2:msgtesttype2") == 0 );
+
+ }
+
+ /* Cleanup. */
+cleanup:
+ if (records != NULL) {
+ unsigned int i;
+ for (i = 0; i < records_size; i++) {
+ if (!records[i])
+ break;
+ rtable->free((record_t *)records[i]);
+ }
+ }
+
+ free(records);
+ free(data);
+ free(ifcon_str);
+ free(msgcon_str);
+
+ CU_ASSERT( status == 0 );
+ if (status != 0) {
+ printf("\n\nReceived error code in %s: %d | %s\n", (ps_pid == 0) ? "server" : "client", status, strerror(status));
+ }
+}
+
Index: selinux-pms-support/libsemanage/tests/test_interfaces_policy.h
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/tests/test_interfaces_policy.h
@@ -0,0 +1,32 @@
+/* Authors: Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __TEST_INTERFACES_POLICY_H__
+#define __TEST_INTERFACES_POLICY_H__
+
+#include <CUnit/Basic.h>
+
+int interfaces_policy_test_init(void);
+int interfaces_policy_test_cleanup(void);
+int interfaces_policy_add_tests(CU_pSuite suite);
+
+void test_semanage_iface_serialize_policy(void);
+
+#endif
--
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH 30/33] libsemanage: node serialization tests
2007-04-23 21:34 [PATCH 00/33] libsemanage/libsepol object serialization and ps-api jbrindle
` (28 preceding siblings ...)
2007-04-23 21:35 ` [PATCH 29/33] libsemanage: interface " jbrindle
@ 2007-04-23 21:35 ` jbrindle
2007-04-23 21:35 ` [PATCH 31/33] libsemanage: port " jbrindle
` (4 subsequent siblings)
34 siblings, 0 replies; 58+ messages in thread
From: jbrindle @ 2007-04-23 21:35 UTC (permalink / raw)
To: selinux
---
libsemanage/tests/libsemanage-tests.c | 6
libsemanage/tests/test_nodes_file.c | 529 ++++++++++++++++++++++++++++++++++
libsemanage/tests/test_nodes_file.h | 32 ++
libsemanage/tests/test_nodes_policy.c | 392 +++++++++++++++++++++++++
libsemanage/tests/test_nodes_policy.h | 32 ++
5 files changed, 991 insertions(+)
Index: selinux-pms-support/libsemanage/tests/libsemanage-tests.c
===================================================================
--- selinux-pms-support.orig/libsemanage/tests/libsemanage-tests.c
+++ selinux-pms-support/libsemanage/tests/libsemanage-tests.c
@@ -45,6 +45,9 @@
#include "test_interfaces_file.h"
#include "test_interfaces_policy.h"
+#include "test_nodes_file.h"
+#include "test_nodes_policy.h"
+
#include <CUnit/Basic.h>
#include <CUnit/Console.h>
#include <CUnit/TestDB.h>
@@ -110,6 +113,9 @@ static int do_tests(int interactive, int
DECLARE_SUITE(interfaces_file);
DECLARE_SUITE(interfaces_policy);
+ DECLARE_SUITE(nodes_file);
+ DECLARE_SUITE(nodes_policy);
+
/* The ps_api_disconnect test 'unforks'. */
DECLARE_SUITE(ps_api_disconnect);
Index: selinux-pms-support/libsemanage/tests/test_nodes_file.c
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/tests/test_nodes_file.c
@@ -0,0 +1,529 @@
+/* Authors: Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* The purpose of this file is to provide unit tests of the functions in:
+ *
+ * libsemanage/src/nodes_file.c
+ *
+ */
+
+#include "globals.h"
+#include "utilities.h"
+#include "test_nodes_file.h"
+
+#include <libgen.h>
+#include <limits.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <CUnit/Basic.h>
+
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <selinux/selinux.h>
+
+#include "debug.h"
+#include "byteswap.h"
+#include "handle.h"
+#include "modules.h"
+#include "policy.h"
+#include "nodes_local.h"
+#include "messages_internal.h"
+#include "semanage_store.h"
+#include "database_file.h"
+#include "user_internal.h"
+#include "seuser_internal.h"
+#include "port_internal.h"
+#include "iface_internal.h"
+#include "boolean_internal.h"
+#include "fcontext_internal.h"
+#include "node_internal.h"
+
+#include "database_llist.h"
+
+/* Server table setup. */
+
+/* Record functions. */
+
+static record_table_t test_node_rtable = {
+ .create = (create_f)semanage_node_create,
+ .key_extract = (key_extract_f)semanage_node_key_extract,
+ .key_free = (key_free_f)semanage_node_key_free,
+ .clone = (clone_f)semanage_node_clone,
+ .compare = (compare_f)semanage_node_compare,
+ .compare2 = (compare2_f)semanage_node_compare2,
+ .compare2_qsort = NULL,
+ .free = (free_f)semanage_node_free,
+ .serialize = (serialize_f)semanage_node_serialize,
+ .unserialize = (unserialize_f)semanage_node_unserialize,
+};
+
+/* Table functions. */
+
+/* Test cache function. */
+static int test_dbase_file_cache(
+ semanage_handle_t *handle,
+ dbase_config_t *dconfig)
+{
+ int status = 0;
+
+ /* Add some test entries to the list. */
+ record_t *node = NULL;
+ record_key_t *nodekey = NULL;
+
+ record_table_t *rtable = dconfig->dtable->get_rtable(dconfig);
+
+ /* Create record. */
+ status = rtable->create(sh, &node);
+ if (status) goto cleanup;
+
+ /* Populate record. */
+ semanage_context_t *context;
+ int proto = SEMANAGE_PROTO_IP4;
+
+ status = semanage_node_set_addr(sh, (semanage_node_t *)node, proto, "10.10.10.10");
+ if (status) goto cleanup;
+ status = semanage_node_set_mask(sh, (semanage_node_t *)node, proto, "255.255.255.255");
+
+ status = semanage_context_from_string(sh, "testuser:testrole:testtype", &context);
+ if (status) goto cleanup;
+ status = semanage_node_set_con(sh, (semanage_node_t *)node, context);
+ if (status) goto cleanup;
+
+ status = rtable->key_extract(sh, node, &nodekey);
+ if (status) goto cleanup;
+
+ /* Add record. */
+ status = dconfig->dtable->add(
+ sh,
+ dconfig,
+ nodekey,
+ node);
+ if (status) goto cleanup;
+
+ /* Cleanup. */
+ semanage_context_free(context);
+ context = NULL;
+ rtable->free(node);
+ node = NULL;
+ rtable->key_free(nodekey);
+ nodekey = NULL;
+
+ /* Create record. */
+ status = rtable->create(sh, &node);
+ if (status) goto cleanup;
+
+ /* Populate record. */
+ status = semanage_node_set_addr(sh, (semanage_node_t *)node, proto, "10.10.10.1");
+ if (status) goto cleanup;
+ status = semanage_node_set_mask(sh, (semanage_node_t *)node, proto, "255.255.255.1");
+
+ status = semanage_context_from_string(sh, "testuser2:testrole2:testtype2", &context);
+ if (status) goto cleanup;
+ status = semanage_node_set_con(sh, (semanage_node_t *)node, context);
+ if (status) goto cleanup;
+
+ status = rtable->key_extract(sh, node, &nodekey);
+ if (status) goto cleanup;
+
+ /* Add record. */
+ status = dconfig->dtable->add(
+ sh,
+ dconfig,
+ nodekey,
+ node);
+ if (status) goto cleanup;
+
+ /* Cleanup. */
+cleanup:
+ semanage_context_free(context);
+ rtable->free(node);
+ rtable->key_free(nodekey);
+
+ CU_ASSERT( status == 0 );
+ return status;
+}
+
+/* Database callback table. */
+static dbase_table_t test_file_dtable = {
+
+ /* Cache/Transactions */
+ .cache = test_dbase_file_cache,
+ .drop_cache = (void *)dbase_llist_drop_cache,
+ .flush = NULL,
+ .is_modified = (void *)dbase_llist_is_modified,
+
+ /* Database API */
+ .iterate = (void *)dbase_llist_iterate,
+ .exists = (void *)dbase_llist_exists,
+ .list = (void *)dbase_llist_list,
+ .add = (void *)dbase_llist_add,
+ .set = (void *)dbase_llist_set,
+ .del = (void *)dbase_llist_del,
+ .clear = (void *)dbase_llist_clear,
+ .modify = (void *)dbase_llist_modify,
+ .query = (void *)dbase_llist_query,
+ .count = (void *)dbase_llist_count,
+
+ /* Polymorphism */
+ .get_rtable = (void *)dbase_llist_get_rtable
+};
+
+/* The suite initialization function.
+ * Returns zero on success, non-zero otherwise.
+ */
+int nodes_file_test_init(void)
+{
+ int status = 0;
+
+ if (ps_pid == 0) {
+ /* Server code. */
+
+ /* Reset locks status. */
+ sh->u.ps_handle.socket_fd = 0;
+
+ /* Store setup. */
+ dbase_config_t *dconfig = semanage_node_dbase_local(sh);
+
+ if ((status =
+ dbase_file_init(
+ sh,
+ "fakesuffix",
+ &test_node_rtable,
+ NULL,
+ (dbase_file_t **)&dconfig->dbase)))
+ goto cleanup;
+
+ dconfig->dtable = &test_file_dtable;
+
+ }
+
+ /* Cleanup. */
+cleanup:
+ return status;
+}
+
+/* The suite cleanup function.
+ * Returns zero on success, non-zero otherwise.
+ */
+int nodes_file_test_cleanup(void)
+{
+ return 0;
+}
+
+/* Adds all the tests needed for this suite.
+*/
+int nodes_file_add_tests(CU_pSuite suite)
+{
+ CU_ErrorCode status;
+
+ if (NULL == CU_add_test(suite, "semanage_node_serialize_local", test_semanage_node_serialize_local))
+ goto cleanup;
+
+cleanup:
+ if (CUE_SUCCESS != (status = CU_get_error()))
+ CU_cleanup_registry();
+ return status;
+}
+
+/* Tests the semanage_node_serialize_local function in nodes_file.c
+ */
+void test_semanage_node_serialize_local(void) {
+ int status;
+
+ uint32_t message_type;
+ uint64_t data_length;
+ char *data = NULL;
+ char *ptr = NULL;
+ int timeout = 0;
+ uint32_t database_type = 0;
+
+ semanage_node_t **records = NULL;
+ unsigned int records_size;
+
+ dbase_config_t *dconfig = semanage_node_dbase_local(sh);
+ record_table_t *rtable = dconfig->dtable->get_rtable(dconfig);
+
+ char *addr = NULL;
+ char *mask = NULL;
+ char *context_str = NULL;
+
+ int commit_number = 7;
+
+ if (ps_pid == 0) {
+ /* Server code. */
+
+ /* On caching the client will ask for the commit number. */
+ status = test_semanage_ps_handle_get_commit_number(sh, commit_number);
+ CU_ASSERT( status == STATUS_SUCCESS );
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Wait for message. */
+ if ((status = read_msg(sh, client_socket_fd, timeout, &message_type, &data_length, &data)))
+ goto cleanup;
+
+ CU_ASSERT( message_type == PS_GET_DATABASE );
+ if (message_type != PS_GET_DATABASE) {
+ status = -1;
+ goto cleanup;
+ }
+
+ /* Get and serialize the database. */
+ free(data);
+ data = NULL;
+
+ if ((status = semanage_node_serialize_local(sh, &data, &data_length)))
+ goto cleanup;
+
+ /* Send back the database. */
+ if ((status = write_msg(sh, client_socket_fd, PS_OK, data_length, data)))
+ goto cleanup;
+
+ /* On caching the client will ask for the commit number. */
+ status = test_semanage_ps_handle_get_commit_number(sh, commit_number);
+ CU_ASSERT( status == STATUS_SUCCESS );
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* On flushing the client will ask for the commit number. */
+ //FIXME: Why does the client ask for the commit number so many times here?
+ status = test_semanage_ps_handle_get_commit_number(sh, commit_number);
+ CU_ASSERT( status == STATUS_SUCCESS );
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ status = test_semanage_ps_handle_get_commit_number(sh, commit_number);
+ CU_ASSERT( status == STATUS_SUCCESS );
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Receive changed database. */
+ free(data);
+ data = NULL;
+
+ if ((status = read_msg(sh, client_socket_fd, timeout, &message_type, &data_length, &data)))
+ goto cleanup;
+
+ CU_ASSERT( message_type == PS_PUT_DATABASE );
+ if (message_type != PS_PUT_DATABASE) {
+ status = -1;
+ goto cleanup;
+ }
+
+ /* Say we got it ok. */
+ if ((status = write_msg(sh, client_socket_fd, PS_OK, 0, NULL)))
+ goto cleanup;
+
+ /* Unserialize the database type */
+ ptr = data;
+ if(semanage_dbase_ps_database_type_unserialize(sh, &ptr, &data_length, &database_type));
+ goto cleanup;
+
+ /* Unserialize the database. and don't move the data pointer.*/
+ if ((status = semanage_node_unserialize_local(sh, ptr, data_length)))
+ goto cleanup;
+
+ /* Gather the database records. */
+ status = dconfig->dtable->list(sh, dconfig, (record_t ***)&records, &records_size);
+ CU_ASSERT( status == 0 );
+ CU_ASSERT( records != NULL );
+ CU_ASSERT( records_size == 3 );
+
+ /* Verify data. */
+ int proto = semanage_node_get_proto(records[0]);
+ status = semanage_node_get_addr(sh, records[0], &addr);
+ status = semanage_node_get_mask(sh, records[0], &mask);
+
+ semanage_context_t *context = semanage_node_get_con(records[0]);
+ status = semanage_context_to_string(sh, context, &context_str);
+
+ CU_ASSERT( proto == SEMANAGE_PROTO_IP4 );
+ CU_ASSERT( strcmp(addr, "10.10.10.10") == 0 );
+ CU_ASSERT( strcmp(mask, "255.255.255.255") == 0 );
+ CU_ASSERT( strcmp(context_str, "testuser:testrole:testtype") == 0 );
+
+ /* Cleanup. */
+ free(addr);
+ free(mask);
+ free(context_str);
+
+ proto = semanage_node_get_proto(records[1]);
+ status = semanage_node_get_addr(sh, records[1], &addr);
+ status = semanage_node_get_mask(sh, records[1], &mask);
+
+ context = semanage_node_get_con(records[1]);
+ status = semanage_context_to_string(sh, context, &context_str);
+
+ CU_ASSERT( proto == SEMANAGE_PROTO_IP4 );
+ CU_ASSERT( strcmp(addr, "10.10.10.1") == 0 );
+ CU_ASSERT( strcmp(mask, "255.255.255.1") == 0 );
+ CU_ASSERT( strcmp(context_str, "testuser2:testrole2:testtype2") == 0 );
+
+ /* Cleanup. */
+ free(addr);
+ free(mask);
+ free(context_str);
+
+ proto = semanage_node_get_proto(records[2]);
+ status = semanage_node_get_addr(sh, records[2], &addr);
+ status = semanage_node_get_mask(sh, records[2], &mask);
+
+ context = semanage_node_get_con(records[2]);
+ status = semanage_context_to_string(sh, context, &context_str);
+
+ CU_ASSERT( proto == SEMANAGE_PROTO_IP4 );
+ CU_ASSERT( strcmp(addr, "10.10.10.2") == 0 );
+ CU_ASSERT( strcmp(mask, "255.255.255.2") == 0 );
+ CU_ASSERT( strcmp(context_str, "testuser3:testrole3:testtype3") == 0 );
+ }
+
+ if (ps_pid > 0) {
+ /* Client code. */
+
+ /* Cache database.
+ * This sends a message to the server requesting the database.
+ * The server serializes the database and sends it to us (the client).
+ * Internally the database is unserialized and loaded.
+ */
+ status = dconfig->dtable->cache(sh, dconfig);
+ CU_ASSERT( status == 0 );
+
+ /* Gather the database records. */
+ status = dconfig->dtable->list(sh, dconfig, (record_t ***)&records, &records_size);
+ CU_ASSERT( status == 0 );
+ CU_ASSERT( records != NULL );
+ CU_ASSERT( records_size == 2 );
+
+ /* Verify data was sent correctly. */
+ int proto = semanage_node_get_proto(records[0]);
+ status = semanage_node_get_addr(sh, records[0], &addr);
+ status = semanage_node_get_mask(sh, records[0], &mask);
+
+ semanage_context_t *context = semanage_node_get_con(records[0]);
+ status = semanage_context_to_string(sh, context, &context_str);
+
+ CU_ASSERT( proto == SEMANAGE_PROTO_IP4 );
+ CU_ASSERT( strcmp(addr, "10.10.10.10") == 0 );
+ CU_ASSERT( strcmp(mask, "255.255.255.255") == 0 );
+ CU_ASSERT( strcmp(context_str, "testuser:testrole:testtype") == 0 );
+
+ /* Cleanup. */
+ free(addr);
+ free(mask);
+ free(context_str);
+
+ proto = semanage_node_get_proto(records[1]);
+ status = semanage_node_get_addr(sh, records[1], &addr);
+ status = semanage_node_get_mask(sh, records[1], &mask);
+
+ context = semanage_node_get_con(records[1]);
+ status = semanage_context_to_string(sh, context, &context_str);
+
+ CU_ASSERT( proto == SEMANAGE_PROTO_IP4 );
+ CU_ASSERT( strcmp(addr, "10.10.10.1") == 0 );
+ CU_ASSERT( strcmp(mask, "255.255.255.1") == 0 );
+ CU_ASSERT( strcmp(context_str, "testuser2:testrole2:testtype2") == 0 );
+
+ /* Change something. */
+
+ /* Add some test entries to the list. */
+ record_t *node = NULL;
+ record_key_t *nodekey = NULL;
+
+ /* Create record. */
+ status = rtable->create(sh, &node);
+ if (status) goto cleanup;
+
+ /* Populate record. */
+ status = semanage_node_set_addr(sh, (semanage_node_t *)node, proto, "10.10.10.2");
+ if (status) goto cleanup;
+ status = semanage_node_set_mask(sh, (semanage_node_t *)node, proto, "255.255.255.2");
+
+ status = semanage_context_from_string(sh, "testuser3:testrole3:testtype3", &context);
+ if (status) goto cleanup;
+ status = semanage_node_set_con(sh, (semanage_node_t *)node, context);
+ if (status) goto cleanup;
+
+ status = rtable->key_extract(sh, node, &nodekey);
+ if (status) goto cleanup;
+
+ /* Add record. */
+ status = dconfig->dtable->add(
+ sh,
+ dconfig,
+ nodekey,
+ node);
+ if (status) goto cleanup;
+
+ /* Cleanup. */
+ semanage_context_free(context);
+ rtable->free(node);
+ rtable->key_free(nodekey);
+
+ /* Flush database.
+ * This sends a message to the server to replace its database
+ * with the one we are sending. Internally the flush serializes
+ * the database and sends it. The server then unserializes it,
+ * clears its old copy, and replaces it with the new one.
+ */
+ status = dconfig->dtable->flush(sh, dconfig);
+ CU_ASSERT( status == 0 );
+ }
+
+ /* Cleanup. */
+cleanup:
+ if (records != NULL) {
+ unsigned int i;
+ for (i = 0; i < records_size; i++) {
+ if (!records[i])
+ break;
+ rtable->free((record_t *)records[i]);
+ }
+ }
+
+ free(records);
+ free(data);
+ free(addr);
+ free(mask);
+ free(context_str);
+
+ CU_ASSERT( status == 0 );
+ if (status != 0) {
+ printf("\n\nReceived error code in %s: %d | %s\n", (ps_pid == 0) ? "server" : "client", status, strerror(status));
+ }
+}
+
Index: selinux-pms-support/libsemanage/tests/test_nodes_file.h
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/tests/test_nodes_file.h
@@ -0,0 +1,32 @@
+/* Authors: Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __TEST_NODES_FILE_H__
+#define __TEST_NODES_FILE_H__
+
+#include <CUnit/Basic.h>
+
+int nodes_file_test_init(void);
+int nodes_file_test_cleanup(void);
+int nodes_file_add_tests(CU_pSuite suite);
+
+void test_semanage_node_serialize_local(void);
+
+#endif
Index: selinux-pms-support/libsemanage/tests/test_nodes_policy.c
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/tests/test_nodes_policy.c
@@ -0,0 +1,392 @@
+/* Authors: Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* The purpose of this file is to provide unit tests of the functions in:
+ *
+ * libsemanage/src/nodes_policy.c
+ *
+ */
+
+#include "globals.h"
+#include "utilities.h"
+#include "test_nodes_policy.h"
+
+#include <libgen.h>
+#include <limits.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <CUnit/Basic.h>
+
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <selinux/selinux.h>
+
+#include "debug.h"
+#include "byteswap.h"
+#include "handle.h"
+#include "modules.h"
+#include "policy.h"
+#include "nodes_policy.h"
+#include "messages_internal.h"
+#include "semanage_store.h"
+#include "database_policydb.h"
+#include "user_internal.h"
+#include "seuser_internal.h"
+#include "port_internal.h"
+#include "iface_internal.h"
+#include "boolean_internal.h"
+#include "fcontext_internal.h"
+#include "node_internal.h"
+
+#include "database_llist.h"
+
+/* Server table setup. */
+
+/* Record functions. */
+
+static record_table_t test_node_rtable = {
+ .create = (create_f)semanage_node_create,
+ .key_extract = (key_extract_f)semanage_node_key_extract,
+ .key_free = (key_free_f)semanage_node_key_free,
+ .clone = (clone_f)semanage_node_clone,
+ .compare = (compare_f)semanage_node_compare,
+ .compare2 = (compare2_f)semanage_node_compare2,
+ .compare2_qsort = NULL,
+ .free = (free_f)semanage_node_free,
+ .serialize = (serialize_f)semanage_node_serialize,
+ .unserialize = (unserialize_f)semanage_node_unserialize,
+};
+
+/* Table functions. */
+
+/* Test cache function. */
+static int test_dbase_policydb_cache(
+ semanage_handle_t *handle,
+ dbase_config_t *dconfig)
+{
+ int status = 0;
+
+ /* Add some test entries to the list. */
+ record_t *node = NULL;
+ record_key_t *nodekey = NULL;
+
+ record_table_t *rtable = dconfig->dtable->get_rtable(dconfig);
+
+ /* Create record. */
+ status = rtable->create(sh, &node);
+ if (status) goto cleanup;
+
+ /* Populate record. */
+ semanage_context_t *context;
+ int proto = SEMANAGE_PROTO_IP4;
+
+ status = semanage_node_set_addr(sh, (semanage_node_t *)node, proto, "10.10.10.10");
+ if (status) goto cleanup;
+ status = semanage_node_set_mask(sh, (semanage_node_t *)node, proto, "255.255.255.255");
+
+ status = semanage_context_from_string(sh, "testuser:testrole:testtype", &context);
+ if (status) goto cleanup;
+ status = semanage_node_set_con(sh, (semanage_node_t *)node, context);
+ if (status) goto cleanup;
+
+ status = rtable->key_extract(sh, node, &nodekey);
+ if (status) goto cleanup;
+
+ /* Add record. */
+ status = dconfig->dtable->add(
+ sh,
+ dconfig,
+ nodekey,
+ node);
+ if (status) goto cleanup;
+
+ /* Cleanup. */
+ semanage_context_free(context);
+ context = NULL;
+ rtable->free(node);
+ node = NULL;
+ rtable->key_free(nodekey);
+ nodekey = NULL;
+
+ /* Create record. */
+ status = rtable->create(sh, &node);
+ if (status) goto cleanup;
+
+ /* Populate record. */
+ status = semanage_node_set_addr(sh, (semanage_node_t *)node, proto, "10.10.10.1");
+ if (status) goto cleanup;
+ status = semanage_node_set_mask(sh, (semanage_node_t *)node, proto, "255.255.255.1");
+
+ status = semanage_context_from_string(sh, "testuser2:testrole2:testtype2", &context);
+ if (status) goto cleanup;
+ status = semanage_node_set_con(sh, (semanage_node_t *)node, context);
+ if (status) goto cleanup;
+
+ status = rtable->key_extract(sh, node, &nodekey);
+ if (status) goto cleanup;
+
+ /* Add record. */
+ status = dconfig->dtable->add(
+ sh,
+ dconfig,
+ nodekey,
+ node);
+ if (status) goto cleanup;
+
+ /* Cleanup. */
+cleanup:
+ semanage_context_free(context);
+ rtable->free(node);
+ rtable->key_free(nodekey);
+
+ CU_ASSERT( status == 0 );
+ return status;
+}
+
+/* Database callback table. */
+static dbase_table_t test_policydb_dtable = {
+
+ /* Cache/Transactions */
+ .cache = test_dbase_policydb_cache,
+ .drop_cache = (void *)dbase_llist_drop_cache,
+ .flush = NULL,
+ .is_modified = (void *)dbase_llist_is_modified,
+
+ /* Database API */
+ .iterate = (void *)dbase_llist_iterate,
+ .exists = (void *)dbase_llist_exists,
+ .list = (void *)dbase_llist_list,
+ .add = (void *)dbase_llist_add,
+ .set = (void *)dbase_llist_set,
+ .del = (void *)dbase_llist_del,
+ .clear = (void *)dbase_llist_clear,
+ .modify = (void *)dbase_llist_modify,
+ .query = (void *)dbase_llist_query,
+ .count = (void *)dbase_llist_count,
+
+ /* Polymorphism */
+ .get_rtable = (void *)dbase_llist_get_rtable
+};
+
+/* The suite initialization function.
+ * Returns zero on success, non-zero otherwise.
+ */
+int nodes_policy_test_init(void)
+{
+ int status = 0;
+
+ if (ps_pid == 0) {
+ /* Server code. */
+
+ /* Reset locks status. */
+ sh->u.ps_handle.socket_fd = 0;
+
+ /* Store setup. */
+ dbase_config_t *dconfig = semanage_node_dbase_policy(sh);
+
+ if ((status =
+ dbase_policydb_init(
+ sh,
+ "fakesuffix",
+ &test_node_rtable,
+ NULL,
+ (dbase_policydb_t **)&dconfig->dbase)))
+ goto cleanup;
+
+ dconfig->dtable = &test_policydb_dtable;
+
+ }
+
+ /* Cleanup. */
+cleanup:
+ return status;
+}
+
+/* The suite cleanup function.
+ * Returns zero on success, non-zero otherwise.
+ */
+int nodes_policy_test_cleanup(void)
+{
+ return 0;
+}
+
+/* Adds all the tests needed for this suite.
+*/
+int nodes_policy_add_tests(CU_pSuite suite)
+{
+ CU_ErrorCode status;
+
+ if (NULL == CU_add_test(suite, "semanage_node_serialize_policy", test_semanage_node_serialize_policy))
+ goto cleanup;
+
+cleanup:
+ if (CUE_SUCCESS != (status = CU_get_error()))
+ CU_cleanup_registry();
+ return status;
+}
+
+/* Tests the semanage_node_serialize_policy function in nodes_policy.c
+ */
+void test_semanage_node_serialize_policy(void) {
+ int status;
+
+ uint32_t message_type;
+ uint64_t data_length;
+ char *data = NULL;
+ int timeout = 0;
+
+ semanage_node_t **records = NULL;
+ unsigned int records_size;
+
+ dbase_config_t *dconfig = semanage_node_dbase_policy(sh);
+ record_table_t *rtable = dconfig->dtable->get_rtable(dconfig);
+
+ char *addr = NULL;
+ char *mask = NULL;
+ char *context_str = NULL;
+
+ int commit_number = 7;
+
+ if (ps_pid == 0) {
+ /* Server code. */
+
+ /* On caching the client will ask for the commit number. */
+ status = test_semanage_ps_handle_get_commit_number(sh, commit_number);
+ CU_ASSERT( status == STATUS_SUCCESS );
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Wait for message. */
+ if ((status = read_msg(sh, client_socket_fd, timeout, &message_type, &data_length, &data)))
+ goto cleanup;
+
+ CU_ASSERT( message_type == PS_GET_DATABASE );
+ if (message_type != PS_GET_DATABASE) {
+ status = -1;
+ goto cleanup;
+ }
+
+ /* Get and serialize the database. */
+ free(data);
+ data = NULL;
+
+ if ((status = semanage_node_serialize_policy(sh, &data, &data_length)))
+ goto cleanup;
+
+ /* Send back the database. */
+ if ((status = write_msg(sh, client_socket_fd, PS_OK, data_length, data)))
+ goto cleanup;
+
+ /* On caching the client will ask for the commit number. */
+ status = test_semanage_ps_handle_get_commit_number(sh, commit_number);
+ CU_ASSERT( status == STATUS_SUCCESS );
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ }
+
+ if (ps_pid > 0) {
+ /* Client code. */
+
+ /* Cache database.
+ * This sends a message to the server requesting the database.
+ * The server serializes the database and sends it to us (the client).
+ * Internally the database is unserialized and loaded.
+ */
+ status = dconfig->dtable->cache(sh, dconfig);
+ CU_ASSERT( status == 0 );
+
+ /* Gather the database records. */
+ status = dconfig->dtable->list(sh, dconfig, (record_t ***)&records, &records_size);
+ CU_ASSERT( status == 0 );
+ CU_ASSERT( records != NULL );
+ CU_ASSERT( records_size == 2 );
+
+ /* Verify data was sent correctly. */
+ int proto = semanage_node_get_proto(records[0]);
+ status = semanage_node_get_addr(sh, records[0], &addr);
+ status = semanage_node_get_mask(sh, records[0], &mask);
+
+ semanage_context_t *context = semanage_node_get_con(records[0]);
+ status = semanage_context_to_string(sh, context, &context_str);
+
+ CU_ASSERT( proto == SEMANAGE_PROTO_IP4 );
+ CU_ASSERT( strcmp(addr, "10.10.10.10") == 0 );
+ CU_ASSERT( strcmp(mask, "255.255.255.255") == 0 );
+ CU_ASSERT( strcmp(context_str, "testuser:testrole:testtype") == 0 );
+
+ /* Cleanup. */
+ free(addr);
+ free(mask);
+ free(context_str);
+
+ proto = semanage_node_get_proto(records[1]);
+ status = semanage_node_get_addr(sh, records[1], &addr);
+ status = semanage_node_get_mask(sh, records[1], &mask);
+
+ context = semanage_node_get_con(records[1]);
+ status = semanage_context_to_string(sh, context, &context_str);
+
+ CU_ASSERT( proto == SEMANAGE_PROTO_IP4 );
+ CU_ASSERT( strcmp(addr, "10.10.10.1") == 0 );
+ CU_ASSERT( strcmp(mask, "255.255.255.1") == 0 );
+ CU_ASSERT( strcmp(context_str, "testuser2:testrole2:testtype2") == 0 );
+ }
+
+ /* Cleanup. */
+cleanup:
+ if (records != NULL) {
+ unsigned int i;
+ for (i = 0; i < records_size; i++) {
+ if (!records[i])
+ break;
+ rtable->free((record_t *)records[i]);
+ }
+ }
+
+ free(records);
+ free(data);
+ free(addr);
+ free(mask);
+ free(context_str);
+
+ CU_ASSERT( status == 0 );
+ if (status != 0) {
+ printf("\n\nReceived error code in %s: %d | %s\n", (ps_pid == 0) ? "server" : "client", status, strerror(status));
+ }
+}
+
Index: selinux-pms-support/libsemanage/tests/test_nodes_policy.h
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/tests/test_nodes_policy.h
@@ -0,0 +1,32 @@
+/* Authors: Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __TEST_NODES_POLICY_H__
+#define __TEST_NODES_POLICY_H__
+
+#include <CUnit/Basic.h>
+
+int nodes_policy_test_init(void);
+int nodes_policy_test_cleanup(void);
+int nodes_policy_add_tests(CU_pSuite suite);
+
+void test_semanage_node_serialize_policy(void);
+
+#endif
--
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH 31/33] libsemanage: port serialization tests
2007-04-23 21:34 [PATCH 00/33] libsemanage/libsepol object serialization and ps-api jbrindle
` (29 preceding siblings ...)
2007-04-23 21:35 ` [PATCH 30/33] libsemanage: node " jbrindle
@ 2007-04-23 21:35 ` jbrindle
2007-04-23 21:35 ` [PATCH 32/33] libsemanage: seuser " jbrindle
` (3 subsequent siblings)
34 siblings, 0 replies; 58+ messages in thread
From: jbrindle @ 2007-04-23 21:35 UTC (permalink / raw)
To: selinux
---
libsemanage/tests/libsemanage-tests.c | 6
libsemanage/tests/test_ports_file.c | 516 ++++++++++++++++++++++++++++++++++
libsemanage/tests/test_ports_file.h | 32 ++
libsemanage/tests/test_ports_policy.c | 384 +++++++++++++++++++++++++
libsemanage/tests/test_ports_policy.h | 32 ++
5 files changed, 970 insertions(+)
Index: selinux-pms-support/libsemanage/tests/libsemanage-tests.c
===================================================================
--- selinux-pms-support.orig/libsemanage/tests/libsemanage-tests.c
+++ selinux-pms-support/libsemanage/tests/libsemanage-tests.c
@@ -48,6 +48,9 @@
#include "test_nodes_file.h"
#include "test_nodes_policy.h"
+#include "test_ports_file.h"
+#include "test_ports_policy.h"
+
#include <CUnit/Basic.h>
#include <CUnit/Console.h>
#include <CUnit/TestDB.h>
@@ -116,6 +119,9 @@ static int do_tests(int interactive, int
DECLARE_SUITE(nodes_file);
DECLARE_SUITE(nodes_policy);
+ DECLARE_SUITE(ports_file);
+ DECLARE_SUITE(ports_policy);
+
/* The ps_api_disconnect test 'unforks'. */
DECLARE_SUITE(ps_api_disconnect);
Index: selinux-pms-support/libsemanage/tests/test_ports_file.c
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/tests/test_ports_file.c
@@ -0,0 +1,516 @@
+/* Authors: Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* The purpose of this file is to provide unit tests of the functions in:
+ *
+ * libsemanage/src/ports_file.c
+ *
+ */
+
+#include "globals.h"
+#include "utilities.h"
+#include "test_ports_file.h"
+
+#include <libgen.h>
+#include <limits.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <CUnit/Basic.h>
+
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <selinux/selinux.h>
+
+#include "debug.h"
+#include "byteswap.h"
+#include "handle.h"
+#include "modules.h"
+#include "policy.h"
+#include "ports_local.h"
+#include "messages_internal.h"
+#include "semanage_store.h"
+#include "database_file.h"
+#include "user_internal.h"
+#include "seuser_internal.h"
+#include "port_internal.h"
+#include "iface_internal.h"
+#include "boolean_internal.h"
+#include "fcontext_internal.h"
+#include "node_internal.h"
+
+#include "database_llist.h"
+
+/* Server table setup. */
+
+/* Record functions. */
+
+static record_table_t test_port_rtable = {
+ .create = (create_f)semanage_port_create,
+ .key_extract = (key_extract_f)semanage_port_key_extract,
+ .key_free = (key_free_f)semanage_port_key_free,
+ .clone = (clone_f)semanage_port_clone,
+ .compare = (compare_f)semanage_port_compare,
+ .compare2 = (compare2_f)semanage_port_compare2,
+ .compare2_qsort = NULL,
+ .free = (free_f)semanage_port_free,
+ .serialize = (serialize_f)semanage_port_serialize,
+ .unserialize = (unserialize_f)semanage_port_unserialize,
+};
+
+/* Table functions. */
+
+/* Test cache function. */
+static int test_dbase_file_cache(
+ semanage_handle_t *handle,
+ dbase_config_t *dconfig)
+{
+ int status = 0;
+
+ /* Add some test entries to the list. */
+ record_t *port = NULL;
+ record_key_t *portkey = NULL;
+
+ record_table_t *rtable = dconfig->dtable->get_rtable(dconfig);
+
+ /* Create record. */
+ status = rtable->create(sh, &port);
+ if (status) goto cleanup;
+
+ /* Populate record. */
+ semanage_context_t *context;
+ int proto = SEMANAGE_PROTO_TCP;
+
+ semanage_port_set_range((semanage_port_t *)port, 1, 65535);
+ semanage_port_set_proto((semanage_port_t *)port, proto);
+
+ status = semanage_context_from_string(sh, "testuser:testrole:testtype", &context);
+ if (status) goto cleanup;
+ status = semanage_port_set_con(sh, (semanage_port_t *)port, context);
+ if (status) goto cleanup;
+
+ status = rtable->key_extract(sh, port, &portkey);
+ if (status) goto cleanup;
+
+ /* Add record. */
+ status = dconfig->dtable->add(
+ sh,
+ dconfig,
+ portkey,
+ port);
+ if (status) goto cleanup;
+
+ /* Cleanup. */
+ semanage_context_free(context);
+ context = NULL;
+ rtable->free(port);
+ port = NULL;
+ rtable->key_free(portkey);
+ portkey = NULL;
+
+ /* Create record. */
+ status = rtable->create(sh, &port);
+ if (status) goto cleanup;
+
+ /* Populate record. */
+ semanage_port_set_range((semanage_port_t *)port, 2, 1024);
+ semanage_port_set_proto((semanage_port_t *)port, proto);
+
+ status = semanage_context_from_string(sh, "testuser2:testrole2:testtype2", &context);
+ if (status) goto cleanup;
+ status = semanage_port_set_con(sh, (semanage_port_t *)port, context);
+ if (status) goto cleanup;
+
+ status = rtable->key_extract(sh, port, &portkey);
+ if (status) goto cleanup;
+
+ /* Add record. */
+ status = dconfig->dtable->add(
+ sh,
+ dconfig,
+ portkey,
+ port);
+ if (status) goto cleanup;
+
+ /* Cleanup. */
+cleanup:
+ semanage_context_free(context);
+ rtable->free(port);
+ rtable->key_free(portkey);
+
+ CU_ASSERT( status == 0 );
+ return status;
+}
+
+/* Database callback table. */
+static dbase_table_t test_file_dtable = {
+
+ /* Cache/Transactions */
+ .cache = test_dbase_file_cache,
+ .drop_cache = (void *)dbase_llist_drop_cache,
+ .flush = NULL,
+ .is_modified = (void *)dbase_llist_is_modified,
+
+ /* Database API */
+ .iterate = (void *)dbase_llist_iterate,
+ .exists = (void *)dbase_llist_exists,
+ .list = (void *)dbase_llist_list,
+ .add = (void *)dbase_llist_add,
+ .set = (void *)dbase_llist_set,
+ .del = (void *)dbase_llist_del,
+ .clear = (void *)dbase_llist_clear,
+ .modify = (void *)dbase_llist_modify,
+ .query = (void *)dbase_llist_query,
+ .count = (void *)dbase_llist_count,
+
+ /* Polymorphism */
+ .get_rtable = (void *)dbase_llist_get_rtable
+};
+
+/* The suite initialization function.
+ * Returns zero on success, non-zero otherwise.
+ */
+int ports_file_test_init(void)
+{
+ int status = 0;
+
+ if (ps_pid == 0) {
+ /* Server code. */
+
+ /* Reset locks status. */
+ sh->u.ps_handle.socket_fd = 0;
+
+ /* Store setup. */
+ dbase_config_t *dconfig = semanage_port_dbase_local(sh);
+
+ if ((status =
+ dbase_file_init(
+ sh,
+ "fakesuffix",
+ &test_port_rtable,
+ NULL,
+ (dbase_file_t **)&dconfig->dbase)))
+ goto cleanup;
+
+ dconfig->dtable = &test_file_dtable;
+
+ }
+
+ /* Cleanup. */
+cleanup:
+ return status;
+}
+
+/* The suite cleanup function.
+ * Returns zero on success, non-zero otherwise.
+ */
+int ports_file_test_cleanup(void)
+{
+ return 0;
+}
+
+/* Adds all the tests needed for this suite.
+*/
+int ports_file_add_tests(CU_pSuite suite)
+{
+ CU_ErrorCode status;
+
+ if (NULL == CU_add_test(suite, "semanage_port_serialize_local", test_semanage_port_serialize_local))
+ goto cleanup;
+
+cleanup:
+ if (CUE_SUCCESS != (status = CU_get_error()))
+ CU_cleanup_registry();
+ return status;
+}
+
+/* Tests the semanage_port_serialize_local function in ports_file.c
+ */
+void test_semanage_port_serialize_local(void) {
+ int status;
+
+ uint32_t message_type;
+ uint64_t data_length;
+ char *data = NULL;
+ char *ptr = NULL;
+ int timeout = 0;
+ uint32_t database_type = 0;
+
+ semanage_port_t **records = NULL;
+ unsigned int records_size;
+
+ dbase_config_t *dconfig = semanage_port_dbase_local(sh);
+ record_table_t *rtable = dconfig->dtable->get_rtable(dconfig);
+
+ char *context_str = NULL;
+
+ int commit_number = 7;
+
+ if (ps_pid == 0) {
+ /* Server code. */
+
+ /* On caching the client will ask for the commit number. */
+ status = test_semanage_ps_handle_get_commit_number(sh, commit_number);
+ CU_ASSERT( status == STATUS_SUCCESS );
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Wait for message. */
+ if ((status = read_msg(sh, client_socket_fd, timeout, &message_type, &data_length, &data)))
+ goto cleanup;
+
+ CU_ASSERT( message_type == PS_GET_DATABASE );
+ if (message_type != PS_GET_DATABASE) {
+ status = -1;
+ goto cleanup;
+ }
+
+ /* Get and serialize the database. */
+ free(data);
+ data = NULL;
+
+ if ((status = semanage_port_serialize_local(sh, &data, &data_length)))
+ goto cleanup;
+
+ /* Send back the database. */
+ if ((status = write_msg(sh, client_socket_fd, PS_OK, data_length, data)))
+ goto cleanup;
+
+ /* On caching the client will ask for the commit number. */
+ status = test_semanage_ps_handle_get_commit_number(sh, commit_number);
+ CU_ASSERT( status == STATUS_SUCCESS );
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* On flushing the client will ask for the commit number. */
+ //FIXME: Why does the client ask for the commit number so many times here?
+ status = test_semanage_ps_handle_get_commit_number(sh, commit_number);
+ CU_ASSERT( status == STATUS_SUCCESS );
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ status = test_semanage_ps_handle_get_commit_number(sh, commit_number);
+ CU_ASSERT( status == STATUS_SUCCESS );
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Receive changed database. */
+ free(data);
+ data = NULL;
+
+ if ((status = read_msg(sh, client_socket_fd, timeout, &message_type, &data_length, &data)))
+ goto cleanup;
+
+ CU_ASSERT( message_type == PS_PUT_DATABASE );
+ if (message_type != PS_PUT_DATABASE) {
+ status = -1;
+ goto cleanup;
+ }
+
+ /* Say we got it ok. */
+ if ((status = write_msg(sh,client_socket_fd, PS_OK, 0, NULL)))
+ goto cleanup;
+
+ /* Unserialize the database type */
+ ptr = data;
+ if(semanage_dbase_ps_database_type_unserialize(sh, &ptr, &data_length, &database_type));
+ goto cleanup;
+
+ /* Unserialize the database. and don't move the data pointer.*/
+ if ((status = semanage_port_unserialize_local(sh, ptr, data_length)))
+ goto cleanup;
+
+ /* Gather the database records. */
+ status = dconfig->dtable->list(sh, dconfig, (record_t ***)&records, &records_size);
+ CU_ASSERT( status == 0 );
+ CU_ASSERT( records != NULL );
+ CU_ASSERT( records_size == 3 );
+
+ /* Verify data. */
+ int proto = semanage_port_get_proto(records[0]);
+ int low = semanage_port_get_low(records[0]);
+ int high = semanage_port_get_high(records[0]);
+
+ semanage_context_t *context = semanage_port_get_con(records[0]);
+ status = semanage_context_to_string(sh, context, &context_str);
+
+ CU_ASSERT( proto == SEMANAGE_PROTO_TCP );
+ CU_ASSERT( low == 1 );
+ CU_ASSERT( high == 65535 );
+ CU_ASSERT( strcmp(context_str, "testuser:testrole:testtype") == 0 );
+
+ /* Cleanup. */
+ free(context_str);
+
+ proto = semanage_port_get_proto(records[1]);
+ low = semanage_port_get_low(records[1]);
+ high = semanage_port_get_high(records[1]);
+
+ context = semanage_port_get_con(records[1]);
+ status = semanage_context_to_string(sh, context, &context_str);
+
+ CU_ASSERT( proto == SEMANAGE_PROTO_TCP );
+ CU_ASSERT( low == 2 );
+ CU_ASSERT( high == 1024 );
+ CU_ASSERT( strcmp(context_str, "testuser2:testrole2:testtype2") == 0 );
+
+ /* Cleanup. */
+ free(context_str);
+
+ proto = semanage_port_get_proto(records[2]);
+ low = semanage_port_get_low(records[2]);
+ high = semanage_port_get_high(records[2]);
+
+ context = semanage_port_get_con(records[2]);
+ status = semanage_context_to_string(sh, context, &context_str);
+
+ CU_ASSERT( proto == SEMANAGE_PROTO_TCP );
+ CU_ASSERT( low == 3 );
+ CU_ASSERT( high == 59049 );
+ CU_ASSERT( strcmp(context_str, "testuser3:testrole3:testtype3") == 0 );
+ }
+
+ if (ps_pid > 0) {
+ /* Client code. */
+
+ /* Cache database.
+ * This sends a message to the server requesting the database.
+ * The server serializes the database and sends it to us (the client).
+ * Internally the database is unserialized and loaded.
+ */
+ status = dconfig->dtable->cache(sh, dconfig);
+ CU_ASSERT( status == 0 );
+
+ /* Gather the database records. */
+ status = dconfig->dtable->list(sh, dconfig, (record_t ***)&records, &records_size);
+ CU_ASSERT( status == 0 );
+ CU_ASSERT( records != NULL );
+ CU_ASSERT( records_size == 2 );
+
+ /* Verify data was sent correctly. */
+ int proto = semanage_port_get_proto(records[0]);
+ int low = semanage_port_get_low(records[0]);
+ int high = semanage_port_get_high(records[0]);
+
+ semanage_context_t *context = semanage_port_get_con(records[0]);
+ status = semanage_context_to_string(sh, context, &context_str);
+
+ CU_ASSERT( proto == SEMANAGE_PROTO_TCP );
+ CU_ASSERT( low == 1 );
+ CU_ASSERT( high == 65535 );
+ CU_ASSERT( strcmp(context_str, "testuser:testrole:testtype") == 0 );
+
+ /* Cleanup. */
+ free(context_str);
+
+ proto = semanage_port_get_proto(records[1]);
+ low = semanage_port_get_low(records[1]);
+ high = semanage_port_get_high(records[1]);
+
+ context = semanage_port_get_con(records[1]);
+ status = semanage_context_to_string(sh, context, &context_str);
+
+ CU_ASSERT( proto == SEMANAGE_PROTO_TCP );
+ CU_ASSERT( low == 2 );
+ CU_ASSERT( high == 1024 );
+ CU_ASSERT( strcmp(context_str, "testuser2:testrole2:testtype2") == 0 );
+
+ /* Change something. */
+
+ /* Add some test entries to the list. */
+ record_t *port = NULL;
+ record_key_t *portkey = NULL;
+
+ /* Create record. */
+ status = rtable->create(sh, &port);
+ if (status) goto cleanup;
+
+ /* Populate record. */
+ semanage_port_set_range((semanage_port_t *)port, 3, 59049);
+ semanage_port_set_proto((semanage_port_t *)port, proto);
+
+ status = semanage_context_from_string(sh, "testuser3:testrole3:testtype3", &context);
+ if (status) goto cleanup;
+ status = semanage_port_set_con(sh, (semanage_port_t *)port, context);
+ if (status) goto cleanup;
+
+ status = rtable->key_extract(sh, port, &portkey);
+ if (status) goto cleanup;
+
+ /* Add record. */
+ status = dconfig->dtable->add(
+ sh,
+ dconfig,
+ portkey,
+ port);
+ if (status) goto cleanup;
+
+ /* Cleanup. */
+ semanage_context_free(context);
+ rtable->free(port);
+ rtable->key_free(portkey);
+
+ /* Flush database.
+ * This sends a message to the server to replace its database
+ * with the one we are sending. Internally the flush serializes
+ * the database and sends it. The server then unserializes it,
+ * clears its old copy, and replaces it with the new one.
+ */
+ status = dconfig->dtable->flush(sh, dconfig);
+ CU_ASSERT( status == 0 );
+ }
+
+ /* Cleanup. */
+cleanup:
+ if (records != NULL) {
+ unsigned int i;
+ for (i = 0; i < records_size; i++) {
+ if (!records[i])
+ break;
+ rtable->free((record_t *)records[i]);
+ }
+ }
+
+ free(records);
+ free(data);
+ free(context_str);
+
+ CU_ASSERT( status == 0 );
+ if (status != 0) {
+ printf("\n\nReceived error code in %s: %d | %s\n", (ps_pid == 0) ? "server" : "client", status, strerror(status));
+ }
+}
+
Index: selinux-pms-support/libsemanage/tests/test_ports_file.h
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/tests/test_ports_file.h
@@ -0,0 +1,32 @@
+/* Authors: Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __TEST_PORTS_FILE_H__
+#define __TEST_PORTS_FILE_H__
+
+#include <CUnit/Basic.h>
+
+int ports_file_test_init(void);
+int ports_file_test_cleanup(void);
+int ports_file_add_tests(CU_pSuite suite);
+
+void test_semanage_port_serialize_local(void);
+
+#endif
Index: selinux-pms-support/libsemanage/tests/test_ports_policy.c
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/tests/test_ports_policy.c
@@ -0,0 +1,384 @@
+/* Authors: Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* The purpose of this file is to provide unit tests of the functions in:
+ *
+ * libsemanage/src/ports_policy.c
+ *
+ */
+
+#include "globals.h"
+#include "utilities.h"
+#include "test_ports_policy.h"
+
+#include <libgen.h>
+#include <limits.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <CUnit/Basic.h>
+
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <selinux/selinux.h>
+
+#include "debug.h"
+#include "byteswap.h"
+#include "handle.h"
+#include "modules.h"
+#include "policy.h"
+#include "ports_policy.h"
+#include "messages_internal.h"
+#include "semanage_store.h"
+#include "database_policydb.h"
+#include "user_internal.h"
+#include "seuser_internal.h"
+#include "port_internal.h"
+#include "iface_internal.h"
+#include "boolean_internal.h"
+#include "fcontext_internal.h"
+#include "node_internal.h"
+
+#include "database_llist.h"
+
+/* Server table setup. */
+
+/* Record functions. */
+
+static record_table_t test_port_rtable = {
+ .create = (create_f)semanage_port_create,
+ .key_extract = (key_extract_f)semanage_port_key_extract,
+ .key_free = (key_free_f)semanage_port_key_free,
+ .clone = (clone_f)semanage_port_clone,
+ .compare = (compare_f)semanage_port_compare,
+ .compare2 = (compare2_f)semanage_port_compare2,
+ .compare2_qsort = NULL,
+ .free = (free_f)semanage_port_free,
+ .serialize = (serialize_f)semanage_port_serialize,
+ .unserialize = (unserialize_f)semanage_port_unserialize,
+};
+
+/* Table functions. */
+
+/* Test cache function. */
+static int test_dbase_policydb_cache(
+ semanage_handle_t *handle,
+ dbase_config_t *dconfig)
+{
+ int status = 0;
+
+ /* Add some test entries to the list. */
+ record_t *port = NULL;
+ record_key_t *portkey = NULL;
+
+ record_table_t *rtable = dconfig->dtable->get_rtable(dconfig);
+
+ /* Create record. */
+ status = rtable->create(sh, &port);
+ if (status) goto cleanup;
+
+ /* Populate record. */
+ semanage_context_t *context;
+ int proto = SEMANAGE_PROTO_TCP;
+
+ semanage_port_set_range((semanage_port_t *)port, 1, 65535);
+ semanage_port_set_proto((semanage_port_t *)port, proto);
+
+ status = semanage_context_from_string(sh, "testuser:testrole:testtype", &context);
+ if (status) goto cleanup;
+ status = semanage_port_set_con(sh, (semanage_port_t *)port, context);
+ if (status) goto cleanup;
+
+ status = rtable->key_extract(sh, port, &portkey);
+ if (status) goto cleanup;
+
+ /* Add record. */
+ status = dconfig->dtable->add(
+ sh,
+ dconfig,
+ portkey,
+ port);
+ if (status) goto cleanup;
+
+ /* Cleanup. */
+ semanage_context_free(context);
+ context = NULL;
+ rtable->free(port);
+ port = NULL;
+ rtable->key_free(portkey);
+ portkey = NULL;
+
+ /* Create record. */
+ status = rtable->create(sh, &port);
+ if (status) goto cleanup;
+
+ /* Populate record. */
+ semanage_port_set_range((semanage_port_t *)port, 2, 1024);
+ semanage_port_set_proto((semanage_port_t *)port, proto);
+
+ status = semanage_context_from_string(sh, "testuser2:testrole2:testtype2", &context);
+ if (status) goto cleanup;
+ status = semanage_port_set_con(sh, (semanage_port_t *)port, context);
+ if (status) goto cleanup;
+
+ status = rtable->key_extract(sh, port, &portkey);
+ if (status) goto cleanup;
+
+ /* Add record. */
+ status = dconfig->dtable->add(
+ sh,
+ dconfig,
+ portkey,
+ port);
+ if (status) goto cleanup;
+
+ /* Cleanup. */
+cleanup:
+ semanage_context_free(context);
+ rtable->free(port);
+ rtable->key_free(portkey);
+
+ CU_ASSERT( status == 0 );
+ return status;
+}
+
+/* Database callback table. */
+static dbase_table_t test_policydb_dtable = {
+
+ /* Cache/Transactions */
+ .cache = test_dbase_policydb_cache,
+ .drop_cache = (void *)dbase_llist_drop_cache,
+ .flush = NULL,
+ .is_modified = (void *)dbase_llist_is_modified,
+
+ /* Database API */
+ .iterate = (void *)dbase_llist_iterate,
+ .exists = (void *)dbase_llist_exists,
+ .list = (void *)dbase_llist_list,
+ .add = (void *)dbase_llist_add,
+ .set = (void *)dbase_llist_set,
+ .del = (void *)dbase_llist_del,
+ .clear = (void *)dbase_llist_clear,
+ .modify = (void *)dbase_llist_modify,
+ .query = (void *)dbase_llist_query,
+ .count = (void *)dbase_llist_count,
+
+ /* Polymorphism */
+ .get_rtable = (void *)dbase_llist_get_rtable
+};
+
+/* The suite initialization function.
+ * Returns zero on success, non-zero otherwise.
+ */
+int ports_policy_test_init(void)
+{
+ int status = 0;
+
+ if (ps_pid == 0) {
+ /* Server code. */
+
+ /* Reset locks status. */
+ sh->u.ps_handle.socket_fd = 0;
+
+ /* Store setup. */
+ dbase_config_t *dconfig = semanage_port_dbase_policy(sh);
+
+ if ((status =
+ dbase_policydb_init(
+ sh,
+ "fakesuffix",
+ &test_port_rtable,
+ NULL,
+ (dbase_policydb_t **)&dconfig->dbase)))
+ goto cleanup;
+
+ dconfig->dtable = &test_policydb_dtable;
+
+ }
+
+ /* Cleanup. */
+cleanup:
+ return status;
+}
+
+/* The suite cleanup function.
+ * Returns zero on success, non-zero otherwise.
+ */
+int ports_policy_test_cleanup(void)
+{
+ return 0;
+}
+
+/* Adds all the tests needed for this suite.
+*/
+int ports_policy_add_tests(CU_pSuite suite)
+{
+ CU_ErrorCode status;
+
+ if (NULL == CU_add_test(suite, "semanage_port_serialize_policy", test_semanage_port_serialize_policy))
+ goto cleanup;
+
+cleanup:
+ if (CUE_SUCCESS != (status = CU_get_error()))
+ CU_cleanup_registry();
+ return status;
+}
+
+/* Tests the semanage_port_serialize_policy function in ports_policy.c
+ */
+void test_semanage_port_serialize_policy(void) {
+ int status;
+
+ uint32_t message_type;
+ uint64_t data_length;
+ char *data = NULL;
+ int timeout = 0;
+
+ semanage_port_t **records = NULL;
+ unsigned int records_size;
+
+ dbase_config_t *dconfig = semanage_port_dbase_policy(sh);
+ record_table_t *rtable = dconfig->dtable->get_rtable(dconfig);
+
+ char *context_str = NULL;
+
+ int commit_number = 7;
+
+ if (ps_pid == 0) {
+ /* Server code. */
+
+ /* On caching the client will ask for the commit number. */
+ status = test_semanage_ps_handle_get_commit_number(sh, commit_number);
+ CU_ASSERT( status == STATUS_SUCCESS );
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Wait for message. */
+ if ((status = read_msg(sh, client_socket_fd, timeout, &message_type, &data_length, &data)))
+ goto cleanup;
+
+ CU_ASSERT( message_type == PS_GET_DATABASE );
+ if (message_type != PS_GET_DATABASE) {
+ status = -1;
+ goto cleanup;
+ }
+
+ /* Get and serialize the database. */
+ free(data);
+ data = NULL;
+
+ if ((status = semanage_port_serialize_policy(sh, &data, &data_length)))
+ goto cleanup;
+
+ /* Send back the database. */
+ if ((status = write_msg(sh, client_socket_fd, PS_OK, data_length, data)))
+ goto cleanup;
+
+ /* On caching the client will ask for the commit number. */
+ status = test_semanage_ps_handle_get_commit_number(sh, commit_number);
+ CU_ASSERT( status == STATUS_SUCCESS );
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ }
+
+ if (ps_pid > 0) {
+ /* Client code. */
+
+ /* Cache database.
+ * This sends a message to the server requesting the database.
+ * The server serializes the database and sends it to us (the client).
+ * Internally the database is unserialized and loaded.
+ */
+ status = dconfig->dtable->cache(sh, dconfig);
+ CU_ASSERT( status == 0 );
+
+ /* Gather the database records. */
+ status = dconfig->dtable->list(sh, dconfig, (record_t ***)&records, &records_size);
+ CU_ASSERT( status == 0 );
+ CU_ASSERT( records != NULL );
+ CU_ASSERT( records_size == 2 );
+
+ /* Verify data was sent correctly. */
+ int proto = semanage_port_get_proto(records[0]);
+ int low = semanage_port_get_low(records[0]);
+ int high = semanage_port_get_high(records[0]);
+
+ semanage_context_t *context = semanage_port_get_con(records[0]);
+ status = semanage_context_to_string(sh, context, &context_str);
+
+ CU_ASSERT( proto == SEMANAGE_PROTO_TCP );
+ CU_ASSERT( low == 1 );
+ CU_ASSERT( high == 65535 );
+ CU_ASSERT( strcmp(context_str, "testuser:testrole:testtype") == 0 );
+
+ /* Cleanup. */
+ free(context_str);
+
+ proto = semanage_port_get_proto(records[1]);
+ low = semanage_port_get_low(records[1]);
+ high = semanage_port_get_high(records[1]);
+
+ context = semanage_port_get_con(records[1]);
+ status = semanage_context_to_string(sh, context, &context_str);
+
+ CU_ASSERT( proto == SEMANAGE_PROTO_TCP );
+ CU_ASSERT( low == 2 );
+ CU_ASSERT( high == 1024 );
+ CU_ASSERT( strcmp(context_str, "testuser2:testrole2:testtype2") == 0 );
+ }
+
+ /* Cleanup. */
+cleanup:
+ if (records != NULL) {
+ unsigned int i;
+ for (i = 0; i < records_size; i++) {
+ if (!records[i])
+ break;
+ rtable->free((record_t *)records[i]);
+ }
+ }
+
+ free(records);
+ free(data);
+ free(context_str);
+
+ CU_ASSERT( status == 0 );
+ if (status != 0) {
+ printf("\n\nReceived error code in %s: %d | %s\n", (ps_pid == 0) ? "server" : "client", status, strerror(status));
+ }
+}
+
Index: selinux-pms-support/libsemanage/tests/test_ports_policy.h
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/tests/test_ports_policy.h
@@ -0,0 +1,32 @@
+/* Authors: Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __TEST_PORTS_POLICY_H__
+#define __TEST_PORTS_POLICY_H__
+
+#include <CUnit/Basic.h>
+
+int ports_policy_test_init(void);
+int ports_policy_test_cleanup(void);
+int ports_policy_add_tests(CU_pSuite suite);
+
+void test_semanage_port_serialize_policy(void);
+
+#endif
--
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH 32/33] libsemanage: seuser serialization tests
2007-04-23 21:34 [PATCH 00/33] libsemanage/libsepol object serialization and ps-api jbrindle
` (30 preceding siblings ...)
2007-04-23 21:35 ` [PATCH 31/33] libsemanage: port " jbrindle
@ 2007-04-23 21:35 ` jbrindle
2007-04-23 21:35 ` [PATCH 33/33] libsemanage: user " jbrindle
` (2 subsequent siblings)
34 siblings, 0 replies; 58+ messages in thread
From: jbrindle @ 2007-04-23 21:35 UTC (permalink / raw)
To: selinux
---
libsemanage/tests/libsemanage-tests.c | 6
libsemanage/tests/test_seusers_file.c | 456 ++++++++++++++++++++++++++++++++
libsemanage/tests/test_seusers_file.h | 32 ++
libsemanage/tests/test_seusers_policy.c | 354 ++++++++++++++++++++++++
libsemanage/tests/test_seusers_policy.h | 32 ++
5 files changed, 880 insertions(+)
Index: selinux-pms-support/libsemanage/tests/libsemanage-tests.c
===================================================================
--- selinux-pms-support.orig/libsemanage/tests/libsemanage-tests.c
+++ selinux-pms-support/libsemanage/tests/libsemanage-tests.c
@@ -51,6 +51,9 @@
#include "test_ports_file.h"
#include "test_ports_policy.h"
+#include "test_seusers_file.h"
+#include "test_seusers_policy.h"
+
#include <CUnit/Basic.h>
#include <CUnit/Console.h>
#include <CUnit/TestDB.h>
@@ -122,6 +125,9 @@ static int do_tests(int interactive, int
DECLARE_SUITE(ports_file);
DECLARE_SUITE(ports_policy);
+ DECLARE_SUITE(seusers_file);
+ DECLARE_SUITE(seusers_policy);
+
/* The ps_api_disconnect test 'unforks'. */
DECLARE_SUITE(ps_api_disconnect);
Index: selinux-pms-support/libsemanage/tests/test_seusers_file.c
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/tests/test_seusers_file.c
@@ -0,0 +1,456 @@
+/* Authors: Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* The purpose of this file is to provide unit tests of the functions in:
+ *
+ * libsemanage/src/seusers_file.c
+ *
+ */
+
+#include "globals.h"
+#include "utilities.h"
+#include "test_seusers_file.h"
+
+#include <libgen.h>
+#include <limits.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <CUnit/Basic.h>
+
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <selinux/selinux.h>
+
+#include "debug.h"
+#include "byteswap.h"
+#include "handle.h"
+#include "modules.h"
+#include "policy.h"
+#include "seusers_local.h"
+#include "messages_internal.h"
+#include "semanage_store.h"
+#include "database_file.h"
+#include "user_internal.h"
+#include "port_internal.h"
+#include "seuser_internal.h"
+#include "iface_internal.h"
+#include "boolean_internal.h"
+#include "fcontext_internal.h"
+#include "node_internal.h"
+
+#include "database_llist.h"
+
+/* Server table setup. */
+
+/* Record functions. */
+
+static record_table_t test_seuser_rtable = {
+ .create = (create_f)semanage_seuser_create,
+ .key_extract = (key_extract_f)semanage_seuser_key_extract,
+ .key_free = (key_free_f)semanage_seuser_key_free,
+ .clone = (clone_f)semanage_seuser_clone,
+ .compare = (compare_f)semanage_seuser_compare,
+ .compare2 = (compare2_f)semanage_seuser_compare2,
+ .compare2_qsort = NULL,
+ .free = (free_f)semanage_seuser_free,
+ .serialize = (serialize_f)semanage_seuser_serialize,
+ .unserialize = (unserialize_f)semanage_seuser_unserialize,
+};
+
+/* Table functions. */
+
+/* Test cache function. */
+static int test_dbase_file_cache(
+ semanage_handle_t *handle,
+ dbase_config_t *dconfig)
+{
+ int status = 0;
+
+ /* Add some test entries to the list. */
+ record_t *seuser = NULL;
+ record_key_t *seuserkey = NULL;
+
+ record_table_t *rtable = dconfig->dtable->get_rtable(dconfig);
+
+ /* Create record. */
+ status = rtable->create(sh, &seuser);
+ if (status) goto cleanup;
+
+ /* Populate record. */
+ status = semanage_seuser_set_name(sh, (semanage_seuser_t *)seuser, "testname");
+ if (status) goto cleanup;
+ status = semanage_seuser_set_sename(sh, (semanage_seuser_t *)seuser, "testsename");
+ if (status) goto cleanup;
+
+ status = rtable->key_extract(sh, seuser, &seuserkey);
+ if (status) goto cleanup;
+
+ /* Add record. */
+ status = dconfig->dtable->add(
+ sh,
+ dconfig,
+ seuserkey,
+ seuser);
+ if (status) goto cleanup;
+
+ /* Cleanup. */
+ rtable->free(seuser);
+ seuser = NULL;
+ rtable->key_free(seuserkey);
+ seuserkey = NULL;
+
+ /* Create record. */
+ status = rtable->create(sh, &seuser);
+ if (status) goto cleanup;
+
+ /* Populate record. */
+ status = semanage_seuser_set_name(sh, (semanage_seuser_t *)seuser, "testname2");
+ if (status) goto cleanup;
+ status = semanage_seuser_set_sename(sh, (semanage_seuser_t *)seuser, "testsename2");
+ if (status) goto cleanup;
+
+ status = rtable->key_extract(sh, seuser, &seuserkey);
+ if (status) goto cleanup;
+
+ /* Add record. */
+ status = dconfig->dtable->add(
+ sh,
+ dconfig,
+ seuserkey,
+ seuser);
+ if (status) goto cleanup;
+
+ /* Cleanup. */
+cleanup:
+ rtable->free(seuser);
+ rtable->key_free(seuserkey);
+
+ CU_ASSERT( status == 0 );
+ return status;
+}
+
+/* Database callback table. */
+static dbase_table_t test_file_dtable = {
+
+ /* Cache/Transactions */
+ .cache = test_dbase_file_cache,
+ .drop_cache = (void *)dbase_llist_drop_cache,
+ .flush = NULL,
+ .is_modified = (void *)dbase_llist_is_modified,
+
+ /* Database API */
+ .iterate = (void *)dbase_llist_iterate,
+ .exists = (void *)dbase_llist_exists,
+ .list = (void *)dbase_llist_list,
+ .add = (void *)dbase_llist_add,
+ .set = (void *)dbase_llist_set,
+ .del = (void *)dbase_llist_del,
+ .clear = (void *)dbase_llist_clear,
+ .modify = (void *)dbase_llist_modify,
+ .query = (void *)dbase_llist_query,
+ .count = (void *)dbase_llist_count,
+
+ /* Polymorphism */
+ .get_rtable = (void *)dbase_llist_get_rtable
+};
+
+/* The suite initialization function.
+ * Returns zero on success, non-zero otherwise.
+ */
+int seusers_file_test_init(void)
+{
+ int status = 0;
+
+ if (ps_pid == 0) {
+ /* Server code. */
+
+ /* Reset locks status. */
+ sh->u.ps_handle.socket_fd = 0;
+
+ /* Store setup. */
+ dbase_config_t *dconfig = semanage_seuser_dbase_local(sh);
+
+ if ((status =
+ dbase_file_init(
+ sh,
+ "fakesuffix",
+ &test_seuser_rtable,
+ NULL,
+ (dbase_file_t **)&dconfig->dbase)))
+ goto cleanup;
+
+ dconfig->dtable = &test_file_dtable;
+
+ }
+
+ /* Cleanup. */
+cleanup:
+ return status;
+}
+
+/* The suite cleanup function.
+ * Returns zero on success, non-zero otherwise.
+ */
+int seusers_file_test_cleanup(void)
+{
+ return 0;
+}
+
+/* Adds all the tests needed for this suite.
+*/
+int seusers_file_add_tests(CU_pSuite suite)
+{
+ CU_ErrorCode status;
+
+ if (NULL == CU_add_test(suite, "semanage_seuser_serialize_local", test_semanage_seuser_serialize_local))
+ goto cleanup;
+
+cleanup:
+ if (CUE_SUCCESS != (status = CU_get_error()))
+ CU_cleanup_registry();
+ return status;
+}
+
+/* Tests the semanage_seuser_serialize_local function in seusers_file.c
+ */
+void test_semanage_seuser_serialize_local(void) {
+ int status;
+
+ uint32_t message_type;
+ uint64_t data_length;
+ char *data = NULL;
+ char *ptr = NULL;
+ int timeout = 0;
+ uint32_t database_type = 0;
+
+ semanage_seuser_t **records = NULL;
+ unsigned int records_size;
+
+ dbase_config_t *dconfig = semanage_seuser_dbase_local(sh);
+ record_table_t *rtable = dconfig->dtable->get_rtable(dconfig);
+
+ int commit_number = 7;
+
+ if (ps_pid == 0) {
+ /* Server code. */
+
+ /* On caching the client will ask for the commit number. */
+ status = test_semanage_ps_handle_get_commit_number(sh, commit_number);
+ CU_ASSERT( status == STATUS_SUCCESS );
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Wait for message. */
+ if ((status = read_msg(sh, client_socket_fd, timeout, &message_type, &data_length, &data)))
+ goto cleanup;
+
+ CU_ASSERT( message_type == PS_GET_DATABASE );
+ if (message_type != PS_GET_DATABASE) {
+ status = -1;
+ goto cleanup;
+ }
+
+ /* Get and serialize the database. */
+ free(data);
+ data = NULL;
+
+ if ((status = semanage_seuser_serialize_local(sh, &data, &data_length)))
+ goto cleanup;
+
+ /* Send back the database. */
+ if ((status = write_msg(sh, client_socket_fd, PS_OK, data_length, data)))
+ goto cleanup;
+
+ /* On caching the client will ask for the commit number. */
+ status = test_semanage_ps_handle_get_commit_number(sh, commit_number);
+ CU_ASSERT( status == STATUS_SUCCESS );
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* On flushing the client will ask for the commit number. */
+ //FIXME: Why does the client ask for the commit number so many times here?
+ status = test_semanage_ps_handle_get_commit_number(sh, commit_number);
+ CU_ASSERT( status == STATUS_SUCCESS );
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ status = test_semanage_ps_handle_get_commit_number(sh, commit_number);
+ CU_ASSERT( status == STATUS_SUCCESS );
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Receive changed database. */
+ free(data);
+ data = NULL;
+
+ if ((status = read_msg(sh, client_socket_fd, timeout, &message_type, &data_length, &data)))
+ goto cleanup;
+
+ CU_ASSERT( message_type == PS_PUT_DATABASE );
+ if (message_type != PS_PUT_DATABASE) {
+ status = -1;
+ goto cleanup;
+ }
+
+ /* Say we got it ok. */
+ if ((status = write_msg(sh, client_socket_fd, PS_OK, 0, NULL)))
+ goto cleanup;
+
+ /* Unserialize the database type */
+ ptr = data;
+ if(semanage_dbase_ps_database_type_unserialize(sh, &ptr, &data_length, &database_type));
+ goto cleanup;
+
+ /* Unserialize the database. and don't move the data pointer.*/
+ if ((status = semanage_seuser_unserialize_local(sh, ptr, data_length)))
+ goto cleanup;
+
+ /* Gather the database records. */
+ status = dconfig->dtable->list(sh, dconfig, (record_t ***)&records, &records_size);
+ CU_ASSERT( status == 0 );
+ CU_ASSERT( records != NULL );
+ CU_ASSERT( records_size == 3 );
+
+ /* Verify data. */
+ char *name = (char *)semanage_seuser_get_name(records[0]);
+ char *sename = (char *)semanage_seuser_get_sename(records[0]);
+
+ CU_ASSERT( strcmp(name, "testname") == 0 );
+ CU_ASSERT( strcmp(sename, "testsename") == 0 );
+
+ name = (char *)semanage_seuser_get_name(records[1]);
+ sename = (char *)semanage_seuser_get_sename(records[1]);
+
+ CU_ASSERT( strcmp(name, "testname2") == 0 );
+ CU_ASSERT( strcmp(sename, "testsename2") == 0 );
+
+ name = (char *)semanage_seuser_get_name(records[2]);
+ sename = (char *)semanage_seuser_get_sename(records[2]);
+
+ CU_ASSERT( strcmp(name, "testname3") == 0 );
+ CU_ASSERT( strcmp(sename, "testsename3") == 0 );
+ }
+
+ if (ps_pid > 0) {
+ /* Client code. */
+
+ /* Cache database.
+ * This sends a message to the server requesting the database.
+ * The server serializes the database and sends it to us (the client).
+ * Internally the database is unserialized and loaded.
+ */
+ status = dconfig->dtable->cache(sh, dconfig);
+ CU_ASSERT( status == 0 );
+
+ /* Gather the database records. */
+ status = dconfig->dtable->list(sh, dconfig, (record_t ***)&records, &records_size);
+ CU_ASSERT( status == 0 );
+ CU_ASSERT( records != NULL );
+ CU_ASSERT( records_size == 2 );
+
+ /* Verify data was sent correctly. */
+ char *name = (char *)semanage_seuser_get_name(records[0]);
+ char *sename = (char *)semanage_seuser_get_sename(records[0]);
+
+ CU_ASSERT( strcmp(name, "testname") == 0 );
+ CU_ASSERT( strcmp(sename, "testsename") == 0 );
+
+ name = (char *)semanage_seuser_get_name(records[1]);
+ sename = (char *)semanage_seuser_get_sename(records[1]);
+
+ CU_ASSERT( strcmp(name, "testname2") == 0 );
+ CU_ASSERT( strcmp(sename, "testsename2") == 0 );
+
+ /* Add some test entries to the list. */
+ record_t *seuser = NULL;
+ record_key_t *seuserkey = NULL;
+
+ /* Create record. */
+ status = rtable->create(sh, &seuser);
+ if (status) goto cleanup;
+
+ /* Populate record. */
+ status = semanage_seuser_set_name(sh, (semanage_seuser_t *)seuser, "testname3");
+ if (status) goto cleanup;
+ status = semanage_seuser_set_sename(sh, (semanage_seuser_t *)seuser, "testsename3");
+ if (status) goto cleanup;
+
+ status = rtable->key_extract(sh, seuser, &seuserkey);
+ if (status) goto cleanup;
+
+ /* Add record. */
+ status = dconfig->dtable->add(
+ sh,
+ dconfig,
+ seuserkey,
+ seuser);
+ if (status) goto cleanup;
+
+ /* Cleanup. */
+ rtable->free(seuser);
+ rtable->key_free(seuserkey);
+
+ /* Flush database.
+ * This sends a message to the server to replace its database
+ * with the one we are sending. Internally the flush serializes
+ * the database and sends it. The server then unserializes it,
+ * clears its old copy, and replaces it with the new one.
+ */
+ status = dconfig->dtable->flush(sh, dconfig);
+ CU_ASSERT( status == 0 );
+ }
+
+ /* Cleanup. */
+cleanup:
+ if (records != NULL) {
+ unsigned int i;
+ for (i = 0; i < records_size; i++) {
+ if (!records[i])
+ break;
+ rtable->free((record_t *)records[i]);
+ }
+ }
+
+ free(records);
+ free(data);
+
+ CU_ASSERT( status == 0 );
+ if (status != 0) {
+ printf("\n\nReceived error code in %s: %d | %s\n", (ps_pid == 0) ? "server" : "client", status, strerror(status));
+ }
+}
+
Index: selinux-pms-support/libsemanage/tests/test_seusers_file.h
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/tests/test_seusers_file.h
@@ -0,0 +1,32 @@
+/* Authors: Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __TEST_SEUSERS_FILE_H__
+#define __TEST_SEUSERS_FILE_H__
+
+#include <CUnit/Basic.h>
+
+int seusers_file_test_init(void);
+int seusers_file_test_cleanup(void);
+int seusers_file_add_tests(CU_pSuite suite);
+
+void test_semanage_seuser_serialize_local(void);
+
+#endif
Index: selinux-pms-support/libsemanage/tests/test_seusers_policy.c
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/tests/test_seusers_policy.c
@@ -0,0 +1,354 @@
+/* Authors: Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* The purpose of this file is to provide unit tests of the functions in:
+ *
+ * libsemanage/src/seusers_policy.c
+ *
+ */
+
+#include "globals.h"
+#include "utilities.h"
+#include "test_seusers_policy.h"
+
+#include <libgen.h>
+#include <limits.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <CUnit/Basic.h>
+
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <selinux/selinux.h>
+
+#include "debug.h"
+#include "byteswap.h"
+#include "handle.h"
+#include "modules.h"
+#include "policy.h"
+#include "seusers_policy.h"
+#include "messages_internal.h"
+#include "semanage_store.h"
+#include "database_policydb.h"
+#include "user_internal.h"
+#include "port_internal.h"
+#include "seuser_internal.h"
+#include "iface_internal.h"
+#include "boolean_internal.h"
+#include "fcontext_internal.h"
+#include "node_internal.h"
+
+#include "database_llist.h"
+
+/* Server table setup. */
+
+/* Record functions. */
+
+static record_table_t test_seuser_rtable = {
+ .create = (create_f)semanage_seuser_create,
+ .key_extract = (key_extract_f)semanage_seuser_key_extract,
+ .key_free = (key_free_f)semanage_seuser_key_free,
+ .clone = (clone_f)semanage_seuser_clone,
+ .compare = (compare_f)semanage_seuser_compare,
+ .compare2 = (compare2_f)semanage_seuser_compare2,
+ .compare2_qsort = NULL,
+ .free = (free_f)semanage_seuser_free,
+ .serialize = (serialize_f)semanage_seuser_serialize,
+ .unserialize = (unserialize_f)semanage_seuser_unserialize,
+};
+
+/* Table functions. */
+
+/* Test cache function. */
+static int test_dbase_policydb_cache(
+ semanage_handle_t *handle,
+ dbase_config_t *dconfig)
+{
+ int status = 0;
+
+ /* Add some test entries to the list. */
+ record_t *seuser = NULL;
+ record_key_t *seuserkey = NULL;
+
+ record_table_t *rtable = dconfig->dtable->get_rtable(dconfig);
+
+ /* Create record. */
+ status = rtable->create(sh, &seuser);
+ if (status) goto cleanup;
+
+ /* Populate record. */
+ status = semanage_seuser_set_name(sh, (semanage_seuser_t *)seuser, "testname");
+ if (status) goto cleanup;
+ status = semanage_seuser_set_sename(sh, (semanage_seuser_t *)seuser, "testsename");
+ if (status) goto cleanup;
+
+ status = rtable->key_extract(sh, seuser, &seuserkey);
+ if (status) goto cleanup;
+
+ /* Add record. */
+ status = dconfig->dtable->add(
+ sh,
+ dconfig,
+ seuserkey,
+ seuser);
+ if (status) goto cleanup;
+
+ /* Cleanup. */
+ rtable->free(seuser);
+ seuser = NULL;
+ rtable->key_free(seuserkey);
+ seuserkey = NULL;
+
+ /* Create record. */
+ status = rtable->create(sh, &seuser);
+ if (status) goto cleanup;
+
+ /* Populate record. */
+ status = semanage_seuser_set_name(sh, (semanage_seuser_t *)seuser, "testname2");
+ if (status) goto cleanup;
+ status = semanage_seuser_set_sename(sh, (semanage_seuser_t *)seuser, "testsename2");
+ if (status) goto cleanup;
+
+ status = rtable->key_extract(sh, seuser, &seuserkey);
+ if (status) goto cleanup;
+
+ /* Add record. */
+ status = dconfig->dtable->add(
+ sh,
+ dconfig,
+ seuserkey,
+ seuser);
+ if (status) goto cleanup;
+
+ /* Cleanup. */
+cleanup:
+ rtable->free(seuser);
+ rtable->key_free(seuserkey);
+
+ CU_ASSERT( status == 0 );
+ return status;
+}
+
+/* Database callback table. */
+static dbase_table_t test_policydb_dtable = {
+
+ /* Cache/Transactions */
+ .cache = test_dbase_policydb_cache,
+ .drop_cache = (void *)dbase_llist_drop_cache,
+ .flush = NULL,
+ .is_modified = (void *)dbase_llist_is_modified,
+
+ /* Database API */
+ .iterate = (void *)dbase_llist_iterate,
+ .exists = (void *)dbase_llist_exists,
+ .list = (void *)dbase_llist_list,
+ .add = (void *)dbase_llist_add,
+ .set = (void *)dbase_llist_set,
+ .del = (void *)dbase_llist_del,
+ .clear = (void *)dbase_llist_clear,
+ .modify = (void *)dbase_llist_modify,
+ .query = (void *)dbase_llist_query,
+ .count = (void *)dbase_llist_count,
+
+ /* Polymorphism */
+ .get_rtable = (void *)dbase_llist_get_rtable
+};
+
+/* The suite initialization function.
+ * Returns zero on success, non-zero otherwise.
+ */
+int seusers_policy_test_init(void)
+{
+ int status = 0;
+
+ if (ps_pid == 0) {
+ /* Server code. */
+
+ /* Reset locks status. */
+ sh->u.ps_handle.socket_fd = 0;
+
+ /* Store setup. */
+ dbase_config_t *dconfig = semanage_seuser_dbase_policy(sh);
+
+ if ((status =
+ dbase_policydb_init(
+ sh,
+ "fakesuffix",
+ &test_seuser_rtable,
+ NULL,
+ (dbase_policydb_t **)&dconfig->dbase)))
+ goto cleanup;
+
+ dconfig->dtable = &test_policydb_dtable;
+
+ }
+
+ /* Cleanup. */
+cleanup:
+ return status;
+}
+
+/* The suite cleanup function.
+ * Returns zero on success, non-zero otherwise.
+ */
+int seusers_policy_test_cleanup(void)
+{
+ return 0;
+}
+
+/* Adds all the tests needed for this suite.
+*/
+int seusers_policy_add_tests(CU_pSuite suite)
+{
+ CU_ErrorCode status;
+
+ if (NULL == CU_add_test(suite, "semanage_seuser_serialize_policy", test_semanage_seuser_serialize_policy))
+ goto cleanup;
+
+cleanup:
+ if (CUE_SUCCESS != (status = CU_get_error()))
+ CU_cleanup_registry();
+ return status;
+}
+
+/* Tests the semanage_seuser_serialize_policy function in seusers_policy.c
+ */
+void test_semanage_seuser_serialize_policy(void) {
+ int status;
+
+ uint32_t message_type;
+ uint64_t data_length;
+ char *data = NULL;
+ int timeout = 0;
+
+ semanage_seuser_t **records = NULL;
+ unsigned int records_size;
+
+ dbase_config_t *dconfig = semanage_seuser_dbase_policy(sh);
+ record_table_t *rtable = dconfig->dtable->get_rtable(dconfig);
+
+ int commit_number = 7;
+
+ if (ps_pid == 0) {
+ /* Server code. */
+
+ /* On caching the client will ask for the commit number. */
+ status = test_semanage_ps_handle_get_commit_number(sh, commit_number);
+ CU_ASSERT( status == STATUS_SUCCESS );
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Wait for message. */
+ if ((status = read_msg(sh, client_socket_fd, timeout, &message_type, &data_length, &data)))
+ goto cleanup;
+
+ CU_ASSERT( message_type == PS_GET_DATABASE );
+ if (message_type != PS_GET_DATABASE) {
+ status = -1;
+ goto cleanup;
+ }
+
+ /* Get and serialize the database. */
+ free(data);
+ data = NULL;
+
+ if ((status = semanage_seuser_serialize_policy(sh, &data, &data_length)))
+ goto cleanup;
+
+ /* Send back the database. */
+ if ((status = write_msg(sh, client_socket_fd, PS_OK, data_length, data)))
+ goto cleanup;
+
+ /* On caching the client will ask for the commit number. */
+ status = test_semanage_ps_handle_get_commit_number(sh, commit_number);
+ CU_ASSERT( status == STATUS_SUCCESS );
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ }
+
+ if (ps_pid > 0) {
+ /* Client code. */
+
+ /* Cache database.
+ * This sends a message to the server requesting the database.
+ * The server serializes the database and sends it to us (the client).
+ * Internally the database is unserialized and loaded.
+ */
+ status = dconfig->dtable->cache(sh, dconfig);
+ CU_ASSERT( status == 0 );
+
+ /* Gather the database records. */
+ status = dconfig->dtable->list(sh, dconfig, (record_t ***)&records, &records_size);
+ CU_ASSERT( status == 0 );
+ CU_ASSERT( records != NULL );
+ CU_ASSERT( records_size == 2 );
+
+ /* Verify data was sent correctly. */
+ char *name = (char *)semanage_seuser_get_name(records[0]);
+ char *sename = (char *)semanage_seuser_get_sename(records[0]);
+
+ CU_ASSERT( strcmp(name, "testname") == 0 );
+ CU_ASSERT( strcmp(sename, "testsename") == 0 );
+
+ name = (char *)semanage_seuser_get_name(records[1]);
+ sename = (char *)semanage_seuser_get_sename(records[1]);
+
+ CU_ASSERT( strcmp(name, "testname2") == 0 );
+ CU_ASSERT( strcmp(sename, "testsename2") == 0 );
+ }
+
+ /* Cleanup. */
+cleanup:
+ if (records != NULL) {
+ unsigned int i;
+ for (i = 0; i < records_size; i++) {
+ if (!records[i])
+ break;
+ rtable->free((record_t *)records[i]);
+ }
+ }
+
+ free(records);
+ free(data);
+
+ CU_ASSERT( status == 0 );
+ if (status != 0) {
+ printf("\n\nReceived error code in %s: %d | %s\n", (ps_pid == 0) ? "server" : "client", status, strerror(status));
+ }
+}
+
Index: selinux-pms-support/libsemanage/tests/test_seusers_policy.h
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/tests/test_seusers_policy.h
@@ -0,0 +1,32 @@
+/* Authors: Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __TEST_SEUSERS_POLICY_H__
+#define __TEST_SEUSERS_POLICY_H__
+
+#include <CUnit/Basic.h>
+
+int seusers_policy_test_init(void);
+int seusers_policy_test_cleanup(void);
+int seusers_policy_add_tests(CU_pSuite suite);
+
+void test_semanage_seuser_serialize_policy(void);
+
+#endif
--
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH 33/33] libsemanage: user serialization tests
2007-04-23 21:34 [PATCH 00/33] libsemanage/libsepol object serialization and ps-api jbrindle
` (31 preceding siblings ...)
2007-04-23 21:35 ` [PATCH 32/33] libsemanage: seuser " jbrindle
@ 2007-04-23 21:35 ` jbrindle
2007-04-24 19:48 ` [PATCH 00/33] libsemanage/libsepol object serialization and ps-api Joshua Brindle
2007-04-24 23:12 ` James Antill
34 siblings, 0 replies; 58+ messages in thread
From: jbrindle @ 2007-04-23 21:35 UTC (permalink / raw)
To: selinux
---
libsemanage/tests/libsemanage-tests.c | 6
libsemanage/tests/test_users_file.c | 534 ++++++++++++++++++++++++++++++++++
libsemanage/tests/test_users_file.h | 32 ++
libsemanage/tests/test_users_policy.c | 391 ++++++++++++++++++++++++
libsemanage/tests/test_users_policy.h | 32 ++
5 files changed, 995 insertions(+)
Index: selinux-pms-support/libsemanage/tests/libsemanage-tests.c
===================================================================
--- selinux-pms-support.orig/libsemanage/tests/libsemanage-tests.c
+++ selinux-pms-support/libsemanage/tests/libsemanage-tests.c
@@ -54,6 +54,9 @@
#include "test_seusers_file.h"
#include "test_seusers_policy.h"
+#include "test_users_file.h"
+#include "test_users_policy.h"
+
#include <CUnit/Basic.h>
#include <CUnit/Console.h>
#include <CUnit/TestDB.h>
@@ -128,6 +131,9 @@ static int do_tests(int interactive, int
DECLARE_SUITE(seusers_file);
DECLARE_SUITE(seusers_policy);
+ DECLARE_SUITE(users_file);
+ DECLARE_SUITE(users_policy);
+
/* The ps_api_disconnect test 'unforks'. */
DECLARE_SUITE(ps_api_disconnect);
Index: selinux-pms-support/libsemanage/tests/test_users_file.c
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/tests/test_users_file.c
@@ -0,0 +1,534 @@
+/* Authors: Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* The purpose of this file is to provide unit tests of the functions in:
+ *
+ * libsemanage/src/users_file.c
+ *
+ */
+
+#include "globals.h"
+#include "utilities.h"
+#include "test_users_file.h"
+
+#include <libgen.h>
+#include <limits.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <CUnit/Basic.h>
+
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <selinux/selinux.h>
+
+#include "debug.h"
+#include "byteswap.h"
+#include "handle.h"
+#include "modules.h"
+#include "policy.h"
+#include "users_local.h"
+#include "messages_internal.h"
+#include "semanage_store.h"
+#include "database_file.h"
+#include "user_internal.h"
+#include "port_internal.h"
+#include "seuser_internal.h"
+#include "iface_internal.h"
+#include "boolean_internal.h"
+#include "fcontext_internal.h"
+#include "node_internal.h"
+
+#include "database_llist.h"
+
+/* Server table setup. */
+
+/* Record functions. */
+
+static record_table_t test_user_rtable = {
+ .create = (create_f)semanage_user_create,
+ .key_extract = (key_extract_f)semanage_user_key_extract,
+ .key_free = (key_free_f)semanage_user_key_free,
+ .clone = (clone_f)semanage_user_clone,
+ .compare = (compare_f)semanage_user_compare,
+ .compare2 = (compare2_f)semanage_user_compare2,
+ .compare2_qsort = NULL,
+ .free = (free_f)semanage_user_free,
+ .serialize = (serialize_f)semanage_user_serialize,
+ .unserialize = (unserialize_f)semanage_user_unserialize,
+};
+
+/* Table functions. */
+
+/* Test cache function. */
+static int test_dbase_file_cache(
+ semanage_handle_t *handle,
+ dbase_config_t *dconfig)
+{
+ int status = 0;
+
+ /* Add some test entries to the list. */
+ record_t *user = NULL;
+ record_key_t *userkey = NULL;
+
+ record_table_t *rtable = dconfig->dtable->get_rtable(dconfig);
+
+ /* Create record. */
+ status = rtable->create(sh, &user);
+ if (status) goto cleanup;
+
+ /* Populate record. */
+ char *roles[] = { "testrole", "testrole2" };
+ int roles_size = 2;
+
+ status = semanage_user_set_name(sh, (semanage_user_t *)user, "testname");
+ if (status) goto cleanup;
+ status = semanage_user_set_roles(sh, (semanage_user_t *)user, (const char **)roles, roles_size);
+ if (status) goto cleanup;
+ status = semanage_user_set_prefix(sh, (semanage_user_t *)user, "testprefix");
+ if (status) goto cleanup;
+
+ status = rtable->key_extract(sh, user, &userkey);
+ if (status) goto cleanup;
+
+ /* Add record. */
+ status = dconfig->dtable->add(
+ sh,
+ dconfig,
+ userkey,
+ user);
+ if (status) goto cleanup;
+
+ /* Cleanup. */
+ rtable->free(user);
+ user = NULL;
+ rtable->key_free(userkey);
+ userkey = NULL;
+
+ /* Create record. */
+ status = rtable->create(sh, &user);
+ if (status) goto cleanup;
+
+ /* Populate record. */
+ roles[0] = "testrole3";
+ roles[1] = "testrole4";
+ roles_size = 2;
+
+ status = semanage_user_set_name(sh, (semanage_user_t *)user, "testname2");
+ if (status) goto cleanup;
+ status = semanage_user_set_roles(sh, (semanage_user_t *)user, (const char **)roles, roles_size);
+ if (status) goto cleanup;
+ status = semanage_user_set_prefix(sh, (semanage_user_t *)user, "testprefix2");
+ if (status) goto cleanup;
+
+ status = rtable->key_extract(sh, user, &userkey);
+ if (status) goto cleanup;
+
+ /* Add record. */
+ status = dconfig->dtable->add(
+ sh,
+ dconfig,
+ userkey,
+ user);
+ if (status) goto cleanup;
+
+ /* Cleanup. */
+cleanup:
+ rtable->free(user);
+ rtable->key_free(userkey);
+
+ CU_ASSERT( status == 0 );
+ return status;
+}
+
+/* Database callback table. */
+static dbase_table_t test_file_dtable = {
+
+ /* Cache/Transactions */
+ .cache = test_dbase_file_cache,
+ .drop_cache = (void *)dbase_llist_drop_cache,
+ .flush = NULL,
+ .is_modified = (void *)dbase_llist_is_modified,
+
+ /* Database API */
+ .iterate = (void *)dbase_llist_iterate,
+ .exists = (void *)dbase_llist_exists,
+ .list = (void *)dbase_llist_list,
+ .add = (void *)dbase_llist_add,
+ .set = (void *)dbase_llist_set,
+ .del = (void *)dbase_llist_del,
+ .clear = (void *)dbase_llist_clear,
+ .modify = (void *)dbase_llist_modify,
+ .query = (void *)dbase_llist_query,
+ .count = (void *)dbase_llist_count,
+
+ /* Polymorphism */
+ .get_rtable = (void *)dbase_llist_get_rtable
+};
+
+/* The suite initialization function.
+ * Returns zero on success, non-zero otherwise.
+ */
+int users_file_test_init(void)
+{
+ int status = 0;
+
+ if (ps_pid == 0) {
+ /* Server code. */
+
+ /* Reset locks status. */
+ sh->u.ps_handle.socket_fd = 0;
+
+ /* Store setup. */
+ dbase_config_t *dconfig = semanage_user_dbase_local(sh);
+
+ if ((status =
+ dbase_file_init(
+ sh,
+ "fakesuffix",
+ &test_user_rtable,
+ NULL,
+ (dbase_file_t **)&dconfig->dbase)))
+ goto cleanup;
+
+ dconfig->dtable = &test_file_dtable;
+
+ }
+
+ /* Cleanup. */
+cleanup:
+ return status;
+}
+
+/* The suite cleanup function.
+ * Returns zero on success, non-zero otherwise.
+ */
+int users_file_test_cleanup(void)
+{
+ return 0;
+}
+
+/* Adds all the tests needed for this suite.
+*/
+int users_file_add_tests(CU_pSuite suite)
+{
+ CU_ErrorCode status;
+
+ if (NULL == CU_add_test(suite, "semanage_user_serialize_local", test_semanage_user_serialize_local))
+ goto cleanup;
+
+cleanup:
+ if (CUE_SUCCESS != (status = CU_get_error()))
+ CU_cleanup_registry();
+ return status;
+}
+
+/* Tests the semanage_user_serialize_local function in users_file.c
+ */
+void test_semanage_user_serialize_local(void) {
+ int status;
+
+ uint32_t message_type;
+ uint64_t data_length;
+ char *data = NULL;
+ char *ptr = NULL;
+ int timeout = 0;
+ uint32_t database_type = 0;
+
+ semanage_user_t **records = NULL;
+ unsigned int records_size;
+
+ dbase_config_t *dconfig = semanage_user_dbase_local(sh);
+ record_table_t *rtable = dconfig->dtable->get_rtable(dconfig);
+
+ char **roles = NULL;
+ unsigned int roles_size;
+
+ int commit_number = 7;
+
+ if (ps_pid == 0) {
+ /* Server code. */
+
+ /* On caching the client will ask for the commit number. */
+ status = test_semanage_ps_handle_get_commit_number(sh, commit_number);
+ CU_ASSERT( status == STATUS_SUCCESS );
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Wait for message. */
+ if ((status = read_msg(sh, client_socket_fd, timeout, &message_type, &data_length, &data)))
+ goto cleanup;
+
+ CU_ASSERT( message_type == PS_GET_DATABASE );
+ if (message_type != PS_GET_DATABASE) {
+ status = -1;
+ goto cleanup;
+ }
+
+ /* Get and serialize the database. */
+ free(data);
+ data = NULL;
+
+ if ((status = semanage_user_serialize_local(sh, &data, &data_length)))
+ goto cleanup;
+
+ /* Send back the database. */
+ if ((status = write_msg(sh, client_socket_fd, PS_OK, data_length, data)))
+ goto cleanup;
+
+ /* On caching the client will ask for the commit number. */
+ status = test_semanage_ps_handle_get_commit_number(sh, commit_number);
+ CU_ASSERT( status == STATUS_SUCCESS );
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* On flushing the client will ask for the commit number. */
+ //FIXME: Why does the client ask for the commit number so many times here?
+ status = test_semanage_ps_handle_get_commit_number(sh, commit_number);
+ CU_ASSERT( status == STATUS_SUCCESS );
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ status = test_semanage_ps_handle_get_commit_number(sh, commit_number);
+ CU_ASSERT( status == STATUS_SUCCESS );
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Receive changed database. */
+ free(data);
+ data = NULL;
+
+ if ((status = read_msg(sh, client_socket_fd, timeout, &message_type, &data_length, &data)))
+ goto cleanup;
+
+ CU_ASSERT( message_type == PS_PUT_DATABASE );
+ if (message_type != PS_PUT_DATABASE) {
+ status = -1;
+ goto cleanup;
+ }
+
+ /* Say we got it ok. */
+ if ((status = write_msg(sh, client_socket_fd, PS_OK, 0, NULL)))
+ goto cleanup;
+
+ /* Unserialize the database type */
+ ptr = data;
+ if(semanage_dbase_ps_database_type_unserialize(sh, &ptr, &data_length, &database_type));
+ goto cleanup;
+
+ /* Unserialize the database. and don't move the data pointer.*/
+ if ((status = semanage_user_unserialize_local(sh, ptr, data_length)))
+ goto cleanup;
+
+ /* Gather the database records. */
+ status = dconfig->dtable->list(sh, dconfig, (record_t ***)&records, &records_size);
+ CU_ASSERT( status == 0 );
+ CU_ASSERT( records != NULL );
+ CU_ASSERT( records_size == 3 );
+
+ /* Verify data. */
+ char *name = (char *)semanage_user_get_name(records[0]);
+ char *mlslevel = (char *)semanage_user_get_mlslevel(records[0]);
+ char *mlsrange = (char *)semanage_user_get_mlsrange(records[0]);
+ status = semanage_user_get_roles(sh, records[0], (const char ***)&roles, &roles_size);
+ CU_ASSERT( status == 0 );
+ char *prefix = (char *)semanage_user_get_prefix(records[0]);
+
+ CU_ASSERT( strcmp(name, "testname") == 0 );
+ CU_ASSERT( mlslevel == NULL );
+ CU_ASSERT( mlsrange == NULL );
+ CU_ASSERT( roles_size == 2 );
+ CU_ASSERT( strcmp(roles[0], "testrole") == 0 );
+ CU_ASSERT( strcmp(roles[1], "testrole2") == 0 );
+ CU_ASSERT( strcmp(prefix, "testprefix") == 0 );
+
+ /* Cleanup. */
+ free(roles);
+ roles = NULL;
+
+ name = (char *)semanage_user_get_name(records[1]);
+ mlslevel = (char *)semanage_user_get_mlslevel(records[1]);
+ mlsrange = (char *)semanage_user_get_mlsrange(records[1]);
+ status = semanage_user_get_roles(sh, records[1], (const char ***)&roles, &roles_size);
+ CU_ASSERT( status == 0 );
+ prefix = (char *)semanage_user_get_prefix(records[1]);
+
+ CU_ASSERT( strcmp(name, "testname2") == 0 );
+ CU_ASSERT( mlslevel == NULL );
+ CU_ASSERT( mlsrange == NULL );
+ CU_ASSERT( roles_size == 2 );
+ CU_ASSERT( strcmp(roles[0], "testrole3") == 0 );
+ CU_ASSERT( strcmp(roles[1], "testrole4") == 0 );
+ CU_ASSERT( strcmp(prefix, "testprefix2") == 0 );
+
+ /* Cleanup. */
+ free(roles);
+ roles = NULL;
+
+ name = (char *)semanage_user_get_name(records[2]);
+ mlslevel = (char *)semanage_user_get_mlslevel(records[2]);
+ mlsrange = (char *)semanage_user_get_mlsrange(records[2]);
+ status = semanage_user_get_roles(sh, records[2], (const char ***)&roles, &roles_size);
+ CU_ASSERT( status == 0 );
+ prefix = (char *)semanage_user_get_prefix(records[2]);
+
+ CU_ASSERT( strcmp(name, "testname3") == 0 );
+ CU_ASSERT( mlslevel == NULL );
+ CU_ASSERT( mlsrange == NULL );
+ CU_ASSERT( roles_size == 2 );
+ CU_ASSERT( strcmp(roles[0], "testrole5") == 0 );
+ CU_ASSERT( strcmp(roles[1], "testrole6") == 0 );
+ CU_ASSERT( strcmp(prefix, "testprefix3") == 0 );
+ }
+
+ if (ps_pid > 0) {
+ /* Client code. */
+
+ /* Cache database.
+ * This sends a message to the server requesting the database.
+ * The server serializes the database and sends it to us (the client).
+ * Internally the database is unserialized and loaded.
+ */
+ status = dconfig->dtable->cache(sh, dconfig);
+ CU_ASSERT( status == 0 );
+
+ /* Gather the database records. */
+ status = dconfig->dtable->list(sh, dconfig, (record_t ***)&records, &records_size);
+ CU_ASSERT( status == 0 );
+ CU_ASSERT( records != NULL );
+ CU_ASSERT( records_size == 2 );
+
+ /* Verify data was sent correctly. */
+ char *name = (char *)semanage_user_get_name(records[0]);
+ char *mlslevel = (char *)semanage_user_get_mlslevel(records[0]);
+ char *mlsrange = (char *)semanage_user_get_mlsrange(records[0]);
+ status = semanage_user_get_roles(sh, records[0], (const char ***)&roles, &roles_size);
+ CU_ASSERT( status == 0 );
+ char *prefix = (char *)semanage_user_get_prefix(records[0]);
+
+ CU_ASSERT( strcmp(name, "testname") == 0 );
+ CU_ASSERT( mlslevel == NULL );
+ CU_ASSERT( mlsrange == NULL );
+ CU_ASSERT( roles_size == 2 );
+ CU_ASSERT( strcmp(roles[0], "testrole") == 0 );
+ CU_ASSERT( strcmp(roles[1], "testrole2") == 0 );
+ CU_ASSERT( strcmp(prefix, "testprefix") == 0 );
+
+ /* Cleanup. */
+ free(roles);
+ roles = NULL;
+
+ name = (char *)semanage_user_get_name(records[1]);
+ mlslevel = (char *)semanage_user_get_mlslevel(records[1]);
+ mlsrange = (char *)semanage_user_get_mlsrange(records[1]);
+ status = semanage_user_get_roles(sh, records[1], (const char ***)&roles, &roles_size);
+ CU_ASSERT( status == 0 );
+ prefix = (char *)semanage_user_get_prefix(records[1]);
+
+ CU_ASSERT( strcmp(name, "testname2") == 0 );
+ CU_ASSERT( mlslevel == NULL );
+ CU_ASSERT( mlsrange == NULL );
+ CU_ASSERT( roles_size == 2 );
+ CU_ASSERT( strcmp(roles[0], "testrole3") == 0 );
+ CU_ASSERT( strcmp(roles[1], "testrole4") == 0 );
+ CU_ASSERT( strcmp(prefix, "testprefix2") == 0 );
+
+ /* Add some test entries to the list. */
+ record_t *user = NULL;
+ record_key_t *userkey = NULL;
+
+ /* Create record. */
+ status = rtable->create(sh, &user);
+ if (status) goto cleanup;
+
+ /* Populate record. */
+ roles[0] = "testrole5";
+ roles[1] = "testrole6";
+ roles_size = 2;
+
+ status = semanage_user_set_name(sh, (semanage_user_t *)user, "testname3");
+ if (status) goto cleanup;
+ status = semanage_user_set_roles(sh, (semanage_user_t *)user, (const char **)roles, roles_size);
+ if (status) goto cleanup;
+ status = semanage_user_set_prefix(sh, (semanage_user_t *)user, "testprefix3");
+ if (status) goto cleanup;
+
+ status = rtable->key_extract(sh, user, &userkey);
+ if (status) goto cleanup;
+
+ /* Add record. */
+ status = dconfig->dtable->add(
+ sh,
+ dconfig,
+ userkey,
+ user);
+ if (status) goto cleanup;
+
+ /* Cleanup. */
+ rtable->free(user);
+ rtable->key_free(userkey);
+
+ /* Flush database.
+ * This sends a message to the server to replace its database
+ * with the one we are sending. Internally the flush serializes
+ * the database and sends it. The server then unserializes it,
+ * clears its old copy, and replaces it with the new one.
+ */
+ status = dconfig->dtable->flush(sh, dconfig);
+ CU_ASSERT( status == 0 );
+ }
+
+ /* Cleanup. */
+cleanup:
+ if (records != NULL) {
+ unsigned int i;
+ for (i = 0; i < records_size; i++) {
+ if (!records[i])
+ break;
+ rtable->free((record_t *)records[i]);
+ }
+ }
+
+ free(records);
+ free(data);
+ free(roles);
+
+ CU_ASSERT( status == 0 );
+ if (status != 0) {
+ printf("\n\nReceived error code in %s: %d | %s\n", (ps_pid == 0) ? "server" : "client", status, strerror(status));
+ }
+}
+
Index: selinux-pms-support/libsemanage/tests/test_users_file.h
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/tests/test_users_file.h
@@ -0,0 +1,32 @@
+/* Authors: Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __TEST_USERS_FILE_H__
+#define __TEST_USERS_FILE_H__
+
+#include <CUnit/Basic.h>
+
+int users_file_test_init(void);
+int users_file_test_cleanup(void);
+int users_file_add_tests(CU_pSuite suite);
+
+void test_semanage_user_serialize_local(void);
+
+#endif
Index: selinux-pms-support/libsemanage/tests/test_users_policy.c
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/tests/test_users_policy.c
@@ -0,0 +1,391 @@
+/* Authors: Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* The purpose of this file is to provide unit tests of the functions in:
+ *
+ * libsemanage/src/users_policy.c
+ *
+ */
+
+#include "globals.h"
+#include "utilities.h"
+#include "test_users_policy.h"
+
+#include <libgen.h>
+#include <limits.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <CUnit/Basic.h>
+
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <selinux/selinux.h>
+
+#include "debug.h"
+#include "byteswap.h"
+#include "handle.h"
+#include "modules.h"
+#include "policy.h"
+#include "users_policy.h"
+#include "messages_internal.h"
+#include "semanage_store.h"
+#include "database_policydb.h"
+#include "user_internal.h"
+#include "port_internal.h"
+#include "seuser_internal.h"
+#include "iface_internal.h"
+#include "boolean_internal.h"
+#include "fcontext_internal.h"
+#include "node_internal.h"
+
+#include "database_llist.h"
+
+/* Server table setup. */
+
+/* Record functions. */
+
+static record_table_t test_user_rtable = {
+ .create = (create_f)semanage_user_create,
+ .key_extract = (key_extract_f)semanage_user_key_extract,
+ .key_free = (key_free_f)semanage_user_key_free,
+ .clone = (clone_f)semanage_user_clone,
+ .compare = (compare_f)semanage_user_compare,
+ .compare2 = (compare2_f)semanage_user_compare2,
+ .compare2_qsort = NULL,
+ .free = (free_f)semanage_user_free,
+ .serialize = (serialize_f)semanage_user_serialize,
+ .unserialize = (unserialize_f)semanage_user_unserialize,
+};
+
+/* Table functions. */
+
+/* Test cache function. */
+static int test_dbase_policydb_cache(
+ semanage_handle_t *handle,
+ dbase_config_t *dconfig)
+{
+ int status = 0;
+
+ /* Add some test entries to the list. */
+ record_t *user = NULL;
+ record_key_t *userkey = NULL;
+
+ record_table_t *rtable = dconfig->dtable->get_rtable(dconfig);
+
+ /* Create record. */
+ status = rtable->create(sh, &user);
+ if (status) goto cleanup;
+
+ /* Populate record. */
+ char *roles[] = { "testrole", "testrole2" };
+ int roles_size = 2;
+
+ status = semanage_user_set_name(sh, (semanage_user_t *)user, "testname");
+ if (status) goto cleanup;
+ status = semanage_user_set_roles(sh, (semanage_user_t *)user, (const char **)roles, roles_size);
+ if (status) goto cleanup;
+ status = semanage_user_set_prefix(sh, (semanage_user_t *)user, "testprefix");
+ if (status) goto cleanup;
+
+ status = rtable->key_extract(sh, user, &userkey);
+ if (status) goto cleanup;
+
+ /* Add record. */
+ status = dconfig->dtable->add(
+ sh,
+ dconfig,
+ userkey,
+ user);
+ if (status) goto cleanup;
+
+ /* Cleanup. */
+ rtable->free(user);
+ user = NULL;
+ rtable->key_free(userkey);
+ userkey = NULL;
+
+ /* Create record. */
+ status = rtable->create(sh, &user);
+ if (status) goto cleanup;
+
+ /* Populate record. */
+ roles[0] = "testrole3";
+ roles[1] = "testrole4";
+ roles_size = 2;
+
+ status = semanage_user_set_name(sh, (semanage_user_t *)user, "testname2");
+ if (status) goto cleanup;
+ status = semanage_user_set_roles(sh, (semanage_user_t *)user, (const char **)roles, roles_size);
+ if (status) goto cleanup;
+ status = semanage_user_set_prefix(sh, (semanage_user_t *)user, "testprefix2");
+ if (status) goto cleanup;
+
+ status = rtable->key_extract(sh, user, &userkey);
+ if (status) goto cleanup;
+
+ /* Add record. */
+ status = dconfig->dtable->add(
+ sh,
+ dconfig,
+ userkey,
+ user);
+ if (status) goto cleanup;
+
+ /* Cleanup. */
+cleanup:
+ rtable->free(user);
+ rtable->key_free(userkey);
+
+ CU_ASSERT( status == 0 );
+ return status;
+}
+
+/* Database callback table. */
+static dbase_table_t test_policydb_dtable = {
+
+ /* Cache/Transactions */
+ .cache = test_dbase_policydb_cache,
+ .drop_cache = (void *)dbase_llist_drop_cache,
+ .flush = NULL,
+ .is_modified = (void *)dbase_llist_is_modified,
+
+ /* Database API */
+ .iterate = (void *)dbase_llist_iterate,
+ .exists = (void *)dbase_llist_exists,
+ .list = (void *)dbase_llist_list,
+ .add = (void *)dbase_llist_add,
+ .set = (void *)dbase_llist_set,
+ .del = (void *)dbase_llist_del,
+ .clear = (void *)dbase_llist_clear,
+ .modify = (void *)dbase_llist_modify,
+ .query = (void *)dbase_llist_query,
+ .count = (void *)dbase_llist_count,
+
+ /* Polymorphism */
+ .get_rtable = (void *)dbase_llist_get_rtable
+};
+
+/* The suite initialization function.
+ * Returns zero on success, non-zero otherwise.
+ */
+int users_policy_test_init(void)
+{
+ int status = 0;
+
+ if (ps_pid == 0) {
+ /* Server code. */
+
+ /* Reset locks status. */
+ sh->u.ps_handle.socket_fd = 0;
+
+ /* Store setup. */
+ dbase_config_t *dconfig = semanage_user_dbase_policy(sh);
+
+ if ((status =
+ dbase_policydb_init(
+ sh,
+ "fakesuffix",
+ &test_user_rtable,
+ NULL,
+ (dbase_policydb_t **)&dconfig->dbase)))
+ goto cleanup;
+
+ dconfig->dtable = &test_policydb_dtable;
+
+ }
+
+ /* Cleanup. */
+cleanup:
+ return status;
+}
+
+/* The suite cleanup function.
+ * Returns zero on success, non-zero otherwise.
+ */
+int users_policy_test_cleanup(void)
+{
+ return 0;
+}
+
+/* Adds all the tests needed for this suite.
+*/
+int users_policy_add_tests(CU_pSuite suite)
+{
+ CU_ErrorCode status;
+
+ if (NULL == CU_add_test(suite, "semanage_user_serialize_policy", test_semanage_user_serialize_policy))
+ goto cleanup;
+
+cleanup:
+ if (CUE_SUCCESS != (status = CU_get_error()))
+ CU_cleanup_registry();
+ return status;
+}
+
+/* Tests the semanage_user_serialize_policy function in users_policy.c
+ */
+void test_semanage_user_serialize_policy(void) {
+ int status;
+
+ uint32_t message_type;
+ uint64_t data_length;
+ char *data = NULL;
+ int timeout = 0;
+
+ semanage_user_t **records = NULL;
+ unsigned int records_size;
+
+ dbase_config_t *dconfig = semanage_user_dbase_policy(sh);
+ record_table_t *rtable = dconfig->dtable->get_rtable(dconfig);
+
+ char **roles = NULL;
+ unsigned int roles_size;
+
+ int commit_number = 7;
+
+ if (ps_pid == 0) {
+ /* Server code. */
+
+ /* On caching the client will ask for the commit number. */
+ status = test_semanage_ps_handle_get_commit_number(sh, commit_number);
+ CU_ASSERT( status == STATUS_SUCCESS );
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ /* Wait for message. */
+ if ((status = read_msg(sh, client_socket_fd, timeout, &message_type, &data_length, &data)))
+ goto cleanup;
+
+ CU_ASSERT( message_type == PS_GET_DATABASE );
+ if (message_type != PS_GET_DATABASE) {
+ status = -1;
+ goto cleanup;
+ }
+
+ /* Get and serialize the database. */
+ free(data);
+ data = NULL;
+
+ if ((status = semanage_user_serialize_policy(sh, &data, &data_length)))
+ goto cleanup;
+
+ /* Send back the database. */
+ if ((status = write_msg(sh, client_socket_fd, PS_OK, data_length, data)))
+ goto cleanup;
+
+ /* On caching the client will ask for the commit number. */
+ status = test_semanage_ps_handle_get_commit_number(sh, commit_number);
+ CU_ASSERT( status == STATUS_SUCCESS );
+ if (status != STATUS_SUCCESS)
+ goto cleanup;
+
+ }
+
+ if (ps_pid > 0) {
+ /* Client code. */
+
+ /* Cache database.
+ * This sends a message to the server requesting the database.
+ * The server serializes the database and sends it to us (the client).
+ * Internally the database is unserialized and loaded.
+ */
+ status = dconfig->dtable->cache(sh, dconfig);
+ CU_ASSERT( status == 0 );
+
+ /* Gather the database records. */
+ status = dconfig->dtable->list(sh, dconfig, (record_t ***)&records, &records_size);
+ CU_ASSERT( status == 0 );
+ CU_ASSERT( records != NULL );
+ CU_ASSERT( records_size == 2 );
+
+ /* Verify data was sent correctly. */
+ char *name = (char *)semanage_user_get_name(records[0]);
+ char *mlslevel = (char *)semanage_user_get_mlslevel(records[0]);
+ char *mlsrange = (char *)semanage_user_get_mlsrange(records[0]);
+ status = semanage_user_get_roles(sh, records[0], (const char ***)&roles, &roles_size);
+ CU_ASSERT( status == 0 );
+ char *prefix = (char *)semanage_user_get_prefix(records[0]);
+
+ CU_ASSERT( strcmp(name, "testname") == 0 );
+ CU_ASSERT( mlslevel == NULL );
+ CU_ASSERT( mlsrange == NULL );
+ CU_ASSERT( roles_size == 2 );
+ CU_ASSERT( strcmp(roles[0], "testrole") == 0 );
+ CU_ASSERT( strcmp(roles[1], "testrole2") == 0 );
+ CU_ASSERT( strcmp(prefix, "testprefix") == 0 );
+
+ /* Cleanup. */
+ free(roles);
+ roles = NULL;
+
+ name = (char *)semanage_user_get_name(records[1]);
+ mlslevel = (char *)semanage_user_get_mlslevel(records[1]);
+ mlsrange = (char *)semanage_user_get_mlsrange(records[1]);
+ status = semanage_user_get_roles(sh, records[1], (const char ***)&roles, &roles_size);
+ CU_ASSERT( status == 0 );
+ prefix = (char *)semanage_user_get_prefix(records[1]);
+
+ CU_ASSERT( strcmp(name, "testname2") == 0 );
+ CU_ASSERT( mlslevel == NULL );
+ CU_ASSERT( mlsrange == NULL );
+ CU_ASSERT( roles_size == 2 );
+ CU_ASSERT( strcmp(roles[0], "testrole3") == 0 );
+ CU_ASSERT( strcmp(roles[1], "testrole4") == 0 );
+ CU_ASSERT( strcmp(prefix, "testprefix2") == 0 );
+ }
+
+ /* Cleanup. */
+cleanup:
+ if (records != NULL) {
+ unsigned int i;
+ for (i = 0; i < records_size; i++) {
+ if (!records[i])
+ break;
+ rtable->free((record_t *)records[i]);
+ }
+ }
+
+ free(records);
+ free(data);
+ free(roles);
+
+ CU_ASSERT( status == 0 );
+ if (status != 0) {
+ printf("\n\nReceived error code in %s: %d | %s\n", (ps_pid == 0) ? "server" : "client", status, strerror(status));
+ }
+}
+
Index: selinux-pms-support/libsemanage/tests/test_users_policy.h
===================================================================
--- /dev/null
+++ selinux-pms-support/libsemanage/tests/test_users_policy.h
@@ -0,0 +1,32 @@
+/* Authors: Christopher Ashworth <cashworth@tresys.com>
+ * Caleb Case <ccase@tresys.com>
+ *
+ * Copyright (C) 2007 Tresys Technology, LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __TEST_USERS_POLICY_H__
+#define __TEST_USERS_POLICY_H__
+
+#include <CUnit/Basic.h>
+
+int users_policy_test_init(void);
+int users_policy_test_cleanup(void);
+int users_policy_add_tests(CU_pSuite suite);
+
+void test_semanage_user_serialize_policy(void);
+
+#endif
--
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [PATCH 00/33] libsemanage/libsepol object serialization and ps-api
2007-04-23 21:34 [PATCH 00/33] libsemanage/libsepol object serialization and ps-api jbrindle
` (32 preceding siblings ...)
2007-04-23 21:35 ` [PATCH 33/33] libsemanage: user " jbrindle
@ 2007-04-24 19:48 ` Joshua Brindle
2007-04-24 23:12 ` James Antill
34 siblings, 0 replies; 58+ messages in thread
From: Joshua Brindle @ 2007-04-24 19:48 UTC (permalink / raw)
To: selinux
jbrindle@tresys.com wrote:
> This is the majority of the patches from the policy server release a few months ago. This implements object serialization to send objects (eg., booleans, file contexts, etc) across the line to the policy server. It also implements the line protocol to connect to the policy server and the backend for libsemanage so that semodule, semanage, etc will talk to a policy server instead of doing local operations.
>
> The object serialization will also be necessary for the policy representation branch as we will use this infrastructure to serialize the policy tree for module reading and writing.
>
> The only part left for the policy server is the hooks that were implemented in the expander. As the policy representation work is going on and should remove the expander entirely these patches will have to wait until we have enough of the new representation work to implement them there.
>
> This is obviously meant only for trunk and the policyrep branch.
>
I accidently sent this with a timestamp of 5:35 yesterday (vm loses
time, oops). So if it fell off the bottom of your mail list and you are
interested in the patches please check them out :)
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [PATCH 01/33] libsepol: basic serilization support
2007-04-23 21:34 ` [PATCH 01/33] libsepol: basic serilization support jbrindle
@ 2007-04-24 20:00 ` Karl MacMillan
2007-04-24 22:29 ` Joshua Brindle
0 siblings, 1 reply; 58+ messages in thread
From: Karl MacMillan @ 2007-04-24 20:00 UTC (permalink / raw)
To: jbrindle; +Cc: selinux
On Mon, 2007-04-23 at 17:34 -0400, jbrindle@tresys.com wrote:
> plain text document attachment (sepol.serialize.diff)
> Serialization versioning added to the sepol handle.
>
> Serialization utility functions added in serialize.[ch]
> ---
> libsepol/include/sepol/handle.h | 17 +
> libsepol/src/handle.c | 89 +++++++++
> libsepol/src/handle.h | 5
> libsepol/src/libsepol.map | 1
> libsepol/src/serialize.c | 389 ++++++++++++++++++++++++++++++++++++++++
> libsepol/src/serialize.h | 45 ++++
> 6 files changed, 546 insertions(+)
>
> Index: selinux-pms-support/libsepol/include/sepol/handle.h
> ===================================================================
> --- selinux-pms-support.orig/libsepol/include/sepol/handle.h
> +++ selinux-pms-support/libsepol/include/sepol/handle.h
> @@ -1,6 +1,11 @@
> #ifndef _SEPOL_HANDLE_H_
> #define _SEPOL_HANDLE_H_
>
> +#include <inttypes.h>
> +
> +#define SEPOL_SERIAL_VERSION_MAJOR 1
> +#define SEPOL_SERIAL_VERSION_MINOR 0
> +
> struct sepol_handle;
> typedef struct sepol_handle sepol_handle_t;
>
> @@ -10,4 +15,16 @@ sepol_handle_t *sepol_handle_create(void
> /* Destroy a sepol handle. */
> void sepol_handle_destroy(sepol_handle_t *);
>
> +/* Serialize the serialization version. */
> +int sepol_handle_version_serialize(sepol_handle_t * sh, char **data, uint64_t *size);
> +
> +/* Unserialize the serialization version. */
> +int sepol_handle_version_unserialize(sepol_handle_t * sh, char **data, uint64_t *size);
> +
> +/* Get the serialization version. */
> +int sepol_handle_get_version(sepol_handle_t *sh, uint32_t * major, uint32_t * minor);
> +
> +/* Set the serialization version. */
> +int sepol_handle_set_version(sepol_handle_t *sh, uint32_t major, uint32_t minor);
> +
> #endif
Can you give some idea about how the versioning is supposed to work? In
particular:
* How is it related to the policy version?
* Why would it change separately from the policy version?
* Is there any advantage to version each component separately rather
that a global version?
<snip>
> Index: selinux-pms-support/libsepol/src/serialize.c
> ===================================================================
> --- /dev/null
> +++ selinux-pms-support/libsepol/src/serialize.c
> @@ -0,0 +1,389 @@
> +/* Author: Caleb Case <ccase@tresys.com>
> + *
> + * Copyright (C) 2004-2007 Tresys Technology, LLC
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
> + */
> +
> +#include <stdlib.h>
> +#include <string.h>
> +#include <limits.h>
> +
> +#include "handle.h"
> +#include "debug.h"
> +#include "serialize.h"
> +#include "private.h"
> +
> +/* This file provides general serialize and unserialize functions. */
> +
> +/** Serializes various kinds of datum.
> + *
> + * Two use cases:
> + * 1) Calling serialize with a non-NULL size.
> + * This causes serialize to calculate the expected
> + * size of serializing. No serialization occurs.
> + * Destructively modifies size. Data may be NULL.
> + * 2) Calling serialize with a NULL size.
> + * This results in data being filled with the
> + * serialized information. Caller must pre-allocate
> + * space for data. Destructively modifies data.
> + *
Why don't you allocate space for the caller? These two use cases are,
well, odd. If you allocate then the caller can memcpy and free if they
want.
> + * This function acts iteratively moving the *data or size values.
> + *
> + * Supported datum_types (defined in serialize.h):
> + *
> + * SEPOL_SERIAL_INT32_T
> + * Serializes datum to a int32_t as defined in inttypes.h
> + * datum may NOT be NULL.
> + * datum_length is not utilized.
> + * SEPOL_SERIAL_UINT32_T
> + * Serializes datum to a uint32_t as defined in inttypes.h
> + * datum may NOT be NULL.
> + * datum_length is not utilized.
> + * SEPOL_SERIAL_SIZE_T
> + * Serializes datum to a size_t as defined in stddef.h
> + * datum may NOT be NULL.
> + * datum_length is not utilized.
How can you serialize a type that is platform specific? How would this
be handled when communication between a 32 and 64 bit host? I thought we
always used fixed width types for all binary communication anyway.
> + * SEPOL_SERIAL_STRING
> + * Serializes a char*.
> + * datum may be NULL.
> + * datum_length should be the length of the string as returned by strlen.
Why not call strlen? Especially since the string array version does.
> + * SEPOL_SERIAL_STRING_ARRAY
> + * Serializes a char**.
> + * datum may be NULL.
> + * datum_length should be the size of the array.
> + * Each string will be serialized as per SEPOL_SERIAL_STRING and its size
> + * determined via strlen.
> + *
> + * NULL pointers are distinguished (where they are allowed at all).
> + * In the case of strings this means that a NULL char* has a different
> + * serialization from the empty string "".
Why?
> + *
> + */
> +int sepol_serialize(sepol_handle_t * handle,
> + const void *datum,
> + size_t datum_length,
> + unsigned int datum_type, char **data, uint64_t * size)
> +{
Why a single multiplexed function? Seems _much_ easier to have a
sepol_serialize_string, sepol_serialize_uint32, etc. This would allow
type safety and improve readability, both at the call site and the
definition.
<snip>
> + case SEPOL_SERIAL_SIZE_T:
> + if (size == NULL) {
> + temp = calloc(1, sizeof(uint64_t));
> + if (temp == NULL) {
> + status = STATUS_ERR;
> + goto cleanup;
> + }
> +
> + *((uint64_t *)temp) = cpu_to_le64(*((size_t *) datum));
> +
> + memcpy(*data, temp, sizeof(uint64_t));
> + *data += sizeof(uint64_t);
> + }
> + else
> + *size += sizeof(uint64_t);
> + break;
Err - I don't think this is allowed. I believe that size_t is supposed
to be word size and there is no reason that word size is limited to 64
bits.
Karl
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [PATCH 12/33] libsemanage: basic serialization
2007-04-23 21:35 ` [PATCH 12/33] libsemanage: basic serialization jbrindle
@ 2007-04-24 21:16 ` Karl MacMillan
2007-04-24 22:31 ` Joshua Brindle
0 siblings, 1 reply; 58+ messages in thread
From: Karl MacMillan @ 2007-04-24 21:16 UTC (permalink / raw)
To: jbrindle; +Cc: selinux
On Mon, 2007-04-23 at 17:35 -0400, jbrindle@tresys.com wrote:
> plain text document attachment (semanage.serialize.diff)
> This is the serialization infrastructure for libsemanage.
>
We have talked about this in the past, but I think the duplication
between libsemanage and libsepol should be removed. This is just
ridiculous.
Karl
> ---
> libsemanage/include/semanage/handle.h | 17 +
> libsemanage/src/handle.c | 28 ++
> libsemanage/src/handle_internal.h | 5
> libsemanage/src/libsemanage.map | 1
> libsemanage/src/serialize.c | 389 ++++++++++++++++++++++++++++++++++
> libsemanage/src/serialize.h | 45 +++
> 6 files changed, 485 insertions(+)
>
> Index: selinux-pms-support/libsemanage/include/semanage/handle.h
> ===================================================================
> --- selinux-pms-support.orig/libsemanage/include/semanage/handle.h
> +++ selinux-pms-support/libsemanage/include/semanage/handle.h
> @@ -21,6 +21,11 @@
> #ifndef _SEMANAGE_HANDLE_H_
> #define _SEMANAGE_HANDLE_H_
>
> +#define SEMANAGE_SERIAL_VERSION_MAJOR 1
> +#define SEMANAGE_SERIAL_VERSION_MINOR 0
> +
> +#include <inttypes.h>
> +
> /* All accesses with semanage are through a "semanage_handle". The
> * handle may ultimately reference local config files,
> * the binary policy file, a module store, or a policy management server.
> @@ -38,6 +43,18 @@ semanage_handle_t *semanage_handle_creat
> * previously called if the handle was connected. */
> void semanage_handle_destroy(semanage_handle_t *);
>
> +/* Get the serialization version. */
> +int semanage_handle_get_version(semanage_handle_t *sh, uint32_t * major, uint32_t * minor);
> +
> +/* Set the serialization version. */
> +int semanage_handle_set_version(semanage_handle_t *sh, uint32_t major, uint32_t minor);
> +
> +/* Serialize the serialization version. */
> +int semanage_handle_version_serialize(semanage_handle_t *sh, char **data, uint64_t *size);
> +
> +/* Unserialize the serialization version. */
> +int semanage_handle_version_unserialize(semanage_handle_t *sh, char **data, uint64_t *size);
> +
> /* This is the type of connection to the store, for now only
> * direct is supported */
> enum semanage_connect_type {
> Index: selinux-pms-support/libsemanage/src/handle.c
> ===================================================================
> --- selinux-pms-support.orig/libsemanage/src/handle.c
> +++ selinux-pms-support/libsemanage/src/handle.c
> @@ -82,6 +82,34 @@ semanage_handle_t *semanage_handle_creat
> return NULL;
> }
>
> +int semanage_handle_get_version(semanage_handle_t *sh, uint32_t * major, uint32_t * minor)
> +{
> + return sepol_handle_get_version(sh->sepolh, major, minor);
> +}
> +
> +hidden_def(semanage_handle_get_version)
> +
> +int semanage_handle_set_version(semanage_handle_t *sh, uint32_t major, uint32_t minor)
> +{
> + return sepol_handle_set_version(sh->sepolh, major, minor);
> +}
> +
> +hidden_def(semanage_handle_set_version)
> +
> +int semanage_handle_version_serialize(semanage_handle_t *sh, char **data, uint64_t *size)
> +{
> + return sepol_handle_version_serialize(sh->sepolh, data, size);
> +}
> +
> +hidden_def(semanage_handle_version_serialize)
> +
> +int semanage_handle_version_unserialize(semanage_handle_t *sh, char **data, uint64_t *size)
> +{
> + return sepol_handle_version_unserialize(sh->sepolh, data, size);
> +}
> +
> +hidden_def(semanage_handle_version_unserialize)
> +
> void semanage_set_rebuild(semanage_handle_t * sh, int do_rebuild)
> {
>
> Index: selinux-pms-support/libsemanage/src/handle_internal.h
> ===================================================================
> --- selinux-pms-support.orig/libsemanage/src/handle_internal.h
> +++ selinux-pms-support/libsemanage/src/handle_internal.h
> @@ -8,4 +8,9 @@ hidden_proto(semanage_begin_transaction)
> hidden_proto(semanage_handle_destroy)
> hidden_proto(semanage_reload_policy)
> hidden_proto(semanage_access_check)
> +hidden_proto(semanage_handle_get_version)
> +hidden_proto(semanage_handle_set_version)
> +hidden_proto(semanage_handle_version_serialize)
> +hidden_proto(semanage_handle_version_unserialize)
> +
> #endif
> Index: selinux-pms-support/libsemanage/src/libsemanage.map
> ===================================================================
> --- selinux-pms-support.orig/libsemanage/src/libsemanage.map
> +++ selinux-pms-support/libsemanage/src/libsemanage.map
> @@ -13,6 +13,7 @@ LIBSEMANAGE_1.0 {
> semanage_iface_*; semanage_port_*; semanage_context_*;
> semanage_node_*;
> semanage_fcontext_*; semanage_access_check; semanage_set_create_store;
> + semanage_*_serialize; semanage_*_unserialize;
> semanage_is_connected;
> local: *;
> };
> Index: selinux-pms-support/libsemanage/src/serialize.c
> ===================================================================
> --- /dev/null
> +++ selinux-pms-support/libsemanage/src/serialize.c
> @@ -0,0 +1,389 @@
> +/* Author: Caleb Case <ccase@tresys.com>
> + *
> + * Copyright (C) 2004-2007 Tresys Technology, LLC
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
> + */
> +
> +#include <stdlib.h>
> +#include <string.h>
> +#include <limits.h>
> +
> +#include "handle.h"
> +#include "debug.h"
> +#include "serialize.h"
> +#include "byteswap.h"
> +
> +/* This file provides general serialize and unserialize functions. */
> +
> +/** Serializes various kinds of datum.
> + *
> + * Two use cases:
> + * 1) Calling serialize with a non-NULL size.
> + * This causes serialize to calculate the expected
> + * size of serializing. No serialization occurs.
> + * Destructively modifies size. Data may be NULL.
> + * 2) Calling serialize with a NULL size.
> + * This results in data being filled with the
> + * serialized information. Caller must pre-allocate
> + * space for data. Destructively modifies data.
> + *
> + * This function acts iteratively moving the *data or size values.
> + *
> + * Supported datum_types (defined in serialize.h):
> + *
> + * SEMANAGE_SERIAL_INT32_T
> + * Serializes datum to a int32_t as defined in inttypes.h
> + * datum may NOT be NULL.
> + * datum_length is not utilized.
> + * SEMANAGE_SERIAL_UINT32_T
> + * Serializes datum to a uint32_t as defined in inttypes.h
> + * datum may NOT be NULL.
> + * datum_length is not utilized.
> + * SEMANAGE_SERIAL_SIZE_T
> + * Serializes datum to a size_t as defined in stddef.h
> + * datum may NOT be NULL.
> + * datum_length is not utilized.
> + * SEMANAGE_SERIAL_STRING
> + * Serializes a char*.
> + * datum may be NULL.
> + * datum_length should be the length of the string as returned by strlen.
> + * SEMANAGE_SERIAL_STRING_ARRAY
> + * Serializes a char**.
> + * datum may be NULL.
> + * datum_length should be the size of the array.
> + * Each string will be serialized as per SEMANAGE_SERIAL_STRING and its size
> + * determined via strlen.
> + *
> + * NULL pointers are distinguished (where they are allowed at all).
> + * In the case of strings this means that a NULL char* has a different
> + * serialization from the empty string "".
> + *
> + */
> +int semanage_serialize(semanage_handle_t * handle,
> + const void *datum,
> + size_t datum_length,
> + unsigned int datum_type, char **data, uint64_t * size)
> +{
> + int status;
> + unsigned int flags;
> + uint32_t i;
> + void *temp = NULL;
> +
> + switch (datum_type) {
> + case SEMANAGE_SERIAL_INT32_T:
> + case SEMANAGE_SERIAL_UINT32_T:
> + if (size == NULL) {
> + temp = calloc(1, sizeof(int32_t));
> + if (temp == NULL) {
> + status = STATUS_ERR;
> + goto cleanup;
> + }
> +
> + *((int32_t *)temp) = cpu_to_le32(*((int32_t *) datum));
> + memcpy(*data, temp, sizeof(int32_t));
> + *data += sizeof(int32_t);
> + }
> + else
> + *size += sizeof(int32_t);
> + break;
> + case SEMANAGE_SERIAL_SIZE_T:
> + if (size == NULL) {
> + temp = calloc(1, sizeof(uint64_t));
> + if (temp == NULL) {
> + status = STATUS_ERR;
> + goto cleanup;
> + }
> +
> + *((uint64_t *)temp) = cpu_to_le64(*((size_t *) datum));
> +
> + memcpy(*data, temp, sizeof(uint64_t));
> + *data += sizeof(uint64_t);
> + }
> + else
> + *size += sizeof(uint64_t);
> + break;
> + case SEMANAGE_SERIAL_STRING:
> + /* Flags (intended as a bitmap):
> + * 0 == NULL
> + * 1 == Non NULL
> + */
> + flags = (datum == NULL) ? 0 : 1;
> +
> + status =
> + semanage_serialize(handle, &flags, 0, SEMANAGE_SERIAL_UINT32_T, data,
> + size);
> + if (status != STATUS_SUCCESS)
> + goto cleanup;
> +
> + /* Write if not null. */
> + if (flags & 1) {
> + /* Size. */
> + status =
> + semanage_serialize(handle, &datum_length, 0,
> + SEMANAGE_SERIAL_SIZE_T, data, size);
> + if (status != STATUS_SUCCESS)
> + goto cleanup;
> +
> + /* Datum. */
> + if (size == NULL) {
> + status =
> + snprintf(*data, datum_length + 1, "%s",
> + (char *)datum);
> + if (status < 0 || (unsigned)status > datum_length)
> + goto cleanup;
> + else {
> + *data += status + 1;
> + status = STATUS_SUCCESS;
> + }
> + } else {
> + *size += datum_length + 1;
> + }
> + }
> + break;
> + case SEMANAGE_SERIAL_STRING_ARRAY:
> + /* Flags (intended as a bitmap):
> + * 0 == NULL
> + * 1 == Non NULL
> + */
> + flags = (datum == NULL) ? 0 : 1;
> +
> + status =
> + semanage_serialize(handle, &flags, 0, SEMANAGE_SERIAL_UINT32_T, data,
> + size);
> + if (status != STATUS_SUCCESS)
> + goto cleanup;
> +
> + /* Write if not null. */
> + if (flags & 1) {
> + /* Size. */
> + status =
> + semanage_serialize(handle, &datum_length, 0,
> + SEMANAGE_SERIAL_UINT32_T, data, size);
> + if (status != STATUS_SUCCESS)
> + goto cleanup;
> +
> + /* Datum. */
> + for (i = 0; i < datum_length; i++) {
> + status =
> + semanage_serialize(handle, ((char **)datum)[i],
> + strlen(((char **)datum)[i]),
> + SEMANAGE_SERIAL_STRING, data, size);
> + if (status != STATUS_SUCCESS)
> + goto cleanup;
> + }
> + }
> + break;
> + default:
> + status = STATUS_ERR;
> + goto cleanup;
> + }
> +
> + /* Cleanup. */
> + status = STATUS_SUCCESS;
> +cleanup:
> + free(temp);
> + return status;
> +}
> +
> +/** Unserializes various kinds of datum as serialized by semanage_serialize.
> + *
> + * This function acts iteratively moving the *data AND size values.
> + * size is decremented as data is unserialized.
> + *
> + * It also allocates memory for datum and, depending on datum_type, datum_length.
> + * Caller must free.
> + *
> + * Supported datum_types (defined in serialize.h):
> + *
> + * SEMANAGE_SERIAL_INT32_T
> + * Unserializes data into an int32_t as defined in inttypes.h.
> + * datum_length may be NULL.
> + * SEMANAGE_SERIAL_UINT32_T
> + * Unserializes data into an uint32_t as defined in inttypes.h.
> + * datum_length may be NULL.
> + * SEMANAGE_SERIAL_SIZE_T
> + * Unserializes data into an size_t as defined in stddef.h.
> + * datum_length may be NULL.
> + * SEMANAGE_SERIAL_STRING
> + * Unserializes data into a NULL terminated char*.
> + * datum_length may NOT be NULL and will be the size of the string.
> + * SEMANAGE_SERIAL_STRING_ARRAY
> + * Unserializes data into a char**.
> + * Each entry in the array will be unserialized as per SEMANAGE_SERIAL_STRING.
> + * datum_length may NOT be NULL and will be the size of the array.
> + */
> +int semanage_unserialize(semanage_handle_t * handle,
> + char **data, uint64_t * size,
> + void **datum,
> + size_t ** datum_length,
> + unsigned int datum_type)
> +{
> + int status;
> + unsigned int *flags = NULL;
> + uint32_t i;
> + void *temp = NULL;
> + size_t *temp_length = NULL;
> +
> + switch (datum_type) {
> + case SEMANAGE_SERIAL_INT32_T:
> + case SEMANAGE_SERIAL_UINT32_T:
> + *datum = calloc(1, sizeof(int32_t));
> + if (*datum == NULL) {
> + status = STATUS_ERR;
> + goto cleanup;
> + }
> +
> + memcpy(*datum, *data, sizeof(int32_t));
> + **((int32_t **)datum) = le32_to_cpu(**((int32_t **) datum));
> +
> + *size -= sizeof(int32_t);
> + *data += sizeof(int32_t);
> + break;
> + case SEMANAGE_SERIAL_SIZE_T:
> + temp = calloc(1, sizeof(uint64_t));
> + if (temp == NULL) {
> + status = STATUS_ERR;
> + goto cleanup;
> + }
> +
> + memcpy(temp, *data, sizeof(uint64_t));
> +
> + *((uint64_t *) temp) = le64_to_cpu(*((uint64_t *) temp));
> +
> + if (*((uint64_t *) temp) > UINT_MAX) {
> + status = STATUS_ERR;
> + goto cleanup;
> + }
> +
> + *datum = calloc(1, sizeof(size_t));
> + if (datum == NULL) {
> + status = STATUS_ERR;
> + goto cleanup;
> + }
> +
> + **((size_t **)datum) = *((uint64_t *) temp);
> +
> + *size -= sizeof(uint64_t);
> + *data += sizeof(uint64_t);
> + break;
> + case SEMANAGE_SERIAL_STRING:
> + /* Flags (intended as a bitmap):
> + * 0 == NULL
> + * 1 == Non NULL
> + */
> + status =
> + semanage_unserialize(handle,
> + data, size,
> + (void **)(&flags), NULL,
> + SEMANAGE_SERIAL_UINT32_T);
> + if (status != STATUS_SUCCESS)
> + goto cleanup;
> +
> + if (*flags & 1) {
> + /* Size. */
> + status =
> + semanage_unserialize(handle,
> + data, size,
> + (void **)datum_length, NULL,
> + SEMANAGE_SERIAL_SIZE_T);
> + if (status != STATUS_SUCCESS)
> + goto cleanup;
> +
> + /* Datum. */
> + *datum = calloc(**datum_length + 1, sizeof(char));
> + if (*datum == NULL) {
> + status = STATUS_ERR;
> + goto cleanup;
> + }
> +
> + memcpy(*datum, *data, **datum_length + 1);
> +
> + *size -= **datum_length + 1;
> + *data += **datum_length + 1;
> + } else {
> + *datum = NULL;
> + *datum_length = NULL;
> + }
> +
> + free(flags);
> + flags = NULL;
> + break;
> + case SEMANAGE_SERIAL_STRING_ARRAY:
> + /* Flags (intended as a bitmap):
> + * 0 == NULL
> + * 1 == Non NULL
> + */
> + status =
> + semanage_unserialize(handle,
> + data, size,
> + (void **)(&flags), NULL,
> + SEMANAGE_SERIAL_UINT32_T);
> + if (status != STATUS_SUCCESS)
> + goto cleanup;
> +
> + /* Write if not null. */
> + if (*flags & 1) {
> + /* Size. */
> + status =
> + semanage_unserialize(handle,
> + data, size,
> + (void **)datum_length, NULL,
> + SEMANAGE_SERIAL_UINT32_T);
> + if (status != STATUS_SUCCESS)
> + goto cleanup;
> +
> + /* Datum. */
> + *datum =
> + calloc(sizeof(char *),
> + sizeof(char *) * (**datum_length));
> + if (*datum == NULL) {
> + status = STATUS_ERR;
> + goto cleanup;
> + }
> +
> + for (i = 0; i < **datum_length; i++) {
> + status = semanage_unserialize(handle,
> + data,
> + size,
> + (void **)&(((char **)(*datum))[i]),
> + &temp_length,
> + SEMANAGE_SERIAL_STRING);
> +
> + if (status != STATUS_SUCCESS)
> + goto cleanup;
> +
> + free(temp_length);
> + temp_length = NULL;
> + }
> + }
> +
> + free(flags);
> + flags = NULL;
> + break;
> + default:
> + status = STATUS_ERR;
> + goto cleanup;
> + }
> +
> + /* Cleanup. */
> + status = STATUS_SUCCESS;
> +cleanup:
> + free(flags);
> + free(temp);
> + free(temp_length);
> + return status;
> +}
> +
> Index: selinux-pms-support/libsemanage/src/serialize.h
> ===================================================================
> --- /dev/null
> +++ selinux-pms-support/libsemanage/src/serialize.h
> @@ -0,0 +1,45 @@
> +/* Author: Caleb Case <ccase@tresys.com>
> + *
> + * Copyright (C) 2005-2007 Tresys Technology, LLC
> + * Copyright (C) 2005 Red Hat Inc.
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
> + */
> +
> +#ifndef _SEMANAGE_SERIALIZE_INTERNAL_H_
> +#define _SEMANAGE_SERIALIZE_INTERNAL_H_
> +
> +#include <inttypes.h>
> +#include "handle.h"
> +
> +/* Datum types. */
> +#define SEMANAGE_SERIAL_INT32_T 0
> +#define SEMANAGE_SERIAL_UINT32_T 1
> +#define SEMANAGE_SERIAL_SIZE_T 2
> +#define SEMANAGE_SERIAL_STRING 3
> +#define SEMANAGE_SERIAL_STRING_ARRAY 4
> +
> +int semanage_serialize(semanage_handle_t * handle,
> + const void *datum,
> + size_t datum_size,
> + unsigned int datum_type, char **data, uint64_t * size);
> +
> +int semanage_unserialize(semanage_handle_t * handle,
> + char **data, uint64_t * size,
> + void **datum,
> + size_t ** datum_length,
> + unsigned int datum_type);
> +
> +#endif
>
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [PATCH 25/33] libsemanage: policy server database hooks
2007-04-23 21:35 ` [PATCH 25/33] libsemanage: policy server database hooks jbrindle
@ 2007-04-24 21:39 ` Karl MacMillan
2007-04-24 22:39 ` Joshua Brindle
0 siblings, 1 reply; 58+ messages in thread
From: Karl MacMillan @ 2007-04-24 21:39 UTC (permalink / raw)
To: jbrindle; +Cc: selinux
On Mon, 2007-04-23 at 17:35 -0400, jbrindle@tresys.com wrote:
> plain text document attachment (semanage.ps_api.diff)
> Implements all database functions for a policy server backend.
Any thoughts on how this should be merged? I'm concerned about merging
without a working policy server that has been reviewed as well.
* What are your plans for the policy server - will it be proposed for
inclusion upstream?
* What is the timeline for completion of the policy server?
* Are their any docs at all about the protocol?
* Any progress on the exec-based policy server instead of the long
running daemon?
Basically - this patch set is too large to review, there have been no
ongoing design discussions, there is no way to review large portions of
the patch set due to external dependencies, and I have seen no proposed
plan for merging.
I have voiced these concerns previously and without at least some of the
above I'm opposed merging at this time.
I would suggest as an alternative plan you do a depth-first submission
instead of the breadth-first approach that you are currently attempting.
That would allow a review of the end-to-end design with a relatively
small amount of code. From that point expanding the coverage would only
require a quick review that the patch continues on the already accepted
approach.
That steps that I suggest are:
* Choose a _single_ and _simple_ semanage operation to control.
Something like adding a role to a user.
* Post a minimal policy server that can control this operation
(preferably exec-based).
* Post the libsemange code to communicate with the server _only_ that
single operation.
* Create an example policy that controls this operation that can be used
to test and demonstrate the functionality.
Karl
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* RE: [PATCH 01/33] libsepol: basic serilization support
2007-04-24 20:00 ` Karl MacMillan
@ 2007-04-24 22:29 ` Joshua Brindle
2007-04-25 4:49 ` Karl MacMillan
0 siblings, 1 reply; 58+ messages in thread
From: Joshua Brindle @ 2007-04-24 22:29 UTC (permalink / raw)
To: Karl MacMillan; +Cc: selinux
> From: Karl MacMillan [mailto:kmacmillan@mentalrootkit.com]
>
> On Mon, 2007-04-23 at 17:34 -0400, jbrindle@tresys.com wrote:
> > plain text document attachment (sepol.serialize.diff) Serialization
> > versioning added to the sepol handle.
> >
> > Serialization utility functions added in serialize.[ch]
> > ---
> > libsepol/include/sepol/handle.h | 17 +
> > libsepol/src/handle.c | 89 +++++++++
> > libsepol/src/handle.h | 5
> > libsepol/src/libsepol.map | 1
> > libsepol/src/serialize.c | 389
> ++++++++++++++++++++++++++++++++++++++++
> > libsepol/src/serialize.h | 45 ++++
> > 6 files changed, 546 insertions(+)
> >
> > Index: selinux-pms-support/libsepol/include/sepol/handle.h
> > ===================================================================
> > --- selinux-pms-support.orig/libsepol/include/sepol/handle.h
> > +++ selinux-pms-support/libsepol/include/sepol/handle.h
> > @@ -1,6 +1,11 @@
> > #ifndef _SEPOL_HANDLE_H_
> > #define _SEPOL_HANDLE_H_
> >
> > +#include <inttypes.h>
> > +
> > +#define SEPOL_SERIAL_VERSION_MAJOR 1
> > +#define SEPOL_SERIAL_VERSION_MINOR 0
> > +
> > struct sepol_handle;
> > typedef struct sepol_handle sepol_handle_t;
> >
> > @@ -10,4 +15,16 @@ sepol_handle_t *sepol_handle_create(void
> > /* Destroy a sepol handle. */
> > void sepol_handle_destroy(sepol_handle_t *);
> >
> > +/* Serialize the serialization version. */ int
> > +sepol_handle_version_serialize(sepol_handle_t * sh, char **data,
> > +uint64_t *size);
> > +
> > +/* Unserialize the serialization version. */ int
> > +sepol_handle_version_unserialize(sepol_handle_t * sh, char **data,
> > +uint64_t *size);
> > +
> > +/* Get the serialization version. */
> > +int sepol_handle_get_version(sepol_handle_t *sh, uint32_t * major,
> > +uint32_t * minor);
> > +
> > +/* Set the serialization version. */
> > +int sepol_handle_set_version(sepol_handle_t *sh, uint32_t major,
> > +uint32_t minor);
> > +
> > #endif
>
> Can you give some idea about how the versioning is supposed
> to work? In
> particular:
>
> * How is it related to the policy version?
> * Why would it change separately from the policy version?
> * Is there any advantage to version each component separately
> rather that a global version?
>
Most of the stuff we are serializing isn't actually in policy, modules
are already a serialized version of policy and we don't do anything with
it, the stuff we are serializing is mostly semanage stuff (file
contexts, seusers, etc) that have nothing to do with policy. The
per-component versioning was discussed but thought to be too much
overhead for the number of objects we are serializing.
> <snip>
>
> > Index: selinux-pms-support/libsepol/src/serialize.c
> > ===================================================================
> > --- /dev/null
> > +++ selinux-pms-support/libsepol/src/serialize.c
> > @@ -0,0 +1,389 @@
> > +/* Author: Caleb Case <ccase@tresys.com>
> > + *
> > + * Copyright (C) 2004-2007 Tresys Technology, LLC
> > + *
> > + * This library is free software; you can redistribute it and/or
> > + * modify it under the terms of the GNU Lesser General Public
> > + * License as published by the Free Software Foundation; either
> > + * version 2.1 of the License, or (at your option) any
> later version.
> > + *
> > + * This library is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
> See the GNU
> > + * Lesser General Public License for more details.
> > + *
> > + * You should have received a copy of the GNU Lesser
> General Public
> > + * License along with this library; if not, write to the Free
> > +Software
> > + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
> > +02110-1301 USA */
> > +
> > +#include <stdlib.h>
> > +#include <string.h>
> > +#include <limits.h>
> > +
> > +#include "handle.h"
> > +#include "debug.h"
> > +#include "serialize.h"
> > +#include "private.h"
> > +
> > +/* This file provides general serialize and unserialize
> functions. */
> > +
> > +/** Serializes various kinds of datum.
> > + *
> > + * Two use cases:
> > + * 1) Calling serialize with a non-NULL size.
> > + * This causes serialize to calculate the expected
> > + * size of serializing. No serialization occurs.
> > + * Destructively modifies size. Data may be NULL.
> > + * 2) Calling serialize with a NULL size.
> > + * This results in data being filled with the
> > + * serialized information. Caller must pre-allocate
> > + * space for data. Destructively modifies data.
> > + *
>
> Why don't you allocate space for the caller? These two use
> cases are, well, odd. If you allocate then the caller can
> memcpy and free if they want.
>
It works basically the same way the current policy serialization works,
pass in the data once to get size, allocate and pass in the buffer to
which its being serialized. We did this for consistency with the current
mechanisms.
> > + * This function acts iteratively moving the *data or size values.
> > + *
> > + * Supported datum_types (defined in serialize.h):
> > + *
> > + * SEPOL_SERIAL_INT32_T
> > + * Serializes datum to a int32_t as defined in inttypes.h
> > + * datum may NOT be NULL.
> > + * datum_length is not utilized.
> > + * SEPOL_SERIAL_UINT32_T
> > + * Serializes datum to a uint32_t as defined in inttypes.h
> > + * datum may NOT be NULL.
> > + * datum_length is not utilized.
> > + * SEPOL_SERIAL_SIZE_T
> > + * Serializes datum to a size_t as defined in stddef.h
> > + * datum may NOT be NULL.
> > + * datum_length is not utilized.
>
> How can you serialize a type that is platform specific? How
> would this be handled when communication between a 32 and 64
> bit host? I thought we always used fixed width types for all
> binary communication anyway.
>
SEPOL_SERIAL_SIZE_T is always 64 bits. We should be checking if it tries
to serialize into a smaller type, if not that's a bug.
> > + * SEPOL_SERIAL_STRING
> > + * Serializes a char*.
> > + * datum may be NULL.
> > + * datum_length should be the length of the string as
> returned by strlen.
>
> Why not call strlen? Especially since the string array version does.
>
IIRC because we use the same entry point for all data types to get to
these.
> > + * SEPOL_SERIAL_STRING_ARRAY
> > + * Serializes a char**.
> > + * datum may be NULL.
> > + * datum_length should be the size of the array.
> > + * Each string will be serialized as per
> SEPOL_SERIAL_STRING and its size
> > + * determined via strlen.
> > + *
> > + * NULL pointers are distinguished (where they are
> allowed at all).
> > + * In the case of strings this means that a NULL char* has a
> > + different
> > + * serialization from the empty string "".
>
> Why?
>
Not sure, will check.
> > + *
> > + */
> > +int sepol_serialize(sepol_handle_t * handle,
> > + const void *datum,
> > + size_t datum_length,
> > + unsigned int datum_type, char **data,
> uint64_t * size) {
>
> Why a single multiplexed function? Seems _much_ easier to
> have a sepol_serialize_string, sepol_serialize_uint32, etc.
> This would allow type safety and improve readability, both at
> the call site and the definition.
>
We can do that I guess, IMO it doesn't make much of a difference.
>
> <snip>
>
> > + case SEPOL_SERIAL_SIZE_T:
> > + if (size == NULL) {
> > + temp = calloc(1, sizeof(uint64_t));
> > + if (temp == NULL) {
> > + status = STATUS_ERR;
> > + goto cleanup;
> > + }
> > +
> > + *((uint64_t *)temp) =
> cpu_to_le64(*((size_t *) datum));
> > +
> > + memcpy(*data, temp, sizeof(uint64_t));
> > + *data += sizeof(uint64_t);
> > + }
> > + else
> > + *size += sizeof(uint64_t);
> > + break;
>
> Err - I don't think this is allowed. I believe that size_t is
> supposed to be word size and there is no reason that word
> size is limited to 64 bits.
>
IIRC in ANSI C it is limited to 64 bits. I might be wrong on this but I
remember us looking it up when this happened.
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* RE: [PATCH 12/33] libsemanage: basic serialization
2007-04-24 21:16 ` Karl MacMillan
@ 2007-04-24 22:31 ` Joshua Brindle
2007-04-24 22:39 ` Karl MacMillan
0 siblings, 1 reply; 58+ messages in thread
From: Joshua Brindle @ 2007-04-24 22:31 UTC (permalink / raw)
To: Karl MacMillan; +Cc: selinux
> From: Karl MacMillan [mailto:kmacmillan@mentalrootkit.com]
>
> On Mon, 2007-04-23 at 17:35 -0400, jbrindle@tresys.com wrote:
> > plain text document attachment (semanage.serialize.diff)
> This is the
> > serialization infrastructure for libsemanage.
> >
>
> We have talked about this in the past, but I think the
> duplication between libsemanage and libsepol should be
> removed. This is just ridiculous.
>
We haven't figured out how to remove it. There are lots of objects that
are only in semanage (fcontext, seuser, etc) and many that are in sepol
(user, boolean, etc). We could do serialization of all sepol types (we
are going to do that anyway for the new policy rep) and remove that
stuff from libsemanage (I thought that was the plan anyway), for now
this is how we did it. Hopefully that'll change. Both libraries are
going to have to have serialization/unserialization infrastructure in
any case.
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* RE: [PATCH 25/33] libsemanage: policy server database hooks
2007-04-24 21:39 ` Karl MacMillan
@ 2007-04-24 22:39 ` Joshua Brindle
2007-04-24 23:20 ` Karl MacMillan
0 siblings, 1 reply; 58+ messages in thread
From: Joshua Brindle @ 2007-04-24 22:39 UTC (permalink / raw)
To: Karl MacMillan; +Cc: selinux
> From: Karl MacMillan [mailto:kmacmillan@mentalrootkit.com]
>
> On Mon, 2007-04-23 at 17:35 -0400, jbrindle@tresys.com wrote:
> > plain text document attachment (semanage.ps_api.diff)
> Implements all
> > database functions for a policy server backend.
>
> Any thoughts on how this should be merged? I'm concerned
> about merging without a working policy server that has been
> reviewed as well.
>
Its available, review it ;) Note that it won't work with _just_ this
patch set as it expects the enforcement hooks to be present. It should
be trivial to comment out all the function pointers to get it to work
without that though.
> * What are your plans for the policy server - will it be
> proposed for inclusion upstream?
>
That was never my intention.
> * What is the timeline for completion of the policy server?
>
I sent out an RFC/announcement a while back about its availability on
oss.tresys.com, noone bothered to respond.
> * Are their any docs at all about the protocol?
>
Some, I'll dig them out and post them on oss.
> * Any progress on the exec-based policy server instead of the
> long running daemon?
>
The exec-based one has nothing to do with this patchset. The exec based
policy server would merely run with the new and old policies as
arguments and do its thing, it would not need to communicate with
libsemanage. This patchset is for the long-running daemon that listens
on a unix domain socket or tcp socket. The exec based one should come
along with the hook code when that gets ported over to the new
representation.
> Basically - this patch set is too large to review, there have
> been no ongoing design discussions, there is no way to review
> large portions of the patch set due to external dependencies,
> and I have seen no proposed plan for merging.
>
There have been occasional RFC's that noone responded to.
> I have voiced these concerns previously and without at least
> some of the above I'm opposed merging at this time.
>
I believe you have some misconceptions about this patchset, read below.
> I would suggest as an alternative plan you do a depth-first
> submission instead of the breadth-first approach that you are
> currently attempting.
> That would allow a review of the end-to-end design with a
> relatively small amount of code. From that point expanding
> the coverage would only require a quick review that the patch
> continues on the already accepted approach.
>
> That steps that I suggest are:
>
> * Choose a _single_ and _simple_ semanage operation to control.
> Something like adding a role to a user.
>
This patchset nor the hooks currently available do access control on
semanage operations. Only policy modules have enforcement hooks written
and all that is available on oss.tresys.com.
> * Post a minimal policy server that can control this
> operation (preferably exec-based).
>
As part of the hooks, yes.
> * Post the libsemange code to communicate with the server
> _only_ that single operation.
>
That is silly, to choose a new backend for libsemanage you need all the
function pointers. Filling in all of them with direct versions except
for a single one would be at least confusing and at most would break
badly since both the local semanage and the policy server would attempt
to lock the store.
> * Create an example policy that controls this operation that
> can be used to test and demonstrate the functionality.
>
Example policy that controls what we have hooks for is available in
tests and on oss.tresys.com.
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* RE: [PATCH 12/33] libsemanage: basic serialization
2007-04-24 22:31 ` Joshua Brindle
@ 2007-04-24 22:39 ` Karl MacMillan
0 siblings, 0 replies; 58+ messages in thread
From: Karl MacMillan @ 2007-04-24 22:39 UTC (permalink / raw)
To: Joshua Brindle; +Cc: selinux
On Tue, 2007-04-24 at 18:31 -0400, Joshua Brindle wrote:
> > From: Karl MacMillan [mailto:kmacmillan@mentalrootkit.com]
> >
> > On Mon, 2007-04-23 at 17:35 -0400, jbrindle@tresys.com wrote:
> > > plain text document attachment (semanage.serialize.diff)
> > This is the
> > > serialization infrastructure for libsemanage.
> > >
> >
> > We have talked about this in the past, but I think the
> > duplication between libsemanage and libsepol should be
> > removed. This is just ridiculous.
> >
>
> We haven't figured out how to remove it. There are lots of objects that
> are only in semanage (fcontext, seuser, etc) and many that are in sepol
> (user, boolean, etc).
We should move this into libsepol. I actually think that would make the
library split clearer.
> We could do serialization of all sepol types (we
> are going to do that anyway for the new policy rep) and remove that
> stuff from libsemanage (I thought that was the plan anyway), for now
> this is how we did it. Hopefully that'll change. Both libraries are
> going to have to have serialization/unserialization infrastructure in
> any case.
Why? Just have a generic way to serialize lists (and perhaps name /
value pairs) in libsepol and all of the code falls out of libsemanage.
Karl
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [PATCH 00/33] libsemanage/libsepol object serialization and ps-api
2007-04-23 21:34 [PATCH 00/33] libsemanage/libsepol object serialization and ps-api jbrindle
` (33 preceding siblings ...)
2007-04-24 19:48 ` [PATCH 00/33] libsemanage/libsepol object serialization and ps-api Joshua Brindle
@ 2007-04-24 23:12 ` James Antill
2007-04-25 4:46 ` James Antill
34 siblings, 1 reply; 58+ messages in thread
From: James Antill @ 2007-04-24 23:12 UTC (permalink / raw)
To: jbrindle; +Cc: selinux
[-- Attachment #1: Type: text/plain, Size: 5523 bytes --]
On Mon, 2007-04-23 at 17:34 -0400, jbrindle@tresys.com wrote:
> This is the majority of the patches from the policy server release a few months ago. This implements object serialization to send objects (eg., booleans, file contexts, etc) across the line to the policy server. It also implements the line protocol to connect to the policy server and the backend for libsemanage so that semodule, semanage, etc will talk to a policy server instead of doing local operations.
>
> The object serialization will also be necessary for the policy representation branch as we will use this infrastructure to serialize the policy tree for module reading and writing.
>
> The only part left for the policy server is the hooks that were implemented in the expander. As the policy representation work is going on and should remove the expander entirely these patches will have to wait until we have enough of the new representation work to implement them there.
>
> This is obviously meant only for trunk and the policyrep branch.
Karl asked me to have a look at this, and I haven't looked at all of
it ... but what I have seen worries me a bit.
[patch 22/33]
status = semanage_unserialize(handle, data, size, (void **)&temp_size,
NULL, SEMANAGE_SERIAL_UINT32_T);
This has the same problem I told Karl about, (foo **) doesn't convert
to (void **) in std. C.
[patch 24/33]
int read_n(semanage_handle_t *sh, int socket_fd, int timeout, char *buf,
size_t n)
int flush_n(semanage_handle_t *sh, int socket_fd, int timeout, uint64_t
n)
Test the result of time() directly against (time_t)-1.
select only easily handles fds upto FD_SETSIZE.
timeout parameter is "interesting" in that it can take upto (timeout *
2) easily, and even (n*timeout) seconds for the worst case.
timeout == 0, means you spin on read() with an O_NONBLOCK fd.
If you get read() == 0, Ie. EOF, you spin until the timeout expires.
int read_msg(semanage_handle_t *sh, int socket_fd, int timeout, uint32_t
* message_type,
uint64_t * data_length, char **data)
Having the parameters be: (len, buf) when read is (buf, len) is a bad
idea, IMO.
int write_msg(semanage_handle_t *sh, int socket_fd, uint32_t
message_type,
uint64_t data_length, char *data)
This doesn't handle EINTR, assumes that writting the msg_header will
happen atomically (and won't get EAGAIN etc.).
Also the use of O_NONBLOCK and a while loop on write are not a good
combination.
int read_server(semanage_handle_t *sh, int socket_fd, uint32_t *
message_type,
uint64_t * data_length, char **data)
WTF is the server sending that you can arbitrarily ignore it????
if (write_msg(handle, fd, PS_PUT_DATABASE, data_length, data))
if (read_server(handle, fd, &message_type, &data_length, &data))
[patch 25/33]
+static int dbase_ps_flush(semanage_handle_t * handle, dbase_config_t *
dconfig)
{
[...]
/* Clean up. */
free(data);
return STATUS_SUCCESS;
err:
ERR(handle, "could not flush database to policy server");
free(data);
free(type);
free(records);
return STATUS_ERR;
}
records/type is leaked on the normal path.
static int dbase_ps_cache(semanage_handle_t * handle, dbase_config_t *
dconfig)
{
[...]
if (semanage_dbase_ps_database_type_serialize(handle,
dbase->database_type, &data, &data_length) != STATUS_SUCCESS)
goto err;
if (write_msg(handle, fd, PS_GET_DATABASE, data_length, data))
goto err;
data = NULL;
data_length = 0;
This leaks data.
int semanage_ps_begintrans(semanage_handle_t * sh)
{
uint32_t response_type = 0;
uint64_t response_length = 0;
char *response = NULL;
err = write_msg(sh, fd, PS_BEGIN_TRANSACTION, 0, NULL);
err = read_server(sh, fd, &response_type, &response_length,
&response);
}
/*
[...]
* The file descriptor will be set to non-blocking mode.
* Return the file descriptor used, -1 if the server could not be
* found, -2 if the server rejected this connection, or -3 for all
* other errors.
*/
int semanage_ps_connect(semanage_handle_t * sh)
Overloading the fd value in this way is pretty hacky.
Also is_connected is set to 1 early in this function, and isn't reset
to 0 on failures.
int semanage_ps_disconnect(semanage_handle_t * sh)
{
[...]
err = close(sh->u.ps_handle.socket_fd);
sh->u.ps_handle.socket_fd = err;
return err;
}
Setting socket_fd to 0, on success, is probably a really bad idea.
This also doesn't reset is_connected to 0.
int semanage_ps_list_modules(semanage_handle_t * sh,
semanage_module_info_t ** modules, int
*num_mods)
This uses C99 variable declarations, is that intentional?
semanage_ps_begintrans
semanage_ps_install_base_module
semanage_ps_install_module
semanage_ps_remove_module
semanage_ps_upgrade_module
Are all basically the same function. And there are a few more which
also C&P this function with a bit added on the end.
static int connect_remote(semanage_handle_t * sh)
Probably at least need a comment that this is IPv4 only, and uses
gethostbyname().
The return value from inet_ntop() isn't checked.
--
James Antill - <james.antill@redhat.com>
setsockopt(fd, IPPROTO_TCP, TCP_CONGESTION, ...);
setsockopt(fd, IPPROTO_TCP, TCP_DEFER_ACCEPT, ...);
setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, ...);
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 58+ messages in thread
* RE: [PATCH 25/33] libsemanage: policy server database hooks
2007-04-24 22:39 ` Joshua Brindle
@ 2007-04-24 23:20 ` Karl MacMillan
2007-04-24 23:57 ` Joshua Brindle
0 siblings, 1 reply; 58+ messages in thread
From: Karl MacMillan @ 2007-04-24 23:20 UTC (permalink / raw)
To: Joshua Brindle; +Cc: selinux
On Tue, 2007-04-24 at 18:39 -0400, Joshua Brindle wrote:
> > From: Karl MacMillan [mailto:kmacmillan@mentalrootkit.com]
> >
> > On Mon, 2007-04-23 at 17:35 -0400, jbrindle@tresys.com wrote:
> > > plain text document attachment (semanage.ps_api.diff)
> > Implements all
> > > database functions for a policy server backend.
> >
> > Any thoughts on how this should be merged? I'm concerned
> > about merging without a working policy server that has been
> > reviewed as well.
> >
>
> Its available, review it ;)
I have - every time you have posted an RFC.
> Note that it won't work with _just_ this
> patch set as it expects the enforcement hooks to be present. It should
> be trivial to comment out all the function pointers to get it to work
> without that though.
>
But there is a working set of patches somewhere?
> > * What are your plans for the policy server - will it be
> > proposed for inclusion upstream?
> >
>
> That was never my intention.
>
Well - that is a problem in my opinion. I think we get two choices:
1) policy server and libsemanage are both upstream and are considered
closely coupled and developed in parallel.
2) protocol for communication with a policy server is well documented
and designed for interop with multiple server implementations.
If you want these huge, intrusive changes for code that won't be part of
upstream I think there needs to be some justification. Why should
upstream take on the maintenance of code that it ultimately can't fix
(because of a huge external dependency)? Why is this better as a
separate project? How will maintenance work? Is a different
implementation of the policy server really feasible or are the changes
really tailored to your specific implementation?
> > * What is the timeline for completion of the policy server?
> >
>
> I sent out an RFC/announcement a while back about its availability on
> oss.tresys.com, noone bothered to respond.
>
I responded - http://marc.info/?l=selinux&m=117286669726063&w=2. That is
where I first asked about an exec based server.
> > * Are their any docs at all about the protocol?
> >
>
> Some, I'll dig them out and post them on oss.
>
> > * Any progress on the exec-based policy server instead of the
> > long running daemon?
> >
>
> The exec-based one has nothing to do with this patchset. The exec based
> policy server would merely run with the new and old policies as
> arguments and do its thing, it would not need to communicate with
> libsemanage.
I don't think that would work - how are you going to detect changes to
port labels or seusers? It would at least be massively inefficient.
You can simply exec the server and communicate over unix-domain sockets
(or a pair pipes). That would make the two servers very similar.
> This patchset is for the long-running daemon that listens
> on a unix domain socket or tcp socket. The exec based one should come
> along with the hook code when that gets ported over to the new
> representation.
>
What is the justification for the long-running daemon?
> > Basically - this patch set is too large to review, there have
> > been no ongoing design discussions, there is no way to review
> > large portions of the patch set due to external dependencies,
> > and I have seen no proposed plan for merging.
> >
>
> There have been occasional RFC's that noone responded to.
>
I've responded to every RFC and stated these concerns every time. Trying
to suggest that nobody has responded is very inaccurate.
> > I have voiced these concerns previously and without at least
> > some of the above I'm opposed merging at this time.
> >
>
> I believe you have some misconceptions about this patchset, read below.
>
I don't think so. Basically - this forms the lowest part of the policy
server protocol. Trying to understand whether these patches make sense
in that context means understanding the system as a whole. Yes you have
posted pieces, but I have not seen something that works end-to-end.
Additionally, you keep posting these massive patch sets. They are not
reviewable in any sane way.
> > I would suggest as an alternative plan you do a depth-first
> > submission instead of the breadth-first approach that you are
> > currently attempting.
> > That would allow a review of the end-to-end design with a
> > relatively small amount of code. From that point expanding
> > the coverage would only require a quick review that the patch
> > continues on the already accepted approach.
> >
> > That steps that I suggest are:
> >
> > * Choose a _single_ and _simple_ semanage operation to control.
> > Something like adding a role to a user.
> >
>
> This patchset nor the hooks currently available do access control on
> semanage operations. Only policy modules have enforcement hooks written
Yes, but they need to eventually and without that serializing all of
these data structures is not useful (at the moment). If they are only
going to be used for the policyrep then we should merge them later and
tailor them for that usage.
> > * Post a minimal policy server that can control this
> > operation (preferably exec-based).
> >
>
> As part of the hooks, yes.
>
> > * Post the libsemange code to communicate with the server
> > _only_ that single operation.
> >
>
> That is silly, to choose a new backend for libsemanage you need all the
> function pointers. Filling in all of them with direct versions except
> for a single one would be at least confusing and at most would break
> badly since both the local semanage and the policy server would attempt
> to lock the store.
>
Of course it would only work for a limited set of operations (and the
rest would likely return an error rather than having direct versions
substituted).
The point is that it would allow review of a smaller set of patches that
makes some sort of sense as a whole. Your submissions are not tailored
for thorough review and any feedback you receive is going to be shallow.
I think that is harmful in the long run.
If others (Steve and Darrell) want to merge these patches that's fine.
But based on the problems I have seen so far, the size of this patch
set, and the _many_ larger questions I'm opposed.
My biggest concern, honestly, is the long term viability and maintenance
of this code.
Karl
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* RE: [PATCH 25/33] libsemanage: policy server database hooks
2007-04-24 23:20 ` Karl MacMillan
@ 2007-04-24 23:57 ` Joshua Brindle
2007-04-25 4:42 ` Karl MacMillan
0 siblings, 1 reply; 58+ messages in thread
From: Joshua Brindle @ 2007-04-24 23:57 UTC (permalink / raw)
To: Karl MacMillan; +Cc: selinux
> From: Karl MacMillan [mailto:kmacmillan@mentalrootkit.com]
>
> On Tue, 2007-04-24 at 18:39 -0400, Joshua Brindle wrote:
> > > From: Karl MacMillan [mailto:kmacmillan@mentalrootkit.com]
> > >
> > > On Mon, 2007-04-23 at 17:35 -0400, jbrindle@tresys.com wrote:
> > > > plain text document attachment (semanage.ps_api.diff)
> > > Implements all
> > > > database functions for a policy server backend.
> > >
> > > Any thoughts on how this should be merged? I'm concerned about
> > > merging without a working policy server that has been reviewed as
> > > well.
> > >
> >
> > Its available, review it ;)
>
> I have - every time you have posted an RFC.
>
I meant the policy server itself.
> > Note that it won't work with _just_ this patch set as it
> expects the
> > enforcement hooks to be present. It should be trivial to
> comment out
> > all the function pointers to get it to work without that though.
> >
>
> But there is a working set of patches somewhere?
>
Yes, which include the hooks, I sent a link to the list which you
responded to:
http://marc.info/?l=selinux&m=117286669726063&w=2
The full set of patches are in the srpms and in the svn tree.
> > > * What are your plans for the policy server - will it be proposed
> > > for inclusion upstream?
> > >
> >
> > That was never my intention.
> >
>
> Well - that is a problem in my opinion. I think we get two choices:
>
> 1) policy server and libsemanage are both upstream and are
> considered closely coupled and developed in parallel.
>
> 2) protocol for communication with a policy server is well
> documented and designed for interop with multiple server
> implementations.
>
I was going to go for #2. It doesn't matter that much to me though, we
could put the policy server in the upstream tree.
> If you want these huge, intrusive changes for code that won't
> be part of upstream I think there needs to be some
> justification. Why should upstream take on the maintenance of
> code that it ultimately can't fix (because of a huge external
> dependency)? Why is this better as a separate project? How
> will maintenance work? Is a different implementation of the
> policy server really feasible or are the changes really
> tailored to your specific implementation?
>
It's a generic protocol and we provide generic hooks (we actually
provide more data in the hooks than my specific implementation uses). I
don't know how useful another implementation would be, though.
> > > * What is the timeline for completion of the policy server?
> > >
> >
> > I sent out an RFC/announcement a while back about its
> availability on
> > oss.tresys.com, noone bothered to respond.
> >
>
> I responded -
> http://marc.info/?l=selinux&m=117286669726063&w=2. That is
> where I first asked about an exec based server.
>
Err.. Right, sorry about that
> > > * Are their any docs at all about the protocol?
> > >
> >
> > Some, I'll dig them out and post them on oss.
> >
> > > * Any progress on the exec-based policy server instead of
> the long
> > > running daemon?
> > >
> >
> > The exec-based one has nothing to do with this patchset. The exec
> > based policy server would merely run with the new and old
> policies as
> > arguments and do its thing, it would not need to communicate with
> > libsemanage.
>
> I don't think that would work - how are you going to detect
> changes to port labels or seusers? It would at least be
> massively inefficient.
>
The policy server will eventually have to implement access control on
ocontext changes and we could just pass the whole active and previous
directories to it to do the things not in policies, like seusers. I
guess we could make it work with a socket pair though.
> You can simply exec the server and communicate over
> unix-domain sockets (or a pair pipes). That would make the
> two servers very similar.
>
> > This patchset is for the long-running daemon that listens
> on a unix
> > domain socket or tcp socket. The exec based one should come
> along with
> > the hook code when that gets ported over to the new representation.
> >
>
> What is the justification for the long-running daemon?
>
Network management.
> > > Basically - this patch set is too large to review, there
> have been
> > > no ongoing design discussions, there is no way to review large
> > > portions of the patch set due to external dependencies,
> and I have
> > > seen no proposed plan for merging.
> > >
> >
> > There have been occasional RFC's that noone responded to.
> >
>
> I've responded to every RFC and stated these concerns every
> time. Trying to suggest that nobody has responded is very inaccurate.
>
Ok, ok, sorry about that mischaractorization.
> > > I have voiced these concerns previously and without at
> least some of
> > > the above I'm opposed merging at this time.
> > >
> >
> > I believe you have some misconceptions about this patchset,
> read below.
> >
>
> I don't think so. Basically - this forms the lowest part of
> the policy server protocol. Trying to understand whether
> these patches make sense in that context means understanding
> the system as a whole. Yes you have posted pieces, but I have
> not seen something that works end-to-end.
>
The stuff on oss works end-to-end.
> Additionally, you keep posting these massive patch sets. They
> are not reviewable in any sane way.
>
Right, we've been sitting on these patches, I'll try to be better about
doing things incrementally in the future (but to be fair this has been
in the works for quite some time).
> > > I would suggest as an alternative plan you do a depth-first
> > > submission instead of the breadth-first approach that you are
> > > currently attempting.
> > > That would allow a review of the end-to-end design with a
> relatively
> > > small amount of code. From that point expanding the
> coverage would
> > > only require a quick review that the patch continues on
> the already
> > > accepted approach.
> > >
> > > That steps that I suggest are:
> > >
> > > * Choose a _single_ and _simple_ semanage operation to control.
> > > Something like adding a role to a user.
> > >
> >
> > This patchset nor the hooks currently available do access
> control on
> > semanage operations. Only policy modules have enforcement hooks
> > written
>
> Yes, but they need to eventually and without that serializing
> all of these data structures is not useful (at the moment).
> If they are only going to be used for the policyrep then we
> should merge them later and tailor them for that usage.
>
They should be useful for both cases. We'll need them for policyrep soon
and for policy server later, I was hoping to have them up and
generalized for both usages.
> > > * Post a minimal policy server that can control this operation
> > > (preferably exec-based).
> > >
> >
> > As part of the hooks, yes.
> >
> > > * Post the libsemange code to communicate with the server _only_
> > > that single operation.
> > >
> >
> > That is silly, to choose a new backend for libsemanage you need all
> > the function pointers. Filling in all of them with direct versions
> > except for a single one would be at least confusing and at
> most would
> > break badly since both the local semanage and the policy
> server would
> > attempt to lock the store.
> >
>
> Of course it would only work for a limited set of operations
> (and the rest would likely return an error rather than having
> direct versions substituted).
>
That won't work with the current libsemanage setup, it'll just fail
anytime you try to do anything.
> The point is that it would allow review of a smaller set of
> patches that makes some sort of sense as a whole. Your
> submissions are not tailored for thorough review and any
> feedback you receive is going to be shallow.
> I think that is harmful in the long run.
>
Yes, big bang integration sucks and this patch set to implement
serialization was much bigger than I'd have liked it to be but its all
done and starting over now makes little sense.
> If others (Steve and Darrell) want to merge these patches that's fine.
> But based on the problems I have seen so far, the size of
> this patch set, and the _many_ larger questions I'm opposed.
>
> My biggest concern, honestly, is the long term viability and
> maintenance of this code.
>
Fair enough.
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* RE: [PATCH 25/33] libsemanage: policy server database hooks
2007-04-24 23:57 ` Joshua Brindle
@ 2007-04-25 4:42 ` Karl MacMillan
0 siblings, 0 replies; 58+ messages in thread
From: Karl MacMillan @ 2007-04-25 4:42 UTC (permalink / raw)
To: Joshua Brindle; +Cc: selinux
On Tue, 2007-04-24 at 19:57 -0400, Joshua Brindle wrote:
> > From: Karl MacMillan [mailto:kmacmillan@mentalrootkit.com]
<snip>
> > Well - that is a problem in my opinion. I think we get two choices:
> >
> > 1) policy server and libsemanage are both upstream and are
> > considered closely coupled and developed in parallel.
> >
> > 2) protocol for communication with a policy server is well
> > documented and designed for interop with multiple server
> > implementations.
> >
>
> I was going to go for #2. It doesn't matter that much to me though, we
> could put the policy server in the upstream tree.
>
For #2 I think we need much more documentation and design review because
it basically becomes a public protocol. That is why I think #1 is better
- then we can just say they are closely coupled and the protocol between
the components is private. It will still need versioning, etc., but
because they are maintained together we will have more freedom.
> > If you want these huge, intrusive changes for code that won't
> > be part of upstream I think there needs to be some
> > justification. Why should upstream take on the maintenance of
> > code that it ultimately can't fix (because of a huge external
> > dependency)? Why is this better as a separate project? How
> > will maintenance work? Is a different implementation of the
> > policy server really feasible or are the changes really
> > tailored to your specific implementation?
> >
>
> It's a generic protocol and we provide generic hooks (we actually
> provide more data in the hooks than my specific implementation uses). I
> don't know how useful another implementation would be, though.
>
I don't think another implementation would be useful, which is why I
think it is better just to upstream the policy server.
> > > > * What is the timeline for completion of the policy server?
> > > >
> > >
> > > I sent out an RFC/announcement a while back about its
> > availability on
> > > oss.tresys.com, noone bothered to respond.
> > >
> >
> > I responded -
> > http://marc.info/?l=selinux&m=117286669726063&w=2. That is
> > where I first asked about an exec based server.
> >
>
> Err.. Right, sorry about that
>
> > > > * Are their any docs at all about the protocol?
> > > >
> > >
> > > Some, I'll dig them out and post them on oss.
> > >
> > > > * Any progress on the exec-based policy server instead of
> > the long
> > > > running daemon?
> > > >
> > >
> > > The exec-based one has nothing to do with this patchset. The exec
> > > based policy server would merely run with the new and old
> > policies as
> > > arguments and do its thing, it would not need to communicate with
> > > libsemanage.
> >
> > I don't think that would work - how are you going to detect
> > changes to port labels or seusers? It would at least be
> > massively inefficient.
> >
>
> The policy server will eventually have to implement access control on
> ocontext changes and we could just pass the whole active and previous
> directories to it to do the things not in policies, like seusers.
It seems a shame to not use the information that we would already have
about what changed.
> I
> guess we could make it work with a socket pair though.
>
That seems to be a gain in efficiency and makes it possible to easily
have a daemon or an exec-based version.
> > You can simply exec the server and communicate over
> > unix-domain sockets (or a pair pipes). That would make the
> > two servers very similar.
> >
> > > This patchset is for the long-running daemon that listens
> > on a unix
> > > domain socket or tcp socket. The exec based one should come
> > along with
> > > the hook code when that gets ported over to the new representation.
> > >
> >
> > What is the justification for the long-running daemon?
> >
>
> Network management.
>
Well - I still think that it is better to just allow proper local
management and let higher-level tools (like
http://reductivelabs.com/projects/puppet/ for example) do the remote
management parts. Plus, I really hesitate to expose something like this
on the network on every client. Using something like puppet lets you use
a pull model.
<snip>
> > >
> > > This patchset nor the hooks currently available do access
> > control on
> > > semanage operations. Only policy modules have enforcement hooks
> > > written
> >
> > Yes, but they need to eventually and without that serializing
> > all of these data structures is not useful (at the moment).
> > If they are only going to be used for the policyrep then we
> > should merge them later and tailor them for that usage.
> >
>
> They should be useful for both cases. We'll need them for policyrep soon
> and for policy server later, I was hoping to have them up and
> generalized for both usages.
>
Ok - looking through these again. If you take out the silly duplication
between libsemanage / libsepol, just one set of serialization patches
are fairly small. I'm not opposed in principal to merging that after the
comments are addressed
(just for libsepol - I think we should remove the libsemanage code).
After that, could you post some more in-depth discussion about the
networking bits?
Karl
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [PATCH 00/33] libsemanage/libsepol object serialization and ps-api
2007-04-24 23:12 ` James Antill
@ 2007-04-25 4:46 ` James Antill
0 siblings, 0 replies; 58+ messages in thread
From: James Antill @ 2007-04-25 4:46 UTC (permalink / raw)
To: jbrindle; +Cc: selinux
[-- Attachment #1: Type: text/plain, Size: 3791 bytes --]
On Tue, 2007-04-24 at 19:12 -0400, James Antill wrote:
> On Mon, 2007-04-23 at 17:34 -0400, jbrindle@tresys.com wrote:
> > This is the majority of the patches from the policy server release a few months ago. This implements object serialization to send objects (eg., booleans, file contexts, etc) across the line to the policy server. It also implements the line protocol to connect to the policy server and the backend for libsemanage so that semodule, semanage, etc will talk to a policy server instead of doing local operations.
> >
> > The object serialization will also be necessary for the policy representation branch as we will use this infrastructure to serialize the policy tree for module reading and writing.
> >
> > The only part left for the policy server is the hooks that were implemented in the expander. As the policy representation work is going on and should remove the expander entirely these patches will have to wait until we have enough of the new representation work to implement them there.
> >
> > This is obviously meant only for trunk and the policyrep branch.
>
> Karl asked me to have a look at this, and I haven't looked at all of
> it ... but what I have seen worries me a bit.
Here's the first parts:
[patch 01]
int sepol_serialize(sepol_handle_t * handle,
const void *datum,
size_t datum_length,
unsigned int datum_type, char **data, uint64_t * size)
This is better fixed by Karl's suggestion of not having a single function, but having datum_length which is ignored for SEPOL_SERIAL_INT32_T etc. is confusing.
The serialization for SEPOL_SERIAL_STRING:
Why are you using snprintf()?
You are moving datum_length into status (size_t into int), which is just asking for pain.
int sepol_unserialize(sepol_handle_t * handle,
char **data, uint64_t * size,
void **datum,
size_t ** datum_length,
unsigned int datum_type)
SEPOL_SERIAL_STRING_ARRAY:
/* Datum. */
*datum =
calloc(sizeof(char *),
sizeof(char *) * (**datum_length));
I'm pretty sure you want calloc(sizeof(char *), **datum_length);
[patch 10]
int dbase_serialize(struct semanage_handle *handle,
dbase_config_t * dconfig,
char **data, uint64_t * data_length)
size_t can still be 32bits, so storing uint64_t's in it might be bad.
I'm not sure I understand what the completed_count is doing, are you leaking anything if the calloc() fails? I think you want to free upto count all the time.
[patch 12]
semanage_serialize is an exact copy of sepol_serialize, AFAICS, so see above.
[patch 16]
I assume semanage_fcontext_get_con(fcontext) doesn't allocate anything, still it'd be nice to not call it twice and just reuse con.
I worry about having semanage_fcontext_unserialize() leave fcontext allocated on failure. A bunch of code does this with arrays ... but even so.
[patch 21]
Dito. user_extra is left allocated on the failure path, in semanage_user_extra_unserialize.
Dito. user is left allocated on the failure path, in semanage_user_unserialize.
[patch 22]
for (i = 0; i < *modules_size; i++) {
/* Module name. */
status = semanage_unserialize(handle, data, size, (void **)&(*modules)[i].name, &temp_size, SEMANAGE_SERIAL_STRING);
if (status != STATUS_SUCCESS)
goto cleanup;
/* Module version. */
status = semanage_unserialize(handle, data, size, (void **)&(*modules)[i].version, &temp_size, SEMANAGE_SERIAL_STRING);
if (status != STATUS_SUCCESS)
goto cleanup;
}
temp_size is allocated on _each call_ to unserialize.
[patch 23]
Why are you calling serialize twice, INT32_T is a fixed size, no?
--
James Antill <jantill@redhat.com>
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 58+ messages in thread
* RE: [PATCH 01/33] libsepol: basic serilization support
2007-04-24 22:29 ` Joshua Brindle
@ 2007-04-25 4:49 ` Karl MacMillan
2007-04-25 14:14 ` Joshua Brindle
0 siblings, 1 reply; 58+ messages in thread
From: Karl MacMillan @ 2007-04-25 4:49 UTC (permalink / raw)
To: Joshua Brindle; +Cc: selinux
On Tue, 2007-04-24 at 18:29 -0400, Joshua Brindle wrote:
> > From: Karl MacMillan [mailto:kmacmillan@mentalrootkit.com]
> >
> > On Mon, 2007-04-23 at 17:34 -0400, jbrindle@tresys.com wrote:
> > > plain text document attachment (sepol.serialize.diff) Serialization
> > > versioning added to the sepol handle.
> > >
> > > Serialization utility functions added in serialize.[ch]
> > > ---
> > > libsepol/include/sepol/handle.h | 17 +
> > > libsepol/src/handle.c | 89 +++++++++
> > > libsepol/src/handle.h | 5
> > > libsepol/src/libsepol.map | 1
> > > libsepol/src/serialize.c | 389
> > ++++++++++++++++++++++++++++++++++++++++
> > > libsepol/src/serialize.h | 45 ++++
> > > 6 files changed, 546 insertions(+)
> > >
> > > Index: selinux-pms-support/libsepol/include/sepol/handle.h
> > > ===================================================================
> > > --- selinux-pms-support.orig/libsepol/include/sepol/handle.h
> > > +++ selinux-pms-support/libsepol/include/sepol/handle.h
> > > @@ -1,6 +1,11 @@
> > > #ifndef _SEPOL_HANDLE_H_
> > > #define _SEPOL_HANDLE_H_
> > >
> > > +#include <inttypes.h>
> > > +
> > > +#define SEPOL_SERIAL_VERSION_MAJOR 1
> > > +#define SEPOL_SERIAL_VERSION_MINOR 0
> > > +
> > > struct sepol_handle;
> > > typedef struct sepol_handle sepol_handle_t;
> > >
> > > @@ -10,4 +15,16 @@ sepol_handle_t *sepol_handle_create(void
> > > /* Destroy a sepol handle. */
> > > void sepol_handle_destroy(sepol_handle_t *);
> > >
> > > +/* Serialize the serialization version. */ int
> > > +sepol_handle_version_serialize(sepol_handle_t * sh, char **data,
> > > +uint64_t *size);
> > > +
> > > +/* Unserialize the serialization version. */ int
> > > +sepol_handle_version_unserialize(sepol_handle_t * sh, char **data,
> > > +uint64_t *size);
> > > +
> > > +/* Get the serialization version. */
> > > +int sepol_handle_get_version(sepol_handle_t *sh, uint32_t * major,
> > > +uint32_t * minor);
> > > +
> > > +/* Set the serialization version. */
> > > +int sepol_handle_set_version(sepol_handle_t *sh, uint32_t major,
> > > +uint32_t minor);
> > > +
> > > #endif
> >
> > Can you give some idea about how the versioning is supposed
> > to work? In
> > particular:
> >
> > * How is it related to the policy version?
> > * Why would it change separately from the policy version?
> > * Is there any advantage to version each component separately
> > rather that a global version?
> >
>
> Most of the stuff we are serializing isn't actually in policy, modules
> are already a serialized version of policy and we don't do anything with
> it, the stuff we are serializing is mostly semanage stuff (file
> contexts, seusers, etc) that have nothing to do with policy.
Well - most of it is closely related.
> The
> per-component versioning was discussed but thought to be too much
> overhead for the number of objects we are serializing.
>
I guess the problem with this is it is hard to know exactly what the
version is for. Per-component headers seem better to me.
> > <snip>
> >
> > > Index: selinux-pms-support/libsepol/src/serialize.c
> > > ===================================================================
> > > --- /dev/null
> > > +++ selinux-pms-support/libsepol/src/serialize.c
> > > @@ -0,0 +1,389 @@
> > > +/* Author: Caleb Case <ccase@tresys.com>
> > > + *
> > > + * Copyright (C) 2004-2007 Tresys Technology, LLC
> > > + *
> > > + * This library is free software; you can redistribute it and/or
> > > + * modify it under the terms of the GNU Lesser General Public
> > > + * License as published by the Free Software Foundation; either
> > > + * version 2.1 of the License, or (at your option) any
> > later version.
> > > + *
> > > + * This library is distributed in the hope that it will be useful,
> > > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
> > See the GNU
> > > + * Lesser General Public License for more details.
> > > + *
> > > + * You should have received a copy of the GNU Lesser
> > General Public
> > > + * License along with this library; if not, write to the Free
> > > +Software
> > > + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
> > > +02110-1301 USA */
> > > +
> > > +#include <stdlib.h>
> > > +#include <string.h>
> > > +#include <limits.h>
> > > +
> > > +#include "handle.h"
> > > +#include "debug.h"
> > > +#include "serialize.h"
> > > +#include "private.h"
> > > +
> > > +/* This file provides general serialize and unserialize
> > functions. */
> > > +
> > > +/** Serializes various kinds of datum.
> > > + *
> > > + * Two use cases:
> > > + * 1) Calling serialize with a non-NULL size.
> > > + * This causes serialize to calculate the expected
> > > + * size of serializing. No serialization occurs.
> > > + * Destructively modifies size. Data may be NULL.
> > > + * 2) Calling serialize with a NULL size.
> > > + * This results in data being filled with the
> > > + * serialized information. Caller must pre-allocate
> > > + * space for data. Destructively modifies data.
> > > + *
> >
> > Why don't you allocate space for the caller? These two use
> > cases are, well, odd. If you allocate then the caller can
> > memcpy and free if they want.
> >
>
> It works basically the same way the current policy serialization works,
> pass in the data once to get size, allocate and pass in the buffer to
> which its being serialized. We did this for consistency with the current
> mechanisms.
>
I'm not certain that I would use the current policy serialization code
as an example for anything - it is very difficult to work with.
> > > + * This function acts iteratively moving the *data or size values.
> > > + *
> > > + * Supported datum_types (defined in serialize.h):
> > > + *
> > > + * SEPOL_SERIAL_INT32_T
> > > + * Serializes datum to a int32_t as defined in inttypes.h
> > > + * datum may NOT be NULL.
> > > + * datum_length is not utilized.
> > > + * SEPOL_SERIAL_UINT32_T
> > > + * Serializes datum to a uint32_t as defined in inttypes.h
> > > + * datum may NOT be NULL.
> > > + * datum_length is not utilized.
> > > + * SEPOL_SERIAL_SIZE_T
> > > + * Serializes datum to a size_t as defined in stddef.h
> > > + * datum may NOT be NULL.
> > > + * datum_length is not utilized.
> >
> > How can you serialize a type that is platform specific? How
> > would this be handled when communication between a 32 and 64
> > bit host? I thought we always used fixed width types for all
> > binary communication anyway.
> >
>
> SEPOL_SERIAL_SIZE_T is always 64 bits. We should be checking if it tries
> to serialize into a smaller type, if not that's a bug.
>
How can that be? On a 64bit platform I can represent a size that can't
be represented by a 32bit size_t. How can I transfer this data to a
32bit system? I can't put it in a data structure with size_t - it would
have to be unint64_t. So why not just use that?
> > > + * SEPOL_SERIAL_STRING
> > > + * Serializes a char*.
> > > + * datum may be NULL.
> > > + * datum_length should be the length of the string as
> > returned by strlen.
> >
> > Why not call strlen? Especially since the string array version does.
> >
>
> IIRC because we use the same entry point for all data types to get to
> these.
>
But you know it is a string.
> > > + * SEPOL_SERIAL_STRING_ARRAY
> > > + * Serializes a char**.
> > > + * datum may be NULL.
> > > + * datum_length should be the size of the array.
> > > + * Each string will be serialized as per
> > SEPOL_SERIAL_STRING and its size
> > > + * determined via strlen.
> > > + *
> > > + * NULL pointers are distinguished (where they are
> > allowed at all).
> > > + * In the case of strings this means that a NULL char* has a
> > > + different
> > > + * serialization from the empty string "".
> >
> > Why?
> >
>
> Not sure, will check.
>
> > > + *
> > > + */
> > > +int sepol_serialize(sepol_handle_t * handle,
> > > + const void *datum,
> > > + size_t datum_length,
> > > + unsigned int datum_type, char **data,
> > uint64_t * size) {
> >
> > Why a single multiplexed function? Seems _much_ easier to
> > have a sepol_serialize_string, sepol_serialize_uint32, etc.
> > This would allow type safety and improve readability, both at
> > the call site and the definition.
> >
>
> We can do that I guess, IMO it doesn't make much of a difference.
>
I think it makes a big difference.
> >
> > <snip>
> >
> > > + case SEPOL_SERIAL_SIZE_T:
> > > + if (size == NULL) {
> > > + temp = calloc(1, sizeof(uint64_t));
> > > + if (temp == NULL) {
> > > + status = STATUS_ERR;
> > > + goto cleanup;
> > > + }
> > > +
> > > + *((uint64_t *)temp) =
> > cpu_to_le64(*((size_t *) datum));
> > > +
> > > + memcpy(*data, temp, sizeof(uint64_t));
> > > + *data += sizeof(uint64_t);
> > > + }
> > > + else
> > > + *size += sizeof(uint64_t);
> > > + break;
> >
> > Err - I don't think this is allowed. I believe that size_t is
> > supposed to be word size and there is no reason that word
> > size is limited to 64 bits.
> >
>
> IIRC in ANSI C it is limited to 64 bits. I might be wrong on this but I
> remember us looking it up when this happened.
>
That sounds unlikely, but more importantly, why? Why not just use
uint64_t?
Karl
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [PATCH 02/33] libsepol: boolean serialization
2007-04-23 21:34 ` [PATCH 02/33] libsepol: boolean serialization jbrindle
@ 2007-04-25 4:56 ` Karl MacMillan
0 siblings, 0 replies; 58+ messages in thread
From: Karl MacMillan @ 2007-04-25 4:56 UTC (permalink / raw)
To: jbrindle; +Cc: selinux
On Mon, 2007-04-23 at 17:34 -0400, jbrindle@tresys.com wrote:
<snip>
> +
> +/* Serialize/Unserialize */
> +/** Destructively modifies data and size.
> + * Caller must pre-allocate space for data.
> + * Use sepol_bool_calculate_serialized_size(). */
> +int sepol_bool_serialize(sepol_handle_t * handle,
> + const sepol_bool_t * boolean,
> + char **data, uint64_t * size)
> +{
> + int status = STATUS_SUCCESS;
> + const char *name = NULL;
> + int value;
> +
> + /* Sundry sanity checks. */
> + if (handle == NULL || boolean == NULL) {
> + status = STATUS_ERR;
> + goto cleanup;
> + }
> +
Why not assert here?
> + /* Boolean name. */
> + name = sepol_bool_get_name(boolean);
> + status =
> + sepol_serialize(handle, name, (name == NULL) ? 0 : strlen(name),
> + SEPOL_SERIAL_STRING, data, size);
Why doesn't the serialization function handle null strings?
> + if (status != STATUS_SUCCESS)
> + goto cleanup;
> +
> + /* Value of boolean. */
> + value = sepol_bool_get_value(boolean);
> + status = sepol_serialize(handle, &value, 0, SEPOL_SERIAL_INT32_T, data, size);
> + if (status != STATUS_SUCCESS)
> + goto cleanup;
> +
I think that it would be nice to put a header on each of these
serialized chunks that identifies what the data represents (e.g.,
boolean, seuser, etc). You could add a version there. That would also
allow you to generically handle lists of objects and, in the future,
trees of these for the policy rep work.
> + /* Cleanup. */
> + cleanup:
> + return status;
Why use this idiom when there is no cleanup?
> +}
> +
> +hidden_def(sepol_bool_serialize)
> +
> +/** Destructively modifies boolean, data and size.
> + * Allocates space for boolean.
> + * Caller must free. */
> +int sepol_bool_unserialize(sepol_handle_t * handle,
> + char **data, uint64_t * size,
> + sepol_bool_t ** boolean)
> +{
> + int status = STATUS_SUCCESS;
> + char *name = NULL;
> + size_t *name_size = NULL;
> + int *value = NULL;
> +
> + /* Sundry sanity checks. */
> + if (handle == NULL || data == NULL || *data == NULL || size == NULL) {
> + status = STATUS_ERR;
> + goto cleanup;
> + }
> +
> + /* Allocate space. */
> + status = sepol_bool_create(handle, boolean);
> + if (status != STATUS_SUCCESS)
> + goto cleanup;
> +
> + /* Boolean name. */
> + status =
> + sepol_unserialize(handle,
> + data, size,
> + (void **)&name, &name_size, SEPOL_SERIAL_STRING);
As James said - this isn't valid. Another reason to have the type safe
versions.
Karl
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* RE: [PATCH 01/33] libsepol: basic serilization support
2007-04-25 4:49 ` Karl MacMillan
@ 2007-04-25 14:14 ` Joshua Brindle
2007-04-25 15:16 ` Karl MacMillan
0 siblings, 1 reply; 58+ messages in thread
From: Joshua Brindle @ 2007-04-25 14:14 UTC (permalink / raw)
To: Karl MacMillan; +Cc: selinux
> From: Karl MacMillan [mailto:kmacmillan@mentalrootkit.com]
<snip>
> > The
> > per-component versioning was discussed but thought to be too much
> > overhead for the number of objects we are serializing.
> >
>
> I guess the problem with this is it is hard to know exactly
> what the version is for. Per-component headers seem better to me.
>
Ok, we can talk about it but it seems like a lot of overhead for no good
reason to version everything.
> > > <snip>
> > It works basically the same way the current policy serialization
> > works, pass in the data once to get size, allocate and pass in the
> > buffer to which its being serialized. We did this for
> consistency with
> > the current mechanisms.
> >
>
> I'm not certain that I would use the current policy
> serialization code as an example for anything - it is very
> difficult to work with.
>
Fair enough.
> >
> > SEPOL_SERIAL_SIZE_T is always 64 bits. We should be checking if it
> > tries to serialize into a smaller type, if not that's a bug.
> >
>
> How can that be? On a 64bit platform I can represent a size
> that can't be represented by a 32bit size_t. How can I
> transfer this data to a 32bit system? I can't put it in a
> data structure with size_t - it would have to be unint64_t.
> So why not just use that?
>
That's why I said "We should be checking if it tries to serialize into a
smaller type, if not that's a bug"
IIRC we needed something that could serialize/unserialize size_t because
its used in some components that we serialize. We could always cast to
uint64_t and serialize it that way (which is pretty much what we are
doing anyway).
> >
> > IIRC because we use the same entry point for all data types
> to get to
> > these.
> >
>
> But you know it is a string.
>
Fine.
> > > > + * SEPOL_SERIAL_STRING_ARRAY
> > > > + * Serializes a char**.
> > > > + * datum may be NULL.
> > > > + * datum_length should be the size of the array.
> > > > + * Each string will be serialized as per
> > > SEPOL_SERIAL_STRING and its size
> > > > + * determined via strlen.
> > > > + *
> > > > + * NULL pointers are distinguished (where they are
> > > allowed at all).
> > > > + * In the case of strings this means that a NULL char* has a
> > > > + different
> > > > + * serialization from the empty string "".
> > >
> > > Why?
> > >
> >
> > Not sure, will check.
> >
> > > > + *
> > > > + */
> > > > +int sepol_serialize(sepol_handle_t * handle,
> > > > + const void *datum,
> > > > + size_t datum_length,
> > > > + unsigned int datum_type, char **data,
> > > uint64_t * size) {
> > >
> > > Why a single multiplexed function? Seems _much_ easier to have a
> > > sepol_serialize_string, sepol_serialize_uint32, etc.
> > > This would allow type safety and improve readability, both at the
> > > call site and the definition.
> > >
> >
> > We can do that I guess, IMO it doesn't make much of a difference.
> >
>
> I think it makes a big difference.
>
I don't know why, this is closer to what we want anyway, where we can
just call object->serialize and get a serialized version.
> > >
> > > <snip>
> > >
> > > > + case SEPOL_SERIAL_SIZE_T:
> > > > + if (size == NULL) {
> > > > + temp = calloc(1,
> sizeof(uint64_t));
> > > > + if (temp == NULL) {
> > > > + status = STATUS_ERR;
> > > > + goto cleanup;
> > > > + }
> > > > +
> > > > + *((uint64_t *)temp) =
> > > cpu_to_le64(*((size_t *) datum));
> > > > +
> > > > + memcpy(*data, temp,
> sizeof(uint64_t));
> > > > + *data += sizeof(uint64_t);
> > > > + }
> > > > + else
> > > > + *size += sizeof(uint64_t);
> > > > + break;
> > >
> > > Err - I don't think this is allowed. I believe that size_t is
> > > supposed to be word size and there is no reason that word size is
> > > limited to 64 bits.
> > >
> >
> > IIRC in ANSI C it is limited to 64 bits. I might be wrong
> on this but
> > I remember us looking it up when this happened.
> >
>
> That sounds unlikely, but more importantly, why? Why not just
> use uint64_t?
>
Because some things we serialize are size_t so we must unserialize into
size_t.
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* RE: [PATCH 01/33] libsepol: basic serilization support
2007-04-25 14:14 ` Joshua Brindle
@ 2007-04-25 15:16 ` Karl MacMillan
2007-04-25 15:21 ` Joshua Brindle
0 siblings, 1 reply; 58+ messages in thread
From: Karl MacMillan @ 2007-04-25 15:16 UTC (permalink / raw)
To: Joshua Brindle; +Cc: selinux
On Wed, 2007-04-25 at 10:14 -0400, Joshua Brindle wrote:
> > From: Karl MacMillan [mailto:kmacmillan@mentalrootkit.com]
<snip>
> > >
> > > SEPOL_SERIAL_SIZE_T is always 64 bits. We should be checking if it
> > > tries to serialize into a smaller type, if not that's a bug.
> > >
> >
> > How can that be? On a 64bit platform I can represent a size
> > that can't be represented by a 32bit size_t. How can I
> > transfer this data to a 32bit system? I can't put it in a
> > data structure with size_t - it would have to be unint64_t.
> > So why not just use that?
> >
>
> That's why I said "We should be checking if it tries to serialize into a
> smaller type, if not that's a bug"
>
> IIRC we needed something that could serialize/unserialize size_t because
> its used in some components that we serialize. We could always cast to
> uint64_t and serialize it that way (which is pretty much what we are
> doing anyway).
>
Something is going wrong in our communication here. You _cannot_
reliably transfer size_t from a 64bit system to a 32bit system (assuming
that size_t is 64 and 32 bits respectively). That means that you cannot
reliably serialize data structures that use size_t - you must change the
data structures. Otherwise the serialized data will not be valid on all
systems.
There is no way to check "if it tries to serialize into a smaller type"
- you will always hit this condition at some point.
As for the size, C99 says:
"The value of the result [of sizeof] is implementation-defined, and its
type (an unsigned integer type) is size_t,"
Later it says:
"The types used for size_t and ptrdiff_t should not have an integer
conversion rank greater than that of signed long int unless the
implementation supports objects large enough to make this necessary."
I read that to say that the width of size_t is implementation defined
and could be larger that 64 bits.
Karl
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* RE: [PATCH 01/33] libsepol: basic serilization support
2007-04-25 15:16 ` Karl MacMillan
@ 2007-04-25 15:21 ` Joshua Brindle
2007-04-25 15:40 ` Karl MacMillan
0 siblings, 1 reply; 58+ messages in thread
From: Joshua Brindle @ 2007-04-25 15:21 UTC (permalink / raw)
To: Karl MacMillan; +Cc: selinux
> From: Karl MacMillan [mailto:kmacmillan@mentalrootkit.com]
>
> On Wed, 2007-04-25 at 10:14 -0400, Joshua Brindle wrote:
> > > From: Karl MacMillan [mailto:kmacmillan@mentalrootkit.com]
>
> <snip>
>
> > > >
> > > > SEPOL_SERIAL_SIZE_T is always 64 bits. We should be
> checking if it
> > > > tries to serialize into a smaller type, if not that's a bug.
> > > >
> > >
> > > How can that be? On a 64bit platform I can represent a size that
> > > can't be represented by a 32bit size_t. How can I
> transfer this data
> > > to a 32bit system? I can't put it in a data structure
> with size_t -
> > > it would have to be unint64_t.
> > > So why not just use that?
> > >
> >
> > That's why I said "We should be checking if it tries to
> serialize into
> > a smaller type, if not that's a bug"
> >
> > IIRC we needed something that could serialize/unserialize size_t
> > because its used in some components that we serialize. We
> could always
> > cast to uint64_t and serialize it that way (which is pretty
> much what
> > we are doing anyway).
> >
>
> Something is going wrong in our communication here. You
> _cannot_ reliably transfer size_t from a 64bit system to a
> 32bit system (assuming that size_t is 64 and 32 bits
> respectively). That means that you cannot reliably serialize
> data structures that use size_t - you must change the data
> structures. Otherwise the serialized data will not be valid
> on all systems.
>
> There is no way to check "if it tries to serialize into a
> smaller type"
> - you will always hit this condition at some point.
>
> As for the size, C99 says:
>
> "The value of the result [of sizeof] is
> implementation-defined, and its type (an unsigned integer
> type) is size_t,"
>
> Later it says:
>
> "The types used for size_t and ptrdiff_t should not have an
> integer conversion rank greater than that of signed long int
> unless the implementation supports objects large enough to
> make this necessary."
>
> I read that to say that the width of size_t is implementation
> defined and could be larger that 64 bits.
How do you suppose we should serialize variables that are normally
size_t then? For example, a policy module is essentially a file that
gets sent across and has a length of size_t, all the policy module
functions (eg., sepol_load_policy, etc) use a size_t so we have to
serialize it and unserialize it in some way.
There is an assumption here that a policy file will never be longer than
uint64 long, probably a fair assumption. On 32 bit systems I'll cast
into a 32 bit and if its too long it should error out.
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* RE: [PATCH 01/33] libsepol: basic serilization support
2007-04-25 15:21 ` Joshua Brindle
@ 2007-04-25 15:40 ` Karl MacMillan
2007-04-25 15:52 ` Joshua Brindle
0 siblings, 1 reply; 58+ messages in thread
From: Karl MacMillan @ 2007-04-25 15:40 UTC (permalink / raw)
To: Joshua Brindle; +Cc: selinux
On Wed, 2007-04-25 at 11:21 -0400, Joshua Brindle wrote:
> > From: Karl MacMillan [mailto:kmacmillan@mentalrootkit.com]
> >
> > On Wed, 2007-04-25 at 10:14 -0400, Joshua Brindle wrote:
> > > > From: Karl MacMillan [mailto:kmacmillan@mentalrootkit.com]
> >
> > <snip>
> >
> > > > >
> > > > > SEPOL_SERIAL_SIZE_T is always 64 bits. We should be
> > checking if it
> > > > > tries to serialize into a smaller type, if not that's a bug.
> > > > >
> > > >
> > > > How can that be? On a 64bit platform I can represent a size that
> > > > can't be represented by a 32bit size_t. How can I
> > transfer this data
> > > > to a 32bit system? I can't put it in a data structure
> > with size_t -
> > > > it would have to be unint64_t.
> > > > So why not just use that?
> > > >
> > >
> > > That's why I said "We should be checking if it tries to
> > serialize into
> > > a smaller type, if not that's a bug"
> > >
> > > IIRC we needed something that could serialize/unserialize size_t
> > > because its used in some components that we serialize. We
> > could always
> > > cast to uint64_t and serialize it that way (which is pretty
> > much what
> > > we are doing anyway).
> > >
> >
> > Something is going wrong in our communication here. You
> > _cannot_ reliably transfer size_t from a 64bit system to a
> > 32bit system (assuming that size_t is 64 and 32 bits
> > respectively). That means that you cannot reliably serialize
> > data structures that use size_t - you must change the data
> > structures. Otherwise the serialized data will not be valid
> > on all systems.
> >
> > There is no way to check "if it tries to serialize into a
> > smaller type"
> > - you will always hit this condition at some point.
> >
> > As for the size, C99 says:
> >
> > "The value of the result [of sizeof] is
> > implementation-defined, and its type (an unsigned integer
> > type) is size_t,"
> >
> > Later it says:
> >
> > "The types used for size_t and ptrdiff_t should not have an
> > integer conversion rank greater than that of signed long int
> > unless the implementation supports objects large enough to
> > make this necessary."
> >
> > I read that to say that the width of size_t is implementation
> > defined and could be larger that 64 bits.
>
> How do you suppose we should serialize variables that are normally
> size_t then? For example, a policy module is essentially a file that
> gets sent across and has a length of size_t, all the policy module
> functions (eg., sepol_load_policy, etc) use a size_t so we have to
> serialize it and unserialize it in some way.
>
You define the size as uint64_t or uint32_t and check for overflow
everywhere you convert from size_t (or long for things like fseek).
> There is an assumption here that a policy file will never be longer than
> uint64 long, probably a fair assumption. On 32 bit systems I'll cast
> into a 32 bit and if its too long it should error out.
Are you using this only for policy file offsets or for length? I would
consider using uint32_t - that is likely sufficient.
Karl
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* RE: [PATCH 01/33] libsepol: basic serilization support
2007-04-25 15:40 ` Karl MacMillan
@ 2007-04-25 15:52 ` Joshua Brindle
2007-04-25 16:00 ` Karl MacMillan
0 siblings, 1 reply; 58+ messages in thread
From: Joshua Brindle @ 2007-04-25 15:52 UTC (permalink / raw)
To: Karl MacMillan; +Cc: selinux
> From: Karl MacMillan [mailto:kmacmillan@mentalrootkit.com]
>
> On Wed, 2007-04-25 at 11:21 -0400, Joshua Brindle wrote:
> > > From: Karl MacMillan [mailto:kmacmillan@mentalrootkit.com]
> > >
> > > On Wed, 2007-04-25 at 10:14 -0400, Joshua Brindle wrote:
> > > > > From: Karl MacMillan [mailto:kmacmillan@mentalrootkit.com]
> > >
> > > <snip>
> > >
> > > > > >
> > > > > > SEPOL_SERIAL_SIZE_T is always 64 bits. We should be
> > > checking if it
> > > > > > tries to serialize into a smaller type, if not that's a bug.
> > > > > >
> > > > >
> > > > > How can that be? On a 64bit platform I can represent
> a size that
> > > > > can't be represented by a 32bit size_t. How can I
> > > transfer this data
> > > > > to a 32bit system? I can't put it in a data structure
> > > with size_t -
> > > > > it would have to be unint64_t.
> > > > > So why not just use that?
> > > > >
> > > >
> > > > That's why I said "We should be checking if it tries to
> > > serialize into
> > > > a smaller type, if not that's a bug"
> > > >
> > > > IIRC we needed something that could
> serialize/unserialize size_t
> > > > because its used in some components that we serialize. We
> > > could always
> > > > cast to uint64_t and serialize it that way (which is pretty
> > > much what
> > > > we are doing anyway).
> > > >
> > >
> > > Something is going wrong in our communication here. You _cannot_
> > > reliably transfer size_t from a 64bit system to a 32bit system
> > > (assuming that size_t is 64 and 32 bits respectively). That means
> > > that you cannot reliably serialize data structures that
> use size_t -
> > > you must change the data structures. Otherwise the
> serialized data
> > > will not be valid on all systems.
> > >
> > > There is no way to check "if it tries to serialize into a smaller
> > > type"
> > > - you will always hit this condition at some point.
> > >
> > > As for the size, C99 says:
> > >
> > > "The value of the result [of sizeof] is
> implementation-defined, and
> > > its type (an unsigned integer
> > > type) is size_t,"
> > >
> > > Later it says:
> > >
> > > "The types used for size_t and ptrdiff_t should not have
> an integer
> > > conversion rank greater than that of signed long int unless the
> > > implementation supports objects large enough to make this
> > > necessary."
> > >
> > > I read that to say that the width of size_t is implementation
> > > defined and could be larger that 64 bits.
> >
> > How do you suppose we should serialize variables that are normally
> > size_t then? For example, a policy module is essentially a
> file that
> > gets sent across and has a length of size_t, all the policy module
> > functions (eg., sepol_load_policy, etc) use a size_t so we have to
> > serialize it and unserialize it in some way.
> >
>
> You define the size as uint64_t or uint32_t and check for
> overflow everywhere you convert from size_t (or long for
> things like fseek).
>
*sigh* I must not be making myself clear. That's what we are doing.
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* RE: [PATCH 01/33] libsepol: basic serilization support
2007-04-25 15:52 ` Joshua Brindle
@ 2007-04-25 16:00 ` Karl MacMillan
2007-04-25 16:25 ` Joshua Brindle
0 siblings, 1 reply; 58+ messages in thread
From: Karl MacMillan @ 2007-04-25 16:00 UTC (permalink / raw)
To: Joshua Brindle; +Cc: selinux
On Wed, 2007-04-25 at 11:52 -0400, Joshua Brindle wrote:
> > From: Karl MacMillan [mailto:kmacmillan@mentalrootkit.com]
<snip>
> > >
> > > How do you suppose we should serialize variables that are normally
> > > size_t then? For example, a policy module is essentially a
> > file that
> > > gets sent across and has a length of size_t, all the policy module
> > > functions (eg., sepol_load_policy, etc) use a size_t so we have to
> > > serialize it and unserialize it in some way.
> > >
> >
> > You define the size as uint64_t or uint32_t and check for
> > overflow everywhere you convert from size_t (or long for
> > things like fseek).
> >
>
> *sigh* I must not be making myself clear. That's what we are doing.
No - it is about where you are doing the checking. This doesn't belong
in the generic layer because it obscures what the problem is. It belongs
at the call site that interprets the fields.
Offering to serialize size_t is not a good interface - it makes it look
like you are actually handling the problem when you are not. By forcing
all of the serialized data into fixed-width types you are bringing the
problem to the foreground.
That way the representation is always clear and valid and good error
messages can be generated.
Karl
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* RE: [PATCH 01/33] libsepol: basic serilization support
2007-04-25 16:00 ` Karl MacMillan
@ 2007-04-25 16:25 ` Joshua Brindle
2007-04-25 17:11 ` James Antill
0 siblings, 1 reply; 58+ messages in thread
From: Joshua Brindle @ 2007-04-25 16:25 UTC (permalink / raw)
To: Karl MacMillan; +Cc: selinux
> From: Karl MacMillan [mailto:kmacmillan@mentalrootkit.com]
>
> On Wed, 2007-04-25 at 11:52 -0400, Joshua Brindle wrote:
> > > From: Karl MacMillan [mailto:kmacmillan@mentalrootkit.com]
>
> <snip>
>
> > > >
> > > > How do you suppose we should serialize variables that
> are normally
> > > > size_t then? For example, a policy module is essentially a
> > > file that
> > > > gets sent across and has a length of size_t, all the
> policy module
> > > > functions (eg., sepol_load_policy, etc) use a size_t so
> we have to
> > > > serialize it and unserialize it in some way.
> > > >
> > >
> > > You define the size as uint64_t or uint32_t and check for
> overflow
> > > everywhere you convert from size_t (or long for things
> like fseek).
> > >
> >
> > *sigh* I must not be making myself clear. That's what we are doing.
>
> No - it is about where you are doing the checking. This
> doesn't belong in the generic layer because it obscures what
> the problem is. It belongs at the call site that interprets
> the fields.
>
> Offering to serialize size_t is not a good interface - it
> makes it look like you are actually handling the problem when
> you are not. By forcing all of the serialized data into
> fixed-width types you are bringing the problem to the foreground.
>
> That way the representation is always clear and valid and
> good error messages can be generated.
>
So move boiler plate casting and checking to the call site? I guess we
can do that... :\
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* RE: [PATCH 01/33] libsepol: basic serilization support
2007-04-25 16:25 ` Joshua Brindle
@ 2007-04-25 17:11 ` James Antill
2007-04-25 18:08 ` Karl MacMillan
0 siblings, 1 reply; 58+ messages in thread
From: James Antill @ 2007-04-25 17:11 UTC (permalink / raw)
To: Joshua Brindle; +Cc: Karl MacMillan, selinux
[-- Attachment #1: Type: text/plain, Size: 1321 bytes --]
On Wed, 2007-04-25 at 12:25 -0400, Joshua Brindle wrote:
> So move boiler plate casting and checking to the call site? I guess we
> can do that... :\
Having a wrapper that does it for you isn't such a bad thing, and
calling that wrapper serialize_sizet/unserialize_sizet or whatever isn't
the worst thing in the world[1].
The problem, from my POV, is that you check on the receiving side if
size_t happens to be bigger than uint32_t[2]. You are basically sending
a uint64_t over the network that can never hold a value bigger than a
uint32_t, so everything gets to send extra zeros. This is very
misleading, just say what you mean by having the protocol use uint32_t,
and check at the sending side if the value > uint32_t can hold, if so
error in some way.
Dito with SERIAL_STRING (although that probably fails by accident
atm.), just fail to ever send "large" strings, and use uint32_t for the
length. You should probably also pick a limit on receive instead of
hoping calloc() will save you.
[1] Although an interface name that makes it obvious the size_t is going
to be down converted to uint32_t would be better.
[2] Well it actually uses (unsigned int), via. UINT_MAX, which is
another bug as it should be using UINT32_MAX from stdint.h.
--
James Antill <jantill@redhat.com>
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 58+ messages in thread
* RE: [PATCH 01/33] libsepol: basic serilization support
2007-04-25 17:11 ` James Antill
@ 2007-04-25 18:08 ` Karl MacMillan
0 siblings, 0 replies; 58+ messages in thread
From: Karl MacMillan @ 2007-04-25 18:08 UTC (permalink / raw)
To: James Antill; +Cc: Joshua Brindle, selinux
On Wed, 2007-04-25 at 13:11 -0400, James Antill wrote:
> On Wed, 2007-04-25 at 12:25 -0400, Joshua Brindle wrote:
>
> > So move boiler plate casting and checking to the call site? I guess we
> > can do that... :\
>
> Having a wrapper that does it for you isn't such a bad thing, and
> calling that wrapper serialize_sizet/unserialize_sizet or whatever isn't
> the worst thing in the world[1].
Like serialize_sizet_to_uint32.
> The problem, from my POV, is that you check on the receiving side if
> size_t happens to be bigger than uint32_t[2]. You are basically sending
> a uint64_t over the network that can never hold a value bigger than a
> uint32_t, so everything gets to send extra zeros. This is very
> misleading, just say what you mean by having the protocol use uint32_t,
> and check at the sending side if the value > uint32_t can hold, if so
> error in some way.
>
I would say that the problem is more general. The goal here is to
serialize data structures - i.e., convert the data structure to/from a
byte stream. Unfortunately, you are using data structures that you
cannot reliably turn into a byte stream.
So the solution is to change the data structures and check for overflow
when you insert into the data structure not when you [un]serialize the
structure. As James points out, this approach will put the error much
closer to the failure point. As it stands now the error is as far away
from the failure point as possible (and possibly on another system
entirely).
I would suggest:
sepol_sizet_to_uint32: conversion only - checks for overflow
sepol_serialize_uint32: serialize only
Karl
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
end of thread, other threads:[~2007-04-25 18:08 UTC | newest]
Thread overview: 58+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-04-23 21:34 [PATCH 00/33] libsemanage/libsepol object serialization and ps-api jbrindle
2007-04-23 21:34 ` [PATCH 01/33] libsepol: basic serilization support jbrindle
2007-04-24 20:00 ` Karl MacMillan
2007-04-24 22:29 ` Joshua Brindle
2007-04-25 4:49 ` Karl MacMillan
2007-04-25 14:14 ` Joshua Brindle
2007-04-25 15:16 ` Karl MacMillan
2007-04-25 15:21 ` Joshua Brindle
2007-04-25 15:40 ` Karl MacMillan
2007-04-25 15:52 ` Joshua Brindle
2007-04-25 16:00 ` Karl MacMillan
2007-04-25 16:25 ` Joshua Brindle
2007-04-25 17:11 ` James Antill
2007-04-25 18:08 ` Karl MacMillan
2007-04-23 21:34 ` [PATCH 02/33] libsepol: boolean serialization jbrindle
2007-04-25 4:56 ` Karl MacMillan
2007-04-23 21:34 ` [PATCH 03/33] libsepol: context serialization jbrindle
2007-04-23 21:34 ` [PATCH 04/33] libsepol: interface serialization jbrindle
2007-04-23 21:35 ` [PATCH 05/33] libsepol: node serialization jbrindle
2007-04-23 21:35 ` [PATCH 06/33] libsepol: port serialization jbrindle
2007-04-23 21:35 ` [PATCH 07/33] libsepol: user serialization jbrindle
2007-04-23 21:35 ` [PATCH 08/33] libsemanage: DESTDIR support in INCLUDE and safe test target jbrindle
2007-04-23 21:35 ` [PATCH 09/33] libsemanage: dbase/dconfig cleanup jbrindle
2007-04-23 21:35 ` [PATCH 10/33] libsemanage: database serialization jbrindle
2007-04-23 21:35 ` [PATCH 11/33] libsemanage: endianness macros jbrindle
2007-04-23 21:35 ` [PATCH 12/33] libsemanage: basic serialization jbrindle
2007-04-24 21:16 ` Karl MacMillan
2007-04-24 22:31 ` Joshua Brindle
2007-04-24 22:39 ` Karl MacMillan
2007-04-23 21:35 ` [PATCH 13/33] libsemanage: testing infrastructure jbrindle
2007-04-23 21:35 ` [PATCH 14/33] libsemanage: boolean serialization jbrindle
2007-04-23 21:35 ` [PATCH 15/33] libsemanage: context serialization jbrindle
2007-04-23 21:35 ` [PATCH 16/33] libsemanage: fcontext serialization jbrindle
2007-04-23 21:35 ` [PATCH 17/33] libsemanage: interface serialization jbrindle
2007-04-23 21:35 ` [PATCH 18/33] libsemanage: node serialization jbrindle
2007-04-23 21:35 ` [PATCH 19/33] libsemanage: port serialization jbrindle
2007-04-23 21:35 ` [PATCH 20/33] libsemanage: seuser serialization jbrindle
2007-04-23 21:35 ` [PATCH 21/33] libsemanage: user serialization jbrindle
2007-04-23 21:35 ` [PATCH 22/33] libsemanage: module serialization jbrindle
2007-04-23 21:35 ` [PATCH 23/33] libsemanage: commit number serialization jbrindle
2007-04-23 21:35 ` [PATCH 24/33] libsemanage: networking support jbrindle
2007-04-23 21:35 ` [PATCH 25/33] libsemanage: policy server database hooks jbrindle
2007-04-24 21:39 ` Karl MacMillan
2007-04-24 22:39 ` Joshua Brindle
2007-04-24 23:20 ` Karl MacMillan
2007-04-24 23:57 ` Joshua Brindle
2007-04-25 4:42 ` Karl MacMillan
2007-04-23 21:35 ` [PATCH 26/33] libsemanage: module serialization tests jbrindle
2007-04-23 21:35 ` [PATCH 27/33] libsemanage: booleans " jbrindle
2007-04-23 21:35 ` [PATCH 28/33] libsemanage: fcontexts " jbrindle
2007-04-23 21:35 ` [PATCH 29/33] libsemanage: interface " jbrindle
2007-04-23 21:35 ` [PATCH 30/33] libsemanage: node " jbrindle
2007-04-23 21:35 ` [PATCH 31/33] libsemanage: port " jbrindle
2007-04-23 21:35 ` [PATCH 32/33] libsemanage: seuser " jbrindle
2007-04-23 21:35 ` [PATCH 33/33] libsemanage: user " jbrindle
2007-04-24 19:48 ` [PATCH 00/33] libsemanage/libsepol object serialization and ps-api Joshua Brindle
2007-04-24 23:12 ` James Antill
2007-04-25 4:46 ` James Antill
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.