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); }
char *rkinit_errmsg(char *string) { static char errmsg[BUFSIZ]; if (string) { BCLEAR(errmsg); strncpy(errmsg, string, sizeof(errmsg) - 1); } return(errmsg); }
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); }
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); }
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); }
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); }