]> git.sur5r.net Git - openldap/blob - servers/slapd/back-bdb/passwd.c
include external.h
[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 {
30         struct bdb_info *bdb = (struct bdb_info *) be->be_private;
31         int rc;
32         Entry *e = NULL;
33         struct berval *hash = NULL;
34         DB_TXN *ltid;
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, "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         /* fetch entry */
86         rc = dn2entry_w( be, NULL, dn, &e, NULL );
87
88         switch(rc) {
89         case DB_NOTFOUND:
90         case 0:
91                 break;
92         default:
93                 send_ldap_result( conn, op, rc=LDAP_OTHER,
94                     NULL, "internal error", NULL, NULL );
95                 return rc;
96         }
97
98         if( e == NULL ) {
99                 *text = "could not locate authorization entry";
100                 rc = LDAP_OPERATIONS_ERROR;
101                 goto done;
102         }
103
104         if( is_entry_alias( e ) ) {
105                 /* entry is an alias, don't allow operation */
106                 *text = "authorization entry is alias";
107                 rc = LDAP_ALIAS_PROBLEM;
108                 goto done;
109         }
110
111         rc = LDAP_OPERATIONS_ERROR;
112
113         if( is_entry_referral( e ) ) {
114                 /* entry is an referral, don't allow operation */
115                 *text = "authorization entry is referral";
116                 goto done;
117         }
118
119         {
120                 Modifications ml;
121                 struct berval *vals[2];
122
123                 vals[0] = hash;
124                 vals[1] = NULL;
125
126                 ml.sml_desc = slap_schema.si_ad_userPassword;
127                 ml.sml_bvalues = vals;
128                 ml.sml_op = LDAP_MOD_REPLACE;
129                 ml.sml_next = NULL;
130
131                 rc = bdb_modify_internal( be,
132                         conn, op, op->o_ndn, &ml, e, text );
133
134         }
135
136         if( rc == LDAP_SUCCESS ) {
137                 /* change the entry itself */
138                 if( bdb_id2entry_add( be, ltid, e ) != 0 ) {
139                         *text = "entry update failed";
140                         rc = LDAP_OTHER;
141                 }
142         }
143         
144 done:
145         if( e != NULL ) {
146                 bdb_entry_return( be, e );
147         }
148
149         if( id != NULL ) {
150                 ber_bvfree( id );
151         }
152
153         if( new != NULL ) {
154                 ber_bvfree( new );
155         }
156
157         if( hash != NULL ) {
158                 ber_bvfree( hash );
159         }
160
161         return rc;
162 }