[389-devel] Please Review: {516089} add option to ldlct for deref esearch "-e deref=deref:attr"

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




>From d67440e7b92c217146a7866eecadde4654fef43e Mon Sep 17 00:00:00 2001
From: Yi Zhang <yzhang@xxxxxxxxxx>
Date: Mon, 9 Nov 2009 09:38:41 -0800
Subject: [PATCH] 516089 - add dereference search option into ldclt

This option will accept format like "-e deref=derefAttr:attr"
    to ldclt when "-e esearch" is requested.
example: -e esearch -e deref=secretary:mail
    search will dereference the "secretary" attribute and then return the "mail" attribute value
---
 ldap/servers/slapd/tools/ldclt/ldapfct.c    |   90 +++++++++++++++++++++++++--
 ldap/servers/slapd/tools/ldclt/ldclt.c      |   42 ++++++++++++-
 ldap/servers/slapd/tools/ldclt/ldclt.h      |    6 +-
 ldap/servers/slapd/tools/ldclt/threadMain.c |    5 +-
 4 files changed, 132 insertions(+), 11 deletions(-)

diff --git a/ldap/servers/slapd/tools/ldclt/ldapfct.c b/ldap/servers/slapd/tools/ldclt/ldapfct.c
index c067f26..1d491cc 100644
--- a/ldap/servers/slapd/tools/ldclt/ldapfct.c
+++ b/ldap/servers/slapd/tools/ldclt/ldapfct.c
@@ -3666,9 +3666,17 @@ doExactSearch (
 {
   int		  ret;		/* Return value */
   LDAPMessage	 *res;		/* LDAP results */
+  LDAPMessage	 *e;		/* LDAP results */
   char		**attrlist;	/* Attribs list */		/*JLS 15-03-01*/
   LDAPControl **ctrlsp = NULL, *ctrls[2], *dctrl = NULL; /* derefence control */
 
+  /* the following variables are used for response parsing */
+  int             i;        /* for counting purpose */
+  int             msgtype, parse_rc , rc ; /* for search result parsing */
+  char            *matcheddn, *errmsg, *dn ;
+  LDAPControl     **resctrls; 
+  LDAPControl     **rcp;
+
   /*
    * Connection to the server
    * The function connectToServer() will take care of the various connection/
@@ -3701,10 +3709,30 @@ doExactSearch (
   if (mctx.mod2 & M2_DEREF) /* dereference */
   {
     char *attrs[2];
-    attrs[0] = "cn";
+    /* I have stored ref attr at mctx.attRef , deref attr at mctx.attRefDef */
+
+    /* using hard coded value for dereferenced attribute if no mctx.attRef is set */
+    if (mctx.attRef == NULL )
+    {
+      attrs[0] = "cn"; 
+    }else{
+      attrs[0] = mctx.attRefDef;
+    }
+
     attrs[1] = NULL;
-    ret = ldclt_create_deref_control(tttctx->ldapCtx,
+
+    /* use pre-defined value if passin mctx.attrRefDef is null 
+     * the pre-defined value LDCLT_DEREF_ATTR is "secretary"
+     */
+    if (mctx.attRef == NULL ){
+      ret = ldclt_create_deref_control(tttctx->ldapCtx,
                                      LDCLT_DEREF_ATTR, attrs, &dctrl);
+    }else{
+      ret = ldclt_create_deref_control(tttctx->ldapCtx,
+                                     mctx.attRef , attrs, &dctrl);
+    }
+
+    /* dctrl contains the returned reference value */
     if (LDAP_SUCCESS == ret)
     {
         ctrls[0] = dctrl;
@@ -3734,8 +3762,8 @@ doExactSearch (
     ret = ldap_search_ext_s (tttctx->ldapCtx, tttctx->bufBaseDN, mctx.scope,
 		tttctx->bufFilter, attrlist, 			/*JLS 15-03-01*/
 		mctx.attrsonly, ctrlsp, NULL, NULL, -1, &res);	/*JLS 03-01-01*/
-    if (ret != LDAP_SUCCESS)
-    {
+    if (ret != LDAP_SUCCESS) 
+    { /* if search failed */
       if (!((mctx.mode & QUIET) && ignoreError (ret)))
 	(void) printErrorFromLdap (tttctx, res, ret,		/*JLS 03-08-00*/
 		"Cannot ldap_search()");			/*JLS 03-08-00*/
@@ -3753,7 +3781,59 @@ doExactSearch (
       }								/*JLS 15-12-00*/
     }
     else
-    {
+    { /* if search success */
+      for (e = ldap_first_message (tttctx->ldapCtx, res); e != NULL ; e = ldap_next_message (tttctx->ldapCtx, e) )
+      {
+        msgtype = ldap_msgtype (e);
+        switch (msgtype)
+        {
+          /* if this is an entry that returned */
+          case LDAP_RES_SEARCH_ENTRY:
+            /* get dereferenced value into resctrls:  deref parsing  */
+            parse_rc = ldap_get_entry_controls ( tttctx->ldapCtx, e, &resctrls );
+            if ( resctrls != NULL ) 
+            {/* parse it only when we have return saved in server control */
+              /* get dn */
+              if (( dn = ldap_get_dn (tttctx->ldapCtx, e)) != NULL )
+              {
+                if (mctx.mode & VERY_VERBOSE)
+                {
+                  for ( rcp = resctrls; rcp && *rcp; rcp++ ) 
+                  {
+                      printf("dn: [%s] -> deref oid: %s, value: %s\n",
+                        dn, 
+                        (**rcp).ldctl_oid?(**rcp).ldctl_oid:"none",
+                        (**rcp).ldctl_value.bv_val?(**rcp).ldctl_value.bv_val:"none");
+                  }
+                }
+                ldap_controls_free( resctrls );
+                ldap_memfree (dn);
+              }
+            }
+          break; /*end of case LDAP_RES_SEARCH_ENTRY */
+
+          /* if this is an reference that returned */
+          case LDAP_RES_SEARCH_REFERENCE: /* we do nothing here */
+          break;
+
+          /* if we reach the end of search result */
+          case LDAP_RES_SEARCH_RESULT:
+            /* just free the returned msg */
+            parse_rc = ldap_parse_result (tttctx->ldapCtx, e, &rc, &matcheddn, &errmsg, NULL , NULL , 0); 
+            if ( parse_rc != LDAP_SUCCESS )
+            {
+              printf("ldap_parse_result error: [%s]\n", ldap_err2string( parse_rc ));
+            }
+            if ( rc != LDAP_SUCCESS )
+            {
+              printf ("ldap_search_ext_s error: [%s]\n", ldap_err2string( rc ));
+            }
+          break; /* end of case LDAP_RES_SEARCH_RESULT */
+          default:
+          break;
+        }
+      } /*end of message retriving */
+
       if (incrementNbOpers (tttctx) < 0)/* Memorize operation */
       {
         goto bail;
diff --git a/ldap/servers/slapd/tools/ldclt/ldclt.c b/ldap/servers/slapd/tools/ldclt/ldclt.c
index 05774c0..7b2a7dd 100644
--- a/ldap/servers/slapd/tools/ldclt/ldclt.c
+++ b/ldap/servers/slapd/tools/ldclt/ldclt.c
@@ -1475,12 +1475,41 @@ basicInit (void)
     }								/*JLS 21-11-00*/
   }								/*JLS 21-11-00*/
 
+
+  /*YI parse reference atrr and dereference attr */
+  /*
+   * Parse deref subvalue
+   */
+  if (mctx.mod2 & M2_DEREF)
+  {
+     /*
+     * Find the reference attribute name
+     */
+    for (i=0 ; (i<strlen(mctx.attrpl)) &&
+                        (mctx.attrpl[i]!=':') ; i++);
+    mctx.attRef= (char *)malloc(i+1);
+    strncpy (mctx.attRef, mctx.attrpl, i);
+    mctx.attRef[i] = '\0';
+
+    /*
+     * Parse the deference attribute value
+     */
+    mctx.attRefDef= (char *)malloc(strlen(mctx.attrpl+i+1) + 1);
+    if (mctx.attRefDef== NULL) {
+      printf ("Error: unable to allocate memory for attRefDef\n");
+      return (-1);
+    }
+
+    strncpy(mctx.attRefDef, mctx.attrpl+i+1, strlen(mctx.attrpl+i+1));
+    mctx.attRefDef[strlen(mctx.attrpl+i+1)] = '\0';
+  }
+
+
   /*
    * Parse attreplacefile subvalue
    */
   if (mctx.mod2 & M2_ATTR_REPLACE_FILE)
   {
-    printf ("debug: parse attreplacefile subvalue\n");
     /*
      * Find the attribute name
      */
@@ -2505,6 +2534,12 @@ decodeExecParams (
 	break;
       case EP_DEREF:
 	mctx.mod2 |= M2_DEREF;
+        if (subvalue == NULL)
+        {
+          fprintf (stderr, "Error: missing arg deref argument pair (deref:attr)\n");
+          return (-1);
+        }
+        mctx.attrpl = strdup (subvalue);
 	break;
       default:
 	fprintf (stderr, "Error: illegal option -e %s\n", subvalue);
@@ -3194,6 +3229,11 @@ main (
       printf ("Attribute to replace  = \"%s\"\n", mctx.attrplName);
       printf ("Attribute value file  = \"%s\"\n", mctx.attrplFile);
     }
+    if (mctx.mod2 & M2_DEREF)
+    {
+      printf ("  Referenced Attribute = \"%s\"\n", mctx.attRef);
+      printf ("Dereferenced Attribute = \"%s\"\n", mctx.attRefDef);
+    }
     if (mctx.mode & ASYNC)
     {
       printf ("Async max pending  = %d\n", mctx.asyncMax);
diff --git a/ldap/servers/slapd/tools/ldclt/ldclt.h b/ldap/servers/slapd/tools/ldclt/ldclt.h
index 09e35b1..e6c858a 100644
--- a/ldap/servers/slapd/tools/ldclt/ldclt.h
+++ b/ldap/servers/slapd/tools/ldclt/ldclt.h
@@ -289,11 +289,11 @@ dd/mm/yy | Author	| Comments
  *  - VALID_OPERS	: valid operations
  */
 #define NEED_FILTER	(ADD_ENTRIES|DELETE_ENTRIES|EXACT_SEARCH|RENAME_ENTRIES|ATTR_REPLACE|SCALAB01)
-#define M2_NEED_FILTER	(M2_ABANDON|M2_ATTR_REPLACE_FILE)
+#define M2_NEED_FILTER	(M2_ABANDON|M2_ATTR_REPLACE_FILE|M2_DEREF)
 #define NEED_RANGE	(INCREMENTAL|RANDOM)
 #define NEED_RND_INCR	(ADD_ENTRIES|DELETE_ENTRIES|RENAME_ENTRIES)
 #define VALID_OPERS	(ADD_ENTRIES|DELETE_ENTRIES|EXACT_SEARCH|RENAME_ENTRIES|ATTR_REPLACE|SCALAB01)
-#define M2_VALID_OPERS	(M2_GENLDIF|M2_BINDONLY|M2_ABANDON|M2_ATTR_REPLACE_FILE)
+#define M2_VALID_OPERS	(M2_GENLDIF|M2_BINDONLY|M2_ABANDON|M2_ATTR_REPLACE_FILE|M2_DEREF)
 #define NEED_CLASSES	(ADD_ENTRIES)
 #define THE_CLASSES	(OC_PERSON|OC_EMAILPERSON|OC_INETORGPRSON)
 
@@ -506,6 +506,8 @@ typedef struct main_context {
 	int		 asyncMax;	/* Max async pending */
 	char		*attrlist[MAX_ATTRIBS];			/*JLS 15-03-01*/
 	int		 attrlistNb;	/* Nb attrib in list */	/*JLS 15-03-01*/
+	char		*attRef;	/* Name of referenced attribute name */
+	char		*attRefDef;	/* Name of dereferenced attribute name*/
 	char		*attrpl;	/* Attrib argument */	/*JLS 21-11-00*/
 	char		*attrplFile;	/* Attrib file to get value from */
 	char		*attrplFileContent;	/* Attrib file content */
diff --git a/ldap/servers/slapd/tools/ldclt/threadMain.c b/ldap/servers/slapd/tools/ldclt/threadMain.c
index 46b1b63..f6a2428 100644
--- a/ldap/servers/slapd/tools/ldclt/threadMain.c
+++ b/ldap/servers/slapd/tools/ldclt/threadMain.c
@@ -1124,9 +1124,8 @@ threadMain (
     tttctx->bufAttrpl = mctx.attrplFileContent;
     if (tttctx->bufAttrpl == NULL)
     {
-      printf ("ldclt[%d]: T%03d: cannot malloc(tttctx->bufAttrpl), error=%d (%s), can we read file [%s]\n",
-		mctx.pid, tttctx->thrdNum, errno, strerror (errno), mctx.attrplFile);
-      ldcltExit (EXIT_INIT);					/*JLS 18-12-00*/
+      printf ("ldclt[%d]: T%03d: cannot malloc(tttctx->bufAttrpl), error=%d (%s), can we read file [%s]\n", mctx.pid, tttctx->thrdNum, errno, strerror (errno), mctx.attrplFile);
+      ldcltExit (EXIT_INIT);
     }
   }
 
-- 
1.6.2.5

--
389-devel mailing list
389-devel@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/fedora-directory-devel

[Index of Archives]     [Fedora Directory Announce]     [Fedora Users]     [Older Fedora Users Mail]     [Fedora Advisory Board]     [Fedora Security]     [Fedora Devel Java]     [Fedora Desktop]     [ATA RAID]     [Fedora Marketing]     [Fedora Mentors]     [Fedora Package Review]     [Fedora Art]     [Fedora Music]     [Fedora Packaging]     [CentOS]     [Fedora SELinux]     [Big List of Linux Books]     [KDE Users]     [Fedora Art]     [Fedora Docs]

  Powered by Linux