From c02fbe41865e458eeb42c47140afff59b07ae418 Mon Sep 17 00:00:00 2001 From: Johan Danielsson Date: Fri, 5 Sep 1997 17:31:18 +0000 Subject: [PATCH] Use new common framework. git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@3389 ec53bebd-3082-4978-b11e-865c3cabbd6b --- lib/kafs/afskrb.c | 371 +++++++-------------------------------------- lib/kafs/afskrb5.c | 370 +++++++------------------------------------- 2 files changed, 113 insertions(+), 628 deletions(-) diff --git a/lib/kafs/afskrb.c b/lib/kafs/afskrb.c index 3dffef9ed..b9ced4570 100644 --- a/lib/kafs/afskrb.c +++ b/lib/kafs/afskrb.c @@ -40,334 +40,73 @@ RCSID("$Id$"); -#define AUTH_SUPERUSER "afs" +struct krb_kafs_data { + const char *realm; +}; -/* - * Here only ASCII characters are relevant. - */ - -#define IsAsciiLower(c) ('a' <= (c) && (c) <= 'z') - -#define ToAsciiUpper(c) ((c) - 'a' + 'A') - -static void -foldup(char *a, const char *b) +static int +get_cred(kafs_data *data, const char *name, const char *inst, + const char *realm, CREDENTIALS *c) { - for (; *b; a++, b++) - if (IsAsciiLower(*b)) - *a = ToAsciiUpper(*b); + KTEXT_ST tkt; + int ret = krb_get_cred((char*)name, (char*)inst, (char*)realm, c); + + if (ret) { + ret = krb_mk_req(&tkt, (char*)name, (char*)inst, (char*)realm, 0); + if (ret == KSUCCESS) + ret = krb_get_cred((char*)name, (char*)inst, (char*)realm, c); + } + return ret; +} + +static krb5_error_code +afslog_uid_int(kafs_data *data, const char *cell, uid_t uid) +{ + int ret; + CREDENTIALS c; + struct krb_kafs_data *d = data->data; + char realm[REALM_SZ], *lrealm; + + if (cell == 0 || cell[0] == 0) + return _kafs_afslog_all_local_cells (data, uid); + + ret = krb_get_lrealm(realm , 0); + if(ret == KSUCCESS && (d->realm == NULL || strcmp(d->realm, realm))) + lrealm = realm; else - *a = *b; - *a = '\0'; -} + lrealm = NULL; -static int -get_cred(const char *princ, const char *inst, const char *krealm, - CREDENTIALS *c, KTEXT_ST *tkt) -{ - int k_errno = krb_get_cred((char*)princ, (char*)inst, (char*)krealm, c); - - if (k_errno != KSUCCESS) - { - k_errno = krb_mk_req(tkt, (char*)princ, (char*)inst, (char*)krealm, 0); - if (k_errno == KSUCCESS) - k_errno = krb_get_cred((char*)princ, (char*)inst, (char*)krealm, c); - } - return k_errno; -} - - -/* Convert a string to a 32 bit ip number in network byte order. - Return 0 on error - */ - -static u_int32_t -ip_aton(char *ip) -{ - u_int32_t addr; - unsigned int a, b, c, d; - - if(sscanf(ip, "%u.%u.%u.%u", &a, &b, &c, &d) != 4) - return 0; - if((a | b | c | d) > 255) - return 0; - addr = (a << 24) | (b << 16) | (c << 8) | d; - addr = htonl(addr); - return addr; -} - -/* Try to get a db-server for an AFS cell from a AFSDB record */ - -static int -dns_find_cell(const char *cell, char *dbserver) -{ - struct dns_reply *r; - int ok = -1; - r = dns_lookup(cell, "afsdb"); - if(r){ - struct resource_record *rr = r->head; - while(rr){ - if(rr->type == T_AFSDB && rr->u.afsdb->preference == 1){ - strncpy(dbserver, rr->u.afsdb->domain, MaxHostNameLen); - dbserver[MaxHostNameLen - 1] = 0; - ok = 0; - break; - } - rr = rr->next; - } - dns_free_data(r); - } - return ok; -} - - -/* Find the realm associated with cell. Do this by opening - /usr/vice/etc/CellServDB and getting the realm-of-host for the - first VL-server for the cell. - - This does not work when the VL-server is living in one cell, but - the cell it is serving is living in another cell. - */ - -static char* -realm_of_cell(const char *cell) -{ - FILE *F; - char buf[1024]; - u_int32_t addr; - struct hostent *hp; - char *realm = NULL; - - if((F = fopen(_PATH_CELLSERVDB, "r"))){ - while(fgets(buf, sizeof(buf), F)){ - if(buf[0] != '>') - continue; - if(strncmp(buf + 1, cell, strlen(cell)) == 0){ - if(fgets(buf, sizeof(buf), F) == NULL) - break; - addr = ip_aton(buf); - if(addr == 0) - break; - hp = gethostbyaddr((char*)&addr, 4, AF_INET); - if(hp == NULL) - break; - strncpy (buf, hp->h_name, sizeof(buf)); - buf[sizeof(buf) - 1] = '\0'; - realm = krb_realmofhost(buf); - break; - } - } - fclose(F); - } - if(realm == NULL){ - if(dns_find_cell(cell, buf) == 0) - realm = krb_realmofhost(buf); - } - return realm; -} - -/* - * Get tokens for all cells[] - */ -static int -k_afslog_cells(char *cells[], int max, const char *krealm, uid_t uid) -{ - int err = KSUCCESS; - int i; - for(i = 0; i < max; i++) - err = k_afsklog_uid(cells[i], krealm, uid); - return err; -} - -/* - * Try to find the cells we should try to klog to in "file". - */ -static void -k_find_cells(char *file, char *cells[], int size, int *index) -{ - FILE *f; - char cell[64]; - int i; - f = fopen(file, "r"); - if (f == NULL) - return; - while (*index < size && fgets(cell, sizeof(cell), f)) { - char *nl = strchr(cell, '\n'); - if (nl) *nl = 0; - for(i = 0; i < *index; i++) - if(strcmp(cells[i], cell) == 0) - break; - if(i == *index) - cells[(*index)++] = strdup(cell); - } - fclose(f); -} - -static int -k_afsklog_all_local_cells(const char *krealm, uid_t uid) -{ - int err; - char *cells[32]; /* XXX */ - int num_cells = sizeof(cells) / sizeof(cells[0]); - int index = 0; - - char *p; + ret = _kafs_get_cred(data, cell, d->realm, lrealm, &c); - if ((p = getenv("HOME"))) { - char home[MaxPathLen]; + if(ret == 0) + ret = kafs_settoken(cell, uid, &c); + return ret; +} - if (k_concat(home, sizeof(home), p, "/.TheseCells", NULL) == 0) - k_find_cells(home, cells, num_cells, &index); - } - k_find_cells(_PATH_THESECELLS, cells, num_cells, &index); - k_find_cells(_PATH_THISCELL, cells, num_cells, &index); - - err = k_afslog_cells(cells, index, krealm, uid); - while(index > 0) - free(cells[--index]); - return err; +static char * +get_realm(kafs_data *data, const char *host) +{ + char *r = krb_realmofhost(host); + if(r) + return strdup(r); + return NULL; } int -k_afsklog_uid(const char *cell, const char *krealm, uid_t uid) +krb_afslog_uid(const char *cell, const char *realm, uid_t uid) { - int k_errno; - CREDENTIALS c; - KTEXT_ST ticket; - char realm[REALM_SZ]; - char *vl_realm; /* realm of vl-server */ - char *lrealm; /* local realm */ - char CELL[64]; - - if (cell == 0 || cell[0] == 0) - return k_afsklog_all_local_cells (krealm, uid); - foldup(CELL, cell); - - k_errno = krb_get_lrealm(realm , 0); - if(k_errno == KSUCCESS && (krealm == NULL || strcmp(krealm, realm))) - lrealm = realm; - else - lrealm = NULL; - - /* We're about to find the the realm that holds the key for afs in - * the specified cell. The problem is that null-instance - * afs-principals are common and that hitting the wrong realm might - * yield the wrong afs key. The following assumptions were made. - * - * Any realm passed to us is preferred. - * - * If there is a realm with the same name as the cell, it is most - * likely the correct realm to talk to. - * - * In most (maybe even all) cases the database servers of the cell - * will live in the realm we are looking for. - * - * Try the local realm, but if the previous cases fail, this is - * really a long shot. - * - */ - - /* comments on the ordering of these tests */ - - /* If the user passes a realm, she probably knows something we don't - * know and we should try afs@krealm (otherwise we're talking with a - * blondino and she might as well have it.) - */ - - k_errno = -1; - if(krealm){ - k_errno = get_cred(AUTH_SUPERUSER, cell, krealm, &c, &ticket); - if(k_errno) - k_errno = get_cred(AUTH_SUPERUSER, "", krealm, &c, &ticket); - } - - if(k_errno) - k_errno = get_cred(AUTH_SUPERUSER, cell, CELL, &c, &ticket); - if(k_errno) - k_errno = get_cred(AUTH_SUPERUSER, "", CELL, &c, &ticket); - - /* this might work in some conditions */ - if(k_errno && (vl_realm = realm_of_cell(cell))){ - k_errno = get_cred(AUTH_SUPERUSER, cell, vl_realm, &c, &ticket); - if(k_errno) - k_errno = get_cred(AUTH_SUPERUSER, "", vl_realm, &c, &ticket); - } - - if(k_errno && lrealm){ - k_errno = get_cred(AUTH_SUPERUSER, cell, lrealm, &c, &ticket); -#if 0 - /* this is most likely never right anyway, but won't fail */ - if(k_errno) - k_errno = get_cred(AUTH_SUPERUSER, "", lrealm, &c, &ticket); -#endif - } - - if (k_errno == KSUCCESS) - { - struct ViceIoctl parms; - struct ClearToken ct; - int32_t sizeof_x; - char buf[2048], *t; - - /* - * Build a struct ClearToken - */ - ct.AuthHandle = c.kvno; - memcpy (ct.HandShakeKey, c.session, sizeof(c.session)); - ct.ViceId = uid; /* is this always valid? */ - ct.BeginTimestamp = 1 + c.issue_date; - ct.EndTimestamp = krb_life_to_time(c.issue_date, c.lifetime); - -#define ODD(x) ((x) & 1) - /* If we don't know the numerical ID lifetime should be even? */ - if (uid == 0 && ODD(ct.EndTimestamp - ct.BeginTimestamp)) - ct.BeginTimestamp--; - - t = buf; - /* - * length of secret token followed by secret token - */ - sizeof_x = c.ticket_st.length; - memcpy(t, &sizeof_x, sizeof(sizeof_x)); - t += sizeof(sizeof_x); - memcpy(t, c.ticket_st.dat, sizeof_x); - t += sizeof_x; - /* - * length of clear token followed by clear token - */ - sizeof_x = sizeof(ct); - memcpy(t, &sizeof_x, sizeof(sizeof_x)); - t += sizeof(sizeof_x); - memcpy(t, &ct, sizeof_x); - t += sizeof_x; - - /* - * do *not* mark as primary cell - */ - sizeof_x = 0; - memcpy(t, &sizeof_x, sizeof(sizeof_x)); - t += sizeof(sizeof_x); - /* - * follow with cell name - */ - sizeof_x = strlen(cell) + 1; - memcpy(t, cell, sizeof_x); - t += sizeof_x; - - /* - * Build argument block - */ - parms.in = buf; - parms.in_size = t - buf; - parms.out = 0; - parms.out_size = 0; - k_pioctl(0, VIOCSETTOK, &parms, 0); - } - return k_errno; + kafs_data kd; + struct krb_kafs_data d; + kd.afslog_uid = afslog_uid_int; + kd.get_cred = get_cred; + kd.get_realm = get_realm; + kd.data = &d; + d.realm = realm; + return afslog_uid_int(&kd, cell, uid); } int -k_afsklog(const char *cell, const char *krealm) +krb_afslog(const char *cell, const char *realm) { - return k_afsklog_uid (cell, krealm, getuid()); + return krb_afslog_uid (cell, realm, getuid()); } diff --git a/lib/kafs/afskrb5.c b/lib/kafs/afskrb5.c index ae5a947f7..66d8ae530 100644 --- a/lib/kafs/afskrb5.c +++ b/lib/kafs/afskrb5.c @@ -40,352 +40,98 @@ RCSID("$Id$"); -#define AUTH_SUPERUSER "afs" +struct krb5_kafs_data { + krb5_context context; + krb5_ccache id; + krb5_const_realm realm; +}; -/* - * Here only ASCII characters are relevant. - */ - -#define IsAsciiLower(c) ('a' <= (c) && (c) <= 'z') - -#define ToAsciiUpper(c) ((c) - 'a' + 'A') - -static void -foldup(char *a, const char *b) -{ - for (; *b; a++, b++) - if (IsAsciiLower(*b)) - *a = ToAsciiUpper(*b); - else - *a = *b; - *a = '\0'; -} - -static krb5_error_code -get_cred(krb5_context context, krb5_ccache id, - const char *name, const char *inst, const char *krealm, - CREDENTIALS *c) +static int +get_cred(kafs_data *data, const char *name, const char *inst, + const char *realm, CREDENTIALS *c) { krb5_error_code ret; krb5_creds in_creds, *out_creds; + struct krb5_kafs_data *d = data->data; memset(&in_creds, 0, sizeof(in_creds)); - ret = krb5_425_conv_principal(context, name, inst, krealm, + ret = krb5_425_conv_principal(d->context, name, inst, realm, &in_creds.server); if(ret) return ret; - ret = krb5_cc_get_principal(context, id, &in_creds.client); + ret = krb5_cc_get_principal(d->context, d->id, &in_creds.client); if(ret){ - krb5_free_principal(context, in_creds.server); + krb5_free_principal(d->context, in_creds.server); return ret; } - ret = krb5_get_credentials(context, 0, id, &in_creds, &out_creds); - krb5_free_principal(context, in_creds.server); - krb5_free_principal(context, in_creds.client); + ret = krb5_get_credentials(d->context, 0, d->id, &in_creds, &out_creds); + krb5_free_principal(d->context, in_creds.server); + krb5_free_principal(d->context, in_creds.client); if(ret) return ret; - ret = krb524_convert_creds_kdc(context, out_creds, c); - krb5_free_creds(context, out_creds); + ret = krb524_convert_creds_kdc(d->context, out_creds, c); + krb5_free_creds(d->context, out_creds); return ret; } - -/* Convert a string to a 32 bit ip number in network byte order. - Return 0 on error - */ - -static u_int32_t -ip_aton(char *ip) -{ - u_int32_t addr; - unsigned int a, b, c, d; - - if(sscanf(ip, "%u.%u.%u.%u", &a, &b, &c, &d) != 4) - return 0; - if((a | b | c | d) > 255) - return 0; - addr = (a << 24) | (b << 16) | (c << 8) | d; - addr = htonl(addr); - return addr; -} - -#if 0 -/* Try to get a db-server for an AFS cell from a AFSDB record */ - -static int -dns_find_cell(const char *cell, char *dbserver) -{ - struct dns_reply *r; - int ok = -1; - r = dns_lookup(cell, "afsdb"); - if(r){ - struct resource_record *rr = r->head; - while(rr){ - if(rr->type == T_AFSDB && rr->u.afsdb->preference == 1){ - strncpy(dbserver, rr->u.afsdb->domain, MaxHostNameLen); - dbserver[MaxHostNameLen - 1] = 0; - ok = 0; - break; - } - rr = rr->next; - } - dns_free_data(r); - } - return ok; -} -#endif - - -/* Find the realm associated with cell. Do this by opening - /usr/vice/etc/CellServDB and getting the realm-of-host for the - first VL-server for the cell. - - This does not work when the VL-server is living in one realm, but - the cell it is serving is living in another realm. - */ - -static krb5_error_code -realm_of_cell(krb5_context context, const char *cell, krb5_realm *realm) -{ - FILE *F; - char buf[1024]; - krb5_realm *realms; - char *p; - krb5_error_code ret = -1; - - if((F = fopen(_PATH_CELLSERVDB, "r"))){ - while(fgets(buf, sizeof(buf), F)){ - if(buf[0] != '>') - continue; - if(strncmp(buf + 1, cell, strlen(cell)) == 0){ - if(fgets(buf, sizeof(buf), F) == NULL) - break; - p = strchr(buf, '#'); - if(p == NULL) - break; - p++; - if(buf[strlen(buf) - 1] == '\n') - buf[strlen(buf) - 1] = 0; - ret = krb5_get_host_realm(context, p, &realms); - *realm = strdup(realms[0]); - krb5_free_host_realm(context, realms); - break; - } - } - fclose(F); - } -#if 0 - if(realm == NULL){ - if(dns_find_cell(cell, buf) == 0) - realm = krb_realmofhost(buf); - } -#endif - return ret; -} - -/* - * Get tokens for all cells[] - */ -static krb5_error_code -k5_afslog_cells(krb5_context context, krb5_ccache id, - char *cells[], int max, krb5_const_realm realm, uid_t uid) -{ - krb5_error_code ret = 0; - int i; - for(i = 0; i < max; i++) - ret = k5_afsklog_uid(context, id, cells[i], realm, uid); - return ret; -} - -/* - * Try to find the cells we should try to klog to in "file". - */ -static void -k_find_cells(char *file, char *cells[], int size, int *index) -{ - FILE *f; - char cell[64]; - int i; - f = fopen(file, "r"); - if (f == NULL) - return; - while (*index < size && fgets(cell, sizeof(cell), f)) { - char *nl = strchr(cell, '\n'); - if (nl) *nl = 0; - for(i = 0; i < *index; i++) - if(strcmp(cells[i], cell) == 0) - break; - if(i == *index) - cells[(*index)++] = strdup(cell); - } - fclose(f); -} - static krb5_error_code -k5_afsklog_all_local_cells(krb5_context context, krb5_ccache id, - krb5_const_realm realm, uid_t uid) +afslog_uid_int(kafs_data *data, const char *cell, uid_t uid) { - krb5_error_code ret; - char *cells[32]; /* XXX */ - int num_cells = sizeof(cells) / sizeof(cells[0]); - int index = 0; - - char *p; - - if ((p = getenv("HOME"))) { - char home[MaxPathLen]; - - if (k_concat(home, sizeof(home), p, "/.TheseCells", NULL) == 0) - k_find_cells(home, cells, num_cells, &index); - } - k_find_cells(_PATH_THESECELLS, cells, num_cells, &index); - k_find_cells(_PATH_THISCELL, cells, num_cells, &index); - - ret = k5_afslog_cells(context, id, cells, index, realm, uid); - while(index > 0) - free(cells[--index]); - return ret; -} - -krb5_error_code -k5_afsklog_uid(krb5_context context, krb5_ccache id, - const char *cell, krb5_const_realm krealm, uid_t uid) -{ - int k_errno; krb5_error_code ret; CREDENTIALS c; - krb5_realm vl_realm; /* realm of vl-server */ krb5_realm lrealm; /* local realm */ - char CELL[64]; - + struct krb5_kafs_data *d = data->data; + if (cell == 0 || cell[0] == 0) - return k5_afsklog_all_local_cells (context, id, krealm, uid); - foldup(CELL, cell); + return _kafs_afslog_all_local_cells (data, uid); - ret = krb5_get_default_realm(context, &lrealm); - if(ret || (krealm && strcmp(krealm, lrealm) == 0)){ + ret = krb5_get_default_realm(d->context, &lrealm); + if(ret || (d->realm && strcmp(d->realm, lrealm) == 0)){ free(lrealm); lrealm = NULL; } - /* We're about to find the the realm that holds the key for afs in - * the specified cell. The problem is that null-instance - * afs-principals are common and that hitting the wrong realm might - * yield the wrong afs key. The following assumptions were made. - * - * Any realm passed to us is preferred. - * - * If there is a realm with the same name as the cell, it is most - * likely the correct realm to talk to. - * - * In most (maybe even all) cases the database servers of the cell - * will live in the realm we are looking for. - * - * Try the local realm, but if the previous cases fail, this is - * really a long shot. - * - */ - - /* comments on the ordering of these tests */ - - /* If the user passes a realm, she probably knows something we don't - * know and we should try afs@krealm (otherwise we're talking with a - * blondino and she might as well have it.) - */ - - ret = -1; - if(krealm){ - ret = get_cred(context, id, AUTH_SUPERUSER, cell, krealm, &c); - if(ret) - ret = get_cred(context, id, AUTH_SUPERUSER, "", krealm, &c); - } - - if(ret) - ret = get_cred(context, id, AUTH_SUPERUSER, cell, CELL, &c); - if(ret) - ret = get_cred(context, id, AUTH_SUPERUSER, "", CELL, &c); - - /* this might work in some cases */ - if(ret){ - if(realm_of_cell(context, cell, &vl_realm) == 0){ - ret = get_cred(context, id, AUTH_SUPERUSER, cell, vl_realm, &c); - if(ret) - ret = get_cred(context, id, AUTH_SUPERUSER, "", vl_realm, &c); - free(vl_realm); - } - } - - if(ret && lrealm) - ret = get_cred(context, id, AUTH_SUPERUSER, cell, lrealm, &c); + ret = _kafs_get_cred(data, cell, d->realm, lrealm, &c); if(lrealm) free(lrealm); - if (ret == 0){ - struct ViceIoctl parms; - struct ClearToken ct; - int32_t sizeof_x; - char buf[2048], *t; + if(ret == 0) + ret = kafs_settoken(cell, uid, &c); + return ret; +} - /* - * Build a struct ClearToken - */ - ct.AuthHandle = c.kvno; - memcpy (ct.HandShakeKey, c.session, sizeof(c.session)); - ct.ViceId = uid; /* is this always valid? */ - ct.BeginTimestamp = 1 + c.issue_date; - ct.EndTimestamp = krb_life_to_time(c.issue_date, c.lifetime); - -#define ODD(x) ((x) & 1) - /* If we don't know the numerical ID lifetime should be even? */ - if (uid == 0 && ODD(ct.EndTimestamp - ct.BeginTimestamp)) - ct.BeginTimestamp--; - - t = buf; - /* - * length of secret token followed by secret token - */ - sizeof_x = c.ticket_st.length; - memcpy(t, &sizeof_x, sizeof(sizeof_x)); - t += sizeof(sizeof_x); - memcpy(t, c.ticket_st.dat, sizeof_x); - t += sizeof_x; - /* - * length of clear token followed by clear token - */ - sizeof_x = sizeof(ct); - memcpy(t, &sizeof_x, sizeof(sizeof_x)); - t += sizeof(sizeof_x); - memcpy(t, &ct, sizeof_x); - t += sizeof_x; - - /* - * do *not* mark as primary cell - */ - sizeof_x = 0; - memcpy(t, &sizeof_x, sizeof(sizeof_x)); - t += sizeof(sizeof_x); - /* - * follow with cell name - */ - sizeof_x = strlen(cell) + 1; - memcpy(t, cell, sizeof_x); - t += sizeof_x; - - /* - * Build argument block - */ - parms.in = buf; - parms.in_size = t - buf; - parms.out = 0; - parms.out_size = 0; - k_pioctl(0, VIOCSETTOK, &parms, 0); - } - return k_errno; +static char * +get_realm(kafs_data *data, const char *host) +{ + struct krb5_kafs_data *d = data->data; + krb5_realm *realms; + char *r; + if(krb5_get_host_realm(d->context, host, &realms)) + return NULL; + r = strdup(realms[0]); + krb5_free_host_realm(d->context, realms); + return r; } krb5_error_code -k5_afsklog(krb5_context context, krb5_ccache id, - const char *cell, krb5_const_realm realm) +krb5_afslog_uid(krb5_context context, krb5_ccache id, + const char *cell, krb5_const_realm realm, uid_t uid) { - return k5_afsklog_uid (context, id, cell, realm, getuid()); + kafs_data kd; + struct krb5_kafs_data d; + kd.afslog_uid = afslog_uid_int; + kd.get_cred = get_cred; + kd.get_realm = get_realm; + kd.data = &d; + d.context = context; + d.id = id; + d.realm = realm; + return afslog_uid_int(&kd, cell, uid); +} + +krb5_error_code +krb5_afslog(krb5_context context, krb5_ccache id, + const char *cell, krb5_const_realm realm) +{ + return krb5_afslog_uid (context, id, cell, realm, getuid()); }