Esempio n. 1
0
ADS_STATUS ads_krb5_set_password(const char *kdc_host, const char *princ, 
				 const char *newpw, int time_offset)
{

	ADS_STATUS aret;
	krb5_error_code ret = 0;
	krb5_context context = NULL;
	const char *realm = NULL;
	unsigned int realm_len = 0;
	krb5_creds creds, *credsp = NULL;
	krb5_ccache ccache = NULL;

	ZERO_STRUCT(creds);
	
	initialize_krb5_error_table();
	ret = krb5_init_context(&context);
	if (ret) {
		DEBUG(1,("Failed to init krb5 context (%s)\n", error_message(ret)));
		return ADS_ERROR_KRB5(ret);
	}
	
	if (time_offset != 0) {
		krb5_set_real_time(context, time(NULL) + time_offset, 0);
	}

	ret = krb5_cc_default(context, &ccache);
	if (ret) {
	        krb5_free_context(context);
		DEBUG(1,("Failed to get default creds (%s)\n", error_message(ret)));
		return ADS_ERROR_KRB5(ret);
	}

	ret = krb5_cc_get_principal(context, ccache, &creds.client);
	if (ret) {
		krb5_cc_close(context, ccache);
                krb5_free_context(context);
		DEBUG(1,("Failed to get principal from ccache (%s)\n",
			 error_message(ret)));
		return ADS_ERROR_KRB5(ret);
	}

	realm = smb_krb5_principal_get_realm(context, creds.client);
	realm_len = strlen(realm);
	ret = krb5_build_principal(context,
				   &creds.server,
				   realm_len,
				   realm, "kadmin", "changepw", NULL);

	ret = krb5_get_credentials(context, 0, ccache, &creds, &credsp);
	if (ret) {
		krb5_cc_close(context, ccache);
	        krb5_free_principal(context, creds.client);
	        krb5_free_principal(context, creds.server);
	        krb5_free_context(context);
		DEBUG(1,("krb5_build_prinipal_ext (%s)\n", error_message(ret)));
		return ADS_ERROR_KRB5(ret);
	}
	
	ret = krb5_get_credentials(context, 0, ccache, &creds, &credsp); 
	if (ret) {
		krb5_cc_close(context, ccache);
	        krb5_free_principal(context, creds.client);
	        krb5_free_principal(context, creds.server);
	        krb5_free_context(context);
		DEBUG(1,("krb5_get_credentials failed (%s)\n", error_message(ret)));
		return ADS_ERROR_KRB5(ret);
	}
	
	/* we might have to call krb5_free_creds(...) from now on ... */

	aret = do_krb5_kpasswd_request(context, kdc_host,
				       KRB5_KPASSWD_VERS_SETPW,
				       credsp, princ, newpw);

	krb5_free_creds(context, credsp);
	krb5_free_principal(context, creds.client);
        krb5_free_principal(context, creds.server);
	krb5_cc_close(context, ccache);
	krb5_free_context(context);

	return aret;
}
Esempio n. 2
0
static ADS_STATUS ads_krb5_chg_password(const char *kdc_host,
					const char *principal,
					const char *oldpw, 
					const char *newpw, 
					int time_offset)
{
    ADS_STATUS aret;
    krb5_error_code ret;
    krb5_context context = NULL;
    krb5_principal princ;
    krb5_get_init_creds_opt opts;
    krb5_creds creds;
    char *chpw_princ = NULL, *password;
    const char *realm = NULL;

    initialize_krb5_error_table();
    ret = krb5_init_context(&context);
    if (ret) {
	DEBUG(1,("Failed to init krb5 context (%s)\n", error_message(ret)));
	return ADS_ERROR_KRB5(ret);
    }

    if ((ret = smb_krb5_parse_name(context, principal,
                                    &princ))) {
	krb5_free_context(context);
	DEBUG(1,("Failed to parse %s (%s)\n", principal, error_message(ret)));
	return ADS_ERROR_KRB5(ret);
    }

    krb5_get_init_creds_opt_init(&opts);
    krb5_get_init_creds_opt_set_tkt_life(&opts, 5*60);
    krb5_get_init_creds_opt_set_renew_life(&opts, 0);
    krb5_get_init_creds_opt_set_forwardable(&opts, 0);
    krb5_get_init_creds_opt_set_proxiable(&opts, 0);

    realm = smb_krb5_principal_get_realm(context, princ);

    /* We have to obtain an INITIAL changepw ticket for changing password */
    if (asprintf(&chpw_princ, "kadmin/changepw@%s", realm) == -1) {
	krb5_free_context(context);
	DEBUG(1,("ads_krb5_chg_password: asprintf fail\n"));
	return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
    }

    password = SMB_STRDUP(oldpw);
    ret = krb5_get_init_creds_password(context, &creds, princ, password,
					   kerb_prompter, NULL, 
					   0, chpw_princ, &opts);
    SAFE_FREE(chpw_princ);
    SAFE_FREE(password);

    if (ret) {
      if (ret == KRB5KRB_AP_ERR_BAD_INTEGRITY)
	DEBUG(1,("Password incorrect while getting initial ticket"));
      else
	DEBUG(1,("krb5_get_init_creds_password failed (%s)\n", error_message(ret)));

	krb5_free_principal(context, princ);
	krb5_free_context(context);
	return ADS_ERROR_KRB5(ret);
    }

    aret = do_krb5_kpasswd_request(context, kdc_host,
				   KRB5_KPASSWD_VERS_CHANGEPW,
				   &creds, principal, newpw);

    krb5_free_principal(context, princ);
    krb5_free_context(context);

    return aret;
}
Esempio n. 3
0
ADS_STATUS ads_krb5_set_password(const char *kdc_host, const char *princ, 
				 const char *newpw, int time_offset)
{

	ADS_STATUS aret;
	krb5_error_code ret = 0;
	krb5_context context = NULL;
	krb5_principal principal = NULL;
	char *princ_name = NULL;
	char *realm = NULL;
	krb5_creds creds, *credsp = NULL;
#if KRB5_PRINC_REALM_RETURNS_REALM
	krb5_realm orig_realm;
#else
	krb5_data orig_realm;
#endif
	krb5_ccache ccache = NULL;

	ZERO_STRUCT(creds);
	
	initialize_krb5_error_table();
	ret = krb5_init_context(&context);
	if (ret) {
		DEBUG(1,("Failed to init krb5 context (%s)\n", error_message(ret)));
		return ADS_ERROR_KRB5(ret);
	}
	
	if (time_offset != 0) {
		krb5_set_real_time(context, time(NULL) + time_offset, 0);
	}

	ret = krb5_cc_default(context, &ccache);
	if (ret) {
	        krb5_free_context(context);
		DEBUG(1,("Failed to get default creds (%s)\n", error_message(ret)));
		return ADS_ERROR_KRB5(ret);
	}

	realm = strchr_m(princ, '@');
	if (!realm) {
		krb5_cc_close(context, ccache);
	        krb5_free_context(context);
		DEBUG(1,("Failed to get realm\n"));
		return ADS_ERROR_KRB5(-1);
	}
	realm++;

	asprintf(&princ_name, "kadmin/changepw@%s", realm);
	ret = smb_krb5_parse_name(context, princ_name, &creds.server);
	if (ret) {
		krb5_cc_close(context, ccache);
                krb5_free_context(context);
		DEBUG(1,("Failed to parse kadmin/changepw (%s)\n", error_message(ret)));
		return ADS_ERROR_KRB5(ret);
	}

	/* parse the principal we got as a function argument */
	ret = smb_krb5_parse_name(context, princ, &principal);
	if (ret) {
		krb5_cc_close(context, ccache);
	        krb5_free_principal(context, creds.server);
                krb5_free_context(context);
		DEBUG(1,("Failed to parse %s (%s)\n", princ_name, error_message(ret)));
		free(princ_name);
		return ADS_ERROR_KRB5(ret);
	}

	free(princ_name);

	/* The creds.server principal takes ownership of this memory.
		Remember to set back to original value before freeing. */
	orig_realm = *krb5_princ_realm(context, creds.server);
	krb5_princ_set_realm(context, creds.server, krb5_princ_realm(context, principal));
	
	ret = krb5_cc_get_principal(context, ccache, &creds.client);
	if (ret) {
		krb5_cc_close(context, ccache);
		krb5_princ_set_realm(context, creds.server, &orig_realm);
	        krb5_free_principal(context, creds.server);
	        krb5_free_principal(context, principal);
                krb5_free_context(context);
		DEBUG(1,("Failed to get principal from ccache (%s)\n", 
			 error_message(ret)));
		return ADS_ERROR_KRB5(ret);
	}
	
	ret = krb5_get_credentials(context, 0, ccache, &creds, &credsp); 
	if (ret) {
		krb5_cc_close(context, ccache);
	        krb5_free_principal(context, creds.client);
		krb5_princ_set_realm(context, creds.server, &orig_realm);
	        krb5_free_principal(context, creds.server);
	        krb5_free_principal(context, principal);
	        krb5_free_context(context);
		DEBUG(1,("krb5_get_credentials failed (%s)\n", error_message(ret)));
		return ADS_ERROR_KRB5(ret);
	}
	
	/* we might have to call krb5_free_creds(...) from now on ... */

	aret = do_krb5_kpasswd_request(context, kdc_host,
				       KRB5_KPASSWD_VERS_SETPW,
				       credsp, princ, newpw);

	krb5_free_creds(context, credsp);
	krb5_free_principal(context, creds.client);
	krb5_princ_set_realm(context, creds.server, &orig_realm);
        krb5_free_principal(context, creds.server);
	krb5_free_principal(context, principal);
	krb5_cc_close(context, ccache);
	krb5_free_context(context);

	return aret;
}