~ttx/openldap/lucid-gssapi-495418

« back to all changes in this revision

Viewing changes to servers/slapd/starttls.c

  • Committer: Bazaar Package Importer
  • Author(s): Mathias Gug
  • Date: 2008-07-10 14:45:49 UTC
  • Revision ID: james.westby@ubuntu.com-20080710144549-wck73med0e72gfyo
Tags: upstream-2.4.10
ImportĀ upstreamĀ versionĀ 2.4.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $OpenLDAP: pkg/ldap/servers/slapd/starttls.c,v 1.41.2.3 2008/02/11 23:26:44 kurt Exp $ */
 
2
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
 
3
 *
 
4
 * Copyright 1998-2008 The OpenLDAP Foundation.
 
5
 * All rights reserved.
 
6
 *
 
7
 * Redistribution and use in source and binary forms, with or without
 
8
 * modification, are permitted only as authorized by the OpenLDAP
 
9
 * Public License.
 
10
 *
 
11
 * A copy of this license is available in the file LICENSE in the
 
12
 * top-level directory of the distribution or, alternatively, at
 
13
 * <http://www.OpenLDAP.org/license.html>.
 
14
 */
 
15
 
 
16
#include "portable.h"
 
17
 
 
18
#include <stdio.h>
 
19
#include <ac/socket.h>
 
20
#include <ac/string.h>
 
21
 
 
22
#include "slap.h"
 
23
#include "lber_pvt.h"
 
24
 
 
25
const struct berval slap_EXOP_START_TLS = BER_BVC(LDAP_EXOP_START_TLS);
 
26
 
 
27
#ifdef HAVE_TLS
 
28
int
 
29
starttls_extop ( Operation *op, SlapReply *rs )
 
30
{
 
31
        int rc;
 
32
 
 
33
        Statslog( LDAP_DEBUG_STATS, "%s STARTTLS\n",
 
34
            op->o_log_prefix, 0, 0, 0, 0 );
 
35
 
 
36
        if ( op->ore_reqdata != NULL ) {
 
37
                /* no request data should be provided */
 
38
                rs->sr_text = "no request data expected";
 
39
                return LDAP_PROTOCOL_ERROR;
 
40
        }
 
41
 
 
42
        /* acquire connection lock */
 
43
        ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex );
 
44
 
 
45
        /* can't start TLS if it is already started */
 
46
        if (op->o_conn->c_is_tls != 0) {
 
47
                rs->sr_text = "TLS already started";
 
48
                rc = LDAP_OPERATIONS_ERROR;
 
49
                goto done;
 
50
        }
 
51
 
 
52
        /* can't start TLS if there are other op's around */
 
53
        if (( !LDAP_STAILQ_EMPTY(&op->o_conn->c_ops) &&
 
54
                        (LDAP_STAILQ_FIRST(&op->o_conn->c_ops) != op ||
 
55
                        LDAP_STAILQ_NEXT(op, o_next) != NULL)) ||
 
56
                ( !LDAP_STAILQ_EMPTY(&op->o_conn->c_pending_ops) ))
 
57
        {
 
58
                rs->sr_text = "cannot start TLS when operations are outstanding";
 
59
                rc = LDAP_OPERATIONS_ERROR;
 
60
                goto done;
 
61
        }
 
62
 
 
63
        if ( !( global_disallows & SLAP_DISALLOW_TLS_2_ANON ) &&
 
64
                ( op->o_conn->c_dn.bv_len != 0 ) )
 
65
        {
 
66
                Statslog( LDAP_DEBUG_STATS,
 
67
                        "%s AUTHZ anonymous mech=starttls ssf=0\n",
 
68
                        op->o_log_prefix, 0, 0, 0, 0 );
 
69
 
 
70
                /* force to anonymous */
 
71
                connection2anonymous( op->o_conn );
 
72
        }
 
73
 
 
74
        if ( ( global_disallows & SLAP_DISALLOW_TLS_AUTHC ) &&
 
75
                ( op->o_conn->c_dn.bv_len != 0 ) )
 
76
        {
 
77
                rs->sr_text = "cannot start TLS after authentication";
 
78
                rc = LDAP_OPERATIONS_ERROR;
 
79
                goto done;
 
80
        }
 
81
 
 
82
        /* fail if TLS could not be initialized */
 
83
        if ( slap_tls_ctx == NULL ) {
 
84
                if (default_referral != NULL) {
 
85
                        /* caller will put the referral in the result */
 
86
                        rc = LDAP_REFERRAL;
 
87
                        goto done;
 
88
                }
 
89
 
 
90
                rs->sr_text = "Could not initialize TLS";
 
91
                rc = LDAP_UNAVAILABLE;
 
92
                goto done;
 
93
        }
 
94
 
 
95
    op->o_conn->c_is_tls = 1;
 
96
    op->o_conn->c_needs_tls_accept = 1;
 
97
 
 
98
    rc = LDAP_SUCCESS;
 
99
 
 
100
done:
 
101
        /* give up connection lock */
 
102
        ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex );
 
103
 
 
104
        /* FIXME: RACE CONDITION! we give up lock before sending result
 
105
         * Should be resolved by reworking connection state, not
 
106
         * by moving send here (so as to ensure proper TLS sequencing)
 
107
         */
 
108
 
 
109
        return rc;
 
110
}
 
111
 
 
112
#endif  /* HAVE_TLS */