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