Expired or must change password with linux/unix/mac clients against Samba4 KDC

Matthieu Patou mat+Informatique.Samba at matws.net
Sun Feb 1 14:44:00 GMT 2009


Hello Love,
I tried without success your patch !
First problem is that it's not only *_kdc_check_flags which returns 
KRB5KDC_ERR_KEY_EXPIRED* but also
_kdc_windc_client_access.

I first added some code to delay the return of KRB5KDC_ERR_KEY_EXPIRED 
until we have been able to check the identity of the client.
It makes kinit ( v1.6 because v1.4 do nothing) to reissue a request to 
kadmin/changepw server.
But as change_pw is not set I was "obliged" to add a hack on the 
server_name comparison.

It's worth noting that when a windows client has an expired password it 
works (even without the patch), the reason of this is that when it gets 
into authsam_account_ok (which seems to be called by 
kdb_windc_client_access) the field pwdLastSet has the value that is set 
to current time for the request to server kadmin/changepw.

I tried to find the place in the code doing this change but so far I'am 
out of luck so I have this poor hack.

Matthieu.

On 02/01/2009 01:08 AM, Love Hörnquist Åstrand wrote:
> Mattheui,
>
> To get the windows behavior you need the attached patch.
>
> The reason the AS-REQ to kadmin/admin is probably that the hdb layer 
> in samba4 doesn't set flags.change_pw flag in the entry for 
> kadmin/admin principal, andrew ?
>
> Love
>
>
>
>
>
> 30 jan 2009 kl. 12:04 skrev Matthieu Patou:
>
>> Dear all,
>>
>> I discovered recently that a it's impossible to change the password for
>> an account that has its password expired or flagged as must be change at
>> next login.
>> I first tried with kpasswd (ie. kpasswd user_tst), the server immediatly
>> reply with error_code: KRB5KDC_ERR_KEY_EXP without asking about the
>> password (btw it might be a security issue because it's easy to know
>> which account has a password either expired or that need to be changed
>> at next login), i tried also with libpam-krb5 3.12 (the latest stable)
>> and in this case pam first try to talk with krbtgt/REALM server, then
>> prompt for password  and then to talk kadmin/changepw but in both case
>> it received KRB5KDC_ERR_KEY_EXP.
>>
>> If you have a look of kpasswd/W2K3 exchange, we can see that things are
>> completly differents:
>>
>> * First the server ask the client for a password by replying with an
>> error_code: KRB5KDC_ERR_PREAUTH_REQUIRED (25)
>> * Then after checking that the password is correct the server replies
>> with an error_code KRB5KDC_ERR_KEY_EXP
>> * The client then issue a request to the kadmin/changepw server which is
>> first replied with KRB5KDC_ERR_PREAUTH_REQUIRED error_code and once the
>> client provides the password the request is validated
>> * The client can prompt for a new password and go ahead in the process
>> for changing the password.
>>
>>
>> Is it possible to make some change to samba kdc so that we achieve more
>> or less the same behavior ?
>> I think more precisely at bypassing the call to authsam_account_ok  if
>> the server name is kadmin/changepw.
>>
>> I attached network capture of kinit client versus Samba4
>> (4.0.0alpha7-GIT-d8f15e4) and versus Windows 2003R2.
>>
>> Any comments ?
>>
>> Matthieu.
>>
>>
>>
>>
>> <kinit2><kinit_samba>
>

-------------- next part --------------
diff --git a/source4/heimdal/kdc/kerberos5.c b/source4/heimdal/kdc/kerberos5.c
index c715e08..b795e3a 100644
--- a/source4/heimdal/kdc/kerberos5.c
+++ b/source4/heimdal/kdc/kerberos5.c
@@ -813,7 +813,7 @@ _kdc_check_flags(krb5_context context,
 	}
 	
 	if (client->pw_end && *client->pw_end < kdc_time
-	    && (server_ex == NULL || !server_ex->entry.flags.change_pw)) {
+	    && (server_ex == NULL || !server_ex->entry.flags.change_pw)&&(strncmp(server_name,"kadmin/changepw",15)!=0)) {
 	    char pwend_str[100];
 	    krb5_format_time(context, *client->pw_end,
 			     pwend_str, sizeof(pwend_str), TRUE);
@@ -981,6 +981,7 @@ _kdc_as_rep(krb5_context context,
     krb5_principal client_princ = NULL, server_princ = NULL;
     char *client_name = NULL, *server_name = NULL;
     krb5_error_code ret = 0;
+    krb5_error_code retwin = 0;
     const char *e_text = NULL;
     krb5_crypto crypto;
     Key *ckey, *skey;
@@ -1069,16 +1070,11 @@ _kdc_as_rep(krb5_context context,
 	goto out;
     }
 
-    ret = _kdc_windc_client_access(context, client, req, &e_data);
-    if(ret)
-	goto out;
-
-    ret = _kdc_check_flags(context, config,
-			   client, client_name,
-			   server, server_name,
-			   TRUE);
-    if(ret)
+    retwin = _kdc_windc_client_access(context, client, req, &e_data);
+    if(retwin &&(retwin !=KRB5KDC_ERR_KEY_EXPIRED)) {
+      	 ret=retwin;
 	goto out;
+    }
 
     memset(&et, 0, sizeof(et));
     memset(&ek, 0, sizeof(ek));
@@ -1363,6 +1359,19 @@ _kdc_as_rep(krb5_context context,
     }
 
     /*
+     * Verify flags after the user been required to prove its identity
+     * with in a preauth mech.
+     */
+    ret = _kdc_check_flags(context, config,
+			   client, client_name,
+			   server, server_name,
+			   TRUE);
+    if(ret) {
+       	e_text = NULL;
+	        client_princ = NULL;
+	        goto out;
+    }
+    /*
      * Find the client key (for preauth ENC-TS verification and reply
      * encryption).  Then the best encryption type for the KDC and
      * last the best session key that shared between the client and


More information about the samba-technical mailing list