]> git.sur5r.net Git - openldap/commitdiff
add slapacl tool
authorPierangelo Masarati <ando@openldap.org>
Tue, 20 Apr 2004 00:08:44 +0000 (00:08 +0000)
committerPierangelo Masarati <ando@openldap.org>
Tue, 20 Apr 2004 00:08:44 +0000 (00:08 +0000)
servers/slapd/Makefile.in
servers/slapd/acl.c
servers/slapd/main.c
servers/slapd/proto-slap.h
servers/slapd/slapacl.c [new file with mode: 0644]
servers/slapd/slapauth.c
servers/slapd/slapcommon.c
servers/slapd/slapcommon.h

index a10736a6c3577b25628140ba7b0da11682ccd831..57fee8be3f230aeec7d8ddd4e1c210fd6806468c 100644 (file)
@@ -13,7 +13,7 @@
 ## top-level directory of the distribution or, alternatively, at
 ## <http://www.OpenLDAP.org/license.html>.
 
-SLAPTOOLS=slapadd slapcat slapdn slapindex slappasswd slaptest slapauth
+SLAPTOOLS=slapadd slapcat slapdn slapindex slappasswd slaptest slapauth slapacl
 PROGRAMS=slapd $(SLAPTOOLS)
 XPROGRAMS=sslapd libbackends.a .backend liboverlays.a
 XSRCS=version.c
@@ -37,7 +37,7 @@ SRCS  = main.c globals.c config.c daemon.c \
                backglue.c operational.c matchedValues.c cancel.c syncrepl.c \
                backover.c ctxcsn.c ldapsync.c sessionlog.c \
                slapadd.c slapcat.c slapcommon.c slapdn.c slapindex.c \
-               slappasswd.c slaptest.c slapauth.c \
+               slappasswd.c slaptest.c slapauth.c slapacl.c \
                $(@PLAT@_SRCS)
 
 OBJS   = main.o globals.o config.o daemon.o \
@@ -54,7 +54,7 @@ OBJS  = main.o globals.o config.o daemon.o \
                backglue.o operational.o matchedValues.o cancel.o syncrepl.o \
                backover.o ctxcsn.o ldapsync.o sessionlog.o \
                slapadd.o slapcat.o slapcommon.o slapdn.o slapindex.o \
-               slappasswd.o slaptest.o slapauth.o \
+               slappasswd.o slaptest.o slapauth.o slapacl.o \
                $(@PLAT@_OBJS)
 
 LDAP_INCDIR= ../../include -I$(srcdir)/slapi
index c337b8fe78ee8e21c61085933a4dbdda32b2362a..b001785eb8ea312b7b64efa7e9f6dc114056c762 100644 (file)
@@ -135,13 +135,14 @@ static int aci_match_set ( struct berval *subj, Operation *op,
  */
 
 int
-access_allowed(
+access_allowed_mask(
        Operation               *op,
        Entry           *e,
        AttributeDescription    *desc,
        struct berval   *val,
        slap_access_t   access,
-       AccessControlState *state )
+       AccessControlState *state,
+       slap_mask_t *maskp )
 {
        int                             ret = 1;
        int                             count;
@@ -162,6 +163,7 @@ access_allowed(
        assert( e != NULL );
        assert( desc != NULL );
        assert( access > ACL_NONE );
+       if ( maskp ) ACL_INVALIDATE( *maskp );
 
        attr = desc->ad_cname.bv_val;
 
@@ -238,6 +240,10 @@ access_allowed(
                    "<= root access granted\n",
                        0, 0, 0 );
 #endif
+               if ( maskp ) {
+                       mask = ACL_LVL_WRITE;
+               }
+
                goto done;
        }
 
@@ -278,6 +284,16 @@ access_allowed(
                        op->o_dn.bv_val ? op->o_dn.bv_val : "(anonymous)" );
 #endif
                ret = be->be_dfltaccess >= access;
+
+               if ( maskp ) {
+                       int     i;
+
+                       mask = ACL_PRIV_LEVEL;
+                       for ( i = ACL_NONE; i <= be->be_dfltaccess; i++ ) {
+                               mask |= ACL_ACCESS2PRIV( i );
+                       }
+               }
+
                goto done;
 
 #ifdef notdef
@@ -297,6 +313,16 @@ access_allowed(
                        global_default_access >= access ? "granted" : "denied", op->o_dn.bv_val );
 #endif
                ret = global_default_access >= access;
+
+               if ( maskp ) {
+                       int     i;
+
+                       mask = ACL_PRIV_LEVEL;
+                       for ( i = ACL_NONE; i <= global_default_access; i++ ) {
+                               mask |= ACL_ACCESS2PRIV( i );
+                       }
+               }
+
                goto done;
 #endif
        }
@@ -420,6 +446,7 @@ done:
                state->as_recorded |= ACL_STATE_RECORDED;
        }
        if (be_null) op->o_bd = NULL;
