user-util.c revision d02608170e599b1ffbc7c9a22062bae2579d6e36
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.
Copyright 2010 Lennart Poettering
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
systemd is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#include <pwd.h>
#include <grp.h>
#include "user-util.h"
#include "macro.h"
#include "util.h"
#include "string-util.h"
#include "path-util.h"
/* Some libc APIs use UID_INVALID as special placeholder */
return false;
/* A long time ago UIDs where 16bit, hence explicitly avoid the 16bit -1 too */
return false;
return true;
}
int r;
assert(s);
r = safe_atou32(s, &uid);
if (r < 0)
return r;
if (!uid_is_valid(uid))
return -ENXIO; /* we return ENXIO instead of EINVAL
* here, to make it easy to distuingish
* invalid numeric uids invalid
* strings. */
if (ret)
return 0;
}
char* getlogname_malloc(void) {
else
return uid_to_name(uid);
}
char *getusername_malloc(void) {
const char *e;
e = getenv("USER");
if (e)
return strdup(e);
return uid_to_name(getuid());
}
int get_user_creds(
const char **username,
const char **home,
const char **shell) {
struct passwd *p;
uid_t u;
/* We enforce some special rules for uid=0: in order to avoid
* NSS lookups for root we hardcode its data. */
*username = "root";
if (uid)
*uid = 0;
if (gid)
*gid = 0;
if (home)
*home = "/root";
if (shell)
return 0;
}
errno = 0;
p = getpwuid(u);
/* If there are multiple users with the same id, make
* sure to leave $USER to the configured value instead
* of the first occurrence in the database. However if
* the uid was configured by a numeric uid, then let's
if (p)
} else {
errno = 0;
}
if (!p)
if (uid)
if (gid)
if (home)
if (shell)
return 0;
}
struct group *g;
/* We enforce some special rules for gid=0: in order to avoid
* NSS lookups for root we hardcode its data. */
*groupname = "root";
if (gid)
*gid = 0;
return 0;
}
errno = 0;
if (g)
} else {
errno = 0;
}
if (!g)
if (gid)
return 0;
}
char *ret;
int r;
/* Shortcut things to avoid NSS lookups */
if (uid == 0)
return strdup("root");
if (uid_is_valid(uid)) {
long bufsize;
if (bufsize <= 0)
bufsize = 4096;
for (;;) {
if (!buf)
return NULL;
if (r == 0 && pw)
if (r != ERANGE)
break;
bufsize *= 2;
}
}
return NULL;
return ret;
}
char *ret;
int r;
if (gid == 0)
return strdup("root");
if (gid_is_valid(gid)) {
long bufsize;
if (bufsize <= 0)
bufsize = 4096;
for (;;) {
if (!buf)
return NULL;
if (r == 0 && gr)
if (r != ERANGE)
break;
bufsize *= 2;
}
}
return NULL;
return ret;
}
int ngroups_max, r, i;
return 1;
return 1;
assert(ngroups_max > 0);
if (r < 0)
return -errno;
for (i = 0; i < r; i++)
return 1;
return 0;
}
int r;
if (r < 0)
return r;
}
int get_home_dir(char **_h) {
struct passwd *p;
const char *e;
char *h;
uid_t u;
/* Take the user specified one */
e = secure_getenv("HOME");
if (e && path_is_absolute(e)) {
h = strdup(e);
if (!h)
return -ENOMEM;
*_h = h;
return 0;
}
/* Hardcode home directory for root to avoid NSS */
u = getuid();
if (u == 0) {
h = strdup("/root");
if (!h)
return -ENOMEM;
*_h = h;
return 0;
}
/* Check the database... */
errno = 0;
p = getpwuid(u);
if (!p)
if (!path_is_absolute(p->pw_dir))
return -EINVAL;
if (!h)
return -ENOMEM;
*_h = h;
return 0;
}
struct passwd *p;
const char *e;
char *s;
uid_t u;
/* 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) {
if (!s)
return -ENOMEM;
*_s = s;
return 0;
}
/* Check the database... */
errno = 0;
p = getpwuid(u);
if (!p)
if (!path_is_absolute(p->pw_shell))
return -EINVAL;
if (!s)
return -ENOMEM;
*_s = s;
return 0;
}
int reset_uid_gid(void) {
return -errno;
if (setresgid(0, 0, 0) < 0)
return -errno;
if (setresuid(0, 0, 0) < 0)
return -errno;
return 0;
}