KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_rc_store(krb5_context context, krb5_rcache id, krb5_donot_replay *rep) { struct rc_entry ent, tmp; time_t t; FILE *f; int ret; size_t count; ent.stamp = time(NULL); checksum_authenticator(rep, ent.data); f = fopen(id->name, "r"); if(f == NULL) { char buf[128]; ret = errno; rk_strerror_r(ret, buf, sizeof(buf)); krb5_set_error_message(context, ret, "open(%s): %s", id->name, buf); return ret; } rk_cloexec_file(f); count = fread(&tmp, sizeof(ent), 1, f); if(count != 1) return KRB5_RC_IO_UNKNOWN; t = ent.stamp - tmp.stamp; while(fread(&tmp, sizeof(ent), 1, f)){ if(tmp.stamp < t) continue; if(memcmp(tmp.data, ent.data, sizeof(ent.data)) == 0){ fclose(f); krb5_clear_error_message (context); return KRB5_RC_REPLAY; } } if(ferror(f)){ char buf[128]; ret = errno; fclose(f); rk_strerror_r(ret, buf, sizeof(buf)); krb5_set_error_message(context, ret, "%s: %s", id->name, buf); return ret; } fclose(f); f = fopen(id->name, "a"); if(f == NULL) { char buf[128]; rk_strerror_r(errno, buf, sizeof(buf)); krb5_set_error_message(context, KRB5_RC_IO_UNKNOWN, "open(%s): %s", id->name, buf); return KRB5_RC_IO_UNKNOWN; } fwrite(&ent, 1, sizeof(ent), f); fclose(f); return 0; }
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_rc_destroy(krb5_context context, krb5_rcache id) { int ret; if(remove(id->name) < 0) { char buf[128]; ret = errno; rk_strerror_r(ret, buf, sizeof(buf)); krb5_set_error_message(context, ret, "remove(%s): %s", id->name, buf); return ret; } return krb5_rc_close(context, id); }
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_rc_initialize(krb5_context context, krb5_rcache id, krb5_deltat auth_lifespan) { FILE *f = fopen(id->name, "w"); struct rc_entry tmp; int ret; if(f == NULL) { char buf[128]; ret = errno; rk_strerror_r(ret, buf, sizeof(buf)); krb5_set_error_message(context, ret, "open(%s): %s", id->name, buf); return ret; } tmp.stamp = auth_lifespan; fwrite(&tmp, 1, sizeof(tmp), f); fclose(f); return 0; }
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_auth_con_genaddrs(krb5_context context, krb5_auth_context auth_context, krb5_socket_t fd, int flags) { krb5_error_code ret; krb5_address local_k_address, remote_k_address; krb5_address *lptr = NULL, *rptr = NULL; struct sockaddr_storage ss_local, ss_remote; struct sockaddr *local = (struct sockaddr *)&ss_local; struct sockaddr *remote = (struct sockaddr *)&ss_remote; socklen_t len; if(flags & KRB5_AUTH_CONTEXT_GENERATE_LOCAL_ADDR) { if (auth_context->local_address == NULL) { len = sizeof(ss_local); if(rk_IS_SOCKET_ERROR(getsockname(fd, local, &len))) { char buf[128]; ret = rk_SOCK_ERRNO; rk_strerror_r(ret, buf, sizeof(buf)); krb5_set_error_message(context, ret, "getsockname: %s", buf); goto out; } ret = krb5_sockaddr2address (context, local, &local_k_address); if(ret) goto out; if(flags & KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR) { krb5_sockaddr2port (context, local, &auth_context->local_port); } else auth_context->local_port = 0; lptr = &local_k_address; } } if(flags & KRB5_AUTH_CONTEXT_GENERATE_REMOTE_ADDR) { len = sizeof(ss_remote); if(rk_IS_SOCKET_ERROR(getpeername(fd, remote, &len))) { char buf[128]; ret = rk_SOCK_ERRNO; rk_strerror_r(ret, buf, sizeof(buf)); krb5_set_error_message(context, ret, "getpeername: %s", buf); goto out; } ret = krb5_sockaddr2address (context, remote, &remote_k_address); if(ret) goto out; if(flags & KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR) { krb5_sockaddr2port (context, remote, &auth_context->remote_port); } else auth_context->remote_port = 0; rptr = &remote_k_address; } ret = krb5_auth_con_setaddrs (context, auth_context, lptr, rptr); out: if (lptr) krb5_free_address (context, lptr); if (rptr) krb5_free_address (context, rptr); return ret; }