Arthur de Jong <adej...@debian.org> writes:

> This sounds like a good idea. I would welcome a patch for that. Thanks a
> lot for working on this.

Here is the changelog, patch based on latest svn (revno:1161):

  * debian/nslcd.templates: Add nslcd/ldap-auth-type and SASL templates.
  
  * debian/nslcd.config: Manage SASL questions, bindpw is shared between
    binddn and sasl, it's asked just after binddn or authcid, this
    complexify a little the switch case.
  
  * debian/nslcd.postinst: Manage SASL options, binddn and SASL disable
    each other. Use 2 functions simple_auth and sasl_auth to simplify
    the configuration.


NB: I added an SASL auto mechanism but I'm not sure if it's useful, feel
free to remove it, it's the default mech in the template.

Regards.
-- 
Daniel Dehennin
Récupérer ma clef GPG:
gpg --keyserver pgp.mit.edu --recv-keys 0x6A2540D1

=== modified file 'debian/nslcd.config'
--- debian/nslcd.config	2010-07-03 14:18:17 +0000
+++ debian/nslcd.config	2010-07-14 11:19:53 +0000
@@ -98,12 +98,35 @@
     searchbase=`sed -n 's/^base[[:space:]]*\([^[:space:]]*\)[[:space:]]*$/\1/ip' "$cfgfile" | tail -n 1`
     [ -n "$searchbase" ] && db_set nslcd/ldap-base "$searchbase"
   fi
-  # find binddn
-  db_get nslcd/ldap-binddn
-  if [ -z "$RET" ]
+  # find authentication type
+  # first none, second binddn, last SASL
+  db_get nslcd/ldap-auth-type
+  authtype="$RET"
+  if [ -z "$authtype" ]
   then
-    binddn=`sed -n 's/^binddn[[:space:]]*//ip' "$cfgfile" | tail -n 1`
-    db_set nslcd/ldap-binddn "$binddn"
+    db_set nslcd/ldap-auth-type "none"
+    # find binddn
+    db_get nslcd/ldap-binddn
+    if [ -z "$RET" ]
+    then
+      binddn=`sed -n 's/^binddn[[:space:]]*//ip' "$cfgfile" | tail -n 1`
+      if [ -n "$binddn" ]
+      then
+	db_set nslcd/ldap-auth-type "simple"
+	db_set nslcd/ldap-binddn "$binddn"
+      fi
+    fi
+    # check SASL mechanism
+    db_get nslcd/ldap-sasl-mech
+    if [ -z "$RET" ]
+    then
+      saslmech=`sed -n 's/^SASL_MECH[[:space:]]*\([^//[:space:]]*\)[[:space:]]*$/\1/ip' "$cfgfile"`
+      if [ -n "$saslmech" ]
+      then
+	db_set nslcd/ldap-auth-type "SASL"
+	db_set nslcd/ldap-sasl-mech "$saslmech"
+      fi
+    fi
   fi
   # find bindpw
   db_get nslcd/ldap-bindpw
@@ -133,6 +156,34 @@
     reqcert=`echo "$reqcert" | tr 'A-Z' 'a-z' | sed 's/^no$/never/;s/^yes$/demand/'`
     [ -n "$reqcert" ] && db_set nslcd/ldap-reqcert "$reqcert"
   fi
+  # check SASL realm
+  db_get nslcd/ldap-sasl-realm
+  if [ -z "$RET" ]
+  then
+    saslrealm=`sed -n 's/^SASL_REALM[[:space:]]*\([^[:space:]]*\)[[:space:]]*$/\1/ip' "$cfgfile"`
+    [ -n "$saslrealm" ] && db_set nslcd/ldap-sasl-realm "$saslrealm"
+  fi
+  # check SASL authentication ID
+  db_get nslcd/ldap-sasl-authcid
+  if [ -z "$RET" ]
+  then
+    saslauthcid=`sed -n 's/^SASL_AUTHCID[[:space:]]*\([^[:space:]]*\)[[:space:]]*$/\1/ip' "$cfgfile"`
+    [ -n "$saslauthcid" ] && db_set nslcd/ldap-sasl-authcid "$saslauthcid"
+  fi
+  # check SASL authorization ID
+  db_get nslcd/ldap-sasl-authzid
+  if [ -z "$RET" ]
+  then
+    saslauthzid=`sed -n 's/^SASL_AUTHZID[[:space:]]*\([^[:space:]]*\)[[:space:]]*$/\1/ip' "$cfgfile"`
+    [ -n "$saslauthzid" ] && db_set nslcd/ldap-sasl-authzid "$saslauthzid"
+  fi
+  # check SASL security properties
+  db_get nslcd/ldap-sasl-secprops
+  if [ -z "$RET" ]
+  then
+    saslsecprops=`sed -n 's/^SASL_SECPROPS[[:space:]]*\([^[:space:]]*\)[[:space:]]*$/\1/ip' "$cfgfile"`
+    [ -n "$saslsecprops" ] && db_set nslcd/ldap-sasl-secprops "$saslsecprops"
+  fi
   # we're done
   return 0
 }
