ITS#9446 - Correctly parse gecos field

This commit is contained in:
Konstantin Andreev 2021-03-03 10:37:19 +00:00 committed by Quanah Gibson-Mount
parent 7c37f14b69
commit f2481c8d88

View File

@ -321,7 +321,7 @@ pw2entry( Backend *be, struct passwd *pw, Entry *e )
#ifdef HAVE_STRUCT_PASSWD_PW_GECOS
/*
* if gecos is present, add it as a cn. first process it
* if gecos is present, add user's full name as a cn. first process it
* according to standard BSD usage. If the processed cn has
* a space, use the tail as the surname.
*/
@ -332,22 +332,39 @@ pw2entry( Backend *be, struct passwd *pw, Entry *e )
ber_str2bv( pw->pw_gecos, 0, 0, &val );
attr_merge_normalize_one( e, ad_desc, &val, NULL );
s = ber_bvchr( &val, ',' );
if ( s ) *s = '\0';
s = ber_bvchr( &val, '&' );
s = strchr( val.bv_val, (unsigned char)',' );
if ( s ) {
if( val.bv_len + pwlen < sizeof(buf) ) {
int i = s - val.bv_val;
strncpy( buf, val.bv_val, i );
s = buf + i;
strcpy( s, pw->pw_name );
*s = TOUPPER((unsigned char)*s);
strcat( s, val.bv_val + i + 1 );
val.bv_val = buf;
}
*s = '\0';
val.bv_len = s - val.bv_val;
}
val.bv_len = strlen( val.bv_val );
s = strchr( val.bv_val, (unsigned char)'&' );
if ( s ) {
unsigned r = sizeof buf;
/* if name with expanded `&` fits in buf */
if ( val.bv_len + pwlen <= r ) {
char * d = buf;
for (;;) {
size_t const i = s - val.bv_val;
memcpy( d, val.bv_val, i );
d += i;
memcpy( d, pw->pw_name, pwlen );
*d = TOUPPER((unsigned char)*pw->pw_name);
d += pwlen;
r -= pwlen + i;
val.bv_len -= i + 1;
val.bv_val = s + 1;
s = strchr( val.bv_val, (unsigned char)'&' );
if (!(s && ( val.bv_len + pwlen <= r )))
break;
}
strcpy( d, val.bv_val );
val.bv_len = d - buf + val.bv_len;
val.bv_val = buf;
} // 1st fits
} // 1st &
if ( val.bv_len && strcasecmp( val.bv_val, pw->pw_name ) ) {
attr_merge_normalize_one( e, slap_schema.si_ad_cn, &val, NULL );