Introduced match_config_pattern function to find a pattern in the config value strings
authorZhanna Tsitkov <tsitkova@mit.edu>
Thu, 29 Jan 2009 19:23:22 +0000 (19:23 +0000)
committerZhanna Tsitkov <tsitkova@mit.edu>
Thu, 29 Jan 2009 19:23:22 +0000 (19:23 +0000)
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@21828 dc483132-0cff-0310-8789-dd5450dbe970

src/include/adm_proto.h
src/kdc/do_tgs_req.c
src/kdc/main.c
src/lib/kadm5/alt_prof.c
src/lib/kadm5/srv/libkadm5srv.exports

index 9d7002027b43e3029e86c4b013b3e3c007c5b8b1..9028da1a4e0a47c0b41c7b1255d4152ec54a98bf 100644 (file)
@@ -97,6 +97,7 @@ krb5_error_code krb5_read_realm_params (krb5_context,
                                        krb5_realm_params **);
 krb5_error_code krb5_free_realm_params (krb5_context,
                                        krb5_realm_params *);
+krb5_boolean match_config_pattern(const char *, const char *);
 
 /* str_conv.c */
 krb5_error_code
index 6063b7393eb85e9248fbf933c512c7aa04c2df17..958f212b21fa5bdda2e777f4ee08e50000147fb1 100644 (file)
@@ -1,4 +1,3 @@
-/* -*- mode: c; indent-tabs-mode: nil -*- */
 /*
  * kdc/do_tgs_req.c
  *
 #include "policy.h"
 #include "extern.h"
 #include "adm_proto.h"
+#include <ctype.h>
 
-static void
-find_alternate_tgs (krb5_kdc_req *, krb5_db_entry *,
-                    krb5_boolean *, int *);
+static void 
+find_alternate_tgs(krb5_kdc_req *,krb5_db_entry *,
+                   krb5_boolean *,int *);
 
-static krb5_error_code
-prepare_error_tgs (krb5_kdc_req *, krb5_ticket *,
-                   int, krb5_principal,
-                   krb5_data **, const char *);
+static krb5_error_code 
+prepare_error_tgs(krb5_kdc_req *,krb5_ticket *,int,
+                  krb5_principal,krb5_data **,const char *);
 
 static krb5_int32
-is_substr (char *, krb5_data *);
-
-static krb5_int32
-prep_reprocess_req(krb5_kdc_req *, krb5_principal *);
+prep_reprocess_req(krb5_kdc_req *,krb5_principal *);
 
 /*ARGSUSED*/
 krb5_error_code
@@ -189,7 +185,6 @@ process_tgs_req(krb5_data *pkt, const krb5_fulladdr *from,
     }
 
     db_ref_done = FALSE;
