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

Help with internal processing of add



Hi

I am trying to add pgp key support to openldap-2.0.0.  
when a key is added a virtual request is sent 
dn: pgpcertid=virtualkey,ou=XXXX,o=XXXX
pgpkey: -------PGP.............

I then decode the key and put the results into a structure. I then
create a new modlist, modstail and Entry and send it to the
(*be->add)(). I then get the memory back take the orignal Entry reformat
it and return it to add.c right before the (*be-add)()

The problem is I am having memory issues I get a segfault in memory.c in
libc.
the code is attached to this call for help.  

How do you make two request form one?

Shaun savage
#include "portable.h"

#include <stdio.h>
#include <stdarg.h>

#include <ac/ctype.h>
#include <ac/string.h>
#include <ac/socket.h>

#include "ldap_pvt.h"
#include "../slap.h"
#include "import.h"

extern int buffer_import(char* buf,int len,keyinfo_t* ki);


static BerValue* add_berval(char * val)
{
	BerValue *bv;

	bv = (BerValue*) ch_malloc(sizeof(BerValue));
	bv->bv_len=strlen(val);
	bv->bv_val = ch_strdup(val);
	return bv;
}

static LDAPModList * add_attr(int op, char *type,const char * fmt,...)
{
	va_list ap;
	int i,cnt;
	void *ptr;
	LDAPModList *mod;

	cnt = strlen(fmt);
	mod = ch_malloc(sizeof(LDAPModList));
	mod->ml_op = op;
	mod->ml_type = ch_strdup(type);
	mod->ml_values = (void*) ch_malloc((cnt+1)*sizeof(void*));
	mod->ml_next = NULL;

	va_start(ap, fmt);
	for(i=0;i<cnt;i++) {
		ptr = va_arg(ap,char*);
		switch(fmt[i]) {
		case 'b':
			mod->ml_bvalues[i]= add_berval(ptr);
			break;
		case 'v':
			mod->ml_bvalues[i]=(BerValue*)ber_bvdup(ptr);
			break;
		case 's':
			mod->ml_values[i]=ch_strdup(ptr);
			break;
		case 'n':
			mod->ml_values[i]=NULL;
			break;
		default:
			break;
		}
	}
	va_end(ap);
	mod->ml_bvalues[i]=NULL;

	return mod;
}

static void
e_free( Entry *e )
{
        Attribute       *a, *next;

        if ( e->e_dn != NULL ) {
                free( e->e_dn );
                e->e_dn = NULL;
        }
        if ( e->e_ndn != NULL ) {
                free( e->e_ndn );
                e->e_ndn = NULL;
        }
        for ( a = e->e_attrs; a != NULL; a = next ) {
                next = a->a_next;
                attr_free( a );
        }
        e->e_attrs = NULL;
        e->e_private = NULL;
//        free( e );
}



