xref: /netbsd-src/external/bsd/openldap/dist/libraries/libldap/passwd.c (revision 549b59ed3ccf0d36d3097190a0db27b770f3a839)
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