[Pkg-openldap-devel] r1411 - openldap/trunk/contrib/slapd-modules/acl

vorlon at alioth.debian.org vorlon at alioth.debian.org
Wed Jan 4 16:49:06 UTC 2012


Author: vorlon
Date: 2012-01-04 16:49:06 +0000 (Wed, 04 Jan 2012)
New Revision: 1411

Added:
   openldap/trunk/contrib/slapd-modules/acl/README.gssacl
   openldap/trunk/contrib/slapd-modules/acl/gssacl.c
Log:
add new files introduced in 2.4.28 to the repo; not sure how these didn't get
caught in the previous commit

Added: openldap/trunk/contrib/slapd-modules/acl/README.gssacl
===================================================================
--- openldap/trunk/contrib/slapd-modules/acl/README.gssacl	                        (rev 0)
+++ openldap/trunk/contrib/slapd-modules/acl/README.gssacl	2012-01-04 16:49:06 UTC (rev 1411)
@@ -0,0 +1,33 @@
+This directory contains native slapd plugins that implement access rules.
+
+gssacl.c contains a simple example that implements access control
+based on GSS naming extensions attributes.
+
+To use the acl-gssacl plugin, add:
+
+moduleload acl-gssacl.so
+
+to your slapd configuration file.
+It is configured using
+
+access to <what>
+        by dynacl/gss/<attribute>.[.{base,regex,expand}]=<valpat> {<level>|<priv(s)>}
+
+The default is "exact"; in case of "expand", "<valpat>" results from
+the expansion of submatches in the "<what>" portion.  "<level>|<priv(s)>"
+describe the level of privilege this rule can assume.
+
+No Makefile is provided. Use a command line similar to:
+
+gcc -shared -I../../../include -I../../../servers/slapd -Wall -g \
+	-o acl-gssacl.so gssacl.c
+
+to compile the gssacl ACL plugin.
+
+---
+Copyright 2011 PADL Software Pty Ltd. 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.
+

