int kadm5_create_magic_princs(kadm5_config_params *params, krb5_context context) { int retval; void *handle; retval = krb5_klog_init(context, "admin_server", progname, 0); if (retval) return retval; if ((retval = kadm5_init(progname, NULL, NULL, params, KADM5_STRUCT_VERSION, KADM5_API_VERSION_2, db5util_db_args, &handle))) { com_err(progname, retval, "while initializing the Kerberos admin interface"); return retval; } retval = add_admin_princs(handle, context, params->realm); kadm5_destroy(handle); krb5_klog_close(context); return retval; }
int main() { kadm5_ret_t ret; char *cp; int x; void *server_handle; kadm5_server_handle_t handle; krb5_context context; ret = kadm5_init_krb5_context(&context); if (ret != 0) { com_err("test", ret, "context init"); exit(2); } for(x = 0; x < TEST_NUM; x++) { ret = kadm5_init(context, "admin", "admin", KADM5_ADMIN_SERVICE, 0, KADM5_STRUCT_VERSION, KADM5_API_VERSION_4, NULL, &server_handle); if(ret != KADM5_OK) { com_err("test", ret, "init"); exit(2); } handle = (kadm5_server_handle_t) server_handle; cp = strdup(strchr(handle->cache_name, ':') + 1); kadm5_destroy(server_handle); if(access(cp, F_OK) == 0) { puts("ticket cache not destroyed"); exit(2); } free(cp); } krb5_free_context(context); exit(0); }
int main() { kadm5_ret_t ret; krb5_keyblock *keys[TEST_NUM]; krb5_principal tprinc; krb5_keyblock *newkey; krb5_context context; void *server_handle; int x, i; kadm5_init_krb5_context(&context); krb5_parse_name(context, "testuser", &tprinc); ret = kadm5_init(context, "admin", "admin", KADM5_ADMIN_SERVICE, NULL, KADM5_STRUCT_VERSION, KADM5_API_VERSION_3, NULL, &server_handle); if(ret != KADM5_OK) { com_err("test", ret, "init"); exit(2); } for(x = 0; x < TEST_NUM; x++) { kadm5_randkey_principal(server_handle, tprinc, &keys[x], NULL); for(i = 0; i < x; i++) { if (!memcmp(newkey->contents, keys[i]->contents, newkey->length)) puts("match found"); } } kadm5_destroy(server_handle); exit(0); }
int main() { kadm5_ret_t ret; void *server_handle; kadm5_config_params params; krb5_context context; memset(¶ms, 0, sizeof(params)); params.mask |= KADM5_CONFIG_NO_AUTH; ret = kadm5_init_krb5_context(&context); if (ret != 0) { com_err("init-test", ret, "while initializing krb5 context"); exit(1); } ret = kadm5_init(context, "admin", "admin", NULL, ¶ms, KADM5_STRUCT_VERSION, KADM5_API_VERSION_3, NULL, &server_handle); if (ret == KADM5_RPC_ERROR) { krb5_free_context(context); exit(0); } else if (ret != 0) { com_err("init-test", ret, "while initializing without auth"); exit(1); } else { fprintf(stderr, "Unexpected success while initializing without auth!\n"); (void) kadm5_destroy(server_handle); krb5_free_context(context); exit(1); } }
void sess_finalize(struct rekey_session *sess) { OM_uint32 min; if (sess->state == REKEY_SESSION_SENDING) prtmsg("warning: session closed before reply sent"); if (sess->ssl) { SSL_shutdown(sess->ssl); SSL_free(sess->ssl); } if (sess->kadm_handle) kadm5_destroy(sess->kadm_handle); if (sess->realm) { #if defined(HAVE_KRB5_REALM) krb5_xfree(sess->realm); #else krb5_free_default_realm(sess->kctx, sess->realm); #endif } if (sess->princ) krb5_free_principal(sess->kctx, sess->princ); if (sess->kctx) krb5_free_context(sess->kctx); if (sess->gctx) (void)gss_delete_sec_context(&min, &sess->gctx, GSS_C_NO_BUFFER); if (sess->name) (void)gss_release_name(&min, &sess->name); if (sess->dbh) sqlite3_close(sess->dbh); free(sess->hostname); free(sess->plain_name); memset(&sess, 0, sizeof(sess)); }
static void add_users (const char *filename, unsigned n) { krb5_error_code ret; int i; void *kadm_handle; krb5_context context; unsigned nwords; char **words; ret = krb5_init_context(&context); if (ret) errx (1, "krb5_init_context failed: %d", ret); ret = kadm5_s_init_with_password_ctx(context, KADM5_ADMIN_SERVICE, NULL, KADM5_ADMIN_SERVICE, NULL, 0, 0, &kadm_handle); if(ret) krb5_err(context, 1, ret, "kadm5_init_with_password"); nwords = read_words (filename, &words); for (i = 0; i < n; ++i) add_user (context, kadm_handle, nwords, words); kadm5_destroy(kadm_handle); krb5_free_context(context); }
int kt_get(struct get_options *opt, int argc, char **argv) { krb5_error_code ret = 0; krb5_keytab keytab; void *kadm_handle = NULL; krb5_enctype *etypes = NULL; size_t netypes = 0; size_t i; int a, j; unsigned int failed = 0; if((keytab = ktutil_open_keytab()) == NULL) return 1; if(opt->realm_string) krb5_set_default_realm(context, opt->realm_string); if (opt->enctypes_strings.num_strings != 0) { etypes = malloc (opt->enctypes_strings.num_strings * sizeof(*etypes)); if (etypes == NULL) { krb5_warnx(context, "malloc failed"); goto out; } netypes = opt->enctypes_strings.num_strings; for(i = 0; i < netypes; i++) { ret = krb5_string_to_enctype(context, opt->enctypes_strings.strings[i], &etypes[i]); if(ret) { krb5_warnx(context, "unrecognized enctype: %s", opt->enctypes_strings.strings[i]); goto out; } } } for(a = 0; a < argc; a++){ krb5_principal princ_ent; kadm5_principal_ent_rec princ; int mask = 0; krb5_keyblock *keys; int n_keys; int created = 0; krb5_keytab_entry entry; ret = krb5_parse_name(context, argv[a], &princ_ent); if (ret) { krb5_warn(context, ret, "can't parse principal %s", argv[a]); failed++; continue; } memset(&princ, 0, sizeof(princ)); princ.principal = princ_ent; mask |= KADM5_PRINCIPAL; princ.attributes |= KRB5_KDB_DISALLOW_ALL_TIX; mask |= KADM5_ATTRIBUTES; princ.princ_expire_time = 0; mask |= KADM5_PRINC_EXPIRE_TIME; if(kadm_handle == NULL) { const char *r; if(opt->realm_string != NULL) r = opt->realm_string; else r = krb5_principal_get_realm(context, princ_ent); kadm_handle = open_kadmin_connection(opt->principal_string, r, opt->admin_server_string, opt->server_port_integer); if(kadm_handle == NULL) break; } ret = kadm5_create_principal(kadm_handle, &princ, mask, "x"); if(ret == 0) created = 1; else if(ret != KADM5_DUP) { krb5_warn(context, ret, "kadm5_create_principal(%s)", argv[a]); krb5_free_principal(context, princ_ent); failed++; continue; } ret = kadm5_randkey_principal(kadm_handle, princ_ent, &keys, &n_keys); if (ret) { krb5_warn(context, ret, "kadm5_randkey_principal(%s)", argv[a]); krb5_free_principal(context, princ_ent); failed++; continue; } ret = kadm5_get_principal(kadm_handle, princ_ent, &princ, KADM5_PRINCIPAL | KADM5_KVNO | KADM5_ATTRIBUTES); if (ret) { krb5_warn(context, ret, "kadm5_get_principal(%s)", argv[a]); for (j = 0; j < n_keys; j++) krb5_free_keyblock_contents(context, &keys[j]); krb5_free_principal(context, princ_ent); failed++; continue; } if(!created && (princ.attributes & KRB5_KDB_DISALLOW_ALL_TIX)) krb5_warnx(context, "%s: disallow-all-tix flag set - clearing", argv[a]); princ.attributes &= (~KRB5_KDB_DISALLOW_ALL_TIX); mask = KADM5_ATTRIBUTES; if(created) { princ.kvno = 1; mask |= KADM5_KVNO; } ret = kadm5_modify_principal(kadm_handle, &princ, mask); if (ret) { krb5_warn(context, ret, "kadm5_modify_principal(%s)", argv[a]); for (j = 0; j < n_keys; j++) krb5_free_keyblock_contents(context, &keys[j]); krb5_free_principal(context, princ_ent); failed++; continue; } for(j = 0; j < n_keys; j++) { int do_add = TRUE; if (netypes) { size_t k; do_add = FALSE; for (k = 0; k < netypes; ++k) if (keys[j].keytype == etypes[k]) { do_add = TRUE; break; } } if (do_add) { entry.principal = princ_ent; entry.vno = princ.kvno; entry.keyblock = keys[j]; entry.timestamp = time (NULL); ret = krb5_kt_add_entry(context, keytab, &entry); if (ret) krb5_warn(context, ret, "krb5_kt_add_entry"); } krb5_free_keyblock_contents(context, &keys[j]); } kadm5_free_principal_ent(kadm_handle, &princ); krb5_free_principal(context, princ_ent); } out: free(etypes); if (kadm_handle) kadm5_destroy(kadm_handle); krb5_kt_close(context, keytab); return ret != 0 || failed > 0; }
/* * Function: krb5_changepw * * Purpose: Initialize and call lower level routines to change a password * * Arguments: * * princ_str principal name to use, optional * old_password old password * new_password new password * * Returns: * exit status of PAM_SUCCESS for success * 1 principal unknown * 2 old password wrong * 3 cannot initialize admin server session * 4 new passwd mismatch or error trying to change pw * 5 password not typed * 6 misc error * 7 incorrect usage * * Requires: * Passwords cannot be more than 255 characters long. * * Modifies: * * Changes the principal's password. * */ static int krb5_changepw( pam_handle_t *pamh, char *princ_str, char *old_password, char *new_password, int debug) { kadm5_ret_t code; krb5_principal princ = 0; char msg_ret[1024], 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; (void) memset((char *)¶ms, 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) snprintf(admin_realm, sizeof (admin_realm), "%s", krb5_princ_realm(context, princ)->data); 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, ¶ms, KADM5_STRUCT_VERSION, KADM5_API_VERSION_2, &server_handle); free(cpw_service); if (code != 0) { if (debug) syslog(LOG_DEBUG, "PAM-KRB5 (password): changepw: " "init_with_pw failed: (%s)", error_message(code)); krb5_free_principal(context, princ); return ((code == KADM5_BAD_PASSWORD) ? 2 : 3); } code = kadm5_chpass_principal_util(server_handle, princ, new_password, NULL /* don't need pw back */, msg_ret, sizeof (msg_ret)); if (code) { char msgs[2][PAM_MAX_MSG_SIZE]; (void) snprintf(msgs[0], PAM_MAX_MSG_SIZE, "%s", dgettext(TEXT_DOMAIN, "Kerberos password not changed: ")); (void) snprintf(msgs[1], PAM_MAX_MSG_SIZE, "%s", msg_ret); display_msgs(pamh, PAM_ERROR_MSG, 2, msgs); } krb5_free_principal(context, princ); (void) kadm5_destroy(server_handle); if (debug) syslog(LOG_DEBUG, "PAM-KRB5 (password): changepw: end %d", code); if (code == KRB5_LIBOS_CANTREADPWD) return (5); else if (code) return (4); else return (PAM_SUCCESS); }
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 *)¶ms, 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, ¶ms, 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); }
/* Modify Kerberos principal */ long modify_kerberos(char *username, int activate) { void *kadm_server_handle = NULL; krb5_context context = NULL; kadm5_ret_t status; krb5_principal princ; kadm5_principal_ent_rec dprinc; kadm5_policy_ent_rec defpol; kadm5_config_params realm_params; char admin_princ[256]; long mask = 0; #ifdef KERBEROS_TEST_REALM char ubuf[256]; sprintf(admin_princ, "moira/%s@%s", hostname, KERBEROS_TEST_REALM); sprintf(ubuf, "%s@%s", username, KERBEROS_TEST_REALM); username = ubuf; realm_params.realm = KERBEROS_TEST_REALM; realm_params.mask = KADM5_CONFIG_REALM; #else strcpy(admin_princ, MOIRA_SVR_PRINCIPAL); realm_params.mask = 0; #endif status = krb5_init_context(&context); if (status) return status; memset(&princ, 0, sizeof(princ)); memset(&dprinc, 0, sizeof(dprinc)); status = krb5_parse_name(context, username, &princ); if (status) return status; status = kadm5_init_with_skey(admin_princ, NULL, KADM5_ADMIN_SERVICE, &realm_params, KADM5_STRUCT_VERSION, KADM5_API_VERSION_2, NULL, &kadm_server_handle); if (status) goto cleanup; status = kadm5_get_principal(kadm_server_handle, princ, &dprinc, KADM5_PRINCIPAL_NORMAL_MASK); if (status) goto cleanup; mask |= KADM5_ATTRIBUTES; if (activate == 2) { /* Force password change */ dprinc.attributes |= KRB5_KDB_REQUIRES_PWCHANGE; dprinc.attributes &= ~KRB5_KDB_DISALLOW_ALL_TIX; } else if (activate == 1) { /* Enable principal */ dprinc.attributes &= ~KRB5_KDB_DISALLOW_ALL_TIX; dprinc.attributes &= ~KRB5_KDB_REQUIRES_PWCHANGE; } else { /* Disable principal */ dprinc.attributes |= KRB5_KDB_DISALLOW_ALL_TIX; dprinc.attributes &= ~KRB5_KDB_REQUIRES_PWCHANGE; } status = kadm5_modify_principal(kadm_server_handle, &dprinc, mask); cleanup: krb5_free_principal(context, princ); kadm5_free_principal_ent(kadm_server_handle, &dprinc); if (kadm_server_handle) kadm5_destroy(kadm_server_handle); return status; }
static void change (krb5_auth_context auth_context, krb5_principal admin_principal, uint16_t version, int s, struct sockaddr *sa, int sa_size, krb5_data *in_data) { krb5_error_code ret; char *client = NULL, *admin = NULL; const char *pwd_reason; kadm5_config_params conf; void *kadm5_handle = NULL; krb5_principal principal = NULL; krb5_data *pwd_data = NULL; char *tmp; ChangePasswdDataMS chpw; memset (&conf, 0, sizeof(conf)); memset(&chpw, 0, sizeof(chpw)); if (version == KRB5_KPASSWD_VERS_CHANGEPW) { ret = krb5_copy_data(context, in_data, &pwd_data); if (ret) { krb5_warn (context, ret, "krb5_copy_data"); reply_priv (auth_context, s, sa, sa_size, KRB5_KPASSWD_MALFORMED, "out out memory copying password"); return; } principal = admin_principal; } else if (version == KRB5_KPASSWD_VERS_SETPW) { size_t len; ret = decode_ChangePasswdDataMS(in_data->data, in_data->length, &chpw, &len); if (ret) { krb5_warn (context, ret, "decode_ChangePasswdDataMS"); reply_priv (auth_context, s, sa, sa_size, KRB5_KPASSWD_MALFORMED, "malformed ChangePasswdData"); return; } ret = krb5_copy_data(context, &chpw.newpasswd, &pwd_data); if (ret) { krb5_warn (context, ret, "krb5_copy_data"); reply_priv (auth_context, s, sa, sa_size, KRB5_KPASSWD_MALFORMED, "out out memory copying password"); goto out; } if (chpw.targname == NULL && chpw.targrealm != NULL) { krb5_warn (context, ret, "kadm5_init_with_password_ctx"); reply_priv (auth_context, s, sa, sa_size, KRB5_KPASSWD_MALFORMED, "targrealm but not targname"); goto out; } if (chpw.targname) { krb5_principal_data princ; princ.name = *chpw.targname; princ.realm = *chpw.targrealm; if (princ.realm == NULL) { ret = krb5_get_default_realm(context, &princ.realm); if (ret) { krb5_warnx (context, "kadm5_init_with_password_ctx: " "failed to allocate realm"); reply_priv (auth_context, s, sa, sa_size, KRB5_KPASSWD_SOFTERROR, "failed to allocate realm"); goto out; } } ret = krb5_copy_principal(context, &princ, &principal); if (*chpw.targrealm == NULL) free(princ.realm); if (ret) { krb5_warn(context, ret, "krb5_copy_principal"); reply_priv(auth_context, s, sa, sa_size, KRB5_KPASSWD_HARDERROR, "failed to allocate principal"); goto out; } } else principal = admin_principal; } else { krb5_warnx (context, "kadm5_init_with_password_ctx: unknown proto"); reply_priv (auth_context, s, sa, sa_size, KRB5_KPASSWD_HARDERROR, "Unknown protocol used"); return; } ret = krb5_unparse_name (context, admin_principal, &admin); if (ret) { krb5_warn (context, ret, "unparse_name failed"); reply_priv (auth_context, s, sa, sa_size, KRB5_KPASSWD_HARDERROR, "out of memory error"); goto out; } conf.realm = principal->realm; conf.mask |= KADM5_CONFIG_REALM; ret = kadm5_init_with_password_ctx(context, admin, NULL, KADM5_ADMIN_SERVICE, &conf, 0, 0, &kadm5_handle); if (ret) { krb5_warn (context, ret, "kadm5_init_with_password_ctx"); reply_priv (auth_context, s, sa, sa_size, 2, "Internal error"); goto out; } ret = krb5_unparse_name(context, principal, &client); if (ret) { krb5_warn (context, ret, "unparse_name failed"); reply_priv (auth_context, s, sa, sa_size, KRB5_KPASSWD_HARDERROR, "out of memory error"); goto out; } /* * Check password quality if not changing as administrator */ if (krb5_principal_compare(context, admin_principal, principal) == TRUE) { pwd_reason = kadm5_check_password_quality (context, principal, pwd_data); if (pwd_reason != NULL ) { krb5_warnx (context, "%s didn't pass password quality check with error: %s", client, pwd_reason); reply_priv (auth_context, s, sa, sa_size, KRB5_KPASSWD_SOFTERROR, pwd_reason); goto out; } krb5_warnx (context, "Changing password for %s", client); } else { ret = _kadm5_acl_check_permission(kadm5_handle, KADM5_PRIV_CPW, principal); if (ret) { krb5_warn (context, ret, "Check ACL failed for %s for changing %s password", admin, client); reply_priv (auth_context, s, sa, sa_size, KRB5_KPASSWD_HARDERROR, "permission denied"); goto out; } krb5_warnx (context, "%s is changing password for %s", admin, client); } ret = krb5_data_realloc(pwd_data, pwd_data->length + 1); if (ret) { krb5_warn (context, ret, "malloc: out of memory"); reply_priv (auth_context, s, sa, sa_size, KRB5_KPASSWD_HARDERROR, "Internal error"); goto out; } tmp = pwd_data->data; tmp[pwd_data->length - 1] = '\0'; ret = kadm5_s_chpass_principal_cond (kadm5_handle, principal, tmp); krb5_free_data (context, pwd_data); pwd_data = NULL; if (ret) { const char *str = krb5_get_error_message(context, ret); krb5_warnx(context, "kadm5_s_chpass_principal_cond: %s", str); reply_priv (auth_context, s, sa, sa_size, KRB5_KPASSWD_SOFTERROR, str ? str : "Internal error"); krb5_free_error_message(context, str); goto out; } reply_priv (auth_context, s, sa, sa_size, KRB5_KPASSWD_SUCCESS, "Password changed"); out: free_ChangePasswdDataMS(&chpw); if (principal != admin_principal) krb5_free_principal(context, principal); if (admin) free(admin); if (client) free(client); if (pwd_data) krb5_free_data(context, pwd_data); if (kadm5_handle) kadm5_destroy (kadm5_handle); }
bool kerberos_expire_password(const char *principal, time_t expires) { char *path, *user; const char *realm; krb5_context ctx; krb5_principal admin = NULL; krb5_principal princ = NULL; krb5_error_code code; kadm5_config_params params; kadm5_principal_ent_rec ent; void *handle; bool okay = false; /* Set up for making our call. */ path = test_file_path("config/admin-keytab"); if (path == NULL) return false; code = krb5_init_context(&ctx); if (code != 0) bail_krb5(ctx, code, "error initializing Kerberos"); admin = kerberos_keytab_principal(ctx, path); realm = krb5_principal_get_realm(ctx, admin); code = krb5_set_default_realm(ctx, realm); if (code != 0) bail_krb5(ctx, code, "cannot set default realm"); code = krb5_unparse_name(ctx, admin, &user); if (code != 0) bail_krb5(ctx, code, "cannot unparse admin principal"); code = krb5_parse_name(ctx, principal, &princ); if (code != 0) bail_krb5(ctx, code, "cannot parse principal %s", principal); /* * If the actual kadmin calls fail, we may be built with MIT Kerberos * against a Heimdal server or vice versa. Return false to skip the * tests. */ memset(¶ms, 0, sizeof(params)); params.realm = (char *) realm; params.mask = KADM5_CONFIG_REALM; code = kadm5_init_with_skey_ctx(ctx, user, path, KADM5_ADMIN_SERVICE, ¶ms, KADM5_STRUCT_VERSION, KADM5_API_VERSION, &handle); if (code != 0) { diag_krb5(ctx, code, "error initializing kadmin"); goto done; } memset(&ent, 0, sizeof(ent)); ent.principal = princ; ent.pw_expiration = expires; code = kadm5_modify_principal(handle, &ent, KADM5_PW_EXPIRATION); if (code == 0) okay = true; else diag_krb5(ctx, code, "error setting password expiration"); done: kadm5_destroy(handle); krb5_free_unparsed_name(ctx, user); krb5_free_principal(ctx, admin); krb5_free_principal(ctx, princ); krb5_free_context(ctx); test_file_path_free(path); return okay; }
int main(int argc, char *argv[]) { OM_uint32 minor_status; gss_buffer_desc in_buf; gss_OID nt_krb5_name_oid = (gss_OID)GSS_KRB5_NT_PRINCIPAL_NAME; auth_gssapi_name names[4]; kadm5_config_params params; verto_ctx *vctx; const char *pid_file = NULL; char **db_args = NULL, **tmpargs; int ret, i, db_args_size = 0, strong_random = 1, proponly = 0; setlocale(LC_ALL, ""); setvbuf(stderr, NULL, _IONBF, 0); names[0].name = names[1].name = names[2].name = names[3].name = NULL; names[0].type = names[1].type = names[2].type = names[3].type = nt_krb5_name_oid; progname = (strrchr(argv[0], '/') != NULL) ? strrchr(argv[0], '/') + 1 : argv[0]; memset(¶ms, 0, sizeof(params)); argc--, argv++; while (argc) { if (strcmp(*argv, "-x") == 0) { argc--, argv++; if (!argc) usage(); db_args_size++; tmpargs = realloc(db_args, sizeof(char *) * (db_args_size + 1)); if (tmpargs == NULL) { fprintf(stderr, _("%s: cannot initialize. Not enough " "memory\n"), progname); exit(1); } db_args = tmpargs; db_args[db_args_size - 1] = *argv; db_args[db_args_size] = NULL; } else if (strcmp(*argv, "-r") == 0) { argc--, argv++; if (!argc) usage(); params.realm = *argv; params.mask |= KADM5_CONFIG_REALM; argc--, argv++; continue; } else if (strcmp(*argv, "-m") == 0) { params.mkey_from_kbd = 1; params.mask |= KADM5_CONFIG_MKEY_FROM_KBD; } else if (strcmp(*argv, "-nofork") == 0) { nofork = 1; #ifdef USE_PASSWORD_SERVER } else if (strcmp(*argv, "-passwordserver") == 0) { kadm5_set_use_password_server(); #endif #ifndef DISABLE_IPROP } else if (strcmp(*argv, "-proponly") == 0) { proponly = 1; #endif } else if (strcmp(*argv, "-port") == 0) { argc--, argv++; if (!argc) usage(); params.kadmind_port = atoi(*argv); params.mask |= KADM5_CONFIG_KADMIND_PORT; } else if (strcmp(*argv, "-P") == 0) { argc--, argv++; if (!argc) usage(); pid_file = *argv; } else if (strcmp(*argv, "-W") == 0) { strong_random = 0; } else if (strcmp(*argv, "-p") == 0) { argc--, argv++; if (!argc) usage(); kdb5_util = *argv; } else if (strcmp(*argv, "-F") == 0) { argc--, argv++; if (!argc) usage(); dump_file = *argv; } else if (strcmp(*argv, "-K") == 0) { argc--, argv++; if (!argc) usage(); kprop = *argv; } else if (strcmp(*argv, "-k") == 0) { argc--, argv++; if (!argc) usage(); kprop_port = *argv; } else { break; } argc--, argv++; } if (argc != 0) usage(); ret = kadm5_init_krb5_context(&context); if (ret) { fprintf(stderr, _("%s: %s while initializing context, aborting\n"), progname, error_message(ret)); exit(1); } krb5_klog_init(context, "admin_server", progname, 1); ret = kadm5_init(context, "kadmind", NULL, NULL, ¶ms, KADM5_STRUCT_VERSION, KADM5_API_VERSION_4, db_args, &global_server_handle); if (ret) fail_to_start(ret, _("initializing")); ret = kadm5_get_config_params(context, 1, ¶ms, ¶ms); if (ret) fail_to_start(ret, _("getting config parameters")); if (!(params.mask & KADM5_CONFIG_REALM)) fail_to_start(0, _("Missing required realm configuration")); if (!(params.mask & KADM5_CONFIG_ACL_FILE)) fail_to_start(0, _("Missing required ACL file configuration")); ret = setup_loop(proponly, &vctx); if (ret) fail_to_start(ret, _("initializing network")); names[0].name = build_princ_name(KADM5_ADMIN_SERVICE, params.realm); names[1].name = build_princ_name(KADM5_CHANGEPW_SERVICE, params.realm); if (names[0].name == NULL || names[1].name == NULL) fail_to_start(0, _("Cannot build GSSAPI auth names")); ret = setup_kdb_keytab(); if (ret) fail_to_start(0, _("Cannot set up KDB keytab")); if (svcauth_gssapi_set_names(names, 2) == FALSE) fail_to_start(0, _("Cannot set GSSAPI authentication names")); /* if set_names succeeded, this will too */ in_buf.value = names[1].name; in_buf.length = strlen(names[1].name) + 1; (void)gss_import_name(&minor_status, &in_buf, nt_krb5_name_oid, &gss_changepw_name); svcauth_gssapi_set_log_badauth2_func(log_badauth, NULL); svcauth_gssapi_set_log_badverf_func(log_badverf, NULL); svcauth_gssapi_set_log_miscerr_func(log_miscerr, NULL); svcauth_gss_set_log_badauth2_func(log_badauth, NULL); svcauth_gss_set_log_badverf_func(log_badverf, NULL); svcauth_gss_set_log_miscerr_func(log_miscerr, NULL); if (svcauth_gss_set_svc_name(GSS_C_NO_NAME) != TRUE) fail_to_start(0, _("Cannot initialize GSSAPI service name")); ret = acl_init(context, params.acl_file); if (ret) fail_to_start(ret, _("initializing ACL file")); if (!nofork && daemon(0, 0) != 0) fail_to_start(errno, _("spawning daemon process")); if (pid_file != NULL) { ret = write_pid_file(pid_file); if (ret) fail_to_start(ret, _("creating PID file")); } krb5_klog_syslog(LOG_INFO, _("Seeding random number generator")); ret = krb5_c_random_os_entropy(context, strong_random, NULL); if (ret) fail_to_start(ret, _("getting random seed")); if (params.iprop_enabled == TRUE) { ulog_set_role(context, IPROP_MASTER); ret = ulog_map(context, params.iprop_logfile, params.iprop_ulogsize); if (ret) fail_to_start(ret, _("mapping update log")); if (nofork) { fprintf(stderr, _("%s: create IPROP svc (PROG=%d, VERS=%d)\n"), progname, KRB5_IPROP_PROG, KRB5_IPROP_VERS); } } if (kprop_port == NULL) kprop_port = getenv("KPROP_PORT"); krb5_klog_syslog(LOG_INFO, _("starting")); if (nofork) fprintf(stderr, _("%s: starting...\n"), progname); verto_run(vctx); krb5_klog_syslog(LOG_INFO, _("finished, exiting")); /* Clean up memory, etc */ svcauth_gssapi_unset_names(); kadm5_destroy(global_server_handle); loop_free(vctx); acl_finish(context); (void)gss_release_name(&minor_status, &gss_changepw_name); (void)gss_release_name(&minor_status, &gss_oldchangepw_name); for (i = 0; i < 4; i++) free(names[i].name); krb5_klog_close(context); krb5_free_context(context); exit(2); }
static krb5_error_code change_entry (krb5_keytab keytab, krb5_principal principal, krb5_kvno kvno, const char *realm, const char *admin_server, int server_port) { krb5_error_code ret; kadm5_config_params conf; void *kadm_handle; char *client_name; krb5_keyblock *keys; int num_keys; int i; ret = krb5_unparse_name (context, principal, &client_name); if (ret) { krb5_warn (context, ret, "krb5_unparse_name"); return ret; } memset (&conf, 0, sizeof(conf)); if(realm == NULL) realm = krb5_principal_get_realm(context, principal); conf.realm = strdup(realm); if (conf.realm == NULL) { free (client_name); krb5_set_error_message(context, ENOMEM, "malloc failed"); return ENOMEM; } conf.mask |= KADM5_CONFIG_REALM; if (admin_server) { conf.admin_server = strdup(admin_server); if (conf.admin_server == NULL) { free(client_name); free(conf.realm); krb5_set_error_message(context, ENOMEM, "malloc failed"); return ENOMEM; } conf.mask |= KADM5_CONFIG_ADMIN_SERVER; } if (server_port) { conf.kadmind_port = htons(server_port); conf.mask |= KADM5_CONFIG_KADMIND_PORT; } ret = kadm5_init_with_skey_ctx (context, client_name, keytab_string, KADM5_ADMIN_SERVICE, &conf, 0, 0, &kadm_handle); free(conf.admin_server); free(conf.realm); if (ret) { krb5_warn (context, ret, "kadm5_c_init_with_skey_ctx: %s:", client_name); free (client_name); return ret; } ret = kadm5_randkey_principal (kadm_handle, principal, &keys, &num_keys); kadm5_destroy (kadm_handle); if (ret) { krb5_warn(context, ret, "kadm5_randkey_principal: %s:", client_name); free (client_name); return ret; } free (client_name); for (i = 0; i < num_keys; ++i) { krb5_keytab_entry new_entry; new_entry.principal = principal; new_entry.timestamp = time (NULL); new_entry.vno = kvno + 1; new_entry.keyblock = keys[i]; ret = krb5_kt_add_entry (context, keytab, &new_entry); if (ret) krb5_warn (context, ret, "krb5_kt_add_entry"); krb5_free_keyblock_contents (context, &keys[i]); } return ret; }
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 *)¶ms, 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, ¶ms, 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); }
int main(int argc, char **argv) { krb5_error_code ret; char **files; kadm5_config_params conf; int optidx = 0; int exit_status = 0; setprogname(argv[0]); ret = krb5_init_context(&context); if (ret) errx (1, "krb5_init_context failed: %d", ret); if(getarg(args, num_args, argc, argv, &optidx)) usage(1); if (help_flag) usage (0); if (version_flag) { print_version(NULL); exit(0); } argc -= optidx; argv += optidx; if (config_file == NULL) { asprintf(&config_file, "%s/kdc.conf", hdb_db_dir(context)); if (config_file == NULL) errx(1, "out of memory"); } ret = krb5_prepend_config_files_default(config_file, &files); if (ret) krb5_err(context, 1, ret, "getting configuration files"); ret = krb5_set_config_files(context, files); krb5_free_config_files(files); if(ret) krb5_err(context, 1, ret, "reading configuration files"); memset(&conf, 0, sizeof(conf)); if(realm) { krb5_set_default_realm(context, realm); /* XXX should be fixed some other way */ conf.realm = realm; conf.mask |= KADM5_CONFIG_REALM; } if (admin_server) { conf.admin_server = admin_server; conf.mask |= KADM5_CONFIG_ADMIN_SERVER; } if (server_port) { conf.kadmind_port = htons(server_port); conf.mask |= KADM5_CONFIG_KADMIND_PORT; } if (keyfile) { conf.stash_file = keyfile; conf.mask |= KADM5_CONFIG_STASH_FILE; } if(local_flag) { int i; kadm5_setup_passwd_quality_check (context, check_library, check_function); for (i = 0; i < policy_libraries.num_strings; i++) { ret = kadm5_add_passwd_quality_verifier(context, policy_libraries.strings[i]); if (ret) krb5_err(context, 1, ret, "kadm5_add_passwd_quality_verifier"); } ret = kadm5_add_passwd_quality_verifier(context, NULL); if (ret) krb5_err(context, 1, ret, "kadm5_add_passwd_quality_verifier"); ret = kadm5_s_init_with_password_ctx(context, KADM5_ADMIN_SERVICE, NULL, KADM5_ADMIN_SERVICE, &conf, 0, 0, &kadm_handle); } else if (mit_flag) { ret = kadm5_mit_init_with_password_ctx(context, client_name, NULL, &conf, 0, 0, &kadm_handle); } else if (ad_flag) { if (client_name == NULL) krb5_errx(context, 1, "keytab mode require principal name"); ret = kadm5_ad_init_with_password_ctx(context, client_name, NULL, KADM5_ADMIN_SERVICE, &conf, 0, 0, &kadm_handle); } else if (keytab) { if (client_name == NULL) krb5_errx(context, 1, "keytab mode require principal name"); ret = kadm5_c_init_with_skey_ctx(context, client_name, keytab, KADM5_ADMIN_SERVICE, &conf, 0, 0, &kadm_handle); } else ret = kadm5_c_init_with_password_ctx(context, client_name, NULL, KADM5_ADMIN_SERVICE, &conf, 0, 0, &kadm_handle); if(ret) krb5_err(context, 1, ret, "kadm5_init_with_password"); signal(SIGINT, SIG_IGN); /* ignore signals for now, the sl command parser will handle SIGINT its own way; we should really take care of this in each function, f.i `get' might be interruptable, but not `create' */ if (argc != 0) { ret = sl_command (commands, argc, argv); if(ret == -1) krb5_warnx (context, "unrecognized command: %s", argv[0]); else if (ret == -2) ret = 0; if(ret != 0) exit_status = 1; } else { while(!exit_seen) { ret = sl_command_loop(commands, "kadmin> ", NULL); if (ret == -2) exit_seen = 1; else if (ret != 0) exit_status = 1; } } kadm5_destroy(kadm_handle); krb5_free_context(context); return exit_status; }
int main(int argc, char **argv) { krb5_context context; krb5_keytab kt; krb5_keytab_entry ktent; krb5_encrypt_block eblock; krb5_creds my_creds; krb5_get_init_creds_opt *opt; kadm5_principal_ent_rec princ_ent; krb5_principal princ, server; char pw[16]; char *whoami, *principal, *authprinc, *authpwd; krb5_data pwdata; void *handle; int ret, test, encnum; unsigned int i; whoami = argv[0]; if (argc < 2 || argc > 4) { fprintf(stderr, "Usage: %s principal [authuser] [authpwd]\n", whoami); exit(1); } principal = argv[1]; authprinc = (argc > 2) ? argv[2] : argv[0]; authpwd = (argc > 3) ? argv[3] : NULL; /* * Setup. Initialize data structures, open keytab, open connection * to kadm5 server. */ memset(&context, 0, sizeof(context)); kadm5_init_krb5_context(&context); ret = krb5_parse_name(context, principal, &princ); if (ret) { com_err(whoami, ret, "while parsing principal name %s", principal); exit(1); } if((ret = krb5_build_principal_ext(context, &server, krb5_princ_realm(kcontext, princ)->length, krb5_princ_realm(kcontext, princ)->data, tgtname.length, tgtname.data, krb5_princ_realm(kcontext, princ)->length, krb5_princ_realm(kcontext, princ)->data, 0))) { com_err(whoami, ret, "while building server name"); exit(1); } ret = krb5_kt_default(context, &kt); if (ret) { com_err(whoami, ret, "while opening keytab"); exit(1); } ret = kadm5_init(context, authprinc, authpwd, KADM5_ADMIN_SERVICE, NULL, KADM5_STRUCT_VERSION, KADM5_API_VERSION_4, NULL, &handle); if (ret) { com_err(whoami, ret, "while initializing connection"); exit(1); } /* these pw's don't need to be secure, just different every time */ SRAND((RAND_TYPE)time((void *) NULL)); pwdata.data = pw; pwdata.length = sizeof(pw); /* * For each test: * * For each enctype in the test, construct a random password/key. * Assign all keys to principal with kadm5_setkey_principal. Add * each key to the keytab, and acquire an initial ticket with the * keytab (XXX can I specify the kvno explicitly?). If * krb5_get_init_creds_keytab succeeds, then the keys were set * successfully. */ for (test = 0; tests[test] != NULL; test++) { krb5_keyblock *testp = tests[test]; kadm5_key_data *extracted; int n_extracted, match; printf("+ Test %d:\n", test); for (encnum = 0; testp[encnum].magic != -1; encnum++) { for (i = 0; i < sizeof(pw); i++) pw[i] = (RAND() % 26) + '0'; /* XXX */ krb5_use_enctype(context, &eblock, testp[encnum].enctype); ret = krb5_string_to_key(context, &eblock, &testp[encnum], &pwdata, NULL); if (ret) { com_err(whoami, ret, "while converting string to key"); exit(1); } } /* now, encnum == # of keyblocks in testp */ ret = kadm5_setkey_principal(handle, princ, testp, encnum); if (ret) { com_err(whoami, ret, "while setting keys"); exit(1); } ret = kadm5_get_principal(handle, princ, &princ_ent, KADM5_KVNO); if (ret) { com_err(whoami, ret, "while retrieving principal"); exit(1); } ret = kadm5_get_principal_keys(handle, princ, 0, &extracted, &n_extracted); if (ret) { com_err(whoami, ret, "while extracting keys"); exit(1); } for (encnum = 0; testp[encnum].magic != -1; encnum++) { printf("+ enctype %d\n", testp[encnum].enctype); for (match = 0; match < n_extracted; match++) { if (extracted[match].key.enctype == testp[encnum].enctype) break; } if (match >= n_extracted) { com_err(whoami, KRB5_WRONG_ETYPE, "while matching enctypes"); exit(1); } if (extracted[match].key.length != testp[encnum].length || memcmp(extracted[match].key.contents, testp[encnum].contents, testp[encnum].length) != 0) { com_err(whoami, KRB5_KDB_NO_MATCHING_KEY, "verifying keys"); exit(1); } memset(&ktent, 0, sizeof(ktent)); ktent.principal = princ; ktent.key = testp[encnum]; ktent.vno = princ_ent.kvno; ret = krb5_kt_add_entry(context, kt, &ktent); if (ret) { com_err(whoami, ret, "while adding keytab entry"); exit(1); } memset(&my_creds, 0, sizeof(my_creds)); my_creds.client = princ; my_creds.server = server; ktypes[0] = testp[encnum].enctype; ret = krb5_get_init_creds_opt_alloc(context, &opt); if (ret) { com_err(whoami, ret, "while allocating gic opts"); exit(1); } krb5_get_init_creds_opt_set_etype_list(opt, ktypes, 1); ret = krb5_get_init_creds_keytab(context, &my_creds, princ, kt, 0, NULL /* in_tkt_service */, opt); krb5_get_init_creds_opt_free(context, opt); if (ret) { com_err(whoami, ret, "while acquiring initial ticket"); exit(1); } krb5_free_cred_contents(context, &my_creds); /* since I can't specify enctype explicitly ... */ ret = krb5_kt_remove_entry(context, kt, &ktent); if (ret) { com_err(whoami, ret, "while removing keytab entry"); exit(1); } } (void)kadm5_free_kadm5_key_data(context, n_extracted, extracted); } ret = krb5_kt_close(context, kt); if (ret) { com_err(whoami, ret, "while closing keytab"); exit(1); } ret = kadm5_destroy(handle); if (ret) { com_err(whoami, ret, "while closing kadmin connection"); exit(1); } krb5_free_principal(context, princ); krb5_free_principal(context, server); krb5_free_context(context); return 0; }