コード例 #1
0
/*
 * ndmpd_worker thread
 *
 * Parameters:
 *   argp (input) - structure containing socket and handler function
 *
 * Returns:
 *   0 - successful connection.
 *  -1 - error.
 */
void *
ndmpd_worker(void *ptarg)
{
	int sock;
	ndmp_connection_t *connection;
	ndmpd_worker_arg_t *argp = (ndmpd_worker_arg_t *)ptarg;

	if (!argp)
		return ((void *)-1);

	NS_INC(trun);
	sock = argp->nw_sock;

	if ((connection = ndmp_create_connection()) == NULL) {
		(void) close(sock);
		free(argp);
		exit(1);
	}

	/* initialize auditing session */
	if (adt_start_session(&connection->conn_ah, NULL, 0) != 0) {
		free(argp);
		return ((void *)-1);
	}

	((ndmp_connection_t *)connection)->conn_sock = sock;
	(*argp->nw_con_handler_func)(connection);
	(void) adt_end_session(connection->conn_ah);
	ndmp_destroy_connection(connection);
	NS_DEC(trun);

	free(argp);
	return (NULL);
}
static void
mdm_session_solaris_auditor_report_logout (MdmSessionAuditor *auditor)
{
        MdmSessionSolarisAuditor *solaris_auditor;
        adt_session_data_t       *adt_ah;  /* Audit session handle */
        adt_event_data_t         *event;   /* Event to generate    */

        solaris_auditor = MDM_SESSION_SOLARIS_AUDITOR (auditor);

        adt_ah = solaris_auditor->priv->audit_session_handle;

        event = adt_alloc_event (adt_ah, ADT_logout);
        if (event == NULL) {
                syslog (LOG_AUTH | LOG_ALERT,
                        "adt_alloc_event (ADT_logout): %m");
        } else if (adt_put_event (event, ADT_SUCCESS, ADT_SUCCESS) != 0) {
                syslog (LOG_AUTH | LOG_ALERT,
                        "adt_put_event (ADT_logout, ADT_SUCCESS): %m");
        }

        adt_free_event (event);

        /* Reset process audit state. this process is being reused. */
        if ((adt_set_user (adt_ah, ADT_NO_AUDIT, ADT_NO_AUDIT, ADT_NO_AUDIT,
                           ADT_NO_AUDIT, NULL, ADT_NEW) != 0) ||
            (adt_set_proc (adt_ah) != 0)) {
                syslog (LOG_AUTH | LOG_ALERT,
                        "adt_set_proc (ADT_logout reset): %m");
        }

        (void) adt_end_session (adt_ah);
        solaris_auditor->priv->audit_session_handle = NULL;
}
コード例 #3
0
ファイル: hotplugd_door.c プロジェクト: olbohlen/illumos-gate
/*
 * audit_changestate()
 *
 *	Audit a 'changestate' door command.
 */
static void
audit_changestate(ucred_t *ucred, char *auth, char *path, char *connection,
                  int new_state, int old_state, int result)
{
    adt_session_data_t	*session;
    adt_event_data_t	*event;
    int			pass_fail, fail_reason;

    if (audit_session(ucred, &session) != 0)
        return;

    if ((event = adt_alloc_event(session, ADT_hotplug_state)) == NULL) {
        (void) adt_end_session(session);
        return;
    }

    if (result == 0) {
        pass_fail = ADT_SUCCESS;
        fail_reason = ADT_SUCCESS;
    } else {
        pass_fail = ADT_FAILURE;
        fail_reason = result;
    }

    event->adt_hotplug_state.auth_used = auth;
    event->adt_hotplug_state.device_path = path;
    event->adt_hotplug_state.connection = connection;
    event->adt_hotplug_state.new_state = state_str(new_state);
    event->adt_hotplug_state.old_state = state_str(old_state);

    /* Put the event */
    if (adt_put_event(event, pass_fail, fail_reason) != 0)
        log_err("Cannot put audit event.\n");

    adt_free_event(event);
    (void) adt_end_session(session);
}
コード例 #4
0
ファイル: in.rlogind.c プロジェクト: AlainODea/illumos-gate
/*
 * audit_rlogin_settid stores the terminal id while it is still
 * available.  Subsequent calls to adt_load_hostname() return
 * the id which is stored here.
 */
