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

Re: y2k bs+create/modify



fixed for netscape I think... I dwiddled with this a while back. I'm
attaching a patch to ud that contains a whole bunch of diffs, some mine
some not. Just go through them and poke at em.

--Jauder

On Tue, 15 Sep 1998, Jared Mauch wrote:

> 
>  Modifytimestamp:
>                980915151324Z
> 
> 	:)
> 
> 	Is this being addressed?  I know it's bs for a bit, but i'm building
> a new system (ldap backend for just about everything, radius+realms, mail,
> pop, etc..), and would kinda like to make it so it doesn't need to be updated
> untik y10k
> 
> 	- jared
> 
> -- 
> Jared Mauch  | pgp key available via finger from jared@puck.nether.net
>              | http://puck.nether.net/~jared/
> 
> 
diff -ruN ud.orig/Makefile ud/Makefile
--- ud.orig/Makefile	Fri Dec 12 01:54:29 1997
+++ ud/Makefile	Sun Mar 29 18:41:18 1998
@@ -40,7 +40,7 @@
 		-DLDAP_FRIENDLY_MAP_FILE=\"$(RUNTIMEETCDIR)/ldapfriendly\"
 TERMLIB= -ltermcap
 
-CFLAGS= ${INCLUDES} ${DEFINES} ${ACFLAGS}
+CFLAGS= ${INCLUDES} ${DEFINES} ${ACFLAGS} -O3 -g
 LIBS= ${TERMLIB} -lldap -llber $(KRBLIBFLAG) $(KRBLIBS) $(ALIBS)
 
 PURIFY=
diff -ruN ud.orig/Version.c ud/Version.c
--- ud.orig/Version.c	Tue Jan 25 08:36:29 1994
+++ ud/Version.c	Mon Mar 23 01:20:06 1998
@@ -10,4 +10,4 @@
  * is provided ``as is'' without express or implied warranty.
  */
 
