I've posted an almost identical version of this on the "issue tracker"
on ccvs.cvshome.org, but
a) apparently no-one looks at that, and
b) this is a slightly better fix.

In cvs 1.11.1p1 a CVSROOT of :gserver:user@host:port/path doesn't work --
the "user" part is ignored. The attached patch fixes this by making a
slightly different auth request with a username.

This version of the patch also lets non-user kerberos principals in if
they are listed in the target account's .k5login file (i.e. host
principals, etc.)  That is to say, if krb5_aname_to_localname doesn't map
the principal to a local account, but a local username was specified,
that's okay.

-----
Marc Mengel <[EMAIL PROTECTED]>
Index: src/client.c
===================================================================
RCS file: /cvs/oss/cvs/src/cvs/src/client.c,v
retrieving revision 1.1.1.3
retrieving revision 1.4
diff -c -r1.1.1.3 -r1.4
*** client.c    2001/08/17 20:31:22     1.1.1.3
--- client.c    2001/10/03 14:42:38     1.4
***************
*** 4199,4209 ****
      gss_buffer_desc *tok_in_ptr, tok_in, tok_out;
      OM_uint32 stat_min, stat_maj;
      gss_name_t server_name;
  
!     str = "BEGIN GSSAPI REQUEST\012";
  
      if (send (sock, str, strlen (str), 0) < 0)
        error (1, 0, "cannot send: %s", SOCK_STRERROR (SOCK_ERRNO));
  
      sprintf (buf, "cvs@%s", hostinfo->h_name);
      tok_in.length = strlen (buf);
--- 4199,4223 ----
      gss_buffer_desc *tok_in_ptr, tok_in, tok_out;
      OM_uint32 stat_min, stat_maj;
      gss_name_t server_name;
+     char *username;
  
!     if ( current_parsed_root->username != NULL ) {
!         str = "BEGIN GSSAPI-U REQUEST\012";
!       fprintf(stderr,"development test of GSSAPI-U username=%s\n", 
current_parsed_root->username);
!     } else {
!         str = "BEGIN GSSAPI REQUEST\012";
!     }
  
      if (send (sock, str, strlen (str), 0) < 0)
        error (1, 0, "cannot send: %s", SOCK_STRERROR (SOCK_ERRNO));
+ 
+     if ( current_parsed_root->username != NULL ) {
+       str = current_parsed_root->username;
+       if (send (sock, str, strlen (str), 0) < 0)
+           error (1, 0, "cannot send: %s", SOCK_STRERROR (SOCK_ERRNO));
+       if (send (sock, "\012", 1, 0) < 0)
+           error (1, 0, "cannot send: %s", SOCK_STRERROR (SOCK_ERRNO));
+     }
  
      sprintf (buf, "cvs@%s", hostinfo->h_name);
      tok_in.length = strlen (buf);
Index: src/server.c
===================================================================
RCS file: /cvs/oss/cvs/src/cvs/src/server.c,v
retrieving revision 1.1.1.3
retrieving revision 1.6
diff -c -r1.1.1.3 -r1.6
*** server.c    2001/08/17 20:31:23     1.1.1.3
--- server.c    2001/10/03 14:42:38     1.6
***************
*** 33,39 ****
  /* We need this to wrap data.  */
  static gss_ctx_id_t gcontext;
  
! static void gserver_authenticate_connection PROTO((void));
  
  /* Whether we are already wrapping GSSAPI communication.  */
  static int cvs_gssapi_wrapping;
--- 33,39 ----
  /* We need this to wrap data.  */
  static gss_ctx_id_t gcontext;
  
! static void gserver_authenticate_connection PROTO((char *));
  
  /* Whether we are already wrapping GSSAPI communication.  */
  static int cvs_gssapi_wrapping;
***************
*** 5752,5763 ****
      {
  #ifdef HAVE_GSSAPI
        free (tmp);
!       gserver_authenticate_connection ();
        return;
  #else
        error (1, 0, "GSSAPI authentication not supported by this server");
  #endif
      }
      else
        error (1, 0, "bad auth protocol start: %s", tmp);
  
--- 5752,5779 ----
      {
  #ifdef HAVE_GSSAPI
        free (tmp);
!       gserver_authenticate_connection ((char *)0);
        return;
  #else
        error (1, 0, "GSSAPI authentication not supported by this server");
  #endif
      }
+     else if (strcmp (tmp, "BEGIN GSSAPI-U REQUEST\n") == 0)
+     {
+ #ifdef HAVE_GSSAPI
+       free (tmp);
+         getline_safe (&username, &username_allocated, stdin, PATH_MAX);
+         strip_trailing_newlines (username);
+       gserver_authenticate_connection (username);
+       if (username_allocated)  {
+          free(username);
+          username_allocated = 0;
+         }
+       return;
+ #else
+       error (1, 0, "GSSAPI authentication not supported by this server");
+ #endif
+     }
      else
        error (1, 0, "bad auth protocol start: %s", tmp);
  
***************
*** 5956,5962 ****
     the same way.  */
  
  static void
! gserver_authenticate_connection ()
  {
      char hostname[MAXHOSTNAMELEN];
      struct hostent *hp;
--- 5972,5978 ----
     the same way.  */
  
  static void
! gserver_authenticate_connection ( char *username )
  {
      char hostname[MAXHOSTNAMELEN];
      struct hostent *hp;
***************
*** 6033,6039 ****
                              &mechid) != GSS_S_COMPLETE
            || krb5_parse_name (kc, ((gss_buffer_t) &desc)->value, &p) != 0
!           || krb5_aname_to_localname (kc, p, sizeof buf, buf) != 0
!           || krb5_kuserok (kc, p, buf) != TRUE)
        {
            error (1, 0, "access denied");
        }
--- 6049,6055 ----
                              &mechid) != GSS_S_COMPLETE
            || krb5_parse_name (kc, ((gss_buffer_t) &desc)->value, &p) != 0
!           || (krb5_aname_to_localname (kc, p, sizeof buf, buf) != 0 && !username)
!           || krb5_kuserok (kc, p, (username ? username: buf)) != TRUE)
        {
            error (1, 0, "access denied");
        }
***************
*** 6053,6059 ****
            error (1, errno, "fwrite failed");
      }
  
!     switch_to_user (buf);
  
      printf ("I LOVE YOU\n");
      fflush (stdout);
--- 6069,6078 ----
            error (1, errno, "fwrite failed");
      }
  
! #ifdef HAVE_SYSLOG_H
!     syslog (LOG_DAEMON | LOG_ERR, "gserver: switching to user %s", (username ? 
username :buf));
! #endif
!     switch_to_user (username ? username : buf);
  
      printf ("I LOVE YOU\n");
      fflush (stdout);

Reply via email to