1*8474SJose.Borrego@Sun.COM /* 2*8474SJose.Borrego@Sun.COM * CDDL HEADER START 3*8474SJose.Borrego@Sun.COM * 4*8474SJose.Borrego@Sun.COM * The contents of this file are subject to the terms of the 5*8474SJose.Borrego@Sun.COM * Common Development and Distribution License (the "License"). 6*8474SJose.Borrego@Sun.COM * You may not use this file except in compliance with the License. 7*8474SJose.Borrego@Sun.COM * 8*8474SJose.Borrego@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*8474SJose.Borrego@Sun.COM * or http://www.opensolaris.org/os/licensing. 10*8474SJose.Borrego@Sun.COM * See the License for the specific language governing permissions 11*8474SJose.Borrego@Sun.COM * and limitations under the License. 12*8474SJose.Borrego@Sun.COM * 13*8474SJose.Borrego@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each 14*8474SJose.Borrego@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*8474SJose.Borrego@Sun.COM * If applicable, add the following below this CDDL HEADER, with the 16*8474SJose.Borrego@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying 17*8474SJose.Borrego@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner] 18*8474SJose.Borrego@Sun.COM * 19*8474SJose.Borrego@Sun.COM * CDDL HEADER END 20*8474SJose.Borrego@Sun.COM */ 21*8474SJose.Borrego@Sun.COM /* 22*8474SJose.Borrego@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23*8474SJose.Borrego@Sun.COM * Use is subject to license terms. 24*8474SJose.Borrego@Sun.COM */ 25*8474SJose.Borrego@Sun.COM 26*8474SJose.Borrego@Sun.COM /* 27*8474SJose.Borrego@Sun.COM * Event Log Service RPC (LOGR) interface definition. 28*8474SJose.Borrego@Sun.COM */ 29*8474SJose.Borrego@Sun.COM #include <sys/utsname.h> 30*8474SJose.Borrego@Sun.COM #include <unistd.h> 31*8474SJose.Borrego@Sun.COM #include <strings.h> 32*8474SJose.Borrego@Sun.COM 33*8474SJose.Borrego@Sun.COM #include <smbsrv/libsmb.h> 34*8474SJose.Borrego@Sun.COM #include <smbsrv/libmlrpc.h> 35*8474SJose.Borrego@Sun.COM #include <smbsrv/ntstatus.h> 36*8474SJose.Borrego@Sun.COM #include <smbsrv/nmpipes.h> 37*8474SJose.Borrego@Sun.COM #include <smbsrv/libmlsvc.h> 38*8474SJose.Borrego@Sun.COM #include "eventlog.h" 39*8474SJose.Borrego@Sun.COM #include <smbsrv/nterror.h> 40*8474SJose.Borrego@Sun.COM 41*8474SJose.Borrego@Sun.COM #define LOGR_FWD +1 42*8474SJose.Borrego@Sun.COM #define LOGR_REW -1 43*8474SJose.Borrego@Sun.COM #define LOGR_RECORD_SIGNATURE 0x654C664C 44*8474SJose.Borrego@Sun.COM 45*8474SJose.Borrego@Sun.COM #define LOGR_PRI(p) ((p) & LOG_PRIMASK) 46*8474SJose.Borrego@Sun.COM #define LOGR_WNSTRLEN(S) ((strlen((S)) + 1) * sizeof (mts_wchar_t)) 47*8474SJose.Borrego@Sun.COM 48*8474SJose.Borrego@Sun.COM #define LOGR_MSG_DWORD_OFFSET 12 49*8474SJose.Borrego@Sun.COM #define LOGR_MSG_WORD_OFFSET 4 50*8474SJose.Borrego@Sun.COM 51*8474SJose.Borrego@Sun.COM /* 52*8474SJose.Borrego@Sun.COM * READ flags for EventLogRead 53*8474SJose.Borrego@Sun.COM * 54*8474SJose.Borrego@Sun.COM * EVENTLOG_SEEK_READ 55*8474SJose.Borrego@Sun.COM * The read operation proceeds from the record specified by the 56*8474SJose.Borrego@Sun.COM * dwRecordOffset parameter. This flag cannot be used with 57*8474SJose.Borrego@Sun.COM * EVENTLOG_SEQUENTIAL_READ. 58*8474SJose.Borrego@Sun.COM * 59*8474SJose.Borrego@Sun.COM * EVENTLOG_SEQUENTIAL_READ 60*8474SJose.Borrego@Sun.COM * The read operation proceeds sequentially from the last call to the 61*8474SJose.Borrego@Sun.COM * ReadEventLog function using this handle. This flag cannot be used 62*8474SJose.Borrego@Sun.COM * with EVENTLOG_SEEK_READ. 63*8474SJose.Borrego@Sun.COM * 64*8474SJose.Borrego@Sun.COM * If the buffer is large enough, more than one record can be read at 65*8474SJose.Borrego@Sun.COM * the specified seek position; you must specify one of the following 66*8474SJose.Borrego@Sun.COM * flags to indicate the direction for successive read operations. 67*8474SJose.Borrego@Sun.COM * 68*8474SJose.Borrego@Sun.COM * EVENTLOG_FORWARDS_READ 69*8474SJose.Borrego@Sun.COM * The log is read in chronological order. This flag cannot be used 70*8474SJose.Borrego@Sun.COM * with EVENTLOG_BACKWARDS_READ. 71*8474SJose.Borrego@Sun.COM * 72*8474SJose.Borrego@Sun.COM * EVENTLOG_BACKWARDS_READ 73*8474SJose.Borrego@Sun.COM * The log is read in reverse chronological order. This flag cannot be 74*8474SJose.Borrego@Sun.COM * used with EVENTLOG_FORWARDS_READ. 75*8474SJose.Borrego@Sun.COM */ 76*8474SJose.Borrego@Sun.COM #define EVENTLOG_SEQUENTIAL_READ 0x0001 77*8474SJose.Borrego@Sun.COM #define EVENTLOG_SEEK_READ 0x0002 78*8474SJose.Borrego@Sun.COM #define EVENTLOG_FORWARDS_READ 0x0004 79*8474SJose.Borrego@Sun.COM #define EVENTLOG_BACKWARDS_READ 0x0008 80*8474SJose.Borrego@Sun.COM 81*8474SJose.Borrego@Sun.COM /* 82*8474SJose.Borrego@Sun.COM * The types of events that can be logged. 83*8474SJose.Borrego@Sun.COM */ 84*8474SJose.Borrego@Sun.COM #define EVENTLOG_SUCCESS 0x0000 85*8474SJose.Borrego@Sun.COM #define EVENTLOG_ERROR_TYPE 0x0001 86*8474SJose.Borrego@Sun.COM #define EVENTLOG_WARNING_TYPE 0x0002 87*8474SJose.Borrego@Sun.COM #define EVENTLOG_INFORMATION_TYPE 0x0004 88*8474SJose.Borrego@Sun.COM #define EVENTLOG_AUDIT_SUCCESS 0x0008 89*8474SJose.Borrego@Sun.COM #define EVENTLOG_AUDIT_FAILURE 0x0010 90*8474SJose.Borrego@Sun.COM 91*8474SJose.Borrego@Sun.COM /* 92*8474SJose.Borrego@Sun.COM * Event Identifiers 93*8474SJose.Borrego@Sun.COM * 94*8474SJose.Borrego@Sun.COM * Event identifiers uniquely identify a particular event. Each event 95*8474SJose.Borrego@Sun.COM * source can define its own numbered events and the description strings 96*8474SJose.Borrego@Sun.COM * to which they are mapped. Event viewers can present these strings to 97*8474SJose.Borrego@Sun.COM * the user. They should help the user understand what went wrong and 98*8474SJose.Borrego@Sun.COM * suggest what actions to take. Direct the description at users solving 99*8474SJose.Borrego@Sun.COM * their own problems, not at administrators or support technicians. 100*8474SJose.Borrego@Sun.COM * Make the description clear and concise and avoid culture-specific 101*8474SJose.Borrego@Sun.COM * phrases. 102*8474SJose.Borrego@Sun.COM * 103*8474SJose.Borrego@Sun.COM * The following diagram illustrates the format of an event identifier. 104*8474SJose.Borrego@Sun.COM * 105*8474SJose.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 106*8474SJose.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 107*8474SJose.Borrego@Sun.COM * +---+-+-+-----------------------+-------------------------------+ 108*8474SJose.Borrego@Sun.COM * |Sev|C|R| Facility | Code | 109*8474SJose.Borrego@Sun.COM * +---+-+-+-----------------------+-------------------------------+ 110*8474SJose.Borrego@Sun.COM * 111*8474SJose.Borrego@Sun.COM * Sev 112*8474SJose.Borrego@Sun.COM * Indicates the severity. This is one of the following values: 113*8474SJose.Borrego@Sun.COM * 00 - Success 114*8474SJose.Borrego@Sun.COM * 01 - Informational 115*8474SJose.Borrego@Sun.COM * 10 - Warning 116*8474SJose.Borrego@Sun.COM * 11 - Error 117*8474SJose.Borrego@Sun.COM * 118*8474SJose.Borrego@Sun.COM * C 119*8474SJose.Borrego@Sun.COM * Indicates a customer code (1) or a system code (0). 120*8474SJose.Borrego@Sun.COM * R 121*8474SJose.Borrego@Sun.COM * Reserved bit. 122*8474SJose.Borrego@Sun.COM * Facility 123*8474SJose.Borrego@Sun.COM * Facility code. 124*8474SJose.Borrego@Sun.COM * Code 125*8474SJose.Borrego@Sun.COM * Status code for the facility. 126*8474SJose.Borrego@Sun.COM */ 127*8474SJose.Borrego@Sun.COM #define EVENTID_SEVERITY_SUCCESS 0x00000000 128*8474SJose.Borrego@Sun.COM #define EVENTID_SEVERITY_INFO 0x40000000 129*8474SJose.Borrego@Sun.COM #define EVENTID_SEVERITY_WARNING 0x80000000 130*8474SJose.Borrego@Sun.COM #define EVENTID_SEVERITY_ERROR 0xC0000000 131*8474SJose.Borrego@Sun.COM 132*8474SJose.Borrego@Sun.COM #define EVENTID_SYSTEM_CODE 0x00000000 133*8474SJose.Borrego@Sun.COM #define EVENTID_CUSTOMER_CODE 0x20000000 134*8474SJose.Borrego@Sun.COM 135*8474SJose.Borrego@Sun.COM static int logr_s_EventLogClose(void *, ndr_xa_t *); 136*8474SJose.Borrego@Sun.COM static int logr_s_EventLogQueryCount(void *, ndr_xa_t *); 137*8474SJose.Borrego@Sun.COM static int logr_s_EventLogGetOldestRec(void *, ndr_xa_t *); 138*8474SJose.Borrego@Sun.COM static int logr_s_EventLogOpen(void *, ndr_xa_t *); 139*8474SJose.Borrego@Sun.COM static int logr_s_EventLogRead(void *, ndr_xa_t *); 140*8474SJose.Borrego@Sun.COM 141*8474SJose.Borrego@Sun.COM static ndr_stub_table_t logr_stub_table[] = { 142*8474SJose.Borrego@Sun.COM { logr_s_EventLogClose, LOGR_OPNUM_EventLogClose }, 143*8474SJose.Borrego@Sun.COM { logr_s_EventLogQueryCount, LOGR_OPNUM_EventLogQueryCount }, 144*8474SJose.Borrego@Sun.COM { logr_s_EventLogGetOldestRec, LOGR_OPNUM_EventLogGetOldestRec }, 145*8474SJose.Borrego@Sun.COM { logr_s_EventLogOpen, LOGR_OPNUM_EventLogOpen }, 146*8474SJose.Borrego@Sun.COM { logr_s_EventLogRead, LOGR_OPNUM_EventLogRead }, 147*8474SJose.Borrego@Sun.COM {0} 148*8474SJose.Borrego@Sun.COM }; 149*8474SJose.Borrego@Sun.COM 150*8474SJose.Borrego@Sun.COM static ndr_service_t logr_service = { 151*8474SJose.Borrego@Sun.COM "LOGR", /* name */ 152*8474SJose.Borrego@Sun.COM "Event Log Service", /* desc */ 153*8474SJose.Borrego@Sun.COM "\\eventlog", /* endpoint */ 154*8474SJose.Borrego@Sun.COM PIPE_NTSVCS, /* sec_addr_port */ 155*8474SJose.Borrego@Sun.COM "82273fdc-e32a-18c3-3f78-827929dc23ea", 0, /* abstract */ 156*8474SJose.Borrego@Sun.COM NDR_TRANSFER_SYNTAX_UUID, 2, /* transfer */ 157*8474SJose.Borrego@Sun.COM 0, /* no bind_instance_size */ 158*8474SJose.Borrego@Sun.COM 0, /* no bind_req() */ 159*8474SJose.Borrego@Sun.COM 0, /* no unbind_and_close() */ 160*8474SJose.Borrego@Sun.COM 0, /* use generic_call_stub() */ 161*8474SJose.Borrego@Sun.COM &TYPEINFO(logr_interface), /* interface ti */ 162*8474SJose.Borrego@Sun.COM logr_stub_table /* stub_table */ 163*8474SJose.Borrego@Sun.COM }; 164*8474SJose.Borrego@Sun.COM 165*8474SJose.Borrego@Sun.COM static int logr_get_snapshot(logr_context_t *); 166*8474SJose.Borrego@Sun.COM 167*8474SJose.Borrego@Sun.COM /* 168*8474SJose.Borrego@Sun.COM * logr_initialize 169*8474SJose.Borrego@Sun.COM * 170*8474SJose.Borrego@Sun.COM * This function registers the LOGR RPC interface with the RPC runtime 171*8474SJose.Borrego@Sun.COM * library. It must be called in order to use either the client side 172*8474SJose.Borrego@Sun.COM * or the server side functions. 173*8474SJose.Borrego@Sun.COM */ 174*8474SJose.Borrego@Sun.COM void 175*8474SJose.Borrego@Sun.COM logr_initialize(void) 176*8474SJose.Borrego@Sun.COM { 177*8474SJose.Borrego@Sun.COM (void) ndr_svc_register(&logr_service); 178*8474SJose.Borrego@Sun.COM } 179*8474SJose.Borrego@Sun.COM 180*8474SJose.Borrego@Sun.COM /* 181*8474SJose.Borrego@Sun.COM * logr_hdlookup 182*8474SJose.Borrego@Sun.COM * 183*8474SJose.Borrego@Sun.COM * Handle lookup wrapper to validate the local service and/or manager context. 184*8474SJose.Borrego@Sun.COM */ 185*8474SJose.Borrego@Sun.COM static ndr_handle_t * 186*8474SJose.Borrego@Sun.COM logr_hdlookup(ndr_xa_t *mxa, ndr_hdid_t *id) 187*8474SJose.Borrego@Sun.COM { 188*8474SJose.Borrego@Sun.COM ndr_handle_t *hd; 189*8474SJose.Borrego@Sun.COM logr_context_t *ctx; 190*8474SJose.Borrego@Sun.COM 191*8474SJose.Borrego@Sun.COM if ((hd = ndr_hdlookup(mxa, id)) == NULL) 192*8474SJose.Borrego@Sun.COM return (NULL); 193*8474SJose.Borrego@Sun.COM 194*8474SJose.Borrego@Sun.COM if ((ctx = (logr_context_t *)hd->nh_data) == NULL) 195*8474SJose.Borrego@Sun.COM return (NULL); 196*8474SJose.Borrego@Sun.COM 197*8474SJose.Borrego@Sun.COM if (ctx->lc_source_name == NULL) 198*8474SJose.Borrego@Sun.COM return (NULL); 199*8474SJose.Borrego@Sun.COM 200*8474SJose.Borrego@Sun.COM return (hd); 201*8474SJose.Borrego@Sun.COM } 202*8474SJose.Borrego@Sun.COM 203*8474SJose.Borrego@Sun.COM /* 204*8474SJose.Borrego@Sun.COM * logr_context_data_free 205*8474SJose.Borrego@Sun.COM * 206*8474SJose.Borrego@Sun.COM * Callback to free the context data associated with local service 207*8474SJose.Borrego@Sun.COM * and/or manager context. 208*8474SJose.Borrego@Sun.COM */ 209*8474SJose.Borrego@Sun.COM static void 210*8474SJose.Borrego@Sun.COM logr_context_data_free(void *ctxp) 211*8474SJose.Borrego@Sun.COM { 212*8474SJose.Borrego@Sun.COM logr_context_t *ctx = (logr_context_t *)ctxp; 213*8474SJose.Borrego@Sun.COM 214*8474SJose.Borrego@Sun.COM if (ctx == NULL) 215*8474SJose.Borrego@Sun.COM return; 216*8474SJose.Borrego@Sun.COM 217*8474SJose.Borrego@Sun.COM free(ctx->lc_source_name); 218*8474SJose.Borrego@Sun.COM free(ctx->lc_cached_read_data->rd_log); 219*8474SJose.Borrego@Sun.COM free(ctx->lc_cached_read_data); 220*8474SJose.Borrego@Sun.COM free(ctx); 221*8474SJose.Borrego@Sun.COM ctx = NULL; 222*8474SJose.Borrego@Sun.COM } 223*8474SJose.Borrego@Sun.COM 224*8474SJose.Borrego@Sun.COM /* 225*8474SJose.Borrego@Sun.COM * logr_mgr_hdalloc 226*8474SJose.Borrego@Sun.COM * 227*8474SJose.Borrego@Sun.COM * Handle allocation wrapper to setup the local manager context. 228*8474SJose.Borrego@Sun.COM */ 229*8474SJose.Borrego@Sun.COM static ndr_hdid_t * 230*8474SJose.Borrego@Sun.COM logr_hdalloc(ndr_xa_t *mxa) 231*8474SJose.Borrego@Sun.COM { 232*8474SJose.Borrego@Sun.COM logr_context_t *ctx; 233*8474SJose.Borrego@Sun.COM 234*8474SJose.Borrego@Sun.COM if ((ctx = malloc(sizeof (logr_context_t))) == NULL) 235*8474SJose.Borrego@Sun.COM return (NULL); 236*8474SJose.Borrego@Sun.COM bzero(ctx, sizeof (logr_context_t)); 237*8474SJose.Borrego@Sun.COM 238*8474SJose.Borrego@Sun.COM ctx->lc_source_name = strdup("eventlog"); 239*8474SJose.Borrego@Sun.COM if ((ctx->lc_source_name != NULL) && (logr_get_snapshot(ctx) < 0)) { 240*8474SJose.Borrego@Sun.COM free(ctx->lc_source_name); 241*8474SJose.Borrego@Sun.COM free(ctx); 242*8474SJose.Borrego@Sun.COM return (NULL); 243*8474SJose.Borrego@Sun.COM } 244*8474SJose.Borrego@Sun.COM 245*8474SJose.Borrego@Sun.COM return (ndr_hdalloc(mxa, ctx)); 246*8474SJose.Borrego@Sun.COM } 247*8474SJose.Borrego@Sun.COM 248*8474SJose.Borrego@Sun.COM /* 249*8474SJose.Borrego@Sun.COM * logr_s_EventLogClose 250*8474SJose.Borrego@Sun.COM * 251*8474SJose.Borrego@Sun.COM * This is a request to close the LOGR interface specified by handle. 252*8474SJose.Borrego@Sun.COM * Free the handle and associated resources, and zero out the result 253*8474SJose.Borrego@Sun.COM * handle for the client. 254*8474SJose.Borrego@Sun.COM */ 255*8474SJose.Borrego@Sun.COM static int 256*8474SJose.Borrego@Sun.COM logr_s_EventLogClose(void *arg, ndr_xa_t *mxa) 257*8474SJose.Borrego@Sun.COM { 258*8474SJose.Borrego@Sun.COM struct logr_EventLogClose *param = arg; 259*8474SJose.Borrego@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 260*8474SJose.Borrego@Sun.COM ndr_handle_t *hd; 261*8474SJose.Borrego@Sun.COM 262*8474SJose.Borrego@Sun.COM if ((hd = ndr_hdlookup(mxa, id)) == NULL) { 263*8474SJose.Borrego@Sun.COM bzero(¶m->result_handle, sizeof (logr_handle_t)); 264*8474SJose.Borrego@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 265*8474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 266*8474SJose.Borrego@Sun.COM } 267*8474SJose.Borrego@Sun.COM logr_context_data_free(hd->nh_data); 268*8474SJose.Borrego@Sun.COM ndr_hdfree(mxa, id); 269*8474SJose.Borrego@Sun.COM 270*8474SJose.Borrego@Sun.COM bzero(¶m->result_handle, sizeof (logr_handle_t)); 271*8474SJose.Borrego@Sun.COM param->status = NT_STATUS_SUCCESS; 272*8474SJose.Borrego@Sun.COM 273*8474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 274*8474SJose.Borrego@Sun.COM } 275*8474SJose.Borrego@Sun.COM 276*8474SJose.Borrego@Sun.COM /* 277*8474SJose.Borrego@Sun.COM * logr_s_EventLogOpen 278*8474SJose.Borrego@Sun.COM * 279*8474SJose.Borrego@Sun.COM * Open the event log. Not supported yet. 280*8474SJose.Borrego@Sun.COM */ 281*8474SJose.Borrego@Sun.COM /*ARGSUSED*/ 282*8474SJose.Borrego@Sun.COM static int 283*8474SJose.Borrego@Sun.COM logr_s_EventLogOpen(void *arg, ndr_xa_t *mxa) 284*8474SJose.Borrego@Sun.COM { 285*8474SJose.Borrego@Sun.COM struct logr_EventLogOpen *param = arg; 286*8474SJose.Borrego@Sun.COM ndr_hdid_t *id = NULL; 287*8474SJose.Borrego@Sun.COM ndr_handle_t *hd; 288*8474SJose.Borrego@Sun.COM 289*8474SJose.Borrego@Sun.COM id = logr_hdalloc(mxa); 290*8474SJose.Borrego@Sun.COM if (id && ((hd = logr_hdlookup(mxa, id)) != NULL)) { 291*8474SJose.Borrego@Sun.COM hd->nh_data_free = logr_context_data_free; 292*8474SJose.Borrego@Sun.COM bcopy(id, ¶m->handle, sizeof (logr_handle_t)); 293*8474SJose.Borrego@Sun.COM param->status = ERROR_SUCCESS; 294*8474SJose.Borrego@Sun.COM } else { 295*8474SJose.Borrego@Sun.COM bzero(¶m->handle, sizeof (logr_handle_t)); 296*8474SJose.Borrego@Sun.COM param->status = ERROR_ACCESS_DENIED; 297*8474SJose.Borrego@Sun.COM } 298*8474SJose.Borrego@Sun.COM 299*8474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 300*8474SJose.Borrego@Sun.COM } 301*8474SJose.Borrego@Sun.COM 302*8474SJose.Borrego@Sun.COM /* 303*8474SJose.Borrego@Sun.COM * logr_get_snapshot 304*8474SJose.Borrego@Sun.COM * 305*8474SJose.Borrego@Sun.COM * Allocate memory and make a copy, as a snapshot, from system log. 306*8474SJose.Borrego@Sun.COM */ 307*8474SJose.Borrego@Sun.COM static int 308*8474SJose.Borrego@Sun.COM logr_get_snapshot(logr_context_t *ctx) 309*8474SJose.Borrego@Sun.COM { 310*8474SJose.Borrego@Sun.COM logr_read_data_t *data = NULL; 311*8474SJose.Borrego@Sun.COM 312*8474SJose.Borrego@Sun.COM ctx->lc_cached_read_data = malloc(sizeof (logr_read_data_t)); 313*8474SJose.Borrego@Sun.COM if (ctx->lc_cached_read_data != NULL) { 314*8474SJose.Borrego@Sun.COM data = ctx->lc_cached_read_data; 315*8474SJose.Borrego@Sun.COM 316*8474SJose.Borrego@Sun.COM data->rd_log = (logr_info_t *)malloc(sizeof (logr_info_t)); 317*8474SJose.Borrego@Sun.COM if (data->rd_log == NULL) { 318*8474SJose.Borrego@Sun.COM free(data); 319*8474SJose.Borrego@Sun.COM return (-1); 320*8474SJose.Borrego@Sun.COM } 321*8474SJose.Borrego@Sun.COM bzero(data->rd_log, sizeof (logr_info_t)); 322*8474SJose.Borrego@Sun.COM 323*8474SJose.Borrego@Sun.COM data->rd_tot_recnum = logr_syslog_snapshot(data->rd_log); 324*8474SJose.Borrego@Sun.COM if (data->rd_tot_recnum < 0) { 325*8474SJose.Borrego@Sun.COM free(data->rd_log); 326*8474SJose.Borrego@Sun.COM free(data); 327*8474SJose.Borrego@Sun.COM return (-1); 328*8474SJose.Borrego@Sun.COM } 329*8474SJose.Borrego@Sun.COM 330*8474SJose.Borrego@Sun.COM data->rd_first_read = 1; 331*8474SJose.Borrego@Sun.COM 332*8474SJose.Borrego@Sun.COM return (0); 333*8474SJose.Borrego@Sun.COM } 334*8474SJose.Borrego@Sun.COM 335*8474SJose.Borrego@Sun.COM return (-1); 336*8474SJose.Borrego@Sun.COM } 337*8474SJose.Borrego@Sun.COM 338*8474SJose.Borrego@Sun.COM /* 339*8474SJose.Borrego@Sun.COM * logr_s_EventLogQueryCount 340*8474SJose.Borrego@Sun.COM * 341*8474SJose.Borrego@Sun.COM * take a snapshot from system log, assign it to the given handle. 342*8474SJose.Borrego@Sun.COM * return number of log entries in the snapshot as result of RPC 343*8474SJose.Borrego@Sun.COM * call. 344*8474SJose.Borrego@Sun.COM */ 345*8474SJose.Borrego@Sun.COM static int 346*8474SJose.Borrego@Sun.COM logr_s_EventLogQueryCount(void *arg, ndr_xa_t *mxa) 347*8474SJose.Borrego@Sun.COM { 348*8474SJose.Borrego@Sun.COM struct logr_EventLogQueryCount *param = arg; 349*8474SJose.Borrego@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 350*8474SJose.Borrego@Sun.COM ndr_handle_t *hd; 351*8474SJose.Borrego@Sun.COM logr_context_t *ctx; 352*8474SJose.Borrego@Sun.COM logr_read_data_t *data; 353*8474SJose.Borrego@Sun.COM 354*8474SJose.Borrego@Sun.COM if ((hd = logr_hdlookup(mxa, id)) == NULL) { 355*8474SJose.Borrego@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 356*8474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 357*8474SJose.Borrego@Sun.COM } 358*8474SJose.Borrego@Sun.COM 359*8474SJose.Borrego@Sun.COM ctx = (logr_context_t *)hd->nh_data; 360*8474SJose.Borrego@Sun.COM data = ctx->lc_cached_read_data; 361*8474SJose.Borrego@Sun.COM 362*8474SJose.Borrego@Sun.COM param->rec_num = data->rd_tot_recnum; 363*8474SJose.Borrego@Sun.COM param->status = NT_STATUS_SUCCESS; 364*8474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 365*8474SJose.Borrego@Sun.COM } 366*8474SJose.Borrego@Sun.COM 367*8474SJose.Borrego@Sun.COM /* 368*8474SJose.Borrego@Sun.COM * logr_s_EventLogGetOldestRec 369*8474SJose.Borrego@Sun.COM * 370*8474SJose.Borrego@Sun.COM * Return oldest record number in the snapshot as result of RPC call. 371*8474SJose.Borrego@Sun.COM */ 372*8474SJose.Borrego@Sun.COM static int 373*8474SJose.Borrego@Sun.COM logr_s_EventLogGetOldestRec(void *arg, ndr_xa_t *mxa) 374*8474SJose.Borrego@Sun.COM { 375*8474SJose.Borrego@Sun.COM struct logr_EventLogGetOldestRec *param = arg; 376*8474SJose.Borrego@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 377*8474SJose.Borrego@Sun.COM ndr_handle_t *hd; 378*8474SJose.Borrego@Sun.COM logr_context_t *ctx; 379*8474SJose.Borrego@Sun.COM logr_read_data_t *data; 380*8474SJose.Borrego@Sun.COM 381*8474SJose.Borrego@Sun.COM if ((hd = logr_hdlookup(mxa, id)) == NULL) { 382*8474SJose.Borrego@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 383*8474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 384*8474SJose.Borrego@Sun.COM } 385*8474SJose.Borrego@Sun.COM 386*8474SJose.Borrego@Sun.COM ctx = (logr_context_t *)hd->nh_data; 387*8474SJose.Borrego@Sun.COM data = ctx->lc_cached_read_data; 388*8474SJose.Borrego@Sun.COM 389*8474SJose.Borrego@Sun.COM param->oldest_rec = data->rd_log->li_idx - data->rd_tot_recnum + 1; 390*8474SJose.Borrego@Sun.COM 391*8474SJose.Borrego@Sun.COM param->status = NT_STATUS_SUCCESS; 392*8474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 393*8474SJose.Borrego@Sun.COM } 394*8474SJose.Borrego@Sun.COM 395*8474SJose.Borrego@Sun.COM /* 396*8474SJose.Borrego@Sun.COM * logr_set_event_typeid 397*8474SJose.Borrego@Sun.COM * 398*8474SJose.Borrego@Sun.COM * Map the local system log priority to the event type and event ID 399*8474SJose.Borrego@Sun.COM * for Windows events. 400*8474SJose.Borrego@Sun.COM */ 401*8474SJose.Borrego@Sun.COM void 402*8474SJose.Borrego@Sun.COM logr_set_event_typeid(int le_pri, WORD *etype, DWORD *eid) 403*8474SJose.Borrego@Sun.COM { 404*8474SJose.Borrego@Sun.COM switch (LOGR_PRI(le_pri)) { 405*8474SJose.Borrego@Sun.COM case LOG_EMERG: 406*8474SJose.Borrego@Sun.COM case LOG_ALERT: 407*8474SJose.Borrego@Sun.COM case LOG_CRIT: 408*8474SJose.Borrego@Sun.COM case LOG_ERR: 409*8474SJose.Borrego@Sun.COM *eid = EVENTID_SEVERITY_ERROR; 410*8474SJose.Borrego@Sun.COM *etype = EVENTLOG_ERROR_TYPE; 411*8474SJose.Borrego@Sun.COM break; 412*8474SJose.Borrego@Sun.COM case LOG_WARNING: 413*8474SJose.Borrego@Sun.COM *eid = EVENTID_SEVERITY_WARNING; 414*8474SJose.Borrego@Sun.COM *etype = EVENTLOG_WARNING_TYPE; 415*8474SJose.Borrego@Sun.COM break; 416*8474SJose.Borrego@Sun.COM case LOG_NOTICE: 417*8474SJose.Borrego@Sun.COM case LOG_INFO: 418*8474SJose.Borrego@Sun.COM case LOG_DEBUG: 419*8474SJose.Borrego@Sun.COM *eid = EVENTID_SEVERITY_INFO; 420*8474SJose.Borrego@Sun.COM *etype = EVENTLOG_INFORMATION_TYPE; 421*8474SJose.Borrego@Sun.COM break; 422*8474SJose.Borrego@Sun.COM default: 423*8474SJose.Borrego@Sun.COM *eid = EVENTID_SEVERITY_SUCCESS; 424*8474SJose.Borrego@Sun.COM *etype = EVENTLOG_SUCCESS; 425*8474SJose.Borrego@Sun.COM } 426*8474SJose.Borrego@Sun.COM } 427*8474SJose.Borrego@Sun.COM 428*8474SJose.Borrego@Sun.COM /* 429*8474SJose.Borrego@Sun.COM * logr_get_entry 430*8474SJose.Borrego@Sun.COM * 431*8474SJose.Borrego@Sun.COM * Gets a log entry. 432*8474SJose.Borrego@Sun.COM */ 433*8474SJose.Borrego@Sun.COM static logr_entry_t * 434*8474SJose.Borrego@Sun.COM logr_get_entry(logr_info_t *linfo, int entno) 435*8474SJose.Borrego@Sun.COM { 436*8474SJose.Borrego@Sun.COM return (&linfo->li_entry[entno]); 437*8474SJose.Borrego@Sun.COM } 438*8474SJose.Borrego@Sun.COM 439*8474SJose.Borrego@Sun.COM /* 440*8474SJose.Borrego@Sun.COM * logr_set_logrecord 441*8474SJose.Borrego@Sun.COM * 442*8474SJose.Borrego@Sun.COM * Fill a Windows event record based on a local system log record. 443*8474SJose.Borrego@Sun.COM */ 444*8474SJose.Borrego@Sun.COM static void 445*8474SJose.Borrego@Sun.COM logr_set_logrecord(char *src_name, logr_entry_t *le, 446*8474SJose.Borrego@Sun.COM DWORD recno, logr_record_t *rec) 447*8474SJose.Borrego@Sun.COM { 448*8474SJose.Borrego@Sun.COM int srcname_len = 0, hostname_len = 0, len; 449*8474SJose.Borrego@Sun.COM int str_offs, sh_len; 450*8474SJose.Borrego@Sun.COM mts_wchar_t wcs_hostname[MAXHOSTNAMELEN]; 451*8474SJose.Borrego@Sun.COM mts_wchar_t wcs_srcname[SYS_NMLN * 2]; 452*8474SJose.Borrego@Sun.COM 453*8474SJose.Borrego@Sun.COM (void) mts_mbstowcs(wcs_srcname, src_name, 454*8474SJose.Borrego@Sun.COM strlen(src_name) + 1); 455*8474SJose.Borrego@Sun.COM srcname_len = LOGR_WNSTRLEN(src_name); 456*8474SJose.Borrego@Sun.COM 457*8474SJose.Borrego@Sun.COM /* Because, Solaris allows remote logging, need to get hostname here */ 458*8474SJose.Borrego@Sun.COM (void) mts_mbstowcs(wcs_hostname, le->le_hostname, 459*8474SJose.Borrego@Sun.COM strlen(le->le_hostname) + 1); 460*8474SJose.Borrego@Sun.COM hostname_len = LOGR_WNSTRLEN(le->le_hostname); 461*8474SJose.Borrego@Sun.COM 462*8474SJose.Borrego@Sun.COM sh_len = srcname_len + hostname_len; 463*8474SJose.Borrego@Sun.COM str_offs = LOGR_MSG_DWORD_OFFSET * sizeof (DWORD) + 464*8474SJose.Borrego@Sun.COM LOGR_MSG_WORD_OFFSET * sizeof (WORD) + sh_len; 465*8474SJose.Borrego@Sun.COM 466*8474SJose.Borrego@Sun.COM rec->Length1 = sizeof (logr_record_t); 467*8474SJose.Borrego@Sun.COM rec->Reserved = LOGR_RECORD_SIGNATURE; 468*8474SJose.Borrego@Sun.COM rec->RecordNumber = recno; 469*8474SJose.Borrego@Sun.COM rec->TimeGenerated = le->le_timestamp.tv_sec; 470*8474SJose.Borrego@Sun.COM rec->TimeWritten = le->le_timestamp.tv_sec; 471*8474SJose.Borrego@Sun.COM logr_set_event_typeid(le->le_pri, &rec->EventType, &rec->EventID); 472*8474SJose.Borrego@Sun.COM rec->NumStrings = 1; 473*8474SJose.Borrego@Sun.COM rec->EventCategory = 0; 474*8474SJose.Borrego@Sun.COM rec->ReservedFlags = 0; 475*8474SJose.Borrego@Sun.COM rec->ClosingRecordNumber = 0; 476*8474SJose.Borrego@Sun.COM rec->StringOffset = str_offs; 477*8474SJose.Borrego@Sun.COM rec->UserSidLength = 0; 478*8474SJose.Borrego@Sun.COM rec->UserSidOffset = 0; 479*8474SJose.Borrego@Sun.COM rec->DataLength = 0; 480*8474SJose.Borrego@Sun.COM rec->DataOffset = 0; 481*8474SJose.Borrego@Sun.COM 482*8474SJose.Borrego@Sun.COM bzero(rec->info, LOGR_MAXENTRYLEN); 483*8474SJose.Borrego@Sun.COM (void) memcpy(rec->info, wcs_srcname, srcname_len); 484*8474SJose.Borrego@Sun.COM (void) memcpy(rec->info + srcname_len, wcs_hostname, hostname_len); 485*8474SJose.Borrego@Sun.COM 486*8474SJose.Borrego@Sun.COM len = strlen(le->le_msg) + 1; 487*8474SJose.Borrego@Sun.COM if (len > 0) 488*8474SJose.Borrego@Sun.COM /*LINTED E_BAD_PTR_CAST_ALIGN*/ 489*8474SJose.Borrego@Sun.COM (void) mts_mbstowcs((mts_wchar_t *)(rec->info + sh_len), 490*8474SJose.Borrego@Sun.COM le->le_msg, len); 491*8474SJose.Borrego@Sun.COM 492*8474SJose.Borrego@Sun.COM rec->Length2 = sizeof (logr_record_t); 493*8474SJose.Borrego@Sun.COM } 494*8474SJose.Borrego@Sun.COM 495*8474SJose.Borrego@Sun.COM /* 496*8474SJose.Borrego@Sun.COM * logr_s_EventLogRead 497*8474SJose.Borrego@Sun.COM * 498*8474SJose.Borrego@Sun.COM * Reads a whole number of entries from system log. The function can 499*8474SJose.Borrego@Sun.COM * read log entries in chronological or reverse chronological order. 500*8474SJose.Borrego@Sun.COM */ 501*8474SJose.Borrego@Sun.COM static int 502*8474SJose.Borrego@Sun.COM logr_s_EventLogRead(void *arg, ndr_xa_t *mxa) 503*8474SJose.Borrego@Sun.COM { 504*8474SJose.Borrego@Sun.COM struct logr_EventLogRead *param = arg; 505*8474SJose.Borrego@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 506*8474SJose.Borrego@Sun.COM ndr_handle_t *hd; 507*8474SJose.Borrego@Sun.COM logr_read_data_t *rdata; 508*8474SJose.Borrego@Sun.COM logr_entry_t *le; 509*8474SJose.Borrego@Sun.COM DWORD ent_no, ent_num, ent_remain; 510*8474SJose.Borrego@Sun.COM logr_record_t *rec; 511*8474SJose.Borrego@Sun.COM BYTE *buf; 512*8474SJose.Borrego@Sun.COM int dir, ent_per_req, iter; 513*8474SJose.Borrego@Sun.COM logr_context_t *ctx; 514*8474SJose.Borrego@Sun.COM 515*8474SJose.Borrego@Sun.COM if ((hd = logr_hdlookup(mxa, id)) == NULL) { 516*8474SJose.Borrego@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 517*8474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 518*8474SJose.Borrego@Sun.COM } 519*8474SJose.Borrego@Sun.COM 520*8474SJose.Borrego@Sun.COM ctx = (logr_context_t *)hd->nh_data; 521*8474SJose.Borrego@Sun.COM rdata = ctx->lc_cached_read_data; 522*8474SJose.Borrego@Sun.COM if (rdata == NULL) { 523*8474SJose.Borrego@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 524*8474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 525*8474SJose.Borrego@Sun.COM } 526*8474SJose.Borrego@Sun.COM 527*8474SJose.Borrego@Sun.COM dir = (param->read_flags & EVENTLOG_FORWARDS_READ) ? 528*8474SJose.Borrego@Sun.COM LOGR_FWD : LOGR_REW; 529*8474SJose.Borrego@Sun.COM 530*8474SJose.Borrego@Sun.COM if (param->read_flags & EVENTLOG_SEEK_READ) 531*8474SJose.Borrego@Sun.COM rdata->rd_last_sentrec = param->rec_offset; 532*8474SJose.Borrego@Sun.COM else if (rdata->rd_first_read) 533*8474SJose.Borrego@Sun.COM /* 534*8474SJose.Borrego@Sun.COM * set last record number which is read for 535*8474SJose.Borrego@Sun.COM * the first iteration of sequential read. 536*8474SJose.Borrego@Sun.COM */ 537*8474SJose.Borrego@Sun.COM rdata->rd_last_sentrec = (dir == LOGR_FWD) 538*8474SJose.Borrego@Sun.COM ? (rdata->rd_log->li_idx - rdata->rd_tot_recnum) 539*8474SJose.Borrego@Sun.COM : rdata->rd_log->li_idx; 540*8474SJose.Borrego@Sun.COM 541*8474SJose.Borrego@Sun.COM ent_remain = (dir == LOGR_FWD) 542*8474SJose.Borrego@Sun.COM ? (rdata->rd_tot_recnum - rdata->rd_last_sentrec) 543*8474SJose.Borrego@Sun.COM : rdata->rd_last_sentrec; 544*8474SJose.Borrego@Sun.COM 545*8474SJose.Borrego@Sun.COM /* 546*8474SJose.Borrego@Sun.COM * function should return as many whole log entries as 547*8474SJose.Borrego@Sun.COM * will fit in the buffer; it should not return partial 548*8474SJose.Borrego@Sun.COM * entries, even if there is room in the buffer. 549*8474SJose.Borrego@Sun.COM */ 550*8474SJose.Borrego@Sun.COM ent_per_req = param->nbytes_to_read / sizeof (logr_record_t); 551*8474SJose.Borrego@Sun.COM if (ent_remain > ent_per_req) 552*8474SJose.Borrego@Sun.COM ent_remain = ent_per_req; 553*8474SJose.Borrego@Sun.COM 554*8474SJose.Borrego@Sun.COM if (ent_remain == 0) { 555*8474SJose.Borrego@Sun.COM /* 556*8474SJose.Borrego@Sun.COM * Send this error to Windows client so that it 557*8474SJose.Borrego@Sun.COM * can figure out that there is no more record 558*8474SJose.Borrego@Sun.COM * to read. 559*8474SJose.Borrego@Sun.COM */ 560*8474SJose.Borrego@Sun.COM param->buf = NDR_STRDUP(mxa, ""); 561*8474SJose.Borrego@Sun.COM param->sent_size = 0; 562*8474SJose.Borrego@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_END_OF_FILE); 563*8474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 564*8474SJose.Borrego@Sun.COM } 565*8474SJose.Borrego@Sun.COM 566*8474SJose.Borrego@Sun.COM param->buf = NDR_MALLOC(mxa, param->nbytes_to_read); 567*8474SJose.Borrego@Sun.COM buf = (BYTE *)param->buf; 568*8474SJose.Borrego@Sun.COM 569*8474SJose.Borrego@Sun.COM for (ent_num = 0, ent_no = rdata->rd_last_sentrec; 570*8474SJose.Borrego@Sun.COM ent_num < ent_remain; ent_num++, ent_no += dir) { 571*8474SJose.Borrego@Sun.COM 572*8474SJose.Borrego@Sun.COM iter = ent_no & LOGR_NMSGMASK; 573*8474SJose.Borrego@Sun.COM if (dir == LOGR_REW) 574*8474SJose.Borrego@Sun.COM iter = (ent_no - 1) & LOGR_NMSGMASK; 575*8474SJose.Borrego@Sun.COM 576*8474SJose.Borrego@Sun.COM le = logr_get_entry(rdata->rd_log, iter); 577*8474SJose.Borrego@Sun.COM 578*8474SJose.Borrego@Sun.COM /*LINTED E_BAD_PTR_CAST_ALIGN*/ 579*8474SJose.Borrego@Sun.COM rec = (logr_record_t *)buf; 580*8474SJose.Borrego@Sun.COM logr_set_logrecord(ctx->lc_source_name, le, ent_no, rec); 581*8474SJose.Borrego@Sun.COM buf += sizeof (logr_record_t); 582*8474SJose.Borrego@Sun.COM } 583*8474SJose.Borrego@Sun.COM 584*8474SJose.Borrego@Sun.COM rdata->rd_last_sentrec = ent_no; 585*8474SJose.Borrego@Sun.COM rdata->rd_first_read = 0; 586*8474SJose.Borrego@Sun.COM 587*8474SJose.Borrego@Sun.COM param->sent_size = sizeof (logr_record_t) * ent_remain; 588*8474SJose.Borrego@Sun.COM param->status = NT_STATUS_SUCCESS; 589*8474SJose.Borrego@Sun.COM 590*8474SJose.Borrego@Sun.COM return (NDR_DRC_OK); 591*8474SJose.Borrego@Sun.COM } 592