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 *)¶m->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(¶m->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(¶m->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(¶m->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(¶m->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, ¶m->handle, sizeof (logr_handle_t));
3178670SJose.Borrego@Sun.COM param->status = NT_STATUS_SUCCESS;
3188474SJose.Borrego@Sun.COM } else {
3198474SJose.Borrego@Sun.COM bzero(¶m->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 *)¶m->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 *)¶m->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 *)¶m->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