@@ -144,9 +195,19 @@
   # clear settings to pick up valus from configfile
   db_set nslcd/ldap-uris ""
   db_set nslcd/ldap-base ""
-  db_set nslcd/ldap-binddn ""
   db_set nslcd/ldap-bindpw ""
   db_set nslcd/ldap-starttls ""
+
+  # Do not clear the following settings
+  # they are manage based on auth-type
+  # db_set nslcd/ldap-auth-type ""
+  # db_set nslcd/ldap-binddn ""
+  # db_set nslcd/ldap-sasl-mech ""
+  # db_set nslcd/ldap-sasl-realm ""
+  # db_set nslcd/ldap-sasl-authcid ""
+  # db_set nslcd/ldap-sasl-authzid ""
+  # db_set nslcd/ldap-sasl-secprops ""
+
   # parse current configuration
   parsecfg "$CONFFILE"
 else
@@ -167,6 +228,14 @@
 db_get nslcd/ldap-starttls
 [ -z "$RET" ] && db_set nslcd/ldap-starttls "false"
 
+# fallback for krb5_keytab
+db_get nslcd/ldap-sasl-krb5-keytab
+[ -z "$RET" ] && db_set nslcd/ldap-sasl-krb5-keytab "/etc/krb5.keytab"
+
+# fallback for krb5_ccname
+db_get nslcd/ldap-sasl-krb5-ccname
+[ -z "$RET" ] && db_set nslcd/ldap-sasl-krb5-ccname "/var/run/nslcd/nslcd.tkt"
+
 #
 # This is the second part of the script. In this part the configurable
 # settings will be presented to the user for approval. The postinst
@@ -182,31 +251,122 @@
     db_input high nslcd/ldap-uris || true
     db_input high nslcd/ldap-base || true
     # ask the questions, go to the next question or exit
-    state="binddn"
+    state="authtype"
     db_go || exit 1
     # TODO: add error checking on options
     ;;
+  authtype)
+    # ask for authentication type
+    db_input medium nslcd/ldap-auth-type || true
+    # ask the question, go to the next question or back
+    if ! db_go
+    then
+      state="server"
+    else
+      db_get nslcd/ldap-auth-type
+      case "$RET" in
+      none)
+        state="starttls"
+	;;
+      simple)
+        state="binddn"
+	;;
+      SASL)
+	state="saslmech"
+	;;
+      *)
+        exit 1
+	;;
+      esac
+    fi
+    ;;
   binddn)
     # ask for login information
     db_input medium nslcd/ldap-binddn || true
     # ask the question, go to the next question or back
     state="bindpw"
-    db_go || state="server"
+    if ! db_go
+    then
+      state="authtype"
+    else
+      # null binddn is not allowed
+      db_get nslcd/ldap-binddn
+      [ -z "$RET" ] && state="binddn"
+    fi
+    ;;
+  saslmech)
+    db_input medium nslcd/ldap-sasl-mech || true
+    # ask the question, go to the next question or back
+    state="saslrealm"
+    db_go || state="authtype"
+    ;;
+  saslrealm)
+    db_input medium nslcd/ldap-sasl-realm || true
+    # ask the question, go to the next question or back
+    state="saslauthcid"
+    db_go || state="saslmech"
+    ;;
+  saslauthcid)
+    db_get nslcd/ldap-sasl-mech
+    if [ "$RET" != "GSSAPI" ]
+    then
+      db_input medium nslcd/ldap-sasl-authcid || true
+      # ask the question, go to the next question or back
+      state="bindpw"
+      db_go || state="saslrealm"
+    else
+      # ask the question, go to the next question or back
+      state="saslauthzid"
+    fi
+    ;;
+  saslauthzid)
+    db_input medium nslcd/ldap-sasl-authzid || true
+    # ask the question, go to the next question or back
+    state="saslsecprops"
+    db_get nslcd/ldap-sasl-mech
+    if [ "$RET" != "GSSAPI" ]
+    then
+      prev="saslauthcid"
+    else
+      prev="saslrealm"
+    fi
+    db_go || state="$prev"
+    ;;
+  saslsecprops)
+    db_input medium nslcd/ldap-sasl-secprops || true
+    # ask the question, go to the next question or back
+    state="starttls"
+    db_go || state="saslauthzid"
     ;;
   bindpw)
