📄 krbhst.c
字号:
hi->proto = krbhst_get_default_proto(kd); hi->port = hi->def_port = socket_get_port(addr); hi->ai = ai; memmove(hi->hostname, host, hostlen); hi->hostname[hostlen] = '\0'; append_host_hostinfo(kd, hi); return 0;}static voidplugin_get_hosts(krb5_context context, struct krb5_krbhst_data *kd, enum locate_service_type type){ struct krb5_plugin *list = NULL, *e; krb5_error_code ret; ret = _krb5_plugin_find(context, PLUGIN_TYPE_DATA, "resolve", &list); if(ret != 0 || list == NULL) return; kd->flags |= KD_CONFIG_EXISTS; for (e = list; e != NULL; e = _krb5_plugin_get_next(e)) { krb5plugin_service_locate_ftable *service; void *ctx; service = _krb5_plugin_get_symbol(e); if (service->minor_version != 0) continue; (*service->init)(context, &ctx); ret = (*service->lookup)(ctx, type, kd->realm, 0, 0, add_locate, kd); (*service->fini)(ctx); if (ret) { krb5_set_error_string(context, "Plugin failed to lookup"); break; } } _krb5_plugin_free(list);}/* * */static krb5_error_codekdc_get_next(krb5_context context, struct krb5_krbhst_data *kd, krb5_krbhst_info **host){ krb5_error_code ret; if ((kd->flags & KD_PLUGIN) == 0) { plugin_get_hosts(context, kd, locate_service_kdc); kd->flags |= KD_PLUGIN; if(get_next(kd, host)) return 0; } if((kd->flags & KD_CONFIG) == 0) { config_get_hosts(context, kd, "kdc"); kd->flags |= KD_CONFIG; if(get_next(kd, host)) return 0; } if (kd->flags & KD_CONFIG_EXISTS) return KRB5_KDC_UNREACH; /* XXX */ if(context->srv_lookup) { if((kd->flags & KD_SRV_UDP) == 0 && (kd->flags & KD_LARGE_MSG) == 0) { srv_get_hosts(context, kd, "udp", "kerberos"); kd->flags |= KD_SRV_UDP; if(get_next(kd, host)) return 0; } if((kd->flags & KD_SRV_TCP) == 0) { srv_get_hosts(context, kd, "tcp", "kerberos"); kd->flags |= KD_SRV_TCP; if(get_next(kd, host)) return 0; } if((kd->flags & KD_SRV_HTTP) == 0) { srv_get_hosts(context, kd, "http", "kerberos"); kd->flags |= KD_SRV_HTTP; if(get_next(kd, host)) return 0; } } while((kd->flags & KD_FALLBACK) == 0) { ret = fallback_get_hosts(context, kd, "kerberos", kd->def_port, krbhst_get_default_proto(kd)); if(ret) return ret; if(get_next(kd, host)) return 0; } return KRB5_KDC_UNREACH; /* XXX */}static krb5_error_codeadmin_get_next(krb5_context context, struct krb5_krbhst_data *kd, krb5_krbhst_info **host){ krb5_error_code ret; if ((kd->flags & KD_PLUGIN) == 0) { plugin_get_hosts(context, kd, locate_service_kadmin); kd->flags |= KD_PLUGIN; if(get_next(kd, host)) return 0; } if((kd->flags & KD_CONFIG) == 0) { config_get_hosts(context, kd, "admin_server"); kd->flags |= KD_CONFIG; if(get_next(kd, host)) return 0; } if (kd->flags & KD_CONFIG_EXISTS) return KRB5_KDC_UNREACH; /* XXX */ if(context->srv_lookup) { if((kd->flags & KD_SRV_TCP) == 0) { srv_get_hosts(context, kd, "tcp", "kerberos-adm"); kd->flags |= KD_SRV_TCP; if(get_next(kd, host)) return 0; } } if (krbhst_empty(kd) && (kd->flags & KD_FALLBACK) == 0) { ret = fallback_get_hosts(context, kd, "kerberos", kd->def_port, krbhst_get_default_proto(kd)); if(ret) return ret; kd->flags |= KD_FALLBACK; if(get_next(kd, host)) return 0; } return KRB5_KDC_UNREACH; /* XXX */}static krb5_error_codekpasswd_get_next(krb5_context context, struct krb5_krbhst_data *kd, krb5_krbhst_info **host){ krb5_error_code ret; if ((kd->flags & KD_PLUGIN) == 0) { plugin_get_hosts(context, kd, locate_service_kpasswd); kd->flags |= KD_PLUGIN; if(get_next(kd, host)) return 0; } if((kd->flags & KD_CONFIG) == 0) { config_get_hosts(context, kd, "kpasswd_server"); kd->flags |= KD_CONFIG; if(get_next(kd, host)) return 0; } if (kd->flags & KD_CONFIG_EXISTS) return KRB5_KDC_UNREACH; /* XXX */ if(context->srv_lookup) { if((kd->flags & KD_SRV_UDP) == 0) { srv_get_hosts(context, kd, "udp", "kpasswd"); kd->flags |= KD_SRV_UDP; if(get_next(kd, host)) return 0; } if((kd->flags & KD_SRV_TCP) == 0) { srv_get_hosts(context, kd, "tcp", "kpasswd"); kd->flags |= KD_SRV_TCP; if(get_next(kd, host)) return 0; } } /* no matches -> try admin */ if (krbhst_empty(kd)) { kd->flags = 0; kd->port = kd->def_port; kd->get_next = admin_get_next; ret = (*kd->get_next)(context, kd, host); if (ret == 0) (*host)->proto = krbhst_get_default_proto(kd); return ret; } return KRB5_KDC_UNREACH; /* XXX */}static krb5_error_codekrb524_get_next(krb5_context context, struct krb5_krbhst_data *kd, krb5_krbhst_info **host){ if ((kd->flags & KD_PLUGIN) == 0) { plugin_get_hosts(context, kd, locate_service_krb524); kd->flags |= KD_PLUGIN; if(get_next(kd, host)) return 0; } if((kd->flags & KD_CONFIG) == 0) { config_get_hosts(context, kd, "krb524_server"); if(get_next(kd, host)) return 0; kd->flags |= KD_CONFIG; } if (kd->flags & KD_CONFIG_EXISTS) return KRB5_KDC_UNREACH; /* XXX */ if(context->srv_lookup) { if((kd->flags & KD_SRV_UDP) == 0) { srv_get_hosts(context, kd, "udp", "krb524"); kd->flags |= KD_SRV_UDP; if(get_next(kd, host)) return 0; } if((kd->flags & KD_SRV_TCP) == 0) { srv_get_hosts(context, kd, "tcp", "krb524"); kd->flags |= KD_SRV_TCP; if(get_next(kd, host)) return 0; } } /* no matches -> try kdc */ if (krbhst_empty(kd)) { kd->flags = 0; kd->port = kd->def_port; kd->get_next = kdc_get_next; return (*kd->get_next)(context, kd, host); } return KRB5_KDC_UNREACH; /* XXX */}static struct krb5_krbhst_data*common_init(krb5_context context, const char *realm, int flags){ struct krb5_krbhst_data *kd; if((kd = calloc(1, sizeof(*kd))) == NULL) return NULL; if((kd->realm = strdup(realm)) == NULL) { free(kd); return NULL; } /* For 'realms' without a . do not even think of going to DNS */ if (!strchr(realm, '.')) kd->flags |= KD_CONFIG_EXISTS; if (flags & KRB5_KRBHST_FLAGS_LARGE_MSG) kd->flags |= KD_LARGE_MSG; kd->end = kd->index = &kd->hosts; return kd;}/* * initialize `handle' to look for hosts of type `type' in realm `realm' */krb5_error_code KRB5_LIB_FUNCTIONkrb5_krbhst_init(krb5_context context, const char *realm, unsigned int type, krb5_krbhst_handle *handle){ return krb5_krbhst_init_flags(context, realm, type, 0, handle);}krb5_error_code KRB5_LIB_FUNCTIONkrb5_krbhst_init_flags(krb5_context context, const char *realm, unsigned int type, int flags, krb5_krbhst_handle *handle){ struct krb5_krbhst_data *kd; krb5_error_code (*next)(krb5_context, struct krb5_krbhst_data *, krb5_krbhst_info **); int def_port; switch(type) { case KRB5_KRBHST_KDC: next = kdc_get_next; def_port = ntohs(krb5_getportbyname (context, "kerberos", "udp", 88)); break; case KRB5_KRBHST_ADMIN: next = admin_get_next; def_port = ntohs(krb5_getportbyname (context, "kerberos-adm", "tcp", 749)); break; case KRB5_KRBHST_CHANGEPW: next = kpasswd_get_next; def_port = ntohs(krb5_getportbyname (context, "kpasswd", "udp", KPASSWD_PORT)); break; case KRB5_KRBHST_KRB524: next = krb524_get_next; def_port = ntohs(krb5_getportbyname (context, "krb524", "udp", 4444)); break; default: krb5_set_error_string(context, "unknown krbhst type (%u)", type); return ENOTTY; } if((kd = common_init(context, realm, flags)) == NULL) return ENOMEM; kd->get_next = next; kd->def_port = def_port; *handle = kd; return 0;}/* * return the next host information from `handle' in `host' */krb5_error_code KRB5_LIB_FUNCTIONkrb5_krbhst_next(krb5_context context, krb5_krbhst_handle handle, krb5_krbhst_info **host){ if(get_next(handle, host)) return 0; return (*handle->get_next)(context, handle, host);}/* * return the next host information from `handle' as a host name * in `hostname' (or length `hostlen) */krb5_error_code KRB5_LIB_FUNCTIONkrb5_krbhst_next_as_string(krb5_context context, krb5_krbhst_handle handle, char *hostname, size_t hostlen){ krb5_error_code ret; krb5_krbhst_info *host; ret = krb5_krbhst_next(context, handle, &host); if(ret) return ret; return krb5_krbhst_format_string(context, host, hostname, hostlen);}void KRB5_LIB_FUNCTIONkrb5_krbhst_reset(krb5_context context, krb5_krbhst_handle handle){ handle->index = &handle->hosts;}void KRB5_LIB_FUNCTIONkrb5_krbhst_free(krb5_context context, krb5_krbhst_handle handle){ krb5_krbhst_info *h, *next; if (handle == NULL) return; for (h = handle->hosts; h != NULL; h = next) { next = h->next; _krb5_free_krbhst_info(h); } free(handle->realm); free(handle);}/* backwards compatibility ahead */static krb5_error_codegethostlist(krb5_context context, const char *realm, unsigned int type, char ***hostlist){ krb5_error_code ret; int nhost = 0; krb5_krbhst_handle handle; char host[MAXHOSTNAMELEN]; krb5_krbhst_info *hostinfo; ret = krb5_krbhst_init(context, realm, type, &handle); if (ret) return ret; while(krb5_krbhst_next(context, handle, &hostinfo) == 0) nhost++; if(nhost == 0) { krb5_set_error_string(context, "No KDC found for realm %s", realm); return KRB5_KDC_UNREACH; } *hostlist = calloc(nhost + 1, sizeof(**hostlist)); if(*hostlist == NULL) { krb5_krbhst_free(context, handle); return ENOMEM; } krb5_krbhst_reset(context, handle); nhost = 0; while(krb5_krbhst_next_as_string(context, handle, host, sizeof(host)) == 0) { if(((*hostlist)[nhost++] = strdup(host)) == NULL) { krb5_free_krbhst(context, *hostlist); krb5_krbhst_free(context, handle); return ENOMEM; } } (*hostlist)[nhost++] = NULL; krb5_krbhst_free(context, handle); return 0;}/* * return an malloced list of kadmin-hosts for `realm' in `hostlist' */krb5_error_code KRB5_LIB_FUNCTIONkrb5_get_krb_admin_hst (krb5_context context, const krb5_realm *realm, char ***hostlist){ return gethostlist(context, *realm, KRB5_KRBHST_ADMIN, hostlist);}/* * return an malloced list of changepw-hosts for `realm' in `hostlist' */krb5_error_code KRB5_LIB_FUNCTIONkrb5_get_krb_changepw_hst (krb5_context context, const krb5_realm *realm, char ***hostlist){ return gethostlist(context, *realm, KRB5_KRBHST_CHANGEPW, hostlist);}/* * return an malloced list of 524-hosts for `realm' in `hostlist' */krb5_error_code KRB5_LIB_FUNCTIONkrb5_get_krb524hst (krb5_context context, const krb5_realm *realm, char ***hostlist){ return gethostlist(context, *realm, KRB5_KRBHST_KRB524, hostlist);}/* * return an malloced list of KDC's for `realm' in `hostlist' */krb5_error_code KRB5_LIB_FUNCTIONkrb5_get_krbhst (krb5_context context, const krb5_realm *realm, char ***hostlist){ return gethostlist(context, *realm, KRB5_KRBHST_KDC, hostlist);}/* * free all the memory allocated in `hostlist' */krb5_error_code KRB5_LIB_FUNCTIONkrb5_free_krbhst (krb5_context context, char **hostlist){ char **p; for (p = hostlist; *p; ++p) free (*p); free (hostlist); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -