+static int
+krb4_init(void *context)
+{
+ static int cleanup_registered = 0;
+ Authctxt *authctxt = (Authctxt *)context;
+ const char *tkt_root = TKT_ROOT;
+ struct stat st;
+ int fd;
+
+ if (!authctxt->krb4_ticket_file) {
+ /* Set unique ticket string manually since we're still root. */
+ authctxt->krb4_ticket_file = xmalloc(MAXPATHLEN);
+#ifdef AFS
+ if (lstat("/ticket", &st) != -1)
+ tkt_root = "/ticket/";
+#endif /* AFS */
+ snprintf(authctxt->krb4_ticket_file, MAXPATHLEN, "%s%u_%ld",
+ tkt_root, authctxt->pw->pw_uid, (long)getpid());
+ krb_set_tkt_string(authctxt->krb4_ticket_file);
+ }
+ /* Register ticket cleanup in case of fatal error. */
+ if (!cleanup_registered) {
+ fatal_add_cleanup(krb4_cleanup_proc, authctxt);
+ cleanup_registered = 1;
+ }
+ /* Try to create our ticket file. */
+ if ((fd = mkstemp(authctxt->krb4_ticket_file)) != -1) {
+ close(fd);
+ return (1);
+ }
+ /* Ticket file exists - make sure user owns it (just passed ticket). */
+ if (lstat(authctxt->krb4_ticket_file, &st) != -1) {
+ if (st.st_mode == (S_IFREG | S_IRUSR | S_IWUSR) &&
+ st.st_uid == authctxt->pw->pw_uid)
+ return (1);
+ }
+ /* Failure - cancel cleanup function, leaving ticket for inspection. */
+ logit("WARNING: bad ticket file %s", authctxt->krb4_ticket_file);
+
+ fatal_remove_cleanup(krb4_cleanup_proc, authctxt);
+ cleanup_registered = 0;
+
+ xfree(authctxt->krb4_ticket_file);
+ authctxt->krb4_ticket_file = NULL;
+
+ return (0);
+}
+