[Date Prev][Date Next] [Chronological] [Thread] [Top]

Authorization on UIDs without bind



Hi,

a while back I posted a question to this list whether it was possible to
do authorization based on the operating system UID/GID for IPC
connections. The answer was that this is possible only with a
SASL/EXTERNAL bind.

The attached patch implements UID based authorization for anonymous
connections. It adds an keyword "uid=xxx" to the access control syntax,
much like the "ssf=xxx" keyword that is already there (in fact the
implementation is largely copied from that). This feature is useful for
granting local processes access to protected attributes without the
requirement of adding clear-text passwords to configuration files. For
example:

access to attrs=userPassword
       by uid=500 read
       by anonymous auth
       by users none

Patch attached below. It is developed for OpenLDAP 2.2.13.

Regards,
Geert

diff -ur openldap-2.2.13.orig/servers/slapd/acl.c openldap-2.2.13/servers/slapd/acl.c
--- openldap-2.2.13.orig/servers/slapd/acl.c	2004-05-13 10:12:37.000000000 +0200
+++ openldap-2.2.13/servers/slapd/acl.c	2006-02-22 00:52:11.000000000 +0100
@@ -1328,6 +1328,38 @@
 			}
 		}
 
+		if ( b->a_authz.sai_local_uid != (uid_t) -1 ) {
+#ifdef NEW_LOGGING
+			LDAP_LOG( ACL, DETAIL1, 
+			   "acl_mask: conn %lu check a_authz.sai_local_uid: " 
+			   "ACL %u > OP %u\n",
+				op->o_connid, b->a_authz.sai_local_uid, op->o_local_uid );
+#else
+			Debug( LDAP_DEBUG_ACL,
+				"<= check a_authz.sai_local_uid: ACL %u > OP %u\n",
+				b->a_authz.sai_local_uid, op->o_local_uid, 0 );
+#endif
+			if ( b->a_authz.sai_local_uid != op->o_local_uid ) {
+				continue;
+			}
+		}
+
+		if ( b->a_authz.sai_local_gid != (gid_t) -1 ) {
+#ifdef NEW_LOGGING
+			LDAP_LOG( ACL, DETAIL1, 
+			   "acl_mask: conn %lu check a_authz.sai_local_gid: " 
+			   "ACL %u > OP %u\n",
+				op->o_connid, b->a_authz.sai_local_gid, op->o_local_gid );
+#else
+			Debug( LDAP_DEBUG_ACL,
+				"<= check a_authz.sai_local_gid: ACL %u > OP %u\n",
+				b->a_authz.sai_local_gid, op->o_local_gid, 0 );
+#endif
+			if ( b->a_authz.sai_local_gid != op->o_local_gid ) {
+				continue;
+			}
+		}
+
 #ifdef SLAPD_ACI_ENABLED
 		if ( b->a_aci_at != NULL ) {
 			Attribute	*at;
diff -ur openldap-2.2.13.orig/servers/slapd/aclparse.c openldap-2.2.13/servers/slapd/aclparse.c
--- openldap-2.2.13.orig/servers/slapd/aclparse.c	2004-04-12 20:13:21.000000000 +0200
+++ openldap-2.2.13/servers/slapd/aclparse.c	2006-02-22 00:51:51.000000000 +0100
@@ -385,6 +385,8 @@
 			*/
 
 			b = (Access *) ch_calloc( 1, sizeof(Access) );
+			b->a_authz.sai_local_uid = (uid_t) -1;
+			b->a_authz.sai_local_gid = (gid_t) -1;
 
 			ACL_INVALIDATE( b->a_access_mask );
 
@@ -1254,6 +1256,73 @@
 					continue;
 				}
 
