Ejemplo n.º 1
0
/*
 * Return the next au_class_entry having the given class name
 */  
struct au_class_ent *getauclassnam(const char *name)
{
	struct au_class_ent *c;
	char *nl;

	if(name == NULL) {
		return NULL;
	}

	/* Rewind to beginning of file */
	setauclass();
		
	pthread_mutex_lock(&mutex);

	if((fp == NULL) 
		&& ((fp = fopen(AUDIT_CLASS_FILE, "r")) == NULL)) {
		
		pthread_mutex_unlock(&mutex);
		return NULL;
	}
	
	c = get_class_area(); /* allocate */ 
	if(c == NULL) {

		pthread_mutex_unlock(&mutex);
		return NULL;
	}
	while(fgets(linestr, AU_LINE_MAX, fp) != NULL) {
		/* Remove trailing new line character */
		if((nl = strrchr(linestr, '\n')) != NULL) {
			*nl = '\0';
		}

		/* parse tokptr to au_class_ent components */	
		if(classfromstr(linestr, delim, c) != NULL) {
			if(!strcmp(name, c->ac_name)) {
					
				pthread_mutex_unlock(&mutex);
				return c;
			}
		}	
	}

	free_au_class_ent(c);

	pthread_mutex_unlock(&mutex);
	return NULL;

}
Ejemplo n.º 2
0
/*
 * Convert the au_mask_t fields into a string value.  If verbose is non-zero
 * the long flag names are used else the short (2-character)flag names are
 * used.
 *
 * XXXRW: If bits are specified that are not matched by any class, they are
 * omitted rather than rejected with EINVAL.
 *
 * XXXRW: This is not thread-safe as it relies on atomicity between
 * setauclass() and sequential calls to getauclassent().  This could be
 * fixed by iterating through the bitmask fields rather than iterating
 * through the classes.
 */
int
getauditflagschar(char *auditstr, au_mask_t *masks, int verbose)
{
	char class_ent_name[AU_CLASS_NAME_MAX];
	char class_ent_desc[AU_CLASS_DESC_MAX];
	struct au_class_ent c;
	char *strptr = auditstr;
	u_char sel;

	bzero(&c, sizeof(c));
	bzero(class_ent_name, sizeof(class_ent_name));
	bzero(class_ent_desc, sizeof(class_ent_desc));
	c.ac_name = class_ent_name;
	c.ac_desc = class_ent_desc;

	/*
	 * Enumerate the class entries, check if each is selected in either
	 * the success or failure masks.
	 */
	setauclass();
	while ((getauclassent_r(&c)) != NULL) {
		sel = 0;

		/* Dont do anything for class = no. */
		if (c.ac_class == 0)
			continue;

		sel |= ((c.ac_class & masks->am_success) == c.ac_class) ?
		    AU_PRS_SUCCESS : 0;
		sel |= ((c.ac_class & masks->am_failure) == c.ac_class) ?
		    AU_PRS_FAILURE : 0;

		/*
		 * No prefix should be attached if both success and failure
		 * are selected.
		 */
		if ((sel & AU_PRS_BOTH) == 0) {
			if ((sel & AU_PRS_SUCCESS) != 0) {
				*strptr = '+';
				strptr = strptr + 1;
			} else if ((sel & AU_PRS_FAILURE) != 0) {
				*strptr = '-';
				strptr = strptr + 1;
			}
		}

		if (sel != 0) {
			if (verbose) {
				strlcpy(strptr, c.ac_desc, AU_CLASS_DESC_MAX);
				strptr += strlen(c.ac_desc);
			} else {
				strlcpy(strptr, c.ac_name, AU_CLASS_NAME_MAX);
				strptr += strlen(c.ac_name);
			}
			*strptr = ','; /* delimiter */
			strptr = strptr + 1;
		}
	}

	/* Overwrite the last delimiter with the string terminator. */
	if (strptr != auditstr)
		*(strptr-1) = '\0';

	return (0);
}
Ejemplo n.º 3
0
/*
 * xcacheauclass:
 *	Read the entire audit_class file into memory.
 *	Return a pointer to the requested entry in the cache
 *	or a pointer to an invalid entry if the the class
 *	requested is not known.
 *
 *	Return < 0, do not set result pointer, if error.
 *	Return   0, set result pointer to invalid entry, if class not in cache.
 *	Return   1, set result pointer to a valid entry, if class is in cache.
 */
static int
xcacheauclass(au_class_ent_t **result, char *class_name, au_class_t class_no,
    int flags)
{
	static int	invalid;
	static au_class_ent_t **class_tbl;
	static int	called_once;
	static int	lines = 0;

	char		line[256];
	FILE		*fp;
	au_class_ent_t	*p_class;
	int		i;
	int		hit = 0;
	char		*s;

	(void) mutex_lock(&mutex_classcache);
	if (called_once == 0) {

		/* Count number of lines in the class file */
		if ((fp = fopen(au_class_fname, "rF")) == NULL) {
			(void) mutex_unlock(&mutex_classcache);
			return (-1);
		}
		while (fgets(line, 256, fp) != NULL) {
			s = line + strspn(line, " \t\r\n");
			if ((*s == '\0') || (*s == '#')) {
				continue;
			}
			lines++;
		}
		(void) fclose(fp);
		class_tbl = (au_class_ent_t **)calloc((size_t)lines + 1,
		    sizeof (class_tbl));
		if (class_tbl == NULL) {
			(void) mutex_unlock(&mutex_classcache);
			return (-2);
		}

		lines = 0;
		setauclass();
		/*
		 * This call to getauclassent is protected by
		 * mutex_classcache, so we don't need to use the thread-
		 * safe version (getauclassent_r).
		 */
		while ((p_class = getauclassent()) != NULL) {
			class_tbl[lines] = (au_class_ent_t *)
			    malloc(sizeof (au_class_ent_t));
			if (class_tbl[lines] == NULL) {
				(void) mutex_unlock(&mutex_classcache);
				return (-3);
			}
			class_tbl[lines]->ac_name = strdup(p_class->ac_name);
			class_tbl[lines]->ac_class = p_class->ac_class;
			class_tbl[lines]->ac_desc = strdup(p_class->ac_desc);
#ifdef DEBUG2
			printclass(class_tbl[lines]);
#endif
			lines++;
		}
		endauclass();
		invalid = lines;
		class_tbl[invalid] = (au_class_ent_t *)
		    malloc(sizeof (au_class_ent_t));
		if (class_tbl[invalid] == NULL) {
			(void) mutex_unlock(&mutex_classcache);
			return (-4);
		}
		class_tbl[invalid]->ac_name = "invalid class";
		class_tbl[invalid]->ac_class = 0;
		class_tbl[invalid]->ac_desc = class_tbl[invalid]->ac_name;

		called_once = 1;

#ifdef DEBUG2
		for (i = 0; i <= lines; i++) {
			printclass(class_tbl[i]);
		}
#endif

	} /* END if called_once */
	*result = class_tbl[invalid];
	if (flags & AU_CACHE_NAME) {
		for (i = 0; i < lines; i++) {
			if (strncmp(class_name, class_tbl[i]->ac_name,
			    AU_CLASS_NAME_MAX) == 0) {
				*result = class_tbl[i];
				hit = 1;
				break;
			}
		}
	} else if (flags & AU_CACHE_NUMBER) {
		for (i = 0; i < lines; i++) {
			if (class_no == class_tbl[i]->ac_class) {
				*result = class_tbl[i];
				hit = 1;
				break;
			}
		}
	}
	(void) mutex_unlock(&mutex_classcache);
	return (hit);
}