-    # only ask question if we have a binddn
-    db_get nslcd/ldap-binddn
-    if [ -n "$RET" ]
+    # check if password is required
+    db_get nslcd/ldap-auth-type
+    authtype="$RET"
+    if [ -n "$authtype" ] || [ "$authtype" != "none" ]
     then
-      # ask for login information
+      # ask for password information
       db_input medium nslcd/ldap-bindpw || true
-    else
-      # clear password
-      db_set nslcd/ldap-bindpw ""
     fi
     # ask the question, go to the next question or back
-    state="starttls"
-    db_go || state="binddn"
+    case "$authtype" in
+    none)
+      state="starttls"
+      prev="authtype"
+      ;;
+    simple)
+      state="starttls"
+      prev="binddn"
+      ;;
+    SASL)
+      state="saslauthzid"
+      prev="saslauthcid"
+      ;;
+    *)
+      state="starttls"
+      prev="authtype"
+      ;;
+    esac
+    db_go || state="$prev"
     ;;
   starttls)
     # check if ldaps:// URL's are used
@@ -222,7 +382,21 @@
     fi
     # ask the question, go to the next question or back
     state="reqcert"
-    db_go || state="bindpw"
+    # Check authentication type
+    db_get nslcd/ldap-auth-type
+    authtype="$RET"
+    case "$authtype" in
+    none)
+      prev="authtype"
+      ;;
+    simple|SASL)
+      prev="bindpw"
+      ;;
+    *)
+      prev="authtype"
+      ;;
+    esac
+    db_go || state="$prev"
     ;;
   reqcert)
     # check if ldaps:// URL's are used
@@ -237,8 +411,38 @@
       db_input high nslcd/ldap-reqcert || true
     fi
     # ask the question, go to the next question or back
+    state="krb5keytab"
+    db_go || state="starttls"
+    ;;
+  krb5keytab)
+    # Check authentication type
+    db_get nslcd/ldap-auth-type
+    authtype="$RET"
+    # check if SASL mechanism is GSSAPI
+    db_get nslcd/ldap-sasl-mech
+    saslmech="$RET"
+    if [ "$authtype" = "SASL" ] && [ "$saslmech" = "GSSAPI" ]
+    then
+      db_input low nslcd/ldap-sasl-krb5-keytab || true
+    fi
+    # ask the question, go to the next question or back
+    state="krb5ccname"
+    db_go || state="reqcert"
+    ;;
+  krb5ccname)
+    # Check authentication type
+    db_get nslcd/ldap-auth-type
+    authtype="$RET"
+    # check if SASL mechanism is GSSAPI
+    db_get nslcd/ldap-sasl-mech
+    saslmech="$RET"
+    if [ "$authtype" = "SASL" ] && [ "$saslmech" = "GSSAPI" ]
+    then
+      db_input low nslcd/ldap-sasl-krb5-ccname || true
+    fi
+    # ask the question, go to the next question or back
     state="done"
-    db_go || state="bindpw"
+    db_go || state="krb5keytab"
     ;;
   esac
 done

=== modified file 'debian/nslcd.postinst'
--- debian/nslcd.postinst	2010-05-09 09:39:45 +0000
+++ debian/nslcd.postinst	2010-07-14 11:08:13 +0000
@@ -4,6 +4,7 @@
 
 CONFFILE="/etc/nslcd.conf"
 OCONFFILE="/etc/nss-ldapd.conf"
+DEFAULCONFFILE="/etc/default/nslcd"
 
 # set an option in the configuration file to the specified value
 cfg_set()
@@ -135,6 +136,158 @@
   return 0
 }
 