static int
audit_rlogin_settid(int fd) {
	adt_session_data_t	*ah;
	adt_termid_t		*termid;
	int			rc;

	if ((rc = adt_start_session(&ah, NULL, 0)) == 0) {
		if ((rc = adt_load_termid(fd, &termid)) == 0) {
			if ((rc = adt_set_user(ah, ADT_NO_AUDIT,
			    ADT_NO_AUDIT, 0, ADT_NO_AUDIT,
			    termid, ADT_SETTID)) == 0)
				(void) adt_set_proc(ah);
			free(termid);
		}
		(void) adt_end_session(ah);
	}
	return (rc);
}
コード例 #5
0
/*
 * Returns 0 on success or -1 on error.
 */
int
solaris_audit_success(int argc, char *argv[])
{
	int rc = -1;

	if (adt_sudo_common(argc, argv) != 0) {
		return -1;
	}
	if (adt_put_event(event, ADT_SUCCESS, ADT_SUCCESS) != 0) {
		log_warning(SLOG_NO_STDERR, "adt_put_event(ADT_SUCCESS)");
	} else {
		rc = 0;
	}
	adt_free_event(event);
	(void) adt_end_session(ah);

	return rc;
}
コード例 #6
0
void
audit_pool(const adt_export_data_t *imported_state, au_event_t event_id,
    int result, const char *auth_used, const char *pool, const char *device)
{
	adt_session_data_t      *ah;
	adt_event_data_t        *event;

	if (adt_start_session(&ah, imported_state, 0) != 0) {
        	printf ("adt_start_session failed %d\n", errno);
        	return;
	}
	if ((event = adt_alloc_event(ah, event_id)) == NULL) {
        	printf ("adt_alloc_event(ADT_attach)\n", errno);
        	return;
	}

	switch (event_id) {
	case ADT_pool_export:
		event->adt_pool_export.auth_used = (char *)auth_used;
		event->adt_pool_export.pool = (char *)pool;
		event->adt_pool_export.device = (char *)device;
		break;
	case ADT_pool_import:
		event->adt_pool_import.auth_used = (char *)auth_used;
		event->adt_pool_import.pool = (char *)pool;
		event->adt_pool_import.device = (char *)device;
		break;
	default:
		goto out;
	}

	if (result == 0) {
		if (adt_put_event(event, ADT_SUCCESS, ADT_SUCCESS) != 0) {
			printf ("adt_put_event(%d, success)\n", event_id);
		}
	} else {
		if (adt_put_event(event, ADT_FAILURE, result) != 0) {
			printf ("adt_put_event(%d, failure)\n", event_id);
		}
	}
out:
	adt_free_event(event);
	(void) adt_end_session(ah);
}
コード例 #7
0
ファイル: hotplugd_door.c プロジェクト: olbohlen/illumos-gate
/*
 * audit_session()
 *
 *	Initialize an audit session.
 */
static int
audit_session(ucred_t *ucred, adt_session_data_t **sessionp)
{
    adt_session_data_t	*session;

    if (adt_start_session(&session, NULL, 0) != 0) {
        log_err("Cannot start audit session.\n");
        return (-1);
    }

    if (adt_set_from_ucred(session, ucred, ADT_NEW) != 0) {
        log_err("Cannot set audit session from ucred.\n");
        (void) adt_end_session(session);
        return (-1);
    }

    *sessionp = session;
    return (0);
}
コード例 #8
0
static int
adt_sudo_common(int argc, char *argv[])
{
	if (adt_start_session(&ah, NULL, ADT_USE_PROC_DATA) != 0) {
		log_warning(SLOG_NO_STDERR, "adt_start_session");
		return -1;
	}
	if ((event = adt_alloc_event(ah, ADT_sudo)) == NULL) {
		log_warning(SLOG_NO_STDERR, "alloc_event");
		(void) adt_end_session(ah);
		return -1;
	}
	if ((event->adt_sudo.cwdpath = getcwd(cwd, sizeof(cwd))) == NULL) {
		log_warning(SLOG_NO_STDERR, _("unable to get current working directory"));
	}

	/* get the real executable name */
	if (user_cmnd != NULL) {
		if (strlcpy(cmdpath, (const char *)user_cmnd,
		    sizeof(cmdpath)) >= sizeof(cmdpath)) {
			log_warningx(SLOG_NO_STDERR,
			    _("truncated audit path user_cmnd: %s"),
			    user_cmnd);
		}
	} else {
		if (strlcpy(cmdpath, (const char *)argv[0],
		    sizeof(cmdpath)) >= sizeof(cmdpath)) {
			log_warningx(SLOG_NO_STDERR,
			    _("truncated audit path argv[0]: %s"),
			    argv[0]);
		}
	}

	event->adt_sudo.cmdpath = cmdpath;
	event->adt_sudo.argc = argc - 1;
	event->adt_sudo.argv = &argv[1];
	event->adt_sudo.envp = env_get();

	return 0;
}
コード例 #9
0
/*
 * Returns 0 on success or -1 on error.
 */
