[1179] in Kerberos-V5-bugs

home help back first fref pref prev next nref lref last post

krb5b4pl3: lib/krb425/rd_req.c: "*" instance should use first

daemon@ATHENA.MIT.EDU (Jonathan I. Kamens)
Tue Mar 14 21:31:03 1995

From: "Jonathan I. Kamens" <jik@cam.ov.com>
Date: Tue, 14 Mar 1995 21:34:07 -0500
To: krb5-bugs@MIT.EDU

The V4 behavior for krb_rd_req was to use the first entry in the
srvtab with the matching service name, when "*" was given for the host
name for the service principal.  This behavior is not implemented in
krb425 in krb5b4pl3; instead, it searches for the local host name in
the keytab file.  The patch below returns the V4 behavior:

--- lib/krb425/rd_req.c	1995/03/08 20:21:57	1.1
+++ lib/krb425/rd_req.c	1995/03/08 20:27:58	1.2
@@ -71,26 +71,58 @@
 		if (r = krb5_get_default_realm(&_krb425_local_realm))
 			return(krb425error(r));
 
+	if (!fn) {
+	    use_set_key = 1;
+	    fn = (char *)0;
+	} else if (!*fn) {
+	    fn = (char *)0;
+	} else {
+	    strcpy(file_name, "FILE:");
+	    strncpy(file_name + 5, fn, MAXPATHLEN-5);
+	    file_name[sizeof(file_name)-1] = '\0';
+	    fn = file_name;
+	}
+	    
 	if (!strcmp(instance, "*")) {
-		static char hostname[64] = { 0 };
+	    /*
+	     * If the instance is "*", look through the keytab for the
+	     * first entry with a matching service, and use the
+	     * corresponding instance.  This is standard V4 behavior.
+	     * 
+	     * XXX I am calling krb5_ktfile_{get_next,end_get} directly,
+	     * because I cannot find the generic kt functions.
+	     */
+	    static char buf[64] = { 0 };
+	    krb5_keytab ktid;
+	    krb5_kt_cursor cur;
+	    krb5_keytab_entry entry;
 
-		if (!hostname[0]) {
-			struct hostent *h;
-	
-			gethostname(hostname, sizeof(hostname));
-			if (h = gethostbyname(hostname)) {
-				char *p;
-
-				strncpy(hostname, h->h_name, sizeof(hostname));
-				hostname[sizeof(hostname)-1] = 0;
-				p = hostname;
-				do {
-					if (isupper(*p)) *p=tolower(*p);
-				} while (*p++);
-			}
-		}
-		instance = hostname;
+	    r = krb5_kt_resolve(fn, &ktid);
+	    if (r) return krb425error(r);
+
+	    r = krb5_kt_start_seq_get(ktid, &cur);
+	    if (r) return krb425error(r);
+
+	    while ((r = krb5_kt_next_entry(ktid, &entry, &cur)) == 0) {
+		if (krb5_princ_size(entry.principal) == 2 &&
+		    strcmp(krb5_princ_component(entry.principal,0)->data,
+			   service) == 0)
+		    break;
+	    }
+
+	    if (r) {
+		if (r == KRB5_KT_END)
+		    krb5_kt_end_seq_get(ktid, &cur);
+		return krb425error(KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN);
+	    }
+
+	    r = krb5_kt_end_seq_get(ktid, &cur);
+	    if (r) return krb425error(r);
+     
+	    strcpy(buf, krb5_princ_component(entry.principal, 1)->data);
+	    instance = buf;
 	}
+
 	if (r = krb5_build_principal(&server,
 				     strlen(_krb425_local_realm),
 				     _krb425_local_realm,
@@ -102,18 +134,6 @@
 	
 	authe.length = authent->length;
 	authe.data = (char *)authent->dat;
-	if (!fn) {
-	    use_set_key = 1;
-	    fn = (char *)0;
-	} else if (!*fn) {
-	    fn = (char *)0;
-	} else {
-	    strcpy(file_name, "FILE:");
-	    strncpy(file_name + 5, fn, MAXPATHLEN-5);
-	    file_name[sizeof(file_name)-1] = '\0';
-	    fn = file_name;
-	}
-	    
 
 #ifdef  EBUG
         EPRINT "Calling krb5_rd_req with:\n");

home help back first fref pref prev next nref lref last post