static void test_misc(krb5_context context) { /* Tests for certain error returns */ krb5_error_code kret; krb5_keytab ktid; char defname[BUFSIZ]; char *name; fprintf(stderr, "Testing miscellaneous error conditions\n"); kret = krb5_kt_resolve(context, "unknown_method_ep:/tmp/name", &ktid); if (kret != KRB5_KT_UNKNOWN_TYPE) { CHECK(kret, "resolve unknown type"); } /* Test length limits on krb5_kt_default_name */ kret = krb5_kt_default_name(context, defname, sizeof(defname)); CHECK(kret, "krb5_kt_default_name error"); /* Now allocate space - without the null... */ name = malloc(strlen(defname)); if(!name) { fprintf(stderr, "Out of memory in testing\n"); exit(1); } kret = krb5_kt_default_name(context, name, strlen(defname)); free(name); if (kret != KRB5_CONFIG_NOTENUFSPACE) { CHECK(kret, "krb5_kt_default_name limited"); } }
std::string Krb5Keytab::getDefaultKeytabName(krb5_context context) { char name[kKeytabNameMaxLength]; krb5_error_code code = krb5_kt_default_name(context, name, sizeof(name)); raiseIf(context, code, "getting default keytab name"); return name; }
static void get_creds(krb5_context context, const char *keytab_str, krb5_ccache *cache, const char *serverhost) { krb5_keytab keytab; krb5_principal client; krb5_error_code ret; krb5_get_init_creds_opt *init_opts; krb5_creds creds; char *server; char keytab_buf[256]; int aret; if (keytab_str == NULL) { ret = krb5_kt_default_name (context, keytab_buf, sizeof(keytab_buf)); if (ret) krb5_err (context, 1, ret, "krb5_kt_default_name"); keytab_str = keytab_buf; } ret = krb5_kt_resolve(context, keytab_str, &keytab); if(ret) krb5_err(context, 1, ret, "%s", keytab_str); ret = krb5_sname_to_principal (context, slave_str, IPROP_NAME, KRB5_NT_SRV_HST, &client); if (ret) krb5_err(context, 1, ret, "krb5_sname_to_principal"); ret = krb5_get_init_creds_opt_alloc(context, &init_opts); if (ret) krb5_err(context, 1, ret, "krb5_get_init_creds_opt_alloc"); aret = asprintf (&server, "%s/%s", IPROP_NAME, serverhost); if (aret == -1 || server == NULL) krb5_errx (context, 1, "malloc: no memory"); ret = krb5_get_init_creds_keytab(context, &creds, client, keytab, 0, server, init_opts); free (server); krb5_get_init_creds_opt_free(context, init_opts); if(ret) krb5_err(context, 1, ret, "krb5_get_init_creds"); ret = krb5_kt_close(context, keytab); if(ret) krb5_err(context, 1, ret, "krb5_kt_close"); ret = krb5_cc_new_unique(context, krb5_cc_type_memory, NULL, cache); if(ret) krb5_err(context, 1, ret, "krb5_cc_new_unique"); ret = krb5_cc_initialize(context, *cache, client); if(ret) krb5_err(context, 1, ret, "krb5_cc_initialize"); ret = krb5_cc_store_cred(context, *cache, &creds); if(ret) krb5_err(context, 1, ret, "krb5_cc_store_cred"); krb5_free_cred_contents(context, &creds); krb5_free_principal(context, client); }
krb5_error_code KRB5_CALLCONV krb5_kt_default(krb5_context context, krb5_keytab *id) { char defname[BUFSIZ]; krb5_error_code retval; if ((retval = krb5_kt_default_name(context, defname, sizeof(defname)))) return retval; return krb5_kt_resolve(context, defname, id); }
int kt_list(struct list_options *opt, int argc, char **argv) { krb5_error_code ret; char kt[1024]; if(verbose_flag) opt->timestamp_flag = 1; if (keytab_string == NULL) { if((ret = krb5_kt_default_name(context, kt, sizeof(kt))) != 0) { krb5_warn(context, ret, "getting default keytab name"); return 1; } keytab_string = kt; } return do_list(opt, keytab_string) != 0; }
/* * effects: If keyprocarg is not NULL, it is taken to be the name of a * keytab. Otherwise, the default keytab will be used. This * routine opens the keytab and finds the principal associated with * principal, vno, and enctype and returns the resulting key in *key * or returning an error code if it is not found. * returns: Either KSUCCESS or error code. * errors: error code if not found or keyprocarg is invalid. */ krb5_error_code KRB5_CALLCONV krb5_kt_read_service_key(krb5_context context, krb5_pointer keyprocarg, krb5_principal principal, krb5_kvno vno, krb5_enctype enctype, krb5_keyblock **key) { krb5_error_code kerror = KSUCCESS; char keytabname[MAX_KEYTAB_NAME_LEN + 1]; /* + 1 for NULL termination */ krb5_keytab id; krb5_keytab_entry entry; /* * Get the name of the file that we should use. */ if (!keyprocarg) { if ((kerror = krb5_kt_default_name(context, (char *)keytabname, sizeof(keytabname) - 1))!= KSUCCESS) return (kerror); } else { memset(keytabname, 0, sizeof(keytabname)); (void) strncpy(keytabname, (char *)keyprocarg, sizeof(keytabname) - 1); } if ((kerror = krb5_kt_resolve(context, (char *)keytabname, &id))) return (kerror); kerror = krb5_kt_get_entry(context, id, principal, vno, enctype, &entry); krb5_kt_close(context, id); if (kerror) return(kerror); krb5_copy_keyblock(context, &entry.key, key); krb5_kt_free_entry(context, &entry); return (KSUCCESS); }
/* call-seq: * krb5.get_init_creds_keytab(principal = nil, keytab = nil, service = nil, ccache = nil) * * Acquire credentials for +principal+ from +keytab+ using +service+. If * no principal is specified, then a principal is derived from the service * name. If no service name is specified, kerberos defaults to "host". * * If no keytab file is provided, the default keytab file is used. This is * typically /etc/krb5.keytab. * * If +ccache+ is supplied and is a Kerberos::Krb5::CredentialsCache, the * resulting credentials will be stored in the credential cache. */ static VALUE rkrb5_get_init_creds_keytab(int argc, VALUE* argv, VALUE self){ RUBY_KRB5* ptr; VALUE v_user, v_keytab_name, v_service, v_ccache; char* user; char* service; char keytab_name[MAX_KEYTAB_NAME_LEN]; krb5_error_code kerror; krb5_get_init_creds_opt* opt; krb5_creds cred; Data_Get_Struct(self, RUBY_KRB5, ptr); if(!ptr->ctx) rb_raise(cKrb5Exception, "no context has been established"); kerror = krb5_get_init_creds_opt_alloc(ptr->ctx, &opt); if(kerror) rb_raise(cKrb5Exception, "krb5_get_init_creds_opt_alloc: %s", error_message(kerror)); rb_scan_args(argc, argv, "04", &v_user, &v_keytab_name, &v_service, &v_ccache); // We need the service information for later. if(NIL_P(v_service)){ service = NULL; } else{ Check_Type(v_service, T_STRING); service = StringValueCStr(v_service); } // Convert the name (or service name) to a kerberos principal. if(NIL_P(v_user)){ kerror = krb5_sname_to_principal( ptr->ctx, NULL, service, KRB5_NT_SRV_HST, &ptr->princ ); if(kerror) { krb5_get_init_creds_opt_free(ptr->ctx, opt); rb_raise(cKrb5Exception, "krb5_sname_to_principal: %s", error_message(kerror)); } } else{ Check_Type(v_user, T_STRING); user = StringValueCStr(v_user); kerror = krb5_parse_name(ptr->ctx, user, &ptr->princ); if(kerror) { krb5_get_init_creds_opt_free(ptr->ctx, opt); rb_raise(cKrb5Exception, "krb5_parse_name: %s", error_message(kerror)); } } // Use the default keytab if none is specified. if(NIL_P(v_keytab_name)){ kerror = krb5_kt_default_name(ptr->ctx, keytab_name, MAX_KEYTAB_NAME_LEN); if(kerror) { krb5_get_init_creds_opt_free(ptr->ctx, opt); rb_raise(cKrb5Exception, "krb5_kt_default_name: %s", error_message(kerror)); } } else{ Check_Type(v_keytab_name, T_STRING); strncpy(keytab_name, StringValueCStr(v_keytab_name), MAX_KEYTAB_NAME_LEN); } kerror = krb5_kt_resolve( ptr->ctx, keytab_name, &ptr->keytab ); if(kerror) { krb5_get_init_creds_opt_free(ptr->ctx, opt); rb_raise(cKrb5Exception, "krb5_kt_resolve: %s", error_message(kerror)); } // Set the credential cache from the supplied Kerberos::Krb5::CredentialsCache if(!NIL_P(v_ccache)){ RUBY_KRB5_CCACHE* ccptr; Data_Get_Struct(v_ccache, RUBY_KRB5_CCACHE, ccptr); kerror = krb5_get_init_creds_opt_set_out_ccache(ptr->ctx, opt, ccptr->ccache); if(kerror) { krb5_get_init_creds_opt_free(ptr->ctx, opt); rb_raise(cKrb5Exception, "krb5_get_init_creds_opt_set_out_ccache: %s", error_message(kerror)); } } kerror = krb5_get_init_creds_keytab( ptr->ctx, &cred, ptr->princ, ptr->keytab, 0, service, opt ); if(kerror) { krb5_get_init_creds_opt_free(ptr->ctx, opt); rb_raise(cKrb5Exception, "krb5_get_init_creds_keytab: %s", error_message(kerror)); } krb5_get_init_creds_opt_free(ptr->ctx, opt); return self; }
//---------------------------------------------------------------------- // Authenticate to server as a daemon (i.e. using the keytab) //---------------------------------------------------------------------- int Condor_Auth_Kerberos :: init_daemon() { int code, rc = TRUE; priv_state priv; char * daemonPrincipal = 0; krb5_keytab keytab = 0; // init some member vars creds_ = (krb5_creds *) malloc(sizeof(krb5_creds)); keytabName_ = param(STR_KERBEROS_SERVER_KEYTAB); // needed for extracting service name char * tmpsname = 0; MyString sname; memset(creds_, 0, sizeof(krb5_creds)); //------------------------------------------ // Initialize the principal for daemon (properly :-) //------------------------------------------ // this means using a keytab to obtain a tgt. // // in krb5-1.2 and earlier this was done with krb5_get_in_tkt_keytab() // // in krb5-1.3 and // later this should be done with krb5_get_init_creds_keytab // select a server principal daemonPrincipal = param(STR_KERBEROS_SERVER_PRINCIPAL); if (daemonPrincipal) { // it was defined explicitly in the config file if ((code = krb5_parse_name(krb_context_, daemonPrincipal, &krb_principal_))) { free(daemonPrincipal); goto error; } } else { // not defined in config, let's construct one from a service name daemonPrincipal = param(STR_KERBEROS_SERVER_SERVICE); if (!daemonPrincipal) { // use the host credential if no service was specified daemonPrincipal = strdup(STR_DEFAULT_CONDOR_SERVICE); } if ((code = krb5_sname_to_principal(krb_context_, NULL, daemonPrincipal, KRB5_NT_SRV_HST, &krb_principal_))) { free(daemonPrincipal); goto error; } } free(daemonPrincipal); daemonPrincipal = 0; dprintf_krb5_principal( D_SECURITY, "init_daemon: client principal is '%s'\n", krb_principal_); if (keytabName_) { dprintf(D_SECURITY, "init_daemon: Using keytab %s\n", keytabName_); code = krb5_kt_resolve(krb_context_, keytabName_, &keytab); } else { char defktname[_POSIX_PATH_MAX]; krb5_kt_default_name(krb_context_, defktname, _POSIX_PATH_MAX); dprintf(D_SECURITY, "init_daemon: Using default keytab %s\n", defktname); code = krb5_kt_default(krb_context_, &keytab); } if (code) { goto error; } // get the service name out of the member variable server_ tmpsname = 0; code = krb5_unparse_name(krb_context_, server_, &tmpsname); if (code) { goto error; } // copy it into a mystring for stack cleanup purposes sname = tmpsname; free (tmpsname); dprintf(D_SECURITY, "init_daemon: Trying to get tgt credential for service %s\n", sname.Value()); priv = set_root_priv(); // Get the old privilige code = krb5_get_init_creds_keytab(krb_context_, creds_, krb_principal_, keytab, 0, const_cast<char*>(sname.Value()), 0); set_priv(priv); if(code) { goto error; } dprintf_krb5_principal( D_SECURITY, "init_daemon: gic_kt creds_->client is '%s'\n", creds_->client ); dprintf_krb5_principal( D_SECURITY, "init_daemon: gic_kt creds_->server is '%s'\n", creds_->server ); dprintf(D_SECURITY, "Success..........................\n"); rc = TRUE; goto cleanup; error: dprintf(D_ALWAYS, "AUTH_ERROR: %s\n", error_message(code)); rc = FALSE; cleanup: if (keytab) { krb5_kt_close(krb_context_, keytab); } return rc; }
/* * Print a krb5 ticket in our service key, for the supplied client principal. * The path to a keytab is mandatory, but the service principal may be * guessed from the keytab contents if desired. The keytab entry must be * one of the allowed_enctypes (a zero-terminated list) if a non-NULL * parameter is passed. */ krb5_error_code get_credv5_akimpersonate(krb5_context context, char* keytab, krb5_principal service_principal, krb5_principal client_principal, time_t starttime, time_t endtime, const int *allowed_enctypes, krb5_creds** out_creds /* out */ ) { char *tmpkt = NULL; struct stat tstat; char *ktname = NULL; krb5_error_code code; krb5_keytab kt = 0; krb5_keytab_entry entry[1]; krb5_creds *creds = 0; krb5_enctype enctype; krb5_keyblock session_key[1]; #if USING_HEIMDAL Ticket *ticket_reply; EncTicketPart *enc_tkt_reply; #else krb5_ticket *ticket_reply; krb5_enc_tkt_part *enc_tkt_reply; #endif *out_creds = NULL; enctype = 0; /* AKIMPERSONATE_IGNORE_ENCTYPE */ memset(entry, 0, sizeof *entry); memset(session_key, 0, sizeof *session_key); ticket_reply = NULL; enc_tkt_reply = NULL; creds = calloc(1, sizeof(*creds)); if (creds == NULL) { code = ENOMEM; goto cleanup; } code = alloc_ticket(&ticket_reply); if (code != 0) goto cleanup; code = alloc_enc_tkt_part(&enc_tkt_reply); if (code != 0) goto cleanup; /* Empty list of allowed etypes must fail. Do it here to avoid issues. */ if (allowed_enctypes != NULL && *allowed_enctypes == 0) { code = KRB5_BAD_ENCTYPE; goto cleanup; } if (allowed_enctypes == NULL) allowed_enctypes = any_enctype; if (keytab != NULL) { tmpkt = strdup(keytab); if (!tmpkt) code = ENOMEM; } else { tmpkt = malloc(256); if (!tmpkt) code = ENOMEM; else code = krb5_kt_default_name(context, tmpkt, 256); } if (code) goto cleanup; if (strncmp(tmpkt, "WRFILE:", 7) == 0) ktname = &(tmpkt[7]); else if (strncmp(tmpkt, "FILE:", 5) == 0) ktname = &(tmpkt[5]); if (ktname && (stat(ktname, &tstat) != 0)) { code = KRB5_KT_NOTFOUND; goto cleanup; } code = krb5_kt_resolve(context, tmpkt, &kt); if (code != 0) goto cleanup; code = pick_enctype_and_principal(context, kt, allowed_enctypes, &enctype, &service_principal, entry); if (code != 0) goto cleanup; /* Conjure up a random session key */ deref_keyblock_enctype(session_key) = enctype; #if USING_HEIMDAL code = krb5_generate_random_keyblock(context, enctype, session_key); #else code = krb5_c_make_random_key(context, enctype, session_key); #endif if (code != 0) goto cleanup; populate_enc_tkt(session_key, client_principal, starttime, endtime, enc_tkt_reply); code = encrypt_enc_tkt(context, service_principal, entry, ticket_reply, enc_tkt_reply); if (code != 0) goto cleanup; code = populate_creds(context, service_principal, client_principal, session_key, ticket_reply, enc_tkt_reply, creds); if (code != 0) goto cleanup; /* return creds */ *out_creds = creds; creds = NULL; cleanup: if (tmpkt) free(tmpkt); if (deref_enc_data(&ticket_reply->enc_part) != NULL) free(deref_enc_data(&ticket_reply->enc_part)); krb5_free_keytab_entry_contents(context, entry); if (client_principal != NULL) krb5_free_principal(context, client_principal); if (service_principal != NULL) krb5_free_principal(context, service_principal); if (kt != NULL) krb5_kt_close(context, kt); if (creds != NULL) krb5_free_creds(context, creds); krb5_free_keyblock_contents(context, session_key); free_ticket(ticket_reply); free_enc_tkt_part(enc_tkt_reply); return code; }
/* * create Kerberos memory cache */ int krb5_create_cache(struct main_args *margs,char *domain) { krb5_keytab keytab = 0; krb5_keytab_entry entry; krb5_kt_cursor cursor; krb5_creds *creds=NULL; krb5_creds *tgt_creds=NULL; krb5_principal *principal_list = NULL; krb5_principal principal = NULL; char *service; char *keytab_name=NULL,*principal_name=NULL,*mem_cache=NULL; char buf[KT_PATH_MAX], *p; int nprinc=0; int i; int retval=0; int found=0; krb5_error_code code = 0; kparam.context=NULL; if (!domain || !strcmp(domain,"")) return(1); /* * Initialise Kerberos */ code = krb5_init_context(&kparam.context); if (code) { fprintf(stderr, "%s| %s: Error while initialising Kerberos library : %s\n",LogTime(), PROGRAM, error_message(code)); retval=1; goto cleanup; } /* * getting default keytab name */ if (margs->debug) fprintf(stderr, "%s| %s: Get default keytab file name\n",LogTime(), PROGRAM); krb5_kt_default_name(kparam.context, buf, KT_PATH_MAX); p = strchr(buf, ':'); /* Find the end if "FILE:" */ if (p) p++; /* step past : */ keytab_name = strdup(p ? p : buf); if (margs->debug) fprintf(stderr, "%s| %s: Got default keytab file name %s\n",LogTime(), PROGRAM, keytab_name); code = krb5_kt_resolve(kparam.context, keytab_name, &keytab); if (code) { fprintf(stderr, "%s| %s: Error while resolving keytab %s : %s\n", LogTime(), PROGRAM, keytab_name,error_message(code)); retval=1; goto cleanup; } code = krb5_kt_start_seq_get(kparam.context, keytab, &cursor); if (code) { fprintf(stderr, "%s| %s: Error while starting keytab scan : %s\n", LogTime(), PROGRAM, error_message(code)); retval=1; goto cleanup; } if (margs->debug) fprintf(stderr, "%s| %s: Get principal name from keytab %s\n",LogTime(), PROGRAM, keytab_name); nprinc=0; while ((code = krb5_kt_next_entry(kparam.context, keytab, &entry, &cursor)) == 0) { principal_list=realloc(principal_list,sizeof(krb5_principal)*(nprinc+1)); krb5_copy_principal(kparam.context,entry.principal,&principal_list[nprinc++]); if (margs->debug) #ifdef HAVE_HEIMDAL_KERBEROS fprintf(stderr, "%s| %s: Keytab entry has realm name: %s\n", LogTime(), PROGRAM, entry.principal->realm); #else fprintf(stderr, "%s| %s: Keytab entry has realm name: %s\n", LogTime(), PROGRAM, krb5_princ_realm(kparam.context, entry.principal)->data); #endif #ifdef HAVE_HEIMDAL_KERBEROS if (!strcasecmp(domain, entry.principal->realm)) #else if (!strcasecmp(domain,krb5_princ_realm(kparam.context, entry.principal)->data)) #endif { code = krb5_unparse_name(kparam.context, entry.principal, &principal_name); if (code) { fprintf(stderr, "%s| %s: Error while unparsing principal name : %s\n", LogTime(), PROGRAM, error_message(code)); } else { if (margs->debug) fprintf(stderr, "%s| %s: Found principal name: %s\n", LogTime(), PROGRAM, principal_name); found=1; } } #if defined(HAVE_HEIMDAL_KERBEROS) || ( defined(HAVE_KRB5_KT_FREE_ENTRY) && HAVE_DECL_KRB5_KT_FREE_ENTRY==1) code = krb5_kt_free_entry(kparam.context,&entry); #else code = krb5_free_keytab_entry_contents(kparam.context,&entry); #endif if (code) { fprintf(stderr, "%s| %s: Error while freeing keytab entry : %s\n", LogTime(), PROGRAM, error_message(code)); retval=1; break; } if (found) break; } if (code && code != KRB5_KT_END) { fprintf(stderr, "%s| %s: Error while scanning keytab : %s\n", LogTime(), PROGRAM, error_message(code)); retval=1; goto cleanup; } code = krb5_kt_end_seq_get(kparam.context, keytab, &cursor); if (code) { fprintf(stderr, "%s| %s: Error while ending keytab scan : %s\n", LogTime(), PROGRAM, error_message(code)); retval=1; goto cleanup; } /* * prepare memory credential cache */ #ifndef HAVE_KRB5_MEMORY_CACHE mem_cache=malloc(strlen("FILE:/tmp/squid_ldap_")+16); snprintf(mem_cache,strlen("FILE:/tmp/squid_ldap_")+16,"FILE:/tmp/squid_ldap_%d",(int)getpid()); #else mem_cache=malloc(strlen("MEMORY:squid_ldap_")+16); snprintf(mem_cache,strlen("MEMORY:squid_ldap_")+16,"MEMORY:squid_ldap_%d",(int)getpid()); #endif setenv("KRB5CCNAME",mem_cache,1); if (margs->debug) fprintf(stderr, "%s| %s: Set credential cache to %s\n",LogTime(), PROGRAM,mem_cache); code = krb5_cc_resolve(kparam.context, mem_cache , &kparam.cc); if (code) { fprintf(stderr, "%s| %s: Error while resolving memory ccache : %s\n",LogTime(), PROGRAM, error_message(code)); retval=1; goto cleanup; } /* * if no principal name found in keytab for domain use the prinipal name which can get a TGT */ if (!principal_name) { if (margs->debug) { fprintf(stderr, "%s| %s: Did not find a principal in keytab for domain %s.\n",LogTime(), PROGRAM,domain); fprintf(stderr, "%s| %s: Try to get principal of trusted domain.\n",LogTime(), PROGRAM); } creds = malloc(sizeof(*creds)); memset(creds, 0, sizeof(*creds)); for (i=0;i<nprinc;i++) { /* * get credentials */ code = krb5_unparse_name(kparam.context, principal_list[i], &principal_name); if (code) { if (margs->debug) fprintf(stderr, "%s| %s: Error while unparsing principal name : %s\n", LogTime(), PROGRAM, error_message(code)); goto loop_end; } if (margs->debug) fprintf(stderr, "%s| %s: Keytab entry has principal: %s\n", LogTime(), PROGRAM, principal_name); #if HAVE_GET_INIT_CREDS_KEYTAB code = krb5_get_init_creds_keytab(kparam.context, creds, principal_list[i], keytab, 0, NULL, NULL); #else service=malloc(strlen("krbtgt")+2*strlen(domain)+3); snprintf(service,strlen("krbtgt")+2*strlen(domain)+3,"krbtgt/%s@%s",domain,domain); creds->client=principal_list[i]; code = krb5_parse_name(kparam.context,service,&creds->server); if (service) free(service); code = krb5_get_in_tkt_with_keytab(kparam.context, 0, NULL, NULL, NULL, keytab, NULL, creds, 0); #endif if (code) { if (margs->debug) fprintf(stderr, "%s| %s: Error while initialising credentials from keytab : %s\n",LogTime(), PROGRAM, error_message(code)); goto loop_end; } code = krb5_cc_initialize(kparam.context, kparam.cc, principal_list[i]); if (code) { fprintf(stderr, "%s| %s: Error while initializing memory caches : %s\n",LogTime(), PROGRAM, error_message(code)); goto loop_end; } code = krb5_cc_store_cred(kparam.context, kparam.cc, creds); if (code) { if (margs->debug) fprintf(stderr, "%s| %s: Error while storing credentials : %s\n",LogTime(), PROGRAM, error_message(code)); goto loop_end; } if (creds->server) krb5_free_principal(kparam.context,creds->server); #ifdef HAVE_HEIMDAL_KERBEROS service=malloc(strlen("krbtgt")+strlen(domain)+strlen(principal_list[i]->realm)+3); snprintf(service,strlen("krbtgt")+strlen(domain)+strlen(principal_list[i]->realm)+3,"krbtgt/%s@%s",domain,principal_list[i]->realm); #else service=malloc(strlen("krbtgt")+strlen(domain)+strlen(krb5_princ_realm(kparam.context, principal_list[i])->data)+3); snprintf(service,strlen("krbtgt")+strlen(domain)+strlen(krb5_princ_realm(kparam.context, principal_list[i])->data)+3,"krbtgt/%s@%s",domain,krb5_princ_realm(kparam.context, principal_list[i])->data); #endif code = krb5_parse_name(kparam.context,service,&creds->server); if (service) free(service); if (code) { fprintf(stderr, "%s| %s: Error while initialising TGT credentials : %s\n",LogTime(), PROGRAM, error_message(code)); goto loop_end; } code = krb5_get_credentials(kparam.context, 0, kparam.cc, creds, &tgt_creds); if (code) { if (margs->debug) fprintf(stderr, "%s| %s: Error while getting tgt : %s\n",LogTime(), PROGRAM, error_message(code)); goto loop_end; } else { if (margs->debug) fprintf(stderr, "%s| %s: Found trusted principal name: %s\n", LogTime(), PROGRAM, principal_name); break; } loop_end: if (principal_name) free(principal_name); principal_name=NULL; } if (tgt_creds) krb5_free_creds(kparam.context,tgt_creds); tgt_creds=NULL; if (creds) krb5_free_creds(kparam.context,creds); creds=NULL; } if (principal_name) { if (margs->debug) fprintf(stderr, "%s| %s: Got principal name %s\n",LogTime(), PROGRAM, principal_name); /* * build principal */ code = krb5_parse_name(kparam.context, principal_name, &principal); if (code) { fprintf(stderr, "%s| %s: Error while parsing name %s : %s\n", LogTime(), PROGRAM, principal_name,error_message(code)); retval=1; goto cleanup; } creds = malloc(sizeof(*creds)); memset(creds, 0, sizeof(*creds)); /* * get credentials */ #if HAVE_GET_INIT_CREDS_KEYTAB code = krb5_get_init_creds_keytab(kparam.context, creds, principal, keytab, 0, NULL, NULL); #else service=malloc(strlen("krbtgt")+2*strlen(domain)+3); snprintf(service,strlen("krbtgt")+2*strlen(domain)+3,"krbtgt/%s@%s",domain,domain); creds->client=principal; code = krb5_parse_name(kparam.context,service,&creds->server); if (service) free(service); code = krb5_get_in_tkt_with_keytab(kparam.context, 0, NULL, NULL, NULL, keytab, NULL, creds, 0); #endif if (code) { fprintf(stderr, "%s| %s: Error while initialising credentials from keytab : %s\n",LogTime(), PROGRAM, error_message(code)); retval=1; goto cleanup; } code = krb5_cc_initialize(kparam.context, kparam.cc, principal); if (code) { fprintf(stderr, "%s| %s: Error while initializing memory caches : %s\n",LogTime(), PROGRAM, error_message(code)); retval=1; goto cleanup; } code = krb5_cc_store_cred(kparam.context, kparam.cc, creds); if (code) { fprintf(stderr, "%s| %s: Error while storing credentials : %s\n",LogTime(), PROGRAM, error_message(code)); retval=1; goto cleanup; } if (margs->debug) fprintf(stderr, "%s| %s: Stored credentials\n",LogTime(), PROGRAM); } else { if (margs->debug) fprintf(stderr, "%s| %s: Got no principal name\n",LogTime(), PROGRAM); retval=1; } cleanup: if (keytab) krb5_kt_close(kparam.context, keytab); if (keytab_name) free(keytab_name); if (principal_name) free(principal_name); if (mem_cache) free(mem_cache); if (principal) krb5_free_principal(kparam.context,principal); for (i=0;i<nprinc;i++) { if (principal_list[i]) krb5_free_principal(kparam.context,principal_list[i]); } if (principal_list) free(principal_list); if (creds) krb5_free_creds(kparam.context,creds); return(retval); }