summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRay Strode <rstrode@redhat.com>2011-03-17 14:26:36 -0400
committerRay Strode <rstrode@redhat.com>2011-03-17 14:26:36 -0400
commitfdb2cbeafce21c9b79f7617706360bc3a87d72f3 (patch)
treea2d90e8587ef0bd0e0cce6d2e019722d73977023
parentc3c6e990defdeb72bf1a4f58b20075e2a4372241 (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.c68
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,