]> andersk Git - moira.git/blobdiff - clients/lib/utils.c
Build without krb4 if it's unavailable.
[moira.git] / clients / lib / utils.c
index c862551844f12d254b506637e1f27603ca38b7b3..207e1bdeda4e011a535fdc863775e00d4e8325c6 100644 (file)
 #include <moira.h>
 #include <mrclient.h>
 
-#include <stdlib.h>
-#include <stdio.h>
-
 #include <com_err.h>
-#include <krb.h>
+#include <krb5.h>
+
+#include <sys/types.h>
+
+#ifdef HAVE_UNAME
+#include <sys/utsname.h>
+#endif
+
+#ifndef _WIN32
+#include <sys/socket.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#endif /* _WIN32 */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 
 RCSID("$Header$");
 
 extern char *whoami;
+extern krb5_context context;
 
-int mrcl_connect(char *server, char *client, int auth)
+int mrcl_connect(char *server, char *client, int version, int auth)
 {
   int status;
   char *motd;
@@ -48,9 +63,38 @@ int mrcl_connect(char *server, char *client, int auth)
       return MRCL_FAIL;
     }
 
+  status = mr_version(version);
+  if (status)
+    {
+      if (status == MR_UNKNOWN_PROC)
+       {
+         if (version > 2)
+           status = MR_VERSION_HIGH;
+         else
+           status = MR_SUCCESS;
+       }
+
+      if (status == MR_VERSION_HIGH)
+       {
+         com_err(whoami, 0, "Warning: This client is running newer code than the server.");
+         com_err(whoami, 0, "Some operations may not work.");
+       }
+      else if (status && status != MR_VERSION_LOW)
+       {
+         com_err(whoami, status, "while setting query version number.");
+         mr_disconnect();
+         return MRCL_FAIL;
+       }
+    }
+
   if (auth)
     {
-      status = mr_auth(client);
+      status = mr_krb5_auth(client);
+
+      /* New client talking to old server, try krb4. */
+      if (status == MR_UNKNOWN_PROC)
+       status = mr_auth(client);
+
       if (status)
        {
          com_err(whoami, status, "while authenticating to Moira.");
@@ -64,23 +108,83 @@ int mrcl_connect(char *server, char *client, int auth)
 
 char *mrcl_krb_user(void)
 {
-  int status;
-  static char pname[ANAME_SZ];
+  int flags = 0;
+  krb5_ccache cache = NULL;
+  krb5_principal princ = NULL;
+  krb5_error_code status;
+  char *username = NULL;
+
+  if (!context)
+    krb5_init_context(&context);
+
+  status = krb5_cc_default(context, &cache);
+  if (status)
+    {
+      com_err(whoami, status, "while reading Kerberos ticket file.");
+      goto out;
+    }
 
-  status = tf_init(TKT_FILE, R_TKT_FIL);
-  if (status == KSUCCESS)
+  status = krb5_cc_get_principal(context, cache, &princ);
+  if (status)
     {
-      status = tf_get_pname(pname);
-      tf_close();
+      com_err(whoami, status, "while retrieving principal name.");
+      goto out;
     }
 
-  if (status != KSUCCESS)
+  username = malloc(krb5_princ_component(context, princ, 0)->length + 1);
+  if (!username)
+    goto out;
+
+  strncpy(username, krb5_princ_component(context, princ, 0)->data,
+         krb5_princ_component(context, princ, 0)->length);
+  username[krb5_princ_component(context, princ, 0)->length] = '\0';
+
+ out:
+  if (cache)
+    krb5_cc_close(context, cache);
+  if (princ)
+    krb5_free_principal(context, princ);
+
+  return username;
+}
+
+char *partial_canonicalize_hostname(char *s)
+{
+  char buf[256], *cp;
+  static char *def_domain = NULL;
+
+  if (!def_domain)
     {
-      /* In case mr_init hasn't been called yet. */
-      initialize_krb_error_table();
-      com_err(whoami, status, "reading Kerberos ticket file.");
-      return NULL;
+      if (mr_host(buf, sizeof(buf)) == MR_SUCCESS)
+       {
+         cp = strchr(buf, '.');
+         if (cp)
+           def_domain = strdup(++cp);
+       }
+      else
+       {
+         struct hostent *hp;
+#ifdef HAVE_UNAME
+         struct utsname name;
+         uname(&name);
+         hp = gethostbyname(name.nodename);
+#else
+         char  name[256];
+         gethostname(name, sizeof(name));
+         name[sizeof(name)-1] = 0;
+         hp = gethostbyname(name);
+#endif /* HAVE_UNAME */
+         cp = strchr(hp->h_name, '.');
+         if (cp)
+           def_domain = strdup(++cp);
+       }
+      if (!def_domain)
+       def_domain = "";
     }
 
-  return pname;
+  if (strchr(s, '.') || strchr(s, '*'))
+    return s;
+  sprintf(buf, "%s.%s", s, def_domain);
+  free(s);
+  return strdup(buf);
 }
This page took 0.040834 seconds and 4 git commands to generate.