home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / ldapsdk.zip / libraries / libldap / kbind.c < prev    next >
C/C++ Source or Header  |  2000-07-29  |  7KB  |  285 lines

  1. /* $OpenLDAP: pkg/ldap/libraries/libldap/kbind.c,v 1.15.6.4 2000/07/29 01:53:08 kurt Exp $ */
  2. /*
  3.  * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  4.  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  5.  */
  6. /*  Portions
  7.  *  Copyright (c) 1993 Regents of the University of Michigan.
  8.  *  All rights reserved.
  9.  *
  10.  *  kbind.c
  11.  */
  12.  
  13. /*
  14.  *    BindRequest ::= SEQUENCE {
  15.  *        version        INTEGER,
  16.  *        name        DistinguishedName,     -- who
  17.  *        authentication    CHOICE {
  18.  *            simple        [0] OCTET STRING -- passwd
  19. #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
  20.  *            krbv42ldap    [1] OCTET STRING
  21.  *            krbv42dsa    [2] OCTET STRING
  22. #endif
  23.  *            sasl        [3] SaslCredentials    -- LDAPv3
  24.  *        }
  25.  *    }
  26.  *
  27.  *    BindResponse ::= SEQUENCE {
  28.  *        COMPONENTS OF LDAPResult,
  29.  *        serverSaslCreds        OCTET STRING OPTIONAL -- LDAPv3
  30.  *    }
  31.  *
  32.  */
  33.  
  34. #include "portable.h"
  35.  
  36. #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
  37.  
  38. #include <stdio.h>
  39. #include <ac/stdlib.h>
  40.  
  41. #include <ac/krb.h>
  42. #include <ac/socket.h>
  43. #include <ac/string.h>
  44. #include <ac/time.h>
  45.  
  46. #include "ldap-int.h"
  47.  
  48.  
  49. /*
  50.  * ldap_kerberos_bind1 - initiate a bind to the ldap server using
  51.  * kerberos authentication.  The dn is supplied.  It is assumed the user
  52.  * already has a valid ticket granting ticket.  The msgid of the
  53.  * request is returned on success (suitable for passing to ldap_result()),
  54.  * -1 is returned if there's trouble.
  55.  *
  56.  * Example:
  57.  *    ldap_kerberos_bind1( ld, "cn=manager, o=university of michigan, c=us" )
  58.  */
  59. int
  60. ldap_kerberos_bind1( LDAP *ld, LDAP_CONST char *dn )
  61. {
  62.     BerElement    *ber;
  63.     char        *cred;
  64.     int        rc;
  65.     ber_len_t credlen;
  66.  
  67.     Debug( LDAP_DEBUG_TRACE, "ldap_kerberos_bind1\n", 0, 0, 0 );
  68.  
  69.     if( ld->ld_version > LDAP_VERSION2 ) {
  70.         ld->ld_errno = LDAP_NOT_SUPPORTED;
  71.         return -1;
  72.     }
  73.  
  74.     if ( dn == NULL )
  75.         dn = "";
  76.  
  77.     if ( (cred = ldap_get_kerberosv4_credentials( ld, dn, "ldapserver",
  78.         &credlen )) == NULL ) {
  79.         return( -1 );    /* ld_errno should already be set */
  80.     }
  81.  
  82.     /* create a message to send */
  83.     if ( (ber = ldap_alloc_ber_with_options( ld )) == NULL ) {
  84.         LDAP_FREE( cred );
  85.         return( -1 );
  86.     }
  87.  
  88.     /* fill it in */
  89.     rc = ber_printf( ber, "{it{istoN}N}", ++ld->ld_msgid, LDAP_REQ_BIND,
  90.         ld->ld_version, dn, LDAP_AUTH_KRBV41, cred, credlen );
  91.  
  92.     if ( rc == -1 ) {
  93.         LDAP_FREE( cred );
  94.         ber_free( ber, 1 );
  95.         ld->ld_errno = LDAP_ENCODING_ERROR;
  96.         return( -1 );
  97.     }
  98.  
  99.     LDAP_FREE( cred );
  100.  
  101. #ifndef LDAP_NOCACHE
  102.     if ( ld->ld_cache != NULL ) {
  103.         ldap_flush_cache( ld );
  104.     }
  105. #endif /* !LDAP_NOCACHE */
  106.  
  107.     /* send the message */
  108.     return ( ldap_send_initial_request( ld, LDAP_REQ_BIND, dn, ber ));
  109. }
  110.  
  111. int
  112. ldap_kerberos_bind1_s( LDAP *ld, LDAP_CONST char *dn )
  113. {
  114.     int        msgid;
  115.     LDAPMessage    *res;
  116.  
  117.     Debug( LDAP_DEBUG_TRACE, "ldap_kerberos_bind1_s\n", 0, 0, 0 );
  118.  
  119.     /* initiate the bind */
  120.     if ( (msgid = ldap_kerberos_bind1( ld, dn )) == -1 )
  121.         return( ld->ld_errno );
  122.  
  123.     /* wait for a result */
  124.     if ( ldap_result( ld, ld->ld_msgid, 1, (struct timeval *) 0, &res )
  125.         == -1 ) {
  126.         return( ld->ld_errno );    /* ldap_result sets ld_errno */
  127.     }
  128.  
  129.     return( ldap_result2error( ld, res, 1 ) );
  130. }
  131.  
  132. /*
  133.  * ldap_kerberos_bind2 - initiate a bind to the X.500 server using
  134.  * kerberos authentication.  The dn is supplied.  It is assumed the user
  135.  * already has a valid ticket granting ticket.  The msgid of the
  136.  * request is returned on success (suitable for passing to ldap_result()),
  137.  * -1 is returned if there's trouble.
  138.  *
  139.  * Example:
  140.  *    ldap_kerberos_bind2( ld, "cn=manager, o=university of michigan, c=us" )
  141.  */
  142. int
  143. ldap_kerberos_bind2( LDAP *ld, LDAP_CONST char *dn )
  144. {
  145.     BerElement    *ber;
  146.     char        *cred;
  147.     int        rc;
  148.     ber_len_t credlen;
  149.  
  150.     Debug( LDAP_DEBUG_TRACE, "ldap_kerberos_bind2\n", 0, 0, 0 );
  151.  
  152.     if( ld->ld_version > LDAP_VERSION2 ) {
  153.         ld->ld_errno = LDAP_NOT_SUPPORTED;
  154.         return -1;
  155.     }
  156.  
  157.     if ( dn == NULL )
  158.         dn = "";
  159.  
  160.     if ( (cred = ldap_get_kerberosv4_credentials( ld, dn, "x500dsa", &credlen ))
  161.         == NULL ) {
  162.         return( -1 );    /* ld_errno should already be set */
  163.     }
  164.  
  165.     /* create a message to send */
  166.     if ( (ber = ldap_alloc_ber_with_options( ld )) == NULL ) {
  167.         LDAP_FREE( cred );
  168.         return( -1 );
  169.     }
  170.  
  171.     /* fill it in */
  172.     rc = ber_printf( ber, "{it{istoN}N}", ++ld->ld_msgid, LDAP_REQ_BIND,
  173.         ld->ld_version, dn, LDAP_AUTH_KRBV42, cred, credlen );
  174.  
  175.  
  176.     LDAP_FREE( cred );
  177.  
  178.     if ( rc == -1 ) {
  179.         ber_free( ber, 1 );
  180.         ld->ld_errno = LDAP_ENCODING_ERROR;
  181.         return( -1 );
  182.     }
  183.  
  184.     /* send the message */
  185.     return ( ldap_send_initial_request( ld, LDAP_REQ_BIND, dn, ber ));
  186. }
  187.  
  188. /* synchronous bind to DSA using kerberos */
  189. int
  190. ldap_kerberos_bind2_s( LDAP *ld, LDAP_CONST char *dn )
  191. {
  192.     int        msgid;
  193.     LDAPMessage    *res;
  194.  
  195.     Debug( LDAP_DEBUG_TRACE, "ldap_kerberos_bind2_s\n", 0, 0, 0 );
  196.  
  197.     /* initiate the bind */
  198.     if ( (msgid = ldap_kerberos_bind2( ld, dn )) == -1 )
  199.         return( ld->ld_errno );
  200.  
  201.     /* wait for a result */
  202.     if ( ldap_result( ld, ld->ld_msgid, 1, (struct timeval *) 0, &res )
  203.         == -1 ) {
  204.         return( ld->ld_errno );    /* ldap_result sets ld_errno */
  205.     }
  206.  
  207.     return( ldap_result2error( ld, res, 1 ) );
  208. }
  209.  
  210. /* synchronous bind to ldap and DSA using kerberos */
  211. int
  212. ldap_kerberos_bind_s( LDAP *ld, LDAP_CONST char *dn )
  213. {
  214.     int    err;
  215.  
  216.     Debug( LDAP_DEBUG_TRACE, "ldap_kerberos_bind_s\n", 0, 0, 0 );
  217.  
  218.     if ( (err = ldap_kerberos_bind1_s( ld, dn )) != LDAP_SUCCESS )
  219.         return( err );
  220.  
  221.     return( ldap_kerberos_bind2_s( ld, dn ) );
  222. }
  223.  
  224.  
  225. #ifndef AUTHMAN
  226. /*
  227.  * ldap_get_kerberosv4_credentials - obtain kerberos v4 credentials for ldap.
  228.  * The dn of the entry to which to bind is supplied.  It's assumed the
  229.  * user already has a tgt.
  230.  */
  231.  
  232. char *
  233. ldap_get_kerberosv4_credentials(
  234.     LDAP *ld,
  235.     LDAP_CONST char *who,
  236.     LDAP_CONST char *service,
  237.     ber_len_t *len )
  238. {
  239.     KTEXT_ST    ktxt;
  240.     int        err;
  241.     char        realm[REALM_SZ], *cred, *krbinstance;
  242.  
  243.     Debug( LDAP_DEBUG_TRACE, "ldap_get_kerberosv4_credentials\n", 0, 0, 0 );
  244.  
  245.     if ( (err = krb_get_tf_realm( tkt_string(), realm )) != KSUCCESS ) {
  246. #ifdef LDAP_LIBUI
  247.         fprintf( stderr, "krb_get_tf_realm failed (%s)\n",
  248.             krb_err_txt[err] );
  249. #endif /* LDAP_LIBUI */
  250.         ld->ld_errno = LDAP_AUTH_UNKNOWN;
  251.         return( NULL );
  252.     }
  253.  
  254.     if ( ber_sockbuf_ctrl( ld->ld_sb, LBER_SB_OPT_GET_FD, NULL ) == -1 ) {
  255.         /* not connected yet */
  256.         int rc = ldap_open_defconn( ld );
  257.  
  258.         if( rc < 0 ) return NULL;
  259.     }
  260.  
  261.     krbinstance = ld->ld_defconn->lconn_krbinstance;
  262.  
  263.     if ( (err = krb_mk_req( &ktxt, service, krbinstance, realm, 0 ))
  264.         != KSUCCESS ) {
  265. #ifdef LDAP_LIBUI
  266.         fprintf( stderr, "krb_mk_req failed (%s)\n", krb_err_txt[err] );
  267. #endif /* LDAP_LIBUI */
  268.         ld->ld_errno = LDAP_AUTH_UNKNOWN;
  269.         return( NULL );
  270.     }
  271.  
  272.     if ( ( cred = LDAP_MALLOC( ktxt.length )) == NULL ) {
  273.         ld->ld_errno = LDAP_NO_MEMORY;
  274.         return( NULL );
  275.     }
  276.  
  277.     *len = ktxt.length;
  278.     AC_MEMCPY( cred, ktxt.dat, ktxt.length );
  279.  
  280.     return( cred );
  281. }
  282.  
  283. #endif /* !AUTHMAN */
  284. #endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND */
  285.