svn commit: r218048 - head/sbin/hastd
Pawel Jakub Dawidek
pjd at FreeBSD.org
Fri Jan 28 22:33:48 UTC 2011
Author: pjd
Date: Fri Jan 28 22:33:47 2011
New Revision: 218048
URL: http://svn.freebsd.org/changeset/base/218048
Log:
Implement function that drops privileges by:
- chrooting to /var/empty (user hast home directory),
- setting groups to 'hast' (user hast primary group),
- setting real group id, effective group id and saved group id to 'hast',
- setting real user id, effective user id and saved user id to 'hast'.
At the end verify that those operations where successfull.
MFC after: 1 week
Modified:
head/sbin/hastd/hast.h
head/sbin/hastd/subr.c
head/sbin/hastd/subr.h
Modified: head/sbin/hastd/hast.h
==============================================================================
--- head/sbin/hastd/hast.h Fri Jan 28 22:29:38 2011 (r218047)
+++ head/sbin/hastd/hast.h Fri Jan 28 22:33:47 2011 (r218048)
@@ -81,6 +81,7 @@
#define HIO_FLUSH 4
#define HIO_KEEPALIVE 5
+#define HAST_USER "hast"
#define HAST_TIMEOUT 5
#define HAST_CONFIG "/etc/hast.conf"
#define HAST_CONTROL "/var/run/hastctl"
Modified: head/sbin/hastd/subr.c
==============================================================================
--- head/sbin/hastd/subr.c Fri Jan 28 22:29:38 2011 (r218047)
+++ head/sbin/hastd/subr.c Fri Jan 28 22:33:47 2011 (r218048)
@@ -38,6 +38,8 @@ __FBSDID("$FreeBSD$");
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
+#include <pwd.h>
+#include <unistd.h>
#include <pjdlog.h>
@@ -116,3 +118,73 @@ role2str(int role)
}
return ("unknown");
}
+
+int
+drop_privs(void)
+{
+ struct passwd *pw;
+ uid_t ruid, euid, suid;
+ gid_t rgid, egid, sgid;
+ gid_t gidset[1];
+
+ /*
+ * According to getpwnam(3) we have to clear errno before calling the
+ * function to be able to distinguish between an error and missing
+ * entry (with is not treated as error by getpwnam(3)).
+ */
+ errno = 0;
+ pw = getpwnam(HAST_USER);
+ if (pw == NULL) {
+ if (errno != 0) {
+ KEEP_ERRNO(pjdlog_errno(LOG_ERR,
+ "Unable to find info about '%s' user", HAST_USER));
+ return (-1);
+ } else {
+ pjdlog_error("'%s' user doesn't exist.", HAST_USER);
+ errno = ENOENT;
+ return (-1);
+ }
+ }
+ if (chroot(pw->pw_dir) == -1) {
+ KEEP_ERRNO(pjdlog_errno(LOG_ERR,
+ "Unable to change root directory to %s", pw->pw_dir));
+ return (-1);
+ }
+ PJDLOG_VERIFY(chdir("/") == 0);
+ gidset[0] = pw->pw_gid;
+ if (setgroups(1, gidset) == -1) {
+ KEEP_ERRNO(pjdlog_errno(LOG_ERR,
+ "Unable to set groups to gid %u",
+ (unsigned int)pw->pw_gid));
+ return (-1);
+ }
+ if (setgid(pw->pw_gid) == -1) {
+ KEEP_ERRNO(pjdlog_errno(LOG_ERR, "Unable to set gid to %u",
+ (unsigned int)pw->pw_gid));
+ return (-1);
+ }
+ if (setuid(pw->pw_uid) == -1) {
+ KEEP_ERRNO(pjdlog_errno(LOG_ERR, "Unable to set uid to %u",
+ (unsigned int)pw->pw_uid));
+ return (-1);
+ }
+
+ /*
+ * Better be sure that everything succeeded.
+ */
+ PJDLOG_VERIFY(getresuid(&ruid, &euid, &suid) == 0);
+ PJDLOG_VERIFY(ruid == pw->pw_uid);
+ PJDLOG_VERIFY(euid == pw->pw_uid);
+ PJDLOG_VERIFY(suid == pw->pw_uid);
+ PJDLOG_VERIFY(getresgid(&rgid, &egid, &sgid) == 0);
+ PJDLOG_VERIFY(rgid == pw->pw_gid);
+ PJDLOG_VERIFY(egid == pw->pw_gid);
+ PJDLOG_VERIFY(sgid == pw->pw_gid);
+ PJDLOG_VERIFY(getgroups(0, NULL) == 1);
+ PJDLOG_VERIFY(getgroups(1, gidset) == 1);
+ PJDLOG_VERIFY(gidset[0] == pw->pw_gid);
+
+ pjdlog_info("Privileges successfully dropped.");
+
+ return (0);
+}
Modified: head/sbin/hastd/subr.h
==============================================================================
--- head/sbin/hastd/subr.h Fri Jan 28 22:29:38 2011 (r218047)
+++ head/sbin/hastd/subr.h Fri Jan 28 22:33:47 2011 (r218048)
@@ -47,5 +47,6 @@
int provinfo(struct hast_resource *res, bool dowrite);
const char *role2str(int role);
+int drop_privs(void);
#endif /* !_SUBR_H_ */
More information about the svn-src-all
mailing list