[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
RFC3244 set password protocol in kpasswdd [was: LDAP backendsupport for OpenLDAP 2.1.x]
- To: lukeh@PADL.COM
- Subject: RFC3244 set password protocol in kpasswdd [was: LDAP backendsupport for OpenLDAP 2.1.x]
- From: Alberto Patino <jalbertop@aranea.com.mx>
- Date: 09 Jun 2003 21:17:37 -0500
- Cc: heimdal-discuss@sics.se
- In-Reply-To: <200306050048.KAA89898@au.padl.com>
- References: <001701c315dc$ca3894c0$0e01a8c0@CELLO><1052511670.1966.69.camel@newton><amptm7qmav.fsf@nutcracker.stacken.kth.se><1053972016.3370.54.camel@newton> <200305262321.JAA76809@au.padl.com><amvfvwn1oo.fsf@nutcracker.stacken.kth.se><200305291159.VAA11350@au.padl.com> <1054772757.22681.46.camel@newton> <200306050048.KAA89898@au.padl.com>
- Sender: owner-heimdal-discuss@sics.se
On Wed, 2003-06-04 at 19:48, Luke Howard wrote:
>
> BTW, I implemented RFC 3244 support in kpasswdd some time ago :-)
>
> -- Luke
>
> --
> Luke Howard | PADL Software Pty Ltd | www.padl.com
Hi Luke.
This is my "experimental" patch for those who have been asked support
for the RFC3244. (for example myself). Right now there is a new RFC
draft so I thinks is not going to be very useful, but I am sending this
patch anyway. Maybe you could add something.
Please consider this:
1- Doesn't have support for the TCP protocol.
2- Doesn't have a "smart" authorization mechanism.
3- You need to modify the kadmin/changepw principal. You must disable
the disallow-tgt-based attribute (from the kadmin console) so the KDC
doesn't complain about KDC policy rejection. (a TGS is not valid for a
ticket that have the initial flag set).
4- Doesn't implement the initial flag check.
5- Doesn't implement the client program to set the password ( I am using
a modified program client provided by Microsoft with the SASL-GSSAPI
that you wrote for Microsoft ;-) )
diff -Naur heimdal-0.6/kpasswd/kpasswdd.c heimdal-0.6-setpasswd/kpasswd/kpasswdd.c
--- heimdal-0.6/kpasswd/kpasswdd.c 2002-12-02 08:31:52.000000000 -0600
+++ heimdal-0.6-setpasswd/kpasswd/kpasswdd.c 2003-06-09 20:53:09.000000000 -0500
@@ -41,11 +41,36 @@
#include <hdb.h>
#include <kadm5/private.h>
+#define USER_WITH_ADMIN_RIGHTS "administrator@MYREALM"
+
static krb5_context context;
static krb5_log_facility *log_facility;
static sig_atomic_t exit_flag = 0;
+
+/*
+ This function must be replaced with a real authorization check!
+ This sample just check for a hardcoded principal name.
+
+*/
+static int
+is_authorized2setpw(krb5_context context,krb5_principal principal)
+{
+char *adminUser;
+int rc;
+
+ krb5_unparse_name(context,principal,&adminUser);
+
+ if ( !strcmp(adminUser,USER_WITH_ADMIN_RIGHTS) )
+ rc = 1;
+ else
+ rc = 0;
+
+ free(adminUser);
+ return rc;
+}
+
static void
send_reply (int s,
struct sockaddr *sa,
@@ -211,7 +236,7 @@
kadm5_config_params conf;
void *kadm5_handle;
char *tmp;
-
+
memset (&conf, 0, sizeof(conf));
krb5_unparse_name (context, principal, &client);
@@ -240,7 +265,7 @@
kadm5_destroy (kadm5_handle);
return;
}
-
+
tmp = malloc (pwd_data->length + 1);
if (tmp == NULL) {
krb5_warnx (context, "malloc: out of memory");
@@ -250,7 +275,7 @@
}
memcpy (tmp, pwd_data->data, pwd_data->length);
tmp[pwd_data->length] = '\0';
-
+
ret = kadm5_s_chpass_principal_cond (kadm5_handle, principal, tmp);
memset (tmp, 0, pwd_data->length);
free (tmp);
@@ -268,6 +293,7 @@
static int
verify (krb5_auth_context *auth_context,
krb5_principal server,
+ krb5_principal *targetPrincipal,
krb5_keytab keytab,
krb5_ticket **ticket,
krb5_data *out_data,
@@ -281,6 +307,9 @@
u_int16_t pkt_len, pkt_ver, ap_req_len;
krb5_data ap_req_data;
krb5_data krb_priv_data;
+ /* ASN Sequence for set password protocol */
+ ChangePasswdData sChangePasswdData;
+ size_t len2;
pkt_len = (msg[0] << 8) | (msg[1]);
pkt_ver = (msg[2] << 8) | (msg[3]);
@@ -291,7 +320,7 @@
reply_error (server, s, sa, sa_size, 0, 1, "Bad request");
return 1;
}
- if (pkt_ver != 0x0001) {
+ if (pkt_ver != 0x0001 && pkt_ver != 0xff80) {
krb5_warnx (context, "Bad version (%d)", pkt_ver);
reply_error (server, s, sa, sa_size, 0, 1, "Wrong program version");
return 1;
@@ -319,13 +348,35 @@
reply_error (server, s, sa, sa_size, ret, 3, "Authentication failed");
return 1;
}
-
- if (!(*ticket)->ticket.flags.initial) {
- krb5_warnx (context, "initial flag not set");
- reply_error (server, s, sa, sa_size, ret, 1,
- "Bad request");
- goto out;
+ if (pkt_ver == 0x0001) {
+ if (!(*ticket)->ticket.flags.initial) {
+ krb5_warnx (context, "initial flag not set");
+ reply_error (server, s, sa, sa_size, ret, 1,
+ "Bad request");
+ goto out;
+ }
+ }
+ else {
+ /* Should verify if the Initial flag must be set */
+ /* If should be and is not set then return 0x0007 */
+ /* Not implemented !!! */
+ int initial_flag_is_required = FALSE;
+ if ( initial_flag_is_required )
+ if (!(*ticket)->ticket.flags.initial) {
+ krb5_warnx (context, "initial flag not set");
+ reply_error (server, s, sa, sa_size, ret, 0x0007,
+ "Bad request");
+ goto out;
+ }
+ /* Then check authorization. If doesnt met criteria */
+ /* then return 0x0005. Obviously in result code. */
+ if ( !is_authorized2setpw(context, (*ticket)->client ) ) {
+ krb5_warn (context, ret, "is_authorized");
+ reply_error (server, s, sa, sa_size, ret, 0x0005, "Authorization Failed.");
+ goto out;
+ }
}
+
krb_priv_data.data = msg + 6 + ap_req_len;
krb_priv_data.length = len - 6 - ap_req_len;
@@ -340,7 +391,46 @@
reply_error (server, s, sa, sa_size, ret, 3, "Bad request");
goto out;
}
+ /* If the request is set password */
+ /* then I need to decode the setpw structure */
+ if (pkt_ver == 0xff80) {
+ memset(&sChangePasswdData, 0, sizeof(sChangePasswdData));
+
+ ret = decode_ChangePasswdData(out_data->data,out_data->length,&sChangePasswdData,&len2);
+ if (ret) {
+ krb5_warn (context, ret, "decode_ChangePasswdData");
+ reply_error (server, s, sa, sa_size, ret, 3, "Bad Request RFC3244");
+ goto out;
+ }
+ krb5_data_free(out_data);
+
+ /* Now put back password to out_data */
+ ret = krb5_data_copy (out_data,
+ sChangePasswdData.newpasswd.data,
+ sChangePasswdData.newpasswd.length);
+ if (ret) {
+ krb5_warn (context, ret, "krb5_data_copy");
+ reply_error (server, s, sa, sa_size, ret, 3, "Bad Request RFC3244");
+ goto out1;
+ }
+
+ /* targetPrincipal is not the ticket owner, is the targname in the */
+ /* KRB_PRIV message */
+ principalname2krb5_principal(targetPrincipal,
+ *sChangePasswdData.targname,
+ *sChangePasswdData.targrealm);
+
+ free_ChangePasswdData (&sChangePasswdData);
+ }
+ else{
+ /* This is the owner of the ticket*/
+ *targetPrincipal=(*ticket)->client;
+ }
return 0;
+
+out1:
+ krb5_data_free(out_data);
+
out:
krb5_free_ticket (context, *ticket);
return 1;
@@ -361,7 +451,8 @@
krb5_data out_data;
krb5_ticket *ticket;
krb5_address other_addr;
-
+ krb5_principal targetPrincipal;
+
krb5_data_zero (&out_data);
ret = krb5_auth_con_init (context, &auth_context);
@@ -389,13 +480,14 @@
goto out;
}
- if (verify (&auth_context, server, keytab, &ticket, &out_data,
+ /* We need to know who is the target prioncipal to set the password */
+ /* So add a new parameter to verify */
+ /* this is targetPrincipal */
+ if (verify (&auth_context, server, &targetPrincipal, keytab, &ticket, &out_data,
s, sa, sa_size, msg, len) == 0) {
- change (auth_context,
- ticket->client,
- s,
- sa, sa_size,
- &out_data);
+
+ change (auth_context, targetPrincipal, s, sa, sa_size, &out_data);
+
memset (out_data.data, 0, out_data.length);
krb5_free_ticket (context, ticket);
free (ticket);
@@ -610,3 +702,4 @@
return doit (keytab, port);
}
+
diff -Naur heimdal-0.6/lib/asn1/k5.asn1 heimdal-0.6-setpasswd/lib/asn1/k5.asn1
--- heimdal-0.6/lib/asn1/k5.asn1 2003-01-14 21:13:47.000000000 -0600
+++ heimdal-0.6-setpasswd/lib/asn1/k5.asn1 2003-06-09 18:45:48.000000000 -0500
@@ -440,6 +440,12 @@
e-data[12] OCTET STRING OPTIONAL
}
+ChangePasswdData ::= SEQUENCE {
+ newpasswd[0] OCTET STRING,
+ targname[1] PrincipalName OPTIONAL,
+ targrealm[2] Realm OPTIONAL
+ }
+
pvno INTEGER ::= 5 -- current Kerberos protocol version number
-- transited encodings
diff -Naur heimdal-0.6/lib/asn1/Makefile.am heimdal-0.6-setpasswd/lib/asn1/Makefile.am
--- heimdal-0.6/lib/asn1/Makefile.am 2003-05-12 10:20:44.000000000 -0500
+++ heimdal-0.6-setpasswd/lib/asn1/Makefile.am 2003-06-09 18:46:40.000000000 -0500
@@ -23,6 +23,7 @@
asn1_Authenticator.x \
asn1_AuthorizationData.x \
asn1_CKSUMTYPE.x \
+ asn1_ChangePasswdData.x \
asn1_Checksum.x \
asn1_ENCTYPE.x \
asn1_ETYPE_INFO.x \