diff --git a/nixos/modules/misc/ids.nix b/nixos/modules/misc/ids.nix index 853efcc09dc..50903aadd53 100644 --- a/nixos/modules/misc/ids.nix +++ b/nixos/modules/misc/ids.nix @@ -139,6 +139,7 @@ polipo = 129; mopidy = 130; unifi = 131; + gdm = 132; # When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399! @@ -252,6 +253,7 @@ polipo = 129; mopidy = 130; docker = 131; + gdm = 132; # When adding a gid, make sure it doesn't match an existing uid. And don't use gids above 399! diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 4806c0e9331..47aef48418a 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -50,6 +50,7 @@ ./programs/bash/bash.nix ./programs/bash/command-not-found.nix ./programs/blcr.nix + ./programs/dconf.nix ./programs/environment.nix ./programs/info.nix ./programs/screen.nix @@ -279,6 +280,7 @@ ./services/x11/desktop-managers/default.nix ./services/x11/display-managers/auto.nix ./services/x11/display-managers/default.nix + ./services/x11/display-managers/gdm.nix ./services/x11/display-managers/kdm.nix ./services/x11/display-managers/lightdm.nix ./services/x11/display-managers/slim.nix diff --git a/nixos/modules/programs/dconf.nix b/nixos/modules/programs/dconf.nix new file mode 100644 index 00000000000..1b7e2079981 --- /dev/null +++ b/nixos/modules/programs/dconf.nix @@ -0,0 +1,34 @@ +{ config, lib, ... }: + +let + inherit (lib) mkOption mkIf types mapAttrsToList; + cfg = config.programs.dconf; + + mkDconfProfile = name: path: + { source = path; target = "dconf/profile/${name}"; }; + +in +{ + ###### interface + + options = { + programs.dconf = { + + profiles = mkOption { + type = types.attrsOf types.path; + default = {}; + description = "Set of dconf profile files."; + internal = true; + }; + + }; + }; + + ###### implementation + + config = mkIf (cfg.profiles != {}) { + environment.etc = + (mapAttrsToList mkDconfProfile cfg.profiles); + }; + +} diff --git a/nixos/modules/services/x11/display-managers/gdm.nix b/nixos/modules/services/x11/display-managers/gdm.nix new file mode 100644 index 00000000000..9d14fc2e137 --- /dev/null +++ b/nixos/modules/services/x11/display-managers/gdm.nix @@ -0,0 +1,151 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.services.xserver.displayManager; + gdm = pkgs.gnome3_12.gdm; # gdm 3.10 not supported + gnome3 = config.environment.gnome3.packageSet; + +in + +{ + + ###### interface + + options = { + + services.xserver.displayManager.gdm = { + + enable = mkOption { + type = types.bool; + default = false; + example = true; + description = '' + Whether to enable GDM as the display manager. + GDM is very experimental and may render system unusable. + ''; + }; + + }; + + }; + + + ###### implementation + + config = mkIf cfg.gdm.enable { + + services.xserver.displayManager.slim.enable = false; + + users.extraUsers.gdm = + { name = "gdm"; + uid = config.ids.uids.gdm; + group = "gdm"; + home = "/run/gdm"; + description = "GDM user"; + }; + + users.extraGroups.gdm.gid = config.ids.gids.gdm; + + services.xserver.displayManager.job = + { + environment = { + GDM_X_SERVER = "${cfg.xserverBin} ${cfg.xserverArgs}"; + GDM_SESSIONS_DIR = "${cfg.session.desktops}"; + XDG_CONFIG_DIRS = "${gnome3.gnome_settings_daemon}/etc/xdg"; + }; + execCmd = "exec ${gdm}/sbin/gdm"; + }; + + # Because sd_login_monitor_new requires /run/systemd/machines + systemd.services.display-manager.wants = [ "systemd-machined.service" ]; + systemd.services.display-manager.after = [ "systemd-machined.service" ]; + + systemd.services.display-manager.path = [ gnome3.gnome_shell gnome3.caribou ]; + + services.dbus.packages = [ gdm ]; + + programs.dconf.profiles.gdm = "${gdm}/share/dconf/profile/gdm"; + + # GDM LFS PAM modules, adapted somehow to NixOS + security.pam.services = { + gdm-launch-environment.text = '' + auth required pam_succeed_if.so audit quiet_success user = gdm + auth optional pam_permit.so + + account required pam_succeed_if.so audit quiet_success user = gdm + account sufficient pam_unix.so + + password required pam_deny.so + + session required pam_succeed_if.so audit quiet_success user = gdm + session required pam_env.so envfile=${config.system.build.pamEnvironment} + session optional ${pkgs.systemd}/lib/security/pam_systemd.so + session optional pam_keyinit.so force revoke + session optional pam_permit.so + ''; + + gdm.text = '' + auth requisite pam_nologin.so + auth required pam_env.so + + auth required pam_succeed_if.so uid >= 1000 quiet + auth optional ${gnome3.gnome_keyring}/lib/security/pam_gnome_keyring.so + auth sufficient pam_unix.so nullok likeauth + auth required pam_deny.so + + account sufficient pam_unix.so + + password requisite pam_unix.so nullok sha512 + + session required pam_env.so envfile=${config.system.build.pamEnvironment} + session required pam_unix.so + session required pam_loginuid.so + session optional ${pkgs.systemd}/lib/security/pam_systemd.so + session optional ${gnome3.gnome_keyring}/lib/security/pam_gnome_keyring.so auto_start + ''; + + gdm-password.text = '' + auth requisite pam_nologin.so + auth required pam_env.so envfile=${config.system.build.pamEnvironment} + + auth required pam_succeed_if.so uid >= 1000 quiet + auth optional ${gnome3.gnome_keyring}/lib/security/pam_gnome_keyring.so + auth sufficient pam_unix.so nullok likeauth + auth required pam_deny.so + + account sufficient pam_unix.so + + password requisite pam_unix.so nullok sha512 + + session required pam_env.so envfile=${config.system.build.pamEnvironment} + session required pam_unix.so + session required pam_loginuid.so + session optional ${pkgs.systemd}/lib/security/pam_systemd.so + session optional ${gnome3.gnome_keyring}/lib/security/pam_gnome_keyring.so auto_start + ''; + + gdm-autologin.text = '' + auth requisite pam_nologin.so + + auth required pam_succeed_if.so uid >= 1000 quiet + auth required pam_permit.so + + account sufficient pam_unix.so + + password requisite pam_unix.so nullok sha512 + + session optional pam_keyinit.so revoke + session required pam_env.so envfile=${config.system.build.pamEnvironment} + session required pam_unix.so + session required pam_loginuid.so + session optional ${pkgs.systemd}/lib/security/pam_systemd.so + ''; + + }; + + }; + +} diff --git a/pkgs/desktops/gnome-3/3.12/core/gdm/default.nix b/pkgs/desktops/gnome-3/3.12/core/gdm/default.nix index 4e9acc822e7..f5dc7639f3a 100644 --- a/pkgs/desktops/gnome-3/3.12/core/gdm/default.nix +++ b/pkgs/desktops/gnome-3/3.12/core/gdm/default.nix @@ -1,5 +1,6 @@ -{ stdenv, fetchurl, pkgconfig, glib, itstool, libxml2, intltool, accountsservice, libX11 -, gtk, libcanberra_gtk3, pam, libtool, gobjectIntrospection, dconf }: +{ stdenv, fetchurl, pkgconfig, glib, itstool, libxml2, xorg, dbus +, intltool, accountsservice, libX11, gnome3, systemd, gnome_session +, gtk, libcanberra_gtk3, pam, libtool, gobjectIntrospection }: stdenv.mkDerivation rec { name = "gdm-3.12.2"; @@ -9,10 +10,33 @@ stdenv.mkDerivation rec { sha256 = "cc91fff5afd2a7c3e712c960a0b60744774167dcfc16f486372e1eb3c0aa1cc4"; }; - buildInputs = [ pkgconfig glib itstool libxml2 intltool accountsservice dconf - gobjectIntrospection libX11 gtk libcanberra_gtk3 pam libtool ]; + # Only needed to make it build + preConfigure = '' + substituteInPlace ./configure --replace "/usr/bin/X" "${xorg.xorgserver}/bin/X" + ''; + + configureFlags = [ "--localstatedir=/var" "--with-systemd=yes" + "--with-systemdsystemunitdir=$(out)/etc/systemd/system" ]; + + buildInputs = [ pkgconfig glib itstool libxml2 intltool + accountsservice gnome3.dconf systemd + gobjectIntrospection libX11 gtk + libcanberra_gtk3 pam libtool ]; + + enableParallelBuilding = true; + + preBuild = '' + substituteInPlace daemon/gdm-simple-slave.c --replace 'BINDIR "/gnome-session' '"${gnome_session}/bin/gnome-session' + substituteInPlace daemon/gdm-launch-environment.c --replace 'BINDIR "/dbus-launch' '"${dbus.tools}/bin/dbus-launch' + ''; + + # Disable Access Control because our X does not support FamilyServerInterpreted yet + patches = [ ./xserver_path.patch ./sessions_dir.patch ./disable_x_access_control.patch ./propagate_xdgconfigdirs.patch ]; meta = with stdenv.lib; { + homepage = https://wiki.gnome.org/Projects/GDM; + description = "A program that manages graphical display servers and handles graphical user logins"; platforms = platforms.linux; + maintainers = [ maintainers.lethalman ]; }; } diff --git a/pkgs/desktops/gnome-3/3.12/core/gdm/disable_x_access_control.patch b/pkgs/desktops/gnome-3/3.12/core/gdm/disable_x_access_control.patch new file mode 100644 index 00000000000..74d054f8c88 --- /dev/null +++ b/pkgs/desktops/gnome-3/3.12/core/gdm/disable_x_access_control.patch @@ -0,0 +1,18 @@ +diff --git a/daemon/gdm-slave.c b/daemon/gdm-slave.c +index 1afe48e..e3d1ec2 100644 +--- a/daemon/gdm-slave.c ++++ b/daemon/gdm-slave.c +@@ -291,9 +291,10 @@ gdm_slave_connect_to_x11_display (GdmSlave *slave) + + gdm_error_trap_push (); + +- for (i = 0; i < G_N_ELEMENTS (host_entries); i++) { ++ /*for (i = 0; i < G_N_ELEMENTS (host_entries); i++) { + XAddHost (slave->priv->server_display, &host_entries[i]); +- } ++ }*/ ++ XDisableAccessControl(slave->priv->server_display); + + XSync (slave->priv->server_display, False); + if (gdm_error_trap_pop ()) { + diff --git a/pkgs/desktops/gnome-3/3.12/core/gdm/propagate_xdgconfigdirs.patch b/pkgs/desktops/gnome-3/3.12/core/gdm/propagate_xdgconfigdirs.patch new file mode 100644 index 00000000000..20d7659c1e5 --- /dev/null +++ b/pkgs/desktops/gnome-3/3.12/core/gdm/propagate_xdgconfigdirs.patch @@ -0,0 +1,26 @@ +--- a/daemon/gdm-launch-environment.c 2014-08-03 12:05:39.380178964 +0200 ++++ b/daemon/gdm-launch-environment.c 2014-08-03 12:08:26.570182517 +0200 +@@ -224,6 +224,7 @@ + NULL + }; + char *system_data_dirs; ++ char *system_config_dirs; + int i; + + load_lang_config_file (LANG_CONFIG_FILE, +@@ -251,6 +252,15 @@ + system_data_dirs)); + g_free (system_data_dirs); + ++ system_config_dirs = g_strjoinv (":", (char **) g_get_system_config_dirs ()); ++ ++ g_hash_table_insert (hash, ++ g_strdup ("XDG_CONFIG_DIRS"), ++ g_strdup_printf ("%s", ++ system_config_dirs)); ++ g_free (system_config_dirs); ++ ++ + g_hash_table_insert (hash, g_strdup ("XAUTHORITY"), g_strdup (launch_environment->priv->x11_authority_file)); + + g_hash_table_insert (hash, g_strdup ("LOGNAME"), g_strdup (launch_environment->priv->user_name)); diff --git a/pkgs/desktops/gnome-3/3.12/core/gdm/sessions_dir.patch b/pkgs/desktops/gnome-3/3.12/core/gdm/sessions_dir.patch new file mode 100644 index 00000000000..b8fbad4d731 --- /dev/null +++ b/pkgs/desktops/gnome-3/3.12/core/gdm/sessions_dir.patch @@ -0,0 +1,17 @@ +diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c +index f759d2d..d154716 100644 +--- a/daemon/gdm-session.c ++++ b/daemon/gdm-session.c +@@ -373,9 +373,12 @@ get_system_session_dirs (void) + #ifdef ENABLE_WAYLAND_SUPPORT + DATADIR "/wayland-sessions/", + #endif ++ NULL, + NULL + }; + ++ search_dirs[4] = getenv("GDM_SESSIONS_DIR") != NULL ? getenv("GDM_SESSIONS_DIR") : NULL; ++ + return search_dirs; + } + diff --git a/pkgs/desktops/gnome-3/3.12/core/gdm/xserver_path.patch b/pkgs/desktops/gnome-3/3.12/core/gdm/xserver_path.patch new file mode 100644 index 00000000000..412daee9f27 --- /dev/null +++ b/pkgs/desktops/gnome-3/3.12/core/gdm/xserver_path.patch @@ -0,0 +1,15 @@ +--- a/daemon/gdm-server.c 2014-07-30 23:00:17.786841724 +0200 ++++ b/daemon/gdm-server.c 2014-07-30 23:02:10.491239180 +0200 +@@ -322,7 +322,11 @@ + fallback: + #endif + +- server->priv->command = g_strdup_printf (X_SERVER X_SERVER_ARG_FORMAT, verbosity, debug_options); ++ if (g_getenv("GDM_X_SERVER") != NULL) { ++ server->priv->command = g_strdup (g_getenv("GDM_X_SERVER")); ++ } else { ++ server->priv->command = g_strdup_printf (X_SERVER X_SERVER_ARG_FORMAT, verbosity, debug_options); ++ } + } + + static gboolean