Esempio n. 1
0
File: sly.c Progetto: OPSF/uClinux
/* Store the v4 TGT in $KRBTKFILE. */
static void
sly_v4(krb5_context ctx, const char *v4tktfile,
       struct _pam_krb5_user_info *userinfo, struct _pam_krb5_stash *stash)
{
	int i;
	char name[ANAME_SZ + 1], instance[INST_SZ + 1], realm[REALM_SZ + 1];

	i = krb5_524_conv_principal(ctx, userinfo->principal_name,
				    name, instance, realm);
	if (i != 0) {
		return;
	}

	tf_init((char *) v4tktfile, W_TKT_FIL);
	v4_in_tkt(name, instance, realm);
	v4_save_credentials(KRB5_TGS_NAME, realm, realm,
			    stash->v4creds.session,
			    stash->v4creds.lifetime,
			    stash->v4creds.kvno,
			    &stash->v4creds.ticket_st,
			    stash->v4creds.issue_date);
	tf_close();
}
Esempio n. 2
0
static int
v4_save(krb5_context ctx,
	struct _pam_krb5_stash *stash,
	struct _pam_krb5_user_info *userinfo,
	struct _pam_krb5_options *options,
	uid_t uid, gid_t gid,
	const char **ccname,
	int clone_cc)
{
	char name[ANAME_SZ + 1], instance[INST_SZ + 1], realm[REALM_SZ + 1];
	char tktfile[PATH_MAX];
	char *saved_tktstring;
	int i, fd;
	struct stat st;

	if (ccname != NULL) {
		*ccname = NULL;
	}

	/* Convert the v5 principal name into v4 notation. */
	memset(name, '\0', sizeof(name));
	memset(instance, '\0', sizeof(instance));
	memset(realm, '\0', sizeof(realm));
	if (stash->v5creds.client != NULL) {
		/* Use the client principal of the creds we have, which we
		 * can assume are always correct, even if "external" somehow
		 * got us to the point where the principal name in "userinfo"
		 * is incorrect. */
		i = krb5_524_conv_principal(ctx, stash->v5creds.client,
					    name, instance, realm);
	} else {
		/* Use the parsed principal as a fallback.  We should never
		 * really get here, but just in case. */
		i = krb5_524_conv_principal(ctx, userinfo->principal_name,
					    name, instance, realm);
	}
	if (i != 0) {
		warn("error converting %s to a Kerberos IV principal "
		     "(shouldn't happen)", userinfo->unparsed_name);
		return PAM_SERVICE_ERR;
	}

	/* Create a new ticket file. */
#ifdef HAVE_LONG_LONG
	snprintf(tktfile, sizeof(tktfile), "%s/tkt%llu_XXXXXX",
		 options->ccache_dir,
		 options->user_check ?
		 (unsigned long long) userinfo->uid :
		 (unsigned long long) getuid());
#else
	snprintf(tktfile, sizeof(tktfile), "%s/tkt%lu_XXXXXX",
		 options->ccache_dir,
		 options->user_check ?
		 (unsigned long) userinfo->uid :
		 (unsigned long) getuid());
#endif
	fd = mkstemp(tktfile);
	if (fd == -1) {
		warn("error creating unique Kerberos IV ticket file "
		     "(shouldn't happen)");
		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("saving v4 tickets to '%s'", tktfile);
	}

	/* Open the ticket file. */
	saved_tktstring = xstrdup(tkt_string());
	krb_set_tkt_string(tktfile);
	i = tf_init(tktfile, W_TKT_FIL);
	if (i != 0) {
		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 ticket file '%s': %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());
			}
		}
		krb_set_tkt_string(saved_tktstring);
		xstrfree(saved_tktstring);
		unlink(tktfile);
		close(fd);
		return PAM_SERVICE_ERR;
	}

	/* Store the user's name. */
	if (v4_in_tkt(name, instance, realm) != 0) {
		warn("error initializing ticket file '%s'", tktfile);
		tf_close();
		krb_set_tkt_string(saved_tktstring);
		xstrfree(saved_tktstring);
		unlink(tktfile);
		close(fd);
		return PAM_SERVICE_ERR;
	}

	/* Store the v4 credentials. */
	if (v4_save_credentials(KRB5_TGS_NAME, realm, realm,
				stash->v4creds.session,
				stash->v4creds.lifetime,
				stash->v4creds.kvno,
				&stash->v4creds.ticket_st,
				stash->v4creds.issue_date) != 0) {
		warn("error saving tickets to '%s'", tktfile);
		tf_close();
		krb_set_tkt_string(saved_tktstring);
		xstrfree(saved_tktstring);
		unlink(tktfile);
		close(fd);
		return PAM_SERVICE_ERR;
	}

	/* Close the new file. */
	tf_close();
	xstrfree(saved_tktstring);
	close(fd);

	/* Save the new file's name in the stash, and optionally return it to
	 * the caller. */
	if (_pam_krb5_stash_push_v4(ctx, stash, options, tktfile) == 0) {
		/* Generate a *new* ticket file with the same contents as this
		 * one. */
		if (clone_cc) {
			_pam_krb5_stash_clone_v4(stash, uid, gid);
		}
		krb_set_tkt_string(stash->v4tktfiles->name);
		if (ccname != NULL) {
			*ccname = stash->v4tktfiles->name;
		}
	}

	return PAM_SUCCESS;
}