at 18.09-beta 8.0 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) lightdm writeScript writeText; 17 18 # lightdm runs with clearenv(), but we need a few things in the environment 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.users.lightdm.name} 46 greeters-directory = ${cfg.greeter.package} 47 ''} 48 sessions-directory = ${dmcfg.session.desktops}/share/xsessions 49 50 [Seat:*] 51 xserver-command = ${xserverWrapper} 52 session-wrapper = ${dmcfg.session.wrapper} 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 ./lightdm-greeters/mini.nix 76 ]; 77 78 options = { 79 80 services.xserver.displayManager.lightdm = { 81 82 enable = mkOption { 83 type = types.bool; 84 default = false; 85 description = '' 86 Whether to enable lightdm as the display manager. 87 ''; 88 }; 89 90 greeter = { 91 enable = mkOption { 92 type = types.bool; 93 default = true; 94 description = '' 95 If set to false, run lightdm in greeterless mode. This only works if autologin 96 is enabled and autoLogin.timeout is zero. 97 ''; 98 }; 99 package = mkOption { 100 type = types.package; 101 description = '' 102 The LightDM greeter to login via. The package should be a directory 103 containing a .desktop file matching the name in the 'name' option. 104 ''; 105 106 }; 107 name = mkOption { 108 type = types.string; 109 description = '' 110 The name of a .desktop file in the directory specified 111 in the 'package' option. 112 ''; 113 }; 114 }; 115 116 background = mkOption { 117 type = types.str; 118 default = "${pkgs.nixos-artwork.wallpapers.simple-dark-gray-bottom}/share/artwork/gnome/nix-wallpaper-simple-dark-gray_bottom.png"; 119 description = '' 120 The background image or color to use. 121 ''; 122 }; 123 124 extraSeatDefaults = mkOption { 125 type = types.lines; 126 default = ""; 127 example = '' 128 greeter-show-manual-login=true 129 ''; 130 description = "Extra lines to append to SeatDefaults section."; 131 }; 132 133 autoLogin = mkOption { 134 default = {}; 135 description = '' 136 Configuration for automatic login. 137 ''; 138 139 type = types.submodule { 140 options = { 141 enable = mkOption { 142 type = types.bool; 143 default = false; 144 description = '' 145 Automatically log in as the specified <option>autoLogin.user</option>. 146 ''; 147 }; 148 149 user = mkOption { 150 type = types.nullOr types.str; 151 default = null; 152 description = '' 153 User to be used for the automatic login. 154 ''; 155 }; 156 157 timeout = mkOption { 158 type = types.int; 159 default = 0; 160 description = '' 161 Show the greeter for this many seconds before automatic login occurs. 162 ''; 163 }; 164 }; 165 }; 166 }; 167 168 }; 169 }; 170 171 config = mkIf cfg.enable { 172 173 assertions = [ 174 { assertion = cfg.autoLogin.enable -> cfg.autoLogin.user != null; 175 message = '' 176 LightDM auto-login requires services.xserver.displayManager.lightdm.autoLogin.user to be set 177 ''; 178 } 179 { assertion = cfg.autoLogin.enable -> dmDefault != "none" || wmDefault != "none"; 180 message = '' 181 LightDM auto-login requires that services.xserver.desktopManager.default and 182 services.xserver.windowMananger.default are set to valid values. The current 183 default session: ${defaultSessionName} is not valid. 184 ''; 185 } 186 { assertion = !cfg.greeter.enable -> (cfg.autoLogin.enable && cfg.autoLogin.timeout == 0); 187 message = '' 188 LightDM can only run without greeter if automatic login is enabled and the timeout for it 189 is set to zero. 190 ''; 191 } 192 ]; 193 194 services.xserver.displayManager.job = { 195 logToFile = true; 196 197 # lightdm relaunches itself via just `lightdm`, so needs to be on the PATH 198 execCmd = '' 199 export PATH=${lightdm}/sbin:$PATH 200 exec ${lightdm}/sbin/lightdm --log-dir=/var/log --run-dir=/run 201 ''; 202 }; 203 204 environment.etc."lightdm/lightdm.conf".source = lightdmConf; 205 environment.etc."lightdm/users.conf".source = usersConf; 206 207 services.dbus.enable = true; 208 services.dbus.packages = [ lightdm ]; 209 210 # lightdm uses the accounts daemon to remember language/window-manager per user 211 services.accounts-daemon.enable = true; 212 213 # Enable the accounts daemon to find lightdm's dbus interface 214 environment.systemPackages = [ lightdm ]; 215 216 security.pam.services.lightdm = { 217 allowNullPassword = true; 218 startSession = true; 219 }; 220 security.pam.services.lightdm-greeter = { 221 allowNullPassword = true; 222 startSession = true; 223 text = '' 224 auth required pam_env.so envfile=${config.system.build.pamEnvironment} 225 auth required pam_permit.so 226 227 account required pam_permit.so 228 229 password required pam_deny.so 230 231 session required pam_env.so envfile=${config.system.build.pamEnvironment} 232 session required pam_unix.so 233 session optional ${pkgs.systemd}/lib/security/pam_systemd.so 234 ''; 235 }; 236 security.pam.services.lightdm-autologin.text = '' 237 auth requisite pam_nologin.so 238 auth required pam_succeed_if.so uid >= 1000 quiet 239 auth required pam_permit.so 240 241 account include lightdm 242 243 password include lightdm 244 245 session include lightdm 246 ''; 247 248 users.users.lightdm = { 249 createHome = true; 250 home = "/var/lib/lightdm-data"; 251 group = "lightdm"; 252 uid = config.ids.uids.lightdm; 253 }; 254 255 users.groups.lightdm.gid = config.ids.gids.lightdm; 256 services.xserver.tty = null; # We might start multiple X servers so let the tty increment themselves.. 257 services.xserver.display = null; # We specify our own display (and logfile) in xserver-wrapper up there 258 }; 259}