]> git.sur5r.net Git - openldap/commitdiff
add granular op restriction
authorPierangelo Masarati <ando@openldap.org>
Sat, 1 May 2004 17:53:37 +0000 (17:53 +0000)
committerPierangelo Masarati <ando@openldap.org>
Sat, 1 May 2004 17:53:37 +0000 (17:53 +0000)
doc/man/man5/slapd.conf.5
servers/slapd/backend.c
servers/slapd/config.c
servers/slapd/slap.h

index f3356344e042529c72981d59eea397c800a7ea5e..961bba83b69d661409c01863ec7360734936bfea 100644 (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.
index b8f4b17d0077b9956eef877d337e504b197a0f8b..b99ecdc1e2c2eab6c589a99b787ed032e11e49e5 100644 (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";
                }
index b2e147ade8548c2c67a91f0f3744e3ba8b086006..c0ca57b330ea404476f95840da43d1028b6aeaf8 100644 (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",
index e01c80dbec2e1cfa6dedd7b34cf71eff97e13ae0..1c0bf3175c5170716db96bdede840b3e0714aebb 100644 (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      \