mirror of
https://git.openldap.org/openldap/openldap.git
synced 2024-12-15 03:01:09 +08:00
Modify password code such that backend end routine calls into
frontend to complete parsing of extended op reqdata. Modify password extended operation to allow optional id (DN) entry to change (not tested). Also, provide room to allow server side password generation (not implemented). Added optional old password field to support proxying (not implemented). Need to implement replog() support.
This commit is contained in:
parent
bb693fd1b5
commit
354d0d5b50
@ -27,8 +27,8 @@ static void
|
|||||||
usage(const char *s)
|
usage(const char *s)
|
||||||
{
|
{
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Usage: %s [options]\n"
|
"Usage: %s [options] dn\n"
|
||||||
" -D binddn\tbind dn\tREQUIRED\n"
|
" -D binddn\tbind dn\n"
|
||||||
" -d level\tdebugging level\n"
|
" -d level\tdebugging level\n"
|
||||||
" -h host\tldap server (default: localhost)\n"
|
" -h host\tldap server (default: localhost)\n"
|
||||||
" -n\t\tmake no modifications\n"
|
" -n\t\tmake no modifications\n"
|
||||||
@ -46,6 +46,7 @@ int
|
|||||||
main( int argc, char *argv[] )
|
main( int argc, char *argv[] )
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
char *dn = NULL;
|
||||||
char *binddn = NULL;
|
char *binddn = NULL;
|
||||||
char *bindpw = NULL;
|
char *bindpw = NULL;
|
||||||
char *ldaphost = NULL;
|
char *ldaphost = NULL;
|
||||||
@ -119,6 +120,12 @@ main( int argc, char *argv[] )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( argc - optind != 1 ) {
|
||||||
|
usage( argv[0] );
|
||||||
|
}
|
||||||
|
|
||||||
|
dn = strdup( argv[optind] );
|
||||||
|
|
||||||
if( newpw == NULL ) {
|
if( newpw == NULL ) {
|
||||||
/* prompt for new password */
|
/* prompt for new password */
|
||||||
char *cknewpw;
|
char *cknewpw;
|
||||||
@ -132,8 +139,8 @@ main( int argc, char *argv[] )
|
|||||||
}
|
}
|
||||||
|
|
||||||
if( binddn == NULL ) {
|
if( binddn == NULL ) {
|
||||||
fprintf( stderr, "no bind DN specified\n" );
|
binddn = dn;
|
||||||
return EXIT_FAILURE;
|
dn = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* handle bind password */
|
/* handle bind password */
|
||||||
@ -188,9 +195,19 @@ main( int argc, char *argv[] )
|
|||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ber_printf( ber, "{es}",
|
if( dn != NULL ) {
|
||||||
(ber_int_t) 0,
|
ber_printf( ber, "{tsts}",
|
||||||
newpw );
|
LDAP_TAG_EXOP_X_MODIFY_PASSWD_ID, dn,
|
||||||
|
LDAP_TAG_EXOP_X_MODIFY_PASSWD_NEW, newpw );
|
||||||
|
|
||||||
|
free(dn);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
ber_printf( ber, "{ts}",
|
||||||
|
LDAP_TAG_EXOP_X_MODIFY_PASSWD_NEW, newpw );
|
||||||
|
}
|
||||||
|
|
||||||
|
free(newpw);
|
||||||
|
|
||||||
rc = ber_flatten( ber, &bv );
|
rc = ber_flatten( ber, &bv );
|
||||||
|
|
||||||
|
@ -96,6 +96,8 @@ ber_skip_tag( BerElement *ber, ber_len_t *len )
|
|||||||
* 2) primitive encodings used whenever possible
|
* 2) primitive encodings used whenever possible
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
*len = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* First, we read the tag.
|
* First, we read the tag.
|
||||||
*/
|
*/
|
||||||
@ -110,8 +112,6 @@ ber_skip_tag( BerElement *ber, ber_len_t *len )
|
|||||||
* greater than what we can hold in a ber_len_t.
|
* greater than what we can hold in a ber_len_t.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
*len = 0;
|
|
||||||
|
|
||||||
if ( ber_read( ber, (char *) &lc, 1 ) != 1 )
|
if ( ber_read( ber, (char *) &lc, 1 ) != 1 )
|
||||||
return( LBER_DEFAULT );
|
return( LBER_DEFAULT );
|
||||||
|
|
||||||
@ -149,6 +149,8 @@ ber_peek_tag(
|
|||||||
assert( ber_in != NULL );
|
assert( ber_in != NULL );
|
||||||
assert( BER_VALID( ber_in ) );
|
assert( BER_VALID( ber_in ) );
|
||||||
|
|
||||||
|
*len = 0;
|
||||||
|
|
||||||
ber = ber_dup( ber_in );
|
ber = ber_dup( ber_in );
|
||||||
|
|
||||||
if( ber == NULL ) {
|
if( ber == NULL ) {
|
||||||
|
@ -28,30 +28,61 @@ ldbm_back_exop_passwd(
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
|
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
|
||||||
int rc = LDAP_OPERATIONS_ERROR;
|
int rc;
|
||||||
Entry *e;
|
Entry *e = NULL;
|
||||||
struct berval *cred = NULL;
|
struct berval *hash = NULL;
|
||||||
|
|
||||||
|
struct berval *id = NULL;
|
||||||
|
struct berval *new = NULL;
|
||||||
|
|
||||||
|
char *dn;
|
||||||
|
|
||||||
assert( oid != NULL );
|
assert( oid != NULL );
|
||||||
assert( strcmp( LDAP_EXOP_X_MODIFY_PASSWD, oid ) == 0 );
|
assert( strcmp( LDAP_EXOP_X_MODIFY_PASSWD, oid ) == 0 );
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_ARGS, "==> ldbm_back_exop_passwd: dn: %s\n",
|
rc = slap_passwd_parse( reqdata,
|
||||||
op->o_dn, 0, 0 );
|
&id, NULL, &new, text );
|
||||||
|
|
||||||
|
Debug( LDAP_DEBUG_ARGS, "==> ldbm_back_exop_passwd: \"%s\"\n",
|
||||||
|
id ? id->bv_val : "", 0, 0 );
|
||||||
|
|
||||||
cred = slap_passwd_generate( reqdata );
|
if( rc != LDAP_SUCCESS ) {
|
||||||
if( cred == NULL || cred->bv_len == 0 ) {
|
goto done;
|
||||||
*text = ch_strdup("password generation failed");
|
|
||||||
return LDAP_OPERATIONS_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "passwd: %s\n", cred->bv_val, 0, 0 );
|
if( new == NULL || new->bv_len == 0 ) {
|
||||||
|
*text = ch_strdup("no password provided");
|
||||||
|
rc = LDAP_OPERATIONS_ERROR;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
e = dn2entry_w( be, op->o_ndn, NULL );
|
hash = slap_passwd_generate( new );
|
||||||
|
|
||||||
|
if( hash == NULL || hash->bv_len == 0 ) {
|
||||||
|
*text = ch_strdup("password generation failed");
|
||||||
|
rc = LDAP_OPERATIONS_ERROR;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
dn = id ? id->bv_val : op->o_dn;
|
||||||
|
|
||||||
|
Debug( LDAP_DEBUG_TRACE, "passwd: \"%s\"%s\n",
|
||||||
|
dn, id ? " (proxy)" : "", 0 );
|
||||||
|
|
||||||
|
if( dn == NULL || dn[0] == NULL ) {
|
||||||
|
*text = ch_strdup("No password is associated with the Root DSE");
|
||||||
|
rc = LDAP_OPERATIONS_ERROR;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
e = dn2entry_w( be,
|
||||||
|
id ? id->bv_val : op->o_dn,
|
||||||
|
NULL );
|
||||||
|
|
||||||
if( e == NULL ) {
|
if( e == NULL ) {
|
||||||
*text = ch_strdup("could not locate authorization entry");
|
*text = ch_strdup("could not locate authorization entry");
|
||||||
return LDAP_OPERATIONS_ERROR;
|
rc = LDAP_OPERATIONS_ERROR;
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ! access_allowed( be, conn, op, e, "entry", NULL, ACL_WRITE ) ) {
|
if( ! access_allowed( be, conn, op, e, "entry", NULL, ACL_WRITE ) ) {
|
||||||
@ -67,6 +98,8 @@ ldbm_back_exop_passwd(
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rc = LDAP_OPERATIONS_ERROR;
|
||||||
|
|
||||||
if( is_entry_referral( e ) ) {
|
if( is_entry_referral( e ) ) {
|
||||||
/* entry is an referral, don't allow operation */
|
/* entry is an referral, don't allow operation */
|
||||||
*text = ch_strdup("authorization entry is referral");
|
*text = ch_strdup("authorization entry is referral");
|
||||||
@ -77,7 +110,7 @@ ldbm_back_exop_passwd(
|
|||||||
LDAPModList ml;
|
LDAPModList ml;
|
||||||
struct berval *vals[2];
|
struct berval *vals[2];
|
||||||
|
|
||||||
vals[0] = cred;
|
vals[0] = hash;
|
||||||
vals[1] = NULL;
|
vals[1] = NULL;
|
||||||
|
|
||||||
ml.ml_type = ch_strdup("userPassword");
|
ml.ml_type = ch_strdup("userPassword");
|
||||||
@ -99,10 +132,20 @@ ldbm_back_exop_passwd(
|
|||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
cache_return_entry_w( &li->li_cache, e );
|
if( e != NULL ) {
|
||||||
|
cache_return_entry_w( &li->li_cache, e );
|
||||||
|
}
|
||||||
|
|
||||||
if( cred != NULL ) {
|
if( id != NULL ) {
|
||||||
ber_bvfree( cred );
|
ber_bvfree( id );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( new != NULL ) {
|
||||||
|
ber_bvfree( new );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( hash != NULL ) {
|
||||||
|
ber_bvfree( hash );
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
|
@ -24,9 +24,6 @@ static int passwd_main(
|
|||||||
struct berval *reqdata, struct berval **rspdata, char **text )
|
struct berval *reqdata, struct berval **rspdata, char **text )
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
BerElement *ber;
|
|
||||||
struct berval *cred = NULL;
|
|
||||||
ber_int_t type;
|
|
||||||
|
|
||||||
assert( oid != NULL );
|
assert( oid != NULL );
|
||||||
assert( strcmp( LDAP_EXOP_X_MODIFY_PASSWD, oid ) == 0 );
|
assert( strcmp( LDAP_EXOP_X_MODIFY_PASSWD, oid ) == 0 );
|
||||||
@ -37,33 +34,7 @@ static int passwd_main(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if( reqdata == NULL || reqdata->bv_len == 0 ) {
|
if( reqdata == NULL || reqdata->bv_len == 0 ) {
|
||||||
*text = ch_strdup("data missing");
|
*text = ch_strdup("request data missing");
|
||||||
return LDAP_PROTOCOL_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
ber = ber_init( reqdata );
|
|
||||||
|
|
||||||
if( ber == NULL ) {
|
|
||||||
*text = ch_strdup("password decoding error");
|
|
||||||
return LDAP_PROTOCOL_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = ber_scanf(ber, "{iO}", &type, &cred );
|
|
||||||
ber_free( ber, 1 );
|
|
||||||
|
|
||||||
if( rc == LBER_ERROR ) {
|
|
||||||
*text = ch_strdup("data decoding error");
|
|
||||||
return LDAP_PROTOCOL_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( cred == NULL || cred->bv_len == 0 ) {
|
|
||||||
*text = ch_strdup("password missing");
|
|
||||||
return LDAP_PROTOCOL_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( type != 0 ) {
|
|
||||||
ber_bvfree( cred );
|
|
||||||
*text = ch_strdup("password type unknown");
|
|
||||||
return LDAP_PROTOCOL_ERROR;
|
return LDAP_PROTOCOL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,15 +43,135 @@ static int passwd_main(
|
|||||||
{
|
{
|
||||||
rc = conn->c_authz_backend->be_extended(
|
rc = conn->c_authz_backend->be_extended(
|
||||||
conn->c_authz_backend,
|
conn->c_authz_backend,
|
||||||
conn, op,
|
conn, op, oid, reqdata, rspdata, text );
|
||||||
oid, cred, rspdata, text );
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
*text = ch_strdup("operation not supported for current user");
|
*text = ch_strdup("operation not supported for current user");
|
||||||
rc = LDAP_UNWILLING_TO_PERFORM;
|
rc = LDAP_UNWILLING_TO_PERFORM;
|
||||||
}
|
}
|
||||||
|
|
||||||
ber_bvfree( cred );
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
int slap_passwd_parse( struct berval *reqdata,
|
||||||
|
struct berval **id,
|
||||||
|
struct berval **old,
|
||||||
|
struct berval **new,
|
||||||
|
char **text )
|
||||||
|
{
|
||||||
|
int rc = LDAP_SUCCESS;
|
||||||
|
ber_tag_t tag;
|
||||||
|
ber_len_t len;
|
||||||
|
BerElement *ber;
|
||||||
|
|
||||||
|
assert( reqdata != NULL );
|
||||||
|
|
||||||
|
ber = ber_init( reqdata );
|
||||||
|
|
||||||
|
if( ber == NULL ) {
|
||||||
|
Debug( LDAP_DEBUG_TRACE, "slap_passwd_parse: ber_init failed\n",
|
||||||
|
0, 0, 0 );
|
||||||
|
*text = ch_strdup("password decoding error");
|
||||||
|
return LDAP_PROTOCOL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
tag = ber_scanf(ber, "{" /*}*/);
|
||||||
|
|
||||||
|
if( tag == LBER_ERROR ) {
|
||||||
|
goto decoding_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
tag = ber_peek_tag( ber, &len );
|
||||||
|
|
||||||
|
if( tag == LDAP_TAG_EXOP_X_MODIFY_PASSWD_ID ) {
|
||||||
|
if( id == NULL ) {
|
||||||
|
Debug( LDAP_DEBUG_TRACE, "slap_passwd_parse: ID not allowed.\n",
|
||||||
|
0, 0, 0 );
|
||||||
|
*text = "user must change own password";
|
||||||
|
rc = LDAP_UNWILLING_TO_PERFORM;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
tag = ber_scanf( ber, "O", id );
|
||||||
|
|
||||||
|
if( tag == LBER_ERROR ) {
|
||||||
|
Debug( LDAP_DEBUG_TRACE, "slap_passwd_parse: ID parse failed.\n",
|
||||||
|
0, 0, 0 );
|
||||||
|
goto decoding_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
tag = ber_peek_tag( ber, &len);
|
||||||
|
}
|
||||||
|
|
||||||
|
if( tag == LDAP_TAG_EXOP_X_MODIFY_PASSWD_OLD ) {
|
||||||
|
if( old == NULL ) {
|
||||||
|
Debug( LDAP_DEBUG_TRACE, "slap_passwd_parse: OLD not allowed.\n",
|
||||||
|
0, 0, 0 );
|
||||||
|
*text = "use bind to verify old password";
|
||||||
|
rc = LDAP_UNWILLING_TO_PERFORM;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
tag = ber_scanf( ber, "O", old );
|
||||||
|
|
||||||
|
if( tag == LBER_ERROR ) {
|
||||||
|
Debug( LDAP_DEBUG_TRACE, "slap_passwd_parse: ID parse failed.\n",
|
||||||
|
0, 0, 0 );
|
||||||
|
goto decoding_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
tag = ber_peek_tag( ber, &len);
|
||||||
|
}
|
||||||
|
|
||||||
|
if( tag == LDAP_TAG_EXOP_X_MODIFY_PASSWD_NEW ) {
|
||||||
|
if( new == NULL ) {
|
||||||
|
Debug( LDAP_DEBUG_TRACE, "slap_passwd_parse: NEW not allowed.\n",
|
||||||
|
0, 0, 0 );
|
||||||
|
*text = "user specified passwords disallowed";
|
||||||
|
rc = LDAP_UNWILLING_TO_PERFORM;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
tag = ber_scanf( ber, "O", new );
|
||||||
|
|
||||||
|
if( tag == LBER_ERROR ) {
|
||||||
|
Debug( LDAP_DEBUG_TRACE, "slap_passwd_parse: OLD parse failed.\n",
|
||||||
|
0, 0, 0 );
|
||||||
|
goto decoding_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
tag = ber_peek_tag( ber, &len );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( len != 0 ) {
|
||||||
|
decoding_error:
|
||||||
|
Debug( LDAP_DEBUG_TRACE,
|
||||||
|
"slap_passwd_parse: decoding error, len=%ld\n",
|
||||||
|
(long) len, 0, 0 );
|
||||||
|
|
||||||
|
*text = ch_strdup("data decoding error");
|
||||||
|
rc = LDAP_PROTOCOL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
if( rc != LDAP_SUCCESS ) {
|
||||||
|
if( id != NULL ) {
|
||||||
|
ber_bvfree( *id );
|
||||||
|
*id = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( old != NULL ) {
|
||||||
|
ber_bvfree( *old );
|
||||||
|
*old = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( new != NULL ) {
|
||||||
|
ber_bvfree( *new );
|
||||||
|
*new = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ber_free( ber, 1 );
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -480,12 +480,22 @@ LIBSLAPD_F (void) slap_init_user LDAP_P(( char *username, char *groupname ));
|
|||||||
/*
|
/*
|
||||||
* passwd.c
|
* passwd.c
|
||||||
*/
|
*/
|
||||||
|
LIBSLAPD_F (int) slap_passwd_init( void );
|
||||||
|
|
||||||
LIBSLAPD_F (int) slap_passwd_check(
|
LIBSLAPD_F (int) slap_passwd_check(
|
||||||
Attribute *attr,
|
Attribute *attr,
|
||||||
struct berval *cred );
|
struct berval *cred );
|
||||||
|
|
||||||
LIBSLAPD_F (struct berval *) slap_passwd_generate(
|
LIBSLAPD_F (struct berval *) slap_passwd_generate(
|
||||||
struct berval *cred );
|
struct berval *cred );
|
||||||
LIBSLAPD_F (int) slap_passwd_init( void );
|
|
||||||
|
LIBSLAPD_F (int) slap_passwd_parse(
|
||||||
|
struct berval *reqdata,
|
||||||
|
struct berval **id,
|
||||||
|
struct berval **old,
|
||||||
|
struct berval **new,
|
||||||
|
char **text );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* kerberos.c
|
* kerberos.c
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user