+				if ( strcasecmp( left, "uid" ) == 0 ) {
+					if (sty != ACL_STYLE_REGEX && sty != ACL_STYLE_BASE) {
+						fprintf( stderr,
+							"%s: line %d: inappropriate style \"%s\" in by clause\n",
+						    fname, lineno, style );
+						acl_usage();
+					}
+
+					if( b->a_authz.sai_local_uid  != -1) {
+						fprintf( stderr,
+							"%s: line %d: uid attribute already specified.\n",
+							fname, lineno );
+						acl_usage();
+					}
+
+					if ( right == NULL || *right == '\0' ) {
+						fprintf( stderr,
+							"%s: line %d: no uid is defined\n",
+							fname, lineno );
+						acl_usage();
+					}
+
+					b->a_authz.sai_local_uid = atoi( right );
+
+					if( !b->a_authz.sai_local_uid ) {
+						fprintf( stderr,
+							"%s: line %d: invalid uid value (%s)\n",
+							fname, lineno, right );
+						acl_usage();
+					}
+					continue;
+				}
+
+				if ( strcasecmp( left, "gid" ) == 0 ) {
+					if (sty != ACL_STYLE_REGEX && sty != ACL_STYLE_BASE) {
+						fprintf( stderr,
+							"%s: line %d: inappropriate style \"%s\" in by clause\n",
+						    fname, lineno, style );
+						acl_usage();
+					}
+
+					if( b->a_authz.sai_local_gid ) {
+						fprintf( stderr,
+							"%s: line %d: gid attribute already specified.\n",
+							fname, lineno );
+						acl_usage();
+					}
+
+					if ( right == NULL || *right == '\0' ) {
+						fprintf( stderr,
+							"%s: line %d: no gid is defined\n",
+							fname, lineno );
+						acl_usage();
+					}
+
+					b->a_authz.sai_local_gid = atoi( right );
+
+					if( !b->a_authz.sai_local_gid ) {
+						fprintf( stderr,
+							"%s: line %d: invalid gid value (%s)\n",
+							fname, lineno, right );
+						acl_usage();
+					}
+					continue;
+				}
+
+
 				if( right != NULL ) {
 					/* unsplit */
 					right[-1] = '=';
@@ -1841,6 +1910,15 @@
 			b->a_authz.sai_sasl_ssf );
 	}
 
+	if ( b->a_authz.sai_local_uid != (uid_t) -1 ) {
+		fprintf( stderr, " uid=%u",
+			b->a_authz.sai_local_uid );
+	}
+	if ( b->a_authz.sai_local_gid != (gid_t) -1 ) {
+		fprintf( stderr, " gid=%u",
+			b->a_authz.sai_local_gid );
+	}
+
 	fprintf( stderr, " %s%s",
 		b->a_dn_self ? "self" : "",
 		accessmask2str( b->a_access_mask, maskbuf ) );
diff -ur openldap-2.2.13.orig/servers/slapd/connection.c openldap-2.2.13/servers/slapd/connection.c
--- openldap-2.2.13.orig/servers/slapd/connection.c	2004-04-29 01:07:36.000000000 +0200
+++ openldap-2.2.13/servers/slapd/connection.c	2006-02-22 00:14:59.000000000 +0100
@@ -365,7 +365,9 @@
 	const char* peername,
 	int flags,
 	slap_ssf_t ssf,
