]> andersk Git - moira.git/blobdiff - server/mr_sauth.c
Case-insensitive stuff.
[moira.git] / server / mr_sauth.c
index b0d1b0a4edb3356b5f9b4d028c92fef1fa907a00..c27ec9452b0fc67580398c1383709b3c46c8250e 100644 (file)
@@ -15,15 +15,18 @@ static char *rcsid_sms_sauth_c = "$Header$";
 
 #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 
@@ -36,64 +39,142 @@ do_auth(cl)
 {
        KTEXT_ST auth;
        AUTH_DAT ad;
-       int status;
-       char buf[REALM_SZ+INST_SZ+ANAME_SZ];
-       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,
+       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.sms_status = status;
+               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]);
 }
This page took 0.04591 seconds and 4 git commands to generate.