Exemplo n.º 1
0
/*
 * Convert 'identifier' into canonical form.
 * Returns a pointer to a static buffer containing the canonical form
 * or NULL if 'identifier' is invalid.
 */
static char *afspts_canonifyid(const char *identifier, size_t len)
{
    static char retbuf[MAX_K_NAME_SZ+1];
    char aname[ANAME_SZ];
    char inst[INST_SZ];
    char realm[REALM_SZ];
    char lrealm[REALM_SZ];
    char krbhst[MAX_HSTNM];
    char *canon_buf;
    char *p;

    if(!len) len = strlen(identifier);

    canon_buf = xmalloc(len + 1);
    memcpy(canon_buf, identifier, len);
    canon_buf[len] = '\0';

    aname[0] = inst[0] = realm[0] = '\0';
    if (kname_parse(aname, inst, realm, canon_buf) != 0) {
        free(canon_buf);
        return 0;
    }

    free(canon_buf);

    /* Upcase realm name */
    for (p = realm; *p; p++) {
        if (Uislower(*p)) *p = toupper(*p);
    }

    if (*realm) {
        if (krb_get_lrealm(lrealm,1) == 0 &&
                strcmp(lrealm, realm) == 0) {
            *realm = 0;
        }
        else if (krb_get_krbhst(krbhst, realm, 1)) {
            return 0;           /* Unknown realm */
        }
    }

    /* Check for krb.equiv remappings. */
    p = auth_map_krbid(aname, inst, realm);
    if (p) {
        strcpy(retbuf, p);
        return retbuf;
    }

    strcpy(retbuf, aname);
    if (*inst) {
        strcat(retbuf, ".");
        strcat(retbuf, inst);
    }
    if (*realm && !is_local_realm(realm)) {
        strcat(retbuf, "@");
        strcat(retbuf, realm);
    }

    return retbuf;
}
Exemplo n.º 2
0
void CKrb4RealmHostMaintenance::ResetDefaultRealmComboBox()
{ // krb4 is loaded without krb5
	CHAR lineBuf[REALM_SZ + MAX_HSTNM + 20];

	int maxItems = m_RealmHostList.GetCount();

	CKrbConfigOptions::m_krbRealmEditbox.ResetContent();

	for (int xItems = 0; xItems < maxItems; xItems++)
	{
		m_RealmHostList.GetText(xItems, lineBuf);

		LPSTR space = strchr(lineBuf, ' ');
		if (space)
		  *space = 0;
		else
		  ASSERT(0);

		if (CB_ERR == CKrbConfigOptions::m_krbRealmEditbox.FindStringExact(-1, lineBuf))
		{ // no dups
			if (LB_ERR == CKrbConfigOptions::m_krbRealmEditbox.AddString(lineBuf))
			{
				MessageBox("OnInitDialog::Can't add to Kerberos Realm Combobox",
						   "Leash", MB_OK);
				return;
			}
		}
	}

	CHAR krbhst[MAX_HSTNM + 1];
	CHAR krbrlm[REALM_SZ + 1];

	strcpy(krbrlm, CKrbConfigOptions::m_newDefaultRealm);
	memset(krbhst, '\0', sizeof(krbhst));

	// Check for Host
	// don't use KRB4 - krb_get_krbhst - would have to re-logon, on file location
	// change, to use this function
	extern int krb_get_krbhst(char* h, char* r, int n);
	if (KFAILURE == krb_get_krbhst(krbhst, krbrlm, 1))
	{
		MessageBox("We can't find the Host Server for your Default Realm!!!",
                    "Leash", MB_OK);
		return;
	}

	CKrbConfigOptions::m_hostServer = krbhst;
}
Exemplo n.º 3
0
/*
 * Map a remote kerberos principal to a local username.  If a mapping
 * is found, a pointer to the local username is returned.  Otherwise,
 * a NULL pointer is returned.
 * Eventually, this may be more sophisticated than a simple file scan.
 */
