X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fshared%2Futil.c;h=c396fc7c6d4ccdbee1ea35f2239f059053034130;hb=4faa70046ca0c1775c8e231179716a78cf3291b1;hp=66276aa54e3925aa6c21225bd39f71a6616de4ec;hpb=bc9fd78c7bfc39881e19457e476393635f8b0442;p=elogind.git diff --git a/src/shared/util.c b/src/shared/util.c index 66276aa54..c396fc7c6 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -4936,15 +4936,15 @@ int fd_inc_sndbuf(int fd, size_t n) { socklen_t l = sizeof(value); r = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, &l); - if (r >= 0 && - l == sizeof(value) && - (size_t) value >= n*2) + if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2) return 0; + /* If we have the privileges we will ignore the kernel limit. */ + value = (int) n; - r = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, sizeof(value)); - if (r < 0) - return -errno; + if (setsockopt(fd, SOL_SOCKET, SO_SNDBUFFORCE, &value, sizeof(value)) < 0) + if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, sizeof(value)) < 0) + return -errno; return 1; } @@ -4954,16 +4954,15 @@ int fd_inc_rcvbuf(int fd, size_t n) { socklen_t l = sizeof(value); r = getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, &l); - if (r >= 0 && - l == sizeof(value) && - (size_t) value >= n*2) + if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2) return 0; - value = (int) n; - r = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, sizeof(value)); - if (r < 0) - return -errno; + /* If we have the privileges we will ignore the kernel limit. */ + value = (int) n; + if (setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, &value, sizeof(value)) < 0) + if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, sizeof(value)) < 0) + return -errno; return 1; } @@ -5220,10 +5219,10 @@ int make_console_stdio(void) { } int get_home_dir(char **_h) { - char *h; + struct passwd *p; const char *e; + char *h; uid_t u; - struct passwd *p; assert(_h); @@ -5266,6 +5265,53 @@ int get_home_dir(char **_h) { return 0; } +int get_shell(char **_s) { + struct passwd *p; + const char *e; + char *s; + uid_t u; + + assert(_s); + + /* Take the user specified one */ + e = getenv("SHELL"); + if (e) { + s = strdup(e); + if (!s) + return -ENOMEM; + + *_s = s; + return 0; + } + + /* Hardcode home directory for root to avoid NSS */ + u = getuid(); + if (u == 0) { + s = strdup("/bin/sh"); + if (!s) + return -ENOMEM; + + *_s = s; + return 0; + } + + /* Check the database... */ + errno = 0; + p = getpwuid(u); + if (!p) + return errno > 0 ? -errno : -ESRCH; + + if (!path_is_absolute(p->pw_shell)) + return -EINVAL; + + s = strdup(p->pw_shell); + if (!s) + return -ENOMEM; + + *_s = s; + return 0; +} + bool filename_is_safe(const char *p) { if (isempty(p)) @@ -6022,5 +6068,11 @@ int namespace_enter(int namespace_fd, int root_fd) { if (chroot(".") < 0) return -errno; + if (setresgid(0, 0, 0) < 0) + return -errno; + + if (setresuid(0, 0, 0) < 0) + return -errno; + return 0; }