extended.c 3.29 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/* extended.c - ldap backend extended routines */
/* $OpenLDAP$ */
/*
 * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
 */

#include "portable.h"

#include <stdio.h>
#include <ac/string.h>

#include "slap.h"
#include "back-ldap.h"
#include "lber_pvt.h"

BI_op_extended ldap_back_exop_passwd;

static struct exop {
	struct berval *oid;
	BI_op_extended	*extended;
} exop_table[] = {
	{ (struct berval *)&slap_EXOP_MODIFY_PASSWD, ldap_back_exop_passwd },
	{ NULL, NULL }
};

int
ldap_back_extended(
	Operation		*op,
30
	SlapReply		*rs )
31
32
33
34
{
	int i;

	for( i=0; exop_table[i].extended != NULL; i++ ) {
35
36
		if( ber_bvcmp( exop_table[i].oid, &op->oq_extended.rs_reqoid ) == 0 ) {
			return (exop_table[i].extended)( op, rs );
37
38
39
		}
	}

40
	rs->sr_text = "not supported within naming context";
41
42
43
44
45
46
	return LDAP_UNWILLING_TO_PERFORM;
}

int
ldap_back_exop_passwd(
	Operation		*op,
47
	SlapReply		*rs )
48
{
49
	struct ldapinfo *li = (struct ldapinfo *) op->o_bd->be_private;
50
51
52
53
	struct ldapconn *lc;
	struct berval id = { 0, NULL };
	struct berval old = { 0, NULL };
	struct berval new = { 0, NULL };
54
	struct berval dn, mdn = { 0, NULL }, newpw;
55
56
57
	LDAPMessage *res;
	ber_int_t msgid;
	int rc;
58
	dncookie dc;
59

Pierangelo Masarati's avatar
Pierangelo Masarati committed
60
61
	lc = ldap_back_getconn(op, rs);
	if (!lc || !ldap_back_dobind(lc, op, rs) ) {
62
63
64
		return -1;
	}

65
	rc = slap_passwd_parse( op->oq_extended.rs_reqdata, &id, &old, &new, &rs->sr_text );
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
	if (rc != LDAP_SUCCESS)
		return rc;
	
	if (id.bv_len) {
		dn = id;
	} else {
		dn = op->o_dn;
	}

#ifdef NEW_LOGGING
	LDAP_LOG ( ACL, DETAIL1, "ldap_back_exop_passwd: \"%s\"%s\"\n",
		dn.bv_val, id.bv_len ? " (proxy)" : "", 0 );
#else
	Debug( LDAP_DEBUG_TRACE, "ldap_back_exop_passwd: \"%s\"%s\n",
		dn.bv_val, id.bv_len ? " (proxy)" : "", 0 );
#endif

	if (dn.bv_len == 0) {
84
		rs->sr_text = "No password is associated with the Root DSE";
85
86
87
		return LDAP_UNWILLING_TO_PERFORM;
	}
	if (id.bv_len) {
88
		dc.li = li;
89
#ifdef ENABLE_REWRITE
90
91
92
93
94
95
96
97
98
99
		dc.conn = op->o_conn;
		dc.rs = rs;
		dc.ctx = "modifyPwd";
#else
		dc.tofrom = 1;
		dc.normalized = 0;
#endif
		if ( ldap_back_dn_massage( &dc, &dn, &mdn ) ) {
			send_ldap_result( op, rs );
			return -1;
100
101
102
103
104
		}
	}

	rc = ldap_passwd(lc->ld, id.bv_len ? &mdn : NULL, old.bv_len ? &old : NULL,
		new.bv_len ? &new : NULL, op->o_ctrls, NULL, &msgid);
105
106

	if (mdn.bv_val != dn.bv_val) {
107
		free(mdn.bv_val);
108
109
	}

110
111
112
113
114
115
116
	if (rc == LDAP_SUCCESS) {
		if (ldap_result(lc->ld, msgid, 1, NULL, &res) == -1) {
			ldap_get_option(lc->ld, LDAP_OPT_ERROR_NUMBER, &rc);
		} else {
			/* sigh. parse twice, because parse_passwd doesn't give
			 * us the err / match / msg info.
			 */
117
			rc = ldap_parse_result(lc->ld, res, &rs->sr_err, (char **)&rs->sr_matched, (char **)&rs->sr_text,
118
119
				NULL, NULL, 0);
			if (rc == LDAP_SUCCESS) {
120
				if (rs->sr_err == LDAP_SUCCESS) {
121
					rc = ldap_parse_passwd(lc->ld, res, &newpw);
122
					if (rc == LDAP_SUCCESS && newpw.bv_val) {
123
124
						rs->sr_type = REP_EXTENDED;
						rs->sr_rspdata = slap_passwd_return(&newpw);
125
						free(newpw.bv_val);
126
127
					}
				} else {
128
					rc = rs->sr_err;
129
130
131
132
133
134
				}
			}
			ldap_msgfree(res);
		}
	}
	if (rc != LDAP_SUCCESS) {
135
		rs->sr_err = ldap_back_map_result(rs);
136
137
138
139
140
		send_ldap_result(op, rs);
		if (rs->sr_matched) free((char *)rs->sr_matched);
		if (rs->sr_text) free((char *)rs->sr_text);
		rs->sr_matched = NULL;
		rs->sr_text = NULL;
141
142
143
144
		rc = -1;
	}
	return rc;
}