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