]> arthur.barton.de Git - netatalk.git/blobdiff - etc/uams/uams_gss.c
Merge master
[netatalk.git] / etc / uams / uams_gss.c
index 2a1e85e2b5b33c01d7696279d37f18c9cff6abcb..da0411f949c4ff3e0483a99df2430f4481813405 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id: uams_gss.c,v 1.7 2009-09-28 13:19:48 franklahm Exp $
- *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * Copyright (c) 1999 Adrian Sun (asun@u.washington.edu)
  * Copyright (c) 2003 The Reed Institute
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif /* HAVE_UNISTD_H */
-
-/* STDC check */
-#if STDC_HEADERS
 #include <string.h>
-#else /* STDC_HEADERS */
-#ifndef HAVE_STRCHR
-#define strchr index
-#define strrchr index
-#endif /* HAVE_STRCHR */
-char *strchr (), *strrchr ();
-#ifndef HAVE_MEMCPY
-#define memcpy(d,s,n) bcopy ((s), (d), (n))
-#define memmove(d,s,n) bcopy ((s), (d), (n))
-#endif /* ! HAVE_MEMCPY */
-#endif /* STDC_HEADERS */
-
 #include <errno.h>
+#include <arpa/inet.h>
+
 #include <atalk/logger.h>
 #include <atalk/afp.h>
 #include <atalk/uam.h>
 #include <atalk/util.h>
+#include <atalk/compat.h>
 
 /* Kerberos includes */
 
