diff options
author | james | 2008-01-21 19:34:13 +0000 |
---|---|---|
committer | james | 2008-01-21 19:34:13 +0000 |
commit | 0aee9ca7e76887fb5752c15ef63bfb7a356df06e (patch) | |
tree | bd7db9d2c4e4ef4d2cedfdef961208ebd680c2f0 /tun.c | |
parent | 7686b1c407f8e78d24669971219f9bc253521744 (diff) | |
download | openvpn-0aee9ca7e76887fb5752c15ef63bfb7a356df06e.zip openvpn-0aee9ca7e76887fb5752c15ef63bfb7a356df06e.tar.gz |
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.c | 56 |
1 files changed, 52 insertions, 4 deletions
@@ -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); } |