-	struct berval *authid )
+	struct berval *authid,
+	uid_t uid,
+	gid_t gid )
 {
 	unsigned long id;
 	Connection *c;
@@ -615,6 +617,9 @@
 	c->c_ssf = c->c_transport_ssf = ssf;
 	c->c_tls_ssf = 0;
 
+	c->c_local_uid = uid;
+	c->c_local_gid = gid;
+
 #ifdef HAVE_TLS
 	if ( flags == CONN_IS_TLS ) {
 		c->c_is_tls = 1;
@@ -1176,7 +1181,7 @@
 {
 	Connection *c;
 
-	if ( connection_init( s, (Listener *)&dummy_list, "", "", CONN_IS_CLIENT, 0, NULL ) < 0 ) {
+	if ( connection_init( s, (Listener *)&dummy_list, "", "", CONN_IS_CLIENT, 0, NULL, -1, -1 ) < 0 ) {
 		return -1;
 	}
 
diff -ur openldap-2.2.13.orig/servers/slapd/daemon.c openldap-2.2.13/servers/slapd/daemon.c
--- openldap-2.2.13.orig/servers/slapd/daemon.c	2004-04-12 20:13:21.000000000 +0200
+++ openldap-2.2.13/servers/slapd/daemon.c	2006-02-22 00:35:39.000000000 +0100
@@ -1491,6 +1491,8 @@
 			long id;
 			slap_ssf_t ssf = 0;
 			struct berval authid = BER_BVNULL;
+			uid_t uid = -1;
+			gid_t gid = -1;
 #ifdef SLAPD_RLOOKUPS
 			char hbuf[NI_MAXHOST];
 #endif
@@ -1524,7 +1526,7 @@
 					id = connection_init(
 						slap_listeners[l]->sl_sd,
 						slap_listeners[l], "", "",
-						CONN_IS_UDP, ssf, NULL );
+						CONN_IS_UDP, ssf, NULL, -1, -1 );
 				    slap_listeners[l]->sl_is_udp++;
 				}
 				continue;
@@ -1671,9 +1673,6 @@
 				sprintf( peername, "PATH=%s", from.sa_un_addr.sun_path );
 				ssf = LDAP_PVT_SASL_LOCAL_SSF;
 				{
-					uid_t uid;
-					gid_t gid;
-
 					if( getpeereid( s, &uid, &gid ) == 0 ) {
 						authid.bv_val = ch_malloc(
 							sizeof("uidnumber=4294967295+gidnumber=4294967295,"
@@ -1768,7 +1767,8 @@
 				0,
 #endif
 				ssf,
-				authid.bv_val ? &authid : NULL );
+				authid.bv_val ? &authid : NULL,
+				uid, gid );
 
 			if( authid.bv_val ) ch_free(authid.bv_val);
 
diff -ur openldap-2.2.13.orig/servers/slapd/proto-slap.h openldap-2.2.13/servers/slapd/proto-slap.h
--- openldap-2.2.13.orig/servers/slapd/proto-slap.h	2004-04-29 01:26:30.000000000 +0200
+++ openldap-2.2.13/servers/slapd/proto-slap.h	2006-02-22 00:36:13.000000000 +0100
@@ -357,7 +357,9 @@
 	const char* peername,
 	int use_tls,
 	slap_ssf_t ssf,
-	struct berval *id ));
+	struct berval *id,
+	uid_t uid,
+	gid_t gid ));
 
 LDAP_SLAPD_F (void) connection_closing LDAP_P(( Connection *c ));
 LDAP_SLAPD_F (int) connection_state_closing LDAP_P(( Connection *c ));
diff -ur openldap-2.2.13.orig/servers/slapd/slap.h openldap-2.2.13/servers/slapd/slap.h
--- openldap-2.2.13.orig/servers/slapd/slap.h	2004-06-04 05:39:43.000000000 +0200
+++ openldap-2.2.13/servers/slapd/slap.h	2006-02-22 00:10:34.000000000 +0100
@@ -1111,6 +1111,10 @@
 	slap_ssf_t	sai_transport_ssf;	/* Transport SSF */
 	slap_ssf_t	sai_tls_ssf;		/* TLS SSF */
 	slap_ssf_t	sai_sasl_ssf;		/* SASL SSF */
+
+        /* UIDs/GIDs for local transport */
+	uid_t		sai_local_uid;		/* Local uid */
+	gid_t		sai_local_gid;		/* Local gid */
 } AuthorizationInformation;
 
 /* the "by" part */
@@ -1864,6 +1868,8 @@
 #define c_transport_ssf	c_authz.sai_transport_ssf
 #define c_tls_ssf		c_authz.sai_tls_ssf
 #define c_sasl_ssf		c_authz.sai_sasl_ssf
+#define c_local_uid		c_authz.sai_local_uid
+#define c_local_gid		c_authz.sai_local_gid
 
 #define o_authtype	o_authz.sai_method
 #define o_authmech	o_authz.sai_mech
@@ -1873,6 +1879,8 @@
 #define o_transport_ssf	o_authz.sai_transport_ssf
 #define o_tls_ssf		o_authz.sai_tls_ssf
 #define o_sasl_ssf		o_authz.sai_sasl_ssf
+#define o_local_uid		o_authz.sai_local_uid
+#define o_local_gid		o_authz.sai_local_gid
 
 typedef int (slap_response)( struct slap_op *, struct slap_rep * );
 

Attachment: signature.asc
Description: OpenPGP digital signature