add granular op restriction

This commit is contained in:
Pierangelo Masarati 2004-05-01 17:53:37 +00:00
parent 9284fbf8ad
commit 03c64541d4
4 changed files with 159 additions and 3 deletions

View File

@ -1273,6 +1273,34 @@ for more information. The specified file should be located
in a directory with limited read/write/execute access as the replication
logs may contain sensitive information.
.TP
.B restrict <oplist>
Specify a whitespace separated list of operations that are restricted.
If defined inside a database specification, restrictions apply only
to that database, otherwise they are global.
Operations can be any of
.BR add ,
.BR bind ,
.BR compare ,
.BR delete ,
.BR extended[=<OID>] ,
.BR modify ,
.BR rename ,
.BR search ,
or the special pseudo-operations
.B read
and
.BR write ,
which respectively summarize read and write operations.
The use of
.I restrict write
is equivalent to
.I readonly on
(see above).
The
.B extended
keyword allows to indicate the OID of the specific operation
to be restricted.
.TP
.B rootdn <dn>
Specify the distinguished name that is not subject to access control
or administrative limit restrictions for operations on this database.

View File

@ -940,6 +940,7 @@ backend_check_restrictions(
slap_mask_t restrictops;
slap_mask_t requires;
slap_mask_t opflag;
slap_mask_t exopflag;
slap_ssf_set_t *ssf;
int updateop = 0;
int starttls = 0;
@ -989,14 +990,23 @@ backend_check_restrictions(
if( bvmatch( opdata, &slap_EXOP_START_TLS ) ) {
session++;
starttls++;
exopflag = SLAP_RESTRICT_EXOP_START_TLS;
break;
}
if( bvmatch( opdata, &slap_EXOP_WHOAMI ) ) {
exopflag = SLAP_RESTRICT_EXOP_WHOAMI;
break;
}
if ( bvmatch( opdata, &slap_EXOP_CANCEL ) ) {
exopflag = SLAP_RESTRICT_EXOP_CANCEL;
break;
}
if ( bvmatch( opdata, &slap_EXOP_MODIFY_PASSWD ) ) {
exopflag = SLAP_RESTRICT_EXOP_MODIFY_PASSWD;
updateop++;
break;
}
@ -1179,9 +1189,12 @@ backend_check_restrictions(
}
if( restrictops & opflag ) {
if( restrictops == SLAP_RESTRICT_OP_READS ) {
if( ( restrictops & opflag )
|| ( exopflag && ( restrictops & exopflag ) ) ) {
if( ( restrictops & SLAP_RESTRICT_OP_MASK) == SLAP_RESTRICT_OP_READS ) {
rs->sr_text = "read operations restricted";
} else if ( restrictops & exopflag ) {
rs->sr_text = "extended operation restricted";
} else {
rs->sr_text = "operation restricted";
}

View File

@ -1304,6 +1304,114 @@ read_config( const char *fname, int depth )
}
}
/* restricts specific operations */
} else if ( strcasecmp( cargv[0], "restrict" ) == 0 ) {
slap_mask_t restrict = 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 ) {
#ifdef NEW_LOGGING
LDAP_LOG( CONFIG, CRIT,
"%s: line %d: missing <op_list> in \"restrict <op_list>\" "
"line.\n", fname, lineno ,0 );
#else
Debug( LDAP_DEBUG_ANY,
"%s: line %d: missing <op_list> in \"restrict <op_list>\" "
"line.\n", fname, lineno, 0 );
#endif
return( 1 );
}
for ( i = 1; i < cargc; i++ ) {
if ( strcasecmp( cargv[ i ], "read" ) == 0 ) {
restrict |= SLAP_RESTRICT_OP_READS;
} else if ( strcasecmp( cargv[ i ], "write" ) == 0 ) {
restrict |= SLAP_RESTRICT_OP_WRITES;
} else if ( strcasecmp( cargv[ i ], "add" ) == 0 ) {
restrict |= SLAP_RESTRICT_OP_ADD;
} else if ( strcasecmp( cargv[ i ], "bind" ) == 0 ) {
restrict |= SLAP_RESTRICT_OP_BIND;
} else if ( strcasecmp( cargv[ i ], "compare" ) == 0 ) {
restrict |= SLAP_RESTRICT_OP_COMPARE;
} else if ( strcasecmp( cargv[ i ], "delete" ) == 0 ) {
restrict |= SLAP_RESTRICT_OP_DELETE;
} else if ( strncasecmp( cargv[ i ], "extended",
STRLENOF( "extended" ) ) == 0 ) {
char *e = cargv[ i ] + STRLENOF( "extended" );
restrict |= SLAP_RESTRICT_OP_EXTENDED;
if ( e[0] == '=' ) {
int j;
e++;
for ( j = 0; restrictable_exops[ j ].name; j++ ) {
if ( strcmp( e, restrictable_exops[ j ].name ) == 0 ) {
restrict |= restrictable_exops[ j ].flag;
break;
}
}
if ( restrictable_exops[ j ].name == NULL ) {
goto restrict_unknown;
}
} else if ( e[0] == '\0' ) {
restrict = SLAP_RESTRICT_EXOP_MASK;
} else {
goto restrict_unknown;
}
} else if ( strcasecmp( cargv[ i ], "modify" ) == 0 ) {
restrict |= SLAP_RESTRICT_OP_MODIFY;
} else if ( strcasecmp( cargv[ i ], "rename" ) == 0
|| strcasecmp( cargv[ i ], "modrdn" ) == 0 ) {
restrict |= SLAP_RESTRICT_OP_RENAME;
} else if ( strcasecmp( cargv[ i ], "search" ) == 0 ) {
restrict |= SLAP_RESTRICT_OP_SEARCH;
} else {
restrict_unknown:;
#ifdef NEW_LOGGING
LDAP_LOG( CONFIG, CRIT, "%s: line %d: "
"unknown operation %s in \"allow <features>\" line.\n",
fname, lineno, cargv[i] );
#else
Debug( LDAP_DEBUG_ANY, "%s: line %d: "
"unknown operation %s in \"allow <features>\" line\n",
fname, lineno, cargv[i] );
#endif
return 1;
}
}
if ( be == NULL ) {
global_restrictops |= restrict;
} else {
be->be_restrictops |= restrict;
}
/* allow these features */
} else if ( strcasecmp( cargv[0], "allows" ) == 0 ||
@ -1357,7 +1465,7 @@ read_config( const char *fname, int depth )
#ifdef NEW_LOGGING
LDAP_LOG( CONFIG, CRIT, "%s: line %d: "
"unknown feature %s in \"allow <features>\" line.\n",
fname, lineno, cargv[1] );
fname, lineno, cargv[i] );
#else
Debug( LDAP_DEBUG_ANY, "%s: line %d: "
"unknown feature %s in \"allow <features>\" line\n",

View File

@ -1490,6 +1490,13 @@ struct slap_backend_db {
#define SLAP_RESTRICT_OP_MODIFY 0x0020U
#define SLAP_RESTRICT_OP_RENAME 0x0040U
#define SLAP_RESTRICT_OP_SEARCH 0x0080U
#define SLAP_RESTRICT_OP_MASK 0x00FFU
#define SLAP_RESTRICT_EXOP_START_TLS 0x0100U
#define SLAP_RESTRICT_EXOP_MODIFY_PASSWD 0x0200U
#define SLAP_RESTRICT_EXOP_WHOAMI 0x0400U
#define SLAP_RESTRICT_EXOP_CANCEL 0x0800U
#define SLAP_RESTRICT_EXOP_MASK 0xFF00U
#define SLAP_RESTRICT_OP_READS \
( SLAP_RESTRICT_OP_COMPARE \