static bool is_allowed_user(cmd_rec *cmd, const char *account) {
    config_rec *c;

    /* ハッシュテーブルにアカウントがあるか否か */
    c = find_config(cmd->server->conf, CONF_PARAM, "LMDBAllowedUser", FALSE);
    if(c && c->argv[0]) {
        pr_table_t *explicit_users = c->argv[0];
        if(pr_table_exists(explicit_users, account) > 0 ) {
            pr_log_debug(DEBUG2,
                "%s: '%s' match with LMDBAllowedUser", MODULE_NAME, account);
            return true;
        }
    }

    /* 正規表現にマッチするか否か */
    c = find_config(cmd->server->conf, CONF_PARAM, "LMDBAllowedUserRegex", FALSE);
    if(c && c->argv[0]) {
        int i;
        array_header *regex_list = c->argv[0];
        regex_t ** elts = regex_list->elts;

        for (i = 0; i < regex_list->nelts; i++) {
            regex_t *preg = elts[i];
            if(regexec(preg, account, 0, NULL, 0) == 0) {
                pr_log_debug(DEBUG2,
                    "%s: '%s' match with LMDBAllowedUserRegex", MODULE_NAME, account);
                return true;
            }
        }
    }

    return false;
}
Beispiel #2
0
int proxy_forward_sess_init(pool *p, const char *tables_dir,
    struct proxy_session *proxy_sess) {
  config_rec *c;
  int allowed = FALSE;
  void *enabled = NULL;

  /* By default, only allow connections from RFC1918 addresses to use
   * forward proxying.  Otherwise, it must be from an explicitly allowed
   * connection class, via the class notes.
   */
  if (session.conn_class != NULL) {
    enabled = pr_table_get(session.conn_class->cls_notes,
      PROXY_FORWARD_ENABLED_NOTE, NULL);
  }

  if (enabled != NULL) {
    allowed = *((int *) enabled);
    if (allowed == FALSE) {
      (void) pr_log_writefile(proxy_logfd, MOD_PROXY_VERSION,
        "forward proxying not allowed from client address %s in <Class %s> "
        "(see ProxyForwardEnabled)",
        pr_netaddr_get_ipstr(session.c->remote_addr),
        session.conn_class->cls_name);
    }

  } else {
    if (pr_netaddr_is_rfc1918(session.c->remote_addr) == TRUE) {
      allowed = TRUE;

    } else {
      (void) pr_log_writefile(proxy_logfd, MOD_PROXY_VERSION,
        "forward proxying not allowed from non-RFC1918 client address %s",
        pr_netaddr_get_ipstr(session.c->remote_addr));
    }
  }

  if (allowed == FALSE) {
    errno = EPERM;
    return -1;
  }

  c = find_config(main_server->conf, CONF_PARAM, "ProxyForwardMethod", FALSE);
  if (c != NULL) {
    proxy_method = *((int *) c->argv[0]);
  }

  c = find_config(main_server->conf, CONF_PARAM, "ProxyRetryCount", FALSE);
  if (c != NULL) {
    forward_retry_count = *((int *) c->argv[0]);
  }

  return 0;
}
Beispiel #3
0
static int authfile_sess_init(void) {
  config_rec *c = NULL;

  c = find_config(main_server->conf, CONF_PARAM, "AuthUserFile", FALSE);
  if (c) {
    af_user_file = c->argv[0];
  }

  c = find_config(main_server->conf, CONF_PARAM, "AuthGroupFile", FALSE);
  if (c) {
    af_group_file = c->argv[0];
  }

  return 0;
}
Beispiel #4
0
static void qos_data_connect_ev(const void *event_data, void *user_data) {
  const struct socket_ctx *sc;

  sc = event_data;

  /* Only set TOS flags on IPv4 sockets; IPv6 sockets don't seem to support
   * them.
   */
  if (pr_netaddr_get_family(sc->addr) == AF_INET) {
    config_rec *c;
    c = find_config(sc->server->conf, CONF_PARAM, "QoSOptions", FALSE);
    if (c) {
      int dataqos, res;

      dataqos = *((int *) c->argv[1]);

      res = setsockopt(sc->sockfd, ip_level, IP_TOS, (void *) &dataqos,
        sizeof(dataqos));
      if (res < 0) {
        pr_log_pri(PR_LOG_NOTICE, MOD_QOS_VERSION
          ": error setting data socket IP_TOS: %s", strerror(errno));
      }
    }
  }
}
static bool is_allowed(cmd_rec *cmd, pr_netaddr_t *na) {
    int i;
    config_rec *c;
    array_header *allowed_acls;

    c = find_config(cmd->server->conf, CONF_PARAM, "LMDBAllow", FALSE);
    if(NULL == c)
        return false;

    allowed_acls = c->argv[0];
    if(NULL == allowed_acls) {
        pr_log_auth(PR_LOG_ERR,
          "%s: pr_table_t is NULL. something fatal", MODULE_NAME);
        return false;
    }

#ifdef DEBUG
    pr_table_do(allowed_acls, walk_table, NULL, 0);
#endif

    pr_netacl_t **elts = allowed_acls->elts;
    for (i = 0; i < allowed_acls->nelts; i++) {
        pr_netacl_t *acl = elts[i];
        if(pr_netacl_match(acl, na) == 1) {
            pr_log_auth(PR_LOG_INFO,
                "%s: client IP matched with LMDBAllow '%s'. Skip last process",
                        MODULE_NAME, pr_netacl_get_str(cmd->tmp_pool, acl));
            return true;
        }
    }

    return false;
}
Beispiel #6
0
MODRET memcache_post_host(cmd_rec *cmd) {

  /* If the HOST command changed the main_server pointer, reinitialize
   * ourselves.
   */
  if (session.prev_server != NULL) {
    int res;
    config_rec *c;

    pr_event_unregister(&memcache_module, "core.exit", mcache_exit_ev);
    (void) close(memcache_logfd);

    c = find_config(session.prev_server->conf, CONF_PARAM, "MemcacheServers",
      FALSE);
    if (c != NULL) {
      memcached_server_st *memcache_servers;

      memcache_servers = c->argv[0];
      memcache_set_servers(memcache_servers);
    }

    /* XXX Restore other memcache settings? */

    res = mcache_sess_init();
    if (res < 0) {
      pr_session_disconnect(&memcache_module,
        PR_SESS_DISCONNECT_SESSION_INIT_FAILED, NULL);
    }
  }

  return PR_DECLINED(cmd);
}
Beispiel #7
0
static void resolve_deferred_patterns(pool *p, const char *directive) {
#if PR_USE_REGEX
  config_rec *c;

  c = find_config(main_server->conf, CONF_PARAM, directive, FALSE);
  while (c != NULL) {
    register unsigned int i;
    array_header *deferred_filters, *filters;

    pr_signals_handle();

    filters = c->argv[0];
    deferred_filters = c->argv[1];

    for (i = 0; i < deferred_filters->nelts; i++) {
      const char *query_name;
      array_header *sql_filters;

      query_name = ((const char **) deferred_filters->elts)[i];

      sql_filters = get_sql_filters(p, query_name);
      if (sql_filters == NULL) {
        continue;
      }

      array_cat(filters, sql_filters);
    }

    c = find_config_next(c, c->next, CONF_PARAM, directive, FALSE);
  }
#endif /* PR_USE_REGEX */
}
/*!

\brief Finds Config.
\details Looks for Config up the EventType tree until Config is found or the root
EventType is reached. Uses dmz::Config::lookup_all_config_merged().
\param[in] Name String containing the name of the Config data to find.
\return Returns a Config object. The Config object will be empty if the named Config
can not be found.

*/
dmz::Config
dmz::EventType::find_config (const String &Name) const {

   EventType type;

   return find_config (Name, type);
}
MODRET add_lmd_allow_from(cmd_rec *cmd) {
    config_rec *c;
    int i;
    array_header *allowed_acls;

    if(cmd->argc < 2 )
        CONF_ERROR(cmd, "argument missing");

    CHECK_CONF(cmd, CONF_ROOT|CONF_GLOBAL);

    /* argv => LMDMemcachedHost 127.0.0.1 192.168.0.1 ... */
    c = find_config(main_server->conf, CONF_PARAM, "LMDBAllow", FALSE);
    if(c && c->argv[0]) {
        allowed_acls = c->argv[0];
    } else {
        c = add_config_param(cmd->argv[0], 0, NULL);
        c->argv[0] = allowed_acls =
          make_array(cmd->server->pool, 0, sizeof(char *));
    }

    for(i=1; i < cmd->argc; i++) {
        char *entry = cmd->argv[i];
        if (strcasecmp(entry, "all") == 0 ||
            strcasecmp(entry, "none") == 0) {
            break;
        }
        pr_netacl_t *acl = pr_netacl_create(cmd->server->pool, entry);
        *((pr_netacl_t **) push_array(allowed_acls)) = acl;
        pr_log_debug(DEBUG2,
            "%s: add LMDBAllow[%d] %s", MODULE_NAME, i, entry);
    }

    return PR_HANDLED(cmd);
}
Beispiel #10
0
static void mcache_sess_reinit_ev(const void *event_data, void *user_data) {
  int res;
  config_rec *c;

  /* A HOST command changed the main_server pointer, reinitialize ourselves. */

  pr_event_unregister(&memcache_module, "core.exit", mcache_exit_ev);
  pr_event_unregister(&memcache_module, "core.session-reinit",
    mcache_sess_reinit_ev);

  (void) close(memcache_logfd);
  memcache_logfd = -1;

  c = find_config(session.prev_server->conf, CONF_PARAM, "MemcacheServers",
    FALSE);
  if (c != NULL) {
    memcached_server_st *memcache_servers;

    memcache_servers = c->argv[0];
    memcache_set_servers(memcache_servers);
  }

  /* XXX Restore other memcache settings? */
  /* reset MemcacheOptions */
  /* reset MemcacheReplicas */
  /* reset MemcacheTimeout */

  res = mcache_sess_init();
  if (res < 0) {
    pr_session_disconnect(&memcache_module,
      PR_SESS_DISCONNECT_SESSION_INIT_FAILED, NULL);
  }
}
Beispiel #11
0
static int authfile_sess_init(void) {
  config_rec *c = NULL;

  pr_event_register(&auth_file_module, "core.session-reinit",
    authfile_sess_reinit_ev, NULL);

  c = find_config(main_server->conf, CONF_PARAM, "AuthUserFile", FALSE);
  if (c) {
    af_user_file = c->argv[0];
  }

  c = find_config(main_server->conf, CONF_PARAM, "AuthGroupFile", FALSE);
  if (c) {
    af_group_file = c->argv[0];
  }

  return 0;
}
Beispiel #12
0
static int sftppam_sess_init(void) {
  config_rec *c;

  c = find_config(main_server->conf, CONF_PARAM, "SFTPPAMEngine", FALSE);
  if (c != NULL) {
    int engine;

    engine = *((int *) c->argv[0]);
    if (engine == FALSE) {
      (void) pr_log_writefile(sftp_logfd, MOD_SFTP_PAM_VERSION,
        "disabled by SFTPPAMEngine setting, unregistered 'pam' driver");
      sftp_kbdint_unregister_driver("pam");
      return 0;
    }
  }

  /* To preserve the principle of least surprise, also check for the AuthPAM
   * directive.
   */
  c = find_config(main_server->conf, CONF_PARAM, "AuthPAM", FALSE);
  if (c != NULL) {
    unsigned char auth_pam;

    auth_pam = *((unsigned char *) c->argv[0]);
    if (auth_pam == FALSE) {
      (void) pr_log_writefile(sftp_logfd, MOD_SFTP_PAM_VERSION,
        "disabled by AuthPAM setting, unregistered 'pam' driver");
      sftp_kbdint_unregister_driver("pam");
      return 0;
    }
  }

  c = find_config(main_server->conf, CONF_PARAM, "SFTPPAMServiceName", FALSE);
  if (c != NULL) {
    sftppam_service = c->argv[0];
  }

  pr_trace_msg(trace_channel, 8, "using PAM service name '%s'",
    sftppam_service);

  return 0;
}
Beispiel #13
0
static void dynmasq_refresh(void) {
    server_rec *s;

    pr_log_debug(DEBUG2, MOD_DYNMASQ_VERSION
                 ": resolving all MasqueradeAddress directives (could take a little while)");

    for (s = (server_rec *) server_list->xas_list; s; s = s->next) {
        config_rec *c;

        c = find_config(s->conf, CONF_PARAM, "MasqueradeAddress", FALSE);
        if (c != NULL) {
            const char *masq_addr;
            pr_netaddr_t *na;

            masq_addr = c->argv[1];

            pr_netaddr_clear_ipcache(masq_addr);
            na = pr_netaddr_get_addr(s->pool, masq_addr, NULL);
            if (na != NULL) {
                /* Compare the obtained netaddr with the one already present.
                 * Only update the "live" netaddr if they differ.
                 */
                pr_log_debug(DEBUG2, MOD_DYNMASQ_VERSION
                             ": resolved MasqueradeAddress '%s' to IP address %s", masq_addr,
                             pr_netaddr_get_ipstr(na));

                if (pr_netaddr_cmp(c->argv[0], na) != 0) {
                    pr_log_pri(PR_LOG_DEBUG, MOD_DYNMASQ_VERSION
                               ": MasqueradeAddress '%s' updated for new address %s (was %s)",
                               masq_addr, pr_netaddr_get_ipstr(na),
                               pr_netaddr_get_ipstr(c->argv[0]));

                    /* Overwrite the old netaddr pointer.  Note that this constitutes
                     * a minor memory leak, as there currently isn't a way to free
                     * the memory used by a netaddr object.  Hrm.
                     */
                    c->argv[0] = na;

                } else {
                    pr_log_debug(DEBUG2, MOD_DYNMASQ_VERSION
                                 ": MasqueradeAddress '%s' has not changed addresses", masq_addr);
                }

            } else {
                pr_log_pri(PR_LOG_INFO, MOD_DYNMASQ_VERSION
                           ": unable to resolve '%s', keeping previous address", masq_addr);
            }
        }
    }

    return;
}
/* usage: FailureLog path [logfmt-name] */
MODRET set_failurelog(cmd_rec *cmd) {
  config_rec *c;
  const char *path;
  char *log_fmt = NULL;

  if (cmd->argc < 2 ||
      cmd->argc > 3) {
    CONF_ERROR(cmd, "wrong number of parameters");
  }

  CHECK_CONF(cmd, CONF_ROOT|CONF_VIRTUAL|CONF_GLOBAL);

  path = cmd->argv[1];
  if (*path != '/') {
    CONF_ERROR(cmd, "must be an absolute path");
  }

  if (cmd->argc == 3) {
    const char *fmt_name;

    fmt_name = cmd->argv[2];

    /* Double-check that logfmt-name is valid, defined, etc. Look up the
     * format string, and stash a pointer to that in the config_rec (but NOT
     * a copy of the format string; don't need to use that much memory).
     */
    c = find_config(cmd->server->conf, CONF_PARAM, "LogFormat", FALSE);
    while (c != NULL) {
      if (strcmp(c->argv[0], fmt_name) == 0) {
        log_fmt = c->argv[1];
        break;
      }

      log_fmt = NULL;
      c = find_config_next(c, c->next, CONF_PARAM, "LogFormat", FALSE);
    }

    if (log_fmt == NULL) {
      CONF_ERROR(cmd, pstrcat(cmd->tmp_pool, "no such LogFormat '",
        cmd->argv[2], "' configured", NULL));
    }
  }

  c = add_config_param(cmd->argv[0], 2, NULL, NULL);
  c->argv[0] = pstrdup(c->pool, path);
  c->argv[1] = log_fmt;

  return PR_HANDLED(cmd);
}
Beispiel #15
0
int pr_ipbind_add_binds(server_rec *serv) {
  int res = 0;
  config_rec *c = NULL;
  conn_t *listen_conn = NULL;
  const pr_netaddr_t *addr = NULL;

  if (serv == NULL) {
    errno = EINVAL;
    return -1;
  }

  c = find_config(serv->conf, CONF_PARAM, "_bind_", FALSE);
  while (c != NULL) {
    listen_conn = NULL;

    pr_signals_handle();

    addr = pr_netaddr_get_addr(serv->pool, c->argv[0], NULL);
    if (addr == NULL) {
      pr_log_pri(PR_LOG_WARNING,
       "notice: unable to determine IP address of '%s'", (char *) c->argv[0]);
      c = find_config_next(c, c->next, CONF_PARAM, "_bind_", FALSE);
      continue;
    }

    /* If the SocketBindTight directive is in effect, create a separate
     * listen socket for this address, and add it to the binding list.
     */
    if (SocketBindTight &&
        serv->ServerPort) {
      listen_conn = pr_ipbind_get_listening_conn(serv, addr, serv->ServerPort);
      if (listen_conn == NULL) {
        return -1;
      }

      PR_CREATE_IPBIND(serv, addr, serv->ServerPort);
      PR_OPEN_IPBIND(addr, serv->ServerPort, listen_conn, FALSE, FALSE, TRUE);

    } else {

      PR_CREATE_IPBIND(serv, addr, serv->ServerPort);
      PR_OPEN_IPBIND(addr, serv->ServerPort, serv->listen, FALSE, FALSE, TRUE);
    }

    c = find_config_next(c, c->next, CONF_PARAM, "_bind_", FALSE);
  }

  return 0;
}
Beispiel #16
0
static int copy_sess_init(void) {
  config_rec *c;

  c = find_config(main_server->conf, CONF_PARAM, "CopyEngine", FALSE);
  if (c != NULL) {
    copy_engine = *((int *) c->argv[0]);
  }

  if (copy_engine == FALSE) {
    return 0;
  }

  /* Advertise support for the SITE command */
  pr_feat_add("SITE COPY");
  return 0;
}
Beispiel #17
0
const char *proxy_ftp_msg_fmt_addr(pool *p, const pr_netaddr_t *addr,
    unsigned short port, int use_masqaddr) {
  char *addr_str, *msg, *ptr;
  size_t msglen;

  if (p == NULL ||
      addr == NULL) {
    errno = EINVAL;
    return NULL;
  }

  if (use_masqaddr) {
    config_rec *c;

    /* TODO What about TLSMasqueradeAddress? */

    /* Handle MasqueradeAddress. */
    c = find_config(main_server->conf, CONF_PARAM, "MasqueradeAddress", FALSE);
    if (c != NULL) {
      addr = c->argv[0];
    }
  }

  addr_str = pstrdup(p, pr_netaddr_get_ipstr(addr));

  /* Fixup the address string for use in PORT commands/PASV responses. */
  ptr = strrchr(addr_str, ':');
  if (ptr != NULL) {
    addr_str = ptr + 1;
  }

  for (ptr = addr_str; *ptr; ptr++) {
    if (*ptr == '.') {
      *ptr = ',';
    }
  }

  /* Allocate enough room for 6 numbers (3 digits max each), 5 separators,
   * and a trailing NUL.
   */
  msglen = (6 * 3) + (5 * 1) + 1;

  msg = pcalloc(p, msglen);
  snprintf(msg, msglen-1, "%s,%u,%u", addr_str, (port >> 8) & 255, port & 255);

  return msg;
}
Beispiel #18
0
MODRET copy_post_pass(cmd_rec *cmd) {
  config_rec *c;

  if (copy_engine == FALSE) {
    return PR_DECLINED(cmd);
  }

  /* The CopyEngine directive may have been changed for this user by
   * e.g. mod_ifsession, thus we check again.
   */
  c = find_config(main_server->conf, CONF_PARAM, "CopyEngine", FALSE);
  if (c != NULL) {
    copy_engine = *((int *) c->argv[0]);
  }

  return PR_DECLINED(cmd);
}
Beispiel #19
0
void lease_update_from_configs(void)
{
  /* changes to the config may change current leases. */
  
  struct dhcp_lease *lease;
  struct dhcp_config *config;
  char *name;
  
  for (lease = leases; lease; lease = lease->next)
    if (lease->flags & (LEASE_TA | LEASE_NA))
      continue;
    else if ((config = find_config(daemon->dhcp_conf, NULL, lease->clid, lease->clid_len, 
				   lease->hwaddr, lease->hwaddr_len, lease->hwaddr_type, NULL)) && 
	     (config->flags & CONFIG_NAME) &&
	     (!(config->flags & CONFIG_ADDR) || config->addr.s_addr == lease->addr.s_addr))
      lease_set_hostname(lease, config->hostname, 1, get_domain(lease->addr), NULL);
    else if ((name = host_from_dns(lease->addr)))
      lease_set_hostname(lease, name, 1, get_domain(lease->addr), NULL); /* updates auth flag only */
}
Beispiel #20
0
/* Check for a CreateHome directive, and act on it if present.  If not, do
 * nothing.
 */
