"Fossies" - the Fresh Open Source Software Archive

Member "memcached-1.6.15/sasl_defs.c" (21 Feb 2022, 6203 Bytes) of package /linux/www/memcached-1.6.15.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "sasl_defs.c" see the Fossies "Dox" file reference documentation.

    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>
    6 #include <sasl/saslplug.h>
    7 
    8 char my_sasl_hostname[1025];
    9 
   10 #if defined(HAVE_SASL_CB_GETCONF) || defined(HAVE_SASL_CB_GETCONFPATH)
   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 
   20 /* If the element of locations is file, locations_dir_path stores the
   21  * directory path of these elements */
   22 const char *const locations_dir_path[] = {
   23     "/etc/sasl",
   24     "/etc/sasl2",
   25     NULL
   26 };
   27 
   28 /* If the element of locations is directory, locations_file_path stores
   29  * the actual configure file which used by sasl, when GETCONFPATH is
   30  * enabled */
   31 const char *const locations_file_path[] = {
   32     "/etc/sasl/memcached.conf/memcached.conf",
   33     "/etc/sasl2/memcached.conf/memcached.conf",
   34     NULL
   35 };
   36 #endif
   37 
   38 #ifndef HAVE_SASL_CALLBACK_FT
   39 typedef int (*sasl_callback_ft)(void);
   40 #endif
   41 
   42 #ifdef ENABLE_SASL_PWDB
   43 #define MAX_ENTRY_LEN 256
   44 
   45 static const char *memcached_sasl_pwdb;
   46 
   47 static int sasl_server_userdb_checkpass(sasl_conn_t *conn,
   48                                         void *context,
   49                                         const char *user,
   50                                         const char *pass,
   51                                         unsigned passlen,
   52                                         struct propctx *propctx)
   53 {
   54     size_t unmlen = strlen(user);
   55     if ((passlen + unmlen) > (MAX_ENTRY_LEN - 4)) {
   56         fprintf(stderr,
   57                 "WARNING: Failed to authenticate <%s> due to too long password (%d)\n",
   58                 user, passlen);
   59         return SASL_NOAUTHZ;
   60     }
   61 
   62     FILE *pwfile = fopen(memcached_sasl_pwdb, "r");
   63     if (pwfile == NULL) {
   64         if (settings.verbose) {
   65             vperror("WARNING: Failed to open sasl database <%s>",
   66                     memcached_sasl_pwdb);
   67         }
   68         return SASL_NOAUTHZ;
   69     }
   70 
   71     char buffer[MAX_ENTRY_LEN];
   72     bool ok = false;
   73 
   74     while ((fgets(buffer, sizeof(buffer), pwfile)) != NULL) {
   75         if (memcmp(user, buffer, unmlen) == 0 && buffer[unmlen] == ':') {
   76             /* This is the correct user */
   77             ++unmlen;
   78             if (memcmp(pass, buffer + unmlen, passlen) == 0 &&
   79                 (buffer[unmlen + passlen] == ':' || /* Additional tokens */
   80                  buffer[unmlen + passlen] == '\n' || /* end of line */
   81                  buffer[unmlen + passlen] == '\r'|| /* dos format? */
   82                  buffer[unmlen + passlen] == '\0')) { /* line truncated */
   83                 ok = true;
   84             }
   85 
   86             break;
   87         }
   88     }
   89     (void)fclose(pwfile);
   90     if (ok) {
   91         return SASL_OK;
   92     }
   93 
   94     if (settings.verbose) {
   95         fprintf(stderr, "INFO: User <%s> failed to authenticate\n", user);
   96     }
   97 
   98     return SASL_NOAUTHZ;
   99 }
  100 #endif
  101 
  102 #if defined(HAVE_SASL_CB_GETCONF) || defined(HAVE_SASL_CB_GETCONFPATH)
  103 static int sasl_getconf(void *context, const char **path)
  104 {
  105     *path = getenv("SASL_CONF_PATH");
  106 
  107     if (*path == NULL) {
  108 #if defined(HAVE_SASL_CB_GETCONF)
  109         for (int i = 0; locations[i] != NULL; ++i) {
  110             if (access(locations[i], F_OK) == 0) {
  111                 *path = locations[i];
  112                 break;
  113             }
  114         }
  115 #elif defined(HAVE_SASL_CB_GETCONFPATH)
  116         for (int i = 0; locations[i] != NULL; ++i) {
  117             if (access(locations_file_path[i], F_OK) == 0) {
  118                 *path = locations[i];
  119                 break;
  120             } else if (access(locations[i], F_OK) == 0) {
  121                 *path = locations_dir_path[i];
  122                 break;
  123             }
  124         }
  125 #endif
  126     }
  127 
  128     if (settings.verbose) {
  129         if (*path != NULL) {
  130             fprintf(stderr, "Reading configuration from: <%s>\n", *path);
  131         } else {
  132             fprintf(stderr, "Failed to locate a config path\n");
  133         }
  134 
  135     }
  136 
  137     return (*path != NULL) ? SASL_OK : SASL_FAIL;
  138 }
  139 #endif
  140 
  141 static int sasl_log(void *context, int level, const char *message)
  142 {
  143     bool log = true;
  144 
  145     switch (level) {
  146     case SASL_LOG_NONE:
  147         log = false;
  148         break;
  149     case SASL_LOG_PASS:
  150     case SASL_LOG_TRACE:
  151     case SASL_LOG_DEBUG:
  152     case SASL_LOG_NOTE:
  153         if (settings.verbose < 2) {
  154             log = false;
  155         }
  156         break;
  157     case SASL_LOG_WARN:
  158     case SASL_LOG_FAIL:
  159         if (settings.verbose < 1) {
  160             log = false;
  161         }
  162         break;
  163     default:
  164         /* This is an error */
  165         ;
  166     }
  167 
  168     if (log) {
  169         fprintf(stderr, "SASL (severity %d): %s\n", level, message);
  170     }
  171 
  172     return SASL_OK;
  173 }
  174 
  175 static sasl_callback_t sasl_callbacks[] = {
  176 #ifdef ENABLE_SASL_PWDB
  177    { SASL_CB_SERVER_USERDB_CHECKPASS, (sasl_callback_ft)sasl_server_userdb_checkpass, NULL },
  178 #endif
  179 
  180    { SASL_CB_LOG, (sasl_callback_ft)sasl_log, NULL },
  181 
  182 #ifdef HAVE_SASL_CB_GETCONF
  183    { SASL_CB_GETCONF, sasl_getconf, NULL },
  184 #else
  185 #ifdef HAVE_SASL_CB_GETCONFPATH
  186    { SASL_CB_GETCONFPATH, (sasl_callback_ft)sasl_getconf, NULL },
  187 #endif
  188 #endif
  189 
  190    { SASL_CB_LIST_END, NULL, NULL }
  191 };
  192 
  193 void init_sasl(void) {
  194 #ifdef ENABLE_SASL_PWDB
  195     memcached_sasl_pwdb = getenv("MEMCACHED_SASL_PWDB");
  196     if (memcached_sasl_pwdb == NULL) {
  197        if (settings.verbose) {
  198           fprintf(stderr,
  199                   "INFO: MEMCACHED_SASL_PWDB not specified. "
  200                   "Internal passwd database disabled\n");
  201        }
  202        sasl_callbacks[0].id = SASL_CB_LIST_END;
  203        sasl_callbacks[0].proc = NULL;
  204     }
  205 #endif
  206 
  207     memset(my_sasl_hostname, 0, sizeof(my_sasl_hostname));
  208     if (gethostname(my_sasl_hostname, sizeof(my_sasl_hostname)-1) == -1) {
  209         if (settings.verbose) {
  210             fprintf(stderr, "Error discovering hostname for SASL\n");
  211         }
  212         my_sasl_hostname[0] = '\0';
  213     }
  214 
  215     if (sasl_server_init(sasl_callbacks, "memcached") != SASL_OK) {
  216         fprintf(stderr, "Error initializing sasl.\n");
  217         exit(EXIT_FAILURE);
  218     } else {
  219         if (settings.verbose) {
  220             fprintf(stderr, "Initialized SASL.\n");
  221         }
  222     }
  223 }