Exemple #1
0
static uint32_t
asl_store_file_open_write(asl_store_t *s, char *tstring, int32_t ruid, int32_t rgid, time_t bb, asl_file_t **f, time_t now, uint32_t check_cache)
{
	char *path;
	mode_t m;
	int32_t i, x;
	uid_t u;
	gid_t g;
	uint32_t status;
	asl_file_t *out;

	if (s == NULL) return ASL_STATUS_INVALID_STORE;

	/* see if the file is already open and in the cache */
	for (i = 0; i < FILE_CACHE_SIZE; i++)
	{
		if ((s->file_cache[i].u == ruid) && (s->file_cache[i].g == rgid) && (s->file_cache[i].bb == bb) && (s->file_cache[i].f != NULL))
		{
			s->file_cache[i].ts = now;
			*f = s->file_cache[i].f;
			if (check_cache == 1) asl_store_file_cache_lru(s, now, i);
			return ASL_STATUS_OK;
		}
	}

	u = 0;
	g = 0;
	m = 0644;
	path = asl_store_make_ug_path(s->base_dir, tstring, "asl", (uid_t)ruid, (gid_t)rgid, &u, &g, &m);
	if (path == NULL) return ASL_STATUS_NO_MEMORY;

	out = NULL;
	status = asl_file_open_write(path, m, u, g, &out);
	if (status != ASL_STATUS_OK)
	{
		free(path);
		return status;
	}

	x = asl_store_file_cache_lru(s, now, FILE_CACHE_SIZE);
	if (s->file_cache[x].f != NULL) asl_file_close(s->file_cache[x].f);
	if (s->file_cache[x].path != NULL) free(s->file_cache[x].path);

	s->file_cache[x].f = out;
	s->file_cache[x].path = path;
	s->file_cache[x].u = ruid;
	s->file_cache[x].g = rgid;
	s->file_cache[x].bb = bb;
	s->file_cache[x].ts = time(NULL);

	*f = out;

	return ASL_STATUS_OK;
}
Exemple #2
0
/*
 * Copy ASL files by reading and writing each record.
 */
