summaryrefslogtreecommitdiffstats
path: root/ldap/clients/dsgw/dnedit.c
diff options
context:
space:
mode:
Diffstat (limited to 'ldap/clients/dsgw/dnedit.c')
-rw-r--r--ldap/clients/dsgw/dnedit.c415
1 files changed, 415 insertions, 0 deletions
diff --git a/ldap/clients/dsgw/dnedit.c b/ldap/clients/dsgw/dnedit.c
new file mode 100644
index 00000000..5ee761ef
--- /dev/null
+++ b/ldap/clients/dsgw/dnedit.c
@@ -0,0 +1,415 @@
+/**
+ * PROPRIETARY/CONFIDENTIAL. Use of this product is subject to
+ * license terms. Copyright © 2001 Sun Microsystems, Inc.
+ * Some preexisting portions Copyright © 2001 Netscape Communications Corp.
+ * All rights reserved.
+ */
+/*
+ * Generate a DN edit screen.
+ */
+
+#include "dsgw.h"
+#include "dbtdsgw.h"
+
+#ifdef DSGW_DEBUG
+int main(int argc, char *argv[], char *env[] )
+#else /* DSGW_DEBUG */
+int main(int argc, char *argv[] )
+#endif /* DSGW_DEBUG */
+{
+ char *tmplname, *attrname, *attrdesc, *qs, *dn, *edn;
+ char *attrs[ 2 ], **attrvals, **xdn, *avedn, *js0, *js1;
+ LDAP *ld;
+ LDAPMessage *msgp;
+ int i;
+
+ /*
+ * The URL used to invoke this CGI looks like:
+ * http://host/dnedit?CONTEXT=context&TEMPLATE=tmplname&DN=dn&ATTR=attrname&DESC=description
+ *
+ * where:
+ * "tmplname" is the name of the HTML template to render
+ * "attrname" is the name of a dn-valued attribute to display
+ * "description" is a textual description of the attribute
+ *
+ * Note: original form http://host/dnedit/dn?... is supported
+ * for keeping backward compatibility.
+ */
+ tmplname = attrname = attrdesc = dn = edn = NULL;
+ if (( qs = getenv( "QUERY_STRING" )) != NULL && *qs != '\0' ) {
+ char *p, *q;
+ q = qs + strlen( qs );
+ while ((( p = strrchr( qs, '&' )) != NULL ) || ( q - qs > 1 )) {
+ if ( p )
+ *p++ = '\0';
+ else
+ p = qs;
+ q = p;
+
+ if ( p != NULL && strncasecmp( p, "dn=", 3 ) == 0 ) {
+ edn = dsgw_ch_strdup( p + 3 );
+ dn = dsgw_ch_strdup( p + 3 );
+ dsgw_form_unescape( dn );
+ } else if ( p != NULL && strncasecmp( p, "template=", 9 ) == 0 ) {
+ tmplname = dsgw_ch_strdup( p + 9 );
+ dsgw_form_unescape( tmplname );
+ } else if ( p != NULL && strncasecmp( p, "attr=", 5 ) == 0 ) {
+ attrname = dsgw_ch_strdup( p + 5 );
+ dsgw_form_unescape( attrname );
+ } else if ( p != NULL && strncasecmp( p, "desc=", 5 ) == 0 ) {
+ attrdesc = dsgw_ch_strdup( p + 5 );
+ /* Don't bother unescaping it;
+ we're only going to put it back in another URL. */
+ } else if ( p != NULL && strncasecmp( p, "context=", 8 ) == 0) {
+ context = dsgw_ch_strdup( p + 8 );
+ dsgw_form_unescape( context );
+ }
+
+ }
+
+ if ( !tmplname )
+ dsgw_error( DSGW_ERR_MISSINGINPUT, "template", DSGW_ERROPT_EXIT,
+ 0, NULL );
+ if ( !attrname )
+ dsgw_error( DSGW_ERR_MISSINGINPUT, "attr", DSGW_ERROPT_EXIT,
+ 0, NULL );
+ if ( !attrdesc )
+ dsgw_error( DSGW_ERR_MISSINGINPUT, "desc", DSGW_ERROPT_EXIT,
+ 0, NULL );
+ } else {
+ dsgw_error( DSGW_ERR_MISSINGINPUT, NULL, DSGW_ERROPT_EXIT, 0, NULL );
+ }
+
+ if ( dn == NULL ) {
+ dsgw_error( DSGW_ERR_MISSINGINPUT, "dn", DSGW_ERROPT_EXIT, 0, NULL );
+ }
+
+ (void)dsgw_init( argc, argv, DSGW_METHOD_GET );
+
+#ifdef DSGW_DEBUG
+ dsgw_logstringarray( "env", env );
+#endif
+
+ dsgw_send_header();
+
+
+ /* Get the current attribute values */
+ (void) dsgw_init_ldap( &ld, NULL, 0, 0);
+ attrs[ 0 ] = attrname;
+ attrs[ 1 ] = NULL;
+ if (ldap_search_s( ld, dn, LDAP_SCOPE_BASE, "(objectclass=*)", attrs, 0,
+ &msgp ) != LDAP_SUCCESS ) {
+ dsgw_error( DSGW_ERR_ENTRY_NOT_FOUND, dn, DSGW_ERROPT_EXIT, 0, NULL );
+ }
+ attrvals = ldap_get_values( ld, msgp, attrname );
+
+
+ /* Send the top-level document HTML */
+ dsgw_emits( "<HTML>\n"
+ "<SCRIPT LANGUAGE=\"JavaScript\">\n" );
+ dsgw_emitf( "var emptyFrame = '';\n" );
+ dsgw_emitf( "var attrname = '%s';\n", attrname );
+ /*
+ * fix for 333110: dn should be escaped to be used in saveChanges/domodify
+ */
+ dsgw_emitf( "var dn = '%s';\n", edn );
+ dsgw_emitf( "var needToSaveChanges = false;\n" );
+ dsgw_emitf( "var completion_url = '%s?dn=%s&context=%s';\n",
+ dsgw_getvp( DSGW_CGINUM_EDIT ), edn, context);
+ dsgw_emitf(
+ /*
+ * This needs to output \\\' so that when JavaScript writeln's
+ * this string, it writes \' to the output document.
+ *
+ * I'm really, really sorry about this - ggood.
+ *
+ * Moral of the story - next time someone asks you to write C code which
+ * writes JavaScript code which writes JavaScript code... just say "no".
+ */
+ "var comp_js = 'var cu=\\\\\\\'%s?context=%s&dn=%s\\\\\\\'; this.document.location.href=cu;'\n",
+ dsgw_getvp( DSGW_CGINUM_EDIT ), context, edn );
+ dsgw_emits("var dnlist = new Array;\n" );
+ for ( i = 0; attrvals && attrvals[ i ] != NULL; i++ ) {
+ xdn = ldap_explode_dn( attrvals[ i ], 1 );
+ avedn = dsgw_strdup_escaped( attrvals[ i ]);
+ dsgw_emitf( "dnlist[%d] = new Object\n", i );
+ dsgw_emitf( "dnlist[%d].edn = '%s';\n", i, avedn );
+ js0 = dsgw_escape_quotes( xdn[ 0 ] );
+ if ( xdn[1] != NULL ) {
+ js1 = dsgw_escape_quotes( xdn[ 1 ] );
+ dsgw_emitf( "dnlist[%d].rdn = '%s, %s';\n", i, js0, js1 );
+ free( js1 );
+ } else {
+ dsgw_emitf( "dnlist[%d].rdn = '%s';\n", i, js0 );
+ }
+ free( js0 );
+ dsgw_emitf( "dnlist[%d].selected = false;\n", i );
+ free( avedn );
+ ldap_value_free( xdn );
+ }
+ dsgw_emitf( "dnlist.count = %d;\n", i );
+ dsgw_emits(
+ "var changesMade = 0;\n"
+ "\n"
+
+ /*
+ * JavaScript function processSearch
+ */
+
+ "function processSearch(f)\n"
+ "{\n"
+ " var sel = f.type;\n"
+ " var selvalue = sel.options[sel.selectedIndex].value;\n"
+ " var lt = f.listtemplate;\n"
+ " if ( f.searchstring.value.length == 0 ) {\n");
+ dsgw_emit_alert( "controlFrame", NULL, XP_GetClientStr( DBT_noSearchStringWasProvidedPleaseT_ ));
+ dsgw_emits(
+ " return false;\n"
+ " }\n"
+ " lt.value = 'fa-' + selvalue;\n");
+ dsgw_emitf(
+ " f.action = ");
+ dsgw_quote_emitf( QUOTATION_JAVASCRIPT, "%s?context=%s",
+ dsgw_getvp( DSGW_CGINUM_DOSEARCH ), context);
+ dsgw_emits( ";\n"
+ " f.searchstring.select();\n"
+ " f.searchstring.focus();\n"
+ " return true;\n"
+ "}\n"
+ "\n"
+
+ /*
+ * JavaScript function removeItem
+ */
+
+ "function removeItem(itemno, refresh)\n"
+ "{\n"
+ " var extantDNs = dnlist;\n"
+ " var extantDNsCount = dnlist.count;\n"
+ " \n"
+ " // Get rid of element in slot dup\n"
+ " for (k = itemno; k < extantDNsCount - 1; k++) {\n"
+ " extantDNs[k] = extantDNs[k+1];\n"
+ " }\n"
+ " dnlist.count--;\n"
+ " if ( refresh ) genOutputFrame(outputFrame, dnlist);\n"
+ " this.changesMade = 1;\n"
+ "}\n"
+ "\n"
+
+ /*
+ * JavaScript function dnarrcomp
+ */
+
+ "function dnarrcomp(a,b)\n"
+ "{\n"
+ " return(a.edn.toLowerCase() > b.edn.toLowerCase());\n"
+ "}\n"
+ " \n"
+#ifdef NAV30_SORT_NO_LONGER_COREDUMPS
+ /*
+ * JavaScript function sortEntries
+ */
+
+ "function sortEntries()\n"
+ "{\n"
+ " var extantDNs = dnlist;\n"
+ " extantDNs.sort(dnarrcomp);\n"
+ " genOutputFrame(outputFrame, dnlist);\n"
+ "}\n"
+ "\n"
+#endif /* NAV30_SORT_NO_LONGER_COREDUMPS */
+
+ /*
+ * JavaScript function genOutputFrame
+ */
+
+ "function genOutputFrame(oframe, dnl)\n"
+ "{\n"
+ " var d = oframe.document;\n"
+ "\n"
+ " d.open('text/html');\n"
+ " d.writeln('<HTML>');\n" );
+
+ dsgw_emitf(
+ " d.writeln('<BODY %s>');\n", dsgw_html_body_colors );
+ dsgw_emits(
+ " d.writeln(");
+ dsgw_quotation_begin (QUOTATION_JAVASCRIPT);
+ dsgw_form_begin (NULL, NULL);
+ dsgw_quotation_end();
+ dsgw_emits( ");\n");
+ dsgw_emits(
+ " d.writeln('<CENTER>');\n"
+ " if (dnl.count == 0) {\n" );
+
+ dsgw_emits( " d.write(" );
+ dsgw_quote_emits (QUOTATION_JAVASCRIPT, XP_GetClientStr (DBT_noNameInTheList_));
+ dsgw_emits( ");\n" );
+
+ dsgw_emits( " } else if (dnl.count == 1) {\n" );
+ dsgw_emits( " d.write(" );
+ dsgw_quote_emits (QUOTATION_JAVASCRIPT, XP_GetClientStr (DBT_oneNameInTheList_));
+ dsgw_emits( ");\n" );
+ dsgw_emits( " } else {\n" );
+ dsgw_emits( " d.write('");
+ dsgw_emitf( XP_GetClientStr( DBT_someNamesInTheList_ ), "' + dnl.count + '" );
+ dsgw_emits( "');\n" );
+
+ dsgw_emits(
+ " }\n"
+#ifdef NAV30_SORT_NO_LONGER_COREDUMPS
+ " d.writeln('</FONT>\\n')\n"
+ " d.writeln('<INPUT TYPE=\"button\" VALUE=\"Sort\" onClick=\"parent.sortEntries();\"></CENTER>\\n');\n"
+#else
+ " d.writeln('</FONT></CENTER>\\n');\n"
+#endif
+ " if (dnl.count > 0) {\n"
+ " d.write('<PRE><B>');\n" );
+
+ dsgw_emitf(
+ " d.write('%s</B><HR>');\n",
+ XP_GetClientStr( DBT_RemoveFromList_ ));
+
+ dsgw_emits(
+ " for (i = 0; i < dnl.count; i++) {\n"
+ " d.write('<INPUT TYPE=CHECKBOX onClick=\"parent."
+ "removeItem(' + i + ', true);\">');\n"
+ " d.write(' ');\n"
+ " d.write(dnl[i].rdn + '\\n');\n"
+ " }\n"
+ " d.writeln('</PRE></FORM><HR>');\n"
+ " }\n"
+ " d.writeln('</BODY>');\n"
+ " d.close();\n"
+ "}\n"
+ "\n"
+
+ /*
+ * JavaScript function mergeLists
+ */
+
+ "function mergeLists(mode, old, newl)\n"
+ "{\n"
+ " var dup = -1;\n"
+ " var i, j, k;\n"
+ " \n"
+ " for (i = 0; i < newl.count; i++) {\n"
+ " // Check for a duplicate\n"
+ " for (j = 0; j < old.count; j++) {\n"
+ " dup = -1;\n"
+ " if (newl[i].edn.toLowerCase() == "
+ "old[j].edn.toLowerCase()) {\n"
+ " // Duplicate - skip\n"
+ " dup = j;\n"
+ " break;\n"
+ " }\n"
+ " }\n"
+ " if ((dup == -1) && (mode == \"add\")) {\n"
+ " // add new dn at end of array\n"
+ " old[old.count] = new Array;\n"
+ " old[old.count].edn = newl[i].edn;\n"
+ " old[old.count].rdn = newl[i].rdn;\n"
+ " old[old.count].sn = newl[i].sn;\n"
+ " old[old.count].selected = false;\n"
+ " old.count++;\n"
+ " } else if (dup != -1 && mode == \"remove\") {\n"
+ " removeItem(dup,false);\n"
+ " }\n"
+ " }\n"
+ "}\n"
+ "\n"
+
+ /*
+ * JavaScript function updateList
+ */
+
+ "function updateList(mode, old_list, new_list, outframe)\n"
+ "{\n"
+ " mergeLists(mode, old_list, new_list);\n"
+ " genOutputFrame(outframe, old_list);\n"
+ " this.changesMade = 1;\n"
+ "}\n"
+ "\n"
+
+ /*
+ * JavaScript function cancel
+ */
+ "function cancel ()\n"
+ "{\n"
+ " if (changesMade == 0) {\n"
+ " document.location = completion_url;\n"
+ " } else {\n");
+ dsgw_emit_confirm ("controlFrame",
+ "opener.document.location.href = opener.completion_url;",
+ NULL /* no */,
+ XP_GetClientStr(DBT_discardChangesWindow_), 1,
+ XP_GetClientStr(DBT_discardChanges_));
+ dsgw_emits (
+ " }\n"
+ "}\n"
+ "\n"
+
+ /*
+ * JavaScript function saveChanges
+ */
+
+ "function saveChanges()\n"
+ "{\n"
+ " var i, j;\n"
+ " needToSaveChanges = true;\n"
+ " of = self.stagingFrame.document;\n"
+ " of.open('text/html');\n" );
+ dsgw_emitf(
+ " of.write('<BODY onLoad=\"if ( parent.needToSaveChanges ) { parent.needToSaveChanges = false; document.stagingForm.submit() }\">');\n" );
+ dsgw_emits(
+ " of.write('");
+ dsgw_form_begin ("stagingForm",
+ "action=\"%s\" METHOD=\"POST\" TARGET=\"_parent\"",
+ dsgw_getvp( DSGW_CGINUM_DOMODIFY ));
+ dsgw_emits("\\n');\n");
+ dsgw_emits(
+ " if (self.dnlist.count < 1) {\n"
+ " of.write('<INPUT TYPE=\"hidden\" NAME=\"replace_');\n"
+ " of.write(self.attrname);\n"
+ " of.write('\" VALUE=\"\">\\n');\n"
+ " } else {\n"
+ " for (j = 0; j < self.dnlist.count; j++) {\n"
+ " of.write('<INPUT TYPE=\"hidden\" NAME=\"replace_');\n"
+ " of.write(self.attrname);\n"
+ " of.write('\" VALUE=\"');\n"
+ " of.write(unescape(self.dnlist[j].edn));\n"
+ " of.write('\">\\n');\n"
+ " }\n"
+ " }\n"
+ " of.writeln('<INPUT TYPE=\"hidden\" NAME=\"changetype\" "
+ "VALUE=\"modify\">\\n');\n"
+ " of.writeln('<INPUT TYPE=\"hidden\" NAME=\"completion_javascript\" "
+ "VALUE=\"' + comp_js + '\">');\n"
+ " of.writeln('<INPUT TYPE=\"hidden\" NAME=\"dn\" VALUE=\"' "
+ "+ self.dn + '\"\\n');\n"
+ " of.writeln('<INPUT TYPE=\"hidden\" NAME=\"context\" "
+ "VALUE=\"");
+ dsgw_emits(context);
+ dsgw_emits("\">\\n');\n"
+ " of.writeln('</FORM>\\n');\n"
+ " of.close();\n"
+ "}\n"
+
+ "</SCRIPT>\n"
+ "\n"
+ "<FRAMESET BORDER=1 FRAMEBORDER=1 ROWS=230,*,0,0 "
+ "SCROLLING=\"NO\" NORESIZE onLoad=\"genOutputFrame"
+ "(this.outputFrame, this.dnlist);\">\n" );
+ dsgw_emitf( " <FRAME SRC=\"%s?%s&dn=%s&context=%s&DNATTR=%s&"
+ "DNDESC=%s\" NAME=\"controlFrame\" SCROLLING=\"no\">\n",
+ dsgw_getvp( DSGW_CGINUM_EDIT ), tmplname, edn, context, attrname,
+ attrdesc );
+ dsgw_emitf( " <FRAME SRC=\"javascript:parent.emptyFrame\" "
+ "NAME=\"outputFrame\">\n"
+ " <FRAME SRC=\"javascript:parent.emptyFrame\" "
+ "NAME=\"stagingFrame\">\n"
+ "</FRAMESET>\n"
+ "</HTML>\n" );
+ return 0;
+}