~yolanda.robla/ubuntu/trusty/memcached/add_distribution

1.4.3 by David Martínez Moreno
Import upstream version 1.4.5
1
/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
#include "memcached.h"
3
#include <stdio.h>
4
#include <stdlib.h>
5
#include <string.h>
1.1.11 by Scott Kitterman
Import upstream version 1.4.11
6
#include <sasl/saslplug.h>
3.3.5 by Arno Töll
* Non-maintainer upload.
7
1.1.12 by Clint Byrum
Import upstream version 1.4.13
8
char my_sasl_hostname[1025];
9
1.4.3 by David Martínez Moreno
Import upstream version 1.4.5
10
#ifdef HAVE_SASL_CB_GETCONF
11
/* The locations we may search for a SASL config file if the user didn't
12
 * specify one in the environment variable SASL_CONF_PATH
13
 */
14
const char * const locations[] = {
15
    "/etc/sasl/memcached.conf",
16
    "/etc/sasl2/memcached.conf",
17
    NULL
18
};
19
#endif
20
1.1.12 by Clint Byrum
Import upstream version 1.4.13
21
#ifndef HAVE_SASL_CALLBACK_FT
22
typedef int (*sasl_callback_ft)(void);
23
#endif
24
1.4.3 by David Martínez Moreno
Import upstream version 1.4.5
25
#ifdef ENABLE_SASL_PWDB
26
#define MAX_ENTRY_LEN 256
27
28
static const char *memcached_sasl_pwdb;
29
30
static int sasl_server_userdb_checkpass(sasl_conn_t *conn,
31
                                        void *context,
32
                                        const char *user,
33
                                        const char *pass,
34
                                        unsigned passlen,
35
                                        struct propctx *propctx)
36
{
37
    size_t unmlen = strlen(user);
38
    if ((passlen + unmlen) > (MAX_ENTRY_LEN - 4)) {
39
        fprintf(stderr,
40
                "WARNING: Failed to authenticate <%s> due to too long password (%d)\n",
41
                user, passlen);
42
        return SASL_NOAUTHZ;
43
    }
44
45
    FILE *pwfile = fopen(memcached_sasl_pwdb, "r");
46
    if (pwfile == NULL) {
47
        if (settings.verbose) {
48
            vperror("WARNING: Failed to open sasl database <%s>",
49
                    memcached_sasl_pwdb);
50
        }
51
        return SASL_NOAUTHZ;
52
    }
53
54
    char buffer[MAX_ENTRY_LEN];
55
    bool ok = false;
56
57
    while ((fgets(buffer, sizeof(buffer), pwfile)) != NULL) {
58
        if (memcmp(user, buffer, unmlen) == 0 && buffer[unmlen] == ':') {
59
            /* This is the correct user */
60
            ++unmlen;
61
            if (memcmp(pass, buffer + unmlen, passlen) == 0 &&
62
                (buffer[unmlen + passlen] == ':' || /* Additional tokens */
63
                 buffer[unmlen + passlen] == '\n' || /* end of line */
64
                 buffer[unmlen + passlen] == '\r'|| /* dos format? */
65
                 buffer[unmlen + passlen] == '\0')) { /* line truncated */
66
                ok = true;
67
            }
68
69
            break;
70
        }
71
    }
72
    (void)fclose(pwfile);
73
    if (ok) {
74
        return SASL_OK;
75
    }
76
77
    if (settings.verbose) {
78
        fprintf(stderr, "INFO: User <%s> failed to authenticate\n", user);
79
    }
80
81
    return SASL_NOAUTHZ;
82
}
83
#endif
84
85
#ifdef HAVE_SASL_CB_GETCONF
86
static int sasl_getconf(void *context, const char **path)
87
{
88
    *path = getenv("SASL_CONF_PATH");
89
90
    if (*path == NULL) {
91
        for (int i = 0; locations[i] != NULL; ++i) {
92
            if (access(locations[i], F_OK) == 0) {
93
                *path = locations[i];
94
                break;
95
            }
96
        }
97
    }
98
99
    if (settings.verbose) {
100
        if (*path != NULL) {
101
            fprintf(stderr, "Reading configuration from: <%s>\n", *path);
102
        } else {
103
            fprintf(stderr, "Failed to locate a config path\n");
104
        }
105
106
    }
107
108
    return (*path != NULL) ? SASL_OK : SASL_FAIL;
109
}
110
#endif
111
112
static int sasl_log(void *context, int level, const char *message)
113
{
114
    bool log = true;
115
116
    switch (level) {
117
    case SASL_LOG_NONE:
118
        log = false;
119
        break;
120
    case SASL_LOG_PASS:
121
    case SASL_LOG_TRACE:
122
    case SASL_LOG_DEBUG:
123
    case SASL_LOG_NOTE:
124
        if (settings.verbose < 2) {
125
            log = false;
126
        }
127
        break;
128
    case SASL_LOG_WARN:
129
    case SASL_LOG_FAIL:
130
        if (settings.verbose < 1) {
131
            log = false;
132
        }
133
        break;
134
    default:
135
        /* This is an error */
136
        ;
137
    }
138
139
    if (log) {
140
        fprintf(stderr, "SASL (severity %d): %s\n", level, message);
141
    }
142
143
    return SASL_OK;
144
}
145
146
static sasl_callback_t sasl_callbacks[] = {
147
#ifdef ENABLE_SASL_PWDB
148
   { SASL_CB_SERVER_USERDB_CHECKPASS, sasl_server_userdb_checkpass, NULL },
149
#endif
150
1.1.11 by Scott Kitterman
Import upstream version 1.4.11
151
   { SASL_CB_LOG, (sasl_callback_ft)sasl_log, NULL },
1.4.3 by David Martínez Moreno
Import upstream version 1.4.5
152
153
#ifdef HAVE_SASL_CB_GETCONF
154
   { SASL_CB_GETCONF, sasl_getconf, NULL },
155
#endif
156
157
   { SASL_CB_LIST_END, NULL, NULL }
158
};
159
160
void init_sasl(void) {
161
#ifdef ENABLE_SASL_PWDB
162
    memcached_sasl_pwdb = getenv("MEMCACHED_SASL_PWDB");
163
    if (memcached_sasl_pwdb == NULL) {
164
       if (settings.verbose) {
165
          fprintf(stderr,
166
                  "INFO: MEMCACHED_SASL_PWDB not specified. "
167
                  "Internal passwd database disabled\n");
168
       }
169
       sasl_callbacks[0].id = SASL_CB_LIST_END;
170
       sasl_callbacks[0].proc = NULL;
171
    }
172
#endif
173
1.1.12 by Clint Byrum
Import upstream version 1.4.13
174
    memset(my_sasl_hostname, 0, sizeof(my_sasl_hostname));
175
    if (gethostname(my_sasl_hostname, sizeof(my_sasl_hostname)-1) == -1) {
176
        if (settings.verbose) {
177
            fprintf(stderr, "Error discovering hostname for SASL\n");
178
        }
179
        my_sasl_hostname[0] = '\0';
180
    }
181
1.4.3 by David Martínez Moreno
Import upstream version 1.4.5
182
    if (sasl_server_init(sasl_callbacks, "memcached") != SASL_OK) {
183
        fprintf(stderr, "Error initializing sasl.\n");
184
        exit(EXIT_FAILURE);
185
    } else {
186
        if (settings.verbose) {
187
            fprintf(stderr, "Initialized SASL.\n");
188
        }
189
    }
190
}