int
solaris_audit_failure(int argc, char *argv[], char const *const fmt, va_list ap)
{
	int rc = -1;

	if (adt_sudo_common(argc, argv) != 0) {
		return -1;
	}
	if (vasprintf(&event->adt_sudo.errmsg, fmt, ap) == -1) {
		log_warning(SLOG_NO_STDERR,
		    _("audit_failure message too long"));
	}
	if (adt_put_event(event, ADT_FAILURE, ADT_FAIL_VALUE_PROGRAM) != 0) {
		log_warning(SLOG_NO_STDERR, "adt_put_event(ADT_FAILURE)");
	} else {
		rc = 0;
	}
	free(event->adt_sudo.errmsg);
	adt_free_event(event);
	(void) adt_end_session(ah);

	return 0;
}
コード例 #10
0
ファイル: ilbd_rules.c プロジェクト: AlainODea/illumos-gate
/*
 * Generates an audit record for a supplied rule name
 * Used for enable_rule, disable_rule, delete_rule,
 * and create_rule subcommands
 */
static void
ilbd_audit_rule_event(const char *audit_rule_name,
    ilb_rule_info_t *rlinfo, ilbd_cmd_t cmd, ilb_status_t rc,
    ucred_t *ucredp)
{
	adt_session_data_t	*ah;
	adt_event_data_t	*event;
	au_event_t		flag;
	int			scf_val_len = ILBD_MAX_VALUE_LEN;
	char			*aobuf = NULL; /* algo:topo */
	char			*valstr1 = NULL;
	char			*valstr2 = NULL;
	char			pbuf[PROTOCOL_LEN]; /* protocol */
	char			hcpbuf[PORT_LEN]; /* hcport */
	int			audit_error;

	if ((ucredp == NULL) && (cmd == ILBD_CREATE_RULE))  {
		/*
		 * we came here from the path where ilbd incorporates
		 * the configuration that is listed in SCF :
		 * i_ilbd_read_config->ilbd_walk_rule_pgs->
		 *    ->ilbd_scf_instance_walk_pg->ilbd_create_rule
		 * We skip auditing in that case
		 */
		return;
	}
	if (adt_start_session(&ah, NULL, 0) != 0) {
		logerr("ilbd_audit_rule_event: adt_start_session failed");
		exit(EXIT_FAILURE);
	}
	if (adt_set_from_ucred(ah, ucredp, ADT_NEW) != 0) {
		(void) adt_end_session(ah);
		logerr("ilbd_audit_rule_event: adt_set_from_ucred failed");
		exit(EXIT_FAILURE);
	}
	if (cmd == ILBD_ENABLE_RULE)
		flag = ADT_ilb_enable_rule;
	else if (cmd == ILBD_DISABLE_RULE)
		flag = ADT_ilb_disable_rule;
	else if (cmd == ILBD_DESTROY_RULE)
		flag = ADT_ilb_delete_rule;
	else if (cmd == ILBD_CREATE_RULE)
		flag = ADT_ilb_create_rule;

	if ((event = adt_alloc_event(ah, flag)) == NULL) {
		logerr("ilbd_audit_rule_event: adt_alloc_event failed");
		exit(EXIT_FAILURE);
	}

	(void) memset((char *)event, 0, sizeof (adt_event_data_t));

	switch (cmd) {
	case ILBD_DESTROY_RULE:
		event->adt_ilb_delete_rule.auth_used = NET_ILB_CONFIG_AUTH;
		event->adt_ilb_delete_rule.rule_name = (char *)audit_rule_name;
		break;
	case ILBD_ENABLE_RULE:
		event->adt_ilb_enable_rule.auth_used = NET_ILB_ENABLE_AUTH;
		event->adt_ilb_enable_rule.rule_name = (char *)audit_rule_name;
		break;
	case ILBD_DISABLE_RULE:
		event->adt_ilb_disable_rule.auth_used = NET_ILB_ENABLE_AUTH;
		event->adt_ilb_disable_rule.rule_name = (char *)audit_rule_name;
		break;
	case ILBD_CREATE_RULE:
		if (((aobuf = malloc(scf_val_len)) == NULL) ||
		    ((valstr1 = malloc(scf_val_len)) == NULL) ||
		    ((valstr2 = malloc(scf_val_len)) == NULL)) {
			logerr("ilbd_audit_rule_event: could not"
			    " allocate buffer");
			exit(EXIT_FAILURE);
		}

		event->adt_ilb_create_rule.auth_used = NET_ILB_CONFIG_AUTH;

		/* Fill in virtual IP address type */
		if (IN6_IS_ADDR_V4MAPPED(&rlinfo->rl_vip)) {
			event->adt_ilb_create_rule.virtual_ipaddress_type =
			    ADT_IPv4;
			cvt_addr(event->adt_ilb_create_rule.virtual_ipaddress,
			    ADT_IPv4, rlinfo->rl_vip);
		} else {
			event->adt_ilb_create_rule.virtual_ipaddress_type =
			    ADT_IPv6;
			cvt_addr(event->adt_ilb_create_rule.virtual_ipaddress,
			    ADT_IPv6, rlinfo->rl_vip);
		}
		/* Fill in port - could be a single value or a range */
		event->adt_ilb_create_rule.min_port = ntohs(rlinfo->rl_minport);
		if (ntohs(rlinfo->rl_maxport) > ntohs(rlinfo->rl_minport)) {
			/* port range */
			event->adt_ilb_create_rule.max_port =
			    ntohs(rlinfo->rl_maxport);
		} else {
			/* in audit record, max=min when single port */
			event->adt_ilb_create_rule.max_port =
			    ntohs(rlinfo->rl_minport);
		}

		/*
		 * Fill in  protocol - if user does not specify it,
		 * its TCP by default
		 */
		if (rlinfo->rl_proto == IPPROTO_UDP)
			(void) snprintf(pbuf, PROTOCOL_LEN, "UDP");
		else
			(void) snprintf(pbuf, PROTOCOL_LEN, "TCP");
		event->adt_ilb_create_rule.protocol = pbuf;

		/* Fill in algorithm and operation type */
		ilbd_algo_to_str(rlinfo->rl_algo, valstr1);
		ilbd_topo_to_str(rlinfo->rl_topo, valstr2);
		(void) snprintf(aobuf, scf_val_len, "%s:%s",
		    valstr1, valstr2);
		event->adt_ilb_create_rule.algo_optype = aobuf;

		/* Fill in proxy-src for the NAT case */
		if (rlinfo->rl_topo == ILB_TOPO_NAT)  {
			/* copy starting proxy-src address */
			if (IN6_IS_ADDR_V4MAPPED(&rlinfo->rl_nat_src_start)) {
				/* V4 case */
				event->adt_ilb_create_rule.proxy_src_min_type =
				    ADT_IPv4;
				cvt_addr(
				    event->adt_ilb_create_rule.proxy_src_min,
				    ADT_IPv4, rlinfo->rl_nat_src_start);
			} else {
				/* V6 case */
				event->adt_ilb_create_rule.proxy_src_min_type =
				    ADT_IPv6;
				cvt_addr(
				    event->adt_ilb_create_rule.proxy_src_min,
				    ADT_IPv6, rlinfo->rl_nat_src_start);
			}

			/* copy ending proxy-src address */
			if (&rlinfo->rl_nat_src_end == 0) {
				/* proxy-src is a single address */
				event->adt_ilb_create_rule.proxy_src_max_type =
				    event->
				    adt_ilb_create_rule.proxy_src_min_type;
				(void) memcpy(
				    event->adt_ilb_create_rule.proxy_src_max,
				    event->adt_ilb_create_rule.proxy_src_min,
				    (4 * sizeof (uint32_t)));
			} else if (
			    IN6_IS_ADDR_V4MAPPED(&rlinfo->rl_nat_src_end)) {
				/*
				 * proxy-src is a address range - copy ending
				 * proxy-src address
				 * V4 case
				 */
				event->adt_ilb_create_rule.proxy_src_max_type =
				    ADT_IPv4;
				cvt_addr(
				    event->adt_ilb_create_rule.proxy_src_max,
				    ADT_IPv4, rlinfo->rl_nat_src_end);
			} else {
				/* V6 case */
				event->adt_ilb_create_rule.proxy_src_max_type =
				    ADT_IPv6;
				cvt_addr(
				    event->adt_ilb_create_rule.proxy_src_max,
				    ADT_IPv6, rlinfo->rl_nat_src_end);
			}
		}

		/*
		 * Fill in pmask if user has specified one - 0 means
		 * no persistence
		 */
		valstr1[0] = '\0';
		ilbd_ip_to_str(rlinfo->rl_ipversion, &rlinfo->rl_stickymask,
		    valstr1);
			event->adt_ilb_create_rule.persist_mask = valstr1;

		/* If there is a hcname */
		if (rlinfo->rl_hcname[0] != '\0')
			event->adt_ilb_create_rule.hcname = rlinfo->rl_hcname;

		/* Fill in hcport */
		if (rlinfo->rl_hcpflag == ILB_HCI_PROBE_FIX) {
			/* hcport is specified by user */
			(void) snprintf(hcpbuf, PORT_LEN, "%d",
			    rlinfo->rl_hcport);
			event->adt_ilb_create_rule.hcport = hcpbuf;
		} else if (rlinfo->rl_hcpflag == ILB_HCI_PROBE_ANY) {
			/* user has specified "ANY" */
			(void) snprintf(hcpbuf, PORT_LEN, "ANY");
			event->adt_ilb_create_rule.hcport = hcpbuf;
		}
		/*
		 * Fill out the conndrain, nat_timeout and persist_timeout
		 * If the user does not specify them, the default value
		 * is set in the kernel. Userland does not know what
		 * the values are. So if the user
		 * does not specify these values they will show up as
		 * 0 in the audit record.
		 */
		event->adt_ilb_create_rule.conndrain_timeout =
		    rlinfo->rl_conndrain;
		event->adt_ilb_create_rule.nat_timeout =
		    rlinfo->rl_nat_timeout;
		event->adt_ilb_create_rule.persist_timeout =
		    rlinfo->rl_sticky_timeout;

		/* Fill out servergroup and rule name */
		event->adt_ilb_create_rule.server_group = rlinfo->rl_sgname;
		event->adt_ilb_create_rule.rule_name = rlinfo->rl_name;
		break;
	}
	if (rc == ILB_STATUS_OK) {
		if (adt_put_event(event, ADT_SUCCESS, ADT_SUCCESS) != 0) {
			logerr("ilbd_audit_rule_event:adt_put_event failed");
			exit(EXIT_FAILURE);
		}
	} else {
		audit_error = ilberror2auditerror(rc);
		if (adt_put_event(event, ADT_FAILURE, audit_error) != 0) {
			logerr("ilbd_audit_rule_event: adt_put_event failed");
			exit(EXIT_FAILURE);
		}
	}
	adt_free_event(event);
	free(aobuf);
	free(valstr1);
	free(valstr2);
	(void) adt_end_session(ah);
}
コード例 #11
0
/*
 * This entry point _should_ be the common entry to suspend.  It is in
 * it's entirety here, but would be best moved to libpower when that
 * is available.
 */
