user-util.c revision b5efdb8af40ea759a1ea584c1bc44ecc81dd00ce
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen This file is part of systemd.
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen Copyright 2010 Lennart Poettering
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen systemd is free software; you can redistribute it and/or modify it
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen under the terms of the GNU Lesser General Public License as published by
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen the Free Software Foundation; either version 2.1 of the License, or
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen (at your option) any later version.
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen systemd is distributed in the hope that it will be useful, but
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen WITHOUT ANY WARRANTY; without even the implied warranty of
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen Lesser General Public License for more details.
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen You should have received a copy of the GNU Lesser General Public License
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen along with systemd; If not, see <http://www.gnu.org/licenses/>.
682265d5e2157882861b0091c6b81fa92699b72aTom Gundersen /* Some libc APIs use UID_INVALID as special placeholder */
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen return false;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen /* A long time ago UIDs where 16bit, hence explicitly avoid the 16bit -1 too */
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen return false;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringint parse_uid(const char *s, uid_t *ret) {
a5a807e63a50314e190e9166d8a453cd8dd258e3Zbigniew Jędrzejewski-Szmek assert_cc(sizeof(uid_t) == sizeof(uint32_t));
682265d5e2157882861b0091c6b81fa92699b72aTom Gundersen return -ENXIO; /* we return ENXIO instead of EINVAL
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt * here, to make it easy to distuingish
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering * invalid numeric uids invalid
682265d5e2157882861b0091c6b81fa92699b72aTom Gundersen * strings. */
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen if (isatty(STDIN_FILENO) && fstat(STDIN_FILENO, &st) >= 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering const char *e;
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering const char **shell) {
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen /* We enforce some special rules for uid=0: in order to avoid
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt * NSS lookups for root we hardcode its data. */
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen if (streq(*username, "root") || streq(*username, "0")) {
if (shell)
errno = 0;
p = getpwuid(u);
errno = 0;
if (uid) {
return -EBADMSG;
if (gid) {
return -EBADMSG;
if (home)
if (shell)
struct group *g;
if (gid)
*gid = 0;
errno = 0;
errno = 0;
if (gid) {
return -EBADMSG;
char *ret;
if (uid == 0)
long bufsize;
if (bufsize <= 0)
if (!buf)
return NULL;
if (r == 0 && pw)
if (r != ERANGE)
return NULL;
return ret;
char *ret;
if (gid == 0)
long bufsize;
if (bufsize <= 0)
if (!buf)
return NULL;
if (r == 0 && gr)
if (r != ERANGE)
return NULL;
return ret;
int ngroups_max, r, i;
return -EINVAL;
return -errno;
struct passwd *p;
uid_t u;
if (e && path_is_absolute(e)) {
h = strdup(e);
return -ENOMEM;
*_h = h;
u = getuid();
return -ENOMEM;
*_h = h;
errno = 0;
p = getpwuid(u);
return -EINVAL;
return -ENOMEM;
*_h = h;
struct passwd *p;
uid_t u;
s = strdup(e);
return -ENOMEM;
*_s = s;
u = getuid();
return -ENOMEM;
*_s = s;
errno = 0;
p = getpwuid(u);
return -EINVAL;
return -ENOMEM;
*_s = s;
int reset_uid_gid(void) {
return -errno;
if (setresgid(0, 0, 0) < 0)
return -errno;
if (setresuid(0, 0, 0) < 0)
return -errno;
.l_start = 0,
.l_len = 0,
const char *path;
int fd, r;
if (root)
if (fd < 0)
return -errno;
return -errno;
return fd;