You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

147 lines
3.3 KiB

  1. --- /dev/null
  2. +++ b/modules/droproot.cpp
  3. @@ -0,0 +1,144 @@
  4. +/*
  5. + * droproot.cpp
  6. + *
  7. + * Copyright (c) 2009 Vadtec (vadtec@vadtec.net)
  8. + * This program is free software; you can redistribute it and/or modify it
  9. + * under the terms of the GNU General Public License version 2 as published
  10. + * by the Free Software Foundation.
  11. + *
  12. + * Copyright (C) 2004-2012 See the AUTHORS file for details.
  13. + *
  14. + * This program is free software; you can redistribute it and/or modify it
  15. + * under the terms of the GNU General Public License version 2 as published
  16. + * by the Free Software Foundation.
  17. + */
  18. +
  19. +#include <znc/znc.h>
  20. +#include <znc/User.h>
  21. +#include <pwd.h>
  22. +#include <grp.h>
  23. +
  24. +class CDroproot : public CModule {
  25. +
  26. +public:
  27. + MODCONSTRUCTOR(CDroproot) {
  28. + }
  29. +
  30. + virtual ~CDroproot() {
  31. + }
  32. +
  33. + uid_t GetUser(const CString& sUser, CString& sMessage) {
  34. + uid_t ret = sUser.ToUInt();
  35. +
  36. + if (ret != 0)
  37. + return ret;
  38. +
  39. + struct passwd *pUser = getpwnam(sUser.c_str());
  40. +
  41. + if (!pUser) {
  42. + sMessage = "User [" + sUser + "] not found!";
  43. + return 0;
  44. + }
  45. +
  46. + return pUser->pw_uid;
  47. + }
  48. +
  49. + gid_t GetGroup(const CString& sGroup, CString& sMessage) {
  50. + gid_t ret = sGroup.ToUInt();
  51. +
  52. + if (ret != 0)
  53. + return ret;
  54. +
  55. + struct group *pGroup = getgrnam(sGroup.c_str());
  56. +
  57. + if (!pGroup) {
  58. + sMessage = "Group [" + sGroup + "] not found!";
  59. + return 0;
  60. + }
  61. +
  62. + return pGroup->gr_gid;
  63. + }
  64. +
  65. + virtual bool OnLoad(const CString& sArgs, CString& sMessage) {
  66. + CString sUser = sArgs.Token(0);
  67. + CString sGroup = sArgs.Token(1, true);
  68. +
  69. + if (sUser.empty() || sGroup.empty()) {
  70. + sMessage = "Usage: LoadModule = Droproot <uid> <gid>";
  71. + return false;
  72. + }
  73. +
  74. + m_user = GetUser(sUser, sMessage);
  75. +
  76. + if (m_user == 0) {
  77. + sMessage
  78. + = "Error: Cannot run as root, check your config file | Usage: LoadModule = Droproot <uid> <gid>";
  79. + return false;
  80. + }
  81. +
  82. + m_group = GetGroup(sGroup, sMessage);
  83. +
  84. + if (m_group == 0) {
  85. + sMessage
  86. + = "Error: Cannot run as root, check your config file | Usage: LoadModule = Droproot <uid> <gid>";
  87. + return false;
  88. + }
  89. +
  90. + return true;
  91. + }
  92. +
  93. + virtual bool OnBoot() {
  94. + int u, eu, g, eg, sg;
  95. +
  96. + if ((geteuid() == 0) || (getuid() == 0) || (getegid() == 0) || (getgid()
  97. + == 0)) {
  98. +
  99. + CUtils::PrintAction("Dropping root permissions");
  100. +
  101. + // Clear all the supplementary groups
  102. + sg = setgroups(0, NULL);
  103. +
  104. + if (sg < 0) {
  105. + CUtils::PrintStatus(false,
  106. + "Could not remove supplementary groups! ["
  107. + + CString(strerror(errno)) + "]");
  108. +
  109. + return false;
  110. + }
  111. +
  112. + // Set the group (if we are root, this sets all three group IDs)
  113. + g = setgid(m_group);
  114. + eg = setegid(m_group);
  115. +
  116. + if ((g < 0) || (eg < 0)) {
  117. + CUtils::PrintStatus(false, "Could not switch group id! ["
  118. + + CString(strerror(errno)) + "]");
  119. +
  120. + return false;
  121. + }
  122. +
  123. + // and set the user (if we are root, this sets all three user IDs)
  124. + u = setuid(m_user);
  125. + eu = seteuid(m_user);
  126. +
  127. + if ((u < 0) || (eu < 0)) {
  128. + CUtils::PrintStatus(false, "Could not switch user id! ["
  129. + + CString(strerror(errno)) + "]");
  130. +
  131. + return false;
  132. + }
  133. +
  134. + CUtils::PrintStatus(true);
  135. +
  136. + return true;
  137. + }
  138. +
  139. + return true;
  140. + }
  141. +
  142. +protected:
  143. + uid_t m_user;
  144. + gid_t m_group;
  145. +};
  146. +
  147. +GLOBALMODULEDEFS(CDroproot, "Allows ZNC to drop root privileges and run as an un-privileged user.")