static void
pm_suspend(void)
{
	int			cprarg = AD_SUSPEND;
	enum adt_uadmin_fcn	fcn_id = ADT_FCN;
	au_event_t		event_id = ADT_uadmin_freeze;
	adt_event_data_t	*event = NULL; /* event to be generated */
	adt_session_data_t	*ah = NULL;  /* audit session handle */

	/*
	 * Does the user have permission to use this command?
	 */
	if (chkauthattr(AUTHNAME_SUSPEND, user) != 1) {
		(void) printf(gettext("User %s does not have correct "
		    "authorizations to suspend this machine.\n"), user);
		exit(1);
	}

	if (flags & LOWPOWER) {
		if (bringto_lowpower() == -1) {
			(void) printf(gettext("LowPower Failed\n"));
			exit(1);
		}
	} else if (flags & TEST) {
		/*
		 * Test mode, do checks as if a real suspend, but
		 * don't actually do the suspend.
		 */
		/* Check if suspend is supported */
		if (pm_check_suspend() == -1) {
			suspend_error(errno);
		}

		(void) printf(gettext("TEST: Suspend would have been"
		    " performed\n"));

	} else {
		/* Check if suspend is supported */
		if (pm_check_suspend() == -1) {
			suspend_error(errno);
		}

		/*
		 * We are about to suspend this machine, try and
		 * lock the screen.  We don't really care if this
		 * succeeds or not, but that we actually tried. We
		 * also know that we have sufficient privileges to
		 * be here, so we lock the screen now, even if
		 * suspend actually fails.
		 * Note that garbage is sometimes displayed, and
		 * we don't really care about it, so we toss all
		 * text response.
		 * it would also be good if there were another option
		 * instead of launcing a file, as the disk might be
		 * spun down if we are suspending due to idle.
		 */
		if (!(flags & NO_XLOCK)) {
			(void) system("/usr/bin/xdg-screensaver lock "
			    " >/dev/null 2>&1");
		}

		/* Time to do the actual deed!  */
		/*
		 * Before we actually suspend, we need to audit and
		 * "suspend" the audit files.
		 */
		/* set up audit session and event */
		if (adt_start_session(&ah, NULL, ADT_USE_PROC_DATA) == 0) {
			if ((event = adt_alloc_event(ah, event_id)) != NULL) {
				event->adt_uadmin_freeze.fcn = fcn_id;
				event->adt_uadmin_freeze.mdep = NULL;
				if (adt_put_event(event, ADT_SUCCESS, 0) != 0) {
					(void) fprintf(stderr, gettext(
					    "%s: can't put audit event\n"),
					    argvl[0]);
				} else {
					wait_for_auqueue();
				}
			}
			(void) change_audit_file();
		} else {
			(void) fprintf(stderr, gettext(
			    "%s: can't start audit session\n"), argvl[0]);
		}

		if (uadmin(A_FREEZE, cprarg, 0) != 0) {
			(void) printf(gettext("Suspend Failed\n"));
			if (flags & FORCE) {
				/*
				 * Note, that if we actually poweroff,
				 * that the poweroff function will handle
				 * that audit trail, and the resume
				 * trail is effectively done.
				 */
				pm_poweroff();
			} else {
				/* suspend_error() will exit. */
				suspend_error(errno);
				/*
				 * Audit the suspend failure and
				 * reuse the event, but don't create one
				 * if we don't already have one.
				 */
				if (event != NULL) {
					(void) adt_put_event(event,
					    ADT_FAILURE, 0);
				}
			}
		}

		/*
		 * Write the thaw event.
		 */
		if (ah != NULL) {
			if ((event == NULL) &&
			    ((event = adt_alloc_event(ah, ADT_uadmin_thaw))
			    == NULL)) {
				(void) fprintf(stderr, gettext(
				    "%s: can't allocate thaw audit event\n"),
				    argvl[0]);
			} else {
				event->adt_uadmin_thaw.fcn = fcn_id;
				if (adt_put_event(event, ADT_SUCCESS, 0) != 0) {
					(void) fprintf(stderr, gettext(
					    "%s: can't put thaw audit event\n"),
					    argvl[0]);
				}
				(void) adt_free_event(event);
			}
		}
	}
	if ((no_tty ? 0 : 1) && !(flags & NO_XLOCK)) {
		pm_do_auth(ah);
	}

	(void) adt_end_session(ah);
}
static void
mdm_session_solaris_auditor_report_login_failure (MdmSessionAuditor *auditor,
                                                  int                pam_error_code,
                                                  const char        *pam_error_string)
{
        MdmSessionSolarisAuditor *solaris_auditor;
        char                     *hostname;
        char                     *display_device;
        adt_session_data_t       *ah;     /* Audit session handle     */
        adt_event_data_t         *event;  /* Event to generate        */
        adt_termid_t             *tid;    /* Terminal ID for failures */

        solaris_auditor = MDM_SESSION_SOLARIS_AUDITOR (auditor);
        g_object_get (G_OBJECT (auditor),
                      "hostname", &hostname,
                      "display-device", &display_device, NULL);

        if (solaris_auditor->priv->user_accredited) {
                if (adt_start_session (&ah, NULL, ADT_USE_PROC_DATA) != 0) {
                        syslog (LOG_AUTH | LOG_ALERT,
                                "adt_start_session (ADT_login, ADT_FAILURE): %m");
                        goto cleanup;
                }
        } else {
                if (adt_start_session (&ah, NULL, 0) != 0) {
                        syslog (LOG_AUTH | LOG_ALERT,
                                "adt_start_session (ADT_login, ADT_FAILURE): %m");
                        goto cleanup;
                }

                /* If display is on console or VT */
                if (hostname != NULL && hostname[0] != '\0') {
                        /* Login from a remote host */
                        if (adt_load_hostname (hostname, &tid) != 0) {
                                syslog (LOG_AUTH | LOG_ALERT,
                                        "adt_loadhostname (%s): %m", hostname);
                        }
                } else {
                        /* login from the local host */
                        if (adt_load_ttyname (display_device, &tid) != 0) {
                                syslog (LOG_AUTH | LOG_ALERT,
                                        "adt_loadhostname (localhost): %m");
                        }
                }

                if (adt_set_user (ah,
                                  solaris_auditor->priv->username != NULL ? solaris_auditor->priv->uid : ADT_NO_ATTRIB,
                                  solaris_auditor->priv->username != NULL ? solaris_auditor->priv->gid : ADT_NO_ATTRIB,
                                  solaris_auditor->priv->username != NULL ? solaris_auditor->priv->uid : ADT_NO_ATTRIB,
                                  solaris_auditor->priv->username != NULL ? solaris_auditor->priv->gid : ADT_NO_ATTRIB,
                                  tid, ADT_NEW) != 0) {

                        syslog (LOG_AUTH | LOG_ALERT,
                                "adt_set_user (%s): %m",
                                solaris_auditor->priv->username != NULL ? solaris_auditor->priv->username : "******");
                }
        }

        event = adt_alloc_event (ah, ADT_login);

        if (event == NULL) {
                syslog (LOG_AUTH | LOG_ALERT,
                        "adt_alloc_event (ADT_login, ADT_FAILURE): %m");
                goto done;
        } else if (adt_put_event (event, ADT_FAILURE,
                                  ADT_FAIL_PAM + pam_error_code) != 0) {
                syslog (LOG_AUTH | LOG_ALERT,
                        "adt_put_event (ADT_login (ADT_FAIL, %s): %m",
                        pam_error_string);
        }

        if (solaris_auditor->priv->password_change_initiated) {
                /* Also audit password change */
                adt_free_event (event);

                event = adt_alloc_event (ah, ADT_passwd);
                if (event == NULL) {
                        syslog (LOG_AUTH | LOG_ALERT,
                                "adt_alloc_event (ADT_passwd): %m");
                        goto done;
                }

                if (solaris_auditor->priv->password_changed) {
                        if (adt_put_event (event, ADT_SUCCESS,
                                           ADT_SUCCESS) != 0) {

                                syslog (LOG_AUTH | LOG_ALERT,
                                        "adt_put_event (ADT_passwd, ADT_SUCCESS): "
                                        "%m");
                        }
                } else {
                        if (adt_put_event (event, ADT_FAILURE,
                                           ADT_FAIL_PAM + pam_error_code) != 0) {

                                syslog (LOG_AUTH | LOG_ALERT,
                                        "adt_put_event (ADT_passwd, ADT_FAILURE): "
                                        "%m");
                        }
                }
        }
        adt_free_event (event);

done:
        /* Reset process audit state. this process is being reused.*/
        if ((adt_set_user (ah, ADT_NO_AUDIT, ADT_NO_AUDIT, ADT_NO_AUDIT,
                           ADT_NO_AUDIT, NULL, ADT_NEW) != 0) ||
            (adt_set_proc (ah) != 0)) {

                syslog (LOG_AUTH | LOG_ALERT,
                        "adt_put_event (ADT_login (ADT_FAILURE reset, %m)");
        }
        (void) adt_end_session (ah);

cleanup:
        g_free (hostname);
        g_free (display_device);
}