From: Todd C. Miller Date: Tue, 16 Jun 2015 19:58:45 +0000 (-0600) Subject: Use non-exiting allocators in the sudoers LDAP backend. X-Git-Tag: SUDO_1_8_14^2~88 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5413637ae83a772188b192b6ad966311de7b675e;p=sudo Use non-exiting allocators in the sudoers LDAP backend. --- diff --git a/plugins/sudoers/ldap.c b/plugins/sudoers/ldap.c index e04855424..e55b17ffa 100644 --- a/plugins/sudoers/ldap.c +++ b/plugins/sudoers/ldap.c @@ -43,6 +43,7 @@ # include #endif #include +#include #include #include #include @@ -398,7 +399,7 @@ static struct ldap_result *sudo_ldap_result_get(struct sudo_nss *nss, struct sudo_ldap_handle { LDAP *ld; struct ldap_result *result; - char *username; + const char *username; struct group_list *grlist; }; @@ -448,9 +449,10 @@ sudo_ldap_conf_add_ports(void) } } - sudo_efree(ldap_conf.host); - ldap_conf.host = sudo_estrdup(hostbuf); - debug_return_bool(true); + free(ldap_conf.host); + if ((ldap_conf.host = strdup(hostbuf)) == NULL) + sudo_warnx(U_("unable to allocate memory")); + debug_return_bool(ldap_conf.host != NULL); overflow: sudo_warnx(U_("internal error, %s overflow"), __func__); @@ -477,7 +479,11 @@ sudo_ldap_parse_uri(const struct ldap_config_str_list *uri_list) hostbuf[0] = '\0'; STAILQ_FOREACH(entry, uri_list, entries) { - buf = sudo_estrdup(entry->val); + buf = strdup(entry->val); + if (buf == NULL) { + sudo_warnx(U_("unable to allocate memory")); + goto done; + } for ((uri = strtok(buf, " \t")); uri != NULL; (uri = strtok(NULL, " \t"))) { if (strncasecmp(uri, "ldap://", 7) == 0) { nldap++; @@ -520,18 +526,21 @@ sudo_ldap_parse_uri(const struct ldap_config_str_list *uri_list) sudo_warnx(U_("starttls not supported when using ldaps")); ldap_conf.ssl_mode = SUDO_LDAP_SSL; } - sudo_efree(buf); + free(buf); } buf = NULL; /* Store parsed URI(s) in host for ldap_create() or ldap_init(). */ - sudo_efree(ldap_conf.host); - ldap_conf.host = sudo_estrdup(hostbuf); + free(ldap_conf.host); + if ((ldap_conf.host = strdup(hostbuf)) == NULL) { + sudo_warnx(U_("unable to allocate memory")); + goto done; + } rc = LDAP_SUCCESS; done: - sudo_efree(buf); + free(buf); debug_return_int(rc); overflow: @@ -544,7 +553,7 @@ sudo_ldap_join_uri(struct ldap_config_str_list *uri_list) { struct ldap_config_str *uri; size_t len = 0; - char *buf, *cp; + char *buf = NULL; debug_decl(sudo_ldap_join_uri, SUDOERS_DEBUG_LDAP) STAILQ_FOREACH(uri, uri_list, entries) { @@ -556,13 +565,17 @@ sudo_ldap_join_uri(struct ldap_config_str_list *uri_list) } len += strlen(uri->val) + 1; } - buf = cp = sudo_emalloc(len); - buf[0] = '\0'; - STAILQ_FOREACH(uri, uri_list, entries) { - cp += strlcpy(cp, uri->val, len - (cp - buf)); - *cp++ = ' '; + if (len == 0 || (buf = malloc(len)) == NULL) { + sudo_warnx(U_("unable to allocate memory")); + } else { + char *cp = buf; + + STAILQ_FOREACH(uri, uri_list, entries) { + cp += strlcpy(cp, uri->val, len - (cp - buf)); + *cp++ = ' '; + } + cp[-1] = '\0'; } - cp[-1] = '\0'; debug_return_str(buf); } #endif /* HAVE_LDAP_INITIALIZE */ @@ -867,7 +880,7 @@ sudo_ldap_extract_digest(char **cmnd, struct sudo_digest *digest) { char *ep, *cp = *cmnd; int digest_type = SUDO_DIGEST_INVALID; - debug_decl(sudo_ldap_check_command, SUDOERS_DEBUG_LDAP) + debug_decl(sudo_ldap_extract_digest, SUDOERS_DEBUG_LDAP) /* * Check for and extract a digest prefix, e.g. @@ -903,7 +916,11 @@ sudo_ldap_extract_digest(char **cmnd, struct sudo_digest *digest) ep++; if (*ep != '\0') { digest->digest_type = digest_type; - digest->digest_str = sudo_estrndup(cp, (size_t)(ep - cp)); + digest->digest_str = strndup(cp, (size_t)(ep - cp)); + if (digest->digest_str == NULL) { + sudo_warnx(U_("unable to allocate memory")); + debug_return_ptr(NULL); + } cp = ep + 1; while (isblank((unsigned char)*cp)) cp++; @@ -959,10 +976,10 @@ sudo_ldap_check_command(LDAP *ld, LDAPMessage *entry, int *setenv_implied) /* check for !command */ if (*val == '!') { foundbang = true; - allowed_cmnd = sudo_estrdup(1 + val); /* !command */ + allowed_cmnd = val + 1; /* !command */ } else { foundbang = false; - allowed_cmnd = sudo_estrdup(val); /* command */ + allowed_cmnd = val; /* command */ } /* split optional args away from command */ @@ -978,12 +995,14 @@ sudo_ldap_check_command(LDAP *ld, LDAPMessage *entry, int *setenv_implied) */ ret = foundbang ? false : true; } + if (allowed_args != NULL) + allowed_args[-1] = ' '; /* restore val */ + DPRINTF2("ldap sudoCommand '%s' ... %s", val, ret == true ? "MATCH!" : "not"); - sudo_efree(allowed_cmnd); /* cleanup */ if (allowed_digest != NULL) - sudo_efree(allowed_digest->digest_str); + free(allowed_digest->digest_str); } ldap_value_free_len(bv); /* more cleanup */ @@ -1030,23 +1049,24 @@ sudo_ldap_check_bool(LDAP *ld, LDAPMessage *entry, char *option) * Read sudoOption and modify the defaults as we go. This is used once * from the cn=defaults entry and also once when a final sudoRole is matched. */ -static void +static bool sudo_ldap_parse_options(LDAP *ld, LDAPMessage *entry) { struct berval **bv, **p; char op, *var, *val; + bool rc = false; debug_decl(sudo_ldap_parse_options, SUDOERS_DEBUG_LDAP) - if (entry == NULL) - debug_return; - bv = ldap_get_values_len(ld, entry, "sudoOption"); if (bv == NULL) - debug_return; + debug_return_bool(true); /* walk through options */ for (p = bv; *p != NULL; p++) { - var = sudo_estrdup((*p)->bv_val); + if ((var = strdup((*p)->bv_val)) == NULL) { + sudo_warnx(U_("unable to allocate memory")); + goto done; + } DPRINTF2("ldap sudoOption: '%s'", var); /* check for equals sign past first char */ @@ -1069,12 +1089,14 @@ sudo_ldap_parse_options(LDAP *ld, LDAPMessage *entry) /* case var Boolean True */ set_default(var, NULL, true); } - sudo_efree(var); + free(var); } + rc = true; +done: ldap_value_free_len(bv); - debug_return; + debug_return_bool(rc); } /* @@ -1099,13 +1121,13 @@ sudo_ldap_parse_options(LDAP *ld, LDAPMessage *entry) * If either the sudoNotAfter or sudoNotBefore attributes are missing, * no time restriction shall be imposed. */ -static int +static bool sudo_ldap_timefilter(char *buffer, size_t buffersize) { struct tm *tp; time_t now; char timebuffer[sizeof("20120727121554.0Z")]; - int bytes = 0; + int len = -1; debug_decl(sudo_ldap_timefilter, SUDOERS_DEBUG_LDAP) /* Make sure we have a formatted timestamp for __now__. */ @@ -1122,15 +1144,15 @@ sudo_ldap_timefilter(char *buffer, size_t buffersize) } /* Build filter. */ - bytes = snprintf(buffer, buffersize, "(&(|(!(sudoNotAfter=*))(sudoNotAfter>=%s))(|(!(sudoNotBefore=*))(sudoNotBefore<=%s)))", + len = snprintf(buffer, buffersize, "(&(|(!(sudoNotAfter=*))(sudoNotAfter>=%s))(|(!(sudoNotBefore=*))(sudoNotBefore<=%s)))", timebuffer, timebuffer); - if (bytes <= 0 || (size_t)bytes >= buffersize) { - sudo_warn(U_("unable to build time filter")); - bytes = 0; + if (len <= 0 || (size_t)len >= buffersize) { + sudo_warnx(U_("internal error, %s overflow"), __func__); + len = -1; } done: - debug_return_int(bytes); + debug_return_bool(len != -1); } /* @@ -1139,13 +1161,13 @@ done: static char * sudo_ldap_build_default_filter(void) { - char *filt; + char *filt = NULL; debug_decl(sudo_ldap_build_default_filter, SUDOERS_DEBUG_LDAP) if (ldap_conf.search_filter) - sudo_easprintf(&filt, "(&%s(cn=defaults))", ldap_conf.search_filter); + (void)asprintf(&filt, "(&%s(cn=defaults))", ldap_conf.search_filter); else - filt = sudo_estrdup("cn=defaults"); + filt = strdup("cn=defaults"); debug_return_str(filt); } @@ -1252,7 +1274,6 @@ static bool sudo_netgroup_lookup_nested(LDAP *ld, char *base, struct timeval *timeout, struct ldap_netgroup_list *netgroups, struct ldap_netgroup *start) { - struct ldap_netgroup *ng, *old_tail; LDAPMessage *entry, *result; size_t filt_len; char *filt; @@ -1261,12 +1282,16 @@ sudo_netgroup_lookup_nested(LDAP *ld, char *base, struct timeval *timeout, DPRINTF1("Checking for nested netgroups from netgroup_base '%s'", base); do { + struct ldap_netgroup *ng, *old_tail; + + result = NULL; old_tail = STAILQ_LAST(netgroups, ldap_netgroup, entries); filt_len = strlen(ldap_conf.netgroup_search_filter) + 7; for (ng = start; ng != NULL; ng = STAILQ_NEXT(ng, entries)) { filt_len += sudo_ldap_value_len(ng->name) + 20; } - filt = sudo_emalloc(filt_len); + if ((filt = malloc(filt_len)) == NULL) + goto oom; CHECK_STRLCPY(filt, "(&", filt_len); CHECK_STRLCAT(filt, ldap_conf.netgroup_search_filter, filt_len); CHECK_STRLCAT(filt, "(|", filt_len); @@ -1277,9 +1302,9 @@ sudo_netgroup_lookup_nested(LDAP *ld, char *base, struct timeval *timeout, } CHECK_STRLCAT(filt, "))", filt_len); DPRINTF1("ldap netgroup search filter: '%s'", filt); - result = NULL; rc = ldap_search_ext_s(ld, base, LDAP_SCOPE_SUBTREE, filt, NULL, 0, NULL, NULL, timeout, 0, &result); + free(filt); if (rc == LDAP_SUCCESS) { LDAP_FOREACH(entry, ld, result) { struct berval **bv; @@ -1293,8 +1318,13 @@ sudo_netgroup_lookup_nested(LDAP *ld, char *base, struct timeval *timeout, break; } if (ng == NULL) { - ng = sudo_emalloc(sizeof(*ng)); - ng->name = sudo_estrdup((*bv)->bv_val); + ng = malloc(sizeof(*ng)); + if (ng == NULL || + (ng->name = strdup((*bv)->bv_val)) == NULL) { + free(ng); + ldap_value_free_len(bv); + goto oom; + } STAILQ_INSERT_TAIL(netgroups, ng, entries); DPRINTF1("Found new netgroup %s for %s", ng->name, base); } @@ -1304,14 +1334,19 @@ sudo_netgroup_lookup_nested(LDAP *ld, char *base, struct timeval *timeout, } if (result) ldap_msgfree(result); - sudo_efree(filt); /* Check for nested netgroups in what we added. */ start = old_tail ? STAILQ_NEXT(old_tail, entries) : STAILQ_FIRST(netgroups); } while (start != NULL); debug_return_bool(true); +oom: + sudo_warnx(U_("unable to allocate memory")); + if (result) + ldap_msgfree(result); + debug_return_bool(false); overflow: + free(filt); sudo_warnx(U_("internal error, %s overflow"), __func__); debug_return_bool(false); } @@ -1328,7 +1363,7 @@ sudo_netgroup_lookup(LDAP *ld, struct passwd *pw, struct ldap_config_str *base; struct ldap_netgroup *ng, *old_tail; struct timeval tv, *tvp = NULL; - LDAPMessage *entry, *result; + LDAPMessage *entry, *result = NULL; const char *domain; size_t filt_len; char *filt; @@ -1363,7 +1398,8 @@ sudo_netgroup_lookup(LDAP *ld, struct passwd *pw, filt_len += 3 * sudo_ldap_value_len(domain); } filt_len += 7 + strlen(ldap_conf.netgroup_search_filter); - filt = sudo_emalloc(filt_len); + if ((filt = malloc(filt_len)) == NULL) + goto oom; CHECK_STRLCPY(filt, "(&", filt_len); CHECK_STRLCAT(filt, ldap_conf.netgroup_search_filter, filt_len); CHECK_STRLCAT(filt, "(|(nisNetgroupTriple=\\28,", filt_len); @@ -1409,7 +1445,8 @@ sudo_netgroup_lookup(LDAP *ld, struct passwd *pw, filt_len += sudo_ldap_value_len(user_host); } filt_len += 7 + strlen(ldap_conf.netgroup_search_filter); - filt = sudo_emalloc(filt_len); + if ((filt = malloc(filt_len)) == NULL) + goto oom; CHECK_STRLCPY(filt, "(&", filt_len); CHECK_STRLCAT(filt, ldap_conf.netgroup_search_filter, filt_len); CHECK_STRLCAT(filt, "(|(nisNetgroupTriple=\\28,", filt_len); @@ -1426,18 +1463,18 @@ sudo_netgroup_lookup(LDAP *ld, struct passwd *pw, } CHECK_STRLCAT(filt, ",*\\29)))", filt_len); } + /* XXX - refactor duplicated code */ DPRINTF1("ldap netgroup search filter: '%s'", filt); result = NULL; rc = ldap_search_ext_s(ld, base->val, LDAP_SCOPE_SUBTREE, filt, NULL, 0, NULL, NULL, tvp, 0, &result); + free(filt); if (rc != LDAP_SUCCESS) { DPRINTF1("ldap netgroup search failed: %s", ldap_err2string(rc)); if (result) ldap_msgfree(result); - sudo_efree(filt); continue; } - sudo_efree(filt); old_tail = STAILQ_LAST(netgroups, ldap_netgroup, entries); LDAP_FOREACH(entry, ld, result) { @@ -1452,8 +1489,13 @@ sudo_netgroup_lookup(LDAP *ld, struct passwd *pw, break; } if (ng == NULL) { - ng = sudo_emalloc(sizeof(*ng)); - ng->name = sudo_estrdup((*bv)->bv_val); + ng = malloc(sizeof(*ng)); + if (ng == NULL || + (ng->name = strdup((*bv)->bv_val)) == NULL) { + free(ng); + ldap_value_free_len(bv); + goto oom; + } STAILQ_INSERT_TAIL(netgroups, ng, entries); DPRINTF1("Found new netgroup %s for %s", ng->name, base->val); @@ -1471,7 +1513,12 @@ sudo_netgroup_lookup(LDAP *ld, struct passwd *pw, } } debug_return_bool(true); +oom: + sudo_warnx(U_("unable to allocate memory")); + ldap_msgfree(result); + debug_return_bool(false); overflow: + free(filt); sudo_warnx(U_("internal error, %s overflow"), __func__); debug_return_bool(false); } @@ -1532,8 +1579,8 @@ sudo_ldap_build_pass1(LDAP *ld, struct passwd *pw) } else { /* sudo_netgroup_lookup() failed, clean up. */ STAILQ_FOREACH_SAFE(ng, &netgroups, entries, nextng) { - sudo_efree(ng->name); - sudo_efree(ng); + free(ng->name); + free(ng); } STAILQ_INIT(&netgroups); } @@ -1542,7 +1589,10 @@ sudo_ldap_build_pass1(LDAP *ld, struct passwd *pw) /* If timed, add space for time limits. */ if (ldap_conf.timed) sz += TIMEFILTER_LENGTH; - buf = sudo_emalloc(sz); + if ((buf = malloc(sz)) == NULL) { + sudo_warnx(U_("unable to allocate memory")); + debug_return_str(NULL); + } *buf = '\0'; /* @@ -1602,8 +1652,8 @@ sudo_ldap_build_pass1(LDAP *ld, struct passwd *pw) CHECK_STRLCAT(buf, "(sudoUser=+", sz); CHECK_LDAP_VCAT(buf, ng->name, sz); CHECK_STRLCAT(buf, ")", sz); - sudo_efree(ng->name); - sudo_efree(ng); + free(ng->name); + free(ng); } /* Add ALL to list and end the global OR. */ @@ -1612,7 +1662,10 @@ sudo_ldap_build_pass1(LDAP *ld, struct passwd *pw) /* Add the time restriction, or simply end the global OR. */ if (ldap_conf.timed) { CHECK_STRLCAT(buf, ")", sz); /* closes the global OR */ - sudo_ldap_timefilter(timebuffer, sizeof(timebuffer)); + if (!sudo_ldap_timefilter(timebuffer, sizeof(timebuffer))) { + free(buf); + debug_return_str(NULL); + } CHECK_STRLCAT(buf, timebuffer, sz); } else if (ldap_conf.search_filter) { CHECK_STRLCAT(buf, ")", sz); /* closes the global OR */ @@ -1621,6 +1674,7 @@ sudo_ldap_build_pass1(LDAP *ld, struct passwd *pw) debug_return_str(buf); overflow: + free(buf); sudo_warnx(U_("internal error, %s overflow"), __func__); debug_return_str(NULL); } @@ -1632,7 +1686,7 @@ overflow: static char * sudo_ldap_build_pass2(void) { - char *filt, timebuffer[TIMEFILTER_LENGTH + 1]; + char *filt = NULL, timebuffer[TIMEFILTER_LENGTH + 1]; bool query_netgroups = def_use_netgroups; debug_decl(sudo_ldap_build_pass2, SUDOERS_DEBUG_LDAP) @@ -1641,11 +1695,15 @@ sudo_ldap_build_pass2(void) query_netgroups = false; /* Short circuit if no netgroups and no non-Unix groups. */ - if (!query_netgroups && !def_group_plugin) + if (!query_netgroups && !def_group_plugin) { + errno = ENOENT; debug_return_str(NULL); + } - if (ldap_conf.timed) - sudo_ldap_timefilter(timebuffer, sizeof(timebuffer)); + if (ldap_conf.timed) { + if (!sudo_ldap_timefilter(timebuffer, sizeof(timebuffer))) + debug_return_str(NULL); + } /* * Match all sudoUsers beginning with '+' or '%:'. @@ -1653,19 +1711,21 @@ sudo_ldap_build_pass2(void) * those get ANDed in to the expression. */ if (query_netgroups && def_group_plugin) { - sudo_easprintf(&filt, "%s%s(|(sudoUser=+*)(sudoUser=%%:*))%s%s", + (void)asprintf(&filt, "%s%s(|(sudoUser=+*)(sudoUser=%%:*))%s%s", (ldap_conf.timed || ldap_conf.search_filter) ? "(&" : "", ldap_conf.search_filter ? ldap_conf.search_filter : "", ldap_conf.timed ? timebuffer : "", (ldap_conf.timed || ldap_conf.search_filter) ? ")" : ""); } else { - sudo_easprintf(&filt, "%s%s(sudoUser=*)(sudoUser=%s*)%s%s", + (void)asprintf(&filt, "%s%s(sudoUser=*)(sudoUser=%s*)%s%s", (ldap_conf.timed || ldap_conf.search_filter) ? "(&" : "", ldap_conf.search_filter ? ldap_conf.search_filter : "", query_netgroups ? "+" : "%:", ldap_conf.timed ? timebuffer : "", (ldap_conf.timed || ldap_conf.search_filter) ? ")" : ""); } + if (filt == NULL) + sudo_warnx(U_("unable to allocate memory")); debug_return_str(filt); } @@ -1687,13 +1747,17 @@ sudo_ldap_decode_secret(const char *secret) */ secret += sizeof("base64:") - 1; reslen = ((strlen(secret) + 3) / 4 * 3); - result = sudo_emalloc(reslen + 1); - len = base64_decode(secret, result, reslen); - if (len == (size_t)-1) { - free(result); - result = NULL; + result = malloc(reslen + 1); + if (result == NULL) { + sudo_warnx(U_("unable to allocate memory")); } else { - result[len] = '\0'; + len = base64_decode(secret, result, reslen); + if (len == (size_t)-1) { + free(result); + result = NULL; + } else { + result[len] = '\0'; + } } } debug_return_str((char *)result); @@ -1706,15 +1770,18 @@ sudo_ldap_read_secret(const char *path) char buf[LINE_MAX]; debug_decl(sudo_ldap_read_secret, SUDOERS_DEBUG_LDAP) + /* XXX - getline */ if ((fp = fopen(path_ldap_secret, "r")) != NULL) { if (fgets(buf, sizeof(buf), fp) != NULL) { buf[strcspn(buf, "\n")] = '\0'; /* copy to bindpw and binddn */ - sudo_efree(ldap_conf.bindpw); + free(ldap_conf.bindpw); ldap_conf.bindpw = sudo_ldap_decode_secret(buf); - if (ldap_conf.bindpw == NULL) - ldap_conf.bindpw = sudo_estrdup(buf); - sudo_efree(ldap_conf.binddn); + if (ldap_conf.bindpw == NULL) { + if ((ldap_conf.bindpw = strdup(buf)) == NULL) + sudo_warnx(U_("unable to allocate memory")); + } + free(ldap_conf.binddn); ldap_conf.binddn = ldap_conf.rootbinddn; ldap_conf.rootbinddn = NULL; } @@ -1760,9 +1827,17 @@ sudo_ldap_parse_keyword(const char *keyword, const char *value, } break; case CONF_STR: - sudo_efree(*(char **)(cur->valp)); - *(char **)(cur->valp) = *value ? sudo_estrdup(value) : NULL; - break; + { + char *cp = NULL; + + free(*(char **)(cur->valp)); + if (*value && (cp = strdup(value)) == NULL) { + sudo_warnx(U_("unable to allocate memory")); + debug_return_bool(false); + } + *(char **)(cur->valp) = cp; + break; + } case CONF_LIST_STR: { struct ldap_config_str_list *head; @@ -1771,7 +1846,10 @@ sudo_ldap_parse_keyword(const char *keyword, const char *value, if (len > 0) { head = (struct ldap_config_str_list *)cur->valp; - str = sudo_emalloc(sizeof(*str) + len); + if ((str = malloc(sizeof(*str) + len)) == NULL) { + sudo_warnx(U_("unable to allocate memory")); + debug_return_bool(false); + } memcpy(str->val, value, len + 1); STAILQ_INSERT_TAIL(head, str, entries); } @@ -1858,12 +1936,17 @@ sudo_ldap_read_config(void) ldap_conf.use_sasl = -1; ldap_conf.rootuse_sasl = -1; ldap_conf.deref = -1; - ldap_conf.search_filter = sudo_estrdup(DEFAULT_SEARCH_FILTER); - ldap_conf.netgroup_search_filter = sudo_estrdup(DEFAULT_NETGROUP_SEARCH_FILTER); + ldap_conf.search_filter = strdup(DEFAULT_SEARCH_FILTER); + ldap_conf.netgroup_search_filter = strdup(DEFAULT_NETGROUP_SEARCH_FILTER); STAILQ_INIT(&ldap_conf.uri); STAILQ_INIT(&ldap_conf.base); STAILQ_INIT(&ldap_conf.netgroup_base); + if (ldap_conf.search_filter == NULL || ldap_conf.netgroup_search_filter == NULL) { + sudo_warnx(U_("unable to allocate memory")); + debug_return_bool(false); + } + if ((fp = fopen(path_ldap_conf, "r")) == NULL) debug_return_bool(false); @@ -1890,8 +1973,13 @@ sudo_ldap_read_config(void) free(line); fclose(fp); - if (!ldap_conf.host) - ldap_conf.host = sudo_estrdup("localhost"); + if (!ldap_conf.host) { + ldap_conf.host = strdup("localhost"); + if (ldap_conf.host == NULL) { + sudo_warnx(U_("unable to allocate memory")); + debug_return_bool(false); + } + } DPRINTF1("LDAP Config Summary"); DPRINTF1("==================="); @@ -2011,7 +2099,7 @@ sudo_ldap_read_config(void) debug_return_bool(false); while ((uri = STAILQ_FIRST(&ldap_conf.uri)) != NULL) { STAILQ_REMOVE_HEAD(&ldap_conf.uri, entries); - sudo_efree(uri); + free(uri); } ldap_conf.port = LDAP_PORT; } @@ -2039,12 +2127,16 @@ sudo_ldap_read_config(void) if (ldap_conf.search_filter && ldap_conf.search_filter[0] != '(') { size_t len = strlen(ldap_conf.search_filter); cp = ldap_conf.search_filter; - ldap_conf.search_filter = sudo_emalloc(len + 3); + ldap_conf.search_filter = malloc(len + 3); + if (ldap_conf.search_filter == NULL) { + sudo_warnx(U_("unable to allocate memory")); + debug_return_bool(false); + } ldap_conf.search_filter[0] = '('; memcpy(ldap_conf.search_filter + 1, cp, len); ldap_conf.search_filter[len + 1] = ')'; ldap_conf.search_filter[len + 2] = '\0'; - sudo_efree(cp); + free(cp); } @@ -2054,7 +2146,7 @@ sudo_ldap_read_config(void) } else if (ldap_conf.bindpw) { cp = sudo_ldap_decode_secret(ldap_conf.bindpw); if (cp != NULL) { - sudo_efree(ldap_conf.bindpw); + free(ldap_conf.bindpw); ldap_conf.bindpw = cp; } } @@ -2062,7 +2154,7 @@ sudo_ldap_read_config(void) if (ldap_conf.tls_keypw) { cp = sudo_ldap_decode_secret(ldap_conf.tls_keypw); if (cp != NULL) { - sudo_efree(ldap_conf.tls_keypw); + free(ldap_conf.tls_keypw); ldap_conf.tls_keypw = cp; } } @@ -2133,6 +2225,10 @@ sudo_ldap_display_defaults(struct sudo_nss *nss, struct passwd *pw, ld = handle->ld; filt = sudo_ldap_build_default_filter(); + if (filt == NULL) { + sudo_warnx(U_("unable to allocate memory")); + goto done; + } STAILQ_FOREACH(base, &ldap_conf.base, entries) { if (ldap_conf.timeout > 0) { tv.tv_sec = ldap_conf.timeout; @@ -2160,7 +2256,7 @@ sudo_ldap_display_defaults(struct sudo_nss *nss, struct passwd *pw, if (result) ldap_msgfree(result); } - sudo_efree(filt); + free(filt); done: debug_return_int(count); } @@ -2350,6 +2446,8 @@ sudo_ldap_display_privs(struct sudo_nss *nss, struct passwd *pw, DPRINTF1("ldap search for command list"); lres = sudo_ldap_result_get(nss, pw); + if (lres == NULL) + goto done; /* Display all matching entries. */ for (i = 0; i < lres->nentries; i++) { @@ -2385,6 +2483,8 @@ sudo_ldap_display_cmnd(struct sudo_nss *nss, struct passwd *pw) */ DPRINTF1("ldap search for command list"); lres = sudo_ldap_result_get(nss, pw); + if (lres == NULL) + goto done; for (i = 0; i < lres->nentries; i++) { entry = lres->entries[i].entry; if (sudo_ldap_check_command(ld, entry, NULL) && @@ -2686,7 +2786,7 @@ sudo_ldap_result_alloc(void) struct ldap_result *result; debug_decl(sudo_ldap_result_alloc, SUDOERS_DEBUG_LDAP) - result = sudo_ecalloc(1, sizeof(*result)); + result = calloc(1, sizeof(*result)); STAILQ_INIT(&result->searches); debug_return_ptr(result); @@ -2703,15 +2803,15 @@ sudo_ldap_result_free(struct ldap_result *lres) if (lres != NULL) { if (lres->nentries) { - sudo_efree(lres->entries); + free(lres->entries); lres->entries = NULL; } while ((s = STAILQ_FIRST(&lres->searches)) != NULL) { STAILQ_REMOVE_HEAD(&lres->searches, entries); ldap_msgfree(s->searchresult); - sudo_efree(s); + free(s); } - sudo_efree(lres); + free(lres); } debug_return; } @@ -2727,10 +2827,12 @@ sudo_ldap_result_add_search(struct ldap_result *lres, LDAP *ldap, debug_decl(sudo_ldap_result_add_search, SUDOERS_DEBUG_LDAP) /* Create new entry and add it to the end of the chain. */ - news = sudo_ecalloc(1, sizeof(*news)); - news->ldap = ldap; - news->searchresult = searchresult; - STAILQ_INSERT_TAIL(&lres->searches, news, entries); + news = calloc(1, sizeof(*news)); + if (news != NULL) { + news->ldap = ldap; + news->searchresult = searchresult; + STAILQ_INSERT_TAIL(&lres->searches, news, entries); + } debug_return_ptr(news); } @@ -2868,7 +2970,7 @@ sudo_ldap_open(struct sudo_nss *nss) goto done; DPRINTF2("ldap_initialize(ld, %s)", buf); rc = ldap_initialize(&ld, buf); - sudo_efree(buf); + free(buf); } else #endif rc = sudo_ldap_init(&ld, ldap_conf.host, ldap_conf.port); @@ -2919,7 +3021,12 @@ sudo_ldap_open(struct sudo_nss *nss) goto done; /* Create a handle container. */ - handle = sudo_ecalloc(1, sizeof(struct sudo_ldap_handle)); + handle = calloc(1, sizeof(struct sudo_ldap_handle)); + if (handle == NULL) { + sudo_warnx(U_("unable to allocate memory")); + rc = -1; + goto done; + } handle->ld = ld; /* handle->result = NULL; */ /* handle->username = NULL; */ @@ -2938,7 +3045,7 @@ sudo_ldap_setdefs(struct sudo_nss *nss) struct sudo_ldap_handle *handle = nss->handle; struct timeval tv, *tvp = NULL; LDAP *ld; - LDAPMessage *entry, *result; + LDAPMessage *entry, *result = NULL; char *filt; int rc; debug_decl(sudo_ldap_setdefs, SUDOERS_DEBUG_LDAP) @@ -2948,6 +3055,10 @@ sudo_ldap_setdefs(struct sudo_nss *nss) ld = handle->ld; filt = sudo_ldap_build_default_filter(); + if (filt == NULL) { + sudo_warnx(U_("unable to allocate memory")); + debug_return_int(-1); + } DPRINTF1("Looking for cn=defaults: %s", filt); STAILQ_FOREACH(base, &ldap_conf.base, entries) { @@ -2956,21 +3067,30 @@ sudo_ldap_setdefs(struct sudo_nss *nss) tv.tv_usec = 0; tvp = &tv; } - result = NULL; + if (result != NULL) { + ldap_msgfree(result); + result = NULL; + } rc = ldap_search_ext_s(ld, base->val, LDAP_SCOPE_SUBTREE, filt, NULL, 0, NULL, NULL, tvp, 0, &result); if (rc == LDAP_SUCCESS && (entry = ldap_first_entry(ld, result))) { DPRINTF1("found:%s", ldap_get_dn(ld, entry)); - sudo_ldap_parse_options(ld, entry); + if (!sudo_ldap_parse_options(ld, entry)) { + rc = -1; + goto done; + } } else { DPRINTF1("no default options found in %s", base->val); } - if (result) - ldap_msgfree(result); } - sudo_efree(filt); + rc = 0; - debug_return_int(0); +done: + if (result != NULL) + ldap_msgfree(result); + free(filt); + + debug_return_int(rc); } /* @@ -2992,6 +3112,8 @@ sudo_ldap_lookup(struct sudo_nss *nss, int ret, int pwflag) /* Fetch list of sudoRole entries that match user and host. */ lres = sudo_ldap_result_get(nss, sudo_user.pw); + if (lres == NULL) + debug_return_int(ret); /* * The following queries are only determine whether or not a @@ -3058,16 +3180,19 @@ sudo_ldap_lookup(struct sudo_nss *nss, int ret, int pwflag) /* Apply entry-specific options. */ if (setenv_implied) def_setenv = true; - sudo_ldap_parse_options(ld, entry); + if (sudo_ldap_parse_options(ld, entry)) { #ifdef HAVE_SELINUX - /* Set role and type if not specified on command line. */ - if (user_role == NULL) - user_role = def_role; - if (user_type == NULL) - user_type = def_type; + /* Set role and type if not specified on command line. */ + if (user_role == NULL) + user_role = def_role; + if (user_type == NULL) + user_type = def_type; #endif /* HAVE_SELINUX */ - SET(ret, VALIDATE_SUCCESS); - CLR(ret, VALIDATE_FAILURE); + SET(ret, VALIDATE_SUCCESS); + CLR(ret, VALIDATE_FAILURE); + } else { + SET(ret, VALIDATE_ERROR); + } } else { SET(ret, VALIDATE_FAILURE); CLR(ret, VALIDATE_SUCCESS); @@ -3155,9 +3280,13 @@ sudo_ldap_result_add_entry(struct ldap_result *lres, LDAPMessage *entry) * of 100 entries to save on allocation time. */ if (++lres->nentries > lres->allocated_entries) { - lres->allocated_entries += ALLOCATION_INCREMENT; - lres->entries = sudo_ereallocarray(lres->entries, lres->allocated_entries, - sizeof(lres->entries[0])); + int allocated_entries = lres->allocated_entries + ALLOCATION_INCREMENT; + struct ldap_entry_wrapper *entries = reallocarray(lres->entries, + allocated_entries, sizeof(lres->entries[0])); + if (entries == NULL) + debug_return_ptr(NULL); + lres->allocated_entries = allocated_entries; + lres->entries = entries; } /* Fill in the new entry and return it. */ @@ -3179,10 +3308,7 @@ sudo_ldap_result_free_nss(struct sudo_nss *nss) if (handle->result != NULL) { DPRINTF1("removing reusable search result"); sudo_ldap_result_free(handle->result); - if (handle->username) { - sudo_efree(handle->username); - handle->username = NULL; - } + handle->username = NULL; handle->grlist = NULL; handle->result = NULL; } @@ -3242,6 +3368,10 @@ sudo_ldap_result_get(struct sudo_nss *nss, struct passwd *pw) * an ldap_result object. The results are then sorted by sudoOrder. */ lres = sudo_ldap_result_alloc(); + if (lres == NULL) { + sudo_warnx(U_("unable to allocate memory")); + debug_return_ptr(NULL); + } for (pass = 0; pass < 2; pass++) { filt = pass ? sudo_ldap_build_pass2() : sudo_ldap_build_pass1(ld, pw); if (filt != NULL) { @@ -3266,18 +3396,32 @@ sudo_ldap_result_get(struct sudo_nss *nss, struct passwd *pw) /* Add the seach result to list of search results. */ DPRINTF1("adding search result"); - sudo_ldap_result_add_search(lres, ld, result); + if (sudo_ldap_result_add_search(lres, ld, result) == NULL) { + sudo_warnx(U_("unable to allocate memory")); + free(filt); + sudo_ldap_result_free(lres); + debug_return_ptr(NULL); + } LDAP_FOREACH(entry, ld, result) { if ((!pass || sudo_ldap_check_non_unix_group(ld, entry, pw)) && sudo_ldap_check_host(ld, entry)) { lres->host_matches = true; - sudo_ldap_result_add_entry(lres, entry); + if (sudo_ldap_result_add_entry(lres, entry) == NULL) { + sudo_warnx(U_("unable to allocate memory")); + free(filt); + sudo_ldap_result_free(lres); + debug_return_ptr(NULL); + } } } DPRINTF1("result now has %d entries", lres->nentries); } - sudo_efree(filt); + free(filt); + } else if (errno != ENOENT) { + /* Out of memory? */ + sudo_ldap_result_free(lres); + debug_return_ptr(NULL); } } @@ -3287,8 +3431,9 @@ sudo_ldap_result_get(struct sudo_nss *nss, struct passwd *pw) ldap_entry_compare); /* Store everything in the sudo_nss handle. */ + /* XXX - store pw and take a reference to it. */ handle->result = lres; - handle->username = sudo_estrdup(pw->pw_name); + handle->username = pw->pw_name; handle->grlist = user_group_list; debug_return_ptr(lres); @@ -3314,7 +3459,7 @@ sudo_ldap_close(struct sudo_nss *nss) } /* Free the handle container. */ - sudo_efree(nss->handle); + free(nss->handle); nss->handle = NULL; } debug_return_int(0); @@ -3339,30 +3484,42 @@ sudo_ldap_parse(struct sudo_nss *nss) static struct ldap_result * sudo_ldap_result_from_search(LDAP *ldap, LDAPMessage *searchresult) { + struct ldap_search_result *last; + struct ldap_result *result; + LDAPMessage *entry; + /* * An ldap_result is built from several search results, which are * organized in a list. The head of the list is maintained in the * ldap_result structure, together with the wrappers that point * to individual entries, this has to be initialized first. */ - struct ldap_result *result = sudo_ldap_result_alloc(); + result = sudo_ldap_result_alloc(); + if (result == NULL) { + sudo_warnx(U_("unable to allocate memory")); + debug_return_ptr(NULL); + } /* * Build a new list node for the search result, this creates the * list node. */ - struct ldap_search_result *last = sudo_ldap_result_add_search(result, - ldap, searchresult); + last = sudo_ldap_result_add_search(result, ldap, searchresult); /* * Now add each entry in the search result to the array of of entries * in the ldap_result object. */ - LDAPMessage *entry; LDAP_FOREACH(entry, last->ldap, last->searchresult) { - sudo_ldap_result_add_entry(result, entry); + if (sudo_ldap_result_add_entry(result, entry) == NULL) { + sudo_warnx(U_("unable to allocate memory")); + sudo_ldap_result_free(result); + result = NULL; + break; + } } - DPRINTF1("sudo_ldap_result_from_search: %d entries found", result->nentries); + DPRINTF1("sudo_ldap_result_from_search: %d entries found", + result ? result->nentries : -1); return result; } #endif