]> git.sur5r.net Git - openldap/blob - servers/slapd/back-ldbm/passwd.c
Added bdb_attribute and bdb_group ACL support routines
[openldap] / servers / slapd / back-ldbm / passwd.c
1 /* passwd.c - ldbm backend password routines */
2 /* $OpenLDAP$ */
3 /*
4  * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
5  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
6  */
7
8 #include "portable.h"
9
10 #include <stdio.h>
11
12 #include <ac/socket.h>
13 #include <ac/string.h>
14
15 #include "slap.h"
16 #include "back-ldbm.h"
17 #include "proto-back-ldbm.h"
18
19 int
20 ldbm_back_exop_passwd(
21     Backend             *be,
22     Connection          *conn,
23     Operation           *op,
24         const char              *reqoid,
25     struct berval       *reqdata,
26         char                    **rspoid,
27     struct berval       **rspdata,
28         LDAPControl             *** rspctrls,
29         const char              **text,
30     struct berval       *** refs
31 )
32 {
33         struct ldbminfo *li = (struct ldbminfo *) be->be_private;
34         int rc;
35         Entry *e = NULL;
36         struct berval *hash = NULL;
37
38         struct berval *id = NULL;
39         struct berval *new = NULL;
40
41         char *dn;
42
43         assert( reqoid != NULL );
44         assert( strcmp( LDAP_EXOP_X_MODIFY_PASSWD, reqoid ) == 0 );
45
46         rc = slap_passwd_parse( reqdata,
47                 &id, NULL, &new, text );
48
49 #ifdef NEW_LOGGING
50         LDAP_LOG(( "backend", LDAP_LEVEL_ENTRY,
51                    "ldbm_back_exop_passwd: \"%s\"\n",
52                    id ? id->bv_val : "" ));
53 #else
54         Debug( LDAP_DEBUG_ARGS, "==> ldbm_back_exop_passwd: \"%s\"\n",
55                 id ? id->bv_val : "", 0, 0 );
56 #endif
57
58
59         if( rc != LDAP_SUCCESS ) {
60                 goto done;
61         }
62
63         if( new == NULL || new->bv_len == 0 ) {
64                 new = slap_passwd_generate();
65
66                 if( new == NULL || new->bv_len == 0 ) {
67                         *text = "password generation failed.";
68                         rc = LDAP_OTHER;
69                         goto done;
70                 }
71                 
72                 *rspdata = slap_passwd_return( new );
73         }
74
75         hash = slap_passwd_hash( new );
76
77         if( hash == NULL || hash->bv_len == 0 ) {
78                 *text = "password hash failed";
79                 rc = LDAP_OTHER;
80                 goto done;
81         }
82
83         dn = id ? id->bv_val : op->o_dn;
84
85 #ifdef NEW_LOGGING
86         LDAP_LOG(( "backend", LDAP_LEVEL_DETAIL1,
87                    "ldbm_back_exop_passwd: \"%s\"%s\n",
88                    dn, id ? " (proxy)" : "" ));
89 #else
90         Debug( LDAP_DEBUG_TRACE, "passwd: \"%s\"%s\n",
91                 dn, id ? " (proxy)" : "", 0 );
92 #endif
93
94
95         if( dn == NULL || dn[0] == '\0' ) {
96                 *text = "No password is associated with the Root DSE";
97                 rc = LDAP_OPERATIONS_ERROR;
98                 goto done;
99         }
100
101         if( dn_normalize( dn ) == NULL ) {
102                 *text = "Invalid DN";
103                 rc = LDAP_INVALID_DN_SYNTAX;
104                 goto done;
105         }
106
107         e = dn2entry_w( be, dn, NULL );
108
109         if( e == NULL ) {
110                 *text = "could not locate authorization entry";
111                 rc = LDAP_NO_SUCH_OBJECT;
112                 goto done;
113         }
114
115         if( is_entry_alias( e ) ) {
116                 /* entry is an alias, don't allow operation */
117                 *text = "authorization entry is alias";
118                 rc = LDAP_ALIAS_PROBLEM;
119                 goto done;
120         }
121
122         rc = LDAP_OPERATIONS_ERROR;
123
124         if( is_entry_referral( e ) ) {
125                 /* entry is an referral, don't allow operation */
126                 *text = "authorization entry is referral";
127                 goto done;
128         }
129
130         {
131                 Modifications ml;
132                 struct berval *vals[2];
133                 char textbuf[SLAP_TEXT_BUFLEN]; /* non-returnable */
134                 size_t textlen;
135
136                 vals[0] = hash;
137                 vals[1] = NULL;
138
139                 ml.sml_desc = slap_schema.si_ad_userPassword;
140                 ml.sml_bvalues = vals;
141                 ml.sml_op = LDAP_MOD_REPLACE;
142                 ml.sml_next = NULL;
143
144                 rc = ldbm_modify_internal( be,
145                         conn, op, op->o_ndn, &ml, e, text, textbuf, textlen );
146
147                 /* FIXME: ldbm_modify_internal may set *tex = textbuf,
148                  * which is BAD */
149                 if ( *text == textbuf ) {
150                         *text = NULL;
151                 }
152
153                 if( rc ) {
154                         /* cannot return textbuf */
155                         *text = "entry modify failed";
156                         goto done;
157                 }
158
159                 /* change the entry itself */
160                 if( id2entry_add( be, e ) != 0 ) {
161                         *text = "entry update failed";
162                         rc = LDAP_OTHER;
163                 }
164
165                 replog( be, op, e->e_dn, &ml );
166         }
167         
168 done:
169         if( e != NULL ) {
170                 cache_return_entry_w( &li->li_cache, e );
171         }
172
173         if( id != NULL ) {
174                 ber_bvfree( id );
175         }
176
177         if( new != NULL ) {
178                 ber_bvfree( new );
179         }
180
181         if( hash != NULL ) {
182                 ber_bvfree( hash );
183         }
184
185         return rc;
186 }