]> git.sur5r.net Git - openldap/commitdiff
Add some sample plugins
authorLuke Howard <lukeh@openldap.org>
Sat, 10 Jan 2004 04:54:24 +0000 (04:54 +0000)
committerLuke Howard <lukeh@openldap.org>
Sat, 10 Jan 2004 04:54:24 +0000 (04:54 +0000)
contrib/slapd-modules/dsaschema/README [new file with mode: 0644]
contrib/slapd-modules/dsaschema/dsaschema.c [new file with mode: 0644]
contrib/slapi-plugins/addrdnvalues/README [new file with mode: 0644]
contrib/slapi-plugins/addrdnvalues/addrdnvalues.c [new file with mode: 0644]

diff --git a/contrib/slapd-modules/dsaschema/README b/contrib/slapd-modules/dsaschema/README
new file mode 100644 (file)
index 0000000..bdce6f8
--- /dev/null
@@ -0,0 +1,20 @@
+
+This directory contains a native slapd plugin, dsaschema, that permits the
+loading of DSA-specific schema from configuration files (including operational
+attributes).
+
+To use the plugin, add:
+
+moduleload libdsaschema-plugin.so
+       /etc/openldap/schema/foo1.schema
+       ...etc...
+       /etc/openldap/schema/fooN.schema
+
+to your slapd configuration file.
+
+No Makefile is provided. Use a command line similar to:
+
+gcc -shared -I../../../include -Wall -g -o libdsaschema-plugin.so dsaschema.c
+
+to compile this plugin.
+
diff --git a/contrib/slapd-modules/dsaschema/dsaschema.c b/contrib/slapd-modules/dsaschema/dsaschema.c
new file mode 100644 (file)
index 0000000..9467145
--- /dev/null
@@ -0,0 +1,432 @@
+/* $Id: dsaschema.c,v 1.4 2004/01/09 06:47:01 lukeh Exp $ */
+/*
+ * Copyright 2004 The OpenLDAP Foundation.
+ * 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 <stdio.h>
+#include <limits.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+#include <time.h>
+
+/*
+ * Schema reader that allows us to define DSA schema (including
+ * operational attributes and non-user object classes)
+ *
+ * A kludge, at best, and in order to avoid including slapd
+ * headers we use fprintf() rather than slapd's native logging,
+ * which may confuse users...
+ *
+ */
+
+#include <ldap.h>
+#include <ldap_schema.h>
+
+extern int at_add(LDAPAttributeType *at, const char **err);
+extern int oc_add(LDAPObjectClass *oc, int user, const char **err);
+extern int cr_add(LDAPContentRule *cr, int user, const char **err);
+
+#define ARGS_STEP 512
+
+static char *fp_getline(FILE *fp, int *lineno);
+static void fp_getline_init(int *lineno);
+static int fp_parse_line(int lineno, char *line);
+static char *strtok_quote( char *line, char *sep );
+
+static char **cargv = NULL;
+static int cargv_size = 0;
+static int cargc = 0;
+static char *strtok_quote_ptr;
+
+int init_module(int argc, char *argv[]);
+
+static int dsaschema_parse_at(const char *fname, int lineno, char *line, char **argv)
+{
+       LDAPAttributeType *at;
+       int code;
+       const char *err;
+
+       at = ldap_str2attributetype(line, &code, &err, LDAP_SCHEMA_ALLOW_ALL);
+       if (!at) {
+               fprintf(stderr, "%s: line %d: %s before %s\n",
+                       fname, lineno, ldap_scherr2str(code), err);
+               return 1;
+       }
+
+       if (at->at_oid == NULL) {
+               fprintf(stderr, "%s: line %d: attributeType has no OID\n",
+                       fname, lineno);
+               return 1;
+       }
+
+       code = at_add(at, &err);
+       if (code) {
+               fprintf(stderr, "%s: line %d: %s: \"%s\"\n",
+                       fname, lineno, ldap_scherr2str(code), err);
+               return 1;
+       }
+
+       ldap_memfree(at);
+
+       return 0;
+}
+
+static int dsaschema_parse_oc(const char *fname, int lineno, char *line, char **argv)
+{
+       LDAPObjectClass *oc;
+       int code;
+       const char *err;
+
+       oc = ldap_str2objectclass(line, &code, &err, LDAP_SCHEMA_ALLOW_ALL);
+       if (!oc) {
+               fprintf(stderr, "%s: line %d: %s before %s\n",
+                       fname, lineno, ldap_scherr2str(code), err);
+               return 1;
+       }
+
+       if (oc->oc_oid == NULL) {
+               fprintf(stderr,
+                       "%s: line %d: objectclass has no OID\n",
+                       fname, lineno);
+               return 1;
+       }
+
+       code = oc_add(oc, 0, &err);
+       if (code) {
+               fprintf(stderr, "%s: line %d: %s: \"%s\"\n",
+                       fname, lineno, ldap_scherr2str(code), err);
+               return 1;
+       }
+
+       ldap_memfree(oc);
+       return 0;
+}
+
+static int dsaschema_parse_cr(const char *fname, int lineno, char *line, char **argv)
+{
+       LDAPContentRule *cr;
+       int code;
+       const char *err;
+
+       cr = ldap_str2contentrule(line, &code, &err, LDAP_SCHEMA_ALLOW_ALL);
+       if (!cr) {
+               fprintf(stderr, "%s: line %d: %s before %s\n",
+                       fname, lineno, ldap_scherr2str(code), err);
+               return 1;
+       }
+
+       if (cr->cr_oid == NULL) {
+               fprintf(stderr,
+                       "%s: line %d: objectclass has no OID\n",
+                       fname, lineno);
+               return 1;
+       }
+
+       code = cr_add(cr, 0, &err);
+       if (code) {
+               fprintf(stderr, "%s: line %d: %s: \"%s\"\n",
+                       fname, lineno, ldap_scherr2str(code), err);
+               return 1;
+       }
+
+       ldap_memfree(cr);
+       return 0;
+}
+
+static int dsaschema_read_config(const char *fname, int depth)
+{
+       FILE *fp;
+       char *line, *savefname, *saveline;
+       int savelineno, lineno;
+       int rc;
+
+       if (depth == 0) {
+               cargv = calloc(ARGS_STEP + 1, sizeof(*cargv));
+               if (cargv == NULL) {
+                       return 1;
+               }
+               cargv_size = ARGS_STEP + 1;
+       }
+
+       fp = fopen(fname, "r");
+       if (fp == NULL) {
+               fprintf(stderr, "could not open config file \"%s\": %s (%d)\n",
+                       fname, strerror(errno), errno);
+               return 1;
+       }
+       fp_getline_init(&lineno);
+
+       while ((line = fp_getline(fp, &lineno)) != NULL) {
+               /* skip comments and blank lines */
+               if (line[0] == '#' || line[0] == '\0') {
+                       continue;
+               }
+
+               saveline = strdup(line);
+               if (saveline == NULL) {
+                       return 1;
+               }
+
+               if (fp_parse_line(lineno, line) != 0) {
+                       return 1;
+               }
+
+               if (cargc < 1) {
+                       continue;
+               }
+
+               if (strcasecmp(cargv[0], "attributetype") == 0 ||
+                   strcasecmp(cargv[0], "attribute") == 0) {
+                       if (cargc < 2) {
+                               fprintf(stderr, "%s: line %d: illegal attribute type format\n",
+                                       fname, lineno);
+                               return 1;
+                       } else if (*cargv[1] == '(' /*')'*/) {
+                               char *p;
+       
+                               p = strchr(saveline, '(' /*')'*/);
+                               rc = dsaschema_parse_at(fname, lineno, p, cargv);
+                               if (rc != 0)
+                                       return rc;
+                       } else {
+                               fprintf(stderr, "%s: line %d: old attribute type format not supported\n",
+                                       fname, lineno);
+                       }
+               } else if (strcasecmp(cargv[0], "ditcontentrule") == 0) {
+                       char *p;
+                       p = strchr(saveline, '(' /*')'*/);
+                       rc = dsaschema_parse_cr(fname, lineno, p, cargv);
+                       if (rc != 0)
+                               return rc;
+               } else if (strcasecmp(cargv[0], "objectclass") == 0) {
+                       if (cargc < 2) {
+                               fprintf(stderr, "%s: line %d: illegal objectclass format\n",
+                                       fname, lineno);
+                               return 1;
+                       } else if (*cargv[1] == '(' /*')'*/) {
+                               char *p;
+
+                               p = strchr(saveline, '(' /*')'*/);
+                               rc = dsaschema_parse_oc(fname, lineno, p, cargv);
+                               if (rc != 0)
+                                       return rc;
+                       } else {
+                               fprintf(stderr, "%s: line %d: object class format not supported\n",
+                                       fname, lineno);
+                       }
+               } else if (strcasecmp(cargv[0], "include") == 0) {
+                       if (cargc < 2) {
+                               fprintf(stderr, "%s: line %d: missing file name in \"include <filename>\" line",
+                                       fname, lineno);
+                               return 1;
+                       }
+                       savefname = strdup(cargv[1]);
+                       if (savefname == NULL) {
+                               return 1;
+                       }
+                       if (dsaschema_read_config(savefname, depth + 1) != 0) {
+                               return 1;
+                       }
+                       free(savefname);
+                       lineno = savelineno - 1;
+               } else {
+                       fprintf(stderr, "%s: line %d: unknown directive \"%s\" (ignored)\n",
+                               fname, lineno, cargv[0]);
+               }
+       }
+
+       fclose(fp);
+
+       if (depth == 0)
+               free(cargv);
+
+       return 0;
+}
+
+int init_module(int argc, char *argv[])
+{
+       int i;
+       int rc;
+
+       for (i = 0; i < argc; i++) {
+               rc = dsaschema_read_config(argv[i], 0);
+               if (rc != 0) {
+                       break;
+               }
+       }
+
+       return rc;
+}
+
+
+static int
+fp_parse_line(
+    int                lineno,
+    char       *line
+)
+{
+       char *  token;
+
+       cargc = 0;
+       token = strtok_quote( line, " \t" );
+
+       if ( strtok_quote_ptr ) {
+               *strtok_quote_ptr = ' ';
+       }
+
+       if ( strtok_quote_ptr ) {
+               *strtok_quote_ptr = '\0';
+       }
+
+       for ( ; token != NULL; token = strtok_quote( NULL, " \t" ) ) {
+               if ( cargc == cargv_size - 1 ) {
+                       char **tmp;
+                       tmp = realloc( cargv, (cargv_size + ARGS_STEP) *
+                                           sizeof(*cargv) );
+                       if ( tmp == NULL ) {
+                               return -1;
+                       }
+                       cargv = tmp;
+                       cargv_size += ARGS_STEP;
+               }
+               cargv[cargc++] = token;
+       }
+       cargv[cargc] = NULL;
+       return 0;
+}
+
+static char *
+strtok_quote( char *line, char *sep )
+{
+       int             inquote;
+       char            *tmp;
+       static char     *next;
+
+       strtok_quote_ptr = NULL;
+       if ( line != NULL ) {
+               next = line;
+       }
+       while ( *next && strchr( sep, *next ) ) {
+               next++;
+       }
+
+       if ( *next == '\0' ) {
+               next = NULL;
+               return( NULL );
+       }
+       tmp = next;
+
+       for ( inquote = 0; *next; ) {
+               switch ( *next ) {
+               case '"':
+                       if ( inquote ) {
+                               inquote = 0;
+                       } else {
+                               inquote = 1;
+                       }
+                       memcpy( next, next + 1, strlen( next + 1 ) + 1 );
+                       break;
+
+               case '\\':
+                       if ( next[1] )
+                               memcpy( next,
+                                           next + 1, strlen( next + 1 ) + 1 );
+                       next++;         /* dont parse the escaped character */
+                       break;
+
+               default:
+                       if ( ! inquote ) {
+                               if ( strchr( sep, *next ) != NULL ) {
+                                       strtok_quote_ptr = next;
+                                       *next++ = '\0';
+                                       return( tmp );
+                               }
+                       }
+                       next++;
+                       break;
+               }
+       }
+
+       return( tmp );
+}
+
+static char    buf[BUFSIZ];
+static char    *line;
+static size_t lmax, lcur;
+
+#define CATLINE( buf ) \
+       do { \
+               size_t len = strlen( buf ); \
+               while ( lcur + len + 1 > lmax ) { \
+                       lmax += BUFSIZ; \
+                       line = (char *) realloc( line, lmax ); \
+               } \
+               strcpy( line + lcur, buf ); \
+               lcur += len; \
+       } while( 0 )
+
+static char *
+fp_getline( FILE *fp, int *lineno )
+{
+       char            *p;
+
+       lcur = 0;
+       CATLINE( buf );
+       (*lineno)++;
+
+       /* hack attack - keeps us from having to keep a stack of bufs... */
+       if ( strncasecmp( line, "include", 7 ) == 0 ) {
+               buf[0] = '\0';
+               return( line );
+       }
+
+       while ( fgets( buf, sizeof(buf), fp ) != NULL ) {
+               /* trim off \r\n or \n */
+               if ( (p = strchr( buf, '\n' )) != NULL ) {
+                       if( p > buf && p[-1] == '\r' ) --p;
+                       *p = '\0';
+               }
+               
+               /* trim off trailing \ and append the next line */
+               if ( line[ 0 ] != '\0' 
+                               && (p = line + strlen( line ) - 1)[ 0 ] == '\\'
+                               && p[ -1 ] != '\\' ) {
+                       p[ 0 ] = '\0';
+                       lcur--;
+
+               } else {
+                       if ( ! isspace( (unsigned char) buf[0] ) ) {
+                               return( line );
+                       }
+
+                       /* change leading whitespace to a space */
+                       buf[0] = ' ';
+               }
+
+               CATLINE( buf );
+               (*lineno)++;
+       }
+       buf[0] = '\0';
+
+       return( line[0] ? line : NULL );
+}
+
+static void
+fp_getline_init( int *lineno )
+{
+       *lineno = -1;
+       buf[0] = '\0';
+}
+
diff --git a/contrib/slapi-plugins/addrdnvalues/README b/contrib/slapi-plugins/addrdnvalues/README
new file mode 100644 (file)
index 0000000..cff74fd
--- /dev/null
@@ -0,0 +1,11 @@
+
+This directory contains a SLAPI plugin, addrdnvalues, which will add to
+an entry any attribute values that appear in the entry's RDN but not in
+the entry. This is necessary for compliance with some "broken" clients.
+
+No Makefile is provided. Use a command line similar to:
+
+gcc -shared -I../../../include -Wall -g -o libaddrdnvalues-plugin.so addrdnvalues.c
+
+to compile this plugin.
+
diff --git a/contrib/slapi-plugins/addrdnvalues/addrdnvalues.c b/contrib/slapi-plugins/addrdnvalues/addrdnvalues.c
new file mode 100644 (file)
index 0000000..243c4c9
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2003-2004 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>.
+ */
+/* (C) Copyright PADL Software Pty Ltd. 2003
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that this notice is preserved
+ * and that due credit is given to PADL Software Pty Ltd. This software
+ * is provided ``as is'' without express or implied warranty.
+ */
+
+#include <string.h>
+#include <unistd.h>
+
+#include <ldap.h>
+#include <lber.h>
+
+#include <slapi-plugin.h>
+
+int addrdnvalues_preop_init(Slapi_PBlock *pb);
+
+static Slapi_PluginDesc pluginDescription = {
+       "addrdnvalues-plugin",
+       "PADL",
+       "1.0",
+       "RDN values addition plugin"
+};
+
+static int addrdnvalues_preop_add(Slapi_PBlock *pb)
+{
+       int rc;
+       Slapi_Entry *e;
+       char *szDN;
+       LDAPDN dn;
+       int i;
+
+       if (slapi_pblock_get(pb, SLAPI_ADD_ENTRY, &e) != 0) {
+               slapi_log_error(SLAPI_LOG_PLUGIN, "addrdnvalues_preop_add",
+                               "Error retrieving target entry\n");
+               return -1;
+       }
+
+       szDN = slapi_entry_get_dn(e);
+       rc = ldap_str2dn(szDN, &dn, LDAP_DN_FORMAT_LDAPV3);
+       if (rc != LDAP_SUCCESS) {
+               slapi_send_ldap_result(pb, rc, NULL, NULL, 0, NULL);
+               slapi_log_error(SLAPI_LOG_PLUGIN, "addrdnvalues_preop_add", "%s\n", ldap_err2string(rc));
+               return -1;
+       }
+
+       if (dn[0] != NULL) {
+               LDAPRDN rdn = dn[0];
+
+               for (i = 0; rdn[i] != NULL; i++) {
+                       LDAPAVA *ava = &rdn[0][i];
+                       struct berval *vals[2];
+                       Slapi_Attr *a = NULL;
+
+                       /* 0 means attr exists */
+                       if (slapi_entry_attr_find(e, ava->la_attr.bv_val, &a) == 0 &&
+                           a != NULL &&
+                           slapi_attr_value_find(a, &ava->la_value) == 0)
+                       {
+                               /* RDN in entry */
+                               continue;
+                       } /* else RDN not in entry */
+
+                       vals[0] = &ava->la_value;
+                       vals[1] = NULL;
+
+                       slapi_entry_attr_merge(e, ava->la_attr.bv_val, vals);
+               }
+       }
+
+       ldap_dnfree(dn);
+
+       return 0;
+}
+
+int addrdnvalues_preop_init(Slapi_PBlock *pb)
+{
+       if (slapi_pblock_set(pb, SLAPI_PLUGIN_VERSION, SLAPI_PLUGIN_VERSION_03) != 0 ||
+           slapi_pblock_set(pb, SLAPI_PLUGIN_DESCRIPTION, &pluginDescription) != 0 ||
+           slapi_pblock_set(pb, SLAPI_PLUGIN_PRE_ADD_FN, (void *)addrdnvalues_preop_add) != 0) {
+               slapi_log_error(SLAPI_LOG_PLUGIN, "addrdnvalues_preop_init",
+                               "Error registering %s\n", pluginDescription.spd_description);
+               return -1;
+       }
+
+       return 0;
+}
+