1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 7 cfg = config.services.xserver.displayManager; 8 gnome3 = config.environment.gnome3.packageSet; 9 gdm = gnome3.gdm; 10 11in 12 13{ 14 15 ###### interface 16 17 options = { 18 19 services.xserver.displayManager.gdm = { 20 21 enable = mkEnableOption '' 22 GDM as the display manager. 23 <emphasis>GDM in NixOS is not well-tested with desktops other 24 than GNOME, so use with caution, as it could render the 25 system unusable.</emphasis> 26 ''; 27 28 debug = mkEnableOption '' 29 debugging messages in GDM 30 ''; 31 32 autoLogin = mkOption { 33 default = {}; 34 description = '' 35 Auto login configuration attrset. 36 ''; 37 38 type = types.submodule { 39 options = { 40 enable = mkOption { 41 type = types.bool; 42 default = false; 43 description = '' 44 Automatically log in as the sepecified <option>autoLogin.user</option>. 45 ''; 46 }; 47 48 user = mkOption { 49 type = types.nullOr types.str; 50 default = null; 51 description = '' 52 User to be used for the autologin. 53 ''; 54 }; 55 56 delay = mkOption { 57 type = types.int; 58 default = 0; 59 description = '' 60 Seconds of inactivity after which the autologin will be performed. 61 ''; 62 }; 63 64 }; 65 }; 66 }; 67 68 }; 69 70 }; 71 72 73 ###### implementation 74 75 config = mkIf cfg.gdm.enable { 76 77 assertions = [ 78 { assertion = cfg.gdm.autoLogin.enable -> cfg.gdm.autoLogin.user != null; 79 message = "GDM auto-login requires services.xserver.displayManager.gdm.autoLogin.user to be set"; 80 } 81 ]; 82 83 services.xserver.displayManager.slim.enable = false; 84 85 users.extraUsers.gdm = 86 { name = "gdm"; 87 uid = config.ids.uids.gdm; 88 group = "gdm"; 89 home = "/run/gdm"; 90 description = "GDM user"; 91 }; 92 93 users.extraGroups.gdm.gid = config.ids.gids.gdm; 94 95 services.xserver.displayManager.job = 96 { 97 environment = { 98 GDM_X_SERVER = "${cfg.xserverBin} ${cfg.xserverArgs}"; 99 GDM_SESSIONS_DIR = "${cfg.session.desktops}"; 100 XDG_CONFIG_DIRS = "${gnome3.gnome_settings_daemon}/etc/xdg"; 101 # Find the mouse 102 XCURSOR_PATH = "~/.icons:${config.system.path}/share/icons"; 103 }; 104 execCmd = "exec ${gdm}/bin/gdm"; 105 }; 106 107 # Because sd_login_monitor_new requires /run/systemd/machines 108 systemd.services.display-manager.wants = [ "systemd-machined.service" ]; 109 systemd.services.display-manager.after = [ "systemd-machined.service" ]; 110 111 systemd.services.display-manager.path = [ gnome3.gnome_shell gnome3.caribou pkgs.xorg.xhost pkgs.dbus_tools ]; 112 113 services.dbus.packages = [ gdm ]; 114 115 programs.dconf.profiles.gdm = "${gdm}/share/dconf/profile/gdm"; 116 117 # Use AutomaticLogin if delay is zero, because it's immediate. 118 # Otherwise with TimedLogin with zero seconds the prompt is still 119 # presented and there's a little delay. 120 environment.etc."gdm/custom.conf".text = '' 121 [daemon] 122 ${optionalString cfg.gdm.autoLogin.enable ( 123 if cfg.gdm.autoLogin.delay > 0 then '' 124 TimedLoginEnable=true 125 TimedLogin=${cfg.gdm.autoLogin.user} 126 TimedLoginDelay=${toString cfg.gdm.autoLogin.delay} 127 '' else '' 128 AutomaticLoginEnable=true 129 AutomaticLogin=${cfg.gdm.autoLogin.user} 130 '') 131 } 132 133 [security] 134 135 [xdmcp] 136 137 [greeter] 138 139 [chooser] 140 141 [debug] 142 ${optionalString cfg.gdm.debug "Enable=true"} 143 ''; 144 145 # GDM LFS PAM modules, adapted somehow to NixOS 146 security.pam.services = { 147 gdm-launch-environment.text = '' 148 auth required pam_succeed_if.so audit quiet_success user = gdm 149 auth optional pam_permit.so 150 151 account required pam_succeed_if.so audit quiet_success user = gdm 152 account sufficient pam_unix.so 153 154 password required pam_deny.so 155 156 session required pam_succeed_if.so audit quiet_success user = gdm 157 session required pam_env.so envfile=${config.system.build.pamEnvironment} 158 session optional ${pkgs.systemd}/lib/security/pam_systemd.so 159 session optional pam_keyinit.so force revoke 160 session optional pam_permit.so 161 ''; 162 163 gdm.text = '' 164 auth requisite pam_nologin.so 165 auth required pam_env.so envfile=${config.system.build.pamEnvironment} 166 167 auth required pam_succeed_if.so uid >= 1000 quiet 168 auth optional ${gnome3.gnome_keyring}/lib/security/pam_gnome_keyring.so 169 auth ${if config.security.pam.enableEcryptfs then "required" else "sufficient"} pam_unix.so nullok likeauth 170 ${optionalString config.security.pam.enableEcryptfs 171 "auth required ${pkgs.ecryptfs}/lib/security/pam_ecryptfs.so unwrap"} 172 173 ${optionalString (! config.security.pam.enableEcryptfs) 174 "auth required pam_deny.so"} 175 176 account sufficient pam_unix.so 177 178 password requisite pam_unix.so nullok sha512 179 ${optionalString config.security.pam.enableEcryptfs 180 "password optional ${pkgs.ecryptfs}/lib/security/pam_ecryptfs.so"} 181 182 session required pam_env.so envfile=${config.system.build.pamEnvironment} 183 session required pam_unix.so 184 ${optionalString config.security.pam.enableEcryptfs 185 "session optional ${pkgs.ecryptfs}/lib/security/pam_ecryptfs.so"} 186 session required pam_loginuid.so 187 session optional ${pkgs.systemd}/lib/security/pam_systemd.so 188 session optional ${gnome3.gnome_keyring}/lib/security/pam_gnome_keyring.so auto_start 189 ''; 190 191 gdm-password.text = '' 192 auth requisite pam_nologin.so 193 auth required pam_env.so envfile=${config.system.build.pamEnvironment} 194 195 auth required pam_succeed_if.so uid >= 1000 quiet 196 auth optional ${gnome3.gnome_keyring}/lib/security/pam_gnome_keyring.so 197 auth ${if config.security.pam.enableEcryptfs then "required" else "sufficient"} pam_unix.so nullok likeauth 198 ${optionalString config.security.pam.enableEcryptfs 199 "auth required ${pkgs.ecryptfs}/lib/security/pam_ecryptfs.so unwrap"} 200 ${optionalString (! config.security.pam.enableEcryptfs) 201 "auth required pam_deny.so"} 202 203 account sufficient pam_unix.so 204 205 password requisite pam_unix.so nullok sha512 206 ${optionalString config.security.pam.enableEcryptfs 207 "password optional ${pkgs.ecryptfs}/lib/security/pam_ecryptfs.so"} 208 209 session required pam_env.so envfile=${config.system.build.pamEnvironment} 210 session required pam_unix.so 211 ${optionalString config.security.pam.enableEcryptfs 212 "session optional ${pkgs.ecryptfs}/lib/security/pam_ecryptfs.so"} 213 session required pam_loginuid.so 214 session optional ${pkgs.systemd}/lib/security/pam_systemd.so 215 session optional ${gnome3.gnome_keyring}/lib/security/pam_gnome_keyring.so auto_start 216 ''; 217 218 gdm-autologin.text = '' 219 auth requisite pam_nologin.so 220 221 auth required pam_succeed_if.so uid >= 1000 quiet 222 auth required pam_permit.so 223 224 account sufficient pam_unix.so 225 226 password requisite pam_unix.so nullok sha512 227 228 session optional pam_keyinit.so revoke 229 session required pam_env.so envfile=${config.system.build.pamEnvironment} 230 session required pam_unix.so 231 session required pam_loginuid.so 232 session optional ${pkgs.systemd}/lib/security/pam_systemd.so 233 ''; 234 235 }; 236 237 }; 238 239}