aheinecke@404: /* Copyright (C) 2014 by Bundesamt für Sicherheit in der Informationstechnik aheinecke@404: * Software engineering by Intevation GmbH aheinecke@404: * aheinecke@404: * This file is Free Software under the GNU GPL (v>=2) aheinecke@404: * and comes with ABSOLUTELY NO WARRANTY! aheinecke@404: * See LICENSE.txt for details. aheinecke@404: */ aheinecke@252: #include "logging.h" aheinecke@252: #include "strhelp.h" aheinecke@252: aheinecke@252: #include andre@615: #include andre@615: #include andre@615: andre@615: #include aheinecke@252: aheinecke@252: #ifdef WIN32 andre@615: # include andre@615: #else andre@615: # include andre@615: #endif andre@615: andre@615: andre@615: #ifdef WIN32 andre@615: static void andre@615: win_log(const char *format, va_list ap, bool error) andre@615: { andre@616: HANDLE log_src = NULL, andre@616: process_token = NULL; andre@615: wchar_t *wmsg = NULL; andre@615: BOOL failure = TRUE; andre@615: WORD type = 0, andre@615: category = 0; andre@615: char buffer[MAX_LOG+1]; andre@616: PTOKEN_USER user_struct = NULL; andre@616: PSID user_sid = NULL; andre@615: andre@615: vsnprintf (buffer, MAX_LOG, format, ap); andre@615: buffer[MAX_LOG] = '\0'; andre@615: andre@615: log_src = RegisterEventSourceA (NULL, LOG_NAME); andre@615: andre@615: if (log_src == NULL) andre@615: { andre@615: PRINTLASTERROR ("Failed to open log source."); andre@615: return; andre@615: } andre@615: andre@615: if (error) andre@615: { andre@615: type = EVENTLOG_ERROR_TYPE; andre@615: } andre@615: else andre@615: { andre@615: type = EVENTLOG_INFORMATION_TYPE; andre@615: } andre@615: andre@615: wmsg = utf8_to_wchar (buffer, strlen(buffer)); andre@615: if (wmsg == NULL) andre@615: { andre@615: ERRORPRINTF ("Failed to convert log message to utf-16"); andre@615: goto done; andre@615: } andre@615: andre@616: /* Get the current user sid for logging */ andre@616: andre@616: OpenProcessToken (GetCurrentProcess(), TOKEN_READ, &process_token); andre@616: if (process_token) andre@616: { andre@616: DWORD size = 0; andre@616: andre@616: // check how much space is needed andre@616: GetTokenInformation (process_token, TokenUser, NULL, 0, &size); andre@616: if (ERROR_INSUFFICIENT_BUFFER == GetLastError()) andre@616: { andre@616: user_struct = xmalloc (size); andre@616: GetTokenInformation (process_token, TokenUser, user_struct, size, &size); andre@616: user_sid = user_struct->User.Sid; andre@616: } andre@616: } andre@616: andre@616: andre@615: failure = ReportEventW (log_src, andre@615: type, andre@615: category, andre@615: 0, andre@616: user_sid, andre@615: 1, andre@615: 0, andre@615: (const WCHAR **) &wmsg, andre@615: NULL); andre@615: if (failure) andre@615: { andre@615: PRINTLASTERROR ("Failed to report event."); andre@615: } andre@615: andre@615: done: andre@616: if (process_token) andre@616: { andre@616: CloseHandle(process_token); andre@616: } andre@616: xfree (user_struct); andre@615: xfree (wmsg); andre@615: andre@615: if (!DeregisterEventSource (log_src)) andre@615: { andre@615: PRINTLASTERROR ("Failed to close log source."); andre@615: } andre@615: return; andre@615: } andre@615: aheinecke@252: char * aheinecke@252: getLastErrorMsg() aheinecke@252: { aheinecke@252: LPWSTR bufPtr = NULL; aheinecke@252: DWORD err = GetLastError(); aheinecke@252: char *retval = NULL; aheinecke@252: FormatMessageW (FORMAT_MESSAGE_ALLOCATE_BUFFER | aheinecke@252: FORMAT_MESSAGE_FROM_SYSTEM | aheinecke@252: FORMAT_MESSAGE_IGNORE_INSERTS, aheinecke@252: NULL, err, 0, (LPWSTR) &bufPtr, 0, NULL); aheinecke@252: if (!bufPtr) aheinecke@252: { aheinecke@252: HMODULE hWinhttp = GetModuleHandleW (L"crypt32"); aheinecke@252: if (hWinhttp) aheinecke@252: { aheinecke@252: FormatMessageW (FORMAT_MESSAGE_ALLOCATE_BUFFER | aheinecke@252: FORMAT_MESSAGE_FROM_HMODULE | aheinecke@252: FORMAT_MESSAGE_IGNORE_INSERTS, aheinecke@252: hWinhttp, HRESULT_CODE (err), 0, aheinecke@252: (LPWSTR) &bufPtr, 0, NULL); aheinecke@252: } aheinecke@252: } aheinecke@252: if (!bufPtr) { aheinecke@252: fprintf (stderr, "Error getting last error for code: %lx \n", err); aheinecke@252: return NULL; aheinecke@252: } aheinecke@252: aheinecke@252: retval = wchar_to_utf8(bufPtr, wcslen(bufPtr)); aheinecke@252: LocalFree (bufPtr); aheinecke@252: aheinecke@252: return retval; aheinecke@252: } aheinecke@252: andre@615: #else /* WIN32 */ andre@615: andre@615: andre@615: static void andre@615: linux_log (const char *format, va_list ap, bool error) andre@615: { andre@615: openlog (LOG_NAME, LOG_CONS | LOG_PID | LOG_NDELAY, LOG_USER); andre@615: vsyslog ( error ? LOG_ERR : LOG_INFO, format, ap); andre@615: } andre@615: andre@615: #endif /* WIN32 */ andre@615: andre@615: void andre@615: syslog_info_printf(const char *format, ...) andre@615: { andre@615: va_list args; andre@615: va_start (args, format); andre@615: #ifdef WIN32 andre@615: win_log (format, args, false); andre@615: #else andre@615: linux_log (format, args, false); aheinecke@252: #endif andre@615: va_end (args); andre@615: } andre@615: andre@615: void andre@615: syslog_error_printf(const char *format, ...) andre@615: { andre@615: va_list args; andre@615: va_start (args, format); andre@615: #ifdef WIN32 andre@615: win_log (format, args, true); andre@615: #else andre@615: linux_log (format, args, true); andre@615: #endif andre@615: va_end (args); andre@615: }