Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 27 Oct 2006 15:39:46 GMT
From:      Michael Bushkov <bushman@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 108572 for review
Message-ID:  <200610271539.k9RFdkMJ054304@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=108572

Change 108572 by bushman@bushman_nss_ldap_cached on 2006/10/27 15:39:37

	+ several missing keywords added to configuration parser
	+ several bugfixes in paging/nested-groups-parser code

Affected files ...

.. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldap_group.c#14 edit
.. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapconf.c#15 edit
.. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapconf.h#14 edit
.. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapsearch.c#15 edit
.. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapsearch.h#14 edit
.. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/nss_ldap.c#16 edit
.. //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/nss_ldap.h#12 edit

Differences ...

==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldap_group.c#14 (text+ko) ====

@@ -125,7 +125,7 @@
 	struct mapped_group new_mg;
 	struct nss_ldap_search_context *newctx;
 	struct map_group_dn_request *req;
-	char **cp, *str;
+	char **cp;
 	char const *uid_attr, *gid_attr;
 	struct mapped_group *hash_entry_data;
 	struct __mg_he *hash_entry;
@@ -224,33 +224,26 @@
 	if (__nss_ldap_check_oc(newctx, _OC(&ctx->conf->schema, posixGroup)) == 
 		NSS_LDAP_SUCCESS) {
 		
-			//printf("__ %s %d %s\n", __FILE__, __LINE__, str);
-			rv = sl_add(req->next_requests, new_mg.dn);
-			if (rv == -1) {
-				free(new_mg.dn);
-				rv = NSS_LDAP_MEMORY_ERROR;
-				goto fin2;
-			}
-			rv = NSS_LDAP_SUCCESS;
-			
-			//printf("__ %s %d %s\n", __FILE__, __LINE__, str);			
+		rv = sl_add(req->next_requests, new_mg.dn);
+		if (rv == -1) {
+			free(new_mg.dn);
+			rv = NSS_LDAP_MEMORY_ERROR;
+			goto fin2;
+		}
+
+		rv = NSS_LDAP_SUCCESS;
 		*res_size = 0;
-		goto fin2;
 	} else {
 		rv = __nss_ldap_assign_attr_str(newctx, uid_attr, res, 
 			res_size, buf, bufsize);
-		if (rv != NSS_LDAP_SUCCESS)
-			goto fin2;
-	}
 
-	rv = HASHTABLE_ENTRY_STORE(__mg_ht, hash_entry, &new_mg);
-	if (rv == -1) {
-		if (new_mg.dn != 
-			req->next_requests->sl_str[req->next_requests->sl_cur])
+		rv = HASHTABLE_ENTRY_STORE(__mg_ht, hash_entry, &new_mg);
+		if (rv == -1) {
 			free(new_mg.dn);
-		rv = NSS_LDAP_MEMORY_ERROR;	
-	} else
-		rv = NSS_LDAP_SUCCESS;
+			rv = NSS_LDAP_MEMORY_ERROR;	
+		} else
+			rv = NSS_LDAP_SUCCESS;
+	}
 	
 fin:
 	if (sreq.attributes != NULL)
@@ -260,7 +253,6 @@
 	if (newctx != NULL)
 		__nss_ldap_end_search(&__nss_ldap_conf->search_method, newctx);
 	
-	//printf("__%s %d %d\n", __FILE__, __LINE__, rv);
 	return (rv);
 }
 
@@ -293,7 +285,7 @@
 		goto fin;
 	}
 
-	//printf("__ %s %d\n", __FILE__, __LINE__);
+	printf("__ %s %d\n", __FILE__, __LINE__);
 	rv = __nss_ldap_assign_attr_multi_str_paged_ext(newctx,
 		_ATM(&ctx->conf->schema, GROUP, uniqueMember),
 		res, res_size, len, buf, bufsize,
@@ -303,7 +295,7 @@
 		nss_ldap_map_group_dn, (void *)dnreq);
 	
 fin:
