/* The idea behind this is to allow you to run krb5 in sync with a kaserver. We're using it for migration. To link this into something, -Dkadm5_chpass_principal=_kadm5_chpass_principal You also need to -I/usr/(mumble)/include/afs, as well as -L/usr/(mumble)/lib/afs -lkauth -lauth -lubik -lrxkad -lsys -lrx -llwp ../lib/des/.libs/libdes.a /usr/local/lib/afs/util.a It expects kadmin/admin to exist in the local keytab with the same key as the kaserver and to be an admin in the kaserver If you have questions you may email shadow@dementia.org Derrick J Brashear 13 July 2000 */ #include "kpasswd_locl.h" #include #include #include #include #include #include #include #include #define EncryptionKey _afs_EncryptionKey #include #undef EncryptionKey #include #ifdef HAVE_SYS_UN_H #include #endif #include #include #include #define PWSERV_ADMIN "kadmin" #define ADMIN_SINST "admin" #define princ_num_comp(P) ((P)->name.name_string.len) #define princ_type(P) ((P)->name.name_type) #define princ_comp(P) ((P)->name.name_string.val) #define princ_ncomp(P, N) ((P)->name.name_string.val[(N)]) #define princ_realm(P) ((P)->realm) void add_to_error_table(struct et_list *new_table) { } kadm5_ret_t _kadm5_chpass_principal(void *server_handle, krb5_principal princ, char *password) { kadm5_ret_t ret; ret = kadm5_afs_chpass_principal(server_handle, princ, password); if (!ret) kadm5_chpass_principal(server_handle, princ, password); return ret; } #define NOT_MY_KEY kadm5_ret_t kadm5_afs_chpass_principal(void *server_handle, krb5_principal princ, char *password) { kadm5_server_context *scontext = server_handle; krb5_context context = scontext->context; krb5_principal principal; kadm5_ret_t ret; char *rname; char *rinstance = NULL; char *rrealm; char cell[MAXKTCREALMLEN]; char realm[MAXKTCREALMLEN]; char *lcell; /* local cellname */ #ifndef NOT_MY_KEY struct kaentryinfo tentry; #endif struct ubik_client *conn; struct ktc_encryptionKey mitkey, newkey; krb5_keyblock *key; krb5_salt salt; struct ktc_token token; int i,local=0; rname = princ_ncomp(princ, 0); rrealm = princ_realm(princ); if (princ_num_comp(princ) > 1) rinstance = princ_ncomp(princ, 1); if ((ka_Init(0)) || !(lcell = ka_LocalCell())) { return(KADM5_FAILURE); } strcpy (realm, lcell); ret = ka_CellToRealm (realm, realm, &local); if (ret || strcmp(realm, rrealm)) return(KADM5_FAILURE); lcstring (cell, realm, sizeof(cell)); ret = krb5_make_principal(context, &principal, NULL, PWSERV_ADMIN, ADMIN_SINST, NULL); if (ret) return ret; ret = krb5_kt_read_service_key(context, "HDB:", principal, 0/*vno*/, ETYPE_DES_CBC_MD5, &key); if (ret) return ret; memcpy(&mitkey, key->keyvalue.data, 8); if (!ret) ret = ka_GetAdminToken (PWSERV_ADMIN, ADMIN_SINST, realm, &mitkey, 1000, &token, /*!new*/0); memset(&mitkey, 0, 8); if (!ret) ret = ka_AuthServerConn (realm, KA_MAINTENANCE_SERVICE, &token, &conn); /* Salt it v4 */ salt.salttype = KRB5_PW_SALT; salt.saltvalue.length = 0; salt.saltvalue.data = NULL; krb5_string_to_key_salt(context, ETYPE_DES_CBC_MD5, password, salt, key); memcpy(&newkey, key->keyvalue.data, 8); if (!ret) ret = ka_ChangePassword (rname, rinstance, conn, 0, &newkey); else conn = 0; #if 0 if (!code) code = ubik_Call (KAM_SetPassword, conn, 0, rname, rinstance, 0, newkey); #endif /* clean up */ if (conn) ubik_ClientDestroy(conn); rx_Finalize(); #ifndef NOT_MY_KEY if (!ret) ret = ka_GetAdminToken(rname, rinstance, realm, &newkey, 1000, &token, /*!new*/0); if (!ret) ret = ka_AuthServerConn(realm, KA_MAINTENANCE_SERVICE, &token, &conn); if (!ret) ret = ubik_Call(KAM_GetEntry, conn, 0, rname, rinstance, KAMAJORVERSION, &tentry); else conn = 0; if (!ret) ret = ubik_Call(KAM_SetPassword, conn, 0, rname, rinstance, tentry.key_version, &newkey); /* clean up */ if (conn) ubik_ClientDestroy(conn); rx_Finalize(); #endif memset(&newkey, 0, 8); krb5_free_keyblock_contents(context, key); return(ret); }