mirror of
https://gitlab.com/openconnect/ocserv.git
synced 2026-02-10 00:37:00 +08:00
Supplementary group/user configuration is now modular.
That will ease the addition of other backends that can be used to read the user/group configuration. The only backend supported now is file.
This commit is contained in:
@@ -63,7 +63,7 @@ COMMON_SOURCES=common.c common.h system.c system.h setproctitle.c setproctitle.h
|
||||
AUTH_SOURCES=auth/pam.c auth/pam.h auth/plain.c auth/plain.h
|
||||
|
||||
ocserv_SOURCES = main.c main-auth.c worker-vpn.c worker-auth.c tlslib.c \
|
||||
cookies.c main-misc.c group-config.c ip-lease.c ip-lease.h \
|
||||
cookies.c main-misc.c ip-lease.c ip-lease.h \
|
||||
vpn.h cookies.h tlslib.h log.c tun.c tun.h \
|
||||
config.c worker-resume.c worker.h main-resume.c main.h \
|
||||
worker-extras.c main-auth.h html.c html.h \
|
||||
@@ -71,6 +71,8 @@ ocserv_SOURCES = main.c main-auth.c worker-vpn.c worker-auth.c tlslib.c \
|
||||
sec-mod.c sec-mod-db.c sec-mod-auth.c sec-mod.h sec-mod-ban.c \
|
||||
script-list.h $(COMMON_SOURCES) $(AUTH_SOURCES) \
|
||||
icmp-ping.c icmp-ping.h \
|
||||
main-sup-config.c main-sup-config.h \
|
||||
sup-config/file.c sup-config/file.h \
|
||||
worker-bandwidth.c worker-bandwidth.h ctl.h main-ctl.h \
|
||||
str.c str.h gettime.h $(CCAN_SOURCES) $(HTTP_PARSER_SOURCES) \
|
||||
$(PROTOBUF_SOURCES)
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
#include <ip-lease.h>
|
||||
#include <ipc.pb-c.h>
|
||||
#include <script-list.h>
|
||||
#include <main-sup-config.h>
|
||||
|
||||
#ifdef HAVE_MALLOC_TRIM
|
||||
# include <malloc.h>
|
||||
@@ -136,67 +137,6 @@ int handle_script_exit(main_server_st *s, struct proc_st *proc, int code)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int read_additional_config_file(main_server_st * s, struct proc_st *proc,
|
||||
const char *file, const char *fallback, const char *type)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (access(file, R_OK) == 0) {
|
||||
mslog(s, proc, LOG_DEBUG, "Loading %s configuration '%s'", type,
|
||||
file);
|
||||
|
||||
ret = parse_group_cfg_file(s, proc, file);
|
||||
if (ret < 0)
|
||||
return ERR_READ_CONFIG;
|
||||
} else {
|
||||
if (fallback != NULL) {
|
||||
mslog(s, proc, LOG_DEBUG, "Loading default %s configuration '%s'", type, fallback);
|
||||
|
||||
ret = parse_group_cfg_file(s, proc, fallback);
|
||||
if (ret < 0)
|
||||
return ERR_READ_CONFIG;
|
||||
} else {
|
||||
mslog(s, proc, LOG_DEBUG, "No %s configuration for '%s'", type,
|
||||
proc->username);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int read_additional_config(struct main_server_st *s,
|
||||
struct proc_st *proc)
|
||||
{
|
||||
char file[_POSIX_PATH_MAX];
|
||||
int ret;
|
||||
|
||||
memset(&proc->config, 0, sizeof(proc->config));
|
||||
|
||||
if (s->config->per_group_dir != NULL && proc->groupname[0] != 0) {
|
||||
snprintf(file, sizeof(file), "%s/%s", s->config->per_group_dir,
|
||||
proc->groupname);
|
||||
|
||||
ret = read_additional_config_file(s, proc, file, s->config->default_group_conf, "group");
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (s->config->per_user_dir != NULL) {
|
||||
snprintf(file, sizeof(file), "%s/%s", s->config->per_user_dir,
|
||||
proc->username);
|
||||
|
||||
ret = read_additional_config_file(s, proc, file, s->config->default_user_conf, "user");
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (proc->config.cgroup != NULL) {
|
||||
put_into_cgroup(s, proc->config.cgroup, proc->pid);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct proc_st *new_proc(main_server_st * s, pid_t pid, int cmd_fd,
|
||||
struct sockaddr_storage *remote_addr, socklen_t remote_addr_len,
|
||||
uint8_t *sid, size_t sid_size)
|
||||
@@ -247,7 +187,9 @@ void remove_proc(main_server_st * s, struct proc_st *proc, unsigned k)
|
||||
proc->pid = -1;
|
||||
|
||||
remove_iroutes(s, proc);
|
||||
del_additional_config(&proc->config);
|
||||
if (s->config_module) {
|
||||
s->config_module->clear_sup_config(&proc->config);
|
||||
}
|
||||
|
||||
if (proc->ipv4 || proc->ipv6)
|
||||
remove_ip_leases(s, proc);
|
||||
@@ -272,11 +214,17 @@ static int accept_user(main_server_st * s, struct proc_st *proc, unsigned cmd)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = read_additional_config(s, proc);
|
||||
if (ret < 0) {
|
||||
mslog(s, proc, LOG_ERR,
|
||||
"error reading additional configuration");
|
||||
return ERR_READ_CONFIG;
|
||||
if (s->config_module) {
|
||||
ret = s->config_module->get_sup_config(s->config, proc);
|
||||
if (ret < 0) {
|
||||
mslog(s, proc, LOG_ERR,
|
||||
"error reading additional configuration");
|
||||
return ERR_READ_CONFIG;
|
||||
}
|
||||
|
||||
if (proc->config.cgroup != NULL) {
|
||||
put_into_cgroup(s, proc->config.cgroup, proc->pid);
|
||||
}
|
||||
}
|
||||
|
||||
ret = open_tun(s, proc);
|
||||
|
||||
37
src/main-sup-config.c
Normal file
37
src/main-sup-config.c
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (C) 2013, 2014 Nikos Mavrogiannopoulos
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <vpn.h>
|
||||
#include <cookies.h>
|
||||
#include <tun.h>
|
||||
#include <main.h>
|
||||
#include <common.h>
|
||||
#include <vpn.h>
|
||||
#include <main-sup-config.h>
|
||||
#include <sup-config/file.h>
|
||||
|
||||
void sup_config_init(main_server_st *s)
|
||||
{
|
||||
s->config_module = &file_sup_config;
|
||||
}
|
||||
|
||||
36
src/main-sup-config.h
Normal file
36
src/main-sup-config.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Red Hat
|
||||
*
|
||||
* Author: Nikos Mavrogiannopoulos
|
||||
*
|
||||
* This file is part of ocserv.
|
||||
*
|
||||
* The GnuTLS is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation; either version 2.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
#ifndef SUP_CONFIG_H
|
||||
# define SUP_CONFIG_H
|
||||
|
||||
#include <main.h>
|
||||
|
||||
/* The get_sup_config() should read any additional configuration for
|
||||
* proc->username/proc->groupname and save it in proc->config.
|
||||
*/
|
||||
struct config_mod_st {
|
||||
int (*get_sup_config)(struct cfg_st *global_config, struct proc_st *proc);
|
||||
void (*clear_sup_config)(struct group_cfg_st *out);
|
||||
};
|
||||
|
||||
void sup_config_init(main_server_st *s);
|
||||
|
||||
#endif
|
||||
@@ -49,6 +49,7 @@
|
||||
# include <systemd/sd-daemon.h>
|
||||
#endif
|
||||
#include <main.h>
|
||||
#include <main-sup-config.h>
|
||||
#include <main-ctl.h>
|
||||
#include <route-add.h>
|
||||
#include <main-auth.h>
|
||||
@@ -934,7 +935,7 @@ int main(int argc, char** argv)
|
||||
|
||||
run_sec_mod(s);
|
||||
|
||||
mslog(s, NULL, LOG_INFO, "initialized %s", PACKAGE_STRING);
|
||||
sup_config_init(s);
|
||||
|
||||
ret = ctl_handler_init(s);
|
||||
if (ret < 0) {
|
||||
@@ -942,6 +943,8 @@ int main(int argc, char** argv)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
mslog(s, NULL, LOG_INFO, "initialized %s", PACKAGE_STRING);
|
||||
|
||||
/* chdir to our chroot directory, to allow opening the sec-mod
|
||||
* socket if necessary. */
|
||||
if (s->config->chroot_dir)
|
||||
|
||||
@@ -180,6 +180,7 @@ typedef struct main_server_st {
|
||||
time_t start_time;
|
||||
|
||||
void * auth_extra;
|
||||
struct config_mod_st *config_module;
|
||||
|
||||
#ifdef HAVE_DBUS
|
||||
void * ctl_ctx;
|
||||
@@ -240,10 +241,6 @@ int handle_script_exit(main_server_st *s, struct proc_st* proc, int code);
|
||||
|
||||
void run_sec_mod(main_server_st * s);
|
||||
|
||||
int parse_group_cfg_file(main_server_st* s, struct proc_st *proc, const char* file);
|
||||
|
||||
void del_additional_config(struct group_cfg_st* config);
|
||||
|
||||
struct proc_st *new_proc(main_server_st * s, pid_t pid, int cmd_fd,
|
||||
struct sockaddr_storage *remote_addr, socklen_t remote_addr_len,
|
||||
uint8_t *sid, size_t sid_size);
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
|
||||
#include <vpn.h>
|
||||
#include <main.h>
|
||||
#include <main-sup-config.h>
|
||||
|
||||
struct cfg_options {
|
||||
const char* name;
|
||||
@@ -138,81 +139,142 @@ unsigned j;
|
||||
* config. The provided config must either be memset to zero, or be
|
||||
* already allocated using this function.
|
||||
*/
|
||||
int parse_group_cfg_file(main_server_st* s, struct proc_st *proc, const char* file)
|
||||
static
|
||||
int parse_group_cfg_file(struct cfg_st *global_config, struct proc_st *proc,
|
||||
const char* file)
|
||||
{
|
||||
tOptionValue const * pov;
|
||||
const tOptionValue* val, *prev;
|
||||
unsigned prefix = 0;
|
||||
struct group_cfg_st *config = &proc->config;
|
||||
struct group_cfg_st *sconfig = &proc->config;
|
||||
|
||||
pov = configFileLoad(file);
|
||||
if (pov == NULL) {
|
||||
mslog(s, NULL, LOG_ERR, "Cannot load config file %s", file);
|
||||
syslog(LOG_ERR, "cannot load config file %s", file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
val = optionGetValue(pov, NULL);
|
||||
if (val == NULL) {
|
||||
mslog(s, NULL, LOG_ERR, "No configuration directives found in %s", file);
|
||||
syslog(LOG_ERR, "no configuration directives found in %s", file);
|
||||
optionUnloadNested(pov);
|
||||
return ERR_READ_CONFIG;
|
||||
}
|
||||
|
||||
do {
|
||||
if (handle_option(val) == 0) {
|
||||
mslog(s, NULL, LOG_ERR, "Skipping unknown option '%s' in %s", val->pzName, file);
|
||||
syslog(LOG_ERR, "skipping unknown option '%s' in %s", val->pzName, file);
|
||||
}
|
||||
prev = val;
|
||||
} while((val = optionNextValue(pov, prev)) != NULL);
|
||||
|
||||
READ_TF("no-udp", config->no_udp, (s->config->udp_port!=0)?0:1);
|
||||
READ_TF("no-udp", sconfig->no_udp, (global_config->udp_port!=0)?0:1);
|
||||
|
||||
READ_RAW_MULTI_LINE("route", config->routes, config->routes_size);
|
||||
READ_RAW_MULTI_LINE("iroute", config->iroutes, config->iroutes_size);
|
||||
READ_RAW_MULTI_LINE("route", sconfig->routes, sconfig->routes_size);
|
||||
READ_RAW_MULTI_LINE("iroute", sconfig->iroutes, sconfig->iroutes_size);
|
||||
|
||||
READ_RAW_MULTI_LINE("dns", config->dns, config->dns_size);
|
||||
if (config->dns_size == 0) {
|
||||
READ_RAW_MULTI_LINE("dns", sconfig->dns, sconfig->dns_size);
|
||||
if (sconfig->dns_size == 0) {
|
||||
/* try aliases */
|
||||
READ_RAW_MULTI_LINE("ipv6-dns", config->dns, config->dns_size);
|
||||
READ_RAW_MULTI_LINE("ipv4-dns", config->dns, config->dns_size);
|
||||
READ_RAW_MULTI_LINE("ipv6-dns", sconfig->dns, sconfig->dns_size);
|
||||
READ_RAW_MULTI_LINE("ipv4-dns", sconfig->dns, sconfig->dns_size);
|
||||
}
|
||||
|
||||
READ_RAW_MULTI_LINE("nbns", config->nbns, config->nbns_size);
|
||||
if (config->nbns_size == 0) {
|
||||
READ_RAW_MULTI_LINE("nbns", sconfig->nbns, sconfig->nbns_size);
|
||||
if (sconfig->nbns_size == 0) {
|
||||
/* try aliases */
|
||||
READ_RAW_MULTI_LINE("ipv6-nbns", config->nbns, config->nbns_size);
|
||||
READ_RAW_MULTI_LINE("ipv4-nbns", config->nbns, config->nbns_size);
|
||||
READ_RAW_MULTI_LINE("ipv6-nbns", sconfig->nbns, sconfig->nbns_size);
|
||||
READ_RAW_MULTI_LINE("ipv4-nbns", sconfig->nbns, sconfig->nbns_size);
|
||||
}
|
||||
|
||||
READ_RAW_STRING("cgroup", config->cgroup);
|
||||
READ_RAW_STRING("ipv4-network", config->ipv4_network);
|
||||
READ_RAW_STRING("ipv6-network", config->ipv6_network);
|
||||
READ_RAW_STRING("ipv4-netmask", config->ipv4_netmask);
|
||||
READ_RAW_STRING("cgroup", sconfig->cgroup);
|
||||
READ_RAW_STRING("ipv4-network", sconfig->ipv4_network);
|
||||
READ_RAW_STRING("ipv6-network", sconfig->ipv6_network);
|
||||
READ_RAW_STRING("ipv4-netmask", sconfig->ipv4_netmask);
|
||||
|
||||
READ_RAW_NUMERIC("ipv6-prefix", prefix);
|
||||
if (prefix > 0) {
|
||||
config->ipv6_netmask = ipv6_prefix_to_mask(proc, prefix);
|
||||
config->ipv6_prefix = prefix;
|
||||
sconfig->ipv6_netmask = ipv6_prefix_to_mask(proc, prefix);
|
||||
sconfig->ipv6_prefix = prefix;
|
||||
|
||||
if (config->ipv6_netmask == NULL) {
|
||||
mslog(s, NULL, LOG_ERR, "unknown ipv6-prefix '%u' in %s", prefix, file);
|
||||
if (sconfig->ipv6_netmask == NULL) {
|
||||
syslog(LOG_ERR, "unknown ipv6-prefix '%u' in %s", prefix, file);
|
||||
}
|
||||
}
|
||||
|
||||
READ_RAW_NUMERIC("rx-data-per-sec", config->rx_per_sec);
|
||||
READ_RAW_NUMERIC("tx-data-per-sec", config->tx_per_sec);
|
||||
config->rx_per_sec /= 1000; /* in kb */
|
||||
config->tx_per_sec /= 1000; /* in kb */
|
||||
READ_RAW_NUMERIC("rx-data-per-sec", sconfig->rx_per_sec);
|
||||
READ_RAW_NUMERIC("tx-data-per-sec", sconfig->tx_per_sec);
|
||||
sconfig->rx_per_sec /= 1000; /* in kb */
|
||||
sconfig->tx_per_sec /= 1000; /* in kb */
|
||||
|
||||
/* net-priority will contain the actual priority + 1,
|
||||
* to allow having zero as uninitialized. */
|
||||
READ_RAW_PRIO_TOS("net-priority", config->net_priority);
|
||||
READ_RAW_PRIO_TOS("net-priority", sconfig->net_priority);
|
||||
|
||||
optionUnloadNested(pov);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void del_additional_config(struct group_cfg_st* config)
|
||||
static int read_sup_config_file(struct cfg_st *global_config, struct proc_st *proc,
|
||||
const char *file, const char *fallback, const char *type)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (access(file, R_OK) == 0) {
|
||||
syslog(LOG_DEBUG, "Loading %s configuration '%s'", type,
|
||||
file);
|
||||
|
||||
ret = parse_group_cfg_file(global_config, proc, file);
|
||||
if (ret < 0)
|
||||
return ERR_READ_CONFIG;
|
||||
} else {
|
||||
if (fallback != NULL) {
|
||||
syslog(LOG_DEBUG, "Loading default %s configuration '%s'", type, fallback);
|
||||
|
||||
ret = parse_group_cfg_file(global_config, proc, fallback);
|
||||
if (ret < 0)
|
||||
return ERR_READ_CONFIG;
|
||||
} else {
|
||||
syslog(LOG_DEBUG, "No %s configuration for '%s'", type,
|
||||
proc->username);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_sup_config(struct cfg_st *global_config, struct proc_st *proc)
|
||||
{
|
||||
char file[_POSIX_PATH_MAX];
|
||||
int ret;
|
||||
|
||||
memset(&proc->config, 0, sizeof(proc->config));
|
||||
|
||||
if (global_config->per_group_dir != NULL && proc->groupname[0] != 0) {
|
||||
snprintf(file, sizeof(file), "%s/%s", global_config->per_group_dir,
|
||||
proc->groupname);
|
||||
|
||||
ret = read_sup_config_file(global_config, proc, file, global_config->default_group_conf, "group");
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (global_config->per_user_dir != NULL) {
|
||||
snprintf(file, sizeof(file), "%s/%s", global_config->per_user_dir,
|
||||
proc->username);
|
||||
|
||||
ret = read_sup_config_file(global_config, proc, file, global_config->default_user_conf, "user");
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
void clear_sup_config(struct group_cfg_st* config)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
@@ -243,3 +305,8 @@ unsigned i;
|
||||
talloc_free(config->ipv6_netmask);
|
||||
safe_memset(config, 0, sizeof(*config));
|
||||
}
|
||||
|
||||
struct config_mod_st file_sup_config = {
|
||||
.get_sup_config = get_sup_config,
|
||||
.clear_sup_config = clear_sup_config,
|
||||
};
|
||||
28
src/sup-config/file.h
Normal file
28
src/sup-config/file.h
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Red Hat
|
||||
*
|
||||
* Author: Nikos Mavrogiannopoulos
|
||||
*
|
||||
* This file is part of ocserv.
|
||||
*
|
||||
* The GnuTLS is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation; either version 2.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
#ifndef SUP_CONFIG_FILE_H
|
||||
#define SUP_CONFIG_FILE_H
|
||||
|
||||
#include <main-sup-config.h>
|
||||
|
||||
extern struct config_mod_st file_sup_config;
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user