1 /* bind.c - ldbm backend bind and unbind routines */
4 * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
5 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
13 #include <ac/socket.h>
14 #include <ac/string.h>
15 #include <ac/unistd.h>
23 Connection *conn, Operation *op,
25 struct berval *reqdata,
27 struct berval **rspdata,
28 LDAPControl ***rspctrls,
35 assert( reqoid != NULL );
36 assert( strcmp( LDAP_EXOP_MODIFY_PASSWD, reqoid ) == 0 );
38 if( op->o_dn.bv_len == 0 ) {
39 *text = "only authenticated users may change passwords";
40 return LDAP_STRONG_AUTH_REQUIRED;
43 ldap_pvt_thread_mutex_lock( &conn->c_mutex );
44 be = conn->c_authz_backend;
45 ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
48 *text = "operation not supported for SASL user";
49 return LDAP_UNWILLING_TO_PERFORM;
52 if( !be->be_extended ) {
53 *text = "operation not supported for current user";
54 return LDAP_UNWILLING_TO_PERFORM;
58 struct berval passwd = BER_BVC( LDAP_EXOP_MODIFY_PASSWD );
60 rc = backend_check_restrictions( be, conn, op, &passwd, text );
63 if( rc != LDAP_SUCCESS ) {
67 if( be->be_update_ndn.bv_len ) {
68 /* we SHOULD return a referral in this case */
69 *refs = referral_rewrite( be->be_update_refs,
70 NULL, NULL, LDAP_SCOPE_DEFAULT );
77 rspoid, rspdata, rspctrls,
84 int slap_passwd_parse( struct berval *reqdata,
86 struct berval *oldpass,
87 struct berval *newpass,
90 int rc = LDAP_SUCCESS;
94 BerElement *ber = (BerElement *)berbuf;
96 if( reqdata == NULL ) {
100 if( reqdata->bv_len == 0 ) {
101 *text = "empty request data field";
102 return LDAP_PROTOCOL_ERROR;
105 /* ber_init2 uses reqdata directly, doesn't allocate new buffers */
106 ber_init2( ber, reqdata, 0 );
108 tag = ber_scanf( ber, "{" /*}*/ );
110 if( tag != LBER_ERROR ) {
111 tag = ber_peek_tag( ber, &len );
114 if( tag == LDAP_TAG_EXOP_MODIFY_PASSWD_ID ) {
117 LDAP_LOG(( "operation", LDAP_LEVEL_ERR,
118 "slap_passwd_parse: ID not allowed.\n"));
120 Debug( LDAP_DEBUG_TRACE, "slap_passwd_parse: ID not allowed.\n",
124 *text = "user must change own password";
125 rc = LDAP_UNWILLING_TO_PERFORM;
129 tag = ber_scanf( ber, "m", id );
131 if( tag == LBER_ERROR ) {
133 LDAP_LOG(( "operation", LDAP_LEVEL_ERR,
134 "slap_passwd_parse: ID parse failed.\n"));
136 Debug( LDAP_DEBUG_TRACE, "slap_passwd_parse: ID parse failed.\n",
143 tag = ber_peek_tag( ber, &len);
146 if( tag == LDAP_TAG_EXOP_MODIFY_PASSWD_OLD ) {
147 if( oldpass == NULL ) {
149 LDAP_LOG(( "operation", LDAP_LEVEL_ERR,
150 "slap_passwd_parse: OLD not allowed.\n" ));
152 Debug( LDAP_DEBUG_TRACE, "slap_passwd_parse: OLD not allowed.\n",
156 *text = "use bind to verify old password";
157 rc = LDAP_UNWILLING_TO_PERFORM;
161 tag = ber_scanf( ber, "m", oldpass );
163 if( tag == LBER_ERROR ) {
165 LDAP_LOG(( "operation", LDAP_LEVEL_ERR,
166 "slap_passwd_parse: ID parse failed.\n" ));
168 Debug( LDAP_DEBUG_TRACE, "slap_passwd_parse: ID parse failed.\n",
175 tag = ber_peek_tag( ber, &len );
178 if( tag == LDAP_TAG_EXOP_MODIFY_PASSWD_NEW ) {
179 if( newpass == NULL ) {
181 LDAP_LOG(( "operation", LDAP_LEVEL_ERR,
182 "slap_passwd_parse: NEW not allowed.\n" ));
184 Debug( LDAP_DEBUG_TRACE, "slap_passwd_parse: NEW not allowed.\n",
188 *text = "user specified passwords disallowed";
189 rc = LDAP_UNWILLING_TO_PERFORM;
193 tag = ber_scanf( ber, "m", newpass );
195 if( tag == LBER_ERROR ) {
197 LDAP_LOG(( "operation", LDAP_LEVEL_ERR,
198 "slap_passwd_parse: OLD parse failed.\n"));
200 Debug( LDAP_DEBUG_TRACE, "slap_passwd_parse: OLD parse failed.\n",
207 tag = ber_peek_tag( ber, &len );
213 LDAP_LOG(( "operation", LDAP_LEVEL_ERR,
214 "slap_passwd_parse: decoding error, len=%ld\n", (long)len ));
216 Debug( LDAP_DEBUG_TRACE,
217 "slap_passwd_parse: decoding error, len=%ld\n",
221 *text = "data decoding error";
222 rc = LDAP_PROTOCOL_ERROR;
229 struct berval * slap_passwd_return(
230 struct berval *cred )
233 struct berval *bv = NULL;
235 /* opaque structure, size unknown but smaller than berbuf */
236 BerElement *ber = (BerElement *)berbuf;
238 assert( cred != NULL );
241 LDAP_LOG(( "operation", LDAP_LEVEL_ENTRY,
242 "slap_passwd_return: %ld\n",(long)cred->bv_len ));
244 Debug( LDAP_DEBUG_TRACE, "slap_passwd_return: %ld\n",
245 (long) cred->bv_len, 0, 0 );
248 ber_init_w_nullc( ber, LBER_USE_DER );
250 rc = ber_printf( ber, "{tON}",
251 LDAP_TAG_EXOP_MODIFY_PASSWD_GEN, cred );
254 (void) ber_flatten( ber, &bv );
266 struct berval *cred )
271 #if defined( SLAPD_CRYPT ) || defined( SLAPD_SPASSWD )
272 ldap_pvt_thread_mutex_lock( &passwd_mutex );
274 lutil_passwd_sasl_conn = conn->c_sasl_context;
278 for ( bv = a->a_vals; bv->bv_val != NULL; bv++ ) {
279 if( !lutil_passwd( bv, cred, NULL ) ) {
285 #if defined( SLAPD_CRYPT ) || defined( SLAPD_SPASSWD )
287 lutil_passwd_sasl_conn = NULL;
289 ldap_pvt_thread_mutex_unlock( &passwd_mutex );
296 slap_passwd_generate( struct berval *pass )
300 LDAP_LOG(( "operation", LDAP_LEVEL_ENTRY,
301 "slap_passwd_generate: begin\n" ));
303 Debug( LDAP_DEBUG_TRACE, "slap_passwd_generate\n", 0, 0, 0 );
306 * generate passwords of only 8 characters as some getpass(3)
307 * implementations truncate at 8 characters.
309 tmp = lutil_passwd_generate( 8 );
321 struct berval * cred,
322 struct berval * new )
325 #ifdef LUTIL_SHA1_BYTES
326 char* hash = default_passwd_hash ? default_passwd_hash : "{SSHA}";
328 char* hash = default_passwd_hash ? default_passwd_hash : "{SMD5}";
332 #if defined( SLAPD_CRYPT ) || defined( SLAPD_SPASSWD )
333 ldap_pvt_thread_mutex_lock( &passwd_mutex );
336 tmp = lutil_passwd_hash( cred , hash );
338 #if defined( SLAPD_CRYPT ) || defined( SLAPD_SPASSWD )
339 ldap_pvt_thread_mutex_unlock( &passwd_mutex );