int
main(int argc, char **argv)
{
	char pname[ANAME_SZ + 1], pinst[INST_SZ + 1];
	CREDENTIALS cred;
	int ret;

	ret = tf_init(tkt_string(), R_TKT_FIL);
	if (ret != 0) {
		printf("Error initializing ticket file \"%s\".\n",
		       tkt_string());
		return ret;
	}
	memset(&cred, 0, sizeof(cred));
	ret = tf_get_pname(pname);
	if (ret != 0) {
		printf("Error reading names from \"%s\".\n", tkt_string());
		return ret;
	}
	ret = tf_get_pinst(pinst);
	if (ret != 0) {
		printf("Error reading names from \"%s\".\n", tkt_string());
		return ret;
	}
	ret = tf_get_cred(&cred);
	if (ret != 0) {
		printf("Error reading creds from \"%s\".\n", tkt_string());
		return ret;
	}
	printf("%lu\n", (unsigned long) cred.lifetime);
	tf_close();
	return 0;
}
Exemple #2
0
int
krb_get_cred(
    char *service,              /* Service name */
    char *instance,             /* Instance */
    char *realm,                /* Auth domain */
    CREDENTIALS *c              /* Credentials struct */
    )
{
    int tf_status;              /* return value of tf function calls */
    struct timeval local_time;
    int kinited = 0;
    char env[16];
    BOOL prompt;

    GetEnvironmentVariable("KERBEROSLOGIN_NEVER_PROMPT",env, sizeof(env));
    prompt = (GetLastError() == ERROR_ENVVAR_NOT_FOUND);

	c->pname[0] = c->pinst[0] = '\0';

check_cache:

    gettimeofday(&local_time, 0);
        
    /* Open ticket file and lock it for shared reading */
    if ((tf_status = tf_init(TKT_FILE, R_TKT_FIL)) != KSUCCESS) {
		goto cache_checked;
    }
    /* Copy principal's name and instance into the CREDENTIALS struc c */
    if (((tf_status = tf_get_pname(c->pname)) != KSUCCESS) ||
        ((tf_status = tf_get_pinst(c->pinst)) != KSUCCESS))
    {
    	goto cache_checked;
    }
    /* Search for requested service credentials and copy into c */ 
    while ((tf_status = tf_get_cred(c)) == KSUCCESS) {
        /* Is this the right ticket? */
        if (!service || (strcmp(c->service,service) == 0) &&
            (!instance || strcmp(c->instance,instance) == 0) &&
            (!realm || strcmp(c->realm,realm) == 0))
        {  
            // Hey, is this a valid ticket? Let's check before we return.
            if (((long)((c->issue_date + c->lifetime * 5L * 60L) -
                        (long)local_time.tv_sec) >= 0)
                &&
                ( 0 == com_addr(c)))
            {
                break; // we're OK
            }
        }
    }

cache_checked:
    tf_close();

    // If we are requesting a tgt, prompt for it
	if (tf_status != KSUCCESS && !kinited && 
        strncmp(service, "krbtgt", ANAME_SZ) == 0 && 
        prompt) 
    {
        static int (*pLeash_kinit_dlg_ex)(HWND hParent, LPLSH_DLGINFO_EX lpdlginfoex) = 0;
        static DWORD (*pLeash_get_default_use_krb4)() = 0;

        kinited = 1;

        if ( !m_hLeashDLL ) {
            m_hLeashDLL = LoadLibrary(LEASHDLL);
            if ( m_hLeashDLL ) {
                (FARPROC)pLeash_kinit_dlg_ex=GetProcAddress(m_hLeashDLL,"Leash_kinit_dlg_ex");
                (FARPROC)pLeash_get_default_use_krb4=GetProcAddress(m_hLeashDLL,"Leash_get_default_use_krb4");
            }
        }

        if ( pLeash_get_default_use_krb4 &&
             pLeash_kinit_dlg_ex ) {
            LSH_DLGINFO_EX dlginfo;
            int success;

            // copy in the existing username and realm
            char * pTmp = calloc(1, strlen(c->pname) + strlen(c->pinst) + 2);
            strcpy(pTmp, c->pname);
            if (c->pname[0] != 0 && c->pinst[0] != 0)
            {
                strcat(pTmp, "/");
                strcat(pTmp, c->pinst);
            }

            memset(&dlginfo, 0, sizeof(LSH_DLGINFO_EX));
            dlginfo.size = sizeof(LSH_DLGINFO_EX);
            dlginfo.dlgtype = DLGTYPE_PASSWD;
            dlginfo.title = dlginfo.in.title;
	    strcpy(dlginfo.in.title,"Kerberos 4 - Obtain Tickets");
            dlginfo.username = dlginfo.in.username;
	    strcpy(dlginfo.in.username,pTmp);
            dlginfo.realm = dlginfo.in.realm;
	    strcpy(dlginfo.in.realm,realm);
            dlginfo.use_defaults = 1;

            success = pLeash_kinit_dlg_ex(GetDesktopWindow(), &dlginfo);
            free(pTmp);
            if (success)
                goto check_cache;
        }
    }

    if (tf_status == EOF)
        return (GC_NOTKT);

    return(tf_status);
}
Exemple #3
0
static int
_pam_krb5_v4_init(krb5_context ctx,
		  struct _pam_krb5_stash *stash,
		  struct _pam_krb5_user_info *user,
		  struct _pam_krb5_options *options,
		  char *sname, char *sinstance,
		  char *password,
		  int *result) 
{
	char name[ANAME_SZ + 1], instance[INST_SZ + 1], realm[REALM_SZ + 1];
	char pname[ANAME_SZ + 1], pinstance[INST_SZ + 1];
	char tktfile[PATH_MAX];
	char *saved_tktstring;
	int life, i, fd;
	struct stat st;

	/* Convert the krb5 version of the principal's name to a v4 principal
	 * name.  This may involve changing "host" to "rcmd" and so on, so let
	 * libkrb5 handle it. */
	memset(name, '\0', sizeof(name));
	memset(instance, '\0', sizeof(instance));
	memset(realm, '\0', sizeof(realm));
	i = krb5_524_conv_principal(ctx, user->principal_name,
				    name, instance, realm);
	if (i != 0) {
		if (result) {
			*result = i;
		}
		return PAM_SERVICE_ERR;
	}
	if (options->debug) {
		debug("converted principal to '%s%s%s%s@'%s'", name,
		      strlen(instance) ? "'.'" : "'", instance,
		      strlen(instance) ? "'" : "", realm);
	}

#ifdef HAVE_KRB_TIME_TO_LIFE
	/* Convert the ticket lifetime of the v5 credentials into a v4
	 * lifetime, which is the X coordinate along a curve where Y is the
	 * actual length.  Again, this is magic. */
	life = krb_time_to_life(stash->v5creds.times.starttime,
				stash->v5creds.times.endtime); 
#else
	/* No life_to_time() function means that we have to estimate the
	 * intended lifetime, in 5-minute increments.  We also have a maximum
	 * value to contend with, because the lifetime is expressed in a single
	 * byte. */
	life = stash->v5creds.times.endtime -
	       stash->v5creds.times.starttime;
	life /= (60 * 5);
	if (life > 0xff) {
		life = 0xff;
	}
#endif

	/* Create the ticket file.  One of two things will happen here.  Either
	 * libkrb[4] will just use the file, and we're safer because it
	 * wouldn't have used O_EXCL to do so, or it will nuke the file and
	 * reopen it with O_EXCL.  In the latter case, the descriptor we have
	 * will become useless, so we don't actually use it for anything. */
#ifdef HAVE_LONG_LONG
	snprintf(tktfile, sizeof(tktfile), "%s/tkt%llu_XXXXXX",
		 options->ccache_dir,
		 options->user_check ?
		 (unsigned long long) user->uid :
		 (unsigned long long) getuid());
#else
	snprintf(tktfile, sizeof(tktfile), "%s/tkt%lu_XXXXXX",
		 options->ccache_dir,
		 options->user_check ?
		 (unsigned long) user->uid :
		 (unsigned long) getuid());
#endif
	fd = mkstemp(tktfile);
	if (fd == -1) {
		if (result) {
			*result = errno;
		}
		return PAM_SERVICE_ERR;
	}
	if (fchown(fd, getuid(), getgid()) != 0) {
		warn("error setting permissions on \"%s\" (%s), attempting "
		     "to continue", tktfile, strerror(errno));
	}
	if (options->debug) {
		debug("preparing to place v4 credentials in '%s'", tktfile);
	}
	/* Save the old default ticket file name, and set the default to use
	 * our just-created empty file. */
	saved_tktstring = xstrdup(tkt_string());
	krb_set_tkt_string(tktfile);
	/* Get the initial credentials. */
	i = krb_get_pw_in_tkt(name, instance, realm,
			      sname, sinstance ? sinstance : realm,
			      life, password);
	if (result) {
		*result = i;
	}
	/* Restore the original default ticket file name. */
	krb_set_tkt_string(saved_tktstring);
	xstrfree(saved_tktstring);
	saved_tktstring = NULL;
	/* If we got credentials, read them from the file, and then remove the
	 * file. */
	if (i == 0) {
		i = tf_init(tktfile, R_TKT_FIL);
		if (i == 0) {
			i = tf_get_pname(pname);
			if (i == 0) {
				i = tf_get_pinst(pinstance);
				if (i == 0) {
					i = tf_get_cred(&stash->v4creds);
					if (i == 0) {
						tf_close();
						unlink(tktfile);
						close(fd);
						return PAM_SUCCESS;
					} else {
						warn("error reading creds "
						     "from '%s': %d (%s)",
						     tktfile,
						     i, v5_error_message(i));
					}
				} else {
					warn("error reading instance from '%s'"
					     ": %d (%s)",
					     tktfile, i, v5_error_message(i));
				}
			} else {
				warn("error reading principal name from '%s'"
				     ": %d (%s)",
				     tktfile, i, v5_error_message(i));
			}
			tf_close();
		} else {
			const char *tferror;
			switch (i) {
			case NO_TKT_FIL:
				tferror = "no ticket file";
				break;
			case TKT_FIL_ACC:
				tferror = "ticket file had wrong permissions";
				break;
			case TKT_FIL_LCK:
				tferror = "error locking ticket file";
				break;
			default:
				tferror = strerror(errno);
				break;
			}
			warn("error opening '%s' for reading: %s",
			     tktfile, tferror);
			if ((i == TKT_FIL_ACC) && (options->debug)) {
				if (stat(tktfile, &st) == 0) {
					debug("file owner is %lu:%lu, "
					      "we are effective %lu:%lu, "
					      "real %lu:%lu",
					      (unsigned long) st.st_uid,
					      (unsigned long) st.st_gid,
					      (unsigned long) geteuid(),
					      (unsigned long) getegid(),
					      (unsigned long) getuid(),
					      (unsigned long) getgid());
				}
			}
		}
	}
	unlink(tktfile);
	close(fd);
	return PAM_AUTH_ERR;
}