]> git.sur5r.net Git - openldap/blob - servers/slapd/back-bdb/passwd.c
if continuation line starts with a tab, rewrite it to a space
[openldap] / servers / slapd / back-bdb / passwd.c
1 /* passwd.c - bdb 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 #include <ac/string.h>
12
13 #include "back-bdb.h"
14 #include "external.h"
15
16 int
17 bdb_exop_passwd(
18         Backend         *be,
19         Connection              *conn,
20         Operation               *op,
21         const char              *reqoid,
22         struct berval   *reqdata,
23         char                    **rspoid,
24         struct berval   **rspdata,
25         LDAPControl             *** rspctrls,
26         const char              **text,
27         struct berval   *** refs )
28 {
29         struct bdb_info *bdb = (struct bdb_info *) be->be_private;
30         int rc;
31         Entry *e = NULL;
32         struct berval *hash = NULL;
33         DB_TXN *ltid = NULL;
34         struct bdb_op_info opinfo;
35
36         struct berval *id = NULL;
37         struct berval *new = NULL;
38
39         char *dn;
40
41         assert( reqoid != NULL );
42         assert( strcmp( LDAP_EXOP_X_MODIFY_PASSWD, reqoid ) == 0 );
43
44         rc = slap_passwd_parse( reqdata,
45                 &id, NULL, &new, text );
46
47         Debug( LDAP_DEBUG_ARGS, "==> bdb_exop_passwd: \"%s\"\n",
48                 id ? id->bv_val : "", 0, 0 );
49
50         if( rc != LDAP_SUCCESS ) {
51                 goto done;
52         }
53
54         if( new == NULL || new->bv_len == 0 ) {
55                 new = slap_passwd_generate();
56
57                 if( new == NULL || new->bv_len == 0 ) {
58                         *text = "password generation failed.";
59                         rc = LDAP_OTHER;
60                         goto done;
61                 }
62                 
63                 *rspdata = slap_passwd_return( new );
64         }
65
66         hash = slap_passwd_hash( new );
67
68         if( hash == NULL || hash->bv_len == 0 ) {
69                 *text = "password hash failed";
70                 rc = LDAP_OTHER;
71                 goto done;
72         }
73
74         dn = id ? id->bv_val : op->o_dn;
75
76         Debug( LDAP_DEBUG_TRACE, "bdb_exop_passwd: \"%s\"%s\n",
77                 dn, id ? " (proxy)" : "", 0 );
78
79         if( dn == NULL || dn[0] == '\0' ) {
80                 *text = "No password is associated with the Root DSE";
81                 rc = LDAP_OPERATIONS_ERROR;
82                 goto done;
83         }
84
85         if (0) {
86 retry:  /* transaction retry */
87                 Debug( LDAP_DEBUG_TRACE, "bdb_exop_passwd: retrying...\n", 0, 0, 0 );
88                 rc = txn_abort( ltid );
89                 ltid = NULL;
90                 op->o_private = NULL;
91                 if( rc != 0 ) {
92                         rc = LDAP_OTHER;
93                         *text = "internal error";
94                         goto done;
95                 }
96         }
97
98         /* begin transaction */
99         rc = txn_begin( bdb->bi_dbenv, NULL, &ltid, 0 );
100         *text = NULL;
101         if( rc != 0 ) {
102                 Debug( LDAP_DEBUG_TRACE,
103                         "bdb_exop_passwd: txn_begin failed: %s (%d)\n",
104                         db_strerror(rc), rc, 0 );
105                 rc = LDAP_OTHER;
106                 *text = "internal error";
107                 goto done;
108         }
109
110         opinfo.boi_bdb = be;
111         opinfo.boi_txn = ltid;
112         opinfo.boi_err = 0;
113         op->o_private = &opinfo;
114
115         /* get entry */
116         rc = bdb_dn2entry( be, ltid, dn, &e, NULL, 0 );
117
118         switch(rc) {
119         case DB_LOCK_DEADLOCK:
120         case DB_LOCK_NOTGRANTED:
121                 goto retry;
122         case DB_NOTFOUND:
123         case 0:
124                 break;
125         default:
126                 rc = LDAP_OTHER;
127                 *text = "internal error";
128                 goto done;
129         }
130
131         if( e == NULL ) {
132                 *text = "could not locate authorization entry";
133                 rc = LDAP_NO_SUCH_OBJECT;
134                 goto done;
135         }
136
137         if( is_entry_alias( e ) ) {
138                 /* entry is an alias, don't allow operation */
139                 *text = "authorization entry is alias";
140                 rc = LDAP_ALIAS_PROBLEM;
141                 goto done;
142         }
143
144
145         if( is_entry_referral( e ) ) {
146                 /* entry is an referral, don't allow operation */
147                 *text = "authorization entry is referral";
148                 rc = LDAP_OPERATIONS_ERROR;
149                 goto done;
150         }
151
152         {
153                 Modifications ml;
154                 struct berval *vals[2];
155
156                 vals[0] = hash;
157                 vals[1] = NULL;
158
159                 ml.sml_desc = slap_schema.si_ad_userPassword;
160                 ml.sml_bvalues = vals;
161                 ml.sml_op = LDAP_MOD_REPLACE;
162                 ml.sml_next = NULL;
163
164                 rc = bdb_modify_internal( be, conn, op, ltid,
165                         &ml, e, text );
166
167                 switch(rc) {
168                 case DB_LOCK_DEADLOCK:
169                 case DB_LOCK_NOTGRANTED:
170                         bdb_entry_return( be, e );
171                         e = NULL;
172                         goto retry;
173                 case 0:
174                         break;
175                 default:
176                         rc = LDAP_OTHER;
177                         *text = "entry modify failed";
178                         goto done;
179                 }
180
181         }
182
183         /* change the entry itself */
184         rc = bdb_id2entry_update( be, ltid, e );
185         if( rc != 0 ) {
186                 switch(rc) {
187                 case DB_LOCK_DEADLOCK:
188                 case DB_LOCK_NOTGRANTED:
189                         bdb_entry_return( be, e );
190                         e = NULL;
191                         goto retry;
192                 }
193                 *text = "entry update failed";
194                 rc = LDAP_OTHER;
195         }
196
197 done:
198         if( e != NULL ) {
199                 bdb_entry_return( be, e );
200         }
201
202         if( id != NULL ) {
203                 ber_bvfree( id );
204         }
205
206         if( new != NULL ) {
207                 ber_bvfree( new );
208         }
209
210         if( hash != NULL ) {
211                 ber_bvfree( hash );
212         }
213
214         if( ltid != NULL ) {
215                 txn_abort( ltid );
216                 op->o_private = NULL;
217         }
218
219         return rc;
220 }