# # Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # Copyright (c) 2018, Joyent, Inc. PROG= kpasswd OBJS = tty_kpasswd.o kpasswd.o SRCS = $(OBJS:.o=.c) CLOBBERFILES += $(TESTPROG) include ../../../Makefile.cmd include $(SRC)/lib/gss_mechs/mech_krb5/Makefile.mech_krb5 POFILE = $(PROG).po POFILES = generic.po # # Override $ROOTLIB # KRB5LIBDIR= $(ROOT)$(KERBLIBDIR) CPPFLAGS += -I$(SRC)/lib/gss_mechs/mech_krb5/include \ -I$(SRC)/uts/common/gssapi/include/ \ -I$(SRC)/uts/common/gssapi/mechs/krb5/include \ -I$(SRC)/lib/krb5 \ -DHAVE_LIBSOCKET=1 -DHAVE_LIBNSL=1 -DHAVE_UNISTD_H=1 \ -DHAVE_SYS_TIMEB_H=1 -DHAVE_ALLOCA_H=1 -DHAVE_FTIME=1 \ -DHAVE_TIMEZONE -DUSE_KADM5_API_VERSION=2 CERRWARN += -Wno-parentheses CERRWARN += -Wno-unused-variable CERRWARN += -Wno-unused-function # not linted SMATCH=off LDFLAGS += $(KRUNPATH) $(KERBRUNPATH) LDLIBS += -L $(KRB5LIBDIR) LDLIBS += $(KMECHLIB) $(KCLNTLIB) .KEEP_STATE: all: $(PROG) $(PROG): $(OBJS) $(LINK.c) $(OBJS) -o $@ $(LDLIBS) $(POST_PROCESS) install: $(KRB5PROG) clean: $(RM) $(OBJS) include ../../../Makefile.targ $(POFILE): $(DERIVED_FILES) .WAIT $(POFILES) $(RM) $@ $(CAT) $(POFILES) > $@ $(RM) generic.po generic.po: $(RM) messages.po $(XGETTEXT) $(XGETFLAGS) `$(GREP) -l gettext *.[ch]` $(SED) "/^domain/d" messages.po > $@ $(RM) messages.po /* * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING * * Openvision retains the copyright to derivative works of * this source code. Do *NOT* create a derivative of this * source code before consulting with your legal department. * Do *NOT* integrate *ANY* of this source code into another * product before consulting with your legal department. * * For further information, read the top-level Openvision * copyright which is contained in the top-level MIT Kerberos * copyright. * * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING * */ /* * Copyright 1993-1994 OpenVision Technologies, Inc., All Rights Reserved. * * $Header$ * * */ static char rcsid[] = "$Id: kpasswd.c 17258 2005-06-21 01:36:03Z raeburn $"; #include #include #include "kpasswd_strings.h" #define string_text error_message #include "kpasswd.h" #include #include #include #include extern char *whoami; extern void display_intro_message(); extern long read_old_password(); extern long read_new_password(); #define MISC_EXIT_STATUS 6 /* * Function: kpasswd * * Purpose: Initialize and call lower level routines to change a password * * Arguments: * * context (r) krb5_context to use * argc/argv (r) principal name to use, optional * read_old_password (f) function to read old password * read_new_password (f) function to read new and change password * display_intro_message (f) function to display intro message * whoami (extern) argv[0] * * Returns: * exit status of 0 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. * * Effects: * * If argc is 2, the password for the principal specified in argv[1] * is changed; otherwise, the principal of the default credential * cache or username is used. display_intro_message is called with * the arguments KPW_STR_CHANGING_PW_FOR and the principal name. * read_old_password is then called to prompt for the old password. * The admin system is then initialized, the principal's policy * retrieved and explained, if appropriate, and finally * read_new_password is called to read the new password and change the * principal's password (presumably ovsec_kadm_chpass_principal). * admin system is de-initialized before the function returns. * * Modifies: * * Changes the principal's password. * */ int kpasswd(context, argc, argv) krb5_context context; int argc; char *argv[]; { kadm5_ret_t code; krb5_ccache ccache = NULL; krb5_principal princ = 0; char *princ_str; struct passwd *pw = 0; unsigned int pwsize; char password[255]; /* I don't really like 255 but that's what kinit uses */ char msg_ret[1024], admin_realm[1024]; kadm5_principal_ent_rec principal_entry; kadm5_policy_ent_rec policy_entry; void *server_handle; kadm5_config_params params; char *cpw_service; memset((char *)¶ms, 0, sizeof (params)); memset(&principal_entry, 0, sizeof (principal_entry)); memset(&policy_entry, 0, sizeof (policy_entry)); if (argc > 2) { com_err(whoami, KPW_STR_USAGE, 0); return(7); /*NOTREACHED*/ } /************************************ * Get principal name to change * ************************************/ /* Look on the command line first, followed by the default credential cache, followed by defaulting to the Unix user name */ if (argc == 2) princ_str = strdup(argv[1]); else { code = krb5_cc_default(context, &ccache); /* If we succeed, find who is in the credential cache */ if (code == 0) { /* Get default principal from cache if one exists */ code = krb5_cc_get_principal(context, ccache, &princ); /* if we got a principal, unparse it, otherwise get out of the if with an error code */ (void) krb5_cc_close(context, ccache); if (code == 0) { code = krb5_unparse_name(context, princ, &princ_str); if (code != 0) { com_err(whoami, code, string_text(KPW_STR_UNPARSE_NAME)); return(MISC_EXIT_STATUS); } } } /* this is a crock.. we want to compare against */ /* "KRB5_CC_DOESNOTEXIST" but there is no such error code, and */ /* both the file and stdio types return FCC_NOFILE. If there is */ /* ever another ccache type (or if the error codes are ever */ /* fixed), this code will have to be updated. */ if (code && code != KRB5_FCC_NOFILE) { com_err(whoami, code, string_text(KPW_STR_WHILE_LOOKING_AT_CC)); return(MISC_EXIT_STATUS); } /* if either krb5_cc failed check the passwd file */ if (code != 0) { pw = getpwuid( getuid()); if (pw == NULL) { com_err(whoami, 0, string_text(KPW_STR_NOT_IN_PASSWD_FILE)); return(MISC_EXIT_STATUS); } princ_str = strdup(pw->pw_name); } } display_intro_message(string_text(KPW_STR_CHANGING_PW_FOR), princ_str); /* Need to get a krb5_principal, unless we started from with one from the credential cache */ if (! princ) { code = krb5_parse_name (context, princ_str, &princ); if (code != 0) { com_err(whoami, code, string_text(KPW_STR_PARSE_NAME), princ_str); free(princ_str); return(MISC_EXIT_STATUS); } } pwsize = sizeof(password); code = read_old_password(context, password, &pwsize); if (code != 0) { memset(password, 0, sizeof(password)); com_err(whoami, code, string_text(KPW_STR_WHILE_READING_PASSWORD)); krb5_free_principal(context, princ); free(princ_str); return(MISC_EXIT_STATUS); } if (pwsize == 0) { memset(password, 0, sizeof(password)); com_err(whoami, 0, string_text(KPW_STR_NO_PASSWORD_READ)); krb5_free_principal(context, princ); free(princ_str); return(5); } snprintf(admin_realm, sizeof (admin_realm), 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)) { fprintf(stderr, gettext("%s: unable to get host based " "service name for realm %s\n"), whoami, admin_realm); exit(1); } code = kadm5_init_with_password(princ_str, password, cpw_service, ¶ms, KADM5_STRUCT_VERSION, KADM5_API_VERSION_2, NULL, &server_handle); free(cpw_service); if (code != 0) { if (code == KADM5_BAD_PASSWORD) com_err(whoami, 0, string_text(KPW_STR_OLD_PASSWORD_INCORRECT)); else com_err(whoami, 0, string_text(KPW_STR_CANT_OPEN_ADMIN_SERVER), admin_realm, error_message(code)); krb5_free_principal(context, princ); free(princ_str); return ((code == KADM5_BAD_PASSWORD) ? 2 : 3); } /* * we can only check the policy if the server speaks * RPCSEC_GSS */ if (_kadm5_get_kpasswd_protocol(server_handle) == KRB5_CHGPWD_RPCSEC) { /* Explain policy restrictions on new password if any. */ /* * 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) { com_err(whoami, 0, string_text((code == KADM5_UNK_PRINC) ? KPW_STR_PRIN_UNKNOWN : KPW_STR_CANT_GET_POLICY_INFO), princ_str); krb5_free_principal(context, princ); free(princ_str); (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 */ com_err(whoami, 0, string_text(KPW_STR_CANT_GET_POLICY_INFO), princ_str); (void) kadm5_free_principal_ent(server_handle, &principal_entry); krb5_free_principal(context, princ); free(princ_str); free(princ_str); (void) kadm5_destroy(server_handle); return (MISC_EXIT_STATUS); } com_err(whoami, 0, string_text(KPW_STR_POLICY_EXPLANATION), princ_str, principal_entry.policy, policy_entry.pw_min_length, policy_entry.pw_min_classes); if (code = kadm5_free_principal_ent(server_handle, &principal_entry)) { (void) kadm5_free_policy_ent(server_handle, &policy_entry); krb5_free_principal(context, princ); free(princ_str); com_err(whoami, code, string_text(KPW_STR_WHILE_FREEING_PRINCIPAL)); (void) kadm5_destroy(server_handle); return (MISC_EXIT_STATUS); } if (code = kadm5_free_policy_ent(server_handle, &policy_entry)) { krb5_free_principal(context, princ); free(princ_str); com_err(whoami, code, string_text(KPW_STR_WHILE_FREEING_POLICY)); (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); free(princ_str); com_err(whoami, code, string_text(KPW_STR_WHILE_FREEING_PRINCIPAL)); (void) kadm5_destroy(server_handle); return (MISC_EXIT_STATUS); } } } /* if protocol == KRB5_CHGPWD_RPCSEC */ pwsize = sizeof(password); code = read_new_password(server_handle, password, &pwsize, msg_ret, sizeof (msg_ret), princ); memset(password, 0, sizeof(password)); if (code) com_err(whoami, 0, msg_ret); krb5_free_principal(context, princ); free(princ_str); (void) kadm5_destroy(server_handle); if (code == KRB5_LIBOS_CANTREADPWD) return(5); else if (code) return(4); else return(0); } /* * kadmin/passwd/kpasswd.h * * Copyright 2001 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. * * * Prototypes for the kpasswd program callback functions. */ #ifndef __KPASSWD_H__ #define __KPASSWD_H__ int kpasswd(krb5_context context, int argc, char *argv[]); long read_old_password(krb5_context context, char *password, unsigned int *pwsize); long read_new_password(void *server_handle, char *password, unsigned int *pwsize, char *msg_ret, int msg_len, krb5_principal princ); void display_intro_message(const char *fmt_string, const char *arg_string); #endif /* __KPASSWD_H__ */ /* * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING * * Openvision retains the copyright to derivative works of * this source code. Do *NOT* create a derivative of this * source code before consulting with your legal department. * Do *NOT* integrate *ANY* of this source code into another * product before consulting with your legal department. * * For further information, read the top-level Openvision * copyright which is contained in the top-level MIT Kerberos * copyright. * * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING * */ #include /* * kpasswd_strings.h: * This file is automatically generated; please do not edit it. */ #define KPW_STR_USAGE (-1767084800L) #define KPW_STR_PRIN_UNKNOWN (-1767084799L) #define KPW_STR_WHILE_LOOKING_AT_CC (-1767084798L) #define KPW_STR_OLD_PASSWORD_INCORRECT (-1767084797L) #define KPW_STR_CANT_OPEN_ADMIN_SERVER (-1767084796L) #define KPW_STR_NEW_PASSWORD_MISMATCH (-1767084795L) #define KPW_STR_PASSWORD_CHANGED (-1767084794L) #define KPW_STR_PASSWORD_NOT_CHANGED (-1767084793L) #define KPW_STR_PARSE_NAME (-1767084792L) #define KPW_STR_UNPARSE_NAME (-1767084791L) #define KPW_STR_NOT_IN_PASSWD_FILE (-1767084790L) #define KPW_STR_CHANGING_PW_FOR (-1767084789L) #define KPW_STR_OLD_PASSWORD_PROMPT (-1767084788L) #define KPW_STR_WHILE_READING_PASSWORD (-1767084787L) #define KPW_STR_NO_PASSWORD_READ (-1767084786L) #define KPW_STR_WHILE_TRYING_TO_CHANGE (-1767084785L) #define KPW_STR_WHILE_DESTROYING_ADMIN_SESSION (-1767084784L) #define KPW_STR_WHILE_FREEING_PRINCIPAL (-1767084783L) #define KPW_STR_WHILE_FREEING_POLICY (-1767084782L) #define KPW_STR_CANT_GET_POLICY_INFO (-1767084781L) #define KPW_STR_POLICY_EXPLANATION (-1767084780L) #define ERROR_TABLE_BASE_kpws (-1767084800L) extern const struct error_table et_kpws_error_table; #if !defined(_WIN32) /* for compatibility with older versions... */ extern void initialize_kpws_error_table (void) /*@modifies internalState@*/; #else #define initialize_kpws_error_table() #endif #if !defined(_WIN32) #define init_kpws_err_tbl initialize_kpws_error_table #define kpws_err_base ERROR_TABLE_BASE_kpws #endif /* * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING * * Openvision retains the copyright to derivative works of * this source code. Do *NOT* create a derivative of this * source code before consulting with your legal department. * Do *NOT* integrate *ANY* of this source code into another * product before consulting with your legal department. * * For further information, read the top-level Openvision * copyright which is contained in the top-level MIT Kerberos * copyright. * * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING * */ /* * Copyright 1993-1994 OpenVision Technologies, Inc., All Rights Reserved. * * $Header: /cvs/krbdev/krb5/src/kadmin/passwd/tty_kpasswd.c,v 1.9 2001/02/26 18:22:08 epeisach Exp $ * * */ static char rcsid[] = "$Id: tty_kpasswd.c,v 1.9 2001/02/26 18:22:08 epeisach Exp $"; #include #include #include "kpasswd_strings.h" #define string_text error_message #include "kpasswd.h" #include #include #include #include #include char *whoami; void display_intro_message(fmt_string, arg_string) const char *fmt_string; const char *arg_string; { com_err(whoami, 0, fmt_string, arg_string); } long read_old_password(context, password, pwsize) krb5_context context; char *password; unsigned int *pwsize; { long code = krb5_read_password(context, (char *) string_text(KPW_STR_OLD_PASSWORD_PROMPT), 0, password, pwsize); return code; } long read_new_password(server_handle, password, pwsize, msg_ret, msg_len, princ) void *server_handle; char *password; unsigned int *pwsize; char *msg_ret; int msg_len; krb5_principal princ; { return (kadm5_chpass_principal_util(server_handle, princ, NULL, NULL /* don't need new pw back */, msg_ret, msg_len)); } /* * main() for tty version of kpasswd.c */ int main(argc, argv) int argc; char *argv[]; { krb5_context context; int retval; whoami = (whoami = strrchr(argv[0], '/')) ? whoami + 1 : argv[0]; (void) setlocale(LC_ALL, ""); #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */ #endif (void) textdomain(TEXT_DOMAIN); retval = krb5_init_context(&context); if (retval) { com_err(whoami, retval, gettext("initializing krb5 context")); exit(retval); } /* initialize_kpws_error_table(); SUNWresync121 */ retval = kpasswd(context, argc, argv); if (!retval) printf(string_text(KPW_STR_PASSWORD_CHANGED)); exit(retval); }