klog: make krb5_524 non-fatal for native K5 tokens
authorJeffrey Altman <jaltman@your-file-system.com>
Wed, 15 Oct 2014 16:19:44 +0000 (12:19 -0400)
committerD Brashear <shadow@your-file-system.com>
Wed, 5 Nov 2014 15:41:09 +0000 (10:41 -0500)
The krb5_524_conv_principal() function should fail whenever the Kerberos
v5 principal cannot safely be mapped onto a Kerberos v4 principal, and
does fail on some Kerberos v5 principals used in real-world AFS
deployments.

Prior to this patchset a failure was treated as a fatal error that
in turn prevents an AFS token from being generated or set into the
cache manager.

Prior to b1f9b4cb5dd295162ae51704310e9d6058008f0a the
krb5_524_conv_principal() function wasn't used and a local client
mapping was created.  b1f9b4cb5dd295162ae51704310e9d6058008f0a
replaced the local mapping with the krb5 function because the local
mapping could be wrong and confusing.

The krb5_524_conv_principal() function as applied to AFS tokens is
just a local guess.  How the username in the token is interpreted by
the AFS server is up to the server.

krb5_524_conv_principal() is only used for Krb5 native tokens. For Krb4
tokens the krb5_524_convert_creds() function is used to obtain both the
Kerberos v4 ticket and the converted names from the KDC. Many
organizations used the krb524d service to perform name translation. When
the krb524d service is used, the name translation is performed by the KDC,
so there is no local call to krb5_524_conf_principal() which might fail.
As a result, disallowing the use of a native Krb5 token due to a failed
local name translation is a needless loss of functionality; the local name
translation is not an essential part of obtaining a token.

This patchset modifies the behavior such that krb5_524_conv_principal()
errors are non-fatal.

 1. If -noprdb is not specified the error message is generated
    and a NULL username is used.

 2. If the username is NULL the prdb lookup is disabled.

 3. If the username is NULL the informational messages do not
    include a username.

 4. If the username is NULL the username info provided to the
    cache manager in the token description is the nul string.

Credit to Ben Kaduk for assistance with the wording of this
commit message.

Change-Id: Ib07131fc0ff4bf5319815213198c3f0adac17b10
Reviewed-on: http://gerrit.openafs.org/11542
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>
Reviewed-by: D Brashear <shadow@your-file-system.com>

doc/man-pages/pod1/aklog.pod
src/aklog/aklog.c

index e6b78a2..eb1727b 100644 (file)
@@ -36,13 +36,15 @@ specified with B<-k>.  B<-k> cannot be used in B<-path> mode (see below).
 When a Kerberos 5 cross-realm trust is used, B<aklog> looks up the AFS ID
 corresponding to the name (Kerberos principal) of the person invoking the
 command, and if the user doesn't exist and the
-system:authuser@FOREIGN.REALM PTS group exists, then it attempts automatic
+C<system:authuser@FOREIGN.REALM> PTS group exists, then it attempts automatic
 registration of the user with the foreign cell.  The user is then added to
-the system:authuser@FOREIGN.REALM PTS group if registration is successful.
+the C<system:authuser@FOREIGN.REALM> PTS group if registration is successful.
 Automatic registration in the foreign cell will fail if the group quota
-for the system:authuser@FOREIGN.REALM group is less than one.  Each
+for the C<system:authuser@FOREIGN.REALM> group is less than one.  Each
 automatic registration decrements the group quota by one.
 
+=head1 CAUTIONS
+
 When using B<aklog>, be aware that AFS uses the Kerberos v4 principal
 naming format, not the Kerberos v5 format, when referring to principals in
 PTS ACLs, F<UserList>, and similar locations.  AFS will internally map
@@ -54,6 +56,15 @@ entry for the Kerberos v5 principal C<user/admin>, refer to it as
 C<user.admin>, and for the principal C<host/shell.example.com>, refer to
 it as C<rcmd.shell>.
 
+The B<aklog> mapping of Kerberos v5 principal to Kerberos v4 principal and
+the determination that a Kerberos realm is foreign is performed in the
+absence of the actual AFS server configuration.  If the B<aklog> mapping
+of Kerberos v5 principal to Kerberos v4 principal or the foreign realm
+determination is wrong, the PTS name-to-id lookup will produce the wrong
+AFS ID for the user.  The AFS ID is only used for display purposes and
+should not be trusted.  Use the B<-noprdb> switch to disable the PTS
+name-to-id lookup.
+
 =head1 OPTIONS
 
 =over 4
