CVS'ers I noticed during my attempts to configure cvs 1.11.1p1 using gssapi authentication and systemauth=no that it did not work as one might expect from the documentation.
I am attaching a patch that changes the behavior - such that gssapi authentication is now subject to the systemauth configuration and the CVSROOT/passwd file. (This includes support for virtual users via the passwd file remapping of usernames.) I submit this for suggestions on how to make it better - i am concerned about the addition of a new function gssapi_check_password() - i feel that there should be a better method of integrating this functionality with the normal check_password function. If anyone has sugegstions about how to better clean that up, I would be delighted to resubmit this patch with modifications to the News file, and other suggestions in the HACKING file. Thanks ever so much for a fabulous product! -VaiX --------------SNIP-------------- diff -rU 5 cvs-1.11.2/src/client.c j.cvs2/src/client.c --- cvs-1.11.2/src/client.c Thu Aug 9 16:27:26 2001 +++ j.cvs2/src/client.c Tue Sep 17 20:05:27 2002 @@ -4236,10 +4236,18 @@ str = "BEGIN GSSAPI REQUEST\012"; if (send (sock, str, strlen (str), 0) < 0) error (1, 0, "cannot send: %s", SOCK_STRERROR (SOCK_ERRNO)); + if (send (sock, current_parsed_root->directory, strlen +(current_parsed_root->directory), 0) < 0) + error (1, 0, "cannot send: %s", SOCK_STRERROR (SOCK_ERRNO)); + + str = "\012"; + + if (send (sock, str, strlen (str), 0) < 0) + error (1, 0, "cannot send: %s", SOCK_STRERROR (SOCK_ERRNO)); + if (strlen (hostinfo->h_name) > BUFSIZE - 5) error (1, 0, "Internal error: hostname exceeds length of buffer"); sprintf (buf, "cvs@%s", hostinfo->h_name); tok_in.length = strlen (buf); tok_in.value = buf; diff -rU 5 cvs-1.11.2/src/server.c j.cvs2/src/server.c --- cvs-1.11.2/src/server.c Tue Mar 19 14:15:45 2002 +++ j.cvs2/src/server.c Tue Sep 17 20:03:37 2002 @@ -31,11 +31,11 @@ # include <krb5.h> /* We need this to wrap data. */ static gss_ctx_id_t gcontext; -static void gserver_authenticate_connection PROTO((void)); +static void gserver_authenticate_connection PROTO((char *)); /* Whether we are already wrapping GSSAPI communication. */ static int cvs_gssapi_wrapping; # ifdef ENCRYPTION @@ -5437,10 +5437,11 @@ fp = CVS_FOPEN (filename, "r"); if (fp == NULL) { if (!existence_error (errno)) error (0, errno, "cannot open %s", filename); + error (0, errno, "cannot open %s", filename); return 0; } /* Look for a relevant line -- one with this user's name. */ namelen = strlen (username); @@ -5674,10 +5675,55 @@ } return host_user; } + + + +/* Return a hosting username if password matches, else NULL. */ +static char * +gssapi_check_password (username, password, repository) + char *username, *password, *repository; +{ + + + int rc; + char *host_user = NULL; + + /* We see if this user has a password in the CVS-specific + * password file. If so, that's enough to authenticate with. */ + + rc = check_repository_password (username, password, repository, + &host_user); + + if (rc == 2) + return NULL; + + /* else */ + + if (rc == 1) + { + /* host_user already set by reference, so just return. */ + goto handle_return; + } + if (rc == 0 ) + error (1, 0, "GSSAPI authentication failed"); + + +handle_return: + if (host_user) + { + /* Set CVS_Username here, in allocated space. + * It might or might not be the same as host_user. */ + CVS_Username = xmalloc (strlen (username) + 1); + strcpy (CVS_Username, username); + } + + return host_user; +} + #endif /* AUTH_SERVER_SUPPORT */ #if defined (AUTH_SERVER_SUPPORT) || defined (HAVE_GSSAPI) /* Read username and password from client (i.e., stdin). @@ -5774,11 +5820,28 @@ ; else if (strcmp (tmp, "BEGIN GSSAPI REQUEST\n") == 0) { #ifdef HAVE_GSSAPI free (tmp); - gserver_authenticate_connection (); + + getline_safe (&repository, &repository_allocated, stdin, PATH_MAX); + strip_trailing_newlines (repository); + + if (!root_allow_ok (repository)) + { + printf ("error 0 %s: no such repository\n", repository); +#ifdef HAVE_SYSLOG_H + syslog (LOG_DAEMON | LOG_NOTICE, "login refused for %s", repository); +#endif + goto i_hate_you; + } + + + gserver_authenticate_connection (repository); + + + return; #else error (1, 0, "GSSAPI authentication not supported by this server"); #endif } @@ -5980,21 +6043,26 @@ /* Authenticate a GSSAPI connection. This is called from pserver_authenticate_connection, and it handles success and failure the same way. */ static void -gserver_authenticate_connection () +gserver_authenticate_connection (repository) + + char *repository; + { char hostname[MAXHOSTNAMELEN]; struct hostent *hp; gss_buffer_desc tok_in, tok_out; char buf[1024]; OM_uint32 stat_min, ret; gss_name_t server_name, client_name; gss_cred_id_t server_creds; int nbytes; gss_OID mechid; + char *host_user = NULL; + gethostname (hostname, sizeof hostname); hp = gethostbyname (hostname); if (hp == NULL) error (1, 0, "can't get canonical hostname"); @@ -6051,20 +6119,38 @@ We could instead use an authentication to access mapping. */ { krb5_context kc; krb5_principal p; gss_buffer_desc desc; + krb5_init_context (&kc); if (gss_display_name (&stat_min, client_name, &desc, - &mechid) != GSS_S_COMPLETE + &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) + || krb5_aname_to_localname (kc, p, sizeof buf, buf) != 0 ) { error (1, 0, "access denied"); } + + parse_config (repository); + + if ( system_auth && krb5_kuserok (kc, p, buf) != TRUE ) + { + error (1, 0, "access denied"); + } + + if ( ! system_auth ) + { + host_user = gssapi_check_password (buf, "", repository); + + if ( host_user == NULL ) + { + error (1, 0, "access denied"); + } + } + krb5_free_principal (kc, p); krb5_free_context (kc); } if (tok_out.length != 0) @@ -6077,11 +6163,15 @@ || (fwrite (tok_out.value, 1, tok_out.length, stdout) != tok_out.length)) error (1, errno, "fwrite failed"); } - switch_to_user (buf); + + if ( system_auth ) + switch_to_user (buf); + else + switch_to_user (host_user); printf ("I LOVE YOU\n"); fflush (stdout); } _______________________________________________ Bug-cvs mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/bug-cvs