Add some sample plugins

This commit is contained in:
Luke Howard 2004-01-10 04:54:24 +00:00
parent 62a0746126
commit 016f332624
4 changed files with 563 additions and 0 deletions

View file

@ -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.

View file

@ -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';
}

View file

@ -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.

View file

@ -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;
}