at 18.03-beta 8.2 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 7 xcfg = config.services.xserver; 8 dmcfg = xcfg.displayManager; 9 xEnv = config.systemd.services."display-manager".environment; 10 cfg = dmcfg.lightdm; 11 12 dmDefault = xcfg.desktopManager.default; 13 wmDefault = xcfg.windowManager.default; 14 hasDefaultUserSession = dmDefault != "none" || wmDefault != "none"; 15 16 inherit (pkgs) stdenv lightdm writeScript writeText; 17 18 # lightdm runs with clearenv(), but we need a few things in the enviornment for X to startup 19 xserverWrapper = writeScript "xserver-wrapper" 20 '' 21 #! ${pkgs.bash}/bin/bash 22 ${concatMapStrings (n: "export ${n}=\"${getAttr n xEnv}\"\n") (attrNames xEnv)} 23 24 display=$(echo "$@" | xargs -n 1 | grep -P ^:\\d\$ | head -n 1 | sed s/^://) 25 if [ -z "$display" ] 26 then additionalArgs=":0 -logfile /var/log/X.0.log" 27 else additionalArgs="-logfile /var/log/X.$display.log" 28 fi 29 30 exec ${dmcfg.xserverBin} ${toString dmcfg.xserverArgs} $additionalArgs "$@" 31 ''; 32 33 usersConf = writeText "users.conf" 34 '' 35 [UserList] 36 minimum-uid=500 37 hidden-users=${concatStringsSep " " dmcfg.hiddenUsers} 38 hidden-shells=/run/current-system/sw/bin/nologin 39 ''; 40 41 lightdmConf = writeText "lightdm.conf" 42 '' 43 [LightDM] 44 ${optionalString cfg.greeter.enable '' 45 greeter-user = ${config.users.extraUsers.lightdm.name} 46 greeters-directory = ${cfg.greeter.package} 47 ''} 48 sessions-directory = ${dmcfg.session.desktops} 49 50 [Seat:*] 51 xserver-command = ${xserverWrapper} 52 session-wrapper = ${dmcfg.session.script} 53 ${optionalString cfg.greeter.enable '' 54 greeter-session = ${cfg.greeter.name} 55 ''} 56 ${optionalString cfg.autoLogin.enable '' 57 autologin-user = ${cfg.autoLogin.user} 58 autologin-user-timeout = ${toString cfg.autoLogin.timeout} 59 autologin-session = ${defaultSessionName} 60 ''} 61 ${optionalString hasDefaultUserSession '' 62 user-session=${defaultSessionName} 63 ''} 64 ${cfg.extraSeatDefaults} 65 ''; 66 67 defaultSessionName = dmDefault + optionalString (wmDefault != "none") ("+" + wmDefault); 68in 69{ 70 # Note: the order in which lightdm greeter modules are imported 71 # here determines the default: later modules (if enable) are 72 # preferred. 73 imports = [ 74 ./lightdm-greeters/gtk.nix 75 ]; 76 77 options = { 78 79 services.xserver.displayManager.lightdm = { 80 81 enable = mkOption { 82 type = types.bool; 83 default = false; 84 description = '' 85 Whether to enable lightdm as the display manager. 86 ''; 87 }; 88 89 greeter = { 90 enable = mkOption { 91 type = types.bool; 92 default = true; 93 description = '' 94 If set to false, run lightdm in greeterless mode. This only works if autologin 95 is enabled and autoLogin.timeout is zero. 96 ''; 97 }; 98 package = mkOption { 99 type = types.package; 100 description = '' 101 The LightDM greeter to login via. The package should be a directory 102 containing a .desktop file matching the name in the 'name' option. 103 ''; 104 105 }; 106 name = mkOption { 107 type = types.string; 108 description = '' 109 The name of a .desktop file in the directory specified 110 in the 'package' option. 111 ''; 112 }; 113 }; 114 115 background = mkOption { 116 type = types.str; 117 default = "${pkgs.nixos-artwork.wallpapers.gnome-dark}/share/artwork/gnome/Gnome_Dark.png"; 118 description = '' 119 The background image or color to use. 120 ''; 121 }; 122 123 extraSeatDefaults = mkOption { 124 type = types.lines; 125 default = ""; 126 example = '' 127 greeter-show-manual-login=true 128 ''; 129 description = "Extra lines to append to SeatDefaults section."; 130 }; 131 132 autoLogin = mkOption { 133 default = {}; 134 description = '' 135 Configuration for automatic login. 136 ''; 137 138 type = types.submodule { 139 options = { 140 enable = mkOption { 141 type = types.bool; 142 default = false; 143 description = '' 144 Automatically log in as the specified <option>autoLogin.user</option>. 145 ''; 146 }; 147 148 user = mkOption { 149 type = types.nullOr types.str; 150 default = null; 151 description = '' 152 User to be used for the automatic login. 153 ''; 154 }; 155 156 timeout = mkOption { 157 type = types.int; 158 default = 0; 159 description = '' 160 Show the greeter for this many seconds before automatic login occurs. 161 ''; 162 }; 163 }; 164 }; 165 }; 166 167 }; 168 }; 169 170 config = mkIf cfg.enable { 171 172 assertions = [ 173 { assertion = cfg.autoLogin.enable -> cfg.autoLogin.user != null; 174 message = '' 175 LightDM auto-login requires services.xserver.displayManager.lightdm.autoLogin.user to be set 176 ''; 177 } 178 { assertion = cfg.autoLogin.enable -> elem defaultSessionName dmcfg.session.names; 179 message = '' 180 LightDM auto-login requires that services.xserver.desktopManager.default and 181 services.xserver.windowMananger.default are set to valid values. The current 182 default session: ${defaultSessionName} is not valid. 183 ''; 184 } 185 { assertion = hasDefaultUserSession -> elem defaultSessionName dmcfg.session.names; 186 message = '' 187 services.xserver.desktopManager.default and 188 services.xserver.windowMananger.default are not set to valid 189 values. The current default session: ${defaultSessionName} 190 is not valid. 191 ''; 192 } 193 { assertion = !cfg.greeter.enable -> (cfg.autoLogin.enable && cfg.autoLogin.timeout == 0); 194 message = '' 195 LightDM can only run without greeter if automatic login is enabled and the timeout for it 196 is set to zero. 197 ''; 198 } 199 ]; 200 201 services.xserver.displayManager.slim.enable = false; 202 203 services.xserver.displayManager.job = { 204 logToFile = true; 205 206 # lightdm relaunches itself via just `lightdm`, so needs to be on the PATH 207 execCmd = '' 208 export PATH=${lightdm}/sbin:$PATH 209 exec ${lightdm}/sbin/lightdm --log-dir=/var/log --run-dir=/run 210 ''; 211 }; 212 213 environment.etc."lightdm/lightdm.conf".source = lightdmConf; 214 environment.etc."lightdm/users.conf".source = usersConf; 215 216 services.dbus.enable = true; 217 services.dbus.packages = [ lightdm ]; 218 219 # lightdm uses the accounts daemon to rember language/window-manager per user 220 services.accounts-daemon.enable = true; 221 222 security.pam.services.lightdm = { 223 allowNullPassword = true; 224 startSession = true; 225 }; 226 security.pam.services.lightdm-greeter = { 227 allowNullPassword = true; 228 startSession = true; 229 text = '' 230 auth required pam_env.so envfile=${config.system.build.pamEnvironment} 231 auth required pam_permit.so 232 233 account required pam_permit.so 234 235 password required pam_deny.so 236 237 session required pam_env.so envfile=${config.system.build.pamEnvironment} 238 session required pam_unix.so 239 session optional ${pkgs.systemd}/lib/security/pam_systemd.so 240 ''; 241 }; 242 security.pam.services.lightdm-autologin.text = '' 243 auth requisite pam_nologin.so 244 auth required pam_succeed_if.so uid >= 1000 quiet 245 auth required pam_permit.so 246 247 account include lightdm 248 249 password include lightdm 250 251 session include lightdm 252 ''; 253 254 users.extraUsers.lightdm = { 255 createHome = true; 256 home = "/var/lib/lightdm-data"; 257 group = "lightdm"; 258 uid = config.ids.uids.lightdm; 259 }; 260 261 users.extraGroups.lightdm.gid = config.ids.gids.lightdm; 262 services.xserver.tty = null; # We might start multiple X servers so let the tty increment themselves.. 263 services.xserver.display = null; # We specify our own display (and logfile) in xserver-wrapper up there 264 }; 265}