Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- tntnet-2.2.1-allUserGroups.patch : this is a backport of tntnet improvement "When doing setuid(), optionally also pick up supplementary groups of that user" posted by me in PR https://github.com/maekitalo/tntnet/pull/52 so this can be applied to the current release tarball.
- Copyright (C) Nov 2016 by Jim Klimov <EvgenyKlimov@eaton.com>
- diff -Naur tntnet-2.2.1.orig/configure.in tntnet-2.2.1/configure.in
- --- tntnet-2.2.1.orig/configure.in 2014-01-17 20:07:21.000000000 +0100
- +++ tntnet-2.2.1/configure.in 2016-11-10 20:53:55.805453772 +0100
- @@ -41,6 +41,30 @@
- AC_CHECK_FUNCS([fopen64], ,[AM_CFLAGS=-DUSE_FILE32API])
- AC_SUBST(AM_CFLAGS)
- +AC_MSG_CHECKING([if system provides getgrouplist() with semantics we expect])
- +AC_COMPILE_IFELSE(
- + [AC_LANG_SOURCE([
- +#include <grp.h>
- +#include <pwd.h>
- +struct passwd pw;
- +gid_t groups;
- +int foundgroups = 1;
- +int gotgroups = getgrouplist("username", pw.pw_gid, &groups, &foundgroups);
- +])], AC_DEFINE(HAVE_GETGROUPLIST, [1], [Defined if system provides getgrouplist() with semantics we expect])
- + AC_MSG_RESULT([yes]), AC_MSG_RESULT([no]))
- +
- +AC_MSG_CHECKING([if system provides setgroups() with semantics we expect])
- +AC_COMPILE_IFELSE(
- + [AC_LANG_SOURCE([
- +#include <sys/types.h>
- +#include <unistd.h>
- +#include <grp.h>
- +#include <pwd.h>
- +gid_t groups;
- +int errcode = setgroups(1, &groups);
- +])], AC_DEFINE(HAVE_SETGROUPS, [1], [Defined if system provides setgroups() with semantics we expect])
- + AC_MSG_RESULT([yes]), AC_MSG_RESULT([no]))
- +
- AC_ARG_WITH([epoll],
- AS_HELP_STRING([--with-epoll=yes|no|probe], [use epoll]),
- [epoll_option=$withval],
- diff -Naur tntnet-2.2.1.orig/doc/man/tntnet.xml.7 tntnet-2.2.1/doc/man/tntnet.xml.7
- --- tntnet-2.2.1.orig/doc/man/tntnet.xml.7 2014-01-17 20:07:21.000000000 +0100
- +++ tntnet-2.2.1/doc/man/tntnet.xml.7 2016-11-10 20:53:55.805453772 +0100
- @@ -32,4 +32,12 @@
- .RE
- .PP
- +\fB\fC<allUserGroups>\fR\fIyes|no\fP\fB\fC</allUserGroups>\fR
- +.IP
- +Specifies that if the \fI<user>\fP is changed for the server process, then the
- +groups (primary and secondary) which this account is a member of should
- +become the primary GID and supplementary GIDs of this process too.
- +.IP
- +The legacy default value is \fIno\fP - to avoid surprises during upgrades.
- +.PP
- \fB\fC<bufferSize>\fR\fIbytes\fP\fB\fC</bufferSize>\fR
- .IP
- diff -Naur tntnet-2.2.1.orig/framework/common/tnt/tntconfig.h tntnet-2.2.1/framework/common/tnt/tntconfig.h
- --- tntnet-2.2.1.orig/framework/common/tnt/tntconfig.h 2014-01-17 20:07:21.000000000 +0100
- +++ tntnet-2.2.1/framework/common/tnt/tntconfig.h 2016-11-10 20:53:55.806364580 +0100
- @@ -81,6 +81,7 @@
- unsigned maxRequestSize;
- unsigned maxRequestTime;
- std::string user;
- + bool allUserGroups;
- std::string group;
- std::string dir;
- std::string chrootdir;
- diff -Naur tntnet-2.2.1.orig/framework/common/tntconfig.cpp tntnet-2.2.1/framework/common/tntconfig.cpp
- --- tntnet-2.2.1.orig/framework/common/tntconfig.cpp 2014-01-17 20:07:21.000000000 +0100
- +++ tntnet-2.2.1/framework/common/tntconfig.cpp 2016-11-10 20:53:55.806725535 +0100
- @@ -112,6 +112,7 @@
- si.getMember("maxRequestSize", config.maxRequestSize);
- si.getMember("maxRequestTime", config.maxRequestTime);
- si.getMember("user", config.user);
- + si.getMember("allUserGroups", config.allUserGroups);
- si.getMember("group", config.group);
- si.getMember("dir", config.dir);
- si.getMember("chrootdir", config.chrootdir);
- @@ -217,6 +217,7 @@ namespace tnt
- TntConfig::TntConfig()
- : maxRequestSize(0),
- maxRequestTime(600),
- + allUserGroups(false),
- daemon(false),
- minThreads(5),
- maxThreads(100),
- diff -Naur tntnet-2.2.1.orig/framework/runtime/process.cpp tntnet-2.2.1/framework/runtime/process.cpp
- --- tntnet-2.2.1.orig/framework/runtime/process.cpp 2013-12-26 19:11:56.000000000 +0100
- +++ tntnet-2.2.1/framework/runtime/process.cpp 2016-11-10 20:53:55.807163455 +0100
- @@ -27,6 +27,7 @@
- */
- +#include "config.h"
- #include "tnt/process.h"
- #include "tnt/tntconfig.h"
- #include <cxxtools/systemerror.h>
- @@ -72,12 +72,104 @@
- throw cxxtools::SystemError("setgid");
- }
- +#if (HAVE_GETGROUPLIST != 1)
- +// Code below snatched from https://gist.github.com/bhaskarvk/6a15083ab9a7997df0a2
- +#include <string.h>
- +int
- +getgrouplist(const char *uname, gid_t agroup, gid_t *groups, int *grpcnt)
- +{
- + const struct group *grp;
- + int i, maxgroups, ngroups, ret;
- +
- + ret = 0;
- + ngroups = 0;
- + maxgroups = *grpcnt;
- + /*
- + * When installing primary group, duplicate it;
- + * the first element of groups is the effective gid
- + * and will be overwritten when a setgid file is executed.
- + */
- + groups ? groups[ngroups++] = agroup : ngroups++;
- + if (maxgroups > 1)
- + groups ? groups[ngroups++] = agroup : ngroups++;
- + /*
- + * Scan the group file to find additional groups.
- + */
- + setgrent();
- + while ((grp = getgrent()) != NULL) {
- + if (groups) {
- + for (i = 0; i < ngroups; i++) {
- + if (grp->gr_gid == groups[i])
- + goto skip;
- + }
- + }
- + for (i = 0; grp->gr_mem[i]; i++) {
- + if (!strcmp(grp->gr_mem[i], uname)) {
- + if (ngroups >= maxgroups) {
- + ret = -1;
- + break;
- + }
- + groups ? groups[ngroups++] = grp->gr_gid : ngroups++;
- + break;
- + }
- + }
- +skip:
- + ;
- + }
- + endgrent();
- + *grpcnt = ngroups;
- + return (ret);
- +}
- +#define HAVE_GETGROUPLIST 1
- +#endif // no HAVE_GETGROUPLIST
- +
- - void setUser(const std::string& user)
- + void setUser(const std::string& user, bool allUserGroups)
- {
- struct passwd * pw = getpwnam(user.c_str());
- if (pw == 0)
- throw std::runtime_error("unknown user " + user);
- + if (allUserGroups)
- + {
- +#if (HAVE_GETGROUPLIST == 1) && (HAVE_SETGROUPS == 1)
- + std::stringstream message;
- + int ngroups = 0;
- + int foundgroups = 0;
- + int foundgroups2 = 0;
- + gid_t tmp_group;
- + ngroups = getgrouplist(user.c_str(), pw->pw_gid, &tmp_group, &foundgroups);
- + if (foundgroups > 0) {
- + gid_t *groups = (gid_t *)malloc(foundgroups * sizeof(gid_t));
- + if (groups != NULL) {
- + foundgroups2 = foundgroups;
- + ngroups = getgrouplist(user.c_str(), pw->pw_gid, groups, &foundgroups);
- + if ( ngroups > 0 && ngroups == foundgroups && foundgroups2 == foundgroups ) {
- + log_debug("set " << ngroups << " supplementary groups of user " << user << '(' << pw->pw_uid << ')');
- + setgroups (ngroups, groups);
- + } else {
- + message << "could not getgrouplist() second time: retrieved " << ngroups << ", found " << foundgroups << ", earlier found " << foundgroups2;
- + //throw std::runtime_error(message.str());
- + log_error(message.str());
- + }
- + free(groups);
- + } else {
- + message << "could not malloc for " << foundgroups << " supplementary groups";
- + // throw std::runtime_error( message.str() );
- + log_error(message.str());
- + // throw std::runtime_error(message.str());
- + log_error(message.str());
- + }
- +#else
- + // throw std::runtime_error("allUserGroups was requested, but support was not compiled in on this platform");
- + log_error("allUserGroups was requested, but support was not compiled in on this platform");
- +#endif
- + } else {
- + log_debug("allUserGroups not requested, so not setting supplementary groups of user " << user << '(' << pw->pw_uid << ')');
- + }
- +
- log_debug("change user to " << user << '(' << pw->pw_uid << ')');
- int ret = ::setuid(pw->pw_uid);
- @@ -85,6 +100,15 @@
- throw cxxtools::SystemError("getuid");
- }
- +#ifdef __GNUC__
- + // Function with legacy signature is not directly used here now
- + void setUser(const std::string& user) __attribute__ ((unused)) ;
- +#endif
- + void setUser(const std::string& user)
- + {
- + setUser(user, false);
- + }
- +
- void setDir(const std::string& dir)
- {
- log_debug("chdir(" << dir << ')');
- @@ -289,7 +308,7 @@
- if (!tnt::TntConfig::it().user.empty())
- {
- log_debug("set user to \"" << tnt::TntConfig::it().user << '"');
- - ::setUser(tnt::TntConfig::it().user);
- + ::setUser(tnt::TntConfig::it().user, tnt::TntConfig::it().allUserGroups);
- }
- if (!tnt::TntConfig::it().dir.empty())
- diff -Naur tntnet-2.2.1.orig/sdk/demos/controls/tntnet.xml tntnet-2.2.1/sdk/demos/controls/tntnet.xml
- --- tntnet-2.2.1.orig/sdk/demos/controls/tntnet.xml 2014-01-17 20:08:24.000000000 +0100
- +++ tntnet-2.2.1/sdk/demos/controls/tntnet.xml 2016-11-10 20:53:55.807455155 +0100
- @@ -57,6 +57,7 @@
- <!-- <maxRequestSize>65536</maxRequestSize> -->
- <!-- <maxRequestTime>600</maxRequestTime> -->
- <!-- <user>tntnet</user> -->
- + <!-- <allUserGroups>no</allUserGroups> -->
- <!-- <group>tntnet</group> -->
- <!-- <dir>/</dir> -->
- <!-- <chrootdir>/var/safedir</chrootdir> -->
- diff -Naur tntnet-2.2.1.orig/tntnet-conf2xml.pl tntnet-2.2.1/tntnet-conf2xml.pl
- --- tntnet-2.2.1.orig/tntnet-conf2xml.pl 2013-12-26 15:08:34.000000000 +0100
- +++ tntnet-2.2.1/tntnet-conf2xml.pl 2016-11-10 20:53:55.807753679 +0100
- @@ -21,6 +21,7 @@
- MaxRequestSize => 'maxRequestSize',
- MaxRequestTime => 'maxRequestTime',
- User => 'user',
- + AllUserGroups => 'allUserGroups',
- Group => 'group',
- Dir => 'dir',
- Chroot => 'chrootdir',
Add Comment
Please, Sign In to add comment