Esempio n. 1
0
int rkinit(char *host, char *r_krealm, rkinit_info *info, int timeout)
{
    int status;
    int version = 0;
    char phost[MAXHOSTNAMELEN];
    jmp_buf timeout_env;
    struct sigaction osa;
    char origtktfilename[MAXPATHLEN]; /* original ticket file name */
    char tktfilename[MAXPATHLEN]; /* temporary client ticket file */

    BCLEAR(phost);
    BCLEAR(origtktfilename);
    BCLEAR(tktfilename);
    BCLEAR(timeout_env);

    initialize_rkin_error_table();

    status = rki_setup_rpc(host);
    if (status)
	return(status);

    /* The alarm handler longjmps us to here. */
    status = setjmp(timeout_env);
    if (status == 0) {
	strcpy(origtktfilename, tkt_string());
	sprintf(tktfilename, "/tmp/tkt_rkinit.%lu", (unsigned long)getpid());
	krb_set_tkt_string(tktfilename);

	if (timeout)
	    rki_setup_timer(timeout_env, &osa);

	status = rki_choose_version(&version);
	if (status == RKINIT_SUCCESS)
	    status = rki_get_tickets(version, host, r_krealm, info);
    }

    if (timeout)
	rki_restore_timer(&osa);

    dest_tkt();
    krb_set_tkt_string(origtktfilename);

    rki_cleanup_rpc();

    return(status);
}
Esempio n. 2
0
char *rkinit_errmsg(char *string)
{
    static char errmsg[BUFSIZ];

    if (string) {
	BCLEAR(errmsg);
	strncpy(errmsg, string, sizeof(errmsg) - 1);
    }

    return(errmsg);
}
Esempio n. 3
0
static void this_phost(char *host, int hostlen)
{
    char this_host[MAXHOSTNAMELEN + 1];

    BCLEAR(this_host);

    if (gethostname(this_host, sizeof(this_host)) < 0) {
	sprintf(errbuf, "gethostname: %s", strerror(errno));
	rkinit_errmsg(errbuf);
	error();
	exit(1);
    }

    strncpy(host, krb_get_phost(this_host), hostlen - 1);
}
Esempio n. 4
0
static int decrypt_tkt(char *user, char *instance, char *realm, char *arg,
		       int (*key_proc)(char *, char *, char *,
				       char *, C_Block),
		       KTEXT *cipp)
{
    MSG_DAT msg_data;		/* Message data containing decrypted data */
    KTEXT_ST auth;		/* Authenticator */
    AUTH_DAT auth_dat;		/* Authentication data */
    KTEXT cip = *cipp;
    MSG_DAT scip;
    int status = 0;
    des_cblock key;
    des_key_schedule sched;
    char phost[MAXHOSTNAMELEN + 1];
    struct sockaddr_in caddr;	/* client internet address */
    struct sockaddr_in saddr;	/* server internet address */

    rkinitd_intkt_info *rii = (rkinitd_intkt_info *)arg;

    u_char enc_data[MAX_KTXT_LEN];

    SBCLEAR(auth);
    SBCLEAR(auth_dat);
    SBCLEAR(scip);
    BCLEAR(enc_data);

    scip.app_data = enc_data;

    /*
     * Exchange with the client our response from the KDC (ticket encrypted
     * in user's private key) for the same ticket encrypted in our
     * (not yet known) session key.
     */

    rpc_exchange_tkt(cip, &scip);

    /*
     * Get the authenticator
     */

    SBCLEAR(auth);

    rpc_getauth(&auth, &caddr, &saddr);

    /*
     * Decode authenticator and extract session key.  The first zero
     * means we don't care what host this comes from.  This needs to
     * be done with euid of root so that /etc/srvtab can be read.
     */

    BCLEAR(phost);
    this_phost(phost, sizeof(phost));

    /*
     * This function has to use longjmp to return to the caller
     * because the kerberos library routine that calls it doesn't
     * pay attention to the return value it gives.  That means that
     * if any of these routines failed, the error returned to the client
     * would be "password incorrect".
     */

    status = krb_rd_req(&auth, KEY, phost, caddr.sin_addr.s_addr,
			    &auth_dat, "");
    if (status) {
	sprintf(errbuf, "krb_rd_req: %s", krb_err_txt[status]);
	rkinit_errmsg(errbuf);
	longjmp(rii->env, status);
    }

    memcpy(key, auth_dat.session, sizeof(key));
    if (des_key_sched(key, sched)) {
	sprintf(errbuf, "Error in des_key_sched");
	rkinit_errmsg(errbuf);
	longjmp(rii->env, RKINIT_DES);
    }

    /* Decrypt the data. */
    if ((status =
	 krb_rd_priv((u_char *)scip.app_data, scip.app_length,
		     sched, key, &caddr, &saddr, &msg_data)) == KSUCCESS) {
	cip->length = msg_data.app_length;
	memcpy(cip->dat, msg_data.app_data, msg_data.app_length);
	cip->dat[cip->length] = 0;
    }
    else {
	sprintf(errbuf, "krb_rd_priv: %s", krb_err_txt[status]);
	rkinit_errmsg(errbuf);
	longjmp(rii->env, status);
    }
    if (setuid(user_id) < 0) {
	sprintf(errbuf,	"Failure setting uid to %lu: %s\n",
		(unsigned long)user_id, strerror(errno));
	rkinit_errmsg(errbuf);
	longjmp(rii->env, RKINIT_DAEMON);
    }
    return(KSUCCESS);
}
Esempio n. 5
0
int get_tickets(int version)
{
    rkinit_info info;
    AUTH_DAT auth_dat;

    int status;
    char errmsg[BUFSIZ];	/* error message for client */

    rkinitd_intkt_info rii;

    SBCLEAR(info);
    SBCLEAR(auth_dat);
    BCLEAR(errmsg);
    SBCLEAR(rii);

    rpc_get_rkinit_info(&info);

    /*
     * The validate_user routine makes sure that the principal in question
     * is allowed to log in as username, and if so, does a setuid(localuid).
     * If there is an access violation or an error in setting the uid,
     * an error is returned and the string errmsg is initialized with
     * an error message that will be sent back to the client.
     */
    status = validate_user(info.aname, info.inst, info.realm,
			   info.username, errmsg);
    if (status != RKINIT_SUCCESS) {
	rpc_send_error(errmsg);
	exit(0);
    }
    else
	rpc_send_success();

    /*
     * If the name of a ticket file was specified, set it; otherwise,
     * just use the default.
     */
    if (strlen(info.tktfilename))
	krb_set_tkt_string(info.tktfilename);

    /*
     * Call internal kerberos library routine so that we can supply
     * our own ticket decryption routine.
     */

    /*
     * We need a setjmp here because krb_get_in_tkt ignores the
     * return value of decrypt_tkt.  Thus if we want any of its
     * return values to reach the client, we have to jump out of
     * the routine.
     */

    if (setjmp(rii.env) == 0) {
	status = krb_get_in_tkt(info.aname, info.inst, info.realm,
				info.sname, info.sinst, info.lifetime,
				NULL, decrypt_tkt, (char *)&rii);
	if (status) {
	    strcpy(errmsg, krb_err_txt[status]);
	    rpc_send_error(errmsg);
	}
	else
	    rpc_send_success();
    }
    else
	rpc_send_error(errbuf);

    return(RKINIT_SUCCESS);
}
Esempio n. 6
0
static void
backtrack(struct saucy_stats *stats)
{
	int i, j, k, t, indx, lastnon;

	/* Keep backtracking for a while */
	do {
		/* Back up from this spot to our ancestor with zeta */
		for (--lev; lev > 0; --lev) {
			BCLEAR(bit_fixed, fixed[lev]);
			if (flag && (lev > anc)) continue;
			break;
		}

		/* If we're at the top, quit */
		if (!lev) return;

		/* Update ancestor with zeta if we've rewound more */
		if (anc > lev) {
			anc = lev;
			indmin = fixed[lev];
		}

		/* Recover the partition nest to this level */
		for (i = j = cells = 0, lastnon = -1; i < n; j = ++i) {

			/* Rewind ptn */
			while (ptn[i] > lev) {
				ptn[i] = n+1;
				cfront[lab[i++]] = j;
			}

			/* We're at the end of a cell */
			++cells;
			if (i == j) continue;

			/* Update lengths and fronts */
			clen[j] = i-j;
			cfront[lab[i]] = j;

			/* Update the nonsingleton list */
			prevnon[j] = lastnon;
			nextnon[lastnon] = j;
			lastnon = j;
		}

		/* Fix the end of the nonsingleton list */
		prevnon[n] = lastnon;
		nextnon[lastnon] = n;

		/* If we're at our gca with zeta, orbit prune with theta */
		if (lev == anc) theta_prune(); else orbit_prune();

		/* Compute |Aut(G)| found so far */
		if ((target_min == n+1) && (anc == lev)) {
			indx = 0; i = start[lev] - 1;

			/* Find factor */
			do {
				/* Find lab[i]'s minimum cell representative */
				for (j = lab[++i]; j != theta[j]; j = theta[j]);
				k = lab[i]; while (theta[k] != j) {
					t = theta[k]; theta[k] = j; k = t;
				}

				/* If it is the fixed value, then increment */
				if (j == indmin) ++indx;
			} while (ptn[i] > lev);

			/* Update size */
			MULTIPLY(stats->grpsize_base, stats->grpsize_exp, indx);
		}
	}
	/* Quit when there's something left in the target */
	while (target_min == n+1);
}