xref: /onnv-gate/usr/src/lib/libbsm/common/audit_cron.c (revision 7753:ebbac916a413)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
56561Sjf206706  * Common Development and Distribution License (the "License").
66561Sjf206706  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
226561Sjf206706  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
230Sstevel@tonic-gate  * Use is subject to license terms.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate 
260Sstevel@tonic-gate #include <sys/types.h>
270Sstevel@tonic-gate #include <sys/systeminfo.h>
280Sstevel@tonic-gate #include <bsm/audit.h>
290Sstevel@tonic-gate #include <bsm/libbsm.h>
300Sstevel@tonic-gate #include <bsm/audit_uevents.h>
310Sstevel@tonic-gate #include <bsm/audit_private.h>
320Sstevel@tonic-gate #include <unistd.h>
330Sstevel@tonic-gate #include <wait.h>
340Sstevel@tonic-gate #include <fcntl.h>
350Sstevel@tonic-gate #include <pwd.h>
360Sstevel@tonic-gate #include <string.h>
370Sstevel@tonic-gate #include <stdlib.h>
380Sstevel@tonic-gate #include <errno.h>
390Sstevel@tonic-gate #include <syslog.h>
400Sstevel@tonic-gate #include <sys/stat.h>
410Sstevel@tonic-gate #include <sys/socket.h>
420Sstevel@tonic-gate #include <netinet/in.h>
430Sstevel@tonic-gate #include <arpa/inet.h>
440Sstevel@tonic-gate #include <libgen.h>
450Sstevel@tonic-gate 
460Sstevel@tonic-gate #include <locale.h>
470Sstevel@tonic-gate #include "generic.h"
480Sstevel@tonic-gate 
49*7753STon.Nguyen@Sun.COM #define	F_AUID	"%u\n"
500Sstevel@tonic-gate #define	F_SMASK	"%x\n"
510Sstevel@tonic-gate #define	F_FMASK	"%x\n"
520Sstevel@tonic-gate #define	F_PORT	"%lx\n"
530Sstevel@tonic-gate #define	F_TYPE	"%x\n"
540Sstevel@tonic-gate #define	F_MACH	"%x %x %x %x\n"
550Sstevel@tonic-gate #define	F_ASID	"%u\n"
560Sstevel@tonic-gate 
570Sstevel@tonic-gate #define	AU_SUFFIX	".au"
580Sstevel@tonic-gate 
590Sstevel@tonic-gate #define	ANC_BAD_FILE	-1
600Sstevel@tonic-gate #define	ANC_BAD_FORMAT	-2
610Sstevel@tonic-gate 
620Sstevel@tonic-gate #define	AUDIT_CRON_TEXTBUF	256
630Sstevel@tonic-gate static char	textbuf[AUDIT_CRON_TEXTBUF];
640Sstevel@tonic-gate 
650Sstevel@tonic-gate int
audit_cron_mode()660Sstevel@tonic-gate audit_cron_mode()
670Sstevel@tonic-gate {
680Sstevel@tonic-gate 	return (!cannot_audit(0));
690Sstevel@tonic-gate }
700Sstevel@tonic-gate 
710Sstevel@tonic-gate static void
audit_cron_syslog(const char * message)720Sstevel@tonic-gate audit_cron_syslog(const char *message) {
730Sstevel@tonic-gate 	static	int	is_open = 0;
740Sstevel@tonic-gate 
750Sstevel@tonic-gate 	if (!is_open) {
766561Sjf206706 		openlog("Solaris_Audit", LOG_ODELAY, LOG_CRON);
770Sstevel@tonic-gate 		is_open = 1;
780Sstevel@tonic-gate 	}
790Sstevel@tonic-gate 	syslog(LOG_WARNING, "%s", message);
800Sstevel@tonic-gate }
810Sstevel@tonic-gate 
820Sstevel@tonic-gate /*
830Sstevel@tonic-gate  * audit_cron_getinfo returns the audit characteristics from the relevant
840Sstevel@tonic-gate  * auxiliary file, it if exists.  If not, it creates them from the crontab
850Sstevel@tonic-gate  * or atjob uid.
860Sstevel@tonic-gate  */
870Sstevel@tonic-gate 
880Sstevel@tonic-gate static int
audit_cron_getinfo(char * fname,char * fname_aux,struct auditinfo_addr * info)890Sstevel@tonic-gate audit_cron_getinfo(char *fname, char *fname_aux, struct auditinfo_addr *info)
900Sstevel@tonic-gate {
910Sstevel@tonic-gate 	int		fd;
920Sstevel@tonic-gate 	struct stat	st;
930Sstevel@tonic-gate 	au_mask_t mask;
940Sstevel@tonic-gate 	struct passwd	pwd;
950Sstevel@tonic-gate 	char		pwd_buff[1024];
960Sstevel@tonic-gate 	static char	*msg =
970Sstevel@tonic-gate 	    "Used defaults instead of ancilary audit file";
980Sstevel@tonic-gate 
990Sstevel@tonic-gate 	if ((fd = open(fname_aux, O_RDONLY)) == -1) {
1000Sstevel@tonic-gate 		/* no syslog here; common case */
1010Sstevel@tonic-gate 		goto make_it_up;
1020Sstevel@tonic-gate 	}
1030Sstevel@tonic-gate 	if (fstat(fd, &st) == -1) {
1040Sstevel@tonic-gate 		/* no syslog here either; common case */
1050Sstevel@tonic-gate 		goto delete_first;
1060Sstevel@tonic-gate 	}
1070Sstevel@tonic-gate 
1080Sstevel@tonic-gate 	if (read(fd, textbuf, st.st_size) != st.st_size) {
1090Sstevel@tonic-gate 		audit_cron_syslog(msg);
1100Sstevel@tonic-gate 		goto delete_first;
1110Sstevel@tonic-gate 	}
1120Sstevel@tonic-gate 
1130Sstevel@tonic-gate 	if (sscanf(textbuf,
1146561Sjf206706 	    F_AUID
1156561Sjf206706 	    F_SMASK
1166561Sjf206706 	    F_FMASK
1176561Sjf206706 	    F_PORT
1186561Sjf206706 	    F_TYPE
1196561Sjf206706 	    F_MACH
1206561Sjf206706 	    F_ASID,
121*7753STon.Nguyen@Sun.COM 	    &(info->ai_auid),
1226561Sjf206706 	    &(info->ai_mask.am_success),
1236561Sjf206706 	    &(info->ai_mask.am_failure),
1246561Sjf206706 	    &(info->ai_termid.at_port),
1256561Sjf206706 	    &(info->ai_termid.at_type),
1266561Sjf206706 	    &(info->ai_termid.at_addr[0]),
1276561Sjf206706 	    &(info->ai_termid.at_addr[1]),
1286561Sjf206706 	    &(info->ai_termid.at_addr[2]),
1296561Sjf206706 	    &(info->ai_termid.at_addr[3]),
130*7753STon.Nguyen@Sun.COM 	    &(info->ai_asid)) != 10) {
1310Sstevel@tonic-gate 		audit_cron_syslog(msg);
1320Sstevel@tonic-gate 		goto delete_first;
1330Sstevel@tonic-gate 	}
1340Sstevel@tonic-gate 	(void) close(fd);
1350Sstevel@tonic-gate 	return (0);
1360Sstevel@tonic-gate 
1370Sstevel@tonic-gate delete_first:
1380Sstevel@tonic-gate 	(void) close(fd);
1390Sstevel@tonic-gate 	if (unlink(fname_aux)) {
1400Sstevel@tonic-gate 		if (errno != ENOENT)
1410Sstevel@tonic-gate 			audit_cron_syslog(
1420Sstevel@tonic-gate 			    "Failed to remove invalid ancilary audit file");
1430Sstevel@tonic-gate 	}
1440Sstevel@tonic-gate 	/* intentionally falls through */
1450Sstevel@tonic-gate 
1460Sstevel@tonic-gate make_it_up:
1470Sstevel@tonic-gate 	if (stat(fname, &st))
1480Sstevel@tonic-gate 		return (-1);
1490Sstevel@tonic-gate 
1500Sstevel@tonic-gate 	/* port and IP are zero */
1510Sstevel@tonic-gate 	(void) memset(&(info->ai_termid), 0, sizeof (au_tid_addr_t));
1520Sstevel@tonic-gate 	info->ai_termid.at_type = AU_IPv4;
1530Sstevel@tonic-gate 
1540Sstevel@tonic-gate 	/* the caller is the child of cron which will run the job. */
1550Sstevel@tonic-gate 	info->ai_asid = getpid();
1560Sstevel@tonic-gate 
1570Sstevel@tonic-gate 	info->ai_mask.am_success = 0;	/* cover error case */
1580Sstevel@tonic-gate 	info->ai_mask.am_failure = 0;
1590Sstevel@tonic-gate 
1600Sstevel@tonic-gate 	if (strstr(fname, "crontabs") != NULL) {
1610Sstevel@tonic-gate 		if (getpwnam_r(basename(fname), &pwd, pwd_buff,
1620Sstevel@tonic-gate 		    sizeof (pwd_buff)) == NULL)
1630Sstevel@tonic-gate 			return (-1); /* getpwnam_r sets errno */
1640Sstevel@tonic-gate 	} else {
1650Sstevel@tonic-gate 		if (getpwuid_r(st.st_uid, &pwd, pwd_buff, sizeof (pwd_buff)) ==
1660Sstevel@tonic-gate 		    NULL)
1670Sstevel@tonic-gate 			return (-1); /* getpwuid_r sets errno */
1680Sstevel@tonic-gate 	}
1690Sstevel@tonic-gate 
1700Sstevel@tonic-gate 	info->ai_auid = pwd.pw_uid;
1710Sstevel@tonic-gate 
1720Sstevel@tonic-gate 	if (au_user_mask(pwd.pw_name, &mask)) {
1730Sstevel@tonic-gate 		errno = EINVAL; /* pw_name lookup failed */
1740Sstevel@tonic-gate 		return (-1);
1750Sstevel@tonic-gate 	}
1760Sstevel@tonic-gate 	info->ai_mask.am_success = mask.am_success;
1770Sstevel@tonic-gate 	info->ai_mask.am_failure = mask.am_failure;
1780Sstevel@tonic-gate 
1790Sstevel@tonic-gate 	return (0);
1800Sstevel@tonic-gate }
1810Sstevel@tonic-gate 
1820Sstevel@tonic-gate int
audit_cron_setinfo(char * fname,struct auditinfo_addr * info)1830Sstevel@tonic-gate audit_cron_setinfo(char *fname, struct auditinfo_addr *info)
1840Sstevel@tonic-gate {
1850Sstevel@tonic-gate 	int		fd, len, r;
1860Sstevel@tonic-gate 	int		save_err;
1870Sstevel@tonic-gate 
1880Sstevel@tonic-gate 	r = chmod(fname, 0200);
1890Sstevel@tonic-gate 	if (r == -1 && errno != ENOENT)
1900Sstevel@tonic-gate 		return (-1);
1910Sstevel@tonic-gate 
1920Sstevel@tonic-gate 	if ((fd = open(fname, O_CREAT|O_WRONLY|O_TRUNC, 0200)) == -1)
1930Sstevel@tonic-gate 		return (-1);
1940Sstevel@tonic-gate 
1950Sstevel@tonic-gate 	len = sprintf(textbuf,
1966561Sjf206706 	    F_AUID
1976561Sjf206706 	    F_SMASK
1986561Sjf206706 	    F_FMASK
1996561Sjf206706 	    F_PORT
2006561Sjf206706 	    F_TYPE
2016561Sjf206706 	    F_MACH
2026561Sjf206706 	    F_ASID,
203*7753STon.Nguyen@Sun.COM 	    info->ai_auid,
2046561Sjf206706 	    info->ai_mask.am_success,
2056561Sjf206706 	    info->ai_mask.am_failure,
2066561Sjf206706 	    info->ai_termid.at_port,
2076561Sjf206706 	    info->ai_termid.at_type,
2086561Sjf206706 	    info->ai_termid.at_addr[0],
2096561Sjf206706 	    info->ai_termid.at_addr[1],
2106561Sjf206706 	    info->ai_termid.at_addr[2],
2116561Sjf206706 	    info->ai_termid.at_addr[3],
212*7753STon.Nguyen@Sun.COM 	    info->ai_asid);
2130Sstevel@tonic-gate 
2140Sstevel@tonic-gate 	if (write(fd, textbuf, len) != len)
2150Sstevel@tonic-gate 		goto audit_setinfo_clean;
2160Sstevel@tonic-gate 
2170Sstevel@tonic-gate 	if (fchmod(fd, 0400) == -1)
2180Sstevel@tonic-gate 		goto audit_setinfo_clean;
2190Sstevel@tonic-gate 
2200Sstevel@tonic-gate 	(void) close(fd);
2210Sstevel@tonic-gate 	return (0);
2220Sstevel@tonic-gate 
2230Sstevel@tonic-gate audit_setinfo_clean:
2240Sstevel@tonic-gate 	save_err = errno;
2250Sstevel@tonic-gate 	(void) close(fd);
2260Sstevel@tonic-gate 	(void) unlink(fname);
2270Sstevel@tonic-gate 	errno = save_err;
2280Sstevel@tonic-gate 	return (-1);
2290Sstevel@tonic-gate }
2300Sstevel@tonic-gate 
2310Sstevel@tonic-gate char *
audit_cron_make_anc_name(char * fname)2320Sstevel@tonic-gate audit_cron_make_anc_name(char *fname)
2330Sstevel@tonic-gate {
2340Sstevel@tonic-gate 	char *anc_name;
2350Sstevel@tonic-gate 
2360Sstevel@tonic-gate 	anc_name = (char *)malloc(strlen(fname) + strlen(AU_SUFFIX) + 1);
2370Sstevel@tonic-gate 	if (anc_name == NULL)
2380Sstevel@tonic-gate 		return (NULL);
2390Sstevel@tonic-gate 
2400Sstevel@tonic-gate 	(void) strcpy(anc_name, fname);
2410Sstevel@tonic-gate 	(void) strcat(anc_name, AU_SUFFIX);
2420Sstevel@tonic-gate 	return (anc_name);
2430Sstevel@tonic-gate }
2440Sstevel@tonic-gate 
2450Sstevel@tonic-gate int
audit_cron_is_anc_name(char * name)2460Sstevel@tonic-gate audit_cron_is_anc_name(char *name)
2470Sstevel@tonic-gate {
2480Sstevel@tonic-gate 	int	pos;
2490Sstevel@tonic-gate 
2500Sstevel@tonic-gate 	pos = strlen(name) - strlen(AU_SUFFIX);
2510Sstevel@tonic-gate 	if (pos <= 0)
2520Sstevel@tonic-gate 		return (0);
2530Sstevel@tonic-gate 
2540Sstevel@tonic-gate 	if (strcmp(name + pos, AU_SUFFIX) == 0)
2550Sstevel@tonic-gate 		return (1);
2560Sstevel@tonic-gate 
2570Sstevel@tonic-gate 	return (0);
2580Sstevel@tonic-gate }
2590Sstevel@tonic-gate 
2600Sstevel@tonic-gate static void
audit_cron_session_failure(char * name,int type,char * err_str)2610Sstevel@tonic-gate audit_cron_session_failure(char *name, int type, char *err_str)
2620Sstevel@tonic-gate {
2630Sstevel@tonic-gate 	const char	*mess;
2640Sstevel@tonic-gate 
2650Sstevel@tonic-gate 	if (type == 0)
2660Sstevel@tonic-gate 		mess = dgettext(bsm_dom,
2670Sstevel@tonic-gate 		"at-job session for user %s failed: ancillary file: %s");
2680Sstevel@tonic-gate 	else
2690Sstevel@tonic-gate 		mess = dgettext(bsm_dom,
2700Sstevel@tonic-gate 		"crontab job session for user %s failed: ancillary file: %s");
2710Sstevel@tonic-gate 
2720Sstevel@tonic-gate 	(void) snprintf(textbuf, sizeof (textbuf), mess, name, err_str);
2730Sstevel@tonic-gate 
2740Sstevel@tonic-gate 	aug_save_event(AUE_cron_invoke);
2750Sstevel@tonic-gate 	aug_save_sorf(4);
2760Sstevel@tonic-gate 	aug_save_text(textbuf);
2770Sstevel@tonic-gate 	(void) aug_audit();
2780Sstevel@tonic-gate }
2790Sstevel@tonic-gate 
2800Sstevel@tonic-gate 
2810Sstevel@tonic-gate int
audit_cron_session(char * name,char * path,uid_t uid,gid_t gid,char * at_jobname)2820Sstevel@tonic-gate audit_cron_session(
2830Sstevel@tonic-gate 		char *name,
2840Sstevel@tonic-gate 		char *path,
2850Sstevel@tonic-gate 		uid_t uid,
2860Sstevel@tonic-gate 		gid_t gid,
2870Sstevel@tonic-gate 		char *at_jobname)
2880Sstevel@tonic-gate {
2890Sstevel@tonic-gate 	struct auditinfo_addr	info;
2900Sstevel@tonic-gate 	au_mask_t		mask;
2910Sstevel@tonic-gate 	char			*anc_file, *fname;
2920Sstevel@tonic-gate 	int			r = 0;
2930Sstevel@tonic-gate 	char			full_path[PATH_MAX];
2940Sstevel@tonic-gate 
2950Sstevel@tonic-gate 	if (cannot_audit(0)) {
2960Sstevel@tonic-gate 		return (0);
2970Sstevel@tonic-gate 	}
2980Sstevel@tonic-gate 
2990Sstevel@tonic-gate 	/* get auditinfo from ancillary file */
3000Sstevel@tonic-gate 	if (at_jobname == NULL) {
3010Sstevel@tonic-gate 		/*
3020Sstevel@tonic-gate 		 *	this is a cron-event, so we can get
3030Sstevel@tonic-gate 		 *	filename from "name" arg
3040Sstevel@tonic-gate 		 */
3050Sstevel@tonic-gate 		fname = name;
3060Sstevel@tonic-gate 		if (path != NULL) {
3070Sstevel@tonic-gate 			if (strlen(path) + strlen(fname) + 2 > PATH_MAX) {
3080Sstevel@tonic-gate 				errno = ENAMETOOLONG;
3090Sstevel@tonic-gate 				r = -1;
3100Sstevel@tonic-gate 			}
3110Sstevel@tonic-gate 			(void) strcat(strcat(strcpy(full_path, path), "/"),
3120Sstevel@tonic-gate 			    fname);
3130Sstevel@tonic-gate 			fname = full_path;
3140Sstevel@tonic-gate 		}
3150Sstevel@tonic-gate 	} else {
3160Sstevel@tonic-gate 		/* this is an at-event, use "at_jobname" */
3170Sstevel@tonic-gate 		fname = at_jobname;
3180Sstevel@tonic-gate 	}
3190Sstevel@tonic-gate 
3200Sstevel@tonic-gate 	if (r == 0) {
3210Sstevel@tonic-gate 		anc_file = audit_cron_make_anc_name(fname);
3220Sstevel@tonic-gate 		if (anc_file == NULL) {
3230Sstevel@tonic-gate 			r = -1;
3240Sstevel@tonic-gate 		} else {
3250Sstevel@tonic-gate 			r = audit_cron_getinfo(fname, anc_file, &info);
3260Sstevel@tonic-gate 		}
3270Sstevel@tonic-gate 	}
3280Sstevel@tonic-gate 
3290Sstevel@tonic-gate 	if (r != 0) {
3300Sstevel@tonic-gate 		char *err_str;
3310Sstevel@tonic-gate 
3320Sstevel@tonic-gate 		if (r == ANC_BAD_FORMAT)
3330Sstevel@tonic-gate 			err_str = dgettext(bsm_dom, "bad format");
3340Sstevel@tonic-gate 		else
3350Sstevel@tonic-gate 			err_str = strerror(errno);
3360Sstevel@tonic-gate 
3370Sstevel@tonic-gate 		audit_cron_session_failure(name,
3386561Sjf206706 		    at_jobname == NULL,
3396561Sjf206706 		    err_str);
3400Sstevel@tonic-gate 		if (anc_file != NULL)
3410Sstevel@tonic-gate 			free(anc_file);
3420Sstevel@tonic-gate 		return (r);
3430Sstevel@tonic-gate 	}
3440Sstevel@tonic-gate 
3450Sstevel@tonic-gate 	free(anc_file);
3460Sstevel@tonic-gate 	aug_init();
3470Sstevel@tonic-gate 
3480Sstevel@tonic-gate 	/* get current audit masks */
3490Sstevel@tonic-gate 	if (au_user_mask(name, &mask) == 0) {
3500Sstevel@tonic-gate 		info.ai_mask.am_success  |= mask.am_success;
3510Sstevel@tonic-gate 		info.ai_mask.am_failure  |= mask.am_failure;
3520Sstevel@tonic-gate 	}
3530Sstevel@tonic-gate 
3540Sstevel@tonic-gate 	/* save audit attributes for further use in current process */
3550Sstevel@tonic-gate 	aug_save_auid(info.ai_auid);
3560Sstevel@tonic-gate 	aug_save_asid(info.ai_asid);
3570Sstevel@tonic-gate 	aug_save_tid_ex(info.ai_termid.at_port, info.ai_termid.at_addr,
3586561Sjf206706 	    info.ai_termid.at_type);
3590Sstevel@tonic-gate 	aug_save_pid(getpid());
3600Sstevel@tonic-gate 	aug_save_uid(uid);
3610Sstevel@tonic-gate 	aug_save_gid(gid);
3620Sstevel@tonic-gate 	aug_save_euid(uid);
3630Sstevel@tonic-gate 	aug_save_egid(gid);
3640Sstevel@tonic-gate 
3650Sstevel@tonic-gate 	/* set mixed audit masks */
3660Sstevel@tonic-gate 	return (setaudit_addr(&info, sizeof (info)));
3670Sstevel@tonic-gate }
3680Sstevel@tonic-gate 
3690Sstevel@tonic-gate /*
3700Sstevel@tonic-gate  * audit_cron_new_job - create audit record with an information
3710Sstevel@tonic-gate  *			about new job started by cron.
3720Sstevel@tonic-gate  *	args:
3730Sstevel@tonic-gate  *	cmd  - command being run by cron daemon.
3740Sstevel@tonic-gate  *	type - type of job (0 - at-job, 1 - crontab job).
3750Sstevel@tonic-gate  *	event - not used. pointer to cron event structure.
3760Sstevel@tonic-gate  */
3770Sstevel@tonic-gate /*ARGSUSED*/
3780Sstevel@tonic-gate void
audit_cron_new_job(char * cmd,int type,void * event)3790Sstevel@tonic-gate audit_cron_new_job(char *cmd, int type, void *event)
3800Sstevel@tonic-gate {
3810Sstevel@tonic-gate 	if (cannot_audit(0))
3820Sstevel@tonic-gate 		return;
3830Sstevel@tonic-gate 
3840Sstevel@tonic-gate 	if (type == 0) {
3856561Sjf206706 		(void) snprintf(textbuf, sizeof (textbuf),
3860Sstevel@tonic-gate 		    dgettext(bsm_dom, "at-job"));
3870Sstevel@tonic-gate 	} else if (type == 1) {
3886561Sjf206706 		(void) snprintf(textbuf, sizeof (textbuf),
3890Sstevel@tonic-gate 		    dgettext(bsm_dom, "batch-job"));
3900Sstevel@tonic-gate 	} else if (type == 2) {
3916561Sjf206706 		(void) snprintf(textbuf, sizeof (textbuf),
3920Sstevel@tonic-gate 		    dgettext(bsm_dom, "crontab-job"));
3930Sstevel@tonic-gate 	} else if ((type > 2) && (type <= 25)) {	/* 25 from cron.h */
3946561Sjf206706 		(void) snprintf(textbuf, sizeof (textbuf),
3950Sstevel@tonic-gate 		    dgettext(bsm_dom, "queue-job (%c)"), (type+'a'));
3960Sstevel@tonic-gate 	} else {
3976561Sjf206706 		(void) snprintf(textbuf, sizeof (textbuf),
3980Sstevel@tonic-gate 		    dgettext(bsm_dom, "unknown job type (%d)"), type);
3990Sstevel@tonic-gate 	}
4000Sstevel@tonic-gate 
4010Sstevel@tonic-gate 	aug_save_event(AUE_cron_invoke);
4020Sstevel@tonic-gate 	aug_save_sorf(0);
4030Sstevel@tonic-gate 	aug_save_text(textbuf);
4040Sstevel@tonic-gate 	aug_save_text1(cmd);
4050Sstevel@tonic-gate 	(void) aug_audit();
4060Sstevel@tonic-gate }
4070Sstevel@tonic-gate 
4080Sstevel@tonic-gate void
audit_cron_bad_user(char * name)4090Sstevel@tonic-gate audit_cron_bad_user(char *name)
4100Sstevel@tonic-gate {
4110Sstevel@tonic-gate 	if (cannot_audit(0))
4120Sstevel@tonic-gate 		return;
4130Sstevel@tonic-gate 
4140Sstevel@tonic-gate 	(void) snprintf(textbuf, sizeof (textbuf),
4156561Sjf206706 	    dgettext(bsm_dom, "bad user %s"), name);
4160Sstevel@tonic-gate 
4170Sstevel@tonic-gate 	aug_save_event(AUE_cron_invoke);
4180Sstevel@tonic-gate 	aug_save_sorf(2);
4190Sstevel@tonic-gate 	aug_save_text(textbuf);
4200Sstevel@tonic-gate 	(void) aug_audit();
4210Sstevel@tonic-gate }
4220Sstevel@tonic-gate 
4230Sstevel@tonic-gate void
audit_cron_user_acct_expired(char * name)4240Sstevel@tonic-gate audit_cron_user_acct_expired(char *name)
4250Sstevel@tonic-gate {
4260Sstevel@tonic-gate 	if (cannot_audit(0))
4270Sstevel@tonic-gate 		return;
4280Sstevel@tonic-gate 
4290Sstevel@tonic-gate 	(void) snprintf(textbuf, sizeof (textbuf),
4306561Sjf206706 	    dgettext(bsm_dom,
4316561Sjf206706 	    "user %s account expired"), name);
4320Sstevel@tonic-gate 
4330Sstevel@tonic-gate 	aug_save_event(AUE_cron_invoke);
4340Sstevel@tonic-gate 	aug_save_sorf(3);
4350Sstevel@tonic-gate 	aug_save_text(textbuf);
4360Sstevel@tonic-gate 	(void) aug_audit();
4370Sstevel@tonic-gate }
4380Sstevel@tonic-gate 
4390Sstevel@tonic-gate int
audit_cron_create_anc_file(char * name,char * path,char * uname,uid_t uid)4400Sstevel@tonic-gate audit_cron_create_anc_file(char *name, char *path, char *uname, uid_t uid)
4410Sstevel@tonic-gate {
4420Sstevel@tonic-gate 	au_mask_t	msk;
4430Sstevel@tonic-gate 	auditinfo_addr_t ai;
4440Sstevel@tonic-gate 	int		pid;
4450Sstevel@tonic-gate 	char		*anc_name;
4460Sstevel@tonic-gate 	char		full_path[PATH_MAX];
4470Sstevel@tonic-gate 
4480Sstevel@tonic-gate 	if (cannot_audit(0))
4490Sstevel@tonic-gate 		return (0);
4500Sstevel@tonic-gate 
4510Sstevel@tonic-gate 	if (name == NULL)
4520Sstevel@tonic-gate 		return (0);
4530Sstevel@tonic-gate 
4540Sstevel@tonic-gate 	if (path != NULL) {
4550Sstevel@tonic-gate 		if (strlen(path) + strlen(name) + 2 > PATH_MAX)
4560Sstevel@tonic-gate 			return (-1);
4570Sstevel@tonic-gate 		(void) strcat(strcat(strcpy(full_path, path), "/"), name);
4580Sstevel@tonic-gate 		name = full_path;
4590Sstevel@tonic-gate 	}
4600Sstevel@tonic-gate 	anc_name = audit_cron_make_anc_name(name);
4610Sstevel@tonic-gate 
4620Sstevel@tonic-gate 	if (access(anc_name, F_OK) != 0) {
4630Sstevel@tonic-gate 		if (au_user_mask(uname, &msk) != 0) {
4640Sstevel@tonic-gate 			free(anc_name);
4650Sstevel@tonic-gate 			return (-1);
4660Sstevel@tonic-gate 		}
4670Sstevel@tonic-gate 
4680Sstevel@tonic-gate 		ai.ai_mask = msk;
4690Sstevel@tonic-gate 		ai.ai_auid = uid;
4700Sstevel@tonic-gate 		ai.ai_termid.at_port = 0;
4710Sstevel@tonic-gate 		ai.ai_termid.at_type = AU_IPv4;
4720Sstevel@tonic-gate 		ai.ai_termid.at_addr[0] = 0;
4730Sstevel@tonic-gate 		ai.ai_termid.at_addr[1] = 0;
4740Sstevel@tonic-gate 		ai.ai_termid.at_addr[2] = 0;
4750Sstevel@tonic-gate 		ai.ai_termid.at_addr[3] = 0;
4760Sstevel@tonic-gate 		/* generate new pid to use it as asid */
4770Sstevel@tonic-gate 		pid = vfork();
4780Sstevel@tonic-gate 		if (pid == -1) {
4790Sstevel@tonic-gate 			free(anc_name);
4800Sstevel@tonic-gate 			return (-1);
4810Sstevel@tonic-gate 		}
4820Sstevel@tonic-gate 		if (pid == 0)
4830Sstevel@tonic-gate 			exit(0);
4840Sstevel@tonic-gate 		else {
4850Sstevel@tonic-gate 		/*
4860Sstevel@tonic-gate 		 * we need to clear status of children for
4870Sstevel@tonic-gate 		 * wait() call in "cron"
4880Sstevel@tonic-gate 		 */
4890Sstevel@tonic-gate 			int lock;
4900Sstevel@tonic-gate 
4910Sstevel@tonic-gate 			(void) waitpid(pid, &lock, 0);
4920Sstevel@tonic-gate 		}
4930Sstevel@tonic-gate 		ai.ai_asid = pid;
4940Sstevel@tonic-gate 		if (audit_cron_setinfo(anc_name, &ai) != 0) {
4950Sstevel@tonic-gate 			free(anc_name);
4960Sstevel@tonic-gate 			return (-1);
4970Sstevel@tonic-gate 		}
4980Sstevel@tonic-gate 	}
4990Sstevel@tonic-gate 
5000Sstevel@tonic-gate 	free(anc_name);
5010Sstevel@tonic-gate 	return (0);
5020Sstevel@tonic-gate }
5030Sstevel@tonic-gate 
5040Sstevel@tonic-gate int
audit_cron_delete_anc_file(char * name,char * path)5050Sstevel@tonic-gate audit_cron_delete_anc_file(char *name, char *path)
5060Sstevel@tonic-gate {
5070Sstevel@tonic-gate 	char	*anc_name;
5080Sstevel@tonic-gate 	char	full_path[PATH_MAX];
5090Sstevel@tonic-gate 	int	r;
5100Sstevel@tonic-gate 
5110Sstevel@tonic-gate 	if (name == NULL)
5120Sstevel@tonic-gate 		return (0);
5130Sstevel@tonic-gate 
5140Sstevel@tonic-gate 	if (path != NULL) {
5150Sstevel@tonic-gate 		if (strlen(path) + strlen(name) + 2 > PATH_MAX)
5160Sstevel@tonic-gate 			return (-1);
5170Sstevel@tonic-gate 		(void) strcat(strcat(strcpy(full_path, path), "/"), name);
5180Sstevel@tonic-gate 		name = full_path;
5190Sstevel@tonic-gate 	}
5200Sstevel@tonic-gate 	anc_name = audit_cron_make_anc_name(name);
5210Sstevel@tonic-gate 	r = unlink(anc_name);
5220Sstevel@tonic-gate 	free(anc_name);
5230Sstevel@tonic-gate 	return (r);
5240Sstevel@tonic-gate }
525