Esempio n. 1
0
static int
fetch_princ_entry(
	krb5_module_data_t *kmd,
	char *princ_str,
	kadm5_principal_ent_rec *prent,	/* out */
	int debug)

{
	kadm5_ret_t		code;
	krb5_principal 		princ = 0;
	char 			admin_realm[1024];
	char			kprinc[2*MAXHOSTNAMELEN];
	char			*cpw_service, *password;
	void 			*server_handle;
	krb5_context		context;
	kadm5_config_params	params;

	password = kmd->password;
	context = kmd->kcontext;

	if ((code = get_kmd_kuser(context, (const char *)princ_str,
	    kprinc, 2*MAXHOSTNAMELEN)) != 0) {
		return (code);
	}

	code = krb5_parse_name(context, kprinc, &princ);
	if (code != 0) {
		return (PAM_SYSTEM_ERR);
	}

	if (strlen(password) == 0) {
		krb5_free_principal(context, princ);
		if (debug)
			__pam_log(LOG_AUTH | LOG_DEBUG,
			    "PAM-KRB5 (acct): fetch_princ_entry: pwlen=0");
		return (PAM_AUTH_ERR);
	}

	(void) strlcpy(admin_realm,
		    krb5_princ_realm(context, princ)->data,
		    sizeof (admin_realm));

	(void) memset((char *)&params, 0, sizeof (params));
	params.mask |= KADM5_CONFIG_REALM;
	params.realm = admin_realm;

	if (kadm5_get_cpw_host_srv_name(context, admin_realm, &cpw_service)) {
		__pam_log(LOG_AUTH | LOG_ERR,
			"PAM-KRB5 (acct):  unable to get host based "
			"service name for realm '%s'",
			admin_realm);
		krb5_free_principal(context, princ);
		return (PAM_SYSTEM_ERR);
	}

	code = kadm5_init_with_password(kprinc, password, cpw_service,
					&params, KADM5_STRUCT_VERSION,
					KADM5_API_VERSION_2, NULL,
					&server_handle);
	if (code != 0) {
		if (debug)
			__pam_log(LOG_AUTH | LOG_DEBUG,
			    "PAM-KRB5 (acct): fetch_princ_entry: "
			    "init_with_pw failed: code = %d", code);
		krb5_free_principal(context, princ);
		return ((code == KADM5_BAD_PASSWORD) ?
			PAM_AUTH_ERR : PAM_SYSTEM_ERR);
	}

	if (_kadm5_get_kpasswd_protocol(server_handle) != KRB5_CHGPWD_RPCSEC) {
		if (debug)
			__pam_log(LOG_AUTH | LOG_DEBUG,
			    "PAM-KRB5 (acct): fetch_princ_entry: "
			    "non-RPCSEC_GSS chpw server, can't get "
			    "princ entry");
		(void) kadm5_destroy(server_handle);
		krb5_free_principal(context, princ);
		return (PAM_SYSTEM_ERR);
	}

	code = kadm5_get_principal(server_handle, princ, prent,
				KADM5_PRINCIPAL_NORMAL_MASK);

	if (code != 0) {
		(void) kadm5_destroy(server_handle);
		krb5_free_principal(context, princ);
		return ((code == KADM5_UNK_PRINC) ?
			PAM_USER_UNKNOWN : PAM_SYSTEM_ERR);
	}

	(void) kadm5_destroy(server_handle);
	krb5_free_principal(context, princ);

	return (PAM_SUCCESS);
}
Esempio n. 2
0
int
krb5_verifypw(
	pam_handle_t *pamh,
	char 	*princ_str,
	char	*old_password,
	boolean_t disp_flag,
	int debug)
{
	kadm5_ret_t		code;
	krb5_principal 		princ = 0;
	char 			admin_realm[1024];
	char			kprinc[2*MAXHOSTNAMELEN];
	char			*cpw_service;
	kadm5_principal_ent_rec principal_entry;
	kadm5_policy_ent_rec	 policy_entry;
	void 			*server_handle;
	krb5_context		context;
	kadm5_config_params	params;
#define	MSG_ROWS		5
	char			msgs[MSG_ROWS][PAM_MAX_MSG_SIZE];

	(void) memset((char *)&params, 0, sizeof (params));
	(void) memset(&principal_entry, 0, sizeof (principal_entry));
	(void) memset(&policy_entry, 0, sizeof (policy_entry));

	if (code = krb5_init_context(&context)) {
		return (6);
	}

	if ((code = get_kmd_kuser(context, (const char *)princ_str, kprinc,
		2*MAXHOSTNAMELEN)) != 0) {
		return (code);
	}

	/* Need to get a krb5_principal struct */

	code = krb5_parse_name(context, kprinc, &princ);

	if (code != 0) {
		return (MISC_EXIT_STATUS);
	}

	if (strlen(old_password) == 0) {
		krb5_free_principal(context, princ);
		return (5);
	}

	(void) strlcpy(admin_realm,
		    krb5_princ_realm(context, princ)->data,
		    sizeof (admin_realm));

	params.mask |= KADM5_CONFIG_REALM;
	params.realm = admin_realm;


	if (kadm5_get_cpw_host_srv_name(context, admin_realm, &cpw_service)) {
		syslog(LOG_ERR,
		    dgettext(TEXT_DOMAIN,
			"PAM-KRB5 (password): unable to get host based "
			"service name for realm %s\n"),
			admin_realm);
		return (3);
	}

	code = kadm5_init_with_password(kprinc, old_password, cpw_service,
					&params, KADM5_STRUCT_VERSION,
					KADM5_API_VERSION_2, &server_handle);
	if (code != 0) {
		if (debug)
			syslog(LOG_DEBUG,
			    "PAM-KRB5: krb5_verifypw: init_with_pw"
			    " failed: (%s)", error_message(code));
		krb5_free_principal(context, princ);
		return ((code == KADM5_BAD_PASSWORD) ? 2 : 3);
	}

	if (disp_flag &&
	    _kadm5_get_kpasswd_protocol(server_handle) == KRB5_CHGPWD_RPCSEC) {
		/*
		 * Note: copy of this exists in login
		 * (kverify.c/get_verified_in_tkt).
		 */

		code = kadm5_get_principal(server_handle, princ,
						&principal_entry,
						KADM5_PRINCIPAL_NORMAL_MASK);
		if (code != 0) {
			krb5_free_principal(context, princ);
			(void) kadm5_destroy(server_handle);
			return ((code == KADM5_UNK_PRINC) ? 1 :
				MISC_EXIT_STATUS);
		}

		if ((principal_entry.aux_attributes & KADM5_POLICY) != 0) {
			code = kadm5_get_policy(server_handle,
						principal_entry.policy,
						&policy_entry);
			if (code != 0) {
				/*
				 * doesn't matter which error comes back,
				 * there's no nice recovery or need to
				 * differentiate to the user
				 */
				(void) kadm5_free_principal_ent(server_handle,
							&principal_entry);
				krb5_free_principal(context, princ);
				(void) kadm5_destroy(server_handle);
				return (MISC_EXIT_STATUS);
			}

			(void) snprintf(msgs[0], PAM_MAX_MSG_SIZE,
				dgettext(TEXT_DOMAIN, "POLICY_EXPLANATION:"));
			(void) snprintf(msgs[1], PAM_MAX_MSG_SIZE,
				dgettext(TEXT_DOMAIN,
					"Principal string is %s"), princ_str);
			(void) snprintf(msgs[2], PAM_MAX_MSG_SIZE,
				dgettext(TEXT_DOMAIN, "Policy Name is  %s"),
				principal_entry.policy);
			(void) snprintf(msgs[3], PAM_MAX_MSG_SIZE,
				dgettext(TEXT_DOMAIN,
					"Minimum password length is %d"),
					policy_entry.pw_min_length);
			(void) snprintf(msgs[4], PAM_MAX_MSG_SIZE,
				dgettext(TEXT_DOMAIN,
					"Minimum password classes is %d"),
					policy_entry.pw_min_classes);
			display_msgs(pamh, PAM_TEXT_INFO, MSG_ROWS, msgs);

			if (code = kadm5_free_principal_ent(server_handle,
							    &principal_entry)) {
				(void) kadm5_free_policy_ent(server_handle,
							&policy_entry);
				krb5_free_principal(context, princ);
				(void) kadm5_destroy(server_handle);
				return (MISC_EXIT_STATUS);
			}
			if (code = kadm5_free_policy_ent(server_handle,
							&policy_entry)) {
				krb5_free_principal(context, princ);

				(void) kadm5_destroy(server_handle);
				return (MISC_EXIT_STATUS);
			}
		} else {
			/*
			 * kpasswd *COULD* output something here to encourage
			 * the choice of good passwords, in the absence of
			 * an enforced policy.
			 */
			if (code = kadm5_free_principal_ent(server_handle,
							    &principal_entry)) {
				krb5_free_principal(context, princ);
				(void) kadm5_destroy(server_handle);
				return (MISC_EXIT_STATUS);
			}
		}
	}
	krb5_free_principal(context, princ);

	(void) kadm5_destroy(server_handle);

	return (0);
}