1 /* $NetBSD: passwd.c,v 1.3 2021/08/14 16:14:56 christos Exp $ */
2
3 /* $OpenLDAP$ */
4 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 *
6 * Copyright 1998-2021 The OpenLDAP Foundation.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted only as authorized by the OpenLDAP
11 * Public License.
12 *
13 * A copy of this license is available in the file LICENSE in the
14 * top-level directory of the distribution or, alternatively, at
15 * <http://www.OpenLDAP.org/license.html>.
16 */
17 /* ACKNOWLEDGEMENTS:
18 * This program was originally developed by Kurt D. Zeilenga for inclusion in
19 * OpenLDAP Software.
20 */
21
22 #include <sys/cdefs.h>
23 __RCSID("$NetBSD: passwd.c,v 1.3 2021/08/14 16:14:56 christos Exp $");
24
25 #include "portable.h"
26
27 #include <stdio.h>
28 #include <ac/stdlib.h>
29 #include <ac/string.h>
30 #include <ac/time.h>
31
32 #include "ldap-int.h"
33
34 /*
35 * LDAP Password Modify (Extended) Operation (RFC 3062)
36 */
37
ldap_parse_passwd(LDAP * ld,LDAPMessage * res,struct berval * newpasswd)38 int ldap_parse_passwd(
39 LDAP *ld,
40 LDAPMessage *res,
41 struct berval *newpasswd )
42 {
43 int rc;
44 struct berval *retdata = NULL;
45
46 assert( ld != NULL );
47 assert( LDAP_VALID( ld ) );
48 assert( res != NULL );
49 assert( newpasswd != NULL );
50
51 newpasswd->bv_val = NULL;
52 newpasswd->bv_len = 0;
53
54 rc = ldap_parse_extended_result( ld, res, NULL, &retdata, 0 );
55 if ( rc != LDAP_SUCCESS ) {
56 return rc;
57 }
58
59 if ( retdata != NULL ) {
60 ber_tag_t tag;
61 BerElement *ber = ber_init( retdata );
62
63 if ( ber == NULL ) {
64 rc = ld->ld_errno = LDAP_NO_MEMORY;
65 goto done;
66 }
67
68 /* we should check the tag */
69 tag = ber_scanf( ber, "{o}", newpasswd );
70 ber_free( ber, 1 );
71
72 if ( tag == LBER_ERROR ) {
73 rc = ld->ld_errno = LDAP_DECODING_ERROR;
74 }
75 }
76
77 done:;
78 ber_bvfree( retdata );
79
80 return rc;
81 }
82
83 int
ldap_passwd(LDAP * ld,struct berval * user,struct berval * oldpw,struct berval * newpw,LDAPControl ** sctrls,LDAPControl ** cctrls,int * msgidp)84 ldap_passwd( LDAP *ld,
85 struct berval *user,
86 struct berval *oldpw,
87 struct berval *newpw,
88 LDAPControl **sctrls,
89 LDAPControl **cctrls,
90 int *msgidp )
91 {
92 int rc;
93 struct berval bv = BER_BVNULL;
94 BerElement *ber = NULL;
95
96 assert( ld != NULL );
97 assert( LDAP_VALID( ld ) );
98 assert( msgidp != NULL );
99
100 if( user != NULL || oldpw != NULL || newpw != NULL ) {
101 /* build change password control */
102 ber = ber_alloc_t( LBER_USE_DER );
103
104 if( ber == NULL ) {
105 ld->ld_errno = LDAP_NO_MEMORY;
106 return ld->ld_errno;
107 }
108
109 ber_printf( ber, "{" /*}*/ );
110
111 if( user != NULL ) {
112 ber_printf( ber, "tO",
113 LDAP_TAG_EXOP_MODIFY_PASSWD_ID, user );
114 }
115
116 if( oldpw != NULL ) {
117 ber_printf( ber, "tO",
118 LDAP_TAG_EXOP_MODIFY_PASSWD_OLD, oldpw );
119 }
120
121 if( newpw != NULL ) {
122 ber_printf( ber, "tO",
123 LDAP_TAG_EXOP_MODIFY_PASSWD_NEW, newpw );
124 }
125
126 ber_printf( ber, /*{*/ "N}" );
127
128 rc = ber_flatten2( ber, &bv, 0 );
129
130 if( rc < 0 ) {
131 ld->ld_errno = LDAP_ENCODING_ERROR;
132 return ld->ld_errno;
133 }
134
135 }
136
137 rc = ldap_extended_operation( ld, LDAP_EXOP_MODIFY_PASSWD,
138 bv.bv_val ? &bv : NULL, sctrls, cctrls, msgidp );
139
140 ber_free( ber, 1 );
141
142 return rc;
143 }
144
145 int
ldap_passwd_s(LDAP * ld,struct berval * user,struct berval * oldpw,struct berval * newpw,struct berval * newpasswd,LDAPControl ** sctrls,LDAPControl ** cctrls)146 ldap_passwd_s(
147 LDAP *ld,
148 struct berval *user,
149 struct berval *oldpw,
150 struct berval *newpw,
151 struct berval *newpasswd,
152 LDAPControl **sctrls,
153 LDAPControl **cctrls )
154 {
155 int rc;
156 int msgid;
157 LDAPMessage *res;
158
159 rc = ldap_passwd( ld, user, oldpw, newpw, sctrls, cctrls, &msgid );
160 if ( rc != LDAP_SUCCESS ) {
161 return rc;
162 }
163
164 if ( ldap_result( ld, msgid, LDAP_MSG_ALL, (struct timeval *) NULL, &res ) == -1 || !res ) {
165 return ld->ld_errno;
166 }
167
168 rc = ldap_parse_passwd( ld, res, newpasswd );
169 if( rc != LDAP_SUCCESS ) {
170 ldap_msgfree( res );
171 return rc;
172 }
173
174 return( ldap_result2error( ld, res, 1 ) );
175 }
176