-
 ref_tgt_again:
     nprincs = 1;
     if ((errcode = krb5_unparse_name(kdc_context, request->server, &sname))) {
@@ -1047,35 +1042,14 @@ find_alternate_tgs(krb5_kdc_req *request, krb5_db_entry *server,
     return;
 }
 
-/* is_substr - verfies if d1 contains d2->data with head/trail-ing whitespaces 
- */
-static krb5_int32
-is_substr ( char *d1, krb5_data *d2)
-{
-    krb5_boolean ret = FALSE;
-    char *new_d2 = 0, *d2_formated = 0;
-    if ( d1 && d2 && d2->data && (d2->length+2 <= strlen(d1))){
-        new_d2 = calloc(1,d2->length+1);
-        if (new_d2 != NULL) {
-            strlcpy(new_d2,d2->data,d2->length+1);
-            if (asprintf( &d2_formated, "%c%s%c",' ',new_d2,' ') < 0)
-                ret = ENOMEM;
-             else  if (d2_formated != 0 && strstr(d1, d2_formated) != NULL)
-                ret = TRUE;
-            free(new_d2);
-            free(d2_formated);
-        }
-    }
-    return ret;
-}
-
 static krb5_int32
 prep_reprocess_req(krb5_kdc_req *request, krb5_principal *krbtgt_princ) 
 {
     krb5_error_code retval = KRB5KRB_AP_ERR_BADMATCH;
+    size_t len = 0;
     char **realms, **cpp, *temp_buf=NULL;
     krb5_data *comp1 = NULL, *comp2 = NULL; 
-    krb5_int32 host_based_srv_listed = 0, no_host_referral_listed = 0;
+    char *comp1_str = NULL; 
 
     /* By now we know that server principal name is unknown.
      * If CANONICALIZE flag is set in the request                                 
@@ -1092,39 +1066,33 @@ prep_reprocess_req(krb5_kdc_req *request, krb5_principal *krbtgt_princ)
      */
 
     if (isflagset(request->kdc_options, KDC_OPT_CANONICALIZE) == TRUE &&   
-        !isflagset(request->kdc_options, KDC_OPT_ENC_TKT_IN_SKEY) &&      
+        !isflagset(request->kdc_options, KDC_OPT_ENC_TKT_IN_SKEY) && 
         krb5_princ_size(kdc_context, request->server) == 2) {             
 
         comp1 = krb5_princ_component(kdc_context, request->server, 0);
         comp2 = krb5_princ_component(kdc_context, request->server, 1);
-        host_based_srv_listed   = FALSE;
-        no_host_referral_listed = TRUE;
-        if (kdc_active_realm->realm_host_based_services != NULL) {
-            host_based_srv_listed = is_substr(kdc_active_realm->realm_host_based_services, comp1);
-            if (host_based_srv_listed == ENOMEM) {
-                retval = ENOMEM; 
-                goto cleanup; 
-             }
-        } 
-        if (kdc_active_realm->realm_no_host_referral != NULL) {
-            no_host_referral_listed = is_substr(kdc_active_realm->realm_no_host_referral,comp1);
-            if (no_host_referral_listed == ENOMEM) {
-                retval = ENOMEM; 
-                goto cleanup; 
-             }
-         } 
 
-        if ((krb5_princ_type(kdc_context, request->server) == KRB5_NT_SRV_HST ||        
-            (krb5_princ_type(kdc_context, request->server) == KRB5_NT_UNKNOWN &&    
+        comp1_str = calloc(1,comp1->length+1);
+        if (!comp1_str) {
+            retval = ENOMEM; 
+            goto cleanup; 
+         }
+        strlcpy(comp1_str,comp1->data,comp1->length+1);
+
+        if ((krb5_princ_type(kdc_context, request->server) == KRB5_NT_SRV_HST || 
+            (krb5_princ_type(kdc_context, request->server) == KRB5_NT_UNKNOWN &&   
             kdc_active_realm->realm_host_based_services != NULL &&
-            (host_based_srv_listed == TRUE ||
-            strchr(kdc_active_realm->realm_host_based_services, '*')))) &&
+            (match_config_pattern(kdc_active_realm->realm_host_based_services, comp1_str) == TRUE ||
+             match_config_pattern(kdc_active_realm->realm_host_based_services, "*") == TRUE))) &&
             (kdc_active_realm->realm_no_host_referral == NULL || 
-            (!strchr(kdc_active_realm->realm_host_based_services, '*') &&
-            no_host_referral_listed == FALSE))) { 
+            (match_config_pattern(kdc_active_realm->realm_no_host_referral, "*") == FALSE &&
+             match_config_pattern(kdc_active_realm->realm_no_host_referral, comp1_str) == FALSE))) { 
 
-            if (memchr(comp2->data, '.', comp2->length) == NULL)
-                goto cleanup;
+            for (len=0; len < comp2->length; len++) {     
+                 if (comp2->data[len] == '.') break;
+            }
+            if (len == comp2->length)    
+                goto cleanup; 
             temp_buf = calloc(1, comp2->length+1);
             if (!temp_buf){
                 retval = ENOMEM; 
@@ -1161,6 +1129,7 @@ prep_reprocess_req(krb5_kdc_req *request, krb5_principal *krbtgt_princ)
         }
     }
 cleanup:
+    free(comp1_str);
     return retval;
 }
 
index 7d260f29677e4b05dcb79e987a8b378f4466a099..b908d594b8f9ef7798c62765e7c7390a7f8ec4cf 100644 (file)
@@ -167,83 +167,55 @@ finish_realm(kdc_realm_t *rdp)
 }
 
 static krb5_error_code 
-handle_referrals(krb5_realm_params *rparams, char *no_refrls, char *host_based_srvcs, kdc_realm_t *rdp )
+handle_referral_params(krb5_realm_params *rparams, 
+                       char *no_refrls, char *host_based_srvcs, 
+                       kdc_realm_t *rdp )
 {
-    int i = 0;
     krb5_error_code retval = 0;
-    if (no_refrls == NULL || strchr(no_refrls, '*') == NULL) {
-        if (no_refrls != NULL){
-            if (rparams && rparams->realm_no_host_referral) {
-                if (asprintf(&(rdp->realm_no_host_referral), "%s%s%s%s%s",
-                         " ", no_refrls," ",rparams->realm_no_host_referral, " ") < 0)
+
+    if (no_refrls && match_config_pattern(no_refrls, "*") == TRUE)
+        rdp->realm_no_host_referral = strdup("*");
+    else {
+        if (rparams && rparams->realm_no_host_referral) {
+            if (match_config_pattern(rparams->realm_no_host_referral, "*") == TRUE)
+                rdp->realm_no_host_referral = strdup("*");
+            else if  (no_refrls && (asprintf(&(rdp->realm_no_host_referral), "%s%s%s%s%s",
+                        " ", no_refrls," ",rparams->realm_no_host_referral, " ") < 0))
+                retval = ENOMEM; 
+            else if (asprintf(&(rdp->realm_no_host_referral),"%s%s%s", " ", 
+                        rparams->realm_no_host_referral, " ") < 0) 
+                retval = ENOMEM; 
+        } else if( no_refrls != NULL && asprintf(&(rdp->realm_no_host_referral),"%s%s%s", " ", no_refrls, " ") < 0)
+            retval = ENOMEM; 
+        else
+            rdp->realm_no_host_referral = NULL;
+    }
+
+    if (rdp->realm_no_host_referral && match_config_pattern(rdp->realm_no_host_referral, "*") == TRUE) {
+        rdp->realm_host_based_services = NULL; 
+        return 0;
+    }
+
+    if (host_based_srvcs && (match_config_pattern(host_based_srvcs, "*") == TRUE))
+            rdp->realm_host_based_services = strdup("*");
+    else {
+            if (rparams && rparams->realm_host_based_services) {
+                if (match_config_pattern(rparams->realm_host_based_services, "*") == TRUE)
+                    rdp->realm_host_based_services = strdup("*");
+                else if (host_based_srvcs && asprintf(&(rdp->realm_host_based_services), "%s%s%s%s%s",
+                           " ", host_based_srvcs," ",rparams->realm_host_based_services, " ") < 0)
                     retval = ENOMEM; 
-            } else {
-                if(asprintf(&(rdp->realm_no_host_referral),"%s%s%s", " ", no_refrls, " ") < 0)
+                else if (asprintf(&(rdp->realm_host_based_services),"%s%s%s", " ", 
+                           rparams->realm_host_based_services, " ") < 0) 
                     retval = ENOMEM; 
-            }
-       } else {
-            if (rparams && rparams->realm_no_host_referral) {   
-                if (asprintf(&(rdp->realm_no_host_referral),"%s%s%s", " ", 
-                             rparams->realm_no_host_referral, " ") < 0)
+            } else if(host_based_srvcs != NULL && asprintf(&(rdp->realm_host_based_services),"%s%s%s", 
+                      " ", host_based_srvcs, " ") < 0)
                     retval = ENOMEM; 
-            } else
-                rdp->realm_no_host_referral = NULL;
-        }
-        if (rdp->realm_no_host_referral &&
-            strlen(rdp->realm_no_host_referral) > 1 && strchr(rdp->realm_no_host_referral, '*') != NULL) {
-            rdp->realm_no_host_referral = strdup("*");
-        } else {
-             /*  only if no_host_referral != "*" */
-            if ((host_based_srvcs != NULL &&  strchr(host_based_srvcs,'*') != NULL) ||
-                 (rparams && rparams->realm_host_based_services && 
-                             strchr(rparams->realm_host_based_services,'*') != NULL)) {
-                if (asprintf(&(rdp->realm_host_based_services),"%s", "*") < 0)
-                    retval = ENOMEM; 
-            } else {
-                if (host_based_srvcs != NULL) {
-                    if (rparams && rparams->realm_host_based_services) {
-                        if (asprintf(&(rdp->realm_host_based_services),"%s%s%s%s%s",
-                            " ", host_based_srvcs," ",rparams->realm_host_based_services," ") < 0)
-                            retval = ENOMEM; 
-                    } else
-                        if (asprintf(&(rdp->realm_host_based_services),"%s%s%s", " ", 
-                                     host_based_srvcs, " ") < 0)
-                            retval = ENOMEM; 
-                } else {
-                    if (rparams && rparams->realm_host_based_services) {
-                        if (asprintf(&(rdp->realm_host_based_services),"%s%s%s", " ", 
-                                     rparams->realm_host_based_services, " ") < 0)
-                            retval = ENOMEM; 
-                    } else 
-                        rdp->realm_host_based_services = NULL;
-                }
-            }
-
-            /* Walk realm_host_based_services and realm_no_host_referral and replace all ',' with whitespace */
-            i = 0; 
-            while (rdp && rdp->realm_host_based_services && (rdp->realm_host_based_services)[i] != 0){
-                if ((rdp->realm_host_based_services)[i] == ',')
-                    (rdp->realm_host_based_services)[i] = ' ';
-                i++; 
-            }
-            i = 0;   
-            while (rdp && rdp->realm_no_host_referral && ( rdp->realm_no_host_referral)[i] != 0){
-                if ((rdp->realm_no_host_referral)[i] == ',')
-                    (rdp->realm_no_host_referral)[i] = ' ';
-                i++;
-            }
-        }
-    } else {
-        if  (no_refrls != NULL && strchr(no_refrls,'*') != NULL) {
-            if (asprintf(&(rdp->realm_no_host_referral),"%s", "*") < 0)
-                retval = ENOMEM; 
-        } else
-            rdp->realm_no_host_referral = NULL;
+            else
+                rdp->realm_host_based_services = NULL;
     }
 
-    return retval;
+    return 0;
 }
 /*
  * Initialize a realm control structure from the alternate profile or from
@@ -333,7 +305,7 @@ init_realm(char *progname, kdc_realm_t *rdp, char *realm,
        rparams->realm_max_rlife : KRB5_KDB_MAX_RLIFE;
 
     /* Handle KDC referrals */
-    kret = handle_referrals(rparams, no_refrls, host_based_srvcs, rdp);
+    kret = handle_referral_params(rparams, no_refrls, host_based_srvcs, rdp);
     if (kret == ENOMEM)
        goto whoops;
 
@@ -514,12 +486,12 @@ initialize_realms(krb5_context kcontext, int argc, char **argv)
 {
     int                c;
     char               *db_name = (char *) NULL;
+    char               *lrealm = (char *) NULL;
     char               *mkey_name = (char *) NULL;
     char               *rcname = KDCRCACHE;
-    char               *lrealm;
     krb5_error_code    retval;
     krb5_enctype       menctype = ENCTYPE_UNKNOWN;
-    kdc_realm_t                *rdatap;
+    kdc_realm_t                *rdatap = NULL;
     krb5_boolean       manual = FALSE;
     char               *default_udp_ports = 0;
     char               *default_tcp_ports = 0;
@@ -544,20 +516,13 @@ initialize_realms(krb5_context kcontext, int argc, char **argv)
        hierarchy[1] = "kdc_max_dgram_reply_size";
        if (krb5_aprof_get_int32(aprof, hierarchy, TRUE, &max_dgram_reply_size))
            max_dgram_reply_size = MAX_DGRAM_SIZE;
-        /* The service name "*" means any service. */
         hierarchy[1] = "no_host_referral";
-        if (!krb5_aprof_get_string_all(aprof, hierarchy, &no_refrls)){
-            if (no_refrls != NULL && strlen(no_refrls) && strchr(no_refrls, '*')) {
-                no_refrls = strdup("*");
-            }
-        }
-        if (no_refrls == 0 || strchr(no_refrls, '*') == NULL) {
+        if (krb5_aprof_get_string_all(aprof, hierarchy, &no_refrls)) 
+            no_refrls = 0;
+        if (!no_refrls || match_config_pattern(no_refrls, "*") == FALSE) {
             hierarchy[1] = "host_based_services";
-            if (!krb5_aprof_get_string_all(aprof, hierarchy, &host_based_srvcs)) {
-                if (strchr(host_based_srvcs, '*')) {
-                    host_based_srvcs = strdup("*");
-                }
-            }
+            if (krb5_aprof_get_string_all(aprof, hierarchy, &host_based_srvcs))
+                host_based_srvcs = 0;
         }
 
        /* aprof_init can return 0 with aprof == NULL */
@@ -856,3 +821,4 @@ int main(int argc, char **argv)
     return errout;
 }
 
+
index 2d8ca15a9478cd7abe3b042c9f490d9a293c8ffd..7fb35a5c81c37ac66cb4cb0f04fbfa63748969bc 100644 (file)
@@ -39,6 +39,7 @@
 #include <ctype.h>
 #include <kdb_log.h>
 
+krb5_boolean match_config_pattern(const char *, const char*);
 static krb5_key_salt_tuple *copy_key_salt_tuple(ksalt, len)
 krb5_key_salt_tuple *ksalt;
 krb5_int32 len;
@@ -294,22 +295,22 @@ krb5_aprof_get_string_all(acontext, hierarchy, stringp)
 {
     krb5_error_code     kret=0;
     char                **values;
-    int                 lastidx;
-    char                *tmp;
-    size_t              buf_size=0; 
+    int                 lastidx = 0;
+    char                *tmp = NULL ;
+    size_t              buf_size = 0; 
     kret = krb5_aprof_getvals(acontext, hierarchy, &values);
     if (!kret) {
         for (lastidx=0; values[lastidx]; lastidx++);
         lastidx--;
          
-        buf_size = strlen(values[0])+2;
+        buf_size = strlen(values[0])+3;
         for (lastidx=1; values[lastidx]; lastidx++){
-            buf_size += strlen(values[lastidx]+1);
+            buf_size += strlen(values[lastidx]) + 3;
          }
     }
     if (buf_size > 0) {
         *stringp = calloc(1,buf_size);
-        if (stringp == NULL){
+        if (*stringp == NULL){
             profile_free_list(values);
             return ENOMEM;
         }
@@ -1028,25 +1029,19 @@ krb5_read_realm_params(kcontext, realm, rparamp)
         rparams->realm_reject_bad_transit_valid = 1;
     }
 
-        hierarchy[2] = "no_host_referral";
-        if (!krb5_aprof_get_string_all(aprofile, hierarchy, &no_refrls)) {
-         
-            if (strchr(no_refrls, '*'))
-                no_refrls = strdup("*");
-            rparams->realm_no_host_referral = no_refrls;
-        } else
+    hierarchy[2] = "no_host_referral";
+    if (!krb5_aprof_get_string_all(aprofile, hierarchy, &no_refrls)) 
+       rparams->realm_no_host_referral = no_refrls;
+    else 
             no_refrls = 0;
 
-          if (no_refrls == 0 || strlen(no_refrls) == 0 || strncmp(no_refrls, "*",1) != 0) {
-            hierarchy[2] = "host_based_services";
-              if (!krb5_aprof_get_string_all(aprofile, hierarchy, &host_based_srvcs)){
-                if (strchr(host_based_srvcs, '*'))
-                    host_based_srvcs = strdup("*");
-                rparams->realm_host_based_services = host_based_srvcs;
-            } else
-                host_based_srvcs = 0;
-        }
-
+    if (!no_refrls || match_config_pattern(no_refrls, "*") == FALSE) {
+        hierarchy[2] = "host_based_services";
+        if (!krb5_aprof_get_string_all(aprofile, hierarchy, &host_based_srvcs))
+            rparams->realm_host_based_services = host_based_srvcs;
+        else
+            host_based_srvcs = 0;
+    }
 
     /* Get the value for the default principal flags */
     hierarchy[2] = "default_principal_flags";
@@ -1105,7 +1100,7 @@ cleanup:
 krb5_error_code
 krb5_free_realm_params(kcontext, rparams)
     krb5_context        kcontext;
-    krb5_realm_params        *rparams;
+    krb5_realm_params   *rparams;
 {
     if (rparams) {
         free(rparams->realm_profile);
@@ -1122,4 +1117,29 @@ krb5_free_realm_params(kcontext, rparams)
     }
     return(0);
 }
+/* 
+ * match_config_pattern - 
+ *       returns TRUE is the pattern is found in the attr's list of values.
+ *       Otherwise - FALSE.
+ *       In conf file the values are separates by commas or whitespaces.
+ */
+krb5_boolean
+match_config_pattern(const char *string, const char *pattern)
+{
+    const char *ptr;
+    char next = '\0';
+    int len = strlen(pattern);
+    for (ptr = strstr(string,pattern); ptr != 0; ptr = strstr(ptr+len,pattern)) {
+         if (ptr == string || isspace(*(ptr-1)) || *(ptr-1) ==',') {
+             next = *(ptr + len);
+             if (next == '\0' || isspace(next) || next ==',') {
+                  return TRUE;
+             }
+         }
+    }
+    return FALSE;
+}
+
+
 
index d0a45bac94985aa95550d94ad1a9f5b1d1f7135b..46a73ef9d35de0540e187308219676c973e4f7fa 100644 (file)
@@ -84,6 +84,7 @@ krb5_klog_syslog
 krb5_read_realm_params
 krb5_string_to_flags
 krb5_string_to_keysalts
+match_config_pattern
 master_db
 master_keyblock
 master_princ