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