+simple_auth()
+{
+  case "$1" in
+  enable)
+    # set bind dn/pw
+    db_get nslcd/ldap-binddn
+    if [ -n "$RET" ]
+    then
+      cfg_set binddn "$RET"
+      db_get nslcd/ldap-bindpw
+      if [ -n "$RET" ]
+      then
+        cfg_set bindpw "$RET"
+      else
+        # no bindpw set
+        if grep -i -q "^bindpw " $CONFFILE
+        then
+          cfg_set bindpw "*removed*"
+          cfg_disable bindpw
+          cfg_disable binddn
+        fi
+      fi
+    else
+      # no binddn/pw, disable options
+      cfg_disable binddn
+      if grep -i -q "^bindpw " $CONFFILE
+      then
+        cfg_set bindpw "*removed*"
+        cfg_disable bindpw
+      fi
+    fi
+    ;;
+  disable)
+    # Password must be hidden
+    cfg_set bindpw "*removed*"
+    for simpleitem in binddn bindpw
+    do
+      if grep -qi "^$simpleitem" $CONFFILE
+      then
+        cfg_disable $simpleitem
+      fi
+    done
+    ;;
+  *)
+    # Should not happen
+    exit 1
+    ;;
+  esac
+}
+
+sasl_auth()
+{
+  case "$1" in
+  enable)
+    # set SASL options
+    db_get nslcd/ldap-sasl-mech
+    if [ -n "$RET" ]
+    then
+      saslmech="$RET"
+      # RFC4313 if SASL, binddn should be disabled
+      cfg_disable binddn
+      cfg_set sasl_mech "$saslmech"
+      db_get nslcd/ldap-sasl-realm
+      if [ -n "$RET" ]
+      then
+        cfg_set sasl_realm "$RET"
+      else
+        cfg_disable sasl_realm
+      fi
+      db_get nslcd/ldap-sasl-authzid
+      if [ -n "$RET" ]
+      then
+        cfg_set sasl_authzid "$RET"
+      else
+        cfg_disable sasl_authzid
+      fi
+      db_get nslcd/ldap-sasl-secprops
+      if [ -n "$RET" ]
+      then
+        cfg_set sasl_secprops "$RET"
+      else
+        cfg_disable sasl_secprops
+      fi
+
+      # Disable krb5_ccname, we don't know what was the mech before
+      grep -qi "^krb5_ccname" $CONFFILE && cfg_disable krb5_ccname
+      # mech specific setup
+      case "$saslmech" in
+      GSSAPI)
+        # TODO handle nslcd/ldap-sasl-krb5-keytab in /etc/default/nslcd
+        # Set kerberos credential cache name
+        db_get nslcd/ldap-sasl-krb5-ccname
+        if [ -n "$RET" ]
+        then
+          cfg_set krb5_ccname "$RET"
+        else
+          # default value
+          cfg_set krb5_ccname "/var/run/nslcd/nslcd.tkt"
+        fi
+	;;
+      LOGIN|PLAIN|CRAM-MD5|DIGEST-MD5)
+	# FIXME login/password only for those?
+        # authcid must be set
+        db_get nslcd/ldap-sasl-authcid
+        saslauthcid="$RET"
+        if [ -n "$saslauthcid" ]
+        then
+          # bindpw must be set
+          db_get nslcd/ldap-bindpw
+          bindpw="$RET"
+          if [ -n "$bindpw" ]
+          then
+            cfg_set sasl_authcid "$saslauthcid"
+            cfg_set bindpw "$bindpw"
+          else
+            cfg_disable sasl_authcid "$saslauthcid"
+            cfg_set bindpw "*removed*"
+            cfg_disable bindpw "$bindpw"
+          fi
+        fi
+	;;
+      esac
+    else
+      # Password must be hidden
+      cfg_set bindpw "*removed*"
+      for saslitem in sasl_mech sasl_realm sasl_authcid sasl_authzid sasl_secprops krb5_ccname
+      do
+        if grep -qi "^$saslitem" $CONFFILE
+        then
+          cfg_disable $saslitem
+        fi
+      done
+    fi
+    ;;
+  disable)
+    # Password must be hidden
+    cfg_set bindpw "*removed*"
+    for saslitem in bindpw sasl_mech sasl_realm sasl_authcid sasl_authzid sasl_secprops krb5_ccname
+    do
+      if grep -qi "^$saslitem" $CONFFILE
+      then
+        cfg_disable $saslitem
+      fi
+    done
+    ;;
+  *)
+    # Should not happen
+    exit 1
+    ;;
+  esac
+}
+
 # real functions begin here
 if [ "$1" = "configure" ]
 then