int create_home(pool *p, const char *home, const char *user, uid_t uid,
    gid_t gid) {
  int res;
  config_rec *c = find_config(main_server->conf, CONF_PARAM, "CreateHome",
    FALSE);

  if (!c || (c && *((unsigned char *) c->argv[0]) == FALSE))
    return 0;

  PRIVS_ROOT

  /* Create the configured path. */
  res = create_path(p, home, user, uid, gid, *((mode_t *) c->argv[2]),
    *((mode_t *) c->argv[1]));

  if (res < 0 && errno != EEXIST) {
    PRIVS_RELINQUISH
    return -1;
  }
Beispiel #21
0
static int forward_dst_filter(pool *p, const char *hostport) {
#ifdef PR_USE_REGEX
  config_rec *c;
  pr_regex_t *pre;
  int negated = FALSE, res;

  c = find_config(main_server->conf, CONF_PARAM, "ProxyForwardTo", FALSE);
  if (c == NULL) {
    return 0;
  }

  pre = c->argv[0];
  negated = *((int *) c->argv[1]);

  res = pr_regexp_exec(pre, hostport, 0, NULL, 0, 0, 0);
  if (res == 0) {
    /* Pattern matched */
    if (negated == TRUE) {
      (void) pr_log_writefile(proxy_logfd, MOD_PROXY_VERSION,
        "host/port '%.100s' matched ProxyForwardTo !%s, rejecting",
        hostport, pr_regexp_get_pattern(pre));

      errno = EPERM;
      return -1;
    }

  } else {
    /* Pattern NOT matched */
    if (negated == FALSE) {
      (void) pr_log_writefile(proxy_logfd, MOD_PROXY_VERSION,
        "host/port '%.100s' did not match ProxyForwardTo %s, rejecting",
        hostport, pr_regexp_get_pattern(pre));
      errno = EPERM;
      return -1;
    }
  }
#endif /* PR_USE_REGEX */
  return 0;
}
MODRET add_lmd_allow_user(cmd_rec *cmd) {
    config_rec *c;
    int i;
    pr_table_t *explicit_users;

    if(cmd->argc < 2)
        CONF_ERROR(cmd, "missing argument");

    CHECK_CONF(cmd, CONF_ROOT|CONF_GLOBAL);

    /* argv => LMDBAllowedUser nobody nobody1 nobody2 */
    c = find_config(main_server->conf, CONF_PARAM, "LMDBAllowedUser", FALSE);
    if(c && c->argv[0]) {
        explicit_users = c->argv[0];
    } else {
        c = add_config_param(cmd->argv[0], 0, NULL);
        c->argv[0] = explicit_users = pr_table_alloc(main_server->pool, 0);
    }

    for(i=1; i < cmd->argc; i++) {
        const char *account = pstrdup(main_server->pool, cmd->argv[i]);
        if(pr_table_exists(explicit_users, account) > 0) {
            pr_log_debug(DEBUG2,
                "%s: %s is already registerd", MODULE_NAME, account);
            continue;
        }

        if(pr_table_add_dup(explicit_users, account, "y", 0) < 0){
            pr_log_pri(PR_LOG_ERR,
                "%s: failed pr_table_add_dup(): %s",
                 MODULE_NAME, strerror(errno));
            exit(1);
        }
        pr_log_debug(DEBUG2,
            "%s: add LMDBAllowedUser[%d] %s", MODULE_NAME, i, account);
    }

    return PR_HANDLED(cmd);
}
Beispiel #23
0
static int qos_sess_init(void) {
#ifdef IP_TOS
  config_rec *c;

  c = find_config(main_server->conf, CONF_PARAM, "QoSOptions", FALSE);
  if (c) {
    int dataqos;

    dataqos = *((int *) c->argv[1]);
    if (dataqos != 0) {
      pr_event_register(&qos_module, "core.data-connect", qos_data_connect_ev,
        NULL);
      pr_event_register(&qos_module, "core.data-listen", qos_data_listen_ev,
        NULL);
    }
  }
#endif

  pr_event_register(&qos_module, "core.session-reinit", qos_sess_reinit_ev,
    NULL);

  return 0;
}
MODRET add_lmd_allow_user_regex(cmd_rec *cmd) {
    array_header *list;
    pr_regex_t *pre;
    int i, res;
    config_rec *c;

    if(cmd->argc < 2)
        CONF_ERROR(cmd, "missing argument");
    CHECK_CONF(cmd, CONF_ROOT|CONF_GLOBAL);

    /* argv => LMDBAllowUserRegex ^test */
    c = find_config(cmd->server->conf, CONF_PARAM, "LMDBAllowedUserRegex", FALSE);
    if(c && c->argv[0]) {
        list = c->argv[0];
    } else {
        c = add_config_param(cmd->argv[0], 0, NULL);
        c->argv[0] = list = make_array(cmd->server->pool, 0, sizeof(regex_t *));
    }

    for(i=1; i < cmd->argc; i++) {
        pre = pr_regexp_alloc(&libmemcached_deny_blacklist_module);
        res = pr_regexp_compile(pre, cmd->argv[i], REG_NOSUB);
        if (res != 0) {
            char errstr[200] = {'\0'};
            pr_regexp_error(res, pre, errstr, sizeof(errstr));
            pr_regexp_free(NULL, pre);
            CONF_ERROR(cmd, pstrcat(cmd->tmp_pool, "'", cmd->argv[i], "' failed "
               "regex compilation: ", errstr, NULL));
        }
        *((pr_regex_t **) push_array(list)) = pre;
        pr_log_debug(DEBUG2,
            "%s: add LMDBAllowedUserRegex[%d] %s", MODULE_NAME, i, cmd->argv[i]);
    }

    return PR_HANDLED(cmd);
}
Beispiel #25
0
static void load_widgets_tab(unsigned char tidx)
{
  struct widget_config cfg;
  struct widget_state s;
  struct widget **w, **r;
  unsigned char tab = tab_list[tidx+1];

  /* disable refresh interrupt */
  EIMSK &= ~_BV(INT0);
  /* wait until lock is released */
  if (nlock == 0)
    goto locked;

  max7456_clr();

  w = all_widgets;
  r = rlist;
  do {
    find_config(tab, (*w)->id, &cfg);
    if (cfg.tab != 0xff) {
      s.props = WIDGET_ENABLED | WIDGET_INIT;
      s.x = cfg.x;
      s.y = cfg.y;
      *r++ = *w;
      (*w)->do_state(&s);
    }
  } while ((*++w) != NULL);
  *r = NULL;

  rwid = rlist;
  current_tidx = tidx;
locked:
  /* re-enable interrupt if we have at least 1 widget to render */
  if ((*rwid) != NULL)
    EIMSK |= _BV(INT0);
}
Beispiel #26
0
/* Check for a CreateHome directive, and act on it if present.  If not, do
 * nothing.
 */
int create_home(pool *p, const char *home, const char *user, uid_t uid,
    gid_t gid) {
  int res;
  config_rec *c;
  mode_t dir_mode, dst_mode;
  uid_t dir_uid, dst_uid;
  gid_t dir_gid, dst_gid, home_gid;

  c = find_config(main_server->conf, CONF_PARAM, "CreateHome", FALSE);
  if (c == NULL ||
      (c && *((unsigned char *) c->argv[0]) == FALSE)) {
    return 0;
  }

  /* Create the configured path. */

  dir_uid = *((uid_t *) c->argv[4]);
  dir_gid = *((gid_t *) c->argv[5]);
  dir_mode = *((mode_t *) c->argv[2]);
  home_gid = *((gid_t *) c->argv[6]);

  dst_uid = uid;
  dst_gid = (home_gid == -1) ? gid : home_gid;

  dst_mode = *((mode_t *) c->argv[1]);

  PRIVS_ROOT

  res = create_path(p, home, user, dir_uid, dir_gid, dir_mode,
    dst_uid, dst_gid, dst_mode);

  if (res < 0 &&
      errno != EEXIST) {
    PRIVS_RELINQUISH
    return -1;
  }
Beispiel #27
0
MODRET wrap_handle_request(cmd_rec *cmd) {

  /* these variables are names expected to be set by the TCP wrapper code
   */
  struct request_info request;

  char *user = NULL;
  config_rec *conf = NULL, *access_conf = NULL, *syslog_conf = NULL;
  hosts_allow_table = NULL;
  hosts_deny_table = NULL;

  /* hide passwords */
  session.hide_password = TRUE;

  /* Sneaky...found in mod_auth.c's cmd_pass() function.  Need to find the
   * login UID in order to resolve the possibly-login-dependent filename.
   */
  user = (char *) get_param_ptr(cmd->server->conf, C_USER, FALSE);

  /* It's possible that a PASS command came before USER.  This is a PRE_CMD
   * handler, so it won't be protected from this case; we'll need to do
   * it manually.
   */
  if (!user)
    return DECLINED(cmd);

  /* Use mod_auth's _auth_resolve_user() [imported for use here] to get the
   * right configuration set, since the user may be logging in anonymously,
   * and the session struct hasn't yet been set for that yet (thus short-
   * circuiting the easiest way to get the right context...the macros.
   */
  conf = wrap_resolve_user(cmd->pool, &user);

  /* Search first for user-specific access files.  Multiple TCPUserAccessFiles
   * directives are allowed.
   */
  if ((access_conf = find_config(conf ? conf->subset : CURRENT_CONF, CONF_PARAM,
      "TCPUserAccessFiles", FALSE)) != NULL) {
    int matched = FALSE;
    array_header *user_array = NULL;

    while (access_conf) {

      user_array = make_array(cmd->tmp_pool, 0, sizeof(char *));
      *((char **) push_array(user_array)) = pstrdup(cmd->tmp_pool, user);

      /* Check the user expression -- don't forget the offset, to skip
       * the access file name strings in argv
       */
      if (wrap_eval_expression(((char **) access_conf->argv) + 2,
          user_array)) {
        pr_log_debug(DEBUG4, MOD_WRAP_VERSION
          ": matched TCPUserAccessFiles expression");
        matched = TRUE;
        break;
      }

      access_conf = find_config_next(access_conf, access_conf->next,
        CONF_PARAM, "TCPUserAccessFiles", FALSE);
    }

    if (!matched)
      access_conf = NULL;
  }

  /* Next, search for group-specific access files.  Multiple
   * TCPGroupAccessFiles directives are allowed.
   */ 
  if (!access_conf && (access_conf = find_config(conf ? conf->subset :
        CURRENT_CONF, CONF_PARAM, "TCPGroupAccessFiles", FALSE)) != NULL) {
    unsigned char matched = FALSE;

    /* NOTE: this gid_array is only necessary until Bug#1461 is fixed */
    array_header *gid_array = make_array(cmd->pool, 0, sizeof(gid_t));

    array_header *group_array = make_array(cmd->pool, 0, sizeof(char *));

    while (access_conf) {
      if (pr_auth_getgroups(cmd->pool, user, &gid_array, &group_array) < 1) {
        pr_log_debug(DEBUG3, MOD_WRAP_VERSION
          ": no supplemental groups found for user '%s'", user);

      } else {

        /* Check the group expression -- don't forget the offset, to skip
         * the access file names strings in argv
         */
        if (wrap_eval_expression(((char **) access_conf->argv) + 2,
            group_array)) {
          pr_log_debug(DEBUG4, MOD_WRAP_VERSION
            ": matched TCPGroupAccessFiles expression");
          matched = TRUE;
          break;
        }
      }

      access_conf = find_config_next(access_conf, access_conf->next,
        CONF_PARAM, "TCPGroupAccessFiles", FALSE);
    }

    if (!matched)
      access_conf = NULL;
  }

  /* Finally for globally-applicable access files.  Only one such directive
   * is allowed.
   */
  if (!access_conf) {
    access_conf = find_config(conf ? conf->subset : CURRENT_CONF,
      CONF_PARAM, "TCPAccessFiles", FALSE);
  }

  if (access_conf) {
    hosts_allow_table = (char *) access_conf->argv[0];
    hosts_deny_table = (char *) access_conf->argv[1];
  }

  /* Now, check the retrieved filename, and see if it requires a login-time
   * file.
   */
  if (hosts_allow_table != NULL && hosts_allow_table[0] == '~' &&
      hosts_allow_table[1] == '/') {
    char *allow_real_table = NULL;

    allow_real_table = wrap_get_user_table(cmd, user, hosts_allow_table);

    if (!wrap_is_usable_file(allow_real_table)) {
      pr_log_pri(PR_LOG_WARNING, MOD_WRAP_VERSION
        ": configured TCPAllowFile %s is unusable", hosts_allow_table);
      hosts_allow_table = NULL;

    } else
      hosts_allow_table = allow_real_table;
  }

  if (hosts_deny_table != NULL && hosts_deny_table[0] == '~' &&
      hosts_deny_table[1] == '/') {
    char *deny_real_table = NULL;

    deny_real_table = dir_realpath(cmd->pool, hosts_deny_table);

    if (!wrap_is_usable_file(deny_real_table)) {
      pr_log_pri(PR_LOG_WARNING, MOD_WRAP_VERSION
        ": configured TCPDenyFile %s is unusable", hosts_deny_table);
      hosts_deny_table = NULL;

    } else 
      hosts_deny_table = deny_real_table;
  }

  /* Make sure that _both_ allow and deny TCPAccessFiles are present.
   * If not, log the missing file, and by default allow request to succeed.
   */
  if (hosts_allow_table != NULL && hosts_deny_table != NULL) {

    /* Most common case...nothing more necessary */

  } else if (hosts_allow_table == NULL && hosts_deny_table != NULL) {

    /* Log the missing file */
    pr_log_pri(PR_LOG_INFO, MOD_WRAP_VERSION ": no usable allow access file -- "
      "allowing connection");

    return DECLINED(cmd);

  } else if (hosts_allow_table != NULL && hosts_deny_table == NULL) {

    /* log the missing file */
    pr_log_pri(PR_LOG_INFO, MOD_WRAP_VERSION ": no usable deny access file -- "
      "allowing connection");

    return DECLINED(cmd);

  } else {

    /* Neither set -- assume the admin hasn't configured these directives
     * at all.
     */
    return DECLINED(cmd);
  }

  /* Log the names of the allow/deny files being used. */
  pr_log_pri(PR_LOG_DEBUG, MOD_WRAP_VERSION ": using access files: %s, %s",
    hosts_allow_table, hosts_deny_table);

  /* retrieve the user-defined syslog priorities, if any.  Fall back to the
   * defaults as seen in tcpd.h if not defined.
   */
  syslog_conf = find_config(main_server->conf, CONF_PARAM,
    "TCPAccessSyslogLevels", FALSE);

  if (syslog_conf) {
    allow_severity = (int) syslog_conf->argv[1];
    deny_severity = (int) syslog_conf->argv[2];

  } else {

    allow_severity = PR_LOG_INFO;
    deny_severity = PR_LOG_WARNING;
  }

  pr_log_debug(DEBUG4, MOD_WRAP_VERSION ": checking under service name '%s'",
    wrap_service_name);
  request_init(&request, RQ_DAEMON, wrap_service_name, RQ_FILE,
    session.c->rfd, 0);

  fromhost(&request);

  if (STR_EQ(eval_hostname(request.client), paranoid) ||
      !hosts_access(&request)) {
    char *denymsg = NULL;

    /* log the denied connection */
    wrap_log_request_denied(deny_severity, &request);

    /* check for AccessDenyMsg */
    if ((denymsg = (char *) get_param_ptr(TOPLEVEL_CONF, "AccessDenyMsg",
        FALSE)) != NULL)
      denymsg = sreplace(cmd->tmp_pool, denymsg, "%u", user, NULL);

    if (denymsg)
      return ERROR_MSG(cmd, R_530, denymsg);
    else
      return ERROR_MSG(cmd, R_530, "Access denied.");
  }

  /* If request is allowable, return DECLINED (for engine to act as if this
   * handler was never called, else ERROR (for engine to abort processing and
   * deny request.
   */
  wrap_log_request_allowed(allow_severity, &request);

  return DECLINED(cmd);
}
Beispiel #28
0
const char *proxy_ftp_msg_fmt_ext_addr(pool *p, const pr_netaddr_t *addr,
    unsigned short port, int cmd_id, int use_masqaddr) {
  const char *addr_str;
  char delim = '|', *msg;
  int family = 0;
  size_t addr_strlen, msglen;

  if (p == NULL ||
      addr == NULL) {
    errno = EINVAL;
    return NULL;
  }

  if (use_masqaddr) {
    config_rec *c;

    /* Handle MasqueradeAddress. */
    c = find_config(main_server->conf, CONF_PARAM, "MasqueradeAddress", FALSE);
    if (c != NULL) {
      addr = c->argv[0];
    }
  }

  /* Format is <d>proto<d>ip address<d>port<d> (ASCII in network order),
   * where <d> is an arbitrary delimiter character.
   */

  switch (pr_netaddr_get_family(addr)) {
    case AF_INET:
      family = 1;
      break;

#ifdef PR_USE_IPV6
    case AF_INET6:
      family = 2;
      break;
#endif /* PR_USE_IPV6 */

    default:
      /* Unlikely to happen. */
      errno = EINVAL;
      return NULL;
  }

  addr_str = pr_netaddr_get_ipstr(addr);
  addr_strlen = strlen(addr_str);

  /* 4 delimiters, the network protocol, the IP address, the port, and a NUL. */
  msglen = (4 * 1) + addr_strlen + 6 + 1;

  msg = pcalloc(p, msglen);
  switch (cmd_id) {
    case PR_CMD_EPRT_ID:
      snprintf(msg, msglen, "%c%d%c%s%c%hu%c", delim, family, delim,
        addr_str, delim, port, delim);
      break;

    case PR_CMD_EPSV_ID:
      snprintf(msg, msglen-1, "%c%c%c%u%c", delim, delim, delim, port, delim);
      break;

    default:
      pr_trace_msg(trace_channel, 3, "invalid/unsupported command ID: %d",
        cmd_id);
      errno = EINVAL;
      return NULL;
  }

  return msg;
}
Beispiel #29
0
/* yet more plagiarizing...this one raided from mod_auth's _auth_resolve_user()
 * function [in case you haven't noticed yet, I'm quite the hack, in the
 * _true_ sense of the world]. =) hmmm...I wonder if it'd be feasible
 * to make some of mod_auth's functions visible from src/auth.c?
 */
static config_rec *wrap_resolve_user(pool *pool, char **user) {
  config_rec *conf = NULL, *top_conf;
  char *ourname = NULL, *anonname = NULL;
  unsigned char is_alias = FALSE, force_anon = FALSE;

  /* Precendence rules:
   *   1. Search for UserAlias directive.
   *   2. Search for Anonymous directive.
   *   3. Normal user login
   */

  ourname = (char*) get_param_ptr(main_server->conf, "UserName", FALSE);

  conf = find_config(main_server->conf, CONF_PARAM, "UserAlias", TRUE);

  if (conf) do {
    if (!strcmp(conf->argv[0], "*") || !strcmp(conf->argv[0], *user)) {
      is_alias = TRUE;
      break;
    } 

  } while ((conf = find_config_next(conf, conf->next, CONF_PARAM,
    "UserAlias", TRUE)) != NULL);

  /* if AuthAliasOnly is set, ignore this one and continue */
  top_conf = conf;

  while (conf && conf->parent &&
      find_config(conf->parent->set, CONF_PARAM, "AuthAliasOnly", FALSE)) {

    is_alias = FALSE;
    find_config_set_top(top_conf);
    conf = find_config_next(conf, conf->next, CONF_PARAM, "UserAlias", TRUE);

    if (conf && (!strcmp(conf->argv[0], "*") || !strcmp(conf->argv[0], *user)))
      is_alias = TRUE;
  }

  if (conf) {
    *user = conf->argv[1];

    /* If the alias is applied inside an <Anonymous> context, we have found
     * our anon block
     */
    if (conf->parent && conf->parent->config_type == CONF_ANON)
      conf = conf->parent;
    else
      conf = NULL;
  }

  /* Next, search for an anonymous entry */
  if (!conf)
    conf = find_config(main_server->conf, CONF_ANON, NULL, FALSE);

  else
    find_config_set_top(conf);

  if (conf) do {
    anonname = (char*) get_param_ptr(conf->subset, "UserName", FALSE);

    if (!anonname)
      anonname = ourname;

    if (anonname && !strcmp(anonname, *user)) {
       break;
    }

  } while ((conf = find_config_next(conf, conf->next, CONF_ANON, NULL,
    FALSE)) != NULL);

  if (!is_alias && !force_anon) {

    if (find_config((conf ? conf->subset :
        main_server->conf), CONF_PARAM, "AuthAliasOnly", FALSE)) {

      if (conf && conf->config_type == CONF_ANON)
        conf = NULL;

      else
        *user = NULL;

      if (*user && find_config(main_server->conf, CONF_PARAM, "AuthAliasOnly",
          FALSE))
        *user = NULL;
    }
  }

  return conf;
}
MODRET counter_stor(cmd_rec *cmd) {
  config_rec *c;
  int res;
  pr_fh_t *fh;
  const char *path;

  if (counter_engine == FALSE) {
    return PR_DECLINED(cmd);
  }

  c = find_config(CURRENT_CONF, CONF_PARAM, "CounterMaxWriters", FALSE);
  counter_max_writers = c ? *((int *) c->argv[0]) : COUNTER_DEFAULT_MAX_WRITERS;

  if (counter_max_writers == 0) {
    return PR_DECLINED(cmd);
  }

  path = pr_table_get(cmd->notes, "mod_xfer.store-path", NULL);
  if (path == NULL) {
    return PR_DECLINED(cmd);
  }

  /* Note that for purposes of our semaphores, we need to use the absolute
   * path.
   */
  counter_curr_path = counter_abs_path(cmd->pool, path, FALSE);

  fh = counter_get_fh(cmd->tmp_pool, counter_curr_path);
  if (fh == NULL) {
    (void) pr_log_writefile(counter_logfd, MOD_COUNTER_VERSION,
      "%s: no CounterFile found for path '%s'", (char *) cmd->argv[0],
      counter_curr_path);

    /* No CounterFile configured/available for this path. */
    return PR_DECLINED(cmd);
  }

  counter_curr_semid = counter_get_sem(fh, counter_curr_path);
  if (counter_curr_semid < 0) {
    (void) pr_log_writefile(counter_logfd, MOD_COUNTER_VERSION,
      "unable to get semaphore for '%s': %s", counter_curr_path,
      strerror(errno));
    return PR_DECLINED(cmd);
  }

  /* Add a writer to this file by decrementing the writer counter value.
   * This functions as a sort of "lock".
   */
  res = counter_add_writer(counter_curr_semid);
  if (res < 0 &&
      errno == EAGAIN) {
  
    /* The lock acquisition failed, which means the file is busy.
     * The upload should be failed.
     */
    (void) pr_log_writefile(counter_logfd, MOD_COUNTER_VERSION,
      "%s: max number of writers (%d) reached for '%s'", (char *) cmd->argv[0],
      counter_max_writers, counter_curr_path);
    pr_response_add_err(R_450, _("%s: File busy"), cmd->arg);
    return PR_ERROR(cmd);
  }

  counter_pending |= COUNTER_HAVE_WRITER;
  (void) pr_log_writefile(counter_logfd, MOD_COUNTER_VERSION,
    "%s: added writer counter for '%s' (semaphore ID %d)",
    (char *) cmd->argv[0], counter_curr_path, counter_curr_semid);

  return PR_DECLINED(cmd);
}