diff options
author | Ray Strode <rstrode@redhat.com> | 2011-03-17 14:26:36 -0400 |
---|---|---|
committer | Ray Strode <rstrode@redhat.com> | 2011-03-17 14:26:36 -0400 |
commit | fdb2cbeafce21c9b79f7617706360bc3a87d72f3 (patch) | |
tree | a2d90e8587ef0bd0e0cce6d2e019722d73977023 | |
parent | c3c6e990defdeb72bf1a4f58b20075e2a4372241 (diff) |
daemon: read minimal uid from login.defs
Different distros have different minimal uids.
This commit grabs it from login.defs.
https://bugs.freedesktop.org/show_bug.cgi?id=34893
-rw-r--r-- | src/daemon.c | 68 |
1 files changed, 64 insertions, 4 deletions
diff --git a/src/daemon.c b/src/daemon.c index 10925f5..94aab39 100644 --- a/src/daemon.c +++ b/src/daemon.c @@ -30,6 +30,8 @@ #include <pwd.h> #include <unistd.h> #include <errno.h> +#include <unistd.h> +#include <sys/types.h> #include <glib.h> #include <glib/gi18n.h> @@ -46,7 +48,11 @@ #define PATH_PASSWD "/etc/passwd" #define PATH_SHADOW "/etc/shadow" -#define MINIMAL_UID 500 +#define PATH_LOGIN_DEFS "/etc/login.defs" + +#ifndef FALLBACK_MINIMAL_UID +#define FALLBACK_MINIMAL_UID 500 +#endif #define USERDIR LOCALSTATEDIR "/lib/AccountsService/users" @@ -93,6 +99,7 @@ struct DaemonPrivate { GHashTable *users; GHashTable *exclusions; + uid_t minimal_uid; User *autologin; @@ -216,7 +223,7 @@ daemon_class_init (DaemonClass *klass) static gboolean user_is_excluded (Daemon *daemon, const gchar *username, uid_t uid) { - if (uid < MINIMAL_UID) { + if (uid < daemon->priv->minimal_uid) { return TRUE; } if (g_hash_table_lookup (daemon->priv->exclusions, username)) { @@ -337,8 +344,7 @@ process_ck_history_line (Daemon *daemon, return; } - /* pass MINIMAL_UID to just check the name here */ - if (user_is_excluded (daemon, username, MINIMAL_UID)) { + if (user_is_excluded (daemon, username, daemon->priv->minimal_uid)) { g_debug ("excluding user '%s'", username); g_free (username); return; @@ -658,6 +664,59 @@ on_passwd_monitor_changed (GFileMonitor *monitor, reload_users (daemon); } +static uid_t +get_minimal_uid (void) +{ + GError *error; + char *contents; + gboolean contents_loaded; + const char *uid_min_string, *start_of_uid_string; + char *end; + uid_t uid = FALLBACK_MINIMAL_UID; + guint64 uid_as_number; + + error = NULL; + contents = NULL; + contents_loaded = g_file_get_contents (PATH_LOGIN_DEFS, &contents, NULL, &error); + if (!contents_loaded) { + g_debug ("unable to read " PATH_LOGIN_DEFS ": %s", error->message); + g_error_free (error); + goto out; + } + + uid_min_string = strstr (contents, "UID_MIN"); + + if (uid_min_string == NULL || + (uid_min_string != contents && uid_min_string[-1] != '\n')) { + g_debug (PATH_LOGIN_DEFS " does not have a UID_MIN field"); + goto out; + } + + start_of_uid_string = uid_min_string + strlen ("UID_MIN"); + + if (start_of_uid_string == '\0') { + g_debug (PATH_LOGIN_DEFS " contains UID_MIN key with no value"); + goto out; + } + + + uid_as_number = g_ascii_strtoll (start_of_uid_string, &end, 10); + if (!g_ascii_isspace (*end) && *end != '\0') { + g_debug (PATH_LOGIN_DEFS " contains non-numerical value for UID_MIN"); + goto out; + } + + if (uid_as_number < 0 || ((uid_t) uid_as_number) != uid_as_number) { + g_debug (PATH_LOGIN_DEFS " contains out-of-range value for UID_MIN"); + goto out; + } + + uid = (uid_t) uid_as_number; +out: + g_free (contents); + return uid; +} + static void daemon_init (Daemon *daemon) { @@ -667,6 +726,7 @@ daemon_init (Daemon *daemon) daemon->priv = DAEMON_GET_PRIVATE (daemon); + daemon->priv->minimal_uid = get_minimal_uid (); daemon->priv->exclusions = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, |