629
645
/* Try each uri in list, add connect fails to tmp list */
646
uris_mutex_lock(ctxt);
630
647
p = ctxt->uri->next;
631
648
while(p != ctxt->uri) {
632
649
this = list_entry(p, struct ldap_uri, list);
650
uris_mutex_unlock(ctxt);
634
651
debug(logopt, "trying server %s", this->uri);
635
652
ldap = connect_to_server(logopt, this->uri, ctxt);
637
654
info(logopt, "connected to uri %s", this->uri);
655
uris_mutex_lock(ctxt);
658
uris_mutex_lock(ctxt);
640
660
list_del_init(&this->list);
641
661
list_add_tail(&this->list, &tmp);
686
uris_mutex_lock(ctxt);
665
687
this = list_entry(ctxt->uri->next, struct ldap_uri, list);
688
uris_mutex_unlock(ctxt);
666
689
ldap = do_connect(logopt, this->uri, ctxt);
670
693
/* Failed to connect, put at end of list */
694
uris_mutex_lock(ctxt);
671
695
list_del_init(&this->list);
672
696
list_add_tail(&this->list, ctxt->uri);
697
uris_mutex_unlock(ctxt);
675
autofs_sasl_done(ctxt);
700
autofs_sasl_dispose(ctxt);
678
703
/* Current server failed connect, try the rest */
1505
1549
return NSS_STATUS_SUCCESS;
1552
static int get_percent_decoded_len(const char *name)
1557
int look_for_close = 0;
1561
/* assume escapes aren't interpreted inside brackets */
1562
if (look_for_close) {
1566
/* check for escaped % */
1580
} else if (*tmp == ']' && look_for_close) {
1591
assert(strlen(name) > escapes);
1592
return strlen(name) - escapes;
1596
* Try to catch heap corruption if our logic happens to be incorrect.
1598
static void validate_string_len(const char *orig, char *start,
1599
char *end, unsigned int len)
1601
debug(LOGOPT_NONE, MODPREFIX "string %s encoded as %s", orig, start);
1602
/* make sure we didn't overflow the allocated space */
1603
if (end - start > len + 1) {
1604
crit(LOGOPT_ANY, MODPREFIX "orig %s, len %d", orig, len);
1605
crit(LOGOPT_ANY, MODPREFIX "en/decoded %s, len %d", start,
1608
assert(end-start <= len + 1);
1509
1612
* Deal with encode and decode of % hack.
1512
1615
* -1 => syntax error or alloc fail.
1513
1616
* 1 transofrmed value returned.
1619
* Assumptions: %'s must be escaped by %'s. %'s are not used to escape
1620
* anything else except capital letters (so you can't escape a closing
1621
* bracket, for example).
1515
1623
static int decode_percent_hack(const char *name, char **key)
1517
1625
const char *tmp;
1518
1626
char *ptr, *new;
1628
int escaped = 0, look_for_close = 0;
1526
while (*tmp && *tmp != '%' && *tmp != '[' && *tmp != ']')
1540
while (*tmp && *tmp != ']') {
1551
new = malloc(strlen(name) + 1);
1635
len = get_percent_decoded_len(name);
1636
new = malloc(len + 1);
1558
if (*tmp == '%' || *tmp == '[' || *tmp == ']') {
1560
if (*tmp && *tmp != '%')
1646
if (!look_for_close)
1657
} else if (*tmp == ']' && look_for_close) {
1668
validate_string_len(name, new, ptr, len);
1569
1669
return strlen(new);
1673
* Calculate the length of a string replacing all capital letters with %letter.
1678
static int get_encoded_len_escaping_every_cap(const char *name)
1681
unsigned int escapes = 0; /* number of % escape characters */
1685
/* We'll need to escape percents */
1686
if (*tmp == '%' || isupper(*tmp))
1691
return strlen(name) + escapes;
1695
* Calculate the length of a string replacing sequences (1 or more) of capital
1696
* letters with %[letters]. For example:
1699
* WorksForMe -> %[W]orks%[F]or%[M]e
1700
* aaBBaa -> aa%[BB]aa
1702
static int get_encoded_len_escaping_sequences(const char *name)
1705
unsigned int escapes = 0;
1709
/* escape percents */
1712
else if (isupper(*tmp)) {
1713
/* start an escape block %[...] */
1714
escapes += 3; /* %[] */
1715
while (*tmp && isupper(*tmp))
1722
return strlen(name) + escapes;
1725
static void encode_individual(const char *name, char *new, unsigned int len)
1733
if (*tmp == '%' || isupper(*tmp))
1738
validate_string_len(name, new, ptr, len);
1741
static void encode_sequence(const char *name, char *new, unsigned int len)
1752
} else if (isupper(*tmp)) {
1757
while (*tmp && isupper(*tmp)) {
1766
validate_string_len(name, new, ptr, len);
1770
* use_class: 1 means encode string as %[CAPITALS], 0 means encode as
1572
1773
static int encode_percent_hack(const char *name, char **key, unsigned int use_class)
1575
1775
unsigned int len = 0;
1781
len = get_encoded_len_escaping_sequences(name);
1783
len = get_encoded_len_escaping_every_cap(name);
1587
else if (isupper(*tmp)) {
1593
if (*tmp && isupper(*tmp))
1597
while (*tmp && isupper(*tmp)) {
1785
/* If there is no escaping to be done, return 0 */
1607
1786
if (len == strlen(name))
1610
new = malloc(len + 1);
1789
*key = malloc(len + 1);
1619
else if (isupper(*tmp)) {
1622
if (*tmp && (!isupper(*tmp) || !use_class))
1627
while (*tmp && isupper(*tmp))
1794
encode_sequence(name, *key, len);
1796
encode_individual(name, *key, len);
1798
if (strlen(*key) != len)
1799
crit(LOGOPT_ANY, MODPREFIX "encoded key length mismatch: key "
1800
"%s len %d strlen %d", *key, len, strlen(*key));
1802
return strlen(*key);
1642
1805
static int do_paged_query(struct ldap_search_params *sp, struct lookup_context *ctxt)
2580
2743
status = check_map_indirect(ap, lkp_key, strlen(lkp_key), ctxt);
2584
MODPREFIX "key \"%s\" not found in map",
2590
2749
cache_readlock(mc);
2591
2750
me = cache_lookup(mc, key);
2592
/* Stale mapent => check for wildcard */
2593
if (me && !me->mapent)
2594
me = cache_lookup_distinct(mc, "*");
2751
/* Stale mapent => check for entry in alternate source or wildcard */
2752
if (me && !me->mapent) {
2753
while ((me = cache_lookup_key_next(me)))
2754
if (me->source == source)
2757
me = cache_lookup_distinct(mc, "*");
2595
2759
if (me && (me->source == source || *me->key == '/')) {
2596
2760
mapent_len = strlen(me->mapent);
2597
2761
mapent = alloca(mapent_len + 1);