static char *auth_map_krbid(const char *real_aname,
                            const char *real_inst,
                            const char *real_realm)
{
    static char localuser[MAX_K_NAME_SZ + 1];
    char principal[MAX_K_NAME_SZ + 1];
    char aname[ANAME_SZ];
    char inst[INST_SZ];
    char realm[REALM_SZ];
    char lrealm[REALM_SZ];
    char krbhst[MAX_HSTNM];
    char *p;
    char buf[1024];
    FILE *mapfile;

    if (!(mapfile = fopen(KRB_MAPNAME, "r"))) {
        /* If the file can't be opened, don't do mappings */
        return 0;
    }

    for (;;) {
        if (!fgets(buf, sizeof(buf), mapfile)) break;
        if (parse_krbequiv_line(buf, principal, localuser) == 0 ||
                kname_parse(aname, inst, realm, principal) != 0) {
            /* Ignore badly formed lines */
            continue;
        }
        if (!strcmp(aname, real_aname) && !strcmp(inst, real_inst) &&
                !strcmp(realm, real_realm)) {
            fclose(mapfile);

            aname[0] = inst[0] = realm[0] = '\0';
            if (kname_parse(aname, inst, realm, localuser) != 0) {
                return 0;
            }

            /* Upcase realm name */
            for (p = realm; *p; p++) {
                if (Uislower(*p)) *p = toupper(*p);
            }

            if (*realm) {
                if (krb_get_lrealm(lrealm,1) == 0 &&
                        strcmp(lrealm, realm) == 0) {
                    *realm = 0;
                }
                else if (krb_get_krbhst(krbhst, realm, 1)) {
                    return 0;           /* Unknown realm */
                }
            }

            strcpy(localuser, aname);
            if (*inst) {
                strcat(localuser, ".");
                strcat(localuser, inst);
            }
            if (*realm) {
                strcat(localuser, "@");
                strcat(localuser, realm);
            }

            return localuser;
        }
    }

    fclose(mapfile);
    return 0;
}
Exemplo n.º 4
0
int
krb4int_send_to_kdc_addr(
    KTEXT pkt, KTEXT rpkt, char *realm,
    struct sockaddr *addr, socklen_t *addrlen)
{
    struct addrlist	al = ADDRLIST_INIT;
    char		lrealm[REALM_SZ];
    krb5int_access	internals;
    krb5_error_code	retval;
    struct servent	*sp;
    int			krb_udp_port = 0;
    int			krbsec_udp_port = 0;
    char		krbhst[MAXHOSTNAMELEN];
    char		*scol;
    int			i;
    int			err;
    krb5_data		message, reply;

    /*
     * If "realm" is non-null, use that, otherwise get the
     * local realm.
     */
    if (realm)
	strncpy(lrealm, realm, sizeof(lrealm) - 1);
    else {
	if (krb_get_lrealm(lrealm, 1)) {
	    DEB (("%s: can't get local realm\n", prog));
	    return SKDC_CANT;
	}
    }
    lrealm[sizeof(lrealm) - 1] = '\0';
    DEB (("lrealm is %s\n", lrealm));

    retval = krb5int_accessor(&internals, KRB5INT_ACCESS_VERSION);
    if (retval)
	return KFAILURE;

    /* The first time, decide what port to use for the KDC.  */
    if (cached_krb_udp_port == 0) {
	sp = getservbyname("kerberos","udp");
        if (sp)
	    cached_krb_udp_port = sp->s_port;
	else
	    cached_krb_udp_port = htons(KERBEROS_PORT); /* kerberos/udp */
        DEB (("cached_krb_udp_port is %d\n", cached_krb_udp_port));
    }
    /* If kerberos/udp isn't 750, try using kerberos-sec/udp (or 750) 
       as a fallback. */
    if (cached_krbsec_udp_port == 0 && 
	cached_krb_udp_port != htons(KERBEROS_PORT)) {
	sp = getservbyname("kerberos-sec","udp");
        if (sp)
	    cached_krbsec_udp_port = sp->s_port;
	else
	    cached_krbsec_udp_port = htons(KERBEROS_PORT); /* kerberos/udp */
        DEB (("cached_krbsec_udp_port is %d\n", cached_krbsec_udp_port));
    }

    for (i = 1; krb_get_krbhst(krbhst, lrealm, i) == KSUCCESS; ++i) {
#ifdef DEBUG
        if (krb_debug) {
            DEB (("Getting host entry for %s...",krbhst));
            (void) fflush(stdout);
        }
#endif
	if (0 != (scol = strchr(krbhst,':'))) {
	    krb_udp_port = htons(atoi(scol+1));
	    *scol = 0;
	    if (krb_udp_port == 0) {
#ifdef DEBUG
		if (krb_debug) {
		    DEB (("bad port number %s\n",scol+1));
		    (void) fflush(stdout);
		}
#endif
		continue;
	    }
	    krbsec_udp_port = 0;
	} else {
	    krb_udp_port = cached_krb_udp_port;
	    krbsec_udp_port = cached_krbsec_udp_port;
	}
        err = internals.add_host_to_list(&al, krbhst,
					 krb_udp_port, krbsec_udp_port,
					 SOCK_DGRAM, PF_INET);
	if (err) {
	    retval = SKDC_CANT;
	    goto free_al;
	}
    }
    if (al.naddrs == 0) {
	DEB (("%s: can't find any Kerberos host.\n", prog));
        retval = SKDC_CANT;
    }

