KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_get_validated_creds(krb5_context context, krb5_creds *creds, krb5_principal client, krb5_ccache ccache, char *service) { krb5_verify_init_creds_opt vopt; krb5_principal server; krb5_error_code ret; if (krb5_principal_compare(context, creds->client, client) != TRUE) { krb5_set_error_message(context, KRB5_PRINC_NOMATCH, N_("Validation credentials and client " "doesn't match", "")); return KRB5_PRINC_NOMATCH; } ret = krb5_sname_to_principal (context, NULL, service, KRB5_NT_SRV_HST, &server); if(ret) return ret; krb5_verify_init_creds_opt_init(&vopt); ret = krb5_verify_init_creds(context, creds, server, NULL, NULL, &vopt); krb5_free_principal(context, server); return ret; }
struct passwd *checkpw (struct passwd *pw,char *pass,int argc,char *argv[]) { char svrnam[MAILTMPLEN],cltnam[MAILTMPLEN]; krb5_context ctx; krb5_timestamp now; krb5_principal service; krb5_ccache ccache; krb5_error_code code; krb5_creds *crd = (krb5_creds *) memset (fs_get (sizeof (krb5_creds)),0, sizeof (krb5_creds)); struct passwd *ret = NIL; if (*pass) { /* only if password non-empty */ /* make service name */ sprintf (svrnam,"%.80s@%.512s", (char *) mail_parameters (NIL,GET_SERVICENAME,NIL), tcp_serverhost ()); /* make client name with principal */ sprintf (cltnam,"%.80s/%.80s",pw->pw_name, (char *) mail_parameters (NIL,GET_SERVICENAME,NIL)); /* get a context */ if (!krb5_init_context (&ctx)) { /* get time, client and server principals */ if (!krb5_timeofday (ctx,&now) && /* Normally, kerb_cp_svr_name (defined/set in env_unix.c) is NIL, so * only the user name is used as a client principal. A few sites want * to have separate client principals for different services, but many * other sites vehemently object... */ !krb5_parse_name (ctx,kerb_cp_svr_name ? cltnam : pw->pw_name, &crd->client) && !krb5_parse_name (ctx,svrnam,&service) && !krb5_build_principal_ext(ctx,&crd->server, krb5_princ_realm (ctx,crd->client)->length, krb5_princ_realm (ctx,crd->client)->data, KRB5_TGS_NAME_SIZE,KRB5_TGS_NAME, krb5_princ_realm (ctx,crd->client)->length, krb5_princ_realm (ctx,crd->client)->data, 0)) { /* expire in 3 minutes */ crd->times.endtime = now + (3 * 60); if (krb5_cc_resolve (ctx,"MEMORY:pwk",&ccache) || krb5_cc_initialize (ctx,ccache,crd->client)) ccache = 0; if (!krb5_get_in_tkt_with_password (ctx,NIL,NIL,NIL,NIL,pass,ccache, crd,0) && !krb5_verify_init_creds (ctx,crd,service,0,ccache ? &ccache : 0,0)) ret = pw; krb5_free_creds (ctx,crd);/* flush creds and service principal */ krb5_free_principal (ctx,service); } krb5_free_context (ctx); /* don't need context any more */ } } return ret; }
static krb5_error_code verify_common (krb5_context context, krb5_principal principal, krb5_ccache ccache, krb5_keytab keytab, krb5_boolean secure, const char *service, krb5_creds cred) { krb5_error_code ret; krb5_principal server; krb5_verify_init_creds_opt vopt; krb5_ccache id; ret = krb5_sname_to_principal (context, NULL, service, KRB5_NT_SRV_HST, &server); if(ret) return ret; krb5_verify_init_creds_opt_init(&vopt); krb5_verify_init_creds_opt_set_ap_req_nofail(&vopt, secure); ret = krb5_verify_init_creds(context, &cred, server, keytab, NULL, &vopt); krb5_free_principal(context, server); if(ret) return ret; if(ccache == NULL) ret = krb5_cc_default (context, &id); else id = ccache; if(ret == 0){ ret = krb5_cc_initialize(context, id, principal); if(ret == 0){ ret = krb5_cc_store_cred(context, id, &cred); } if(ccache == NULL) krb5_cc_close(context, id); } krb5_free_cred_contents(context, &cred); return ret; }
krb5_error_code func(krb5_context context, krb5_creds *creds, krb5_principal server_principal) { krb5_error_code ret = KRB5_OK; krb5_verify_init_creds_opt options; krb5_verify_init_creds_opt_init (&options); krb5_verify_init_creds_opt_set_ap_req_nofail (&options, 1); ret = krb5_verify_init_creds(context, creds, server_principal, NULL /* use default keytab */, NULL /* don't store creds in ccache */, &options); if (ret) { /* error while verifying credentials for server */ } return ret; }
static krb5_error_code verify_common (krb5_context context, krb5_principal principal, krb5_principal server_principal, krb5_ccache ccache, krb5_keytab keytab, krb5_boolean secure, const char *service, krb5_creds *cred) { krb5_error_code ret; krb5_verify_init_creds_opt vopt; krb5_ccache id; krb5_verify_init_creds_opt_init(&vopt); krb5_verify_init_creds_opt_set_ap_req_nofail(&vopt, secure); krb5_verify_init_creds_opt_set_service(&vopt, service); ret = krb5_verify_init_creds(context, cred, server_principal, keytab, NULL, &vopt); if(ret) return ret; if(ccache == NULL) ret = krb5_cc_default (context, &id); else id = ccache; if(ret == 0){ ret = krb5_cc_initialize(context, id, principal); if(ret == 0){ ret = krb5_cc_store_cred(context, id, cred); } if(ccache == NULL) krb5_cc_close(context, id); } return ret; }
int main(int argc, const char **argv) { krb5_context ctx; krb5_ccache ccache; krb5_creds mcreds, creds; krb5_keytab keytab; krb5_principal server; krb5_verify_init_creds_opt opts; int ret; ctx = NULL; ret = krb5_init_context(&ctx); if (ret != 0) { crit("error initializing Kerberos: %s", error_message(ret)); return ret; } ccache = NULL; ret = krb5_cc_default(ctx, &ccache); if (ret != 0) { crit("error resolving ccache: %s", error_message(ret)); return ret; } keytab = NULL; ret = krb5_kt_default(ctx, &keytab); if (ret != 0) { crit("error resolving keytab: %s", error_message(ret)); return ret; } server = NULL; memset(&mcreds, 0, sizeof(mcreds)); ret = krb5_cc_get_principal(ctx, ccache, &mcreds.client); if (ret != 0) { crit("error reading client name from ccache: %s", error_message(ret)); return ret; } ret = krb5_build_principal_ext(ctx, &mcreds.server, v5_princ_realm_length(mcreds.client), v5_princ_realm_contents(mcreds.client), KRB5_TGS_NAME_SIZE, KRB5_TGS_NAME, v5_princ_realm_length(mcreds.client), v5_princ_realm_contents(mcreds.client), 0); if (ret != 0) { crit("error building ticket granting server name: %s", error_message(ret)); return ret; } ret = krb5_cc_retrieve_cred(ctx, ccache, 0, &mcreds, &creds); if (ret != 0) { crit("error reading ccache: %s", error_message(ret)); return ret; } krb5_cc_close(ctx, ccache); krb5_verify_init_creds_opt_init(&opts); ret = krb5_verify_init_creds(ctx, &creds, server, keytab, NULL, &opts); if (ret != 0) { crit("error verifying creds: %s", error_message(ret)); } else { printf("OK\n"); } krb5_free_context(ctx); return ret; }
int main(int argc, char **argv) { krb5_context context; krb5_error_code ret; krb5_creds cred; krb5_preauthtype pre_auth_types[] = {KRB5_PADATA_ENC_TIMESTAMP}; krb5_get_init_creds_opt *get_options; krb5_verify_init_creds_opt verify_options; krb5_principal principal = NULL; int optidx = 0; setprogname (argv[0]); if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx)) usage(1); if (help_flag) usage (0); if(version_flag) { print_version(NULL); exit(0); } argc -= optidx; argv += optidx; ret = krb5_init_context(&context); if (ret) errx (1, "krb5_init_context failed: %d", ret); ret = krb5_get_init_creds_opt_alloc (context, &get_options); if (ret) krb5_err(context, 1, ret, "krb5_get_init_creds_opt_alloc"); krb5_get_init_creds_opt_set_preauth_list (get_options, pre_auth_types, 1); krb5_verify_init_creds_opt_init (&verify_options); if (argc) { ret = krb5_parse_name(context, argv[0], &principal); if (ret) krb5_err(context, 1, ret, "krb5_parse_name: %s", argv[0]); } else { ret = krb5_get_default_principal(context, &principal); if (ret) krb5_err(context, 1, ret, "krb5_get_default_principal"); } ret = krb5_get_init_creds_password (context, &cred, principal, NULL, krb5_prompter_posix, NULL, 0, NULL, get_options); if (ret) krb5_err(context, 1, ret, "krb5_get_init_creds"); ret = krb5_verify_init_creds (context, &cred, NULL, NULL, NULL, &verify_options); if (ret) krb5_err(context, 1, ret, "krb5_verify_init_creds"); krb5_free_cred_contents (context, &cred); krb5_free_context (context); return 0; }
int auth_krb5_password(Authctxt *authctxt, const char *password) { #ifndef HEIMDAL krb5_creds creds; krb5_principal server; #endif krb5_error_code problem; krb5_ccache ccache = NULL; int len; char *client, *platform_client; /* get platform-specific kerberos client principal name (if it exists) */ platform_client = platform_krb5_get_principal_name(authctxt->pw->pw_name); client = platform_client ? platform_client : authctxt->pw->pw_name; temporarily_use_uid(authctxt->pw); problem = krb5_init(authctxt); if (problem) goto out; problem = krb5_parse_name(authctxt->krb5_ctx, client, &authctxt->krb5_user); if (problem) goto out; #ifdef HEIMDAL problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_mcc_ops, &ccache); if (problem) goto out; problem = krb5_cc_initialize(authctxt->krb5_ctx, ccache, authctxt->krb5_user); if (problem) goto out; restore_uid(); problem = krb5_verify_user(authctxt->krb5_ctx, authctxt->krb5_user, ccache, password, 1, NULL); temporarily_use_uid(authctxt->pw); if (problem) goto out; problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_fcc_ops, &authctxt->krb5_fwd_ccache); if (problem) goto out; problem = krb5_cc_copy_cache(authctxt->krb5_ctx, ccache, authctxt->krb5_fwd_ccache); krb5_cc_destroy(authctxt->krb5_ctx, ccache); ccache = NULL; if (problem) goto out; #else problem = krb5_get_init_creds_password(authctxt->krb5_ctx, &creds, authctxt->krb5_user, (char *)password, NULL, NULL, 0, NULL, NULL); if (problem) goto out; problem = krb5_sname_to_principal(authctxt->krb5_ctx, NULL, NULL, KRB5_NT_SRV_HST, &server); if (problem) goto out; restore_uid(); problem = krb5_verify_init_creds(authctxt->krb5_ctx, &creds, server, NULL, NULL, NULL); krb5_free_principal(authctxt->krb5_ctx, server); temporarily_use_uid(authctxt->pw); if (problem) goto out; if (!krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user, client)) { problem = -1; goto out; } problem = ssh_krb5_cc_gen(authctxt->krb5_ctx, &authctxt->krb5_fwd_ccache); if (problem) goto out; problem = krb5_cc_initialize(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache, authctxt->krb5_user); if (problem) goto out; problem= krb5_cc_store_cred(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache, &creds); if (problem) goto out; #endif authctxt->krb5_ticket_file = (char *)krb5_cc_get_name(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache); len = strlen(authctxt->krb5_ticket_file) + 6; authctxt->krb5_ccname = xmalloc(len); snprintf(authctxt->krb5_ccname, len, "FILE:%s", authctxt->krb5_ticket_file); #ifdef USE_PAM if (options.use_pam) do_pam_putenv("KRB5CCNAME", authctxt->krb5_ccname); #endif out: restore_uid(); if (platform_client != NULL) xfree(platform_client); if (problem) { if (ccache) krb5_cc_destroy(authctxt->krb5_ctx, ccache); if (authctxt->krb5_ctx != NULL && problem!=-1) debug("Kerberos password authentication failed: %s", krb5_get_err_text(authctxt->krb5_ctx, problem)); else debug("Kerberos password authentication failed: %d", problem); krb5_cleanup_proc(authctxt); if (options.kerberos_or_local_passwd) return (-1); else return (0); } return (authctxt->valid ? 1 : 0); }
static int krb5_verify_password (POP *p) { krb5_preauthtype pre_auth_types[] = {KRB5_PADATA_ENC_TIMESTAMP}; krb5_get_init_creds_opt *get_options; krb5_verify_init_creds_opt verify_options; krb5_error_code ret; krb5_principal client, server; krb5_creds creds; const char *estr; ret = krb5_get_init_creds_opt_alloc (p->context, &get_options); if (ret) { estr = krb5_get_error_message(p->context, ret); pop_log(p, POP_PRIORITY, "krb5_get_init_creds_opt_alloc: %s", estr); krb5_free_error_message(p->context, estr); return 1; } krb5_get_init_creds_opt_set_preauth_list (get_options, pre_auth_types, 1); krb5_verify_init_creds_opt_init (&verify_options); ret = krb5_parse_name (p->context, p->user, &client); if (ret) { krb5_get_init_creds_opt_free(p->context, get_options); estr = krb5_get_error_message(p->context, ret); pop_log(p, POP_PRIORITY, "krb5_parse_name: %s", estr); krb5_free_error_message(p->context, estr); return 1; } ret = krb5_get_init_creds_password (p->context, &creds, client, p->pop_parm[1], NULL, NULL, 0, NULL, get_options); krb5_get_init_creds_opt_free(p->context, get_options); if (ret) { estr = krb5_get_error_message(p->context, ret); pop_log(p, POP_PRIORITY, "krb5_get_init_creds_password: %s", estr); krb5_free_error_message(p->context, estr); return 1; } ret = krb5_sname_to_principal (p->context, p->myhost, "pop", KRB5_NT_SRV_HST, &server); if (ret) { estr = krb5_get_error_message(p->context, ret); pop_log(p, POP_PRIORITY, "krb5_get_init_creds_password: %s", estr); krb5_free_error_message(p->context, estr); return 1; } ret = krb5_verify_init_creds (p->context, &creds, server, NULL, NULL, &verify_options); krb5_free_principal (p->context, client); krb5_free_principal (p->context, server); krb5_free_cred_contents (p->context, &creds); return ret; }
int cosign_login_krb5( struct connlist *head, char *cosignname, char *id, char *realm, char *passwd, char *ip_addr, char *cookie, struct subparams *sp, char **msg ) { krb5_error_code kerror = 0; krb5_context kcontext; krb5_principal kprinc; krb5_principal sprinc; krb5_get_init_creds_opt kopts; krb5_verify_init_creds_opt kvic_opts[ 1 ]; krb5_creds kcreds; krb5_ccache kccache; krb5_keytab keytab = 0; char *tmpl = ERROR_HTML; char *sprinc_name = NULL; char ktbuf[ MAX_KEYTAB_NAME_LEN + 1 ]; char tmpkrb[ 16 ], krbpath [ MAXPATHLEN ]; int i; lcgi_configure(); if (( kerror = krb5_init_context( &kcontext ))) { sl[ SL_ERROR ].sl_data = (char *)error_message( kerror ); sl[ SL_TITLE ].sl_data = "Authentication Required ( kerberos error )"; subfile( tmpl, sl, 0 ); exit( 0 ); } if (( kerror = krb5_parse_name( kcontext, id, &kprinc ))) { sl[ SL_ERROR ].sl_data = (char *)error_message( kerror ); sl[ SL_TITLE ].sl_data = "Authentication Required ( kerberos error )"; subfile( tmpl, sl, 0 ); exit( 0 ); } /* need to get realm out */ if ( realm == NULL || *realm == '\0' ) { if (( kerror = krb5_get_default_realm( kcontext, &realm )) != 0 ) { sl[ SL_ERROR ].sl_data = (char *)error_message( kerror ); sl[ SL_TITLE ].sl_data = "Authentication Required " "( krb realm error )"; subfile( tmpl, sl, 0 ); exit( 0 ); } } if ( store_tickets ) { if ( mkcookie( sizeof( tmpkrb ), tmpkrb ) != 0 ) { sl[ SL_ERROR ].sl_data = "An unknown error occurred."; sl[ SL_TITLE ].sl_data = "Authentication Required (kerberos error)"; subfile( tmpl, sl, 0 ); exit( 0 ); } if ( snprintf( krbpath, sizeof( krbpath ), "%s/%s", ticket_path, tmpkrb ) >= sizeof( krbpath )) { sl[ SL_ERROR ].sl_data = "An unknown error occurred."; sl[ SL_TITLE ].sl_data = "Authentication Required (krbpath error)"; subfile( tmpl, sl, 0 ); exit( 0 ); } if (( kerror = krb5_cc_resolve( kcontext, krbpath, &kccache )) != 0 ) { sl[ SL_ERROR ].sl_data = (char *)error_message( kerror ); sl[ SL_TITLE ].sl_data = "Authentication Required (kerberos error)"; subfile( tmpl, sl, 0 ); exit( 0 ); } } krb5_get_init_creds_opt_init( &kopts ); krb5_get_init_creds_opt_set_tkt_life( &kopts, tkt_life ); krb5_get_init_creds_opt_set_renew_life( &kopts, 0 ); krb5_get_init_creds_opt_set_forwardable( &kopts, 1 ); krb5_get_init_creds_opt_set_proxiable( &kopts, 0 ); if (( kerror = krb5_get_init_creds_password( kcontext, &kcreds, kprinc, passwd, NULL, NULL, 0, NULL /*keytab */, &kopts ))) { if (( kerror == KRB5KRB_AP_ERR_BAD_INTEGRITY ) || ( kerror == KRB5KDC_ERR_PREAUTH_FAILED ) || ( kerror == KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN )) { return( COSIGN_CGI_ERROR ); /* draw login or reauth page */ } else if ( kerror == KRB5KDC_ERR_KEY_EXP ) { *msg = (char *)error_message( kerror ); return( COSIGN_CGI_PASSWORD_EXPIRED ); } else { sl[ SL_ERROR ].sl_data = (char *)error_message( kerror ); sl[ SL_TITLE ].sl_data = "Error"; subfile( tmpl, sl, 0 ); exit( 0 ); } } /* verify no KDC spoofing */ if ( *keytab_path != '\0' ) { if ( strlen( keytab_path ) > MAX_KEYTAB_NAME_LEN ) { sl[ SL_ERROR ].sl_data = "server configuration error"; sl[ SL_TITLE ].sl_data = "Ticket Verification Error"; subfile( tmpl, sl, 0 ); exit( 0 ); } strcpy( ktbuf, keytab_path ); /* from mdw */ krb5_verify_init_creds_opt_init( kvic_opts ); krb5_verify_init_creds_opt_set_ap_req_nofail( kvic_opts, 1 ); if (( kerror = krb5_kt_resolve( kcontext, ktbuf, &keytab )) != 0 ) { sl[ SL_ERROR ].sl_data = (char *)error_message( kerror ); sl[ SL_TITLE ].sl_data = "KT Resolve Error"; subfile( tmpl, sl, 0 ); exit( 0 ); } if ( cosign_princ ) { kerror = krb5_parse_name( kcontext, cosign_princ, &sprinc ); } else { kerror = krb5_sname_to_principal( kcontext, NULL, "cosign", KRB5_NT_SRV_HST, &sprinc ); } if ( kerror != 0 ) { sl[ SL_ERROR ].sl_data = (char *)error_message( kerror ); sl[ SL_TITLE ].sl_data = "Server Principal Error"; subfile( tmpl, sl, 0 ); exit( 0 ); } if (( kerror = krb5_verify_init_creds( kcontext, &kcreds, sprinc, keytab, NULL, kvic_opts )) != 0 ) { if ( krb5_unparse_name( kcontext, sprinc, &sprinc_name ) == 0 ) { fprintf( stderr, "ticket verify error for " "user %s, keytab principal %s", id, sprinc_name ); free( sprinc_name ); } else { fprintf( stderr, "ticket verify error for user %s", id ); } sl[ SL_ERROR ].sl_data = (char *)error_message( kerror ); sl[ SL_TITLE ].sl_data = "Ticket Verify Error"; subfile( tmpl, sl, 0 ); krb5_free_principal( kcontext, sprinc ); exit( 0 ); } (void)krb5_kt_close( kcontext, keytab ); krb5_free_principal( kcontext, sprinc ); } for ( i = 0; i < COSIGN_MAXFACTORS - 1; i++ ) { if ( new_factors[ i ] == NULL ) { new_factors[ i ] = strdup( realm ); new_factors[ i + 1 ] = NULL; break; } if ( strcmp( new_factors[ i ], realm ) == 0 ) { break; } } if ( sp->sp_reauth && sp->sp_ipchanged == 0 ) { return( COSIGN_CGI_OK ); } if ( store_tickets ) { if (( kerror = krb5_cc_initialize( kcontext, kccache, kprinc )) != 0 ) { sl[ SL_ERROR ].sl_data = (char *)error_message( kerror ); sl[ SL_TITLE ].sl_data = "CC Initialize Error"; subfile( tmpl, sl, 0 ); exit( 0 ); } if (( kerror = krb5_cc_store_cred( kcontext, kccache, &kcreds )) != 0 ) { sl[ SL_ERROR ].sl_data = (char *)error_message( kerror ); sl[ SL_TITLE ].sl_data = "CC Storing Error"; subfile( tmpl, sl, 0 ); exit( 0 ); } krb5_cc_close( kcontext, kccache ); } krb5_free_cred_contents( kcontext, &kcreds ); krb5_free_principal( kcontext, kprinc ); krb5_free_context( kcontext ); /* password has been accepted, tell cosignd */ if ( cosign_login( head, cookie, ip_addr, cosignname, realm, ( store_tickets ? krbpath : NULL )) < 0 ) { fprintf( stderr, "cosign_login_krb5: login failed\n") ; sl[ SL_ERROR ].sl_data = "We were unable to contact the " "authentication server. Please try again later."; sl[ SL_TITLE ].sl_data = "Error: Please try later"; subfile( tmpl, sl, 0 ); exit( 0 ); } return( COSIGN_CGI_OK ); }
int main(int argc, char **argv) { krb5_context context; krb5_error_code ret; krb5_creds cred; krb5_preauthtype pre_auth_types[] = {KRB5_PADATA_ENC_TIMESTAMP}; krb5_get_init_creds_opt *get_options; krb5_verify_init_creds_opt verify_options; int optind = 0; if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optind)) usage(1); if (help_flag) usage (0); if(version_flag) { print_version(NULL); exit(0); } ret = krb5_init_context(&context); if (ret) errx (1, "krb5_init_context failed: %d", ret); ret = krb5_get_init_creds_opt_alloc (context, &get_options); if (ret) krb5_err(context, 1, ret, "krb5_get_init_creds_opt_alloc"); krb5_get_init_creds_opt_set_preauth_list (get_options, pre_auth_types, 1); krb5_verify_init_creds_opt_init (&verify_options); ret = krb5_get_init_creds_password (context, &cred, NULL, NULL, krb5_prompter_posix, NULL, 0, NULL, get_options); if (ret) errx (1, "krb5_get_init_creds: %s", krb5_get_err_text(context, ret)); ret = krb5_verify_init_creds (context, &cred, NULL, NULL, NULL, &verify_options); if (ret) errx (1, "krb5_verify_init_creds: %s", krb5_get_err_text(context, ret)); krb5_free_cred_contents (context, &cred); krb5_free_context (context); return 0; }
int auth_krb5_password(Authctxt *authctxt, const char *password) { #ifndef HEIMDAL krb5_creds creds; krb5_principal server; char ccname[40]; int tmpfd; mode_t old_umask; #endif krb5_error_code problem; krb5_ccache ccache = NULL; int len; if (!authctxt->valid) return (0); temporarily_use_uid(authctxt->pw); problem = krb5_init(authctxt); if (problem) goto out; problem = krb5_parse_name(authctxt->krb5_ctx, authctxt->pw->pw_name, &authctxt->krb5_user); if (problem) goto out; #ifdef HEIMDAL problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_mcc_ops, &ccache); if (problem) goto out; problem = krb5_cc_initialize(authctxt->krb5_ctx, ccache, authctxt->krb5_user); if (problem) goto out; restore_uid(); problem = krb5_verify_user(authctxt->krb5_ctx, authctxt->krb5_user, ccache, password, 1, NULL); temporarily_use_uid(authctxt->pw); if (problem) goto out; problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_fcc_ops, &authctxt->krb5_fwd_ccache); if (problem) goto out; problem = krb5_cc_copy_cache(authctxt->krb5_ctx, ccache, authctxt->krb5_fwd_ccache); krb5_cc_destroy(authctxt->krb5_ctx, ccache); ccache = NULL; if (problem) goto out; #else problem = krb5_get_init_creds_password(authctxt->krb5_ctx, &creds, authctxt->krb5_user, (char *)password, NULL, NULL, 0, NULL, NULL); if (problem) goto out; problem = krb5_sname_to_principal(authctxt->krb5_ctx, NULL, NULL, KRB5_NT_SRV_HST, &server); if (problem) goto out; restore_uid(); problem = krb5_verify_init_creds(authctxt->krb5_ctx, &creds, server, NULL, NULL, NULL); krb5_free_principal(authctxt->krb5_ctx, server); temporarily_use_uid(authctxt->pw); if (problem) goto out; if (!krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user, authctxt->pw->pw_name)) { problem = -1; goto out; } snprintf(ccname,sizeof(ccname),"FILE:/tmp/krb5cc_%d_XXXXXX",geteuid()); old_umask = umask(0177); tmpfd = mkstemp(ccname + strlen("FILE:")); umask(old_umask); if (tmpfd == -1) { logit("mkstemp(): %.100s", strerror(errno)); problem = errno; goto out; } if (fchmod(tmpfd,S_IRUSR | S_IWUSR) == -1) { logit("fchmod(): %.100s", strerror(errno)); close(tmpfd); problem = errno; goto out; } close(tmpfd); problem = krb5_cc_resolve(authctxt->krb5_ctx, ccname, &authctxt->krb5_fwd_ccache); if (problem) goto out; problem = krb5_cc_initialize(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache, authctxt->krb5_user); if (problem) goto out; problem= krb5_cc_store_cred(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache, &creds); if (problem) goto out; #endif authctxt->krb5_ticket_file = (char *)krb5_cc_get_name(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache); len = strlen(authctxt->krb5_ticket_file) + 6; authctxt->krb5_ccname = xmalloc(len); snprintf(authctxt->krb5_ccname, len, "FILE:%s", authctxt->krb5_ticket_file); out: restore_uid(); if (problem) { if (ccache) krb5_cc_destroy(authctxt->krb5_ctx, ccache); if (authctxt->krb5_ctx != NULL && problem!=-1) debug("Kerberos password authentication failed: %s", krb5_get_err_text(authctxt->krb5_ctx, problem)); else debug("Kerberos password authentication failed: %d", problem); krb5_cleanup_proc(authctxt); if (options.kerberos_or_local_passwd) return (-1); else return (0); } return (1); }
static int chk_kerberos( const struct berval *sc, const struct berval * passwd, const struct berval * cred, const char **text ) { unsigned int i; int rtn; for( i=0; i<cred->bv_len; i++) { if(cred->bv_val[i] == '\0') { return LUTIL_PASSWD_ERR; /* NUL character in password */ } } if( cred->bv_val[i] != '\0' ) { return LUTIL_PASSWD_ERR; /* cred must behave like a string */ } for( i=0; i<passwd->bv_len; i++) { if(passwd->bv_val[i] == '\0') { return LUTIL_PASSWD_ERR; /* NUL character in password */ } } if( passwd->bv_val[i] != '\0' ) { return LUTIL_PASSWD_ERR; /* passwd must behave like a string */ } rtn = LUTIL_PASSWD_ERR; #ifdef HAVE_KRB5 /* HAVE_HEIMDAL_KRB5 */ { /* Portions: * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska H\xf6gskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * 3. Neither the name of the Institute nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ krb5_context context; krb5_error_code ret; krb5_creds creds; krb5_get_init_creds_opt get_options; krb5_verify_init_creds_opt verify_options; krb5_principal client, server; #ifdef notdef krb5_preauthtype pre_auth_types[] = {KRB5_PADATA_ENC_TIMESTAMP}; #endif ret = krb5_init_context( &context ); if (ret) { return LUTIL_PASSWD_ERR; } #ifdef notdef krb5_get_init_creds_opt_set_preauth_list(&get_options, pre_auth_types, 1); #endif krb5_get_init_creds_opt_init( &get_options ); krb5_verify_init_creds_opt_init( &verify_options ); ret = krb5_parse_name( context, passwd->bv_val, &client ); if (ret) { krb5_free_context( context ); return LUTIL_PASSWD_ERR; } ret = krb5_get_init_creds_password( context, &creds, client, cred->bv_val, NULL, NULL, 0, NULL, &get_options ); if (ret) { krb5_free_principal( context, client ); krb5_free_context( context ); return LUTIL_PASSWD_ERR; } { char *host = ldap_pvt_get_fqdn( NULL ); if( host == NULL ) { krb5_free_principal( context, client ); krb5_free_context( context ); return LUTIL_PASSWD_ERR; } ret = krb5_sname_to_principal( context, host, "ldap", KRB5_NT_SRV_HST, &server ); ber_memfree( host ); } if (ret) { krb5_free_principal( context, client ); krb5_free_context( context ); return LUTIL_PASSWD_ERR; } ret = krb5_verify_init_creds( context, &creds, server, NULL, NULL, &verify_options ); krb5_free_principal( context, client ); krb5_free_principal( context, server ); krb5_free_cred_contents( context, &creds ); krb5_free_context( context ); rtn = ret ? LUTIL_PASSWD_ERR : LUTIL_PASSWD_OK; } #elif defined(HAVE_KRB4) { /* Borrowed from Heimdal kpopper */ /* Portions: * Copyright (c) 1989 Regents of the University of California. * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. */ int status; char lrealm[REALM_SZ]; char tkt[MAXHOSTNAMELEN]; status = krb_get_lrealm(lrealm,1); if (status == KFAILURE) { return LUTIL_PASSWD_ERR; } snprintf(tkt, sizeof(tkt), "%s_slapd.%u", TKT_ROOT, (unsigned)getpid()); krb_set_tkt_string (tkt); status = krb_verify_user( passwd->bv_val, "", lrealm, cred->bv_val, 1, "ldap"); dest_tkt(); /* no point in keeping the tickets */ return status == KFAILURE ? LUTIL_PASSWD_ERR : LUTIL_PASSWD_OK; } #endif return rtn; }
/* * Validate userid/passwd (MIT) */ static rlm_rcode_t krb5_auth(void *instance, REQUEST *request) { rlm_krb5_t *inst = instance; rlm_rcode_t rcode; krb5_error_code ret; krb5_principal client; krb5_creds init_creds; krb5_keytab keytab; krb5_context *context = NULL; /* * All the snippets on threadsafety say that individual threads * must each use their own copy of context. * * As we don't have any per thread instantiation, we either have * to clone inst->context on every request, or use the connection * API. * * @todo Use the connection API (3.0 only). */ ret = krb5_copy_context(*(inst->context), context); if (ret) { radlog(L_ERR, "rlm_krb5 (%s): Error cloning krb5 context: %s", inst->xlat_name, error_message(ret)); return RLM_MODULE_FAIL; } /* * Check we have all the required VPs, and convert the username * into a principal. */ rcode = krb5_parse_user(inst, request, &client); if (rcode != RLM_MODULE_OK) goto cleanup; /* * Retrieve the TGT from the TGS/KDC and check we can decrypt it. */ memset(&init_creds, 0, sizeof(init_creds)); ret = krb5_get_init_creds_password(*context, &init_creds, client, request->password->vp_strvalue, NULL, NULL, 0, NULL, inst->gic_options); if (ret) { error: switch (ret) { case KRB5_LIBOS_BADPWDMATCH: case KRB5KRB_AP_ERR_BAD_INTEGRITY: RDEBUG("Provided password was incorrect: %s", error_message(ret)); rcode = RLM_MODULE_REJECT; break; case KRB5KDC_ERR_KEY_EXP: case KRB5KDC_ERR_CLIENT_REVOKED: case KRB5KDC_ERR_SERVICE_REVOKED: RDEBUG("Account has been locked out: %s", error_message(ret)); rcode = RLM_MODULE_USERLOCK; break; case KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN: RDEBUG("User not found: %s", error_message(ret)); rcode = RLM_MODULE_NOTFOUND; default: radlog(L_ERR, "rlm_krb5 (%s): Failed getting/verifying " "credentials: %s", inst->xlat_name, error_message(ret)); rcode = RLM_MODULE_FAIL; break; } goto cleanup; } RDEBUG("Successfully retrieved and decrypted TGT"); memset(&keytab, 0, sizeof(keytab)); ret = inst->keytabname ? krb5_kt_resolve(*context, inst->keytabname, &keytab) : krb5_kt_default(*context, &keytab); if (ret) { radlog(L_ERR, "rlm_krb5 (%s): Resolving keytab failed: %s", inst->xlat_name, error_message(ret)); goto cleanup; } ret = krb5_verify_init_creds(*context, &init_creds, inst->server, keytab, NULL, inst->vic_options); if (ret) goto error; cleanup: krb5_free_cred_contents(*context, &init_creds); krb5_free_context(*context); krb5_kt_close(*context, keytab); return rcode; }