aboutsummaryrefslogtreecommitdiff
path: root/tun.c
diff options
context:
space:
mode:
authorjames <james@e7ae566f-a301-0410-adde-c780ea21d3b5>2008-01-21 19:34:13 +0000
committerjames <james@e7ae566f-a301-0410-adde-c780ea21d3b5>2008-01-21 19:34:13 +0000
commit0aee9ca7e76887fb5752c15ef63bfb7a356df06e (patch)
treebd7db9d2c4e4ef4d2cedfdef961208ebd680c2f0 /tun.c
parentRewrote extract_x509_field and modified COMMON_NAME_CHAR_CLASS (diff)
downloadopenvpn-0aee9ca7e76887fb5752c15ef63bfb7a356df06e.tar.xz
Allow OpenVPN to run completely unprivileged under Linux
by allowing openvpn --mktun to be used with --user and --group to set the UID/GID of the tun device node. Also added --iproute option to allow an alternative command to be executed in place of the default iproute2 command (Alon Bar-Lev). git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@2639 e7ae566f-a301-0410-adde-c780ea21d3b5
Diffstat (limited to 'tun.c')
-rw-r--r--tun.c56
1 files changed, 52 insertions, 4 deletions
diff --git a/tun.c b/tun.c
index 8c8616a..3a740bf 100644
--- a/tun.c
+++ b/tun.c
@@ -577,7 +577,8 @@ do_ifconfig (struct tuntap *tt,
* Set the MTU for the device
*/
openvpn_snprintf (command_line, sizeof (command_line),
- IPROUTE_PATH " link set dev %s up mtu %d",
+ "%s link set dev %s up mtu %d",
+ iproute_path,
actual,
tun_mtu
);
@@ -590,7 +591,8 @@ do_ifconfig (struct tuntap *tt,
* Set the address for the device
*/
openvpn_snprintf (command_line, sizeof (command_line),
- IPROUTE_PATH " addr add dev %s local %s peer %s",
+ "%s addr add dev %s local %s peer %s",
+ iproute_path,
actual,
ifconfig_local,
ifconfig_remote_netmask
@@ -599,7 +601,8 @@ do_ifconfig (struct tuntap *tt,
system_check (command_line, es, S_FATAL, "Linux ip addr add failed");
} else {
openvpn_snprintf (command_line, sizeof (command_line),
- IPROUTE_PATH " addr add dev %s %s/%d broadcast %s",
+ "%s addr add dev %s %s/%d broadcast %s",
+ iproute_path,
actual,
ifconfig_local,
count_netmask_bits(ifconfig_remote_netmask),
@@ -1162,8 +1165,20 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6
#ifdef TUNSETPERSIST
+/*
+ * This can be removed in future
+ * when all systems will use newer
+ * linux-headers
+ */
+#ifndef TUNSETOWNER
+#define TUNSETOWNER _IOW('T', 204, int)
+#endif
+#ifndef TUNSETGROUP
+#define TUNSETGROUP _IOW('T', 206, int)
+#endif
+
void
-tuncfg (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, int persist_mode, const struct tuntap_options *options)
+tuncfg (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, int persist_mode, const char *username, const char *groupname, const struct tuntap_options *options)
{
struct tuntap *tt;
@@ -1174,6 +1189,26 @@ tuncfg (const char *dev, const char *dev_type, const char *dev_node, bool ipv6,
open_tun (dev, dev_type, dev_node, ipv6, tt);
if (ioctl (tt->fd, TUNSETPERSIST, persist_mode) < 0)
msg (M_ERR, "Cannot ioctl TUNSETPERSIST(%d) %s", persist_mode, dev);
+ if (username != NULL)
+ {
+ struct user_state user_state;
+
+ if (!get_user (username, &user_state))
+ msg (M_ERR, "Cannot get user entry for %s", username);
+ else
+ if (ioctl (tt->fd, TUNSETOWNER, user_state.pw->pw_uid) < 0)
+ msg (M_ERR, "Cannot ioctl TUNSETOWNER(%s) %s", username, dev);
+ }
+ if (groupname != NULL)
+ {
+ struct group_state group_state;
+
+ if (!get_group (groupname, &group_state))
+ msg (M_ERR, "Cannot get group entry for %s", groupname);
+ else
+ if (ioctl (tt->fd, TUNSETGROUP, group_state.gr->gr_gid) < 0)
+ msg (M_ERR, "Cannot ioctl TUNSETOWNER(%s) %s", groupname, dev);
+ }
close_tun (tt);
msg (M_INFO, "Persist state set to: %s", (persist_mode ? "ON" : "OFF"));
}
@@ -1185,6 +1220,19 @@ close_tun (struct tuntap *tt)
{
if (tt)
{
+#ifdef CONFIG_FEATURE_IPROUTE
+ char command_line[256];
+ /*
+ * Flush IP configuration for the device
+ */
+ openvpn_snprintf (command_line, sizeof (command_line),
+ "%s addr flush dev %s",
+ iproute_path,
+ tt->actual_name
+ );
+ msg (M_INFO, "%s", command_line);
+ system_check (command_line, NULL, S_FATAL, "Linux ip flush failed");
+#endif
close_tun_generic (tt);
free (tt);
}