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);