X-Git-Url: http://andersk.mit.edu/gitweb/moira.git/blobdiff_plain/c0d411866caff3a8a785e7376ad0a2c7c973085a..dcfa270ac1d2f55eb793c4da4bbd555903a88b09:/server/mr_sauth.c diff --git a/server/mr_sauth.c b/server/mr_sauth.c index 6830290d..dcb45b23 100644 --- a/server/mr_sauth.c +++ b/server/mr_sauth.c @@ -15,15 +15,17 @@ static char *rcsid_sms_sauth_c = "$Header$"; #include #include -#include "sms_server.h" +#include "mr_server.h" +#include #include 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,65 +38,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); + strcpy(cl->clname, kname_unparse(ad.pname, ad.pinst, ad.prealm)); - if (!strcmp(ad.prealm, krb_realm)) - 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) { + strncpy(cl->entity, cl->args->mr_argv[1], 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]); }