/*
- * $Source$
- * $Author$
+ * lib/krb5/os/sn2princ.c
*
* Copyright 1991 by the Massachusetts Institute of Technology.
* All Rights Reserved.
*
- * For copying and distribution information, please see the file
- * <krb5/copyright.h>.
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
*
* Convert a hostname and service name to a principal in the "standard"
* form.
*/
-#if !defined(lint) && !defined(SABER)
-static char rcsid_sn2princ_c[] =
-"$Id$";
-#endif /* !lint & !SABER */
-
-#include <krb5/krb5.h>
-#include <krb5/ext-proto.h>
-#include <krb5/los-proto.h>
-#include <netdb.h>
+#define NEED_SOCKETS
+#include "k5-int.h"
#include <ctype.h>
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
-krb5_error_code
-krb5_sname_to_principal(DECLARG(const char *,hostname),
- DECLARG(const char *,sname),
- DECLARG(krb5_boolean,canonicalize),
- DECLARG(krb5_principal *,ret_princ))
-OLDDECLARG(const char *,hostname)
-OLDDECLARG(const char *,sname)
-OLDDECLARG(krb5_boolean,canonicalize)
-OLDDECLARG(krb5_principal *,ret_princ)
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
+krb5_sname_to_principal(context, hostname, sname, type, ret_princ)
+ krb5_context context;
+ const char FAR * hostname;
+ const char FAR * sname;
+ krb5_int32 type;
+ krb5_principal FAR * ret_princ;
{
- krb5_principal lprinc;
struct hostent *hp;
- char **hrealms, *remote_host;
+ char **hrealms, *realm, *remote_host;
krb5_error_code retval;
- register char **cpp, *cp;
+ register char *cp;
+ char localname[MAXHOSTNAMELEN];
- /* copy the hostname into non-volatile storage */
- if (canonicalize) {
- if (!(hp = gethostbyname(hostname)))
- return KRB5_ERR_BAD_HOSTNAME;
- remote_host = strdup(hp->h_name);
- } else {
- remote_host = strdup(hostname);
- }
- if (!remote_host)
- return ENOMEM;
+ if ((type == KRB5_NT_UNKNOWN) ||
+ (type == KRB5_NT_SRV_HST)) {
- for (cp = remote_host; *cp; cp++)
- if (isupper(*cp))
- *cp = tolower(*cp);
+ /* if hostname is NULL, use local hostname */
+ if (! hostname) {
+ if (gethostname(localname, MAXHOSTNAMELEN))
+ return SOCKET_ERRNO;
+ hostname = localname;
+ }
- if (retval = krb5_get_host_realm(remote_host, &hrealms)) {
- free(remote_host);
- return retval;
- }
- if (!hrealms[0]) {
- free(remote_host);
- xfree(hrealms);
- return KRB5_ERR_HOST_REALM_UNKNOWN;
- }
- if (!(lprinc = (krb5_principal) calloc(4, sizeof(*lprinc)))) {
- free(remote_host);
- krb5_free_host_realm(hrealms);
- return ENOMEM;
- }
- if (!(lprinc[0] = (krb5_data *)malloc(sizeof(*lprinc[0])))) {
- krb5_free_host_realm(hrealms);
- nomem:
- free(remote_host);
- krb5_free_principal(lprinc);
- return ENOMEM;
- }
- lprinc[0]->data = hrealms[0];
- lprinc[0]->length = strlen(hrealms[0]);
+ /* if sname is NULL, use "host" */
+ if (! sname)
+ sname = "host";
- /* they're allocated; leave the first one alone, however */
- for (cpp = &hrealms[1]; *cpp; cpp++)
- xfree(*cpp);
- xfree(hrealms);
+ /* copy the hostname into non-volatile storage */
- if (!(lprinc[1] = (krb5_data *)malloc(sizeof(*lprinc[1])))) {
- goto nomem;
- }
- lprinc[1]->length = strlen(sname);
- lprinc[1]->data = strdup(sname);
- if (!(lprinc[2] = (krb5_data *)malloc(sizeof(*lprinc[2])))) {
- goto nomem;
- }
- lprinc[2]->length = strlen(remote_host);
- lprinc[2]->data = remote_host;
+ if (type == KRB5_NT_SRV_HST) {
+ char *addr;
+
+ if (!(hp = gethostbyname(hostname)))
+ return KRB5_ERR_BAD_HOSTNAME;
+ remote_host = strdup(hp->h_name);
+ if (!remote_host)
+ return ENOMEM;
+ /*
+ * Do a reverse resolution to get the full name, just in
+ * case there's some funny business going on. If there
+ * isn't an in-addr record, give up.
+ */
+ addr = malloc(hp->h_length);
+ if (!addr)
+ return ENOMEM;
+ memcpy(addr, hp->h_addr, hp->h_length);
+ hp = gethostbyaddr(addr, hp->h_length, hp->h_addrtype);
+ free(addr);
+ if (hp) {
+ free(remote_host);
+ remote_host = strdup(hp->h_name);
+ if (!remote_host)
+ return ENOMEM;
+ }
+ } else /* type == KRB5_NT_UNKNOWN */ {
+ remote_host = strdup((char *) hostname);
+ }
+ if (!remote_host)
+ return ENOMEM;
+
+ if (type == KRB5_NT_SRV_HST)
+ for (cp = remote_host; *cp; cp++)
+ if (isupper(*cp))
+ *cp = tolower(*cp);
+
+ /*
+ * Windows NT5's broken resolver gratuitously tacks on a
+ * trailing period to the hostname (at least it does in
+ * Beta2). Find and remove it.
+ */
+ if (remote_host[0]) {
+ cp = remote_host + strlen(remote_host)-1;
+ if (*cp == '.')
+ *cp = 0;
+ }
+
+
+ if (retval = krb5_get_host_realm(context, remote_host, &hrealms)) {
+ free(remote_host);
+ return retval;
+ }
+ if (!hrealms[0]) {
+ free(remote_host);
+ krb5_xfree(hrealms);
+ return KRB5_ERR_HOST_REALM_UNKNOWN;
+ }
+ realm = hrealms[0];
+
+ retval = krb5_build_principal(context, ret_princ, strlen(realm),
+ realm, sname, remote_host,
+ (char *)0);
+
+ krb5_princ_type(context, *ret_princ) = type;
- *ret_princ = lprinc;
- return 0;
+ free(remote_host);
+
+ krb5_free_host_realm(context, hrealms);
+ return retval;
+ } else {
+ return KRB5_SNAME_UNSUPP_NAMETYPE;
+ }
}