home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / modules / rdf / src / ldap2rdf.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  12.0 KB  |  546 lines

  1. /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  *
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18.  
  19. /* 
  20.    This file implements LDAP support for the rdf data model.
  21.    For more information on this file, contact rjc or guha 
  22.    For more information on RDF, look at the RDF section of www.mozilla.org
  23. */
  24.  
  25. #ifdef MOZ_LDAP
  26.  
  27. #include "ldap2rdf.h"
  28. #include "utils.h"
  29.  
  30.  
  31.     /* statics */
  32. static PRHashTable    *ldap2rdfHash;
  33. static PRHashTable    *invldap2rdfHash;
  34. static RDFT        gRDFDB;
  35. static PRBool        ldap2rdfInitedp = 0;
  36.  
  37.  
  38.  
  39. RDFT
  40. MakeLdapStore (char* url)
  41. {
  42.   RDF_Translator ntr = (RDF_Translator)getMem(sizeof(RDF_TranslatorStruct));
  43.   ntr->assert = ldapAssert;
  44.   ntr->unassert = ldapUnassert;
  45.   ntr->getSlotValue = ldapGetSlotValue;
  46.   ntr->getSlotValues = ldapGetSlotValues;
  47.   ntr->hasAssertion = ldapHasAssertion;
  48.   ntr->nextValue = ldapNextValue;
  49.   ntr->disposeCursor = ldapDisposeCursor;
  50.   ldap2rdfInit(ntr);
  51.   return ntr;
  52. }
  53.  
  54.  
  55.  
  56. RDF_Error
  57. LdapInit (RDFT ntr)
  58. {
  59.   ntr->assert = ldapAssert;
  60.   ntr->unassert = ldapUnassert;
  61.   ntr->getSlotValue = ldapGetSlotValue;
  62.   ntr->getSlotValues = ldapGetSlotValues;
  63.   ntr->hasAssertion = ldapHasAssertion;
  64.   ntr->nextValue = ldapNextValue;
  65.   ntr->disposeCursor = ldapDisposeCursor;
  66.   ldap2rdfInit(ntr);
  67.   return 0;
  68. }
  69.  
  70.  
  71.  
  72. void
  73. ldap2rdfInit (RDFT rdf)
  74. {
  75.   if (!ldap2rdfInitedp) {
  76.     ldap2rdfHash = PR_NewHashTable(500, idenHash, idenEqual, idenEqual, null, null);
  77.     invldap2rdfHash = PR_NewHashTable(500, idenHash, idenEqual, idenEqual, null, null);
  78.     gRDFDB  = rdf;
  79.     ldap2rdfInitedp = 1;
  80.   }
  81. }
  82.  
  83.  
  84.  
  85. Assertion
  86. ldaparg1 (RDF_Resource u)
  87. {
  88.     return (Assertion) PR_HashTableLookup(ldap2rdfHash, u);
  89. }
  90.  
  91.  
  92.  
  93. Assertion
  94. setldaparg1 (RDF_Resource u, Assertion as)
  95. {
  96.     return (Assertion) PR_HashTableAdd(ldap2rdfHash, u, as);
  97. }
  98.  
  99.  
  100.  
  101. Assertion
  102. ldaparg2 (RDF_Resource u)
  103. {
  104.     return (Assertion) PR_HashTableLookup(invldap2rdfHash, u);
  105. }
  106.  
  107.  
  108.  
  109. Assertion
  110. setldaparg2 (RDF_Resource u, Assertion as)
  111. {
  112.     return (Assertion) PR_HashTableAdd(invldap2rdfHash, u, as);
  113. }
  114.  
  115.  
  116.  
  117. PRBool
  118. ldapAssert (RDFT rdf, RDF_Resource u, RDF_Resource s, void* v, 
  119.            RDF_ValueType type, PRBool tv)
  120. {
  121.   if (!ldap2rdfInitedp) ldap2rdfInit(rdf);
  122.   if ((s == gCoreVocab->RDF_parent) && (type == RDF_RESOURCE_TYPE)  &&
  123.       (tv) && (ldapContainerp(v))) {
  124.     return (ldapAddChild(rdf, (RDF_Resource)v, u));
  125.   } else {
  126.     return 0;
  127.   }
  128. }
  129.  
  130.  
  131.  
  132. PRBool
  133. ldapUnassert (RDFT rdf, RDF_Resource u, RDF_Resource s, void* v, 
  134.            RDF_ValueType type)
  135. {
  136.   if (!ldap2rdfInitedp) ldap2rdfInit(rdf);
  137.   if ((s == gCoreVocab->RDF_parent) && (type == RDF_RESOURCE_TYPE)  &&
  138.       (ldapContainerp(v))) {
  139.     return (ldapRemoveChild(rdf, (RDF_Resource)v, u));
  140.   } else {
  141.     return 0;
  142.   }
  143. }
  144.  
  145.  
  146.  
  147. PRBool
  148. ldapDBAdd (RDFT rdf, RDF_Resource u, RDF_Resource s, void* v, RDF_ValueType type)
  149. {
  150.   Assertion nextAs, prevAs, newAs; 
  151.   if ((s == gCoreVocab->RDF_instanceOf) && (v == gWebData->RDF_Container)) {
  152.     setContainerp(u, true);
  153.     return 1;
  154.   }
  155.      
  156.   nextAs = prevAs = ldaparg1(u);
  157.   while (nextAs != null) {
  158.     if (asEqual(nextAs, u, s, v, type)) return 1;
  159.     prevAs = nextAs;
  160.     nextAs = nextAs->next;
  161.   }
  162.   newAs = makeNewAssertion(u, s, v, type, 1);
  163.   if (prevAs == null) {
  164.     setldaparg1(u, newAs);
  165.   } else {
  166.     prevAs->next = newAs;
  167.   }
  168.   if (type == RDF_RESOURCE_TYPE) {
  169.     nextAs = prevAs = ldaparg2((RDF_Resource)v);
  170.     while (nextAs != null) {
  171.       prevAs = nextAs;
  172.       nextAs = nextAs->invNext;
  173.     }
  174.     if (prevAs == null) {
  175.       setldaparg2((RDF_Resource)v, newAs);
  176.     } else {
  177.       prevAs->invNext = newAs;
  178.     }
  179.   }
  180.   sendNotifications2(rdf, RDF_ASSERT_NOTIFY, u, s, v, type, 1);
  181.   return true;
  182. }
  183.  
  184.  
  185.  
  186. PRBool
  187. ldapDBRemove (RDFT rdf, RDF_Resource u, RDF_Resource s, void* v, RDF_ValueType type)
  188. {
  189.   Assertion nextAs, prevAs,  ans;
  190.   PRBool found = false;
  191.   nextAs = prevAs = ldaparg1(u);
  192.   while (nextAs != null) {
  193.     if (asEqual(nextAs, u, s, v, type)) {
  194.       if (prevAs == null) {
  195.     setldaparg1(u, nextAs->next);
  196.       } else {
  197.     prevAs->next = nextAs->next;
  198.       }
  199.       found = true;
  200.       ans = nextAs;
  201.       break;
  202.     }
  203.     prevAs = nextAs;
  204.     nextAs = nextAs->next; 
  205.   }
  206.   if (found == false) return false;
  207.   if (type == RDF_RESOURCE_TYPE) {
  208.     nextAs = prevAs = ldaparg2((RDF_Resource)v);
  209.     while (nextAs != null) {
  210.       if (nextAs == ans) {
  211.     if (prevAs == nextAs) {
  212.     setldaparg2((RDF_Resource)v,  nextAs->invNext);
  213.     } else {
  214.       prevAs->invNext = nextAs->invNext;
  215.     }
  216.       }
  217.       prevAs = nextAs;
  218.       nextAs = nextAs->invNext;
  219.     }
  220.   }
  221.   sendNotifications2(rdf, RDF_DELETE_NOTIFY, u, s, v, type, 1);
  222.   return true;
  223. }
  224.  
  225.  
  226.  
  227. PRBool
  228. ldapHasAssertion (RDFT rdf, RDF_Resource u, RDF_Resource s, void* v, RDF_ValueType type, PRBool tv)
  229. {
  230.   Assertion nextAs;
  231.   if (!ldap2rdfInitedp) ldap2rdfInit(rdf);
  232.  
  233.   nextAs = ldaparg1(u);
  234.   while (nextAs != null) {
  235.     if (asEqual(nextAs, u, s, v, type) && (nextAs->tv == tv)) return true;
  236.     nextAs = nextAs->next;
  237.   }
  238.  
  239.   possiblyAccessldap(rdf, u, s, false);
  240.  
  241.   nextAs = ldaparg1(u);
  242.   while (nextAs != null) {
  243.     if (asEqual(nextAs, u, s, v, type) && (nextAs->tv == tv)) return true;
  244.     nextAs = nextAs->next;
  245.   }
  246.   return false;
  247. }
  248.  
  249.  
  250.  
  251. void *
  252. ldapGetSlotValue (RDFT rdf, RDF_Resource u, RDF_Resource s, RDF_ValueType type, PRBool inversep,  PRBool tv)
  253. {
  254.   Assertion nextAs;
  255.   if (!ldap2rdfInitedp) ldap2rdfInit(rdf);
  256.  
  257.   nextAs = (inversep ? ldaparg2(u) : ldaparg1(u));
  258.   while (nextAs != null) {
  259.     if ((nextAs->s == s) && (nextAs->tv == tv) && (nextAs->type == type)) {
  260.       return (inversep ? nextAs->u : nextAs->value);
  261.     }
  262.     nextAs = (inversep ? nextAs->invNext : nextAs->next);
  263.   }
  264.  
  265.   possiblyAccessldap(rdf, u, s, inversep);
  266.  
  267.   nextAs = (inversep ? ldaparg2(u) : ldaparg1(u));
  268.   while (nextAs != null) {
  269.     if ((nextAs->s == s) && (nextAs->tv == tv) && (nextAs->type == type)) {
  270.       return (inversep ? nextAs->u : nextAs->value);
  271.     }
  272.     nextAs = (inversep ? nextAs->invNext : nextAs->next);
  273.   }
  274.  
  275.   return null;
  276. }
  277.  
  278.  
  279.  
  280. RDF_Cursor
  281. ldapGetSlotValues (RDFT rdf, RDF_Resource u, RDF_Resource s, RDF_ValueType type,  PRBool inversep, PRBool tv)
  282. {
  283.   Assertion as;
  284.   RDF_Cursor c;
  285.   if (!ldap2rdfInitedp) ldap2rdfInit(rdf);
  286.   as  = (inversep ? ldaparg2(u) : ldaparg1(u));
  287.   if (as == null) {
  288.     possiblyAccessldap(rdf, u, s, inversep);
  289.     as  = (inversep ? ldaparg2(u) : ldaparg1(u));
  290.     if (as == null)
  291.     return null;
  292.   }
  293.   c = (RDF_CursorStruc*)getMem(sizeof(RDF_CursorStruc));
  294.   c->u = u;
  295.   c->s = s;
  296.   c->type = type;
  297.   c->inversep = inversep;
  298.   c->tv = tv;
  299.   c->count = 0;
  300.   c->pdata = as;
  301.   return c;
  302. }
  303.  
  304.  
  305.  
  306. void *
  307. ldapNextValue (RDFT mcf, RDF_Cursor c)
  308. {
  309.   while (c->pdata != null) {
  310.     Assertion as = (Assertion) c->pdata;
  311.     if ((as->s == c->s) && (as->tv == c->tv) && (c->type == as->type)) {
  312.       c->value = (c->inversep ? as->u : as->value);
  313.       c->pdata = (c->inversep ? as->invNext : as->next);
  314.       return c->value;
  315.     }
  316.     c->pdata = (c->inversep ? as->invNext : as->next);
  317.   }
  318.   return null;
  319. }
  320.  
  321.  
  322.  
  323. RDF_Error
  324. ldapDisposeCursor (RDFT mcf, RDF_Cursor c)
  325. {
  326.   freeMem(c);
  327.   return noRDFErr;
  328. }
  329.  
  330.  
  331.  
  332. RDF_Resource
  333. ldapNewContainer(char *id)
  334. {
  335.     return(NULL);
  336. }
  337.  
  338.  
  339.  
  340. int
  341. ldapModifyEntry (RDFT rdf, RDF_Resource parent, RDF_Resource child, PRBool addFlag)
  342. {
  343.     RDF_Cursor    c;
  344.     RDF_Resource    newParent, r;
  345.     char        *urivals[2];
  346.     LDAP        *ld;
  347.     LDAPMod        urimod, *mods[2];
  348.     LDAPURLDesc    *ldURL=NULL;
  349.     int        err;
  350.     char        *errStr, *parentID;
  351.  
  352.     parentID = resourceID(parent);
  353.  
  354.     if (containerp(child))
  355.     {
  356.         if (newParent = ldapNewContainer(parentID))
  357.         {
  358.             if ((c = RDF_GetSources(rdf->rdf->rdf, child,
  359.                 gCoreVocab->RDF_parent, RDF_RESOURCE_TYPE, 1)) != NULL)
  360.             {
  361.                 while ((r = RDF_NextValue(c)) != NULL)
  362.                 {
  363.                     err = ldapModifyEntry(rdf, newParent, r, addFlag);
  364.                     if (err)
  365.                     {
  366.                         /* XXX MAJOR rollback issues!
  367.                             Punt for now! */
  368.  
  369.                         return(err);
  370.                     }
  371.                 }
  372.             }
  373.             else
  374.             {
  375.                 return(-1);
  376.             }
  377.         }
  378.         else
  379.         {
  380.             return(-1);
  381.         }
  382.     }
  383.  
  384.     ldap_url_parse(parentID, &ldURL);
  385.     if (ldURL == NULL)    return(-1);
  386.     ld = ldap_init (ldURL->lud_host, ldURL->lud_port);
  387.     if (ld == NULL)
  388.     {
  389.         ldap_free_urldesc(ldURL);
  390.         return(-1);
  391.     }
  392.     if ((err = ldap_simple_bind_s(ld, ADMIN_ID, ADMIN_PW))        /* XXX */
  393.         != LDAP_SUCCESS)
  394.     {
  395.         if ((errStr = ldap_err2string(err)) != NULL)
  396.         {
  397.             XP_MakeHTMLAlert(NULL, errStr);
  398.         }
  399.  
  400.         ldap_unbind(ld);
  401.         ldap_free_urldesc(ldURL);
  402.         return(-1);
  403.     }
  404.  
  405.     urivals[0] = resourceID(child);
  406.     urivals[1] = NULL;
  407.  
  408.     urimod.mod_op = ((addFlag == true) ? LDAP_MOD_ADD : LDAP_MOD_DELETE);
  409.     urimod.mod_type = "labeledURI";
  410.     urimod.mod_values = urivals;
  411.  
  412.     mods[0] = &urimod;
  413.     mods[1] = NULL;
  414.  
  415.     err = ldap_modify_s(ld, ldURL->lud_dn, mods);
  416.     if (err != LDAP_SUCCESS)
  417.     {
  418.         if ((errStr = ldap_err2string(err)) != NULL)
  419.         {
  420.             XP_MakeHTMLAlert(NULL, errStr);
  421.         }
  422.     }
  423.  
  424.     ldap_unbind(ld);
  425.     ldap_free_urldesc(ldURL);
  426.     return(err);
  427. }
  428.  
  429.  
  430.  
  431. PRBool
  432. ldapAddChild (RDFT rdf, RDF_Resource parent, RDF_Resource child)
  433. {
  434.     return (ldapModifyEntry(rdf, parent, child, true) != LDAP_SUCCESS);
  435. }
  436.  
  437.  
  438.  
  439. PRBool
  440. ldapRemoveChild (RDFT rdf, RDF_Resource parent, RDF_Resource child)
  441. {
  442.     return (ldapModifyEntry(rdf, parent, child, false) != LDAP_SUCCESS);
  443. }
  444.  
  445.  
  446.  
  447. void
  448. possiblyAccessldap(RDFT rdf, RDF_Resource u, RDF_Resource s, PRBool inversep)
  449. {
  450.   /** try to get the values of u.s from the directory **/
  451.  
  452.     LDAP        *ld;
  453.     LDAPMessage    *result=NULL, *entry;
  454.     LDAPURLDesc    *ldURL=NULL;
  455.     RDF_Resource    node;
  456.     char        *attrs[2], **vals;
  457.     int        err, i;
  458.     char        *title = NULL;
  459.  
  460.     /*
  461.         Note: a labeledURI is a url followed by an optional [space title-string]
  462.          */
  463.  
  464.   if (!stringEquals(resourceID(s), resourceID(gCoreVocab->RDF_parent)) || (!inversep) || (!ldap_is_ldap_url(resourceID(u))))    return;
  465.  
  466.   ldap_url_parse(resourceID(u), &ldURL);
  467.   if (ldURL == NULL)    return;
  468.   ld = ldap_init (ldURL->lud_host, ldURL->lud_port);
  469.   if (ld == NULL)
  470.     {
  471.     ldap_free_urldesc(ldURL);
  472.     return;
  473.     }
  474.   if ((err = ldap_simple_bind_s(ld, NULL, NULL)) != LDAP_SUCCESS)
  475.     {
  476.     ldap_unbind(ld);
  477.     ldap_free_urldesc(ldURL);
  478.     return;
  479.     }
  480.  
  481.   attrs[0] = "labeledURI";
  482.   attrs[1] = NULL;
  483.  
  484.   err = ldap_search_s(ld, ldURL->lud_dn, LDAP_SCOPE_BASE, ldURL->lud_filter, attrs, 0, &result);
  485.   if (err == LDAP_SUCCESS)
  486.     {
  487.     for (entry=ldap_first_entry(ld, result); entry!=NULL; entry=ldap_next_entry(ld, entry))
  488.         {
  489.         if ((vals = ldap_get_values(ld, entry, attrs[0])) != NULL)
  490.         {
  491.             for (i=0; vals[i] != NULL; i++)
  492.             {
  493.                 /* vals[i] has a URL... add into RDF graph */
  494.  
  495. /*
  496.                 if (((title = strstr(vals[i], " ")) != NULL)
  497.                     && (*(title+1) != '\0'))
  498.                 {
  499.                     *(++title) = '\0';
  500.                 }
  501.                 else
  502.                 {
  503.                     title = NULL;
  504.                 }
  505. */
  506.                 if ((node = RDF_Create(vals[i], true)) != NULL)
  507.                 {
  508.                     setResourceType(node, LDAP_RT);
  509.                     if (ldapContainerp(node) == true)
  510.                     {
  511.                         setContainerp(node, 1);
  512.                     }
  513.  
  514.                     ldapDBAdd(rdf, node, gCoreVocab->RDF_parent,
  515.                             u, RDF_RESOURCE_TYPE);
  516.  
  517.                     if (title != NULL)
  518.                     {
  519.                         ldapDBAdd(rdf, node, gCoreVocab->RDF_name,
  520.                             title, RDF_STRING_TYPE);
  521.                     }
  522.                 }
  523.             }
  524.             ldap_value_free(vals);
  525.             }
  526.         }
  527.     }
  528.   if (result != NULL)
  529.     {
  530.     ldap_msgfree(result);
  531.     }
  532.   ldap_unbind(ld);
  533.   ldap_free_urldesc(ldURL);
  534. }
  535.  
  536.  
  537.  
  538. PRBool
  539. ldapContainerp (RDF_Resource u)
  540. {
  541.     return(ldap_is_ldap_url(resourceID(u)));        /* XXX ??? */
  542. }
  543.  
  544.  
  545. #endif /* MOZ_LDAP */
  546.