]> git.sur5r.net Git - openldap/blob - servers/ldapd/kerberos.c
Add Kerberos V5 support from Predrag Balorda <pele@artewisdom.com>
[openldap] / servers / ldapd / kerberos.c
1 /*
2  * Copyright (c) 1990 Regents of the University of Michigan.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are permitted
6  * provided that this notice is preserved and that due credit is given
7  * to the University of Michigan at Ann Arbor. The name of the University
8  * may not be used to endorse or promote products derived from this
9  * software without specific prior written permission. This software
10  * is provided ``as is'' without express or implied warranty.
11  */
12
13 #ifdef KERBEROS
14
15 #include <stdio.h>
16 #include <sys/types.h>
17 #ifdef KERBEROS_V
18 #include <kerberosIV/krb.h>
19 #else
20 #include <krb.h>
21 #endif /* KERBEROS_V */
22 #include <sys/socket.h>
23 #include <netdb.h>
24 #include <netinet/in.h>
25 #include <quipu/bind.h>
26 #if ISODEPACKAGE == IC
27 #include <quipu/DAS-types.h>
28 #else
29 #include <pepsy/DAS-types.h>
30 #endif
31 #include "lber.h"
32 #include "ldap.h"
33 #include "common.h"
34
35 int
36 kerberosv4_ldap_auth( char *cred, long  len )
37 {
38         KTEXT_ST        k;
39         KTEXT           ktxt = &k;
40         char            instance[INST_SZ];
41         int             err;
42         AUTH_DAT        ad;
43         extern char     *krb_ldap_service;
44         extern char     *kerberos_keyfile;
45
46         Debug( LDAP_DEBUG_TRACE, "kerberosv4_ldap_auth\n", 0, 0, 0 );
47
48         SAFEMEMCPY( ktxt->dat, cred, len );
49         ktxt->length = len;
50
51         strcpy( instance, "*" );
52         if ( (err = krb_rd_req( ktxt, krb_ldap_service, instance, 0L,
53             &ad, kerberos_keyfile )) != KSUCCESS ) {
54                 Debug( LDAP_DEBUG_ANY, "krb_rd_req failed (%s)\n",
55                     krb_err_txt[err], 0, 0 );
56                 return( LDAP_INVALID_CREDENTIALS );
57         }
58
59         return( LDAP_SUCCESS );
60 }
61
62 int
63 kerberosv4_bindarg( 
64     struct ds_bind_arg  *ba,
65     DN                  dn,
66     char                *cred,
67     long                len,
68     u_long              *nonce
69 )
70 {
71         struct type_UNIV_EXTERNAL       *e;
72         struct kerberos_parms           kp;
73         PE                              pe;
74         struct timeval                  tv;
75         char                            realm[REALM_SZ];
76         int                             err;
77         extern char                     *krb_x500_service;
78         extern char                     *krb_x500_instance;
79
80         Debug( LDAP_DEBUG_TRACE, "kerberosv4_bindarg\n", 0, 0, 0 );
81
82         e = (struct type_UNIV_EXTERNAL *) calloc( 1,
83             sizeof(struct type_UNIV_EXTERNAL) );
84         e->encoding = (struct choice_UNIV_0 *) calloc( 1,
85             sizeof(struct choice_UNIV_0) );
86         ba->dba_external = e;
87         ba->dba_version = DBA_VERSION_V1988;
88         ba->dba_auth_type = DBA_AUTH_EXTERNAL;
89
90         e->indirect__reference = AUTH_TYPE_KERBEROS_V4;
91         e->direct__reference = NULLOID;
92         e->data__value__descriptor = str2qb( "KRBv4 client credentials",
93             24, 1 );
94
95         kp.kp_dn = dn;
96         kp.kp_version = AUTH_TYPE_KERBEROS_V4;
97
98         if ( (err = krb_get_lrealm( realm, 1 )) != KSUCCESS ) {
99                 Debug( LDAP_DEBUG_ANY, "krb_get_lrealm failed (%s)\n",
100                     krb_err_txt[err], 0, 0 );
101                 return( LDAP_OPERATIONS_ERROR );
102         }
103
104         gettimeofday( &tv, NULL );
105         *nonce = tv.tv_sec;
106         SAFEMEMCPY( kp.kp_ktxt.dat, cred, len );
107         kp.kp_ktxt.length = len;
108         if ( encode_kerberos_parms( &pe, &kp ) == NOTOK ) {
109                 Debug( LDAP_DEBUG_ANY, "kerberos parms encoding failed\n", 0,
110                     0, 0 );
111                 return( LDAP_OPERATIONS_ERROR );
112         }
113
114         e->encoding->offset = choice_UNIV_0_single__ASN1__type;
115         e->encoding->un.single__ASN1__type = pe;
116
117         return( 0 );
118 }
119
120 int
121 kerberos_check_mutual(
122     struct ds_bind_arg  *res,
123     u_long              nonce
124 )
125 {
126         struct type_UNIV_EXTERNAL       *e = res->dba_external;
127         struct kerberos_parms           *kp;
128         int                             ret;
129
130         Debug( LDAP_DEBUG_TRACE, "kerberos_check_mutual\n", 0, 0, 0 );
131
132         if ( decode_kerberos_parms( e->encoding->un.single__ASN1__type, &kp )
133             == NOTOK )
134                 return( NOTOK );
135         ret = ((kp->kp_nonce == (nonce + 1)) ? OK : NOTOK );
136
137         Debug( LDAP_DEBUG_TRACE, "expecting %d got %d\n", nonce, kp->kp_nonce,
138             0 );
139
140         pe_free( e->encoding->un.single__ASN1__type );
141         dn_free( kp->kp_dn );
142         free( (char *) kp );
143
144         return( ret );
145 }
146
147 #endif