- val.bv_len = strlen( pw->pw_name );
- attr_merge( e, "cn", vals );
- attr_merge( e, "sn", vals );
- attr_merge( e, "uid", vals );
- val.bv_val = pw->pw_gecos;
- val.bv_len = strlen( pw->pw_gecos );
- attr_merge( e, "cn", vals );
- val.bv_val = "person";
- val.bv_len = strlen( val.bv_val );
- attr_merge( e, "objectclass", vals );
-
- return( e );
+ val.bv_len = pwlen;
+ attr_merge_normalize_one( e, slap_schema.si_ad_uid, &val, NULL ); /* required by uidObject */
+ attr_merge_normalize_one( e, slap_schema.si_ad_cn, &val, NULL ); /* required by person */
+ attr_merge_normalize_one( e, ad_sn, &val, NULL ); /* required by person */
+
+#ifdef HAVE_STRUCT_PASSWD_PW_GECOS
+ /*
+ * if gecos is present, add it as a cn. first process it
+ * according to standard BSD usage. If the processed cn has
+ * a space, use the tail as the surname.
+ */
+ if (pw->pw_gecos[0]) {
+ char *s;
+
+ 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, '&' );
+ if ( s ) {
+ char buf[1024];
+
+ 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;
+ }
+ }
+ val.bv_len = strlen( val.bv_val );
+
+ if ( val.bv_len && strcasecmp( val.bv_val, pw->pw_name ) ) {
+ attr_merge_normalize_one( e, slap_schema.si_ad_cn, &val, NULL );
+ }
+
+ if ( ( s = strrchr(val.bv_val, ' ' ) ) ) {
+ ber_str2bv( s + 1, 0, 0, &val );
+ attr_merge_normalize_one( e, ad_sn, &val, NULL );
+ }
+ }
+#endif /* HAVE_STRUCT_PASSWD_PW_GECOS */
+
+ return( 0 );