-	//printf("__ %s %d\n", __FILE__, __LINE__);
+	printf("__ %s %d %d\n", __FILE__, __LINE__, rv);
 	if (newctx != NULL)
 		__nss_ldap_end_search(&__nss_ldap_conf->search_method, newctx);
 
@@ -341,14 +333,14 @@
 		&grp->gr_gid);
 	if (rv != NSS_LDAP_SUCCESS)
 		goto errfin;
-//	printf("__ %s %d\n", __FILE__, __LINE__);
+	//printf("__ %s %d\n", __FILE__, __LINE__);
 	
 	rv = __nss_ldap_assign_rdn_str(sctx, 
 		_ATM(schema, GROUP, cn),
 		&grp->gr_name, &len, buf, rbuf - buf);
 	if (rv != NSS_LDAP_SUCCESS)
 		goto errfin;
-//	printf("__ %s %d\n", __FILE__, __LINE__);
+	//printf("__ %s %d\n", __FILE__, __LINE__);
 	buf += len;
 	
 	rv = __nss_ldap_assign_attr_password(sctx,
@@ -401,7 +393,6 @@
 
 	if (rv != NSS_LDAP_BUFFER_ERROR) {
 		res_memlen = memlen;
-		//printf("__ %s %d\n", __FILE__, __LINE__);
 		rv = __nss_ldap_assign_attr_multi_str_paged_ext(sctx,
 			_ATM(schema, GROUP, uniqueMember),
 			&res, &memlen, &len, buf, rbuf - buf,
@@ -416,6 +407,11 @@
 			grp->gr_mem = res;
 			rbuf = (char *)res;
 			buf += len;
+//			char **cp;
+//			for (cp = res; *cp; ++cp) {
+//				printf("__ %s %d %p\n", __FILE__, __LINE__, (void *)*cp);
+//				printf("==__ %s %d %s\n", __FILE__, __LINE__, *cp);
+//			}
 
 			//printf("__ %s %d %d %d %d\n", __FILE__, __LINE__,
 			//	nr_offset,
@@ -440,7 +436,7 @@
 				
 				++nr_offset;
 			}
-//			printf("__ %s %d %d %d\n", __FILE__, __LINE__, memlen, len);
+			//printf("__ %s %d %d %d\n", __FILE__, __LINE__, res_memlen, len);
 //			char **cp;
 //			for (cp = res; *cp; ++cp) {
 //				printf("__ %p %p %p\n", __FILE__, __LINE__, (void *)cp, (void *)*cp, (void *)buf);

==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapconf.c#15 (text+ko) ====

@@ -168,7 +168,12 @@
 	conf->connect_policy = NSS_LDAP_CONNECT_POLICY_PERSIST_PERTHREAD;
 	conf->restart = 0;
 	conf->debug = 0;
-	conf->search_page_size = NSS_LDAP_DEFAULT_SEARCH_PAGE_SIZE;
+	conf->page_results = NSS_LDAP_OPTION_YES;
+	conf->results_page_size = NSS_LDAP_DEFAULT_RESULTS_PAGE_SIZE;
+	
+	conf->no_nested_processing = NSS_LDAP_OPTION_NO;
+	conf->nested_backlink = NULL;
+	conf->ignore_getgrouplist_users = NULL;
 	
 	conf->tls_checkpeer = NSS_LDAP_OPTION_DEFAULT;
 
@@ -364,6 +369,75 @@
 			    if ((field_count == 2) && (set_base_map(conf,
 				fields[0], fields[1]) == NSS_LDAP_SUCCESS))
 			    	continue;
+			} else if (strcmp(fields[0], "nss_schema") == 0) {
+			    if (field_count == 2) {
+				if (strcmp(fields[1], "rfc2307") == 0) {
+				    conf->schema_processing =
+					NSS_LDAP_SCHEMA_PROCESSING_RFC2307;
+				    continue;
+				} else if (strcmp(fields[1], "rfc2307bis") == 0) {
+				    conf->schema_processing =
+					NSS_LDAP_SCHEMA_PROCESSING_RFC2307BIS;
+				    continue;
+				} else if (strcmp(fields[1], "rfc2307_bsd") == 0) {
+				    conf->schema_processing =
+					NSS_LDAP_SCHEMA_PROCESSING_RFC2307_BSD;
+				    continue;
+				} else if (strcmp(fields[1], "rfc2307bis_bsd") == 0) {
+				    conf->schema_processing =
+					NSS_LDAP_SCHEMA_PROCESSING_RFC2307BIS_BSD;
+				    continue;
+				}
+			    }					
+			} else if (strcmp(fields[0], "nss_paged_results") == 0) {
+			    if ((field_count == 2) && 
+				    (get_yesno(fields[1], &value) == 
+			    	    NSS_LDAP_SUCCESS)) {
+				conf->page_results = value;
+				continue;
+			    }				
+			} else if (strcmp(fields[0], "nss_no_nested_processing") == 0) {
+			    if ((field_count == 2) &&
+				    (get_yesno(fields[1], &value) ==
+			    	    NSS_LDAP_SUCCESS)) {
+				conf->no_nested_processing = value;
+				continue;
+			    }
+			} else if ((strcmp(fields[0], "nss_initgroups") == 0) || 
+				strcmp(fields[0], "nss_nested_backlink") == 0) {
+			    if (field_count == 2) {
+				free(conf->nested_backlink);
+				conf->nested_backlink = strdup(fields[1]);
+				if (conf->nested_backlink != NULL)
+					continue;
+			    }
+			} else if ((strcmp(fields[0], "nss_initgroups_ignoreusers") == 0) ||
+			    (strcmp(fields[0], "nss_getgrouplist_ignoreusers") == 0)) {			
+			    if (field_count >= 2) {
+				if (conf->ignore_getgrouplist_users != NULL)
+				    sl_free(conf->ignore_getgrouplist_users, 1);
+				    
+				conf->ignore_getgrouplist_users = sl_init();
+				if (conf->ignore_getgrouplist_users != NULL) {				
+				    rv = 0;
+				    for (i = 1; i < field_count; ++i) {
+					str = strdup(fields[i]);
+					if (str == NULL) {
+					    rv = -1;
+					    break;
+					}
+					rv = sl_add(
+					    conf->ignore_getgrouplist_users,
+					    str);
+					
+					if (rv != 0)
+					    break;
+				    }
+					
+				    if (rv == 0);
+					continue;
+				}
+			    }
 			} else if (strcmp(fields[0], "nss_map_attribute") == 0) {
 			    if ((field_count == 3) &&
 				(set_schema_rule(conf,
@@ -411,8 +485,15 @@
 			    }
 			}
 			break;
-		case 'p':			
-			if (strcmp(fields[0], "port") == 0) {
+		case 'p':	
+			if (strcmp(fields[0], "pagesize") == 0) {
+			    if ((field_count == 2) && 
+				(get_number(fields[1], 0, -1, &value) == 
+			    	    NSS_LDAP_SUCCESS)) {
+				conf->results_page_size = value;
+			    	continue;
+			    }			    
+			} else if (strcmp(fields[0], "port") == 0) {
 			    if ((field_count == 2) && 
 				(get_number(fields[1], 0, -1, &value) == 
 			    	    NSS_LDAP_SUCCESS)) {
@@ -694,12 +775,15 @@
 		sl_free(conf->hosts, 1);
 	if (conf->uris != NULL)
 		sl_free(conf->uris, 1);
+	if (conf->ignore_getgrouplist_users != NULL)
+		sl_free(conf->ignore_getgrouplist_users, 1);
 	free(conf->base);
 	free(conf->root_bind_dn);
 	free(conf->bind_dn);
 	free(conf->root_bind_pw);
 	free(conf->bind_pw);
 	free(conf->logdir);
+	free(conf->nested_backlink);
 
 	free(conf->root_sasl_authid);
 	free(conf->sasl_authid);

==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapconf.h#14 (text+ko) ====

@@ -44,8 +44,10 @@
 #define NSS_LDAP_SSL_ON 1
 #define NSS_LDAP_SSL_START_TLS 2
 
-#define NSS_LDAP_SCHEMA_RFC2307 0
-#define NSS_LDAP_SCHEMA_RFC2307BIS 1
+#define NSS_LDAP_SCHEMA_PROCESSING_RFC2307 0
+#define NSS_LDAP_SCHEMA_PROCESSING_RFC2307BIS 1
+#define NSS_LDAP_SCHEMA_PROCESSING_RFC2307_BSD 2
+#define NSS_LDAP_SCHEMA_PROCESSING_RFC2307BIS_BSD 4
 
 #define NSS_LDAP_PROTO_VERSION_2 2
 #define NSS_LDAP_PROTO_VERSION_3 3
@@ -63,7 +65,7 @@
 
 #define NSS_LDAP_MAX_ERR_DESC_SIZE 256
 
-#define NSS_LDAP_DEFAULT_SEARCH_PAGE_SIZE 1024
+#define NSS_LDAP_DEFAULT_RESULTS_PAGE_SIZE 1024
 
 struct nss_ldap_configuration
 {
@@ -101,7 +103,14 @@
 	int connect_policy;
 	int restart;
 	int debug;
-	int search_page_size;
+	int schema_processing;
+	
+	int page_results;
+	int results_page_size;
+	
+	int no_nested_processing;	
+	char *nested_backlink;
+	StringList *ignore_getgrouplist_users;
 	
 	char *sasl_authid;
 	char *root_sasl_authid;

==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapsearch.c#15 (text+ko) ====

@@ -135,7 +135,7 @@
 	sbuf = buf;
 	rbuf = buf + bufsize;
 	
-	//printf("__ %s %d %d\n", __FILE__, __LINE__, valsize);
+	//printf("__ %s %d %d\n", __FILE__, __LINE__, flags);
 	if (flags & NSS_LDAP_ATTR_MULTI_STR_END_WITH_PTRS_FLAG) {
 		siter_end = (char **)ALIGN(rbuf);
 		while ((char *)siter_end > rbuf)
@@ -250,7 +250,7 @@
 	size_t res_arr_size, res_buf_size, res_buf_offset, res_arr_offset;
 	int range_start, range_end, rv, sf;
 	
-	//printf("__ %s %d\n", __FILE__, __LINE__);
+	//printf("__ %s %d %s %s\n", __FILE__, __LINE__, attr, attr_model);
 	rv = __nss_ldap_parse_range(attr, &range_start, &range_end);
 	if (rv != NSS_LDAP_SUCCESS)
 		return (rv);
@@ -267,6 +267,7 @@
 		rv = do_assign_attr_multi_str(ctx, attr,
 			&res_arr, &res_arr_offset, &res_buf_offset, 
 			buf, rbuf - buf,
+			(flags & NSS_LDAP_ATTR_MULTI_STR_NO_END_NULL_FLAG) |
 			(sf == 0 ? NSS_LDAP_ATTR_MULTI_STR_END_WITH_PTRS_FLAG :
 			    NSS_LDAP_ATTR_MULTI_STR_END_WITH_PTRS_FLAG |
 			    NSS_LDAP_ATTR_MULTI_STR_NO_END_NULL_FLAG) | 
@@ -421,7 +422,7 @@
 	assert(msgid != NULL);
 
 	server_controls[1] = NULL;
-	rv = __nss_ldap_create_page_control(conn->ld, conf->search_page_size,
+	rv = __nss_ldap_create_page_control(conn->ld, conf->results_page_size,
 		sctx == NULL ? NULL : sctx->cookie, 0, &server_controls[0]);
 	if (rv != LDAP_SUCCESS) {		
 		/* TODO: warn the logs */
@@ -881,7 +882,7 @@
 		"__nss_ldap_assign_attr_multi_str_ext failed: attr='%s', "
 		"rv=%d", attr, rv);
 			
-	printf("__ %s %d %d\n", __FILE__, __LINE__);
+	//printf("__ %s %d %d\n", __FILE__, __LINE__);
 	return (rv);
 }
 
@@ -916,47 +917,31 @@
 	
 	attr_len = strlen(attr);
 	
+	rv = NSS_LDAP_PARSE_ERROR;
 	aname = ldap_first_attribute(ctx->conn->ld, ctx->msg, &cookie);
-	if (aname != NULL) {
+	if (aname != NULL) {		
 		do {
-			if (strncasecmp(aname, attr, attr_len) == 0) {
-				/* 
-				 * Falling back to standard routine if there
-				 * is no Range option in the 
-				 * AttributeDescription
-				 */
-				if (strlen(aname) == attr_len) {
-//					printf("__ %s %d %s\n",
+			//printf("__ %s %d %s\n", __FILE__, __LINE__, aname);
+			if ((strncasecmp(aname, attr, attr_len) == 0) &&
+				(strlen(aname) > attr_len) &&
+				(aname[attr_len] == ';')) {
+					//printf("__ %s %d %s %s\n",
 //						__FILE__,
-//						__LINE__,
+//						__LINE__, attr,
 //						aname);
-//					printf("__ %s %d\n", __FILE__, __LINE__);
-					rv = do_assign_attr_multi_str(
-						ctx, attr, str_array, 
-						str_array_size, len, buf, 
-						bufsize, flags, sp_fn, mdata);
-//					printf("__ %s %d %d\n", __FILE__, __LINE__, rv);
-				} else {
-//					printf("__ %s %d %s\n",
-//						__FILE__,
-//						__LINE__,
-//						aname);
-//					printf("__ %s %d\n", __FILE__, __LINE__);
-					rv = do_assign_attr_multi_str_paged(
-						ctx, attr, aname, str_array, 
-						str_array_size, len, buf, 
-						bufsize, flags, sp_fn, mdata);					
-				}
+//				printf("__ %s %d\n", __FILE__, __LINE__);
+				rv = do_assign_attr_multi_str_paged(
+					ctx, attr, aname, str_array, 
+					str_array_size, len, buf, 
+					bufsize, flags, sp_fn, mdata);	
+//				printf("__ %s %d %d\n", __FILE__, __LINE__, rv);					
 				
-//				printf("__ %s %d\n", __FILE__, __LINE__);
-//				printf("__ %s %d\n", __FILE__, __LINE__);
-				if ((rv != NSS_LDAP_SUCCESS) ||
-					((rv == NSS_LDAP_SUCCESS) && 
-					(*str_array_size != (flags & 
-					NSS_LDAP_ATTR_MULTI_STR_NO_END_NULL_FLAG ? 0 : 1)))) {						
+				//printf("__ %s %d\n", __FILE__, __LINE__, rv);
+				//printf("__ %s %d\n", __FILE__, __LINE__);
+				if (rv != NSS_LDAP_SUCCESS) {						
 					ldap_memfree(aname);
 					ber_free(cookie, 0);
-//					printf("__ %s %d %d\n", __FILE__, __LINE__, *str_array_size);
+					//printf("__ %s %d %d\n", __FILE__, __LINE__, *str_array_size);
 					goto fin;
 				}
 //				printf("__ %s %d\n", __FILE__, __LINE__);
@@ -969,10 +954,19 @@
 //			printf("__ %s %d\n", __FILE__, __LINE__);
 		} while (aname != NULL);
 		ber_free(cookie, 0);
+		
+		/* 
+		 * Falling back to standard routine if there
+		 * is no Range option in the 
+		 * AttributeDescription
+		 */
+		if (rv == NSS_LDAP_PARSE_ERROR)
+			rv = do_assign_attr_multi_str(
+				ctx, attr, str_array, 
+				str_array_size, len, buf, 
+				bufsize, flags, sp_fn, mdata);
 	}
 	
-//	printf("__ %s %d\n", __FILE__, __LINE__);
-	rv = NSS_LDAP_PARSE_ERROR;
 fin:
 	if (rv != NSS_LDAP_SUCCESS)	
 	    __nss_ldap_log(NSS_LDAP_LL_DEBUG_INT,
@@ -1212,97 +1206,3 @@
 	ldap_value_free(values);
 	return (rv);
 }
-
-int 
-__nss_ldap_map_dn2attr_fn(struct nss_ldap_search_context *ctx, char const *dn,
-	char **res, size_t *res_size, char *buf, size_t bufsize, void *mdata)
-{
-	struct nss_ldap_search_request sreq;
-	struct nss_ldap_search_context *newctx;
-	struct nss_ldap_dn2attr_request *req;
-	char **cp;
-	int rv;
-	
-	assert(ctx != NULL);
-	assert(dn != NULL);
-	assert(res != NULL);
-	assert(res_size != NULL);
-	assert(buf != NULL);
-	assert(mdata != NULL);
-	
-	//printf("__ %s %d\n", __FILE__, __LINE__);
-	
-	req = mdata;
-	newctx = NULL;
-	memset(&sreq, 0, sizeof(sreq));
-	
-	sreq.scope = LDAP_SCOPE_BASE;
-	sreq.filter = "(objectClass=*)";
-	sreq.search_base = (char *)dn;
-
-	sreq.attributes = sl_init();
-	rv = sl_add(sreq.attributes, req->attr);
-	if (rv == -1) {
-		rv = NSS_LDAP_MEMORY_ERROR;
-		goto fin;
-	}	
-	if (req->oc != NULL) {
-		rv = sl_add(sreq.attributes, "objectClass");
-		if (rv == -1) {
-			rv = NSS_LDAP_MEMORY_ERROR;
-			goto fin;
-		}
-	}
-	rv = sl_add(sreq.attributes, NULL);
-	if (rv == -1) {
-		rv = NSS_LDAP_MEMORY_ERROR;
-		goto fin;
-	}
-	
-//		printf("__ %s %d\n", __FILE__, __LINE__);
-	newctx = __nss_ldap_start_search(&__nss_ldap_conf->search_method,
-		ctx->conn, ctx->conf, &sreq);
-//		printf("__ %s %d\n", __FILE__, __LINE__);
-	sl_free(sreq.attributes, 0);
-	sreq.attributes = NULL; /* just in case */
-	
-	if (newctx == NULL) {
-		rv = NSS_LDAP_SUCCESS;
-		*res_size = 0;
-		goto fin2;
-	}
-	
-	rv = __nss_ldap_search_next(&__nss_ldap_conf->search_method, 
-		newctx);
-	if (rv != NSS_LDAP_SUCCESS) {
-		rv = NSS_LDAP_SUCCESS;
-		*res_size = 0;		
-		goto fin2;
-	}
-	
-	if (req->oc != NULL) {
-		for (cp = req->oc; *cp; ++cp) {
-			rv = __nss_ldap_check_oc(newctx, *cp);
-			if (rv == NSS_LDAP_SUCCESS)
-				break;
-		}
-		
-		if (rv != NSS_LDAP_SUCCESS) {
-			rv = NSS_LDAP_SUCCESS;
-			*res_size = 0;
-			goto fin2;
-		}
-	}
-	
-	rv = __nss_ldap_assign_attr_str(newctx, req->attr, res, res_size, buf,
-		bufsize);
-	
-fin:
-	if (sreq.attributes != NULL)
-		sl_free(sreq.attributes, 0);
-		
-fin2:
-	if (newctx != NULL)
-		__nss_ldap_end_search(&__nss_ldap_conf->search_method, newctx);
-	return (rv);
-}

==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/ldapsearch.h#14 (text+ko) ====

@@ -141,11 +141,7 @@
 	char const *, time_t *);
 extern int __nss_ldap_assign_attr_password(struct nss_ldap_search_context *,
 	char const *, char **, size_t *, char *, size_t);
-
 extern int __nss_ldap_check_oc(struct nss_ldap_search_context *,
 	char const *);
 
-extern int __nss_ldap_map_dn2attr_fn(struct nss_ldap_search_context *, 
-	char const *, char **, size_t *, char *, size_t, void *);
-
 #endif

==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/nss_ldap.c#16 (text+ko) ====


==== //depot/projects/soc2006/nss_ldap_cached/src/lib/nss_ldap/nss_ldap.h#12 (text+ko) ====




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200610271539.k9RFdkMJ054304>