Added: openldap/trunk/contrib/slapd-modules/acl/gssacl.c
===================================================================
--- openldap/trunk/contrib/slapd-modules/acl/gssacl.c	                        (rev 0)
+++ openldap/trunk/contrib/slapd-modules/acl/gssacl.c	2012-01-04 16:49:06 UTC (rev 1411)
@@ -0,0 +1,316 @@
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 2011 PADL Software Pty Ltd.
+ * 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 the file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * <http://www.OpenLDAP.org/license.html>.
+ */
+
+#include <portable.h>
+
+#include <ac/string.h>
+#include <slap.h>
+#include <lutil.h>
+
+#include <sasl/sasl.h>
+#include <gssapi/gssapi.h>
+#include <gssapi/gssapi_ext.h>
+
+#define ACL_BUF_SIZE 1024
+
+typedef struct gssattr_t {
+	slap_style_t		gssattr_style;
+	struct berval		gssattr_name;		/* asserted name */
+	struct berval		gssattr_value;		/* asserted value */
+} gssattr_t;
+
+static int gssattr_dynacl_destroy( void *priv );
+
+static int
+regex_matches(
+	struct berval	*pat,		/* pattern to expand and match against */
+	char		*str,		/* string to match against pattern */
+	struct berval	*dn_matches,	/* buffer with $N expansion variables from DN */
+	struct berval	*val_matches,	/* buffer with $N expansion variables from val */
+	AclRegexMatches	*matches	/* offsets in buffer for $N expansion variables */
+);
+
+static int
+gssattr_dynacl_parse(
+	const char	*fname,
+	int 		lineno,
+	const char	*opts,
+	slap_style_t	style,
+	const char	*pattern,
+	void		**privp )
+{
+	gssattr_t	*gssattr;
+
+	gssattr = (gssattr_t *)ch_calloc( 1, sizeof( gssattr_t ) );
+
+	if ( opts == NULL || opts[0] == '\0' ) {
+		fprintf( stderr, "%s line %d: GSS ACL: no attribute specified.\n",
+			 fname, lineno );
+		goto cleanup;
+	}
+
+	if ( pattern == NULL || pattern[0] == '\0' ) {
+		fprintf( stderr, "%s line %d: GSS ACL: no attribute value specified.\n",
+			 fname, lineno );
+		goto cleanup;
+	}
+
+	gssattr->gssattr_style = style;
+
+	switch ( gssattr->gssattr_style ) {
+	case ACL_STYLE_BASE:
+	case ACL_STYLE_REGEX:
+	case ACL_STYLE_EXPAND:
+		break;
+	default:
+		fprintf( stderr, "%s line %d: GSS ACL: unsupported style \"%s\".\n",
+			 fname, lineno, style_strings[style] );
+		goto cleanup;
+		break;
+	}
+
+	ber_str2bv( opts,    0, 1, &gssattr->gssattr_name );
+	ber_str2bv( pattern, 0, 1, &gssattr->gssattr_value );
+
+	*privp = (void *)gssattr;
+	return 0;
+
+cleanup:
+	(void)gssattr_dynacl_destroy( (void *)gssattr );
+
+	return 1;
+}
+
+static int
+gssattr_dynacl_unparse(
+	void		*priv,
+	struct berval	*bv )
+{
+	gssattr_t	*gssattr = (gssattr_t *)priv;
+	char		*ptr;
+
+	bv->bv_len = STRLENOF( " dynacl/gss/.expand=" ) +
+		     gssattr->gssattr_name.bv_len +
+		     gssattr->gssattr_value.bv_len;
+	bv->bv_val = ch_malloc( bv->bv_len + 1 );
+
+	ptr = lutil_strcopy( bv->bv_val, " dynacl/gss/" );
+	ptr = lutil_strncopy( ptr, gssattr->gssattr_name.bv_val,
+			      gssattr->gssattr_name.bv_len );
+	switch ( gssattr->gssattr_style ) {
+	case ACL_STYLE_BASE:
+		ptr = lutil_strcopy( ptr, ".exact=" );
+		break;
+	case ACL_STYLE_REGEX:
+		ptr = lutil_strcopy( ptr, ".regex=" );
+		break;
+	case ACL_STYLE_EXPAND:
+		ptr = lutil_strcopy( ptr, ".expand=" );
+		break;
+	default:
+		assert( 0 );
+		break;
+	}
+
+	ptr = lutil_strncopy( ptr, gssattr->gssattr_value.bv_val,
+			      gssattr->gssattr_value.bv_len );
+
+	ptr[ 0 ] = '\0';
+
+	bv->bv_len = ptr - bv->bv_val;
+
+	return 0;
+}
+
+static int
+gssattr_dynacl_mask(
+	void			*priv,
+	Operation		*op,
+	Entry			*target,
+	AttributeDescription	*desc,
+	struct berval		*val,
+	int			nmatch,
+	regmatch_t		*matches,
+	slap_access_t		*grant,
+	slap_access_t		*deny )
+{
+	gssattr_t	*gssattr = (gssattr_t *)priv;
+	sasl_conn_t	*sasl_ctx = op->o_conn->c_sasl_authctx;
+	gss_name_t	gss_name = GSS_C_NO_NAME;
+	OM_uint32	major, minor;
+	int		more = -1;
+	int		authenticated, complete;
+	gss_buffer_desc	attr = GSS_C_EMPTY_BUFFER;
+	int		granted = 0;
+
+	ACL_INVALIDATE( *deny );
+
+	if ( sasl_ctx == NULL ||
+	     sasl_getprop( sasl_ctx, SASL_GSS_PEER_NAME, (const void **)&gss_name) != 0 ||
+	     gss_name == GSS_C_NO_NAME ) {
+		return 0;
+	}
+
+	attr.length = gssattr->gssattr_name.bv_len;
+	attr.value = gssattr->gssattr_name.bv_val;
+
+	while ( more != 0 ) {
+		AclRegexMatches amatches = { 0 };
+		gss_buffer_desc	gss_value = GSS_C_EMPTY_BUFFER;
+		gss_buffer_desc	gss_display_value = GSS_C_EMPTY_BUFFER;
+		struct berval bv_value;
+
+		major = gss_get_name_attribute( &minor, gss_name, &attr,
+						&authenticated, &complete,
+						&gss_value, &gss_display_value, &more );
+		if ( GSS_ERROR( major ) ) {
+			break;
+		} else if ( authenticated == 0 ) {
+			gss_release_buffer( &minor, &gss_value );
+			gss_release_buffer( &minor, &gss_display_value );
+			continue;
+		}
+
+		bv_value.bv_len = gss_value.length;
+		bv_value.bv_val = (char *)gss_value.value;
+
+		if ( !ber_bvccmp( &gssattr->gssattr_value, '*' ) ) {
+			if ( gssattr->gssattr_style != ACL_STYLE_BASE ) {
+				amatches.dn_count = nmatch;
+				AC_MEMCPY( amatches.dn_data, matches, sizeof( amatches.dn_data ) );
+			}
+
+			switch ( gssattr->gssattr_style ) {
+			case ACL_STYLE_REGEX:
+				/* XXX assumes value NUL terminated */
+				granted = regex_matches( &gssattr->gssattr_value, bv_value.bv_val,
+							  &target->e_nname, val, &amatches );
+				break;
+			case ACL_STYLE_EXPAND: {
+				struct berval bv;
+				char buf[ACL_BUF_SIZE];
+
+				bv.bv_len = sizeof( buf ) - 1;
+				bv.bv_val = buf;
+
+				granted = ( acl_string_expand( &bv, &gssattr->gssattr_value,
+							       &target->e_nname, val,
+							       &amatches ) == 0 ) &&
+					  ( ber_bvstrcmp( &bv, &bv_value) == 0 );
+				break;
+			}
+			case ACL_STYLE_BASE:
+				granted = ( ber_bvstrcmp( &gssattr->gssattr_value, &bv_value ) == 0 );
+				break;
+			default:
+				assert(0);
+				break;
+			}
+		} else {
+			granted = 1;
+		}
+
+		gss_release_buffer( &minor, &gss_value );
+		gss_release_buffer( &minor, &gss_display_value );
+
+		if ( granted ) {
+			break;
+		}
+	}
+
+	if ( granted ) {
+		ACL_LVL_ASSIGN_WRITE( *grant );
+	}
+
+	return 0;
+}
+
+static int
+gssattr_dynacl_destroy(
+	void		*priv )
+{
+	gssattr_t		*gssattr = (gssattr_t *)priv;
+
+	if ( gssattr != NULL ) {
+		if ( !BER_BVISNULL( &gssattr->gssattr_name ) ) {
+			ber_memfree( gssattr->gssattr_name.bv_val );
+		}
+		if ( !BER_BVISNULL( &gssattr->gssattr_value ) ) {
+			ber_memfree( gssattr->gssattr_value.bv_val );
+		}
+		ch_free( gssattr );
+	}
+
+	return 0;
+}
+
+static struct slap_dynacl_t gssattr_dynacl = {
+	"gss",
+	gssattr_dynacl_parse,
+	gssattr_dynacl_unparse,
+	gssattr_dynacl_mask,
+	gssattr_dynacl_destroy
+};
+
+int
+init_module( int argc, char *argv[] )
+{
+	return slap_dynacl_register( &gssattr_dynacl );
+}
+
+
+static int
+regex_matches(
+	struct berval	*pat,		/* pattern to expand and match against */
+	char		*str,		/* string to match against pattern */
+	struct berval	*dn_matches,	/* buffer with $N expansion variables from DN */
+	struct berval	*val_matches,	/* buffer with $N expansion variables from val */
+	AclRegexMatches	*matches	/* offsets in buffer for $N expansion variables */
+)
+{
+	regex_t re;
+	char newbuf[ACL_BUF_SIZE];
+	struct berval bv;
+	int	rc;
+
+	bv.bv_len = sizeof( newbuf ) - 1;
+	bv.bv_val = newbuf;
+
+	if (str == NULL) {
+		str = "";
+	};
+
+	acl_string_expand( &bv, pat, dn_matches, val_matches, matches );
+	rc = regcomp( &re, newbuf, REG_EXTENDED|REG_ICASE );
+	if ( rc ) {
+		char error[ACL_BUF_SIZE];
+		regerror( rc, &re, error, sizeof( error ) );
+
+		Debug( LDAP_DEBUG_TRACE,
+		    "compile( \"%s\", \"%s\") failed %s\n",
+			pat->bv_val, str, error );
+		return( 0 );
+	}
+
+	rc = regexec( &re, str, 0, NULL, 0 );
+	regfree( &re );
+
+	Debug( LDAP_DEBUG_TRACE,
+	    "=> regex_matches: string:	 %s\n", str, 0, 0 );
+	Debug( LDAP_DEBUG_TRACE,
+	    "=> regex_matches: rc: %d %s\n",
+		rc, !rc ? "matches" : "no matches", 0 );
+	return( !rc );
+}
+




More information about the Pkg-openldap-devel mailing list