+       if ( maskp ) *maskp = mask;
        return ret;
 }
 
index 91887448df8db77dc31acd81f6001455b05c5f52..97ca93576ee81f3393328814476be3fcf30d8608 100644 (file)
@@ -66,7 +66,7 @@ static struct sockaddr_in     bind_addr;
 
 typedef int (MainFunc) LDAP_P(( int argc, char *argv[] ));
 extern MainFunc slapadd, slapcat, slapdn, slapindex, slappasswd,
-       slaptest, slapauth;
+       slaptest, slapauth, slapacl;
 
 static struct {
        char *name;
@@ -79,6 +79,7 @@ static struct {
        {"slappasswd", slappasswd},
        {"slaptest", slaptest},
        {"slapauth", slapauth},
+       {"slapacl", slapacl},
        /* NOTE: new tools must be added in chronological order,
         * not in alphabetical order, because for backwards
         * compatibility name[4] is used to identify the
index b7c77caaff0dc5f495b0b1544914828834645d66..0038438d62cc57df440994f1de73ed91a767def9 100644 (file)
@@ -34,11 +34,13 @@ LDAP_BEGIN_DECL
 /*
  * acl.c
  */
-LDAP_SLAPD_F (int) access_allowed LDAP_P((
+LDAP_SLAPD_F (int) access_allowed_mask LDAP_P((
        Operation *op,
        Entry *e, AttributeDescription *desc, struct berval *val,
        slap_access_t access,
-       AccessControlState *state ));
+       AccessControlState *state,
+       slap_mask_t *mask ));
+#define access_allowed(op,e,desc,val,access,state) access_allowed_mask(op,e,desc,val,access,state,NULL)
 LDAP_SLAPD_F (int) acl_check_modlist LDAP_P((
        Operation *op, Entry *e, Modifications *ml ));
 
diff --git a/servers/slapd/slapacl.c b/servers/slapd/slapacl.c
new file mode 100644 (file)
index 0000000..6caf938
--- /dev/null
@@ -0,0 +1,143 @@
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 2004 The OpenLDAP Foundation.
+ * Portions Copyright 2004 Pierangelo Masarati.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted only as authorized by the OpenLDAP
+ * Public License.
+ *
+ * A copy of this license is available in file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * <http://www.OpenLDAP.org/license.html>.
+ */
+/* ACKNOWLEDGEMENTS:
+ * This work was initially developed by Pierangelo Masarati for inclusion
+ * in OpenLDAP Software.
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/stdlib.h>
+
+#include <ac/ctype.h>
+#include <ac/string.h>
+#include <ac/socket.h>
+#include <ac/unistd.h>
+
+#include <lber.h>
+#include <ldif.h>
+#include <lutil.h>
+
+#include "slapcommon.h"
+
+int
+slapacl( int argc, char **argv )
+{
+       int                     rc = EXIT_SUCCESS;
+       const char              *progname = "slapacl";
+       Connection              conn;
+       Operation               op;
+       Entry                   e = { 0 };
+
+#ifdef NEW_LOGGING
+       lutil_log_initialize( argc, argv );
+#endif
+       slap_tool_init( progname, SLAPACL, argc, argv );
+
+       argv = &argv[ optind ];
+       argc -= optind;
+
+       memset( &conn, 0, sizeof( Connection ) );
+       memset( &op, 0, sizeof( Operation ) );
+
+       connection_fake_init( &conn, &op, &conn );
+
+       assert( be != NULL );
+
+       if ( !BER_BVISNULL( &authcID ) ) {
+               rc = slap_sasl_getdn( &conn, &op, &authcID, NULL, &authcDN, SLAP_GETDN_AUTHCID );
+               if ( rc != LDAP_SUCCESS ) {
+                       fprintf( stderr, "ID: <%s> check failed %d (%s)\n",
+                                       authcID.bv_val, rc,
+                                       ldap_err2string( rc ) );
+                       rc = 1;
+                       goto destroy;
+               }
+       }
+
+       if ( !BER_BVISNULL( &authcDN ) ) {
+               fprintf( stderr, "DN: \"%s\"\n", authcDN.bv_val );
+       }
+
+       assert( !BER_BVISNULL( &baseDN ) );
+       rc = dnPrettyNormal( NULL, &baseDN, &e.e_name, &e.e_nname, NULL );
+       if ( rc != LDAP_SUCCESS ) {
+               fprintf( stderr, "base=\"%s\" normalization failed %d (%s)\n",
+                               baseDN.bv_val, rc,
+                               ldap_err2string( rc ) );
+               rc = 1;
+               goto destroy;
+       }
+
+       op.o_bd = be;
+       if ( !BER_BVISNULL( &authcDN ) ) {
+               op.o_dn = authcDN;
+               op.o_ndn = authcDN;
+       }
+
+       for ( ; argc--; argv++ ) {
+               slap_mask_t             mask;
+               AttributeDescription    *desc = NULL;
+               int                     rc;
+               struct berval           val;
+               const char              *text;
+               char                    accessmaskbuf[ACCESSMASK_MAXLEN];
+               char                    *accessstr;
+               slap_access_t           access = ACL_AUTH;
+
+               val.bv_val = strchr( argv[0], ':' );
+               if ( val.bv_val != NULL ) {
+                       val.bv_val[0] = '\0';
+                       val.bv_val++;
+                       val.bv_len = strlen( val.bv_val );
+               }
+
+               accessstr = strchr( argv[0], '/' );
+               if ( accessstr != NULL ) {
+                       accessstr[0] = '\0';
+                       accessstr++;
+                       access = str2access( accessstr );
+                       if ( access == ACL_INVALID_ACCESS ) {
+                               fprintf( stderr, "unknown access \"%s\" for attribute \"%s\"\n",
+                                               accessstr, argv[0] );
+                               continue;
+                       }
+               }
+
+               rc = slap_str2ad( argv[0], &desc, &text );
+               if ( rc != LDAP_SUCCESS ) {
+                       fprintf( stderr, "slap_str2ad(%s) failed %d (%s)\n",
+                                       argv[0], rc, ldap_err2string( rc ) );
+                       continue;
+               }
+
+               rc = access_allowed_mask( &op, &e, desc, &val, access,
+                               NULL, &mask );
+
+               fprintf( stderr, "%s%s%s: %s\n",
+                               desc->ad_cname.bv_val,
+                               val.bv_val ? "=" : "",
+                               val.bv_val ? val.bv_val : "",
+                               accessmask2str( mask, accessmaskbuf ) );
+       }
+
+destroy:;
+       slap_tool_destroy();
+
+       return rc;
+}
+
index 8e998c5b0f78198306aba82377c9caa0dc078223..a01933b4b58d0a3b1bf0e3e5644c448f764d3793 100644 (file)
 static int
 do_check( Connection *c, Operation *op, struct berval *id )
 {
-       struct berval   authcDN;
+       struct berval   authcdn;
        int             rc;
 
-       rc = slap_sasl_getdn( c, op, id, NULL, &authcDN, SLAP_GETDN_AUTHCID );
+       rc = slap_sasl_getdn( c, op, id, NULL, &authcdn, SLAP_GETDN_AUTHCID );
        if ( rc != LDAP_SUCCESS ) {
                fprintf( stderr, "ID: <%s> check failed %d (%s)\n",
                                id->bv_val, rc,
@@ -49,7 +49,7 @@ do_check( Connection *c, Operation *op, struct berval *id )
                        
        } else {
                if ( !BER_BVISNULL( &authzID ) ) {
-                       rc = slap_sasl_authorized( op, &authcDN, &authzID );
+                       rc = slap_sasl_authorized( op, &authcdn, &authzID );
 
                        fprintf( stderr,
                                        "ID:      <%s>\n"
@@ -57,7 +57,7 @@ do_check( Connection *c, Operation *op, struct berval *id )
                                        "authzDN: <%s>\n"
                                        "authorization %s\n",
                                        id->bv_val,
-                                       authcDN.bv_val,
+                                       authcdn.bv_val,
                                        authzID.bv_val,
                                        rc == LDAP_SUCCESS ? "OK" : "failed" );
 
@@ -65,8 +65,8 @@ do_check( Connection *c, Operation *op, struct berval *id )
                        fprintf( stderr, "ID: <%s> check succeeded\n"
                                        "authcID:     <%s>\n",
                                        id->bv_val,
-                                       authcDN.bv_val );
-                       op->o_tmpfree( authcDN.bv_val, op->o_tmpmemctx );
+                                       authcdn.bv_val );
+                       op->o_tmpfree( authcdn.bv_val, op->o_tmpmemctx );
                }
                rc = 0;
        }
@@ -96,9 +96,9 @@ slapauth( int argc, char **argv )
        connection_fake_init( &conn, &op, &conn );
 
        if ( !BER_BVISNULL( &authzID ) ) {
-               struct berval   authzDN;
+               struct berval   authzdn;
                
-               rc = slap_sasl_getdn( &conn, &op, &authzID, NULL, &authzDN,
+               rc = slap_sasl_getdn( &conn, &op, &authzID, NULL, &authzdn,
                                SLAP_GETDN_AUTHZID );
                if ( rc != LDAP_SUCCESS ) {
                        fprintf( stderr, "authzID: <%s> check failed %d (%s)\n",
@@ -109,7 +109,7 @@ slapauth( int argc, char **argv )
                        goto destroy;
                } 
 
-               authzID = authzDN;
+               authzID = authzdn;
        }
 
 
@@ -120,11 +120,11 @@ slapauth( int argc, char **argv )
                }
 
                for ( ; argc--; argv++ ) {
-                       struct berval   authzDN;
+                       struct berval   authzdn;
                
                        ber_str2bv( argv[ 0 ], 0, 0, &authzID );
 
-                       rc = slap_sasl_getdn( &conn, &op, &authzID, NULL, &authzDN,
+                       rc = slap_sasl_getdn( &conn, &op, &authzID, NULL, &authzdn,
                                        SLAP_GETDN_AUTHZID );
                        if ( rc != LDAP_SUCCESS ) {
                                fprintf( stderr, "authzID: <%s> check failed %d (%s)\n",
@@ -135,7 +135,7 @@ slapauth( int argc, char **argv )
                                goto destroy;
                        }
 
-                       authzID = authzDN;
+                       authzID = authzdn;
 
                        rc = do_check( &conn, &op, &authcID );
 
index 857d4228486e6f55b6fc5a44dbf527c9bc1da705..f3c73d93a70a125a6fe5953fe9b1ddb529e93048 100644 (file)
@@ -73,6 +73,10 @@ usage( int tool, const char *progname )
        case SLAPAUTH:
                options = "\t[-U authcID] [-X authzID] ID [...]\n";
                break;
+
+       case SLAPACL:
+               options = "\t[-U authcID | -D authcDN] -b DN attr[/level][:value] [...]\n";
+               break;
        }
 
        if ( options != NULL ) {
@@ -138,6 +142,10 @@ slap_tool_init(
                mode |= SLAP_TOOL_READMAIN;
                break;
 
+       case SLAPACL:
+               options = "b:D:d:f:U:v";
+               break;
+
        default:
                fprintf( stderr, "%s: unknown tool mode (%d)\n",
                         progname, tool );
@@ -159,6 +167,10 @@ slap_tool_init(
                        ldap_debug += atoi( optarg );
                        break;
 
+               case 'D':
+                       ber_str2bv( optarg, 0, 0, &authcDN );
+                       break;
+
                case 'f':       /* specify a conf file */
                        conffile = strdup( optarg );
                        break;
@@ -284,6 +296,16 @@ slap_tool_init(
                }
                break;
 
+       case SLAPACL:
+               if ( !BER_BVISNULL( &authcDN ) && !BER_BVISNULL( &authcID ) ) {
+                       usage( tool, progname );
+               }
+               if ( BER_BVISNULL( &base ) ) {
+                       usage( tool, progname );
+               }
+               ber_dupbv( &baseDN, &base );
+               break;
+
        default:
                break;
        }
index ff29921cd1c54dcc9c2499bdf8fcc616e88ddd3d..41fca6f4fba5598d6746c4d6c1554a2b6e8e341c 100644 (file)
@@ -28,6 +28,7 @@ enum slaptool {
        SLAPPASSWD,     /* password generation tool */
        SLAPTEST,       /* slapd.conf test tool */
        SLAPAUTH,       /* test authz-regexp and authc/authz stuff */
+       SLAPACL,        /* test acl */
        SLAPLAST
 };
 
@@ -51,6 +52,8 @@ typedef struct tool_vars {
        int tv_dryrun;
        struct berval tv_sub_ndn;
        FILE    *tv_ldiffp;
+       struct berval tv_authcDN;
+       struct berval tv_baseDN;
        struct berval tv_authcID;
        struct berval tv_authzID;
 } tool_vars;
@@ -72,6 +75,8 @@ extern tool_vars tool_globals;
 #define dryrun tool_globals.tv_dryrun
 #define sub_ndn tool_globals.tv_sub_ndn
 #define ldiffp tool_globals.tv_ldiffp
+#define authcDN tool_globals.tv_authcDN
+#define baseDN tool_globals.tv_baseDN
 #define authcID tool_globals.tv_authcID
 #define authzID tool_globals.tv_authzID