* $Header$
*
* Copyright (C) 1987 by the Massachusetts Institute of Technology
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
*
*/
static char *rcsid_sms_sauth_c = "$Header$";
#endif lint
-extern int krb_err_base;
+#include <mit-copyright.h>
#include <strings.h>
-#include "sms_server.h"
+#include "mr_server.h"
+#include <ctype.h>
+#include <krb_et.h>
extern char buf1[];
extern char *whoami;
extern char *malloc();
+char *kname_unparse();
+
/*
- * Handle a SMS_AUTH RPC request.
+ * Handle a MOIRA_AUTH RPC request.
*
* argv[0] is a kerberos authenticator. Decompose it, and if
* successful, store the name the user authenticated to in
{
KTEXT_ST auth;
AUTH_DAT ad;
- int status;
- char buf[REALM_SZ+INST_SZ+ANAME_SZ];
- extern int krb_err_base;
- static char *unknown = "???";
-
- if (cl->clname) {
- free(cl->clname);
- cl->clname = 0;
- cl->users_id = 0;
- bzero(&cl->kname, sizeof(cl->kname));
- }
- if (cl->entity && cl->entity != unknown) {
- free(cl->entity);
- cl->entity = 0;
- }
-
- auth.length = cl->args->sms_argl[0];
- bcopy(cl->args->sms_argv[0], (char *)auth.dat, auth.length);
+ int status, ok;
+ char buf[REALM_SZ+INST_SZ+ANAME_SZ], hostbuf[BUFSIZ], *host, *p;
+ extern int errno;
+
+ auth.length = cl->args->mr_argl[0];
+ bcopy(cl->args->mr_argv[0], (char *)auth.dat, auth.length);
auth.mbz = 0;
-
- if ((status = krb_rd_req (&auth, "sms", "sms", cl->haddr.sin_addr,
- &ad, "")) != KSUCCESS) {
- status += krb_err_base;
- cl->reply.sms_status = status;
+ if (gethostname(hostbuf, sizeof(hostbuf)) < 0)
+ com_err(whoami, errno, "Unable to get local hostname");
+ host = canonicalize_hostname(strsave(hostbuf));
+ for (p = host; *p && *p != '.'; p++)
+ if (isupper(*p))
+ *p = tolower(*p);
+ *p = 0;
+
+ if ((status = krb_rd_req (&auth, MOIRA_SNAME, host, cl->haddr.sin_addr,
+ &ad, "")) != 0 &&
+ /* for backwards compatability with old clients */
+ (status = krb_rd_req (&auth, "sms", "sms", cl->haddr.sin_addr,
+ &ad, "")) != 0) {
+ status += ERROR_TABLE_BASE_krb;
+ cl->reply.mr_status = status;
if (log_flags & LOG_RES)
com_err(whoami, status, "(authentication failed)");
return;
}
+ free(host);
+
bcopy(ad.pname, cl->kname.name, ANAME_SZ);
bcopy(ad.pinst, cl->kname.inst, INST_SZ);
bcopy(ad.prealm, cl->kname.realm, REALM_SZ);
-
- (void) strcpy(buf, ad.pname);
- if(ad.pinst[0]) {
- (void) strcat(buf, ".");
- (void) strcat(buf, ad.pinst);
- }
- (void) strcat(buf, "@");
- (void) strcat(buf, ad.prealm);
- if (cl->clname) free((char *)cl->clname);
-
- cl->clname = (char *)malloc((unsigned)(strlen(buf)+1));
- (void) strcpy(cl->clname, buf);
- bzero(&ad, sizeof(ad)); /* Clean up session key, etc. */
+ strcpy(cl->clname, kname_unparse(ad.pname, ad.pinst, ad.prealm));
- cl->users_id = get_users_id(cl->kname.name);
+ if (ad.pinst[0] == 0 && !strcmp(ad.prealm, krb_realm))
+ ok = 1;
+ else
+ ok = 0;
+ /* this is in a separate function because it accesses the database */
+ status = set_krb_mapping(cl->clname, ad.pname, ok,
+ &cl->client_id, &cl->users_id);
- if (cl->args->sms_version_no == SMS_VERSION_2) {
- unsigned len = strlen(cl->args->sms_argv[1]) + 1;
-
- cl->entity = (char *)malloc(len);
- bcopy(cl->args->sms_argv[1], cl->entity, len+1);
+ if (cl->args->mr_version_no == MR_VERSION_2) {
+ bcopy(cl->args->mr_argv[1], cl->entity, 8);
+ cl->entity[8] = 0;
} else {
- cl->entity = unknown;
+ strcpy(cl->entity, "???");
}
+ bzero(&ad, sizeof(ad)); /* Clean up session key, etc. */
if (log_flags & LOG_RES)
- com_err(whoami, 0, "Authenticated to %s using %s, id %d",
- cl->clname, cl->entity, cl->users_id);
- if (cl->users_id == 0)
- cl->reply.sms_status = SMS_USER_AUTH;
+ com_err(whoami, 0, "Auth to %s using %s, uid %d cid %d",
+ cl->clname, cl->entity, cl->users_id, cl->client_id);
+ if (status != MR_SUCCESS)
+ cl->reply.mr_status = status;
+ else if (cl->users_id == 0)
+ cl->reply.mr_status = MR_USER_AUTH;
+}
+
+
+/* Turn a principal, instance, realm triple into a single non-ambiguous
+ * string. This is the inverse of kname_parse(). It returns a pointer
+ * to a static buffer, or NULL on error.
+ */
+
+char *kname_unparse(p, i, r)
+char *p;
+char *i;
+char *r;
+{
+ static char name[MAX_K_NAME_SZ];
+ char *s;
+
+ s = name;
+ if (!p || strlen(p) > ANAME_SZ)
+ return(NULL);
+ while (*p) {
+ switch (*p) {
+ case '@':
+ *s++ = '\\';
+ *s++ = '@';
+ break;
+ case '.':
+ *s++ = '\\';
+ *s++ = '.';
+ break;
+ case '\\':
+ *s++ = '\\';
+ *s++ = '\\';
+ break;
+ default:
+ *s++ = *p;
+ }
+ p++;
+ }
+ if (i && *i) {
+ if (strlen(i) > INST_SZ)
+ return(NULL);
+ *s++ = '.';
+ while (*i) {
+ switch (*i) {
+ case '@':
+ *s++ = '\\';
+ *s++ = '@';
+ break;
+ case '.':
+ *s++ = '\\';
+ *s++ = '.';
+ break;
+ case '\\':
+ *s++ = '\\';
+ *s++ = '\\';
+ break;
+ default:
+ *s++ = *i;
+ }
+ i++;
+ }
+ }
+ *s++ = '@';
+ if (!r || strlen(r) > REALM_SZ)
+ return(NULL);
+ while (*r) {
+ switch (*r) {
+ case '@':
+ *s++ = '\\';
+ *s++ = '@';
+ break;
+ case '\\':
+ *s++ = '\\';
+ *s++ = '\\';
+ break;
+ default:
+ *s++ = *r;
+ }
+ r++;
+ }
+ *s = '\0';
+ return(&name[0]);
}