File: logging.c

package info (click to toggle)
remctl 3.18-5
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 5,612 kB
  • sloc: ansic: 19,504; sh: 5,386; perl: 1,778; java: 740; makefile: 715; xml: 502; python: 430
file content (126 lines) | stat: -rw-r--r-- 3,272 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/*
 * Logging and error handling for the remctld server.
 *
 * A set of helper routines to do error handling and other logging for
 * remctld, mostly wrappers around warn and die which will send errors to the
 * right place.
 *
 * Written by Russ Allbery <eagle@eyrie.org>
 * Copyright 2006-2008, 2010, 2014
 *     The Board of Trustees of the Leland Stanford Junior University
 *
 * SPDX-License-Identifier: MIT
 */

#include <config.h>
#include <portable/gssapi.h>
#include <portable/socket.h>
#include <portable/system.h>
#include <portable/uio.h>

#include <errno.h>

#include <server/internal.h>
#include <util/gss-errors.h>
#include <util/messages.h>
#include <util/tokens.h>
#include <util/vector.h>


/*
 * Report a GSS-API failure using warn.
 */
void
warn_gssapi(const char *error, OM_uint32 major, OM_uint32 minor)
{
    char *string;

    string = gssapi_error_string(error, major, minor);
    warn("%s", string);
    free(string);
}


/*
 * Report a token error using warn.
 */
void
warn_token(const char *error, int status, OM_uint32 major, OM_uint32 minor)
{
    switch (status) {
    case TOKEN_OK:
        warn("error %s", error);
        break;
    case TOKEN_FAIL_SYSTEM:
        syswarn("error %s", error);
        break;
    case TOKEN_FAIL_SOCKET:
        warn("error %s: %s", error, socket_strerror(socket_errno));
        break;
    case TOKEN_FAIL_INVALID:
        warn("error %s: invalid token format", error);
        break;
    case TOKEN_FAIL_LARGE:
        warn("error %s: token too large", error);
        break;
    case TOKEN_FAIL_EOF:
        warn("error %s: unexpected end of file", error);
        break;
    case TOKEN_FAIL_GSSAPI:
        warn_gssapi(error, major, minor);
        break;
    case TOKEN_FAIL_TIMEOUT:
        warn("error %s: timed out", error);
        break;
    default:
        warn("error %s: unknown error", error);
        break;
    }
}


/*
 * Log a command.  Takes the argument vector, the configuration line that
 * matched the command, and the principal running the command.
 */
void
server_log_command(struct iovec **argv, struct rule *rule, const char *user)
{
    char *command, *p;
    unsigned int i;
    unsigned int *j;
    struct vector *masked;
    const char *arg;

    masked = vector_new();
    for (i = 0; argv[i] != NULL; i++) {
        arg = NULL;
        if (rule != NULL) {
            if (rule->logmask != NULL)
                for (j = rule->logmask; *j != 0; j++) {
                    if (*j == i) {
                        arg = "**MASKED**";
                        break;
                    }
                }
            if (i > 0
                && (rule->stdin_arg == (long) i
                    || (rule->stdin_arg == -1 && argv[i + 1] == NULL))) {
                arg = "**DATA**";
            }
        }
        if (arg != NULL)
            vector_add(masked, arg);
        else
            vector_addn(masked, argv[i]->iov_base, argv[i]->iov_len);
    }
    command = vector_join(masked, " ");
    vector_free(masked);

    /* Replace non-printable characters with . when logging. */
    for (p = command; *p != '\0'; p++)
        if (*p < 9 || (*p > 9 && *p < 32) || *p == 127)
            *p = '.';
    notice("COMMAND from %s: %s", user, command);
    free(command);
}