/* Copyright (C) 2005 Red Hat, Inc. */

struct semanage_user_base;
struct semanage_user_key;
typedef struct semanage_user_base 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 <ctype.h>
#include <string.h>
#include <semanage/handle.h>
#include "user_internal.h"
#include "database_file.h"
#include "parse_utils.h"
#include "debug.h"

static int user_base_print(semanage_handle_t * handle,
			   semanage_user_base_t * user, FILE * str)
{

	const char **roles = NULL;
	unsigned int i, nroles;

	const char *name = semanage_user_base_get_name(user);
	const char *mls_level = semanage_user_base_get_mlslevel(user);
	const char *mls_range = semanage_user_base_get_mlsrange(user);

	if (fprintf(str, "user %s roles { ", name) < 0)
		goto err;

	if (semanage_user_base_get_roles(handle, user, &roles, &nroles) < 0)
		goto err;

	for (i = 0; i < nroles; i++) {
		if (fprintf(str, "%s ", roles[i]) < 0)
			goto err;
	}

	if (fprintf(str, "} ") < 0)
		goto err;

	/* MLS */
	if (mls_level != NULL && mls_range != NULL)
		if (fprintf(str, "level %s range %s", mls_level, mls_range) < 0)
			goto err;

	if (fprintf(str, ";\n") < 0)
		goto err;

	free(roles);
	return STATUS_SUCCESS;

      err:
	free(roles);
	ERR(handle, "could not print user %s to stream", name);
	return STATUS_ERR;
}

static int user_base_parse(semanage_handle_t * handle,
			   parse_info_t * info, semanage_user_base_t * user)
{

	int islist = 0;
	char *str = NULL;
	char *start;
	char *name_str = NULL;

	if (parse_skip_space(handle, info) < 0)
		goto err;
	if (!info->ptr)
		goto last;

	/* Parse user header */
	if (parse_assert_str(handle, info, "user") < 0)
		goto err;
	if (parse_assert_space(handle, info) < 0)
		goto err;

	/* Parse user name */
	if (parse_fetch_string(handle, info, &name_str, ' ') < 0)
		goto err;

	if (semanage_user_base_set_name(handle, user, name_str) < 0) {
		free(name_str);
		goto err;
	}
	free(name_str);

	if (parse_assert_space(handle, info) < 0)
		goto err;
	if (parse_assert_str(handle, info, "roles") < 0)
		goto err;
	if (parse_assert_space(handle, info) < 0)
		goto err;

	islist = (parse_optional_ch(info, '{') != STATUS_NODATA);

	/* For each role, loop */
	do {
		char delim;

		if (parse_skip_space(handle, info) < 0)
			goto err;
		if (parse_assert_noeof(handle, info) < 0)
			goto err;

		start = info->ptr;
		while (*(info->ptr) &&
		       *(info->ptr) != ';' &&
		       *(info->ptr) != '}' && !isspace(*(info->ptr)))
			info->ptr++;

		delim = *(info->ptr);
		*(info->ptr)++ = '\0';

		if (semanage_user_base_add_role(handle, user, start) < 0)
			goto err;

		if (delim && !isspace(delim)) {
			if (islist && delim == '}')
				break;
			else if (!islist && delim == ';')
				goto skip_semicolon;
			else
				goto err;
		}

		if (parse_skip_space(handle, info) < 0)
			goto err;
		if (parse_optional_ch(info, ';') != STATUS_NODATA)
			goto skip_semicolon;
		if (parse_optional_ch(info, '}') != STATUS_NODATA)
			islist = 0;

	} while (islist);

	/* Handle mls */
	/* Parse level header */
	if (parse_skip_space(handle, info) < 0)
		goto err;
	if (parse_optional_str(info, "level") == STATUS_NODATA)
		goto semicolon;
	if (parse_assert_space(handle, info) < 0)
		goto err;

	/* NOTE: does not allow spaces/multiline */
	if (parse_fetch_string(handle, info, &str, ' ') < 0)
		goto err;
	if (semanage_user_base_set_mlslevel(handle, user, str) < 0)
		goto err;
	free(str);
	str = NULL;

	/* Parse range header */
	if (parse_assert_space(handle, info) < 0)
		goto err;
	if (parse_assert_str(handle, info, "range") < 0)
		goto err;
	if (parse_assert_space(handle, info) < 0)
		goto err;

	/* NOTE: does not allow spaces/multiline */
	if (parse_fetch_string(handle, info, &str, ';') < 0)
		goto err;
	if (semanage_user_base_set_mlsrange(handle, user, str) < 0)
		goto err;

	free(str);
	str = NULL;

	/* Check for semicolon */
      semicolon:
	if (parse_skip_space(handle, info) < 0)
		goto err;
	if (parse_assert_ch(handle, info, ';') < 0)
		goto err;

      skip_semicolon:
	return STATUS_SUCCESS;

      last:
	parse_dispose_line(info);
	return STATUS_NODATA;

      err:
	ERR(handle, "could not parse user record");
	free(str);
	parse_dispose_line(info);
	return STATUS_ERR;
}

/* USER BASE record: FILE extension: method table */
record_file_table_t SEMANAGE_USER_BASE_FILE_RTABLE = {
	.parse = user_base_parse,
	.print = user_base_print,
};

int user_base_file_dbase_init(semanage_handle_t * handle,
			      const char *path_ro,
			      const char *path_rw,
			      dbase_config_t * dconfig)
{

	if (dbase_file_init(handle,
			    path_ro,
			    path_rw,
			    &SEMANAGE_USER_BASE_RTABLE,
			    &SEMANAGE_USER_BASE_FILE_RTABLE,
			    &dconfig->dbase) < 0)
		return STATUS_ERR;

	dconfig->dtable = &SEMANAGE_FILE_DTABLE;
	return STATUS_SUCCESS;
}

void user_base_file_dbase_release(dbase_config_t * dconfig)
{

	dbase_file_release(dconfig->dbase);
}
