struct in_addr dc_ip;
fstring srv_name;
- if (!get_dc_name(domain, srv_name, &dc_ip)) {
+ if (!rpc_dc_name(domain, srv_name, &dc_ip)) {
DEBUG(0,("find_connect_dc: Failed to find an DCs for %s\n", lp_workgroup()));
return NT_STATUS_NO_LOGON_SERVERS;
}
/*
try a connection to a given ldap server, returning True and setting the servers IP
in the ads struct if successful
+
+ TODO : add a negative connection cache in here leveraged off of the one
+ found in the rpc code. --jerry
*/
static BOOL ads_try_connect(ADS_STRUCT *ads, const char *server, unsigned port)
{
}
}
+ if ( DEBUGLEVEL >= 4 ) {
+ DEBUG(4,("get_dc_list: returning %d ip addresses in an %sordered list\n", local_count,
+ *ordered ? "":"un"));
+ DEBUG(4,("get_dc_list: "));
+ for ( i=0; i<local_count; i++ )
+ DEBUGADD(4,("%s ", inet_ntoa(return_iplist[i])));
+ DEBUGADD(4,("\n"));
+ }
+
*ip_list = return_iplist;
*count = local_count;
-
- DEBUG(8,("get_dc_list: return %d ip addresses\n", *count));
return (*count != 0);
}
valid since we have already done a name_status_find on it
***************************************************************************/
-BOOL get_dc_name(const char *domain, fstring srv_name, struct in_addr *ip_out)
+BOOL rpc_dc_name(const char *domain, fstring srv_name, struct in_addr *ip_out)
{
struct in_addr *ip_list = NULL, dc_ip, exclude_ip;
int count, i;
if ( use_pdc_only && get_pdc_ip(domain, &dc_ip) )
{
- DEBUG(10,("get_dc_name: Atempting to lookup PDC to avoid sam sync delays\n"));
+ DEBUG(10,("rpc_dc_name: Atempting to lookup PDC to avoid sam sync delays\n"));
/* check the connection cache and perform the node status
lookup only if the IP is not found to be bad */
}
}
- if ( !list_ordered )
- {
- /*
- * Pick a nice close server. Look for DC on local net
- * (assuming we don't have a list of preferred DC's)
- */
-
- for (i = 0; i < count; i++) {
- if (is_zero_ip(ip_list[i]))
- continue;
-
- if ( !is_local_net(ip_list[i]) )
- continue;
-
- if (name_status_find(domain, 0x1c, 0x20, ip_list[i], srv_name)) {
- result = check_negative_conn_cache( domain, srv_name );
- if ( NT_STATUS_IS_OK(result) ) {
- dc_ip = ip_list[i];
- goto done;
- }
- }
-
- zero_ip(&ip_list[i]);
- }
-
- /*
- * Try looking in the name status cache for an
- * entry we already have. We know that already
- * resolved ok.
- */
-
- for (i = 0; i < count; i++) {
- if (is_zero_ip(ip_list[i]))
- continue;
-
- if (namecache_status_fetch(domain, 0x1c, 0x20,
- ip_list[i], srv_name)) {
- result = check_negative_conn_cache( domain, srv_name );
- if ( NT_STATUS_IS_OK(result) ) {
- dc_ip = ip_list[i];
- goto done;
- }
- }
- }
-
- /*
- * Secondly try and contact a random PDC/BDC.
- */
-
- i = (sys_random() % count);
-
- if ( !is_zero_ip(ip_list[i]) ) {
- if ( name_status_find(domain, 0x1c, 0x20, ip_list[i], srv_name)) {
- result = check_negative_conn_cache( domain, srv_name );
- if ( NT_STATUS_IS_OK(result) ) {
- dc_ip = ip_list[i];
- goto done;
- }
- }
- zero_ip(&ip_list[i]); /* Tried and failed. */
- }
+ /* Pick a nice close server, but only if the list was not ordered */
+
+ if (!list_ordered && (count > 1) ) {
+ qsort(ip_list, count, sizeof(struct in_addr), QSORT_CAST ip_compare);
}
- /* Finally return first DC that we can contact */
-
for (i = 0; i < count; i++) {
if (is_zero_ip(ip_list[i]))
continue;
dc_ip = ip_list[i];
goto done;
}
- }
+ }
}
+
SAFE_FREE(ip_list);
the DC is alive and kicking. If we can catch a dead DC before
performing a cli_connect() we can avoid a 30-second timeout. */
- DEBUG(3, ("get_dc_name: Returning DC %s (%s) for domain %s\n", srv_name,
+ DEBUG(3, ("rpc_dc_name: Returning DC %s (%s) for domain %s\n", srv_name,
inet_ntoa(dc_ip), domain));
*ip_out = dc_ip;
return True;
}
-static BOOL cm_get_dc_name(const char *domain, fstring srv_name, struct in_addr *ip_out)
+/**********************************************************************
+ wrapper around ads and rpc methods of finds DC's
+**********************************************************************/
+
+static BOOL cm_get_dc_name(const char *domain, fstring srv_name,
+ struct in_addr *ip_out)
{
- static struct get_dc_name_cache *get_dc_name_cache;
- struct get_dc_name_cache *dcc;
struct in_addr dc_ip;
BOOL ret;
- /* Check the cache for previous lookups */
-
- for (dcc = get_dc_name_cache; dcc; dcc = dcc->next) {
-
- if (!strequal(domain, dcc->domain_name))
- continue; /* Not our domain */
-
- if ((time(NULL) - dcc->lookup_time) >
- GET_DC_NAME_CACHE_TIMEOUT) {
-
- /* Cache entry has expired, delete it */
-
- DEBUG(10, ("get_dc_name_cache entry expired for %s\n", domain));
-
- DLIST_REMOVE(get_dc_name_cache, dcc);
- SAFE_FREE(dcc);
-
- break;
- }
-
- /* Return a positive or negative lookup for this domain */
-
- if (dcc->srv_name[0]) {
- DEBUG(10, ("returning positive get_dc_name_cache entry for %s\n", domain));
- fstrcpy(srv_name, dcc->srv_name);
- return True;
- } else {
- DEBUG(10, ("returning negative get_dc_name_cache entry for %s\n", domain));
- return False;
- }
- }
-
- /* Add cache entry for this lookup. */
-
- DEBUG(10, ("Creating get_dc_name_cache entry for %s\n", domain));
-
- if (!(dcc = (struct get_dc_name_cache *)
- malloc(sizeof(struct get_dc_name_cache))))
- return False;
-
- ZERO_STRUCTP(dcc);
-
- fstrcpy(dcc->domain_name, domain);
- dcc->lookup_time = time(NULL);
-
- DLIST_ADD(get_dc_name_cache, dcc);
-
zero_ip(&dc_ip);
ret = False;
if (!ret) {
/* fall back on rpc methods if the ADS methods fail */
- ret = get_dc_name(domain, srv_name, &dc_ip);
+ ret = rpc_dc_name(domain, srv_name, &dc_ip);
}
- if (!ret)
- return False;
-
- /* We have a name so make the cache entry positive now */
- fstrcpy(dcc->srv_name, srv_name);
-
- DEBUG(3, ("cm_get_dc_name: Returning DC %s (%s) for domain %s\n", srv_name,
- inet_ntoa(dc_ip), domain));
-
*ip_out = dc_ip;
- return True;
+ return ret;
}
/* Choose between anonymous or authenticated connections. We need to use
fstrcpy(new_conn->domain, domain);
fstrcpy(new_conn->pipe_name, get_pipe_name_from_index(pipe_index));
- /* connection failure cache has been moved inside of get_dc_name
+ /* connection failure cache has been moved inside of rpc_dc_name
so we can deal with half dead DC's --jerry */
if (!cm_get_dc_name(domain, new_conn->controller, &dc_ip)) {
return WINBINDD_ERROR;
}
- if ( !((name_type==SID_NAME_DOM_GRP) ||
- ((name_type==SID_NAME_ALIAS) && strequal(lp_workgroup(), domain->name))) )
- {
- DEBUG(1, ("name '%s' is not a local or domain group: %d\n",
- group_name, name_type));
- return WINBINDD_ERROR;
- }
-
/* Fill in group structure */
domain = find_domain_from_sid(&group_sid);
return WINBINDD_ERROR;
}
+ if ( !((name_type==SID_NAME_DOM_GRP) ||
+ ((name_type==SID_NAME_ALIAS) && strequal(lp_workgroup(), domain->name))) )
+ {
+ DEBUG(1, ("name '%s' is not a local or domain group: %d\n",
+ group_name, name_type));
+ return WINBINDD_ERROR;
+ }
+
if (!fill_grent(&state->response.data.gr, dom_name, group_name,
state->request.data.gid) ||
!fill_grent_mem(domain, &group_sid, name_type,
if ((ldp = ldap_open_with_timeout(server, LDAP_PORT, 10)) == NULL)
return -1;
-#if 0
- /* As per tridge comment this doesn't seem to be needed. JRA */
- if ((err = ldap_simple_bind_s(ldp, NULL, NULL)) != 0)
- goto done;
-#endif
-
/* Timeout if no response within 20 seconds. */
to.tv_sec = 10;
to.tv_usec = 0;
return False;
}
- if ( !list_ordered )
- {
- /*
- * Pick a nice close server. Look for DC on local net
- * (assuming we don't have a list of preferred DC's)
- */
-
- for (i = 0; i < count; i++) {
- if (is_zero_ip(ip_list[i]))
- continue;
-
- if ( !is_local_net(ip_list[i]) )
- continue;
-
- if ( (ret = get_ldap_seq( inet_ntoa(ip_list[i]), seq)) == 0 )
- goto done;
-
- zero_ip(&ip_list[i]);
- }
+ /* sort the list so we can pick a close server */
-
- /*
- * Secondly try and contact a random PDC/BDC.
- */
-
- i = (sys_random() % count);
-
- if ( !is_zero_ip(ip_list[i]) ) {
- if ( (ret = get_ldap_seq( inet_ntoa(ip_list[i]), seq)) == 0 )
- goto done;
- }
- zero_ip(&ip_list[i]); /* Tried and failed. */
+ if (!list_ordered && (count > 1) ) {
+ qsort(ip_list, count, sizeof(struct in_addr), QSORT_CAST ip_compare);
}
/* Finally return first DC that we can contact */
/* get a printer handle */
result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
- MAXIMUM_ALLOWED_ACCESS, servername,
+ PRINTER_ALL_ACCESS, servername,
user, &pol);
if (!W_ERROR_IS_OK(result))