+ /* restricts specific operations */
+ } else if ( strcasecmp( cargv[0], "restrict" ) == 0 ) {
+ slap_mask_t restrictops = 0;
+ struct restrictable_exops_t {
+ char *name;
+ int flag;
+ } restrictable_exops[] = {
+ { LDAP_EXOP_START_TLS, SLAP_RESTRICT_EXOP_START_TLS },
+ { LDAP_EXOP_MODIFY_PASSWD, SLAP_RESTRICT_EXOP_MODIFY_PASSWD },
+ { LDAP_EXOP_X_WHO_AM_I, SLAP_RESTRICT_EXOP_WHOAMI },
+ { LDAP_EXOP_X_CANCEL, SLAP_RESTRICT_EXOP_CANCEL },
+ { NULL, 0 }
+ };
+ int i;
+
+ if ( cargc < 2 ) {
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: missing <op_list> in \"restrict <op_list>\" "
+ "line.\n", fname, lineno, 0 );
+ return 1;
+ }
+
+ for ( i = 1; i < cargc; i++ ) {
+ if ( strcasecmp( cargv[ i ], "read" ) == 0 ) {
+ restrictops |= SLAP_RESTRICT_OP_READS;
+
+ } else if ( strcasecmp( cargv[ i ], "write" ) == 0 ) {
+ restrictops |= SLAP_RESTRICT_OP_WRITES;
+
+ } else if ( strcasecmp( cargv[ i ], "add" ) == 0 ) {
+ restrictops |= SLAP_RESTRICT_OP_ADD;
+
+ } else if ( strcasecmp( cargv[ i ], "bind" ) == 0 ) {
+ restrictops |= SLAP_RESTRICT_OP_BIND;
+
+ } else if ( strcasecmp( cargv[ i ], "compare" ) == 0 ) {
+ restrictops |= SLAP_RESTRICT_OP_COMPARE;
+
+ } else if ( strcasecmp( cargv[ i ], "delete" ) == 0 ) {
+ restrictops |= SLAP_RESTRICT_OP_DELETE;
+
+ } else if ( strncasecmp( cargv[ i ], "extended",
+ STRLENOF( "extended" ) ) == 0 )
+ {
+ char *e = cargv[ i ] + STRLENOF( "extended" );
+
+ if ( e[0] == '=' ) {
+ int j;
+
+ e++;
+ for ( j = 0; restrictable_exops[ j ].name; j++ ) {
+ if ( strcmp( e, restrictable_exops[j].name ) == 0 )
+ {
+ restrictops |= restrictable_exops[ j ].flag;
+ break;
+ }
+ }
+
+ if ( restrictable_exops[ j ].name == NULL ) {
+ goto restrict_unknown;
+ }
+
+ restrictops &= ~SLAP_RESTRICT_OP_EXTENDED;
+
+ } else if ( e[0] == '\0' ) {
+ restrictops &= ~SLAP_RESTRICT_EXOP_MASK;
+ restrictops |= SLAP_RESTRICT_OP_EXTENDED;
+
+ } else {
+ goto restrict_unknown;
+ }
+
+ } else if ( strcasecmp( cargv[ i ], "modify" ) == 0 ) {
+ restrictops |= SLAP_RESTRICT_OP_MODIFY;
+
+ } else if ( strcasecmp( cargv[ i ], "rename" ) == 0
+ || strcasecmp( cargv[ i ], "modrdn" ) == 0 )
+ {
+ restrictops |= SLAP_RESTRICT_OP_RENAME;
+
+ } else if ( strcasecmp( cargv[ i ], "search" ) == 0 ) {
+ restrictops |= SLAP_RESTRICT_OP_SEARCH;
+
+ } else {
+restrict_unknown:;
+
+ Debug( LDAP_DEBUG_ANY, "%s: line %d: "
+ "unknown operation %s in \"allow <features>\" line\n",
+ fname, lineno, cargv[i] );
+ return 1;
+ }
+ }
+
+ if ( be == NULL ) {
+ frontendDB->be_restrictops |= restrictops;
+ } else {
+ be->be_restrictops |= restrictops;
+ }