    message.length = pkt->length;
    message.data = (char *)pkt->dat; /* XXX yuck */
    retval = internals.sendto_udp(NULL, &message, &al, NULL, &reply, addr,
				  addrlen, NULL, 0, NULL);
    DEB(("sendto_udp returns %d\n", retval));
free_al:
    internals.free_addrlist(&al);
    if (retval)
	return SKDC_CANT;
    DEB(("reply.length=%d\n", reply.length));
    if (reply.length > sizeof(rpkt->dat))
	retval = SKDC_CANT;
    rpkt->length = 0;
    if (!retval) {
	memcpy(rpkt->dat, reply.data, reply.length);
	rpkt->length = reply.length;
    }
    krb5_free_data_contents(NULL, &reply);
    return retval;
}
Exemplo n.º 5
0
/*
 * send_to_kdc() sends a message to the Kerberos authentication
 * server(s) in the given realm and returns the reply message.
 * The "pkt" argument points to the message to be sent to Kerberos;
 * the "rpkt" argument will be filled in with Kerberos' reply.
 * The "realm" argument indicates the realm of the Kerberos server(s)
 * to transact with.  If the realm is null, the local realm is used.
 *
 * If more than one Kerberos server is known for a given realm,
 * different servers will be queried until one of them replies.
 * Several attempts (retries) are made for each server before
 * giving up entirely.
 *
 * If an answer was received from a Kerberos host, KSUCCESS is
 * returned.  The following errors can be returned:
 *
 * SKDC_CANT    - can't get local realm
 *              - can't find "kerberos" in /etc/services database
 *              - can't open socket
 *              - can't bind socket
 *              - all ports in use
 *              - couldn't find any Kerberos host
 *
 * SKDC_RETRY   - couldn't get an answer from any Kerberos server,
 *                after several retries
 */
