summary refs log tree commit diff
path: root/nixos/modules/programs/shadow.nix
blob: f40faa1ca5fb04ccf6ac1c095de86d9bd4f6de43 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# Configuration for the pwdutils suite of tools: passwd, useradd, etc.

{ config, lib, utils, pkgs, ... }:

with lib;

let

  loginDefs =
    ''
      DEFAULT_HOME yes

      SYS_UID_MIN  400
      SYS_UID_MAX  499
      UID_MIN      1000
      UID_MAX      29999

      SYS_GID_MIN  400
      SYS_GID_MAX  499
      GID_MIN      1000
      GID_MAX      29999

      TTYGROUP     tty
      TTYPERM      0620

      # Ensure privacy for newly created home directories.
      UMASK        077

      # Uncomment this to allow non-root users to change their account
      #information.  This should be made configurable.
      #CHFN_RESTRICT frwh

    '';

in

{

  ###### interface

  options = {

    users.defaultUserShell = lib.mkOption {
      description = ''
        This option defines the default shell assigned to user
        accounts. This can be either a full system path or a shell package.

        This must not be a store path, since the path is
        used outside the store (in particular in /etc/passwd).
      '';
      example = literalExample "pkgs.zsh";
      type = types.either types.path types.shellPackage;
    };

  };


  ###### implementation

  config = {

    environment.systemPackages =
      lib.optional config.users.mutableUsers pkgs.shadow ++
      lib.optional (types.shellPackage.check config.users.defaultUserShell)
        config.users.defaultUserShell;

    environment.etc =
      [ { # /etc/login.defs: global configuration for pwdutils.  You
          # cannot login without it!
          source = pkgs.writeText "login.defs" loginDefs;
          target = "login.defs";
        }

        { # /etc/default/useradd: configuration for useradd.
          source = pkgs.writeText "useradd"
            ''
              GROUP=100
              HOME=/home
              SHELL=${utils.toShellPath config.users.defaultUserShell}
            '';
          target = "default/useradd";
        }
      ];

    security.pam.services =
      { chsh = { rootOK = true; };
        chfn = { rootOK = true; };
        su = { rootOK = true; forwardXAuth = true; logFailures = true; };
        passwd = {};
        # Note: useradd, groupadd etc. aren't setuid root, so it
        # doesn't really matter what the PAM config says as long as it
        # lets root in.
        useradd = { rootOK = true; };
        usermod = { rootOK = true; };
        userdel = { rootOK = true; };
        groupadd = { rootOK = true; };
        groupmod = { rootOK = true; };
        groupmems = { rootOK = true; };
        groupdel = { rootOK = true; };
        login = { startSession = true; allowNullPassword = true; showMotd = true; updateWtmp = true; };
        chpasswd = { rootOK = true; };
        chgpasswd = { rootOK = true; };
      };

    security.permissionsWrappers.setuid = 
    [
      { program = "su";
        source  = "${pkgs.shadow.su}/bin/su";
        owner   = "root";
        group   = "root";
        setuid  = true;        
      }

      { program = "chfn";
        source  = "${pkgs.shadow.out}/bin/chfn";
        owner   = "root";
        group   = "root";
        setuid  = true;
      }
    ] ++
    (lib.optionals config.users.mutableUsers
     map (x: x // { user = "root";
                    group   = "root";
                    setuid  = true;
                  })
         [
           { program = "passwd";
             source  = "${pkgs.shadow.out}/bin/passwd";
           }

           { program = "sg";
             source  = "${pkgs.shadow.out}/bin/sg";
           }

           { program = "newgrp";
             source  = "${pkgs.shadow.out}/bin/newgrp";
           }

           { program = "newuidmap";
             source  = "${pkgs.shadow.out}/bin/newuidmap";
           }

           { program = "newgidmap";
             source  = "${pkgs.shadow.out}/bin/newgidmap";
           }
         ]
    );
  };
}