Home | History | Annotate | Line # | Download | only in libldap
      1 /*	$NetBSD: passwd.c,v 1.4 2025/09/05 21:16:21 christos Exp $	*/
      2 
      3 /* $OpenLDAP$ */
      4 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
      5  *
      6  * Copyright 1998-2024 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.4 2025/09/05 21:16:21 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 
     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
     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
    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