xref: /onnv-gate/usr/src/lib/smbsrv/libmlsvc/common/eventlog_svc.c (revision 12508:edb7861a1533)
18474SJose.Borrego@Sun.COM /*
28474SJose.Borrego@Sun.COM  * CDDL HEADER START
38474SJose.Borrego@Sun.COM  *
48474SJose.Borrego@Sun.COM  * The contents of this file are subject to the terms of the
58474SJose.Borrego@Sun.COM  * Common Development and Distribution License (the "License").
68474SJose.Borrego@Sun.COM  * You may not use this file except in compliance with the License.
78474SJose.Borrego@Sun.COM  *
88474SJose.Borrego@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
98474SJose.Borrego@Sun.COM  * or http://www.opensolaris.org/os/licensing.
108474SJose.Borrego@Sun.COM  * See the License for the specific language governing permissions
118474SJose.Borrego@Sun.COM  * and limitations under the License.
128474SJose.Borrego@Sun.COM  *
138474SJose.Borrego@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
148474SJose.Borrego@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
158474SJose.Borrego@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
168474SJose.Borrego@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
178474SJose.Borrego@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
188474SJose.Borrego@Sun.COM  *
198474SJose.Borrego@Sun.COM  * CDDL HEADER END
208474SJose.Borrego@Sun.COM  */
21*12508Samw@Sun.COM 
228474SJose.Borrego@Sun.COM /*
23*12508Samw@Sun.COM  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
248474SJose.Borrego@Sun.COM  */
258474SJose.Borrego@Sun.COM 
268474SJose.Borrego@Sun.COM /*
278474SJose.Borrego@Sun.COM  * Event Log Service RPC (LOGR) interface definition.
288474SJose.Borrego@Sun.COM  */
298474SJose.Borrego@Sun.COM #include <sys/utsname.h>
308474SJose.Borrego@Sun.COM #include <unistd.h>
318474SJose.Borrego@Sun.COM #include <strings.h>
328474SJose.Borrego@Sun.COM #include <smbsrv/libsmb.h>
338474SJose.Borrego@Sun.COM #include <smbsrv/libmlrpc.h>
348474SJose.Borrego@Sun.COM #include <smbsrv/nmpipes.h>
358474SJose.Borrego@Sun.COM #include <smbsrv/libmlsvc.h>
3610122SJordan.Brown@Sun.COM #include <smbsrv/ndl/eventlog.ndl>
378474SJose.Borrego@Sun.COM 
3810122SJordan.Brown@Sun.COM 
398474SJose.Borrego@Sun.COM #define	LOGR_FWD		+1
408474SJose.Borrego@Sun.COM #define	LOGR_REW		-1
418474SJose.Borrego@Sun.COM #define	LOGR_RECORD_SIGNATURE	0x654C664C
428474SJose.Borrego@Sun.COM 
438474SJose.Borrego@Sun.COM #define	LOGR_PRI(p)		((p) & LOG_PRIMASK)
4410966SJordan.Brown@Sun.COM #define	LOGR_WNSTRLEN(S)	((strlen((S)) + 1) * sizeof (smb_wchar_t))
458474SJose.Borrego@Sun.COM 
468474SJose.Borrego@Sun.COM #define	LOGR_MSG_DWORD_OFFSET	12
478474SJose.Borrego@Sun.COM #define	LOGR_MSG_WORD_OFFSET	4
488474SJose.Borrego@Sun.COM 
498474SJose.Borrego@Sun.COM /*
508474SJose.Borrego@Sun.COM  * READ flags for EventLogRead
518474SJose.Borrego@Sun.COM  *
528474SJose.Borrego@Sun.COM  * EVENTLOG_SEEK_READ
538474SJose.Borrego@Sun.COM  * The read operation proceeds from the record specified by the
548474SJose.Borrego@Sun.COM  * dwRecordOffset parameter. This flag cannot be used with
558474SJose.Borrego@Sun.COM  * EVENTLOG_SEQUENTIAL_READ.
568474SJose.Borrego@Sun.COM  *
578474SJose.Borrego@Sun.COM  * EVENTLOG_SEQUENTIAL_READ
588474SJose.Borrego@Sun.COM  * The read operation proceeds sequentially from the last call to the
598474SJose.Borrego@Sun.COM  * ReadEventLog function using this handle. This flag cannot be used
608474SJose.Borrego@Sun.COM  * with EVENTLOG_SEEK_READ.
618474SJose.Borrego@Sun.COM  *
628474SJose.Borrego@Sun.COM  * If the buffer is large enough, more than one record can be read at
638474SJose.Borrego@Sun.COM  * the specified seek position; you must specify one of the following
648474SJose.Borrego@Sun.COM  * flags to indicate the direction for successive read operations.
658474SJose.Borrego@Sun.COM  *
668474SJose.Borrego@Sun.COM  * EVENTLOG_FORWARDS_READ
678474SJose.Borrego@Sun.COM  * The log is read in chronological order. This flag cannot be used
688474SJose.Borrego@Sun.COM  * with EVENTLOG_BACKWARDS_READ.
698474SJose.Borrego@Sun.COM  *
708474SJose.Borrego@Sun.COM  * EVENTLOG_BACKWARDS_READ
718474SJose.Borrego@Sun.COM  * The log is read in reverse chronological order. This flag cannot be
728474SJose.Borrego@Sun.COM  * used with EVENTLOG_FORWARDS_READ.
738474SJose.Borrego@Sun.COM  */
748474SJose.Borrego@Sun.COM #define	EVENTLOG_SEQUENTIAL_READ	0x0001
758474SJose.Borrego@Sun.COM #define	EVENTLOG_SEEK_READ		0x0002
768474SJose.Borrego@Sun.COM #define	EVENTLOG_FORWARDS_READ		0x0004
778474SJose.Borrego@Sun.COM #define	EVENTLOG_BACKWARDS_READ		0x0008
788474SJose.Borrego@Sun.COM 
798474SJose.Borrego@Sun.COM /*
808474SJose.Borrego@Sun.COM  * The types of events that can be logged.
818474SJose.Borrego@Sun.COM  */
828474SJose.Borrego@Sun.COM #define	EVENTLOG_SUCCESS		0x0000
838474SJose.Borrego@Sun.COM #define	EVENTLOG_ERROR_TYPE		0x0001
848474SJose.Borrego@Sun.COM #define	EVENTLOG_WARNING_TYPE		0x0002
858474SJose.Borrego@Sun.COM #define	EVENTLOG_INFORMATION_TYPE	0x0004
868474SJose.Borrego@Sun.COM #define	EVENTLOG_AUDIT_SUCCESS		0x0008
878474SJose.Borrego@Sun.COM #define	EVENTLOG_AUDIT_FAILURE		0x0010
888474SJose.Borrego@Sun.COM 
898474SJose.Borrego@Sun.COM /*
908474SJose.Borrego@Sun.COM  * Event Identifiers
918474SJose.Borrego@Sun.COM  *
928474SJose.Borrego@Sun.COM  * Event identifiers uniquely identify a particular event. Each event
938474SJose.Borrego@Sun.COM  * source can define its own numbered events and the description strings
948474SJose.Borrego@Sun.COM  * to which they are mapped. Event viewers can present these strings to
958474SJose.Borrego@Sun.COM  * the user. They should help the user understand what went wrong and
968474SJose.Borrego@Sun.COM  * suggest what actions to take. Direct the description at users solving
978474SJose.Borrego@Sun.COM  * their own problems, not at administrators or support technicians.
988474SJose.Borrego@Sun.COM  * Make the description clear and concise and avoid culture-specific
998474SJose.Borrego@Sun.COM  * phrases.
1008474SJose.Borrego@Sun.COM  *
1018474SJose.Borrego@Sun.COM  * The following diagram illustrates the format of an event identifier.
1028474SJose.Borrego@Sun.COM  *
1038474SJose.Borrego@Sun.COM  *   3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
1048474SJose.Borrego@Sun.COM  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
1058474SJose.Borrego@Sun.COM  *  +---+-+-+-----------------------+-------------------------------+
1068474SJose.Borrego@Sun.COM  *  |Sev|C|R|     Facility          |               Code            |
1078474SJose.Borrego@Sun.COM  *  +---+-+-+-----------------------+-------------------------------+
1088474SJose.Borrego@Sun.COM  *
1098474SJose.Borrego@Sun.COM  *  Sev
1108474SJose.Borrego@Sun.COM  *        Indicates the severity. This is one of the following values:
1118474SJose.Borrego@Sun.COM  *        00 - Success
1128474SJose.Borrego@Sun.COM  *        01 - Informational
1138474SJose.Borrego@Sun.COM  *        10 - Warning
1148474SJose.Borrego@Sun.COM  *        11 - Error
1158474SJose.Borrego@Sun.COM  *
1168474SJose.Borrego@Sun.COM  *  C
1178474SJose.Borrego@Sun.COM  *        Indicates a customer code (1) or a system code (0).
1188474SJose.Borrego@Sun.COM  *  R
1198474SJose.Borrego@Sun.COM  *        Reserved bit.
1208474SJose.Borrego@Sun.COM  *  Facility
1218474SJose.Borrego@Sun.COM  *        Facility code.
1228474SJose.Borrego@Sun.COM  *  Code
1238474SJose.Borrego@Sun.COM  *        Status code for the facility.
1248474SJose.Borrego@Sun.COM  */
1258474SJose.Borrego@Sun.COM #define	EVENTID_SEVERITY_SUCCESS	0x00000000
1268474SJose.Borrego@Sun.COM #define	EVENTID_SEVERITY_INFO		0x40000000
1278474SJose.Borrego@Sun.COM #define	EVENTID_SEVERITY_WARNING	0x80000000
1288474SJose.Borrego@Sun.COM #define	EVENTID_SEVERITY_ERROR		0xC0000000
1298474SJose.Borrego@Sun.COM 
1308474SJose.Borrego@Sun.COM #define	EVENTID_SYSTEM_CODE		0x00000000
1318474SJose.Borrego@Sun.COM #define	EVENTID_CUSTOMER_CODE		0x20000000
1328474SJose.Borrego@Sun.COM 
1338474SJose.Borrego@Sun.COM static int logr_s_EventLogClose(void *, ndr_xa_t *);
1348474SJose.Borrego@Sun.COM static int logr_s_EventLogQueryCount(void *, ndr_xa_t *);
1358474SJose.Borrego@Sun.COM static int logr_s_EventLogGetOldestRec(void *, ndr_xa_t *);
1368474SJose.Borrego@Sun.COM static int logr_s_EventLogOpen(void *, ndr_xa_t *);
1378474SJose.Borrego@Sun.COM static int logr_s_EventLogRead(void *, ndr_xa_t *);
1388474SJose.Borrego@Sun.COM 
1398474SJose.Borrego@Sun.COM static ndr_stub_table_t logr_stub_table[] = {
1408474SJose.Borrego@Sun.COM 	{ logr_s_EventLogClose,		LOGR_OPNUM_EventLogClose },
1418474SJose.Borrego@Sun.COM 	{ logr_s_EventLogQueryCount,	LOGR_OPNUM_EventLogQueryCount },
1428474SJose.Borrego@Sun.COM 	{ logr_s_EventLogGetOldestRec,	LOGR_OPNUM_EventLogGetOldestRec },
1438474SJose.Borrego@Sun.COM 	{ logr_s_EventLogOpen,		LOGR_OPNUM_EventLogOpen },
1448474SJose.Borrego@Sun.COM 	{ logr_s_EventLogRead,		LOGR_OPNUM_EventLogRead },
1458474SJose.Borrego@Sun.COM 	{0}
1468474SJose.Borrego@Sun.COM };
1478474SJose.Borrego@Sun.COM 
1488474SJose.Borrego@Sun.COM static ndr_service_t logr_service = {
1498474SJose.Borrego@Sun.COM 	"LOGR",				/* name */
1508474SJose.Borrego@Sun.COM 	"Event Log Service",		/* desc */
1518474SJose.Borrego@Sun.COM 	"\\eventlog",			/* endpoint */
1528474SJose.Borrego@Sun.COM 	PIPE_NTSVCS,			/* sec_addr_port */
1538474SJose.Borrego@Sun.COM 	"82273fdc-e32a-18c3-3f78-827929dc23ea", 0,	/* abstract */
1548474SJose.Borrego@Sun.COM 	NDR_TRANSFER_SYNTAX_UUID,		2,	/* transfer */
1558474SJose.Borrego@Sun.COM 	0,				/* no bind_instance_size */
1568474SJose.Borrego@Sun.COM 	0,				/* no bind_req() */
1578474SJose.Borrego@Sun.COM 	0,				/* no unbind_and_close() */
1588474SJose.Borrego@Sun.COM 	0,				/* use generic_call_stub() */
1598474SJose.Borrego@Sun.COM 	&TYPEINFO(logr_interface),	/* interface ti */
1608474SJose.Borrego@Sun.COM 	logr_stub_table			/* stub_table */
1618474SJose.Borrego@Sun.COM };
1628474SJose.Borrego@Sun.COM 
1638474SJose.Borrego@Sun.COM /*
1648474SJose.Borrego@Sun.COM  * logr_initialize
1658474SJose.Borrego@Sun.COM  *
1668474SJose.Borrego@Sun.COM  * This function registers the LOGR RPC interface with the RPC runtime
1678474SJose.Borrego@Sun.COM  * library. It must be called in order to use either the client side
1688474SJose.Borrego@Sun.COM  * or the server side functions.
1698474SJose.Borrego@Sun.COM  */
1708474SJose.Borrego@Sun.COM void
logr_initialize(void)1718474SJose.Borrego@Sun.COM logr_initialize(void)
1728474SJose.Borrego@Sun.COM {
1738474SJose.Borrego@Sun.COM 	(void) ndr_svc_register(&logr_service);
17410122SJordan.Brown@Sun.COM 	logr_init();
17510122SJordan.Brown@Sun.COM }
17610122SJordan.Brown@Sun.COM 
17710122SJordan.Brown@Sun.COM void
logr_finalize(void)17810122SJordan.Brown@Sun.COM logr_finalize(void)
17910122SJordan.Brown@Sun.COM {
18010122SJordan.Brown@Sun.COM 	logr_fini();
1818474SJose.Borrego@Sun.COM }
1828474SJose.Borrego@Sun.COM 
1838474SJose.Borrego@Sun.COM /*
1848474SJose.Borrego@Sun.COM  * logr_hdlookup
1858474SJose.Borrego@Sun.COM  *
1868474SJose.Borrego@Sun.COM  * Handle lookup wrapper to validate the local service and/or manager context.
1878474SJose.Borrego@Sun.COM  */
1888474SJose.Borrego@Sun.COM static ndr_handle_t *
logr_hdlookup(ndr_xa_t * mxa,ndr_hdid_t * id)1898474SJose.Borrego@Sun.COM logr_hdlookup(ndr_xa_t *mxa, ndr_hdid_t *id)
1908474SJose.Borrego@Sun.COM {
1918474SJose.Borrego@Sun.COM 	ndr_handle_t *hd;
1928474SJose.Borrego@Sun.COM 	logr_context_t *ctx;
1938474SJose.Borrego@Sun.COM 
1948474SJose.Borrego@Sun.COM 	if ((hd = ndr_hdlookup(mxa, id)) == NULL)
1958474SJose.Borrego@Sun.COM 		return (NULL);
1968474SJose.Borrego@Sun.COM 
1978474SJose.Borrego@Sun.COM 	if ((ctx = (logr_context_t *)hd->nh_data) == NULL)
1988474SJose.Borrego@Sun.COM 		return (NULL);
1998474SJose.Borrego@Sun.COM 
2008474SJose.Borrego@Sun.COM 	if (ctx->lc_source_name == NULL)
2018474SJose.Borrego@Sun.COM 		return (NULL);
2028474SJose.Borrego@Sun.COM 
2038474SJose.Borrego@Sun.COM 	return (hd);
2048474SJose.Borrego@Sun.COM }
2058474SJose.Borrego@Sun.COM 
2068474SJose.Borrego@Sun.COM /*
2078474SJose.Borrego@Sun.COM  * logr_context_data_free
2088474SJose.Borrego@Sun.COM  *
2098474SJose.Borrego@Sun.COM  * Callback to free the context data associated with local service
2108474SJose.Borrego@Sun.COM  * and/or manager context.
2118474SJose.Borrego@Sun.COM  */
2128474SJose.Borrego@Sun.COM static void
logr_context_data_free(void * ctxp)2138474SJose.Borrego@Sun.COM logr_context_data_free(void *ctxp)
2148474SJose.Borrego@Sun.COM {
2158474SJose.Borrego@Sun.COM 	logr_context_t *ctx = (logr_context_t *)ctxp;
2168474SJose.Borrego@Sun.COM 
2178474SJose.Borrego@Sun.COM 	if (ctx == NULL)
2188474SJose.Borrego@Sun.COM 		return;
2198474SJose.Borrego@Sun.COM 
2208474SJose.Borrego@Sun.COM 	free(ctx->lc_source_name);
2218474SJose.Borrego@Sun.COM 	free(ctx->lc_cached_read_data->rd_log);
2228474SJose.Borrego@Sun.COM 	free(ctx->lc_cached_read_data);
2238474SJose.Borrego@Sun.COM 	free(ctx);
2248474SJose.Borrego@Sun.COM 	ctx = NULL;
2258474SJose.Borrego@Sun.COM }
2268474SJose.Borrego@Sun.COM 
2278474SJose.Borrego@Sun.COM /*
22810122SJordan.Brown@Sun.COM  * logr_hdalloc
2298474SJose.Borrego@Sun.COM  *
2308474SJose.Borrego@Sun.COM  * Handle allocation wrapper to setup the local manager context.
2318474SJose.Borrego@Sun.COM  */
2328474SJose.Borrego@Sun.COM static ndr_hdid_t *
logr_hdalloc(ndr_xa_t * mxa,char * logname)23310122SJordan.Brown@Sun.COM logr_hdalloc(ndr_xa_t *mxa, char *logname)
2348474SJose.Borrego@Sun.COM {
2358474SJose.Borrego@Sun.COM 	logr_context_t *ctx;
2368474SJose.Borrego@Sun.COM 
2378474SJose.Borrego@Sun.COM 	if ((ctx = malloc(sizeof (logr_context_t))) == NULL)
2388474SJose.Borrego@Sun.COM 		return (NULL);
2398474SJose.Borrego@Sun.COM 	bzero(ctx, sizeof (logr_context_t));
2408474SJose.Borrego@Sun.COM 
24110122SJordan.Brown@Sun.COM 	ctx->lc_source_name = strdup(logname);
24210122SJordan.Brown@Sun.COM 	if (ctx->lc_source_name == NULL) {
24310122SJordan.Brown@Sun.COM 		free(ctx);
24410122SJordan.Brown@Sun.COM 		return (NULL);
24510122SJordan.Brown@Sun.COM 	}
24610122SJordan.Brown@Sun.COM 
24710122SJordan.Brown@Sun.COM 	if (logr_get_snapshot(ctx) != 0) {
2488474SJose.Borrego@Sun.COM 		free(ctx->lc_source_name);
2498474SJose.Borrego@Sun.COM 		free(ctx);
2508474SJose.Borrego@Sun.COM 		return (NULL);
2518474SJose.Borrego@Sun.COM 	}
2528474SJose.Borrego@Sun.COM 
2538474SJose.Borrego@Sun.COM 	return (ndr_hdalloc(mxa, ctx));
2548474SJose.Borrego@Sun.COM }
2558474SJose.Borrego@Sun.COM 
2568474SJose.Borrego@Sun.COM /*
2578474SJose.Borrego@Sun.COM  * logr_s_EventLogClose
2588474SJose.Borrego@Sun.COM  *
2598474SJose.Borrego@Sun.COM  * This is a request to close the LOGR interface specified by handle.
2608474SJose.Borrego@Sun.COM  * Free the handle and associated resources, and zero out the result
2618474SJose.Borrego@Sun.COM  * handle for the client.
2628474SJose.Borrego@Sun.COM  */
2638474SJose.Borrego@Sun.COM static int
logr_s_EventLogClose(void * arg,ndr_xa_t * mxa)2648474SJose.Borrego@Sun.COM logr_s_EventLogClose(void *arg, ndr_xa_t *mxa)
2658474SJose.Borrego@Sun.COM {
2668474SJose.Borrego@Sun.COM 	struct logr_EventLogClose *param = arg;
2678474SJose.Borrego@Sun.COM 	ndr_hdid_t *id = (ndr_hdid_t *)&param->handle;
2688474SJose.Borrego@Sun.COM 	ndr_handle_t *hd;
2698474SJose.Borrego@Sun.COM 
2708474SJose.Borrego@Sun.COM 	if ((hd = ndr_hdlookup(mxa, id)) == NULL) {
2718474SJose.Borrego@Sun.COM 		bzero(&param->result_handle, sizeof (logr_handle_t));
2728474SJose.Borrego@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
2738474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
2748474SJose.Borrego@Sun.COM 	}
2758474SJose.Borrego@Sun.COM 	logr_context_data_free(hd->nh_data);
2768474SJose.Borrego@Sun.COM 	ndr_hdfree(mxa, id);
2778474SJose.Borrego@Sun.COM 
2788474SJose.Borrego@Sun.COM 	bzero(&param->result_handle, sizeof (logr_handle_t));
2798474SJose.Borrego@Sun.COM 	param->status = NT_STATUS_SUCCESS;
2808474SJose.Borrego@Sun.COM 
2818474SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
2828474SJose.Borrego@Sun.COM }
2838474SJose.Borrego@Sun.COM 
2848474SJose.Borrego@Sun.COM /*
2858474SJose.Borrego@Sun.COM  * logr_s_EventLogOpen
2868474SJose.Borrego@Sun.COM  *
2878474SJose.Borrego@Sun.COM  * Open the event log. Not supported yet.
2888474SJose.Borrego@Sun.COM  */
2898474SJose.Borrego@Sun.COM /*ARGSUSED*/
2908474SJose.Borrego@Sun.COM static int
logr_s_EventLogOpen(void * arg,ndr_xa_t * mxa)2918474SJose.Borrego@Sun.COM logr_s_EventLogOpen(void *arg, ndr_xa_t *mxa)
2928474SJose.Borrego@Sun.COM {
2938474SJose.Borrego@Sun.COM 	struct logr_EventLogOpen *param = arg;
2948474SJose.Borrego@Sun.COM 	ndr_hdid_t *id = NULL;
2958474SJose.Borrego@Sun.COM 	ndr_handle_t *hd;
2968670SJose.Borrego@Sun.COM 	char *log_name = NULL;
2978670SJose.Borrego@Sun.COM 
29810122SJordan.Brown@Sun.COM 	if (!ndr_is_admin(mxa)) {
2998670SJose.Borrego@Sun.COM 		bzero(&param->handle, sizeof (logr_handle_t));
3008670SJose.Borrego@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
3018670SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
3028670SJose.Borrego@Sun.COM 	}
3038474SJose.Borrego@Sun.COM 
30410122SJordan.Brown@Sun.COM 	if (param->log_name.length != 0)
30510122SJordan.Brown@Sun.COM 		log_name = (char *)param->log_name.str;
30610122SJordan.Brown@Sun.COM 
30710122SJordan.Brown@Sun.COM 	if (!logr_is_supported(log_name)) {
30810122SJordan.Brown@Sun.COM 		bzero(&param->handle, sizeof (logr_handle_t));
30910122SJordan.Brown@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
31010122SJordan.Brown@Sun.COM 		return (NDR_DRC_OK);
31110122SJordan.Brown@Sun.COM 	}
31210122SJordan.Brown@Sun.COM 
31310122SJordan.Brown@Sun.COM 	id = logr_hdalloc(mxa, log_name);
3148474SJose.Borrego@Sun.COM 	if (id && ((hd = logr_hdlookup(mxa, id)) != NULL)) {
3158474SJose.Borrego@Sun.COM 		hd->nh_data_free = logr_context_data_free;
3168474SJose.Borrego@Sun.COM 		bcopy(id, &param->handle, sizeof (logr_handle_t));
3178670SJose.Borrego@Sun.COM 		param->status = NT_STATUS_SUCCESS;
3188474SJose.Borrego@Sun.COM 	} else {
3198474SJose.Borrego@Sun.COM 		bzero(&param->handle, sizeof (logr_handle_t));
3208670SJose.Borrego@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
3218474SJose.Borrego@Sun.COM 	}
3228474SJose.Borrego@Sun.COM 
3238474SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
3248474SJose.Borrego@Sun.COM }
3258474SJose.Borrego@Sun.COM 
3268474SJose.Borrego@Sun.COM /*
3278474SJose.Borrego@Sun.COM  * logr_s_EventLogQueryCount
3288474SJose.Borrego@Sun.COM  *
3298474SJose.Borrego@Sun.COM  * take a snapshot from system log, assign it to the given handle.
3308474SJose.Borrego@Sun.COM  * return number of log entries in the snapshot as result of RPC
3318474SJose.Borrego@Sun.COM  * call.
3328474SJose.Borrego@Sun.COM  */
3338474SJose.Borrego@Sun.COM static int
logr_s_EventLogQueryCount(void * arg,ndr_xa_t * mxa)3348474SJose.Borrego@Sun.COM logr_s_EventLogQueryCount(void *arg, ndr_xa_t *mxa)
3358474SJose.Borrego@Sun.COM {
3368474SJose.Borrego@Sun.COM 	struct logr_EventLogQueryCount *param = arg;
3378474SJose.Borrego@Sun.COM 	ndr_hdid_t *id = (ndr_hdid_t *)&param->handle;
3388474SJose.Borrego@Sun.COM 	ndr_handle_t *hd;
3398474SJose.Borrego@Sun.COM 	logr_context_t *ctx;
3408474SJose.Borrego@Sun.COM 	logr_read_data_t *data;
3418474SJose.Borrego@Sun.COM 
3428474SJose.Borrego@Sun.COM 	if ((hd = logr_hdlookup(mxa, id)) == NULL) {
3438474SJose.Borrego@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
3448474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
3458474SJose.Borrego@Sun.COM 	}
3468474SJose.Borrego@Sun.COM 
3478474SJose.Borrego@Sun.COM 	ctx = (logr_context_t *)hd->nh_data;
3488474SJose.Borrego@Sun.COM 	data = ctx->lc_cached_read_data;
3498474SJose.Borrego@Sun.COM 
3508474SJose.Borrego@Sun.COM 	param->rec_num = data->rd_tot_recnum;
3518474SJose.Borrego@Sun.COM 	param->status = NT_STATUS_SUCCESS;
3528474SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
3538474SJose.Borrego@Sun.COM }
3548474SJose.Borrego@Sun.COM 
3558474SJose.Borrego@Sun.COM /*
3568474SJose.Borrego@Sun.COM  * logr_s_EventLogGetOldestRec
3578474SJose.Borrego@Sun.COM  *
3588474SJose.Borrego@Sun.COM  * Return oldest record number in the snapshot as result of RPC call.
3598474SJose.Borrego@Sun.COM  */
3608474SJose.Borrego@Sun.COM static int
logr_s_EventLogGetOldestRec(void * arg,ndr_xa_t * mxa)3618474SJose.Borrego@Sun.COM logr_s_EventLogGetOldestRec(void *arg, ndr_xa_t *mxa)
3628474SJose.Borrego@Sun.COM {
3638474SJose.Borrego@Sun.COM 	struct logr_EventLogGetOldestRec *param = arg;
3648474SJose.Borrego@Sun.COM 	ndr_hdid_t *id = (ndr_hdid_t *)&param->handle;
3658474SJose.Borrego@Sun.COM 	ndr_handle_t *hd;
3668474SJose.Borrego@Sun.COM 	logr_context_t *ctx;
3678474SJose.Borrego@Sun.COM 	logr_read_data_t *data;
3688474SJose.Borrego@Sun.COM 
3698474SJose.Borrego@Sun.COM 	if ((hd = logr_hdlookup(mxa, id)) == NULL) {
3708474SJose.Borrego@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
3718474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
3728474SJose.Borrego@Sun.COM 	}
3738474SJose.Borrego@Sun.COM 
3748474SJose.Borrego@Sun.COM 	ctx = (logr_context_t *)hd->nh_data;
3758474SJose.Borrego@Sun.COM 	data = ctx->lc_cached_read_data;
3768474SJose.Borrego@Sun.COM 
3778474SJose.Borrego@Sun.COM 	param->oldest_rec = data->rd_log->li_idx - data->rd_tot_recnum + 1;
3788474SJose.Borrego@Sun.COM 
3798474SJose.Borrego@Sun.COM 	param->status = NT_STATUS_SUCCESS;
3808474SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
3818474SJose.Borrego@Sun.COM }
3828474SJose.Borrego@Sun.COM 
3838474SJose.Borrego@Sun.COM /*
3848474SJose.Borrego@Sun.COM  * logr_set_event_typeid
3858474SJose.Borrego@Sun.COM  *
3868474SJose.Borrego@Sun.COM  * Map the local system log priority to the event type and event ID
3878474SJose.Borrego@Sun.COM  * for Windows events.
3888474SJose.Borrego@Sun.COM  */
3898474SJose.Borrego@Sun.COM void
logr_set_event_typeid(int le_pri,WORD * etype,DWORD * eid)3908474SJose.Borrego@Sun.COM logr_set_event_typeid(int le_pri, WORD *etype, DWORD *eid)
3918474SJose.Borrego@Sun.COM {
3928474SJose.Borrego@Sun.COM 	switch (LOGR_PRI(le_pri)) {
3938474SJose.Borrego@Sun.COM 	case LOG_EMERG:
3948474SJose.Borrego@Sun.COM 	case LOG_ALERT:
3958474SJose.Borrego@Sun.COM 	case LOG_CRIT:
3968474SJose.Borrego@Sun.COM 	case LOG_ERR:
3978474SJose.Borrego@Sun.COM 		*eid   = EVENTID_SEVERITY_ERROR;
3988474SJose.Borrego@Sun.COM 		*etype = EVENTLOG_ERROR_TYPE;
3998474SJose.Borrego@Sun.COM 		break;
4008474SJose.Borrego@Sun.COM 	case LOG_WARNING:
4018474SJose.Borrego@Sun.COM 		*eid   = EVENTID_SEVERITY_WARNING;
4028474SJose.Borrego@Sun.COM 		*etype = EVENTLOG_WARNING_TYPE;
4038474SJose.Borrego@Sun.COM 		break;
4048474SJose.Borrego@Sun.COM 	case LOG_NOTICE:
4058474SJose.Borrego@Sun.COM 	case LOG_INFO:
4068474SJose.Borrego@Sun.COM 	case LOG_DEBUG:
4078474SJose.Borrego@Sun.COM 		*eid   = EVENTID_SEVERITY_INFO;
4088474SJose.Borrego@Sun.COM 		*etype = EVENTLOG_INFORMATION_TYPE;
4098474SJose.Borrego@Sun.COM 		break;
4108474SJose.Borrego@Sun.COM 	default:
4118474SJose.Borrego@Sun.COM 		*eid   = EVENTID_SEVERITY_SUCCESS;
4128474SJose.Borrego@Sun.COM 		*etype = EVENTLOG_SUCCESS;
4138474SJose.Borrego@Sun.COM 	}
4148474SJose.Borrego@Sun.COM }
4158474SJose.Borrego@Sun.COM 
4168474SJose.Borrego@Sun.COM /*
4178474SJose.Borrego@Sun.COM  * logr_get_entry
4188474SJose.Borrego@Sun.COM  *
4198474SJose.Borrego@Sun.COM  * Gets a log entry.
4208474SJose.Borrego@Sun.COM  */
4218474SJose.Borrego@Sun.COM static logr_entry_t *
logr_get_entry(logr_info_t * linfo,int entno)4228474SJose.Borrego@Sun.COM logr_get_entry(logr_info_t *linfo, int entno)
4238474SJose.Borrego@Sun.COM {
4248474SJose.Borrego@Sun.COM 	return (&linfo->li_entry[entno]);
4258474SJose.Borrego@Sun.COM }
4268474SJose.Borrego@Sun.COM 
4278474SJose.Borrego@Sun.COM /*
4288474SJose.Borrego@Sun.COM  * logr_set_logrecord
4298474SJose.Borrego@Sun.COM  *
4308474SJose.Borrego@Sun.COM  * Fill a Windows event record based on a local system log record.
4318474SJose.Borrego@Sun.COM  */
4328474SJose.Borrego@Sun.COM static void
logr_set_logrecord(char * src_name,logr_entry_t * le,DWORD recno,logr_record_t * rec)4338474SJose.Borrego@Sun.COM logr_set_logrecord(char *src_name, logr_entry_t *le,
4348474SJose.Borrego@Sun.COM     DWORD recno, logr_record_t *rec)
4358474SJose.Borrego@Sun.COM {
4368474SJose.Borrego@Sun.COM 	int srcname_len = 0, hostname_len = 0, len;
4378474SJose.Borrego@Sun.COM 	int str_offs, sh_len;
43810966SJordan.Brown@Sun.COM 	smb_wchar_t wcs_hostname[MAXHOSTNAMELEN];
43910966SJordan.Brown@Sun.COM 	smb_wchar_t wcs_srcname[SYS_NMLN * 2];
4408474SJose.Borrego@Sun.COM 
44110966SJordan.Brown@Sun.COM 	(void) smb_mbstowcs(wcs_srcname, src_name,
4428474SJose.Borrego@Sun.COM 	    strlen(src_name) + 1);
4438474SJose.Borrego@Sun.COM 	srcname_len = LOGR_WNSTRLEN(src_name);
4448474SJose.Borrego@Sun.COM 
4458474SJose.Borrego@Sun.COM 	/* Because, Solaris allows remote logging, need to get hostname here */
44610966SJordan.Brown@Sun.COM 	(void) smb_mbstowcs(wcs_hostname, le->le_hostname,
4478474SJose.Borrego@Sun.COM 	    strlen(le->le_hostname) + 1);
4488474SJose.Borrego@Sun.COM 	hostname_len = LOGR_WNSTRLEN(le->le_hostname);
4498474SJose.Borrego@Sun.COM 
4508474SJose.Borrego@Sun.COM 	sh_len = srcname_len + hostname_len;
4518474SJose.Borrego@Sun.COM 	str_offs = LOGR_MSG_DWORD_OFFSET * sizeof (DWORD) +
4528474SJose.Borrego@Sun.COM 	    LOGR_MSG_WORD_OFFSET * sizeof (WORD) + sh_len;
4538474SJose.Borrego@Sun.COM 
4548474SJose.Borrego@Sun.COM 	rec->Length1 = sizeof (logr_record_t);
4558474SJose.Borrego@Sun.COM 	rec->Reserved = LOGR_RECORD_SIGNATURE;
4568474SJose.Borrego@Sun.COM 	rec->RecordNumber = recno;
4578474SJose.Borrego@Sun.COM 	rec->TimeGenerated = le->le_timestamp.tv_sec;
4588474SJose.Borrego@Sun.COM 	rec->TimeWritten = le->le_timestamp.tv_sec;
4598474SJose.Borrego@Sun.COM 	logr_set_event_typeid(le->le_pri, &rec->EventType, &rec->EventID);
4608474SJose.Borrego@Sun.COM 	rec->NumStrings = 1;
4618474SJose.Borrego@Sun.COM 	rec->EventCategory = 0;
4628474SJose.Borrego@Sun.COM 	rec->ReservedFlags = 0;
4638474SJose.Borrego@Sun.COM 	rec->ClosingRecordNumber = 0;
4648474SJose.Borrego@Sun.COM 	rec->StringOffset = str_offs;
4658474SJose.Borrego@Sun.COM 	rec->UserSidLength = 0;
4668474SJose.Borrego@Sun.COM 	rec->UserSidOffset = 0;
4678474SJose.Borrego@Sun.COM 	rec->DataLength = 0;
4688474SJose.Borrego@Sun.COM 	rec->DataOffset = 0;
4698474SJose.Borrego@Sun.COM 
4708474SJose.Borrego@Sun.COM 	bzero(rec->info, LOGR_MAXENTRYLEN);
4718474SJose.Borrego@Sun.COM 	(void) memcpy(rec->info, wcs_srcname, srcname_len);
4728474SJose.Borrego@Sun.COM 	(void) memcpy(rec->info + srcname_len, wcs_hostname, hostname_len);
4738474SJose.Borrego@Sun.COM 
4748474SJose.Borrego@Sun.COM 	len = strlen(le->le_msg) + 1;
4758474SJose.Borrego@Sun.COM 	if (len > 0)
4768474SJose.Borrego@Sun.COM 		/*LINTED E_BAD_PTR_CAST_ALIGN*/
47710966SJordan.Brown@Sun.COM 		(void) smb_mbstowcs((smb_wchar_t *)(rec->info + sh_len),
4788474SJose.Borrego@Sun.COM 		    le->le_msg, len);
4798474SJose.Borrego@Sun.COM 
4808474SJose.Borrego@Sun.COM 	rec->Length2 = sizeof (logr_record_t);
4818474SJose.Borrego@Sun.COM }
4828474SJose.Borrego@Sun.COM 
4838474SJose.Borrego@Sun.COM /*
4848474SJose.Borrego@Sun.COM  * logr_s_EventLogRead
4858474SJose.Borrego@Sun.COM  *
4868474SJose.Borrego@Sun.COM  * Reads a whole number of entries from system log. The function can
4878474SJose.Borrego@Sun.COM  * read log entries in chronological or reverse chronological order.
4888474SJose.Borrego@Sun.COM  */
4898474SJose.Borrego@Sun.COM static int
logr_s_EventLogRead(void * arg,ndr_xa_t * mxa)4908474SJose.Borrego@Sun.COM logr_s_EventLogRead(void *arg, ndr_xa_t *mxa)
4918474SJose.Borrego@Sun.COM {
4928474SJose.Borrego@Sun.COM 	struct logr_EventLogRead *param = arg;
4938474SJose.Borrego@Sun.COM 	ndr_hdid_t *id = (ndr_hdid_t *)&param->handle;
4948474SJose.Borrego@Sun.COM 	ndr_handle_t *hd;
4958474SJose.Borrego@Sun.COM 	logr_read_data_t *rdata;
4968474SJose.Borrego@Sun.COM 	logr_entry_t *le;
4978474SJose.Borrego@Sun.COM 	DWORD ent_no, ent_num, ent_remain;
4988474SJose.Borrego@Sun.COM 	logr_record_t *rec;
4998474SJose.Borrego@Sun.COM 	BYTE *buf;
5008474SJose.Borrego@Sun.COM 	int dir, ent_per_req, iter;
5018474SJose.Borrego@Sun.COM 	logr_context_t *ctx;
5028474SJose.Borrego@Sun.COM 
5038474SJose.Borrego@Sun.COM 	if ((hd = logr_hdlookup(mxa, id)) == NULL) {
5048474SJose.Borrego@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
5058474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
5068474SJose.Borrego@Sun.COM 	}
5078474SJose.Borrego@Sun.COM 
5088474SJose.Borrego@Sun.COM 	ctx = (logr_context_t *)hd->nh_data;
5098474SJose.Borrego@Sun.COM 	rdata = ctx->lc_cached_read_data;
5108474SJose.Borrego@Sun.COM 	if (rdata == NULL) {
5118474SJose.Borrego@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
5128474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
5138474SJose.Borrego@Sun.COM 	}
5148474SJose.Borrego@Sun.COM 
5158474SJose.Borrego@Sun.COM 	dir = (param->read_flags & EVENTLOG_FORWARDS_READ) ?
5168474SJose.Borrego@Sun.COM 	    LOGR_FWD : LOGR_REW;
5178474SJose.Borrego@Sun.COM 
5188474SJose.Borrego@Sun.COM 	if (param->read_flags & EVENTLOG_SEEK_READ)
5198474SJose.Borrego@Sun.COM 		rdata->rd_last_sentrec = param->rec_offset;
5208474SJose.Borrego@Sun.COM 	else if (rdata->rd_first_read)
5218474SJose.Borrego@Sun.COM 		/*
5228474SJose.Borrego@Sun.COM 		 * set last record number which is read for
5238474SJose.Borrego@Sun.COM 		 * the first iteration of sequential read.
5248474SJose.Borrego@Sun.COM 		 */
5258474SJose.Borrego@Sun.COM 		rdata->rd_last_sentrec = (dir == LOGR_FWD)
5268474SJose.Borrego@Sun.COM 		    ? (rdata->rd_log->li_idx - rdata->rd_tot_recnum)
5278474SJose.Borrego@Sun.COM 		    : rdata->rd_log->li_idx;
5288474SJose.Borrego@Sun.COM 
5298474SJose.Borrego@Sun.COM 	ent_remain = (dir == LOGR_FWD)
5308474SJose.Borrego@Sun.COM 	    ? (rdata->rd_tot_recnum - rdata->rd_last_sentrec)
5318474SJose.Borrego@Sun.COM 	    : rdata->rd_last_sentrec;
5328474SJose.Borrego@Sun.COM 
5338474SJose.Borrego@Sun.COM 	/*
5348474SJose.Borrego@Sun.COM 	 * function should return as many whole log entries as
5358474SJose.Borrego@Sun.COM 	 * will fit in the buffer; it should not return partial
5368474SJose.Borrego@Sun.COM 	 * entries, even if there is room in the buffer.
5378474SJose.Borrego@Sun.COM 	 */
5388474SJose.Borrego@Sun.COM 	ent_per_req = param->nbytes_to_read / sizeof (logr_record_t);
5398474SJose.Borrego@Sun.COM 	if (ent_remain > ent_per_req)
5408474SJose.Borrego@Sun.COM 		ent_remain = ent_per_req;
5418474SJose.Borrego@Sun.COM 
5428474SJose.Borrego@Sun.COM 	if (ent_remain == 0) {
5438474SJose.Borrego@Sun.COM 		/*
5448474SJose.Borrego@Sun.COM 		 * Send this error to Windows client so that it
5458474SJose.Borrego@Sun.COM 		 * can figure out that there is no more record
5468474SJose.Borrego@Sun.COM 		 * to read.
5478474SJose.Borrego@Sun.COM 		 */
5488474SJose.Borrego@Sun.COM 		param->buf = NDR_STRDUP(mxa, "");
5498474SJose.Borrego@Sun.COM 		param->sent_size = 0;
5508474SJose.Borrego@Sun.COM 		param->status = NT_SC_ERROR(NT_STATUS_END_OF_FILE);
5518474SJose.Borrego@Sun.COM 		return (NDR_DRC_OK);
5528474SJose.Borrego@Sun.COM 	}
5538474SJose.Borrego@Sun.COM 
5548474SJose.Borrego@Sun.COM 	param->buf = NDR_MALLOC(mxa, param->nbytes_to_read);
5558474SJose.Borrego@Sun.COM 	buf = (BYTE *)param->buf;
5568474SJose.Borrego@Sun.COM 
5578474SJose.Borrego@Sun.COM 	for (ent_num = 0, ent_no = rdata->rd_last_sentrec;
5588474SJose.Borrego@Sun.COM 	    ent_num < ent_remain; ent_num++, ent_no += dir) {
5598474SJose.Borrego@Sun.COM 
5608474SJose.Borrego@Sun.COM 		iter = ent_no & LOGR_NMSGMASK;
5618474SJose.Borrego@Sun.COM 		if (dir == LOGR_REW)
5628474SJose.Borrego@Sun.COM 			iter = (ent_no - 1) & LOGR_NMSGMASK;
5638474SJose.Borrego@Sun.COM 
5648474SJose.Borrego@Sun.COM 		le = logr_get_entry(rdata->rd_log, iter);
5658474SJose.Borrego@Sun.COM 
5668474SJose.Borrego@Sun.COM 		/*LINTED E_BAD_PTR_CAST_ALIGN*/
5678474SJose.Borrego@Sun.COM 		rec = (logr_record_t *)buf;
5688474SJose.Borrego@Sun.COM 		logr_set_logrecord(ctx->lc_source_name, le, ent_no, rec);
5698474SJose.Borrego@Sun.COM 		buf += sizeof (logr_record_t);
5708474SJose.Borrego@Sun.COM 	}
5718474SJose.Borrego@Sun.COM 
5728474SJose.Borrego@Sun.COM 	rdata->rd_last_sentrec = ent_no;
5738474SJose.Borrego@Sun.COM 	rdata->rd_first_read = 0;
5748474SJose.Borrego@Sun.COM 
5758474SJose.Borrego@Sun.COM 	param->sent_size = sizeof (logr_record_t) * ent_remain;
5768474SJose.Borrego@Sun.COM 	param->status = NT_STATUS_SUCCESS;
5778474SJose.Borrego@Sun.COM 
5788474SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
5798474SJose.Borrego@Sun.COM }
580