int
send_to_kdc(
    KTEXT pkt,
    KTEXT rpkt,
    char *realm
    )
{
    int i;
    SOCKET f = INVALID_SOCKET;
    int no_host; /* was a kerberos host found? */
    int retry;
    int n_hosts;
    int retval;
    struct sockaddr_in to;
    struct hostent *host, *hostlist, *fphost, *temp_hostlist;
    int *portlist, *temp_portlist;
    char *cp;
    char krbhst[MAX_HSTNM];
    char lrealm[REALM_SZ];

    hostlist = 0;
    portlist = 0;

    /*
     * If "realm" is non-null, use that, otherwise get the
     * local realm.
     */                      

    if (realm && realm[0]) {
	strncpy(lrealm, realm, REALM_SZ);
        lrealm[REALM_SZ] = 0;
    }
    else
	if (krb_get_lrealm(lrealm, 1)) {
	    if (krb_debug)
		kdebug("%s: can't get local realm\n", prog);
	    return(SKDC_CANT);
	}
    if (krb_debug)
	kdebug("lrealm is %s\n", lrealm);

    if (krb_udp_port_conf == 0) {
	register struct servent FAR *sp;
        if (sp = getservbyname("kerberos", "udp")) {
            krb_udp_port_conf = sp->s_port;
        } else if (KRB_PORT) {
            if (krb_debug)
                kdebug("%s: Can't get kerberos/udp service -- "
                       "using default port\n", prog);
            krb_udp_port_conf = htons(KRB_PORT);
        } else {
            if (krb_debug)
                kdebug("%s: Can't get kerberos/udp service at all\n", prog);
            return(SKDC_CANT);
        }
        if (krb_debug)
            kdebug("krb_udp_port_conf is %d\n", ntohs(krb_udp_port_conf));
    }

    /* from now on, exit through rtn label for cleanup */

    memset((char *)&to, 0, S_AD_SZ);
    hostlist = (struct hostent *) malloc(sizeof(struct hostent));
    if (!hostlist) {
        retval = SKDC_CANT;
        goto rtn;
    }
    memset(hostlist, 0, sizeof(struct hostent));

    f = socket(AF_INET, SOCK_DGRAM, 0);
    if (f == INVALID_SOCKET) {
        if (krb_debug)
            kdebug("%s: Can't open socket (error %d)\n", prog, 
                   WSAGetLastError());
        retval = SKDC_CANT;
        goto rtn;
    }

    /* make the socket non-blocking */
    {
        u_long onOff = TRUE;
        if (ioctlsocket(f, FIONBIO, (u_long FAR*)&onOff))
        {
            if (krb_debug)
                kdebug("%s: Can't make socket non-blocking (error %d)\n", 
                       prog, WSAGetLastError());
            retval = SKDC_CANT;
            goto rtn;
        }
    }

    /*
    ** FTP Software's WINSOCK implmentation insists that
    ** a socket be bound before it can receive datagrams.
    ** This is outside specs.  Since it shouldn't hurt any
    ** other implementations we'll go ahead and do it for
    ** now.
    */
    {
	struct sockaddr_in from;
	memset ((char *)&from, 0, S_AD_SZ);
	from.sin_family = AF_INET;
	from.sin_addr.s_addr = INADDR_ANY;
	if ( bind(f, (struct sockaddr *)&from, S_AD_SZ) == SOCKET_ERROR ) {
	    if (krb_debug)
                kdebug("%s : Can't bind\n", prog);
	    retval = SKDC_CANT;
	    goto rtn;
	}
    }
    /* End of kludge for FTP Software WinSock stack.  */

    no_host = 1;
    /* get an initial allocation */
    n_hosts = 0;
    for (i = 1; krb_get_krbhst(krbhst, lrealm, i) == KSUCCESS; ++i) {
#ifdef USE_DNS
        int krb_udp_port = krb_udp_port_dns?krb_udp_port_dns:krb_udp_port_conf;
        if (krb_debug) {
            kdebug("krb_udp_port is %d\n", ntohs(krb_udp_port));
        }
#else /* !USE_DNS */
        int krb_udp_port = krb_udp_port_conf;
#endif /* !USE_DNS */
        if (krb_debug) {
            kdebug("Getting host entry for %s...", krbhst);
        }
        fphost = /* host = */ GETHOSTBYNAME(krbhst);
        if (krb_debug) {
            kdebug("%s.\n",
                   fphost ? "Got it" : "Didn't get it");
        }
        if (!fphost){
            continue;
        }    
        no_host = 0;    /* found at least one */
        n_hosts++;
        /* preserve host network address to check later
         * (would be better to preserve *all* addresses,
         * take care of that later)
         */
        temp_portlist = portlist;
        portlist = (int *) realloc(portlist, n_hosts*sizeof(int));
        if (!portlist) {
            portlist = temp_portlist;
            retval = SKDC_CANT;
            goto rtn;
        }
        portlist[n_hosts-1] = krb_udp_port;

        temp_hostlist = hostlist;
        hostlist = (struct hostent *)
            realloc((char *)hostlist,
                    (unsigned)
                    sizeof(struct hostent)*(n_hosts+1));
        if (!hostlist){
            hostlist = temp_hostlist;
            retval = SKDC_CANT;
            goto rtn;
        }
        hostlist[n_hosts-1] = *fphost;
        memset(&hostlist[n_hosts], 0, sizeof(struct hostent));
        host = &hostlist[n_hosts-1];
        cp = (char*)malloc((unsigned)host->h_length);
        if (!cp) {
            retval = SKDC_CANT;
            goto rtn;
        }
        memcpy(cp, host->h_addr, host->h_length);
        host->h_addr_list = (char **)malloc(sizeof(char *));
        if (!host->h_addr_list) {
            retval = SKDC_CANT;
            goto rtn;
        }
        host->h_addr = cp;
        to.sin_family = host->h_addrtype;
        memcpy((char *)&to.sin_addr, host->h_addr, 
	       host->h_length);
        to.sin_port = krb_udp_port;
        if (send_recv(pkt, rpkt, f, &to, hostlist)) {
            retval = KSUCCESS;
            goto rtn;
        }
        if (krb_debug) {
            kdebug("Timeout, error, or wrong descriptor\n");
        }
    }
    if (no_host) {
        if (krb_debug)
            kdebug("%s: can't find any Kerberos host.\n", prog);
        retval = SKDC_CANT;
        goto rtn;
    }
    /* retry each host in sequence */
    for (retry = 0; retry < CLIENT_KRB_RETRY; ++retry) {
        i = 0;
        for (host = hostlist; host->h_name != 0; host++) {
            to.sin_family = host->h_addrtype;
            to.sin_port = portlist[i++];
            memcpy((char *)&to.sin_addr, host->h_addr, 
		   host->h_length);
            if (send_recv(pkt, rpkt, f, &to, hostlist)) {
                retval = KSUCCESS;
                goto rtn;
            }
        }
    }
    retval = SKDC_RETRY;

 rtn:
    if (f != INVALID_SOCKET)
        if (closesocket(f) == SOCKET_ERROR)
            if (krb_debug)
                kdebug("%s: Could not close socket (error %d)\n",
                       prog, WSAGetLastError());
    if (hostlist) {
        register struct hostent *hp;
        for (hp = hostlist; hp->h_name; hp++)
            if (hp->h_addr_list) {
                if (hp->h_addr)
                    free(hp->h_addr);
                free(hp->h_addr_list);
            }
        free(hostlist);
    }
    if (portlist)
        free(portlist);
    return(retval);
}