@@ -107,7 +93,7 @@ static void log_status( char *s, OM_uint32 major_status,
 
 static void log_ctx_flags( OM_uint32 flags )
 {
-#ifdef DEBUG1
+#ifdef DEBUG
     if (flags & GSS_C_DELEG_FLAG)
         LOG(log_debug, logtype_uams, "uams_gss.c :context flag: GSS_C_DELEG_FLAG" );
     if (flags & GSS_C_MUTUAL_FLAG)
@@ -125,7 +111,8 @@ static void log_ctx_flags( OM_uint32 flags )
 
 static void log_principal(gss_name_t server_name)
 {
-#ifdef DEBUG1
+#if 0
+    /* FIXME: must call gss_canonicalize_name before gss_export_name */
     OM_uint32 major_status = 0, minor_status = 0;
     gss_buffer_desc exported_name;
 
@@ -140,28 +127,29 @@ static void log_principal(gss_name_t server_name)
 static int get_afpd_principal(void *obj, gss_name_t *server_name)
 {
     OM_uint32 major_status = 0, minor_status = 0;
-    char *realm, *fqdn, *service, *principal, *p;
-    int realmlen=0, fqdnlen=0, servicelen=0;
+    char *fqdn, *service, *principal, *p;
+    size_t fqdnlen=0, servicelen=0;
     size_t principal_length;
     gss_buffer_desc s_princ_buffer;
 
     /* get all the required information from afpd */
-    if (uam_afpserver_option(obj, UAM_OPTION_KRB5REALM, (void*) &realm, &realmlen) < 0)
-        return 1;
     if (uam_afpserver_option(obj, UAM_OPTION_FQDN, (void*) &fqdn, &fqdnlen) < 0)
         return 1;
+    LOG(log_debug, logtype_uams, "get_afpd_principal: fqdn: %s", fqdn);
+
     if (uam_afpserver_option(obj, UAM_OPTION_KRB5SERVICE, (void *)&service, &servicelen) < 0)
         return 1;
+    LOG(log_debug, logtype_uams, "get_afpd_principal: service: %s", service);
 
     /* we need all the info, log error and return if one's missing */
-    if (!service || !servicelen || !fqdn || !fqdnlen || !realm || !realmlen) {
+    if (!service || !servicelen || !fqdn || !fqdnlen) {
         LOG(log_error, logtype_uams,
             "get_afpd_principal: could not retrieve required information from afpd.");
         return 1;
     }
 
     /* allocate memory to hold the temporary principal string */
-    principal_length = servicelen + 1 + fqdnlen + 1 + realmlen + 1;
+    principal_length = servicelen + 1 + fqdnlen + 1;
     if ( NULL == (principal = (char*) malloc( principal_length)) ) {
         LOG(log_error, logtype_uams,
             "get_afpd_principal: out of memory allocating %u bytes",
@@ -171,24 +159,21 @@ static int get_afpd_principal(void *obj, gss_name_t *server_name)
 
     /*
      * Build the principal string.
-     * Format: 'service/fqdn@realm'
+     * Format: 'service@fqdn'
      */
     strlcpy( principal, service, principal_length);
-    strlcat( principal, "/", principal_length);
+    strlcat( principal, "@", principal_length);
 
     /*
      * The fqdn we get from afpd may contain a port.
      * We need to strip the port from fqdn for principal.
      */
-    p = strchr(fqdn, ':');
-    if (p)
+    if ((p = strchr(fqdn, ':')))
         *p = '\0';
+
     strlcat( principal, fqdn, principal_length);
     if (p)
         *p = ':';
-    strlcat( principal, "@", principal_length);
-    strlcat( principal, realm, principal_length);
-
     /*
      * Import our principal into the gssapi internal representation
      * stored in server_name.
@@ -199,7 +184,7 @@ static int get_afpd_principal(void *obj, gss_name_t *server_name)
     LOG(log_debug, logtype_uams, "get_afpd_principal: importing principal `%s'", principal);
     major_status = gss_import_name( &minor_status,
                                     &s_princ_buffer,
-                                    GSS_C_NO_OID,
+                                    GSS_C_NT_HOSTBASED_SERVICE,
                                     server_name );
 
     /*
@@ -321,7 +306,7 @@ static int acquire_credentials (gss_name_t *server_name, gss_cred_id_t *server_c
     OM_uint32 major_status = 0, minor_status = 0;
     char *envp;
 
-    if (envp = getenv("KRB5_KTNAME"))
+    if ((envp = getenv("KRB5_KTNAME")))
         LOG(log_debug, logtype_uams,
             "acquire credentials: acquiring credentials (uid = %d, keytab = %s)",
             (int)geteuid(), envp);
@@ -425,7 +410,7 @@ static int do_gss_auth(void *obj, char *ibuf, int ticket_len,
         if (!ret) {
             /* FIXME: Is copying the authenticator really necessary?
                Where is this documented? */
-            u_int16_t auth_len = htons( authenticator_buff.length );
+            uint16_t auth_len = htons( authenticator_buff.length );
 
             /* copy the authenticator length into the reply buffer */
             memcpy( rbuf, &auth_len, sizeof(auth_len) );
@@ -454,11 +439,11 @@ cleanup_vars:
 
 /* -------------------------- */
 static int gss_login(void *obj, struct passwd **uam_pwd,
-                     char *ibuf, int ibuflen,
-                     char *rbuf, int *rbuflen)
+                     char *ibuf, size_t ibuflen,
+                     char *rbuf, size_t *rbuflen)
 {
 
-    u_int16_t  temp16;
+    uint16_t  temp16;
 
     *rbuflen = 0;
 
@@ -472,24 +457,24 @@ static int gss_login(void *obj, struct passwd **uam_pwd,
 }
 
 static int gss_logincont(void *obj, struct passwd **uam_pwd,
-                         char *ibuf, int ibuflen,
-                         char *rbuf, int *rbuflen)
+                         char *ibuf, size_t ibuflen,
+                         char *rbuf, size_t *rbuflen)
 {
     struct passwd *pwd = NULL;
-    u_int16_t login_id;
+    uint16_t login_id;
     char *username;
-    u_int16_t ticket_len;
+    uint16_t ticket_len;
     char *p;
     int rblen;
-    int userlen;
+    size_t userlen;
     struct session_info *sinfo;
 
     /* Apple's AFP 3.1 documentation specifies that this command
      * takes the following format:
      * pad (byte)
-     * id returned in LoginExt response (u_int16_t)
+     * id returned in LoginExt response (uint16_t)
      * username (format unspecified) padded, when necessary, to end on an even boundary
-     * ticket length (u_int16_t)
+     * ticket length (uint16_t)
      * ticket
      */
 
@@ -497,20 +482,20 @@ static int gss_logincont(void *obj, struct passwd **uam_pwd,
      * format of this request is as follows:
      * pad (byte) [consumed before login_ext is called]
      * ?? (byte) - always observed to be 0
-     * id returned in LoginExt response (u_int16_t)
+     * id returned in LoginExt response (uint16_t)
      * username, encoding unspecified, null terminated C string,
      *   padded when the terminating null is an even numbered byte.
      *   The packet is formated such that the username begins on an
      *   odd numbered byte. Eg if the username is 3 characters and the
      *   terminating null makes 4, expect to pad the the result.
      *   The encoding of this string is unknown.
-     * ticket length (u_int16_t)
+     * ticket length (uint16_t)
      * ticket
      */
 
     rblen = *rbuflen = 0;
 
-    if (ibuflen < 3) {
+    if (ibuflen < 1 +sizeof(login_id)) {
         LOG(log_info, logtype_uams, "uams_gss.c :LoginCont: received incomplete packet");
         return AFPERR_PARAM;
     }
@@ -547,7 +532,7 @@ static int gss_logincont(void *obj, struct passwd **uam_pwd,
 
     if ((ibuf - p + 1) % 2) ibuf++, ibuflen--; /* deal with potential padding */
 
-    LOG(log_info, logtype_uams, "uams_gss.c :LoginCont: client thinks user is %s", p);
+    LOG(log_debug, logtype_uams, "uams_gss.c :LoginCont: client thinks user is %s", p);
 
     /* get the length of the ticket the client sends us */
     memcpy(&ticket_len, ibuf, sizeof(ticket_len));
@@ -569,7 +554,7 @@ static int gss_logincont(void *obj, struct passwd **uam_pwd,
            encoding is the gssapi name in? */
         if((pwd = uam_getname( obj, username, userlen )) == NULL) {
             LOG(log_info, logtype_uams, "uam_getname() failed for %s", username);
-            return AFPERR_PARAM;
+            return AFPERR_NOTAUTH;
         }
         if (uam_checkuser(pwd) < 0) {
             LOG(log_info, logtype_uams, "%s not a valid user", username);
@@ -591,10 +576,10 @@ static int gss_logincont(void *obj, struct passwd **uam_pwd,
  * point is trustworthy as we'll have a signed ticket to parse in logincont.
  */
 static int gss_login_ext(void *obj, char *uname, struct passwd **uam_pwd,
-                         char *ibuf, int ibuflen,
-                         char *rbuf, int *rbuflen)
+                         char *ibuf, size_t ibuflen,
+                         char *rbuf, size_t *rbuflen)
 {
-    u_int16_t  temp16;
+    uint16_t  temp16;
 
     *rbuflen = 0;