uint32_t
copy_asl_file(const char *src, const char *dst, mode_t mode)
{
	asl_msg_list_t *res;
	asl_file_t *f;
	uint32_t status, i;
	uint64_t mid;
	size_t rcount;

	if (src == NULL) return ASL_STATUS_INVALID_ARG;
	if (dst == NULL) return ASL_STATUS_INVALID_ARG;

	f = NULL;
	status = asl_file_open_read(src, &f);
	if (status != ASL_STATUS_OK) return status;

	res = NULL;
	mid = 0;

	res = asl_file_match(f, NULL, &mid, 0, 0, 0, 1);
	asl_file_close(f);

	if (res == NULL) return ASL_STATUS_OK;
	rcount = asl_msg_list_count(res);
	if (rcount == 0)
	{
		asl_msg_list_release(res);
		return ASL_STATUS_OK;
	}

	f = NULL;
	status = asl_file_open_write(dst, mode, -1, -1, &f);
	if (status != ASL_STATUS_OK) return status;
	if (f == ASL_STATUS_OK) return ASL_STATUS_FAILED;

	f->flags = ASL_FILE_FLAG_PRESERVE_MSG_ID;

	for (i = 0; i < rcount; i++)
	{
		mid = 0;
		status = asl_file_save(f, asl_msg_list_get_index(res, i), &mid);
		if (status != ASL_STATUS_OK) break;
	}

	asl_file_close(f);
	return status;
}
Exemple #3
0
/* save a message to an appropriately named BB file */
static uint32_t 
save_bb_msg(aslmsg msg)
{
	const char *val;
	uid_t u, ruid;
	gid_t g, rgid;
	struct tm ctm;
	time_t msg_time, bb;
	char *path, *tstring;
	asl_file_t *out;
	uint64_t mid;
	mode_t m;
	uint32_t status;

	if (msg == NULL) return ASL_STATUS_OK;

	val = asl_get(msg, ASL_KEY_EXPIRE_TIME);
	if (val == NULL)  return ASL_STATUS_INVALID_ARG;
	msg_time = asl_parse_time(val);

	val = asl_get(msg, ASL_KEY_READ_UID);
	ruid = -1;
	if (val != NULL) ruid = atoi(val);

	val = asl_get(msg, ASL_KEY_READ_GID);
	rgid = -1;
	if (val != NULL) rgid = atoi(val);

	if (localtime_r((const time_t *)&msg_time, &ctm) == NULL) return ASL_STATUS_FAILED;

	/*
	 * This supports 12 monthy "Best Before" buckets.
	 * We advance the actual expiry time to day zero of the following month.
	 * mktime() is clever enough to know that you actually mean the last day
	 * of the previous month.  What we get back from localtime is the last
	 * day of the month in which the message expires, which we use in the name.
	 */
	ctm.tm_sec = 0;
	ctm.tm_min = 0;
	ctm.tm_hour = 0;
	ctm.tm_mday = 0;
	ctm.tm_mon += 1;

	bb = mktime(&ctm);

	u = 0;
	g = 0;
	if (ruid != -1) u = ruid;
	if (rgid != -1) g = rgid;

	out = NULL;

	if (cache_file != NULL)
	{
		if ((cache_uid == u) && (cache_gid == g) && (cache_bb == bb))
		{
			out = cache_file;
		}
		else
		{
			asl_file_close(cache_file);
			cache_file = NULL;
			cache_uid = -1;
			cache_gid = -1;
			cache_bb = 0;
		}
	}

	if (out == NULL)
	{
		if (localtime_r((const time_t *)&bb, &ctm) == NULL) return ASL_STATUS_FAILED;

		tstring = NULL;
		asprintf(&tstring, "%s/BB.%d.%02d.%02d", store_path, ctm.tm_year + 1900, ctm.tm_mon + 1, ctm.tm_mday);
		if (tstring == NULL) return ASL_STATUS_NO_MEMORY;

		path = NULL;
		m = 0644;

		if (ruid == -1)
		{
			if (rgid == -1)
			{
				asprintf(&path, "%s.asl", tstring);
			}
			else
			{
				m = 0640;
				asprintf(&path, "%s.G%d.asl", tstring, g);
			}
		}
		else
		{
			if (rgid == -1)
			{
				m = 0600;
				asprintf(&path, "%s.U%d.asl", tstring, u);
			}
			else
			{
				m = 0640;
				asprintf(&path, "%s.U%d.G%u.asl", tstring, u, g);
			}
		}

		if (path == NULL) return ASL_STATUS_NO_MEMORY;

		status = asl_file_open_write(path, m, u, g, &out);
		free(path);
		if (status != ASL_STATUS_OK) return status;
		if (out == NULL) return ASL_STATUS_FAILED;

		out->flags = ASL_FILE_FLAG_PRESERVE_MSG_ID;

		cache_file = out;
		cache_uid = u;
		cache_gid = g;
		cache_bb = bb;
	}

	status = asl_file_save(out, msg, &mid);

	return status;
}
Exemple #4
0
/* remove all messages that have an ASLExpireTime key */
static uint32_t
do_ASLExpireTime_filter(const char *name)
{
	aslmsg msg;
	asl_file_t *in, *out;
	uint32_t status;
	uint64_t mid;
	char *inpath, *outpath;
	struct stat sb;

	if (name == NULL) return ASL_STATUS_INVALID_ARG;

	in = NULL;
	inpath = NULL;
	asprintf(&inpath, "%s/%s", store_path, name);
	if (inpath == NULL) return ASL_STATUS_NO_MEMORY;

	memset(&sb, 0, sizeof(struct stat));
	if (stat(inpath, &sb) < 0)
	{
		free(inpath);
		return ASL_STATUS_INVALID_STORE;
	}

	status = asl_file_open_read(inpath, &in);
	if (status != ASL_STATUS_OK) 
	{
		free(inpath);
		return ASL_STATUS_OK;
	}

	out = NULL;
	outpath = NULL;
	asprintf(&outpath, "%s/%s", store_path, TEMP_NAME);
	if (outpath == NULL)
	{
		asl_file_close(in);
		free(inpath);
		return ASL_STATUS_NO_MEMORY;
	}

	status = asl_file_open_write(outpath, sb.st_mode, sb.st_uid, sb.st_gid, &out);
	if (status != ASL_STATUS_OK)
	{
		asl_file_close(in);
		free(inpath);
		free(outpath);
		return status;
	}

	out->flags = ASL_FILE_FLAG_PRESERVE_MSG_ID;

	msg = NULL;
	while (asl_file_fetch_next(in, &msg) == ASL_STATUS_OK)
	{
		if (msg == NULL) break;

		mid = 0;

		if (asl_get(msg, ASL_KEY_EXPIRE_TIME) == NULL) status = asl_file_save(out, msg, &mid);

		asl_free(msg);
		msg = NULL;

		if (status != ASL_STATUS_OK) break;
	}

	asl_file_close(in);
	asl_file_close(out);

	unlink(inpath);
	rename(outpath, inpath);

	free(inpath);
	free(outpath);

	return status;
}