@@ -173,34 +326,24 @@
   else
     cfg_disable base
   fi
-  # set bind dn/pw
-  db_get nslcd/ldap-binddn
-  if [ -n "$RET" ]
-  then
-    cfg_set binddn "$RET"
-    db_get nslcd/ldap-bindpw
-    if [ -n "$RET" ]
-    then
-      cfg_set bindpw "$RET"
-    else
-      # no bindpw set
-      if grep -i -q "^bindpw " $CONFFILE
-      then
-        cfg_set bindpw "*removed*"
-        cfg_disable bindpw
-      fi
-    fi
-  else
-    # no binddn/pw, disable options
-    cfg_disable binddn
-    if grep -i -q "^bindpw " $CONFFILE
-    then
-      cfg_set bindpw "*removed*"
-      cfg_disable bindpw
-    fi
-  fi
-  # remove password from database
-  db_set nslcd/ldap-bindpw ""
+  # authentication
+  db_get nslcd/ldap-auth-type
+  authtype="$RET"
+  case "$authtype" in
+  simple)
+    sasl_auth disable
+    simple_auth enable
+    ;;
+  SASL)
+    simple_auth disable
+    sasl_auth enable
+    ;;
+  none)
+    sasl_auth disable
+    simple_auth disable
+    ;;
+  esac
+
   # set ssl option
   db_get nslcd/ldap-starttls
   if [ "$RET" = "true" ]
@@ -221,6 +364,8 @@
     # clear debconf value so that this option is only set if the question is asked
     db_set nslcd/ldap-reqcert ""
   fi
+  # remove password from database
+  db_set nslcd/ldap-bindpw ""
   # we're done
   db_stop
   # rename reconnect_maxsleeptime to reconnect_retrytime

=== modified file 'debian/nslcd.templates'
--- debian/nslcd.templates	2009-08-31 20:46:01 +0000
+++ debian/nslcd.templates	2010-07-14 10:54:13 +0000
@@ -25,11 +25,15 @@
  the account that will be used here. Leave it empty otherwise.
  .
  This value should be specified as a DN (distinguished name).
+ .
+ Leave empty for Simple Authentication and Security Layer (SASL)
+ authentication.
 
 Template: nslcd/ldap-bindpw
 Type: password
 _Description: LDAP user password:
- Enter the password that will be used to log in to the LDAP database.
+ Enter the password that will be used to log in to the LDAP database
+ with simple binddn or SASL authentications.
 
 Template: nslcd/ldap-starttls
 Type: boolean
@@ -52,3 +56,130 @@
   * demand: a certificate will be requested, required, and checked.
  If certificate checking is enabled, at least one of the tls_cacertdir or
  tls_cacertfile options must be put in /etc/nslcd.conf.
