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