1rlm_mschap
2==========
3
4The mschap module provides support for MS-CHAPv1 and MS-CHAPv2, which is
5a common authentication mechanisms for Microsoft clients.
6
7If you want to support mschap, there are only 3 possibilities:
8
9 1. You have access to the users plaintext password, and you configure
10    FreeRADIUS to read this, and set the Cleartext-Password control attribute.
11
12 2. You have access to the NT (MS-CHAPv2) or LM (MS-CHAPv1) hashes,
13    and you configure FreeRADIUS to read this and set the NT/LM-Password
14    control attribute.
15
16 3. You have Samba installed, joined into a windows domain, and use
17    the ntlm_auth helper binary to pass authentication onwards to
18    a domain controller.
19
20These are the ONLY possibilities; MS-CHAP is IMPOSSIBLE if you e.g. only
21have the unix/md5/sha crypt of your users password.
22
23For more info, see:
24
25 http://deployingradius.com/documents/protocols/compatibility.html
26
27EAP-MSCHAPv2
28============
29
30The EAP module provides MS-CHAPv2 support as well. It simply passes the
31data through to the mschap module, so you must configure mschap properly.
32
33ntlm_auth
34=========
35
36Method 3 above involves configuring the mschap module to call the Samba
37ntlm_auth helper:
38
39::
40
41  mschap {
42    ntlm_auth = "/path/to/bin ..."
43  }
44
45You need to be careful about setting this command line. There are several
46options for the arguments, in particular username and domain:
47
48 * --username=%{User-Name} - this will fail if you're using realms or host-based auth
49 * --username=%{mschap:User-Name} - this will fail if using using suffix i.e. user@domain
50
51You'll need to fit this to your local needs.
52
53Disabling ntlm_auth for some users
54----------------------------------
55
56You might have some users in the domain, and others in files or SQL that you
57want to authenticate locally. To do this, set::
58
59 MS-CHAP-Use-NTLM-Auth := 0
60
61This will disable ntlm_auth for that user/group. This is also obeyed
62for password changes (see below).
63
64Password changes
65================
66
67From FreeRADIUS version 3.0.0 the mschap module supports password changes.
68
69There are two options, ntlm_auth and local.
70
71ntlm_auth
72---------
73
74If you are using ntlm_auth to check passwords, you must also use
75ntlm_auth to change passwords. In modules/mschap you should configure::
76
77  mschap {
78    ntlm_auth = "...."
79    passchange {
80
81      # path to the binary
82      ntlm_auth = "/path/to/ntlm_auth --helper-protocol=ntlm-change-password-1"
83
84      # initial data to send
85      # this MUST be supplied
86      ntlm_auth_username = "username: %{mschap:User-Name}"
87      ntlm_auth_domain = "nt-domain: %{%{mschap:NT-Domain}:-YOURDOMAIN}"
88
89      # Or, you could try:
90      ntlm_auth_username = "full-username: %{User-Name}"
91      # ntlm_auth_domain - disabled
92
93    }
94
95
96If you are using ntlm_auth, then domain controllers might say
97"Password expired" if the user password is valid but has expired; the
98mschap module will detect this and return error 648 to the client,
99instructing it to try a password change.
100
101Note: if you have disabled ntlm_auth for a user/group, this will apply
102for password changes too - they will fall through to using the Local
103method.
104
105Local
106-----
107
108If you are performing mschap locally with Cleartext-Password/NT-Password, you
109can decrypt and process the password change locally. To do this, you configure
110the "local_cpw" string::
111
112  mschap {
113    passchange {
114      local_cpw = "%{xlat:...}
115    }
116  }
117
118To actually force a client to change passwords, you must set the expiry bit
119in the SMB-Account-Ctrl value - for example::
120
121  update control {
122    # U == user
123    # e == expired
124    SMB-Account-Ctrl-Text := '[Ue]'
125  }
126
127This will cause the client to receive "error 648 - password
128expired". Obviously you will need to ensure your local_cpw xlat clears
129this value, or else the client password will be expired the next time
130they log in. For example, you might use an SQL stored procedure to
131change passwords::
132
133  mschap {
134    passchange {
135      local_cpw = "%{sql:select change_password('%{SQL-User-Name}','%{MS-CHAP-New-NT-Password}')}"
136    }
137  }
138
139...and an example stored procedure for Postgres might be::
140
141  CREATE FUNCTION change_password(raduser text, ntpassword text) RETURNS text
142      LANGUAGE plpgsql
143      AS $$
144  BEGIN
145          update radcheck set value=ntpassword where username=raduser and attribute='NT-Password';
146          if not FOUND then
147                  -- the user does not exist; die
148                  return '';
149          end if;
150          update radcheck set value=replace(value,'e','') where username=raduser and attribute='SMB-Account-Ctrl-Text' and value like '%e%';
151          return 'ok';
152  END;
153  $$;
154
155
156The local_cpw xlat has access to two variables:
157
158 * MS-CHAP-New-NT-Password        - the new value of NT-Password
159 * MS-CHAP-New-Cleartext-PAssword - the new value of Cleartext-Password
160
161This allows you to do things like::
162
163  # update via SQL
164  local_cpw = "%{sql:update radcheck set value='%{MS-CHAP-New-NT-Password}' where username='%{SQL-User-Name} and attribute='NT-Password'}"
165
166Or::
167
168  # update via exec/script
169  local_cpw = "%{exec:/my/script %{User-Name} %{MS-CHAP-New-Cleartext-Password}}"
170
171WARNING - wherever possible, you should use
172MS-CHAP-New-NT-Password. The reason is that cleartext passwords have
173undergone unicode transformation from the client encoding (utf-16) to
174the server encoding (utf-8) and the current code does this in a very
175ad-hoc way. The reverse transformation is also not done - when the
176server reads Cleartext-Password out of files/database, it assumes
177US-ASCII and thus international characters will fail.
178
179N.B. this could be fixed, if we wanted to pull in something like iconv.
180
181In addition, you should beware of Cleartext-Password when using SQL;
182any password character not in safe_characters will be encoded as a hex
183number, e.g. =20.
184
185Password changes over EAP
186=========================
187
188You must set the following in eap.conf::
189
190 eap {
191   mschapv2 {
192     send_error = yes
193   }
194 }
195
196Otherwise password changes for PEAP/MSCHAPv2 will not work.
197