+
+Template: nslcd/ldap-auth-type
+Type: select
+__Choices: none, simple, SASL
+_Default: none
+_Description: LDAP authentication to use:
+ LDAP bind can be performed anonymously or authenticated with either a
+ simple binddn/password or the Simple Authentication and Security Layer.
+ .
+ You can choose in the following list:
+  * none: no authentication.
+  * simple: simple clear text binddn/password.
+  * SASL: one of the Simple Authentication and Security Layer
+          mechanisms.
+ .
+ Clear text authentication methods should be use with Transport Layer
+ security (TLS) enabled.
+
+Template: nslcd/ldap-sasl-mech
+Type: select
+__Choices: auto, LOGIN, PLAIN, NTLM, CRAM-MD5, DIGEST-MD5, GSSAPI, OTP
+Default: auto
+_Description: SASL mechanism to use:
+ Simple Authentication and Security Layer is a challange based
+ protocol.
+ .
+ You can choose in the following list:
+  * auto: autonegociation, you can restrict autonegociation with
+          security properties.
+  * LOGIN: a simple cleartext password mechanism (need SASL SECPROPS
+           none or noanonymous).
+  * PLAIN: a simple cleartext password mechanism. PLAIN obsoleted the
+           LOGIN mechanism (need SASL SECPROPS none or noanonymous).
+  * NTLM: an NT LAN Manager authentication mechanism.
+  * CRAM-MD5: a simple challenge-response scheme based on HMAC-MD5
+              (need SASL SECPROPS minssf=0).
+  * DIGEST-MD5: HTTP Digest compatible challenge-response scheme based
+                upon MD5. DIGEST-MD5 offers a data security layer.
+  * GSSAPI: Generic Security Services Application Program Interface
+            (Kerberos, needs libsasl2-modules-gssapi-mit or
+            libsasl2-modules-gssapi-heimdal)
+  * OTP: a One Time Password mechanism. OTP obsoleted the SKEY
+         mechanism (untested, needs libsasl2-modules-otp).
+ .
+ Clear text authentication methods should be use with Transport Layer
+ security (TLS) enabled.
+
+Template: nslcd/ldap-sasl-realm
+Type: string
+_Description: SASL realm:
+ Simple Authentication and Security Layer realm to use for LDAP
+ authentication.
+ .
+ If empty, the GSSAPI mechanism will use informations from the kerberos
+ credential cache. Others may need @<REALM> suffixing sasl_authcid and
+ sasl_authzid.
+ .
+ The realm is appended to authentication and authorisation identities.
+
+Template: nslcd/ldap-sasl-authcid
+Type: string
+_Description: SASL authentication identity:
+ Simple Authentication and Security Layer identity.
+ .
+ This is the login used in LOGIN, PLAIN, CRAM-MD5 and DIGEST-MD5 mechanisms.
+
+Template: nslcd/ldap-sasl-authzid
+Type: string
+_Description: SASL proxy authorisation identity:
+ Simple Authentication and Security Layer proxy authorisation
+ identity.
+ .
+ This is the object in the name of witch the LDAP request are
+ done. They should have a DN syntax.
+
+Template: nslcd/ldap-sasl-secprops
+Type: string
+_Description: Cyrus SASL security properties:
+ The Cyrus Simple Authentication and Security Layer library provides
+ the following security properties:
+  * none: (without any other properties) causes the properties
+          defaults ("noanonymous,noplain") to be cleared.
+          Use it to enable ANONYMOUS and LOGIN and PLAIN.
+  * noplain: disables mechanisms susceptible to simple passive
+             attacks. Use it to enable ANONYMOUS.
+  * noactive: disables mechanisms susceptible to active attacks.
+  * nodict: disables mechanisms susceptible to passive dictionary
+            attacks.
+  * noanonymous: disables mechanisms which support anonymous login,
+                 can be used to enable LOGIN and PLAIN.
+  * forwardsec: requires forward secrecy between sessions.
+  * passcred: requires mechanisms which pass client credentials (and
+              allows mechanisms which can pass credentials to do so).
+  * minssf=<factor>: specifies the minimum acceptable security strength
+                     factor as an integer approximating the effective
+                     key length used for encryption.  0 (zero) implies
+                     no protection, 1 implies integrity protection
+                     only, 56 allows DES or other weak ciphers, 112
+                     allows triple DES and other strong ciphers, 128
+                     allows RC4, Blowfish and other modern strong
+                     ciphers. The default is 0.
+  * maxssf=<factor>: specifies the maximum acceptable security
+                     strength factor as an integer (see minssf
+                     description). The default is INT_MAX.
+  * maxbufsize=<factor>: specifies the maximum security layer receive
+                         buffer size allowed. 0 disables security
+                         layers. The default is 65536.
+
+Template: nslcd/ldap-sasl-krb5-keytab
+Type: string
+Default: /etc/krb5.keytab
+_Description: Kerberos keytab file path:
+ The GSSAPI/Kerberos authentication mechanism needs a keytab file.
+ .
+ The keytab file is used by k5start to create the credential cache
+ file.
+ .
+ This option is not used for now, edit /etc/default/nslcd directly.
+
+Template: nslcd/ldap-sasl-krb5-ccname
+Type: string
+Default: /var/run/nslcd/nslcd.tkt
+_Description: Kerberos credential cache file path:
+ The GSSAPI/Kerberos authentication mechanism needs a credential cache
+ file.
+ .
+ The cache file is initialised and maintained by k5start.

Attachment: pgpvROnz7JvBK.pgp
Description: PGP signature

Reply via email to