index a21da6c..c9f9cfe 100644 (file)
@@ -655,7 +655,8 @@ out:
  *     structure which should be freed by the caller.
  * @param[out[ userPtr
  *     A string containing the principal of the user to whom the token was
- *     issued. This is a malloc'd block which should be freed by the caller.
+ *     issued. This is a malloc'd block which should be freed by the caller,
+ *      if set.
  *
  * @returns
  *     0 on success, an error value upon failure
@@ -663,7 +664,7 @@ out:
 static int
 rxkad_build_native_token(krb5_context context, krb5_creds *v5cred,
                         struct ktc_tokenUnion **tokenPtr, char **userPtr) {
-    char username[BUFSIZ];
+    char username[BUFSIZ]="";
     struct ktc_token token;
     int status;
 #ifdef HAVE_NO_KRB5_524
@@ -688,14 +689,15 @@ rxkad_build_native_token(krb5_context context, krb5_creds *v5cred,
                                      (char *) &k4inst,
                                      (char *) &k4realm);
     if (status) {
-       afs_com_err(progname, status, "while converting principal "
-                   "to Kerberos V4 format");
-       return AKLOG_KERBEROS;
-    }
-    strcpy (username, k4name);
-    if (k4inst[0]) {
-       strcat (username, ".");
-       strcat (username, k4inst);
+       if (!noprdb)
+           afs_com_err(progname, status,
+                       "while converting principal to Kerberos V4 format");
+    } else {
+       strcpy (username, k4name);
+       if (k4inst[0]) {
+           strcat (username, ".");
+           strcat (username, k4inst);
+       }
     }
 #else
     len = min(get_princ_len(context, v5cred->client, 0),
@@ -731,7 +733,8 @@ rxkad_build_native_token(krb5_context context, krb5_creds *v5cred,
        return status;
     }
 
-    *userPtr = strdup(username);
+    if (username[0] != '\0')
+       *userPtr = strdup(username);
 
     return 0;
 }
@@ -751,7 +754,8 @@ rxkad_build_native_token(krb5_context context, krb5_creds *v5cred,
  *     structure which should be freed by the caller.
  * @param[out[ userPtr
  *     A string containing the principal of the user to whom the token was
- *     issued. This is a malloc'd block which should be freed by the caller.
+ *     issued. This is a malloc'd block which should be freed by the caller,
+ *      if set.
  *
  * @returns
  *     0 on success, an error value upon failure
@@ -838,7 +842,8 @@ rxkad_get_converted_token(krb5_context context, krb5_creds *v5cred,
  *     be freed by the caller.
  * @parma[out] authuser
  *     A string containing the principal of the user to whom the token was
- *     issued. This is a malloc'd block which should be freed by the caller.
+ *     issued. This is a malloc'd block which should be freed by the caller,
+ *      if set.
  * @param[out] foreign
  *     Whether the user is considered as 'foreign' to the realm of the cell.
  *
@@ -871,7 +876,7 @@ rxkad_get_token(krb5_context context, struct afsconf_cell *cell, char *realm,
 
     /* We now have the username, plus the realm name, so stitch them together
      * to give us the name that the ptserver will know the user by */
-    if (realmUsed == NULL) {
+    if (realmUsed == NULL || username == NULL) {
        *authuser = username;
        username = NULL;
        *foreign = 0;
@@ -998,7 +1003,10 @@ auth_to_cell(krb5_context context, const char *config,
        noprdb = 1;
 #endif
 
-       if (noprdb) {
+       if (username == NULL) {
+           afs_dprintf("Not resolving name to id\n");
+       }
+       else if (noprdb) {
            afs_dprintf("Not resolving name %s to id (-noprdb set)\n", username);
        }
        else {
@@ -1069,7 +1077,12 @@ auth_to_cell(krb5_context context, const char *config,
            }
        }
 
-       afs_dprintf("Setting tokens. %s @ %s \n", username, cellconf.name);
+       if (username) {
+           afs_dprintf("Setting tokens. %s @ %s\n",
+                       username, cellconf.name);
+       } else {
+           afs_dprintf("Setting tokens for cell %s\n", cellconf.name);
+       }
 
 #ifndef AFS_AIX51_ENV
        /* on AIX 4.1.4 with AFS 3.4a+ if a write is not done before