-char Version[] = "  X.500 UserDirectory %VERSION% (%WHEN%)\n\t%WHOANDWHERE%\n";
+char Version[] = "  Transmeta LDAP Directory %VERSION% (%WHEN%)\n\t%WHOANDWHERE%\n";
diff -ruN ud.orig/auth.c ud/auth.c
--- ud.orig/auth.c	Tue Apr  2 12:14:44 1996
+++ ud/auth.c	Wed Nov 26 15:29:01 1997
@@ -155,7 +155,7 @@
 
 		if ( hassimple && !kinited ) {
 			printf("  Which password would you like to use?\n");
-			printf("    1 -> X.500 password\n");
+			printf("    1 -> LDAP password\n");
 #ifdef UOFM
 			printf("    2 -> UMICH password (aka Uniqname or Kerberos password)\n");
 #else
@@ -221,7 +221,7 @@
 	} else {
 #endif
 		authmethod = LDAP_AUTH_SIMPLE;
-		sprintf(prompt, "  Enter your X.500 password: ");
+		sprintf(prompt, "  Enter your LDAP password: ");
 		do {
 			passwd = mygetpass(prompt);
 		} while (passwd != NULL && *passwd == '\0');
diff -ruN ud.orig/find.c ud/find.c
--- ud.orig/find.c	Wed Feb 21 09:48:01 1996
+++ ud/find.c	Wed Nov 26 15:37:30 1997
@@ -224,7 +224,7 @@
 		} else if (matches == 1) {
 			if (ldap_search_s(ld, ldap_get_dn(ld, ldap_first_entry(ld, res)), LDAP_SCOPE_BASE, "objectClass=*", read_attrs, FALSE, &res) != LDAP_SUCCESS) {
 				if (ld->ld_errno == LDAP_UNAVAILABLE)
-					printf("  Could not contact the X.500 server to find \"%s\".\n", who);
+					printf("  Could not contact the LDAP server to find \"%s\".\n", who);
 				else
 					ldap_perror(ld, "ldap_search_s");
 				return(NULL);
diff -ruN ud.orig/globals.c ud/globals.c
--- ud.orig/globals.c	Thu May 18 13:24:34 1995
+++ ud/globals.c	Sun Mar 29 18:19:02 1998
@@ -37,19 +37,26 @@
 	{ "mail", "E-mail address", change_field, ATTR_FLAG_PERSON | ATTR_FLAG_GROUP | ATTR_FLAG_READ | ATTR_FLAG_SEARCH | ATTR_FLAG_PERSON_MOD | ATTR_FLAG_MAY_EDIT },
 	{ "member", "Members", mod_addrDN, ATTR_FLAG_GROUP | ATTR_FLAG_READ | ATTR_FLAG_IS_A_DN | ATTR_FLAG_GROUP_MOD },
 	{ "homePhone", "Home phone", change_field, ATTR_FLAG_PERSON | ATTR_FLAG_READ  | ATTR_FLAG_PERSON_MOD },
+	{ "homeFax", "Home fax", change_field, ATTR_FLAG_PERSON | ATTR_FLAG_READ  | ATTR_FLAG_PERSON_MOD },
+	{ "homeOffice", "Home office", change_field, ATTR_FLAG_PERSON | ATTR_FLAG_READ  | ATTR_FLAG_PERSON_MOD },
 	{ "homePostalAddress", "Home address", change_field, ATTR_FLAG_PERSON | ATTR_FLAG_READ  | ATTR_FLAG_PERSON_MOD | ATTR_FLAG_IS_MULTILINE },
 	{ "objectClass", "Object class", NULL, ATTR_FLAG_PERSON | ATTR_FLAG_GROUP | ATTR_FLAG_READ | ATTR_FLAG_SEARCH },
-#ifdef UOFM
-	{ "multiLineDescription", "Description", change_field, ATTR_FLAG_PERSON | ATTR_FLAG_GROUP | ATTR_FLAG_READ  | ATTR_FLAG_PERSON_MOD | ATTR_FLAG_GROUP_MOD | ATTR_FLAG_IS_MULTILINE },
-#endif
+	{ "description", "Description", change_field, ATTR_FLAG_PERSON | ATTR_FLAG_GROUP | ATTR_FLAG_READ  | ATTR_FLAG_PERSON_MOD | ATTR_FLAG_GROUP_MOD | ATTR_FLAG_IS_MULTILINE },
 #ifdef KERBEROS
 	{ "krbName", "Kerberos name", NULL, ATTR_FLAG_PERSON | ATTR_FLAG_READ },
 #endif
-	{ "description", "Brief description", NULL, ATTR_FLAG_PERSON | ATTR_FLAG_GROUP | ATTR_FLAG_READ },
 	{ "facsimileTelephoneNumber", "Fax number", change_field, ATTR_FLAG_PERSON | ATTR_FLAG_GROUP | ATTR_FLAG_READ  | ATTR_FLAG_PERSON_MOD | ATTR_FLAG_GROUP_MOD },
 	{ "pager", "Pager number", change_field, ATTR_FLAG_PERSON | ATTR_FLAG_READ  | ATTR_FLAG_PERSON_MOD },
+	{ "pagerMail", "Pager email", change_field, ATTR_FLAG_PERSON | ATTR_FLAG_READ  | ATTR_FLAG_PERSON_MOD },
+#ifdef UOFM
 	{ "uid", "Uniqname", NULL, ATTR_FLAG_PERSON | ATTR_FLAG_GROUP | ATTR_FLAG_READ },
+#else
+	{ "uid", "Username", NULL, ATTR_FLAG_PERSON | ATTR_FLAG_GROUP | ATTR_FLAG_READ },
+#endif
+	{ "buildingName", "Building", NULL, ATTR_FLAG_PERSON | ATTR_FLAG_GROUP | ATTR_FLAG_READ },
+	{ "mobile", "Mobile phone", NULL, ATTR_FLAG_PERSON | ATTR_FLAG_GROUP | ATTR_FLAG_READ },
 	{ "userPassword", "Password", NULL, ATTR_FLAG_PERSON | ATTR_FLAG_GROUP | ATTR_FLAG_READ },
+	{ "ou", "Department", NULL, ATTR_FLAG_PERSON | ATTR_FLAG_GROUP | ATTR_FLAG_READ },
 #ifdef UOFM
 	{ "noBatchUpdates", "No batch updates", set_updates, ATTR_FLAG_PERSON | ATTR_FLAG_READ | ATTR_FLAG_PERSON_MOD },
 #endif
@@ -67,5 +74,7 @@
 	{ "drink", "Favorite Beverage", change_field, ATTR_FLAG_PERSON | ATTR_FLAG_READ | ATTR_FLAG_PERSON_MOD },
 	{ "lastModifiedBy", "Last modified by", NULL, ATTR_FLAG_GROUP | ATTR_FLAG_PERSON | ATTR_FLAG_IS_A_DN | ATTR_FLAG_READ },
 	{ "lastModifiedTime", "Last modified at", NULL, ATTR_FLAG_GROUP | ATTR_FLAG_PERSON | ATTR_FLAG_READ | ATTR_FLAG_IS_A_DATE },
+	{ "modifiersname", "Last modified by", NULL, ATTR_FLAG_GROUP | ATTR_FLAG_PERSON | ATTR_FLAG_IS_A_DN | ATTR_FLAG_READ },
+	{ "modifytimestamp", "Last modified at", NULL, ATTR_FLAG_GROUP | ATTR_FLAG_PERSON | ATTR_FLAG_READ | ATTR_FLAG_IS_A_DATE },
 	{ NULL, NULL, NULL, ATTR_FLAG_NONE }
 };
diff -ruN ud.orig/group.c ud/group.c
--- ud.orig/group.c	Tue Apr  2 11:36:47 1996
+++ ud/group.c	Wed Nov 26 15:30:26 1997
@@ -175,7 +175,7 @@
 #endif
 
 	/*
-	 *  Now add this to the X.500 Directory.
+	 *  Now add this to the LDAP Directory.
 	 */
 	if (ldap_add_s(ld, dn, attrs) != 0) {
 		ldap_perror(ld, "  ldap_add_s");
@@ -225,7 +225,7 @@
 		return;
 
 	/*
-	 *  Now remove this from the X.500 Directory.
+	 *  Now remove this from the LDAP Directory.
 	 */
 	if (ldap_delete_s(ld, dn) != 0) {
 		if (ld->ld_errno == LDAP_INSUFFICIENT_ACCESS)
@@ -452,7 +452,7 @@
 		}
 
 		/*
-		 *  Add the X.500 style names.
+		 *  Add the LDAP style names.
 		 */
 		if (count_x500 > 0) {
 			mods[0] = &mod;
@@ -562,7 +562,7 @@
 	vp = Entry.attrs[attr_to_index("member")].values;
 	if (vp == NULL) {
 		if (verbose)
-			printf("  \"%s\" has no X.500 members.  There is nothing to purge.\n", group);
+			printf("  \"%s\" has no LDAP members.  There is nothing to purge.\n", group);
 		return;
 	}
 	for (; *vp != NULL; vp++) {
@@ -805,7 +805,7 @@
 	}
 	if (verbose) {
 		printf("\n");
-		format("Values may be specified as a name (which is then looked up in the X.500 Directory) or as a domain-style (i.e., user@domain) e-mail address.  Simply hit the RETURN key at the prompt when finished.\n", 75, 2);
+		format("Values may be specified as a name (which is then looked up in the LDAP Directory) or as a domain-style (i.e., user@domain) e-mail address.  Simply hit the RETURN key at the prompt when finished.\n", 75, 2);
 		printf("\n");
 	}
 
diff -ruN ud.orig/help.c ud/help.c
--- ud.orig/help.c	Mon Mar 18 11:46:47 1996
+++ ud/help.c	Wed Nov 26 15:30:48 1997
@@ -88,7 +88,7 @@
 		format("should be specified as a ordinary name (e.g., 'Friends of maX500').", 75, 15);
 		printf("\n");
 		printf("  [where]      A place in the Directory needs to be specified.  This name\n");
-		format("should be specified as an X.500-style name (e.g., 'ou=people, o=University of Michigan, c=United States of America').  In most cases, it is easier to omit the [where] and allow the program to guide you.", 75, 15);
+		format("should be specified as an LDAP-style name (e.g., 'ou=people, o=University of Michigan, c=United States of America').  In most cases, it is easier to omit the [where] and allow the program to guide you.", 75, 15);
 		printf("\n");
 		printf("  [who]        A person in the Directory needs to be specified.  This name\n");
 		format("can be specified as either a ordinary name (e.g., 'Jane Doe'), or as some other identifying characteristic (e.g., 'uid=babs').", 75, 15);
@@ -111,7 +111,7 @@
 	}
 	else if (!strncasecmp("groupbase", s, len)) {
 		printf("  groupbase [where]\n\n");
-		format("The syntax and use of this command is identical to the more commonly used 'cb' command.  This command sets the base which is used to create groups in the X.500 Directory.  Setting the base to a certain value does not necessarily grant the person write-access to that part of the Directory in order to successfully create a group.", 75, 2);
+		format("The syntax and use of this command is identical to the more commonly used 'cb' command.  This command sets the base which is used to create groups in the LDAP Directory.  Setting the base to a certain value does not necessarily grant the person write-access to that part of the Directory in order to successfully create a group.", 75, 2);
 	}
 	else if (!strncasecmp("cd", s, len) || !strncasecmp("cb", s,len)) {
 		printf("  cb [where]\n");
@@ -125,7 +125,7 @@
 	printf("\n            * cb default\n\n");
 	format("sets the search base to its original default value.", 75, 2);
 	printf("\n            * cb o=Merit Computer Network, c=US\n\n");
-	format("sets the search base to organization given, the Merit Computer Network in this case.  This comamnd checks the validity of the specified search base, and rejects it if it is not a valid Distinguished Name (DN).  A DN uniquely identifies a portion of the global X.500 namespace.", 75, 2);
+	format("sets the search base to organization given, the Merit Computer Network in this case.  This comamnd checks the validity of the specified search base, and rejects it if it is not a valid Distinguished Name (DN).  A DN uniquely identifies a portion of the global LDAP namespace.", 75, 2);
 	}
 	else if (!strncasecmp("quit", s, len) || !strncasecmp("stop",s, len)) {
 		printf("  quit\n");
@@ -145,7 +145,7 @@
 	else if (!strncasecmp("modify", s, len) || !strncasecmp("change", s, len)) {
 		printf("  modify [entry]\n");
 		printf("  change [entry]\n\n");
-		format("Changes information associated with an entry in the X.500 Directory.  'change' is an alias for 'modify'.", 75, 2);
+		format("Changes information associated with an entry in the LDAP Directory.  'change' is an alias for 'modify'.", 75, 2);
 	}
 	else if (!strncasecmp("verbose", s, len)) {
 		printf("  verbose\n\n");
@@ -182,7 +182,7 @@
 	}
 	else if (!strncasecmp("tidy", s, len)) {
 		printf("  tidy\n\n");
-		format("Unsubscribes you from non-existent groups.  Useful when you cannot resign from a group because, while your X.500 entry still contains a pointer to it, someone has removed a group of which you were a subscriber.", 75, 2);
+		format("Unsubscribes you from non-existent groups.  Useful when you cannot resign from a group because, while your LDAP entry still contains a pointer to it, someone has removed a group of which you were a subscriber.", 75, 2);
 	}
 	else if (*s == '?') {
 		format("Prints out a brief description of each command.  Same as typing 'help help'.", 75, 2);
diff -ruN ud.orig/main.c ud/main.c
--- ud.orig/main.c	Mon Apr  1 06:45:26 1996
+++ ud/main.c	Sat Mar 28 21:05:07 1998
@@ -16,6 +16,16 @@
  *	Simon Fraser University, Academic Computing Services
  */
 
+/* 
+ * Copyright (C) 1998
+ * Jauder Ho <jauderho@transmeta.com>, Transmeta Corporation.
+ * All rights reserved.
+ *
+ * Further modifications to the code for interaction with the Netscape DS.
+ * Reworking of UMich specific code.
+ *
+ */
+
 #include <stdio.h>
 #include <sys/types.h>
 #if defined(NeXT)
@@ -68,8 +78,8 @@
 char *default_bind_object = UD_BINDDN;
 
 char *bound_dn;			/* bound user's Distinguished Name */
-char *group_base;		/* place in X.500 tree where groups are */
-char *search_base;		/* place in X.500 tree where searches start */
+char *group_base;		/* place in LDAP tree where groups are */
+char *search_base;		/* place in LDAP tree where searches start */
 
 static jmp_buf env;		/* spot to jump to on an interrupt */
 
@@ -98,7 +108,7 @@
 	verbose = 1;
 
 	/*  handle argument list */
-	while ((c = getopt(argc, argv, "c:d:Df:l:p:s:u:vV")) != -1) {
+	while ((c = getopt(argc, argv, "c:d:Df:l:p:s:u:hvV")) != -1) {
 		switch (c) {
 		case 'l' :
 #ifdef LDAP_DEBUG
@@ -120,6 +130,9 @@
 		case 'f' :
 			config_file = optarg;
 			break;
+		case 'h' :
+			printf("Usage: ud [-c filter-config-file] [-d debug-level] [-h] [-l ldap-debug-level] [-s server] [-p port] [-V]\n");
+			exit(0);
 		case 'p' :
 			ldap_port = atoi(optarg);
 			break;
@@ -145,7 +158,7 @@
 			format("These are masks, and may be added to form multiple debug levels.  For example, '-d 35' would perform a function trace, print out information about the find() function, and would print out information about the output routines too.", 75, 2);
 			exit(0);
 		default:
-			fprintf(stderr, "Usage: %s [-c filter-config-file] [-d debug-level] [-l ldap-debug-level] [-s server] [-p port] [-V]\n", argv[0]);
+			fprintf(stderr, "Usage: ud [-c filter-config-file] [-d debug-level] [-h] [-l ldap-debug-level] [-s server] [-p port] [-V]\n");
 			exit(-1);
 			/* NOTREACHED */
 		}
@@ -184,7 +197,7 @@
 		printf("->do_commands()\n");
 #endif
 	if (verbose) 
-		printf("\n  Enter a command.  If you need help, type 'h' or '?' and hit RETURN.\n\n");
+		printf("  Enter a command.  If you need help, type 'h' or '?' and hit RETURN.\n\n");
 	/* jump here on an interrupt */
 	(void) setjmp(env);
 	for (;;) {
@@ -208,7 +221,7 @@
 			*ap++ = *cp++;
 		if (iscom("status"))
 			status();
-		else if (iscom("stop") || iscom("quit"))
+		else if (iscom("stop") || iscom("quit") || iscom("exit"))
 			break;
 		else if (iscom("cb") || iscom("cd") || iscom("moveto")) {
 			while (isspace(*cp) && (*cp != '\0')) 
@@ -275,7 +288,7 @@
 		else
 			printf("  Invalid command.  Type \"help commands.\"\n");
 	}
-	printf(" Thank you!\n");
+	/* printf("  Thank you!\n"); */
 	
 	ldap_unbind(ld);
 #ifdef KERBEROS
@@ -374,7 +387,7 @@
 	}
 
 	/*
-	 *  User wants to ascend one level in the X.500 tree.
+	 *  User wants to ascend one level in the LDAP tree.
 	 *  Easy:  Just strip off the first element of the
 	 *  current search base, unless it's the root, in
 	 *  which case we just do nothing.
@@ -627,13 +640,13 @@
 	 *  because we want to be sure to use TCP, not UDP.
 	 */
 	if ((ld = ldap_open(server, ldap_port)) == NULL) {
-		fprintf(stderr, "  The X.500 Directory is temporarily unavailable.  Please try again later.\n");
+		fprintf(stderr, "  The LDAP Directory is temporarily unavailable.  Please try again later.\n");
 		exit(0);
 		/* NOTREACHED */
 	}
 	if (ldap_bind_s(ld, (char *) default_bind_object, (char *) UD_PASSWD,
 	    LDAP_AUTH_SIMPLE) != LDAP_SUCCESS) {
-		fprintf(stderr, "  The X.500 Directory is temporarily unavailable.  Please try again later.\n");
+		fprintf(stderr, "  The LDAP Directory is temporarily unavailable.  Please try again later.\n");
 		if (ld->ld_errno != LDAP_UNAVAILABLE)
 			ldap_perror(ld, "  ldap_bind_s");
 		exit(0);
@@ -700,7 +713,7 @@
 {
 	fflush(stderr);
 	fflush(stdout);
-	printf("\n\n  INTERRUPTED!\n");
+	printf("\n\n  Interrupted!\n");
 #if defined(DOS) || defined(SYSV)
 	(void) signal(SIGINT, attn);
 #endif
@@ -722,3 +735,25 @@
 	(void) signal(SIGWINCH, chwinsz);
 }
 #endif
+ 
+/* Fix for getting ud to compile when NO_CACHE is defined */
+/* Fixed by a patch from Mark Wahl */
+
+#if defined(NO_CACHE)
+
+void ldap_uncache_entry( LDAP *ld, char *dn )
+{
+
+}
+
+int ldap_enable_cache( LDAP *ld, long timeout, long maxmem )
+{
+  return 0;
+}
+
+void ldap_flush_cache( LDAP *ld )
+{
+
+}
+
+#endif /* NO_CACHE */
diff -ruN ud.orig/mod.c ud/mod.c
--- ud.orig/mod.c	Mon Mar 18 07:31:13 1996
+++ ud/mod.c	Wed Dec  3 14:15:27 1997
@@ -109,7 +109,7 @@
 	if (verbose && !printed_warning && (ld->ld_errno == LDAP_NO_SUCH_ATTRIBUTE)) {
 		printed_warning = 1;
 		printf("\n  WARNING!\n");
-		printf("  You are about to make a modification to an X.500 entry\n");
+		printf("  You are about to make a modification to an LDAP entry\n");
 		printf("  that has its \"automatic updates\" field set to ON.\n");
 		printf("  This means that the entry will be automatically updated\n");
 		printf("  each month from official University sources like the\n");
@@ -139,7 +139,7 @@
 			printf("\n  Choices are:\n");
 			printf("  -----------------------\n");
 			print_mod_list(is_a_group);
-			printf("\n  Pressing Return will cancel the process.\n");
+/*			printf("\n  Pressing Return will cancel the process.\n"); */
 			displayed_choices = 1;
 		}
 		printf("\n  Modify what? ");
@@ -401,7 +401,7 @@
 	count = 1;
 	(void) memset(buffer, 0, sizeof(buffer));
 #ifdef UOFM
-	if (!strcmp(id, "postalAddress") || !strcmp(id, "homePostalAddress") || !strcmp(id, "multiLineDescription") || !strcmp(id, "vacationMessage")) 
+	if (!strcmp(id, "postalAddress") || !strcmp(id, "homePostalAddress") || !strcmp(id, "description") || !strcmp(id, "vacationMessage")) 
 #else
 	if (!strcmp(id, "postalAddress") || !strcmp(id, "homePostalAddress"))
 #endif
@@ -481,7 +481,7 @@
 			if (lmp == (LDAPMessage *) NULL) {
 				printf("  Could not find \"%s\" in the Directory\n", line);
 				if (verbose) 
-					format("Owners of groups must be valid entries in the X.500 Directory.  The name you have typed above could not be found in the X.500 Directory.", 72, 2);
+					format("Owners of groups must be valid entries in the LDAP Directory.  The name you have typed above could not be found in the LDAP Directory.", 72, 2);
 				return(NULL);
 			}
 			elmp = ldap_first_entry(ld, lmp);
@@ -520,7 +520,7 @@
 			break;
 		}
 #ifdef UOFM
-		if ((count > MAX_DESC_LINES) && !strcmp(id, "multiLineDescription")) {
+		if ((count > MAX_DESC_LINES) && !strcmp(id, "description")) {
 			printf("  We only allow %d lines of description\n", MAX_DESC_LINES);
 			break;
 		}
@@ -620,9 +620,9 @@
 	if (verbose) {
 		printf("\n  By default, updates that are received from the Personnel\n");
 		printf("  Office and the Office of the Registrar are applied to all\n");
-		printf("  entries in the X.500 database each month.  Sometimes this\n");
+		printf("  entries in the LDAP database each month.  Sometimes this\n");
 		printf("  feature is undesirable.  For example, if you maintain your\n");
-		printf("  entry in the X.500 database manually, you may not want to\n");
+		printf("  entry in the LDAP database manually, you may not want to\n");
 		printf("  have these updates applied to your entry, possibly overwriting\n");
 		printf("  correct information with out-dated information.\n\n");
 	}
diff -ruN ud.orig/print.c ud/print.c
--- ud.orig/print.c	Tue Dec 12 09:22:52 1995
+++ ud/print.c	Sun Mar 29 18:31:18 1998
@@ -38,23 +38,29 @@
  */
 static char *person_attr_print_order[] = {
 	"cn",
+	"ou",
 	"mail",
+	"pagerMail",
+	"pager",
 	"telephoneNumber",
 	"facsimileTelephoneNumber",
-	"pager",
+	"buildingName",
 	"postalAddress",
 	"title",
 	"uid",
-	"multiLineDescription",
+	"description",
 	"homePhone",
+	"homeOffice",
+	"homeFax",
 	"homePostalAddress",
+	"mobile",
 	"drink",
 	"labeledURL",
 	"onVacation",
 	"vacationMessage",
 	"memberOfGroup",
-	"lastModifiedBy",
-	"lastModifiedTime",
+	"modifiersname",
+	"modifytimestamp",
 	NULL
 };
 
@@ -63,7 +69,7 @@
 	"facsimileTelephoneNumber",
 	"telephoneNumber",
 	"postalAddress",
-	"multiLineDescription",
+	"description",
 	"joinable",
 	"associatedDomain",
 	"owner",
@@ -77,6 +83,8 @@
 	"labeledURL",
 	"lastModifiedBy",
 	"lastModifiedTime",
+	"modifiersname",
+	"modifytimestamp",
 	NULL
 };
 
@@ -191,7 +199,9 @@
 	char is_a_group, **order;
 	char *sub_list[MAX_VALUES], buf[SMALL_BUF_SIZE];
 	extern int col_size, isaurl(), isadn();
+	extern struct attribute attrlist[];
 	static char *time2text();
+	static char *nstime2text();
 
 #ifdef DEBUG
 	if (debug & D_TRACE)
@@ -238,10 +248,20 @@
 			print_DN(Entry.attrs[idx]);
 		else if (isaurl(order[i]))
 			print_URL(Entry.attrs[idx]);
-		else if (isadate(order[i])) {
+		else if (isADate(order[i])) {
 			/* fix time and date, then call usual routine */
-			Entry.attrs[idx].values[0] = 
+			
+			/* It is necessary to have 2 subroutines since Netscape
+			 * decided to express it's dates in a different format
+			 */
+			if ( strlen(Entry.attrs[idx].values[0]) == 13 ) {
+				Entry.attrs[idx].values[0] = 
 				time2text(Entry.attrs[idx].values[0], FALSE);
+			} else if ( strlen(Entry.attrs[idx].values[0]) == 15 ) {
+				Entry.attrs[idx].values[0] = 
+				nstime2text(Entry.attrs[idx].values[0], FALSE);
+			}
+
 			print_values(Entry.attrs[idx]);
 		}
 		else
@@ -344,7 +364,7 @@
 		for (cp = *vp; *cp != '\0'; cp++) {
 			switch (*cp) {
 			case '$' :
-				if (!strncmp(A.output_string, "Home a", 6) || !strncmp(A.output_string, "Business a", 10) || !strcmp(A.quipu_name, "multiLineDescription")) {
+				if (!strncmp(A.output_string, "Home a", 6) || !strncmp(A.output_string, "Business a", 10) || !strcmp(A.quipu_name, "description")) {
 					putchar('\n');
 					for (k = lead; k > 0; k--)
 						putchar(' ');
@@ -592,6 +612,49 @@
     return( strdup( timestr ) );
 }
 
+static char *
+nstime2text( char *ldtimestr, int dateonly )
+{
+    struct tm		t;
+    char		*p, *timestr, zone, *fmterr = "badly formatted time";
+    time_t		gmttime;
+    static long		gtime();
+
+    memset( (char *)&t, 0, sizeof( struct tm ));
+    if ( strlen( ldtimestr ) < 15 ) {
+	return( fmterr );
+    }
+
+    for ( p = ldtimestr; p - ldtimestr < 14; ++p ) {
+	if ( !isdigit( *p )) {
+	    return( fmterr );
+	}
+    }
+
+    p = ldtimestr;
+    p += 2; /* Shift 2 to ignore 19 portion of 19xx */
+    t.tm_year = GET2BYTENUM( p ); p += 2;
+    t.tm_mon = GET2BYTENUM( p ) - 1; p += 2;
+    t.tm_mday = GET2BYTENUM( p ); p += 2;
+    t.tm_hour = GET2BYTENUM( p ); p += 2;
+    t.tm_min = GET2BYTENUM( p ); p += 2;
+    t.tm_sec = GET2BYTENUM( p ); p += 2;
+
+    if (( zone = *p ) == 'Z' ) {	/* GMT */
+	zone = '\0';	/* no need to indicate on screen, so we make it null */
+    }
+
+    gmttime = gtime( &t );
+    timestr = ctime( &gmttime );
+
+    timestr[ strlen( timestr ) - 1 ] = zone;	/* replace trailing newline */
+    if ( dateonly ) {
+	strcpy( timestr + 11, timestr + 20 );
+    }
+
+    Free ( ldtimestr );
+    return( strdup( timestr ) );
+}
 
 /* gtime.c - inverse gmtime */
 
diff -ruN ud.orig/util.c ud/util.c
--- ud.orig/util.c	Tue Dec 12 11:57:07 1995
+++ ud/util.c	Sun Mar 29 18:31:07 1998
@@ -80,7 +80,7 @@
 #endif
 	/*
 	 *  Stolen from the getpass() routine.  Can't use the plain
-	 *  getpass() for two reasons.  One is that X.500 passwords
+	 *  getpass() for two reasons.  One is that LDAP passwords
 	 *  can be really, really long - much longer than 8 chars.
 	 *  The second is that we like to make this client available
 	 *  out of inetd via a Merit asynch port, and we need to be
@@ -226,7 +226,9 @@
 fatal(s)
 char *s;
 {
-	void exit();
+	/* not a void function. does not return but prototype is not void */
+	/* Fixed by a patch from Larry Schwimmer */
+	/* void exit(); */
 
 	if (errno != 0)
 		perror(s);
@@ -563,7 +565,7 @@
 }
 
 /* return TRUE if this attribute should be printed as a date and time */
-isadate(s)
+isADate(s)
 char *s;
 {
 	register int i;