From ffbb5d4ed2ba5d4cf75b6c1c971bdea51ba77d60 Mon Sep 17 00:00:00 2001 From: Jong Hyuk Choi Date: Sat, 18 Sep 2004 02:07:41 +0000 Subject: [PATCH] *oc support in attr list --- servers/slapd/config.c | 204 +++++++++++++++++++++++++++++++++++-- servers/slapd/proto-slap.h | 5 +- servers/slapd/slap.h | 1 + servers/slapd/slapcommon.c | 2 +- servers/slapd/syncrepl.c | 25 ++++- 5 files changed, 226 insertions(+), 11 deletions(-) diff --git a/servers/slapd/config.c b/servers/slapd/config.c index e0d0eab7af..c864bb547e 100644 --- a/servers/slapd/config.c +++ b/servers/slapd/config.c @@ -89,6 +89,10 @@ static int add_syncrepl LDAP_P(( Backend *, char **, int )); static int parse_syncrepl_line LDAP_P(( char **, int, syncinfo_t *)); static int get_attrs_from_file LDAP_P(( char ***, const char *, const char * )); +static int get_ocs_from_file LDAP_P(( + ObjectClass ***, const char *, const char *)); +static char **str2attrs( char ***, char *, const char * ); +static ObjectClass **str2ocs( ObjectClass ***, char *, const char * ); int read_config( const char *fname, int depth ) @@ -2280,6 +2284,8 @@ add_syncrepl( si->si_attrsonly = 0; si->si_attrs = (char **) ch_calloc( 1, sizeof( char * )); si->si_attrs[0] = NULL; + si->si_ocs = (ObjectClass **) ch_calloc( 1, sizeof( ObjectClass )); + si->si_ocs[0] = NULL; si->si_exattrs = (char **) ch_calloc( 1, sizeof( char * )); si->si_exattrs[0] = NULL; si->si_type = LDAP_SYNC_REFRESH_ONLY; @@ -2543,9 +2549,14 @@ parse_syncrepl_line( ch_free( attr_fname ); return -1; } + if ( get_ocs_from_file( &si->si_ocs, attr_fname, " ,\t" )) { + ch_free( attr_fname ); + return -1; + } ch_free( attr_fname ); } else { - str2clist( &si->si_attrs, val, " ,\t" ); + str2attrs( &si->si_attrs, val, " ,\t" ); + str2ocs( &si->si_ocs, val, " ,\t" ); } } else if ( !strncasecmp( cargv[ i ], EXATTRSSTR, sizeof( EXATTRSSTR ) - 1 ) ) @@ -2561,7 +2572,7 @@ parse_syncrepl_line( } ch_free( attr_fname ); } else { - str2clist( &si->si_exattrs, val, " ,\t" ); + str2attrs( &si->si_exattrs, val, " ,\t" ); } } else if ( !strncasecmp( cargv[ i ], TYPESTR, sizeof( TYPESTR ) - 1 ) ) @@ -2644,7 +2655,7 @@ parse_syncrepl_line( retry_list = (char **) ch_calloc( 1, sizeof( char * )); retry_list[0] = NULL; - str2clist( &retry_list, val, " ,\t" ); + slap_str2clist( &retry_list, val, " ,\t" ); for ( k = 0; retry_list && retry_list[k]; k++ ) ; n = k / 2; @@ -2710,8 +2721,130 @@ parse_syncrepl_line( return 0; } +static ObjectClass ** +str2ocs( ObjectClass ***out, char *in, const char *brkstr ) +{ + char **clist; + int i, k = 0; + ObjectClass *oc; + + clist = (char **) ch_calloc( 1, sizeof( char *)); + clist[0] = NULL; + + slap_str2clist( &clist, in, brkstr ); + + for ( i = 0; clist && clist[i]; i++ ) { + struct berval ocbv; + if (*clist[i] == '@' ) { + ber_str2bv( clist[i]+1, strlen(clist[i]+1), 1, &ocbv ); + oc = oc_bvfind( &ocbv ); + if ( oc ) { + k++; + } + } + ch_free( ocbv.bv_val ); + } + + *out = ch_realloc( *out, (k + 1) * sizeof( ObjectClass *)); + + for ( i = 0; clist && clist[i]; i++ ) { + struct berval ocbv; + if (*clist[i] == '@' ) { + ber_str2bv( clist[i]+1, strlen(clist[i]+1), 1, &ocbv ); + (*out)[i] = oc_bvfind( &ocbv ); + } + ch_free( ocbv.bv_val ); + } + + (*out)[i] = NULL; + + for ( i = 0; clist && clist[i]; i++ ) { + ch_free( clist[i] ); + } + ch_free( clist ); + + return (*out); +} + +static char ** +str2attrs( char ***out, char *in, const char *brkstr ) +{ + int i, j = 0, k = 0, l = 0; + ObjectClass *oc; + + slap_str2clist( out, in , brkstr ); + + for ( i = 0; *out && (*out)[i]; i++ ) { + if ( *(*out)[i] == '@' ) { + struct berval ocbv; + ber_str2bv( (*out)[i]+1, strlen((*out)[i]+1), 1, &ocbv ); + oc = oc_bvfind( &ocbv ); + if ( oc ) { + k++; + for ( j = 0; oc->soc_required && oc->soc_required[j]; j++ ); + l += j; + for ( j = 0; oc->soc_allowed && oc->soc_allowed[j]; j++ ); + l += j; + } + ch_free( ocbv.bv_val ); + } + } + + *out = ch_realloc( *out, (i - k + l + 1) * sizeof( char * )); + + for ( i = 0; *out && (*out)[i]; i++ ) { +retest1: + if ( *(*out)[i] == '@' ) { + struct berval ocbv; + ber_str2bv( (*out)[i]+1, strlen((*out)[i]+1), 1, &ocbv ); + oc = oc_bvfind( &ocbv ); + for ( k = i; (*out)[k]; k++ ) { + if ( k == i ) + ch_free( (*out)[i] ); + (*out)[k] = (*out)[k+1]; + } + k--; + if ( oc ) { + for ( j = 0; oc->soc_required && oc->soc_required[j]; j++ ) { + (*out)[k++] = ch_strdup( + oc->soc_required[j]->sat_cname.bv_val ); + } + for ( j = 0; oc->soc_allowed && oc->soc_allowed[j]; j++ ) { + (*out)[k++] = ch_strdup( + oc->soc_allowed[j]->sat_cname.bv_val ); + } + (*out)[k] = NULL; + } + ch_free( ocbv.bv_val ); + goto retest1; + } + } + + for ( i = 0; *out && (*out)[i]; i++ ) { + for ( j = i+1; *out && (*out)[j]; j++ ) { +retest2: + if ( !strcmp( (*out)[i], (*out)[j] )) { + ch_free( (*out)[j] ); + for ( k = j; (*out)[k]; k++ ) { + (*out)[k] = (*out)[k+1]; + } + if ( (*out)[j] != NULL ) + goto retest2; + else + break; + } + } + } + + for ( i = 0; *out && (*out)[i]; i++ ); + + *out = ch_realloc( *out, (i + 1) * sizeof( char * )); + + return (*out); +} + char ** -str2clist( char ***out, char *in, const char *brkstr ) +slap_str2clist( char ***out, char *in, const char *brkstr ) { char *str; char *s; @@ -2755,7 +2888,7 @@ str2clist( char ***out, char *in, const char *brkstr ) } #define LBUFSIZ 80 -int +static int get_attrs_from_file( char ***attrs, const char *fname, const char *brkstr ) { FILE *fp; @@ -2803,10 +2936,69 @@ get_attrs_from_file( char ***attrs, const char *fname, const char *brkstr ) lcur = line + strlen( line ); continue; } - str2clist( attrs, line, brkstr ); + str2attrs( attrs, line, brkstr ); + lcur = line; + } + ch_free( line ); + fclose(fp); + return 0; +} +#undef LBUFSIZ + +#define LBUFSIZ 80 +static int +get_ocs_from_file( ObjectClass ***ocs, const char *fname, const char *brkstr ) +{ + FILE *fp; + char *line = NULL; + char *lcur = NULL; + char *c; + size_t lmax = LBUFSIZ; + + fp = fopen( fname, "r" ); + if ( fp == NULL ) { + Debug( LDAP_DEBUG_ANY, + "get_ocs_from_file: failed to open attribute list file " + "\"%s\": %s\n", fname, strerror(errno), 0 ); + return 1; + } + + lcur = line = (char *) ch_malloc( lmax ); + if ( !line ) { + Debug( LDAP_DEBUG_ANY, + "get_ocs_from_file: could not allocate memory\n", + 0, 0, 0 ); + fclose(fp); + return 1; + } + + while ( fgets( lcur, LBUFSIZ, fp ) != NULL ) { + if (c = strchr( lcur, '\n' )) { + if ( c == line ) { + *c = '\0'; + } else if ( *(c-1) == '\r' ) { + *(c-1) = '\0'; + } else { + *c = '\0'; + } + } else { + lmax += LBUFSIZ; + line = (char *) ch_realloc( line, lmax ); + if ( !line ) { + Debug( LDAP_DEBUG_ANY, + "get_ocs_from_file: could not allocate memory\n", + 0, 0, 0 ); + fclose(fp); + return 1; + } + lcur = line + strlen( line ); + continue; + } + str2ocs( ocs, line, brkstr ); lcur = line; } ch_free( line ); fclose(fp); return 0; } +#undef LBUFSIZ diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index ddb45d4977..99dae3ace4 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -366,7 +366,10 @@ LDAP_SLAPD_F (int) get_supported_controls LDAP_P (( char ***ctrloidsp, slap_mask */ LDAP_SLAPD_F (int) read_config LDAP_P(( const char *fname, int depth )); LDAP_SLAPD_F (void) config_destroy LDAP_P ((void)); -LDAP_SLAPD_F (char **) str2clist LDAP_P(( char ***, char *, const char * )); +LDAP_SLAPD_F (char **) slap_str2clist LDAP_P(( + char ***, + char *, + const char * )); #ifdef LDAP_SLAPI LDAP_SLAPD_V (int) slapi_plugins_used; #endif diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index 0b7b5dba64..574c1b6840 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -1444,6 +1444,7 @@ typedef struct syncinfo_s { int si_scope; int si_attrsonly; char **si_attrs; + ObjectClass **si_ocs; char **si_exattrs; int si_type; time_t si_interval; diff --git a/servers/slapd/slapcommon.c b/servers/slapd/slapcommon.c index be318ed93b..6da5f80915 100644 --- a/servers/slapd/slapcommon.c +++ b/servers/slapd/slapcommon.c @@ -190,7 +190,7 @@ slap_tool_init( usage( tool, progname ); exit( EXIT_FAILURE ); } - str2clist( &replica_id_strlist, replica_id_string, "," ); + slap_str2clist( &replica_id_strlist, replica_id_string, "," ); for ( i = 0; replica_id_strlist && replica_id_strlist[i]; i++ ) ; replica_id_list = ch_calloc( i + 1, sizeof( int ) ); for ( i = 0; replica_id_strlist && replica_id_strlist[i]; i++ ) { diff --git a/servers/slapd/syncrepl.c b/servers/slapd/syncrepl.c index aa824ca24b..d9935e84a7 100644 --- a/servers/slapd/syncrepl.c +++ b/servers/slapd/syncrepl.c @@ -52,7 +52,7 @@ struct runqueue_s syncrepl_rq; void init_syncrepl(syncinfo_t *si) { - int i, j, k, n; + int i, j, k, l, n; char **tmp; if ( !sync_descs[0] ) { @@ -71,8 +71,9 @@ init_syncrepl(syncinfo_t *si) if ( strcmp( si->si_attrs[j], sync_descs[i]->ad_cname.bv_val ) == 0 ) { - ch_free( si->si_attrs[j] ); for ( k = j; si->si_attrs[k] != NULL; k++ ) { + if ( k == j ) + ch_free( si->si_attrs[k] ); si->si_attrs[k] = si->si_attrs[k+1]; } } @@ -110,13 +111,28 @@ init_syncrepl(syncinfo_t *si) if ( strcmp( si->si_exattrs[j], sync_descs[i]->ad_cname.bv_val ) == 0 ) { - ch_free( si->si_exattrs[j] ); for ( k = j; si->si_exattrs[k] != NULL; k++ ) { + if ( k == j ) + ch_free( si->si_exattrs[k] ); si->si_exattrs[k] = si->si_exattrs[k+1]; } } } } + for ( i = 0; si->si_exattrs[i] != NULL; i++ ) { + for ( j = 0; si->si_ocs[j]; j++ ) { + for ( k = 0; si->si_ocs[j]->soc_required[k]; k++ ) { + if (!strcmp( si->si_exattrs[i], + si->si_ocs[j]->soc_required[k]->sat_cname.bv_val )) { + for ( l = i; si->si_exattrs[l] != NULL; l++ ) { + if ( l == i ) + ch_free( si->si_exattrs[l] ); + si->si_exattrs[l] = si->si_exattrs[l+1]; + } + } + } + } + } } } @@ -2033,6 +2049,9 @@ syncinfo_free( syncinfo_t *sie ) } ch_free( sie->si_attrs ); } + if ( sie->si_ocs ) { + ch_free( sie->si_ocs ); + } if ( sie->si_exattrs ) { int i = 0; while ( sie->si_exattrs[i] != NULL ) { -- 2.39.5