00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "includes.h"
00027
00028
00029
00030
00031
00032 #ifdef HAVE_KRB5
00033 static BOOL is_our_primary_domain(const char *domain)
00034 {
00035 int role = lp_server_role();
00036
00037 if ((role == ROLE_DOMAIN_MEMBER) && strequal(lp_workgroup(), domain)) {
00038 return True;
00039 } else if (strequal(get_global_sam_name(), domain)) {
00040 return True;
00041 }
00042 return False;
00043 }
00044 #endif
00045
00046
00047
00048
00049
00050 static BOOL ads_dc_name(const char *domain,
00051 const char *realm,
00052 struct in_addr *dc_ip,
00053 fstring srv_name)
00054 {
00055 ADS_STRUCT *ads;
00056 char *sitename;
00057 int i;
00058
00059 if (!realm && strequal(domain, lp_workgroup())) {
00060 realm = lp_realm();
00061 }
00062
00063 sitename = sitename_fetch(realm);
00064
00065
00066 for( i =0 ; i < 3; i++) {
00067 ads = ads_init(realm, domain, NULL);
00068 if (!ads) {
00069 SAFE_FREE(sitename);
00070 return False;
00071 }
00072
00073 DEBUG(4,("ads_dc_name: domain=%s\n", domain));
00074
00075 #ifdef HAVE_ADS
00076
00077 ads->auth.flags |= ADS_AUTH_NO_BIND;
00078 ads_connect(ads);
00079 #endif
00080
00081 if (!ads->config.realm) {
00082 SAFE_FREE(sitename);
00083 ads_destroy(&ads);
00084 return False;
00085 }
00086
00087
00088
00089
00090
00091 if (stored_sitename_changed(realm, sitename)) {
00092 SAFE_FREE(sitename);
00093 sitename = sitename_fetch(realm);
00094 ads_destroy(&ads);
00095
00096 namecache_delete(realm, 0x1C);
00097 namecache_delete(domain, 0x1C);
00098 continue;
00099 }
00100
00101 #ifdef HAVE_KRB5
00102 if (is_our_primary_domain(domain) && (ads->config.flags & ADS_KDC)) {
00103 if (ads_closest_dc(ads)) {
00104
00105
00106
00107
00108 create_local_private_krb5_conf_for_domain(realm,
00109 domain,
00110 sitename,
00111 ads->ldap_ip);
00112 } else {
00113
00114 create_local_private_krb5_conf_for_domain(realm,
00115 domain,
00116 NULL,
00117 ads->ldap_ip);
00118 }
00119 }
00120 #endif
00121 break;
00122 }
00123
00124 if (i == 3) {
00125 DEBUG(1,("ads_dc_name: sitename (now \"%s\") keeps changing ???\n",
00126 sitename ? sitename : ""));
00127 SAFE_FREE(sitename);
00128 return False;
00129 }
00130
00131 SAFE_FREE(sitename);
00132
00133 fstrcpy(srv_name, ads->config.ldap_server_name);
00134 strupper_m(srv_name);
00135 *dc_ip = ads->ldap_ip;
00136 ads_destroy(&ads);
00137
00138 DEBUG(4,("ads_dc_name: using server='%s' IP=%s\n",
00139 srv_name, inet_ntoa(*dc_ip)));
00140
00141 return True;
00142 }
00143
00144
00145
00146
00147
00148
00149 static BOOL rpc_dc_name(const char *domain, fstring srv_name, struct in_addr *ip_out)
00150 {
00151 struct ip_service *ip_list = NULL;
00152 struct in_addr dc_ip, exclude_ip;
00153 int count, i;
00154 NTSTATUS result;
00155
00156 zero_ip(&exclude_ip);
00157
00158
00159
00160 if (!NT_STATUS_IS_OK(get_sorted_dc_list(domain, NULL, &ip_list, &count,
00161 False))) {
00162 DEBUG(3, ("Could not look up dc's for domain %s\n", domain));
00163 return False;
00164 }
00165
00166
00167
00168 for (i = 0; i < count; i++) {
00169 if (is_zero_ip(ip_list[i].ip))
00170 continue;
00171
00172 if (name_status_find(domain, 0x1c, 0x20, ip_list[i].ip, srv_name)) {
00173 result = check_negative_conn_cache( domain, srv_name );
00174 if ( NT_STATUS_IS_OK(result) ) {
00175 dc_ip = ip_list[i].ip;
00176 goto done;
00177 }
00178 }
00179 }
00180
00181
00182 SAFE_FREE(ip_list);
00183
00184
00185 return False;
00186
00187 done:
00188
00189
00190
00191
00192
00193 DEBUG(3, ("rpc_dc_name: Returning DC %s (%s) for domain %s\n", srv_name,
00194 inet_ntoa(dc_ip), domain));
00195
00196 *ip_out = dc_ip;
00197
00198 SAFE_FREE(ip_list);
00199
00200 return True;
00201 }
00202
00203
00204
00205
00206
00207 BOOL get_dc_name(const char *domain, const char *realm, fstring srv_name, struct in_addr *ip_out)
00208 {
00209 struct in_addr dc_ip;
00210 BOOL ret;
00211 BOOL our_domain = False;
00212
00213 zero_ip(&dc_ip);
00214
00215 ret = False;
00216
00217 if ( strequal(lp_workgroup(), domain) || strequal(lp_realm(), realm) )
00218 our_domain = True;
00219
00220
00221
00222
00223 if ( (our_domain && lp_security()==SEC_ADS) || realm ) {
00224 ret = ads_dc_name(domain, realm, &dc_ip, srv_name);
00225 }
00226
00227 if (!domain) {
00228
00229 return False;
00230 }
00231
00232 if (!ret) {
00233
00234 ret = rpc_dc_name(domain, srv_name, &dc_ip);
00235 }
00236
00237 *ip_out = dc_ip;
00238
00239 return ret;
00240 }