int pgpParseKey(Backend *be,Connection *conn,Operation *op, Entry *e)
{
	int rc;
	keyinfo_t ki;
	Attribute *at_key, *at_mod, *tat, *at = e->e_attrs;
	char *text, buf[32], dn[128], *dn1, *ndn;

	if(!strcasecmp(at->a_desc->ad_cname->bv_val,"PGPKEY")) {
		LDAP *ld;
		dn1 = strchr(e->e_dn,',');
		tat = at;
		while(tat) {
			char *desc = tat->a_desc->ad_cname->bv_val;
			AttributeDescription *ad = tat->a_desc;
//			printf("ATTR %s %s\n",tat->a_desc->ad_cname->bv_val,
//			tat->a_vals[0]->bv_val); 
//			printf("\tAttDesc %x %s %x \n",ad->ad_flags,
//					ad->ad_type->sat_cname,
//					ad->ad_type->sat_atype);
			if(!strcasecmp(desc,"PGPKEY"))
				at_key = tat;
			else if(!strcasecmp(desc,"modifyTimestamp"))
				at_mod = tat;
			tat=tat->a_next;
		}
		rc = buffer_import(at->a_vals[0]->bv_val,at->a_vals[0]->bv_len,&ki);
		if(rc) {
			printf("error\n");
			return rc;
		}
		if(0) {
			printf("dn: PGPCERTID=%08lX%08lX\n",(ulong)ki.pgpcertid[0],
                                        (ulong)ki.pgpcertid[1]);
	        	printf("dn: pgpUserID=%s,PGPCERTID=%08lX%08lX,\n",ki.pgpuserid,(ulong)ki.pgpcertid[0],(ulong)ki.pgpcertid[1]);
        		printf("pgpcertid: %08lX%08lX\n",(ulong)ki.pgpcertid[0],
                                        (ulong)ki.pgpcertid[1]);
	        	printf("pgpdisabled: 0\n");
        		printf("pgpkeyid: %08lX\n",(ulong)ki.pgpcertid[1]);
	        	printf("pgpkeytype: %8s\n",ki.pgpkeytype);
        		printf("pgpuserid: %s\n",ki.pgpuserid);
	        	printf("pgpkeycreatetime: %s\n",ki.pgpkeycreatetime);
        		printf("pgpkeyexpiretime: %s\n",ki.pgpkeyexpiretime);
	        	printf("pgpkeysize %d\n",ki.pgpkeysize);
        		printf("pgprevoked: 0\n");
	        	printf("pgpsignerid: %08lX%08lX\n",(ulong)ki.pgpsignerid[0],(ulong)ki.pgpsignerid[1]);
        		printf("pgpsubkeyid: \n");
		}

	        sprintf(dn,"pgpUser=%s,PGPCERTID=%08lX%08lX%s",ki.pgpuserid,(ulong)ki.pgpcertid[0],
                                        (ulong)ki.pgpcertid[1],dn1);
		dn1 = strchr(dn,',');
		dn1++;

		ndn = ch_strdup(dn1);
		dn_normalize(ndn);

		{
		        LDAPModList     *modlist;
		        LDAPModList     **modtail = &modlist;
			LDAPModList	*mod;
			Modifications **modstail, *mods = NULL;
			Entry	*e1;

			mod = add_attr(LDAP_MOD_ADD,"pgpkey","v",at_key->a_vals[0]);
			*modtail = mod;
			modtail = &mod->ml_next;
			*modtail = mod = add_attr(LDAP_MOD_ADD,"objectClass","b","pgpCertificate");
			modtail = &mod->ml_next;
			*modtail = mod  = add_attr(LDAP_MOD_ADD,"version","b","2.0");
			modtail = &mod->ml_next;

			rc = slap_modlist2mods(modlist,0,&mods,&text);
			if(rc) {
				printf("modlist2mods\n");
				return rc;
			}
			for(modstail= &mods; *modstail != NULL;modstail = &(*modstail)->sml_next)
				;
			rc = slap_mods_opattrs(op,modstail,&text);
			if(rc) {
				printf("mods_opattrs\n");
				return rc;
			}
			e1 = (Entry*) ch_malloc(sizeof(Entry));
			e1->e_dn = ch_strdup(dn1);
			e1->e_ndn = ndn;
			e1->e_attrs = NULL;
			e1->e_private = NULL;

			rc = slap_mods2entry(mods,&e1,&text);
			if(rc) {
				printf("mods2attr\n");
				return rc;
			}

			rc = (*be->be_add)(be,conn,op,e1);
			if(rc)
				return rc;
		        if( modlist != NULL ) {
                		slap_modlist_free( modlist );
        		}
        		if( mods != NULL ) {
                		slap_mods_free( mods );
        		}
        		if( e1 != NULL ) {
                		entry_free( e1 );
        		}

		        *modtail = &modlist;
			mods = NULL;

			ndn = ch_strdup(dn);
			dn_normalize(ndn);

			sprintf(buf,"%08lX%08lX",ki.pgpcertid[0],ki.pgpcertid[1]);
			mod = add_attr(LDAP_MOD_ADD,"pgpcertid","b",buf);
			*modtail = mod;
			modtail = &mod->ml_next;

			mod = add_attr(LDAP_MOD_ADD,"pgpdisabled","b","0");
			*modtail = mod;
			modtail = &mod->ml_next;

			sprintf(buf,"%08lX",ki.pgpcertid[1]);
			mod = add_attr(LDAP_MOD_ADD,"pgpkeyid","b",buf);
			*modtail = mod;
			modtail = &mod->ml_next;

			sprintf(buf,"%d",ki.pgpkeysize);
			mod = add_attr(LDAP_MOD_ADD,"pgpkeysize","b",buf);
			*modtail = mod;
			modtail = &mod->ml_next;

			mod = add_attr(LDAP_MOD_ADD,"pgpkeytype","b",ki.pgpkeytype);
			*modtail = mod;
			modtail = &mod->ml_next;

			sprintf(buf,"%08lX%08lX",ki.pgpcertid[0],ki.pgpcertid[1]);
			mod = add_attr(LDAP_MOD_ADD,"pgpsignerid","b",buf);
			*modtail = mod;
			modtail = &mod->ml_next;

			mod = add_attr(LDAP_MOD_ADD,"pgprevoked","b","0");
			*modtail = mod;
			modtail = &mod->ml_next;

			mod = add_attr(LDAP_MOD_ADD,"pgpkeycreatetime","b",ki.pgpkeycreatetime);
			*modtail = mod;
			modtail = &mod->ml_next;

			mod = add_attr(LDAP_MOD_ADD,"pgpkeyexpiretime","b",ki.pgpkeyexpiretime);
			*modtail = mod;
			modtail = &mod->ml_next;

        		if( e != NULL ) {
                		e_free( e );
        		}
			
			rc = slap_modlist2mods(modlist,0,&mods,&text);
			if(rc) {
				printf("modlist2mods\n");
				return rc;
			}
			for(modstail= &mods; *modstail != NULL;modstail = &(*modstail)->sml_next)
				;
			rc = slap_mods_opattrs(op,modstail,&text);
			if(rc) {
				printf("mods_opattrs\n");
				return rc;
			}

			e->e_dn = ch_strdup(dn);
			e->e_ndn = ndn;
			e->e_attrs = NULL;
			e->e_private = NULL;

			rc = slap_mods2entry(mods,&e,&text);
			if(rc) {
				printf("mods2attr\n");
				return rc;
			}

			return 0;
		}

	}
	if(!strncasecmp(at->a_desc->ad_cname->bv_val,"PGPREQUEST",10)) {
		rc = buffer_import(at->a_vals[0]->bv_val,at->a_vals[0]->bv_len,&ki);
	}
	return 0;
}

/* make two Entrys 
 *   dn: PGPCERTID=xxxxxxxx,OU=ACTIVE,O=PGP KEYSPACE
 *       oc: pgpCertificate
 *       pgpkey: XXXXXXXXXXXX
 *       version: 2.0.1
 *   
 *   dn: pgpUser=AAAAA,PGPCERTID=XXXXXXXXX,OA=ACTIVE,O=PGP KEYSPACE
 *       oc: pgpUserID
 *	 pgpcertid: XXXXXXXX
 *	 pgpdisabled: 1/0
 *       pgpkeyid:  XXXXXXX
 *       pgpkeyexpiretime:
 *       pgpkeycratetime:
 *       pgpkeysize:
 *	 pgpkeytype:
 *	 pgprevoked:
 *	 pgpsignerid:
 */