static int sudo_sss_open(struct sudo_nss *nss);
static int sudo_sss_close(struct sudo_nss *nss);
static int sudo_sss_parse(struct sudo_nss *nss);
-static void sudo_sss_parse_options(struct sudo_sss_handle *handle,
+static bool sudo_sss_parse_options(struct sudo_sss_handle *handle,
struct sss_sudo_rule *rule);
static int sudo_sss_setdefs(struct sudo_nss *nss);
static int sudo_sss_lookup(struct sudo_nss *nss, int ret, int pwflag);
uint32_t *state);
static void
+sudo_sss_attrfree(struct sss_sudo_attr *attr)
+{
+ unsigned int i;
+ debug_decl(sudo_sss_attrfree, SUDOERS_DEBUG_SSSD)
+
+ free(attr->name);
+ attr->name = NULL;
+ if (attr->values != NULL) {
+ for (i = 0; i < attr->num_values; ++i)
+ free(attr->values[i]);
+ free(attr->values);
+ attr->values = NULL;
+ }
+ attr->num_values = 0;
+
+ debug_return;
+}
+
+static bool
sudo_sss_attrcpy(struct sss_sudo_attr *dst, const struct sss_sudo_attr *src)
{
- unsigned int i;
- debug_decl(sudo_sss_attrcpy, SUDOERS_DEBUG_SSSD)
+ unsigned int i = 0;
+ debug_decl(sudo_sss_attrcpy, SUDOERS_DEBUG_SSSD)
+
+ sudo_debug_printf(SUDO_DEBUG_DEBUG, "dst=%p, src=%p", dst, src);
+ sudo_debug_printf(SUDO_DEBUG_INFO, "malloc: cnt=%d", src->num_values);
+
+ dst->name = strdup(src->name);
+ dst->values = reallocarray(NULL, dst->num_values, sizeof(char *));
+ if (dst->name == NULL || dst->values == NULL)
+ goto oom;
+ dst->num_values = src->num_values;
+
+ for (i = 0; i < dst->num_values; ++i) {
+ dst->values[i] = strdup(src->values[i]);
+ if (dst->values[i] == NULL) {
+ dst->num_values = i;
+ goto oom;
+ }
+ }
- sudo_debug_printf(SUDO_DEBUG_DEBUG, "dst=%p, src=%p", dst, src);
- sudo_debug_printf(SUDO_DEBUG_INFO, "sudo_emalloc: cnt=%d", src->num_values);
+ debug_return_bool(true);
+oom:
+ sudo_warnx(U_("unable to allocate memory"));
+ sudo_sss_attrfree(dst);
+ debug_return_bool(false);
+}
- dst->name = sudo_estrdup(src->name);
- dst->num_values = src->num_values;
- dst->values = sudo_emallocarray(dst->num_values, sizeof(char *));
+static void
+sudo_sss_rulefree(struct sss_sudo_rule *rule)
+{
+ unsigned int i;
+ debug_decl(sudo_sss_rulefree, SUDOERS_DEBUG_SSSD)
- for (i = 0; i < dst->num_values; ++i)
- dst->values[i] = sudo_estrdup(src->values[i]);
+ for (i = 0; i < rule->num_attrs; ++i)
+ sudo_sss_attrfree(rule->attrs + i);
+ free(rule->attrs);
+ rule->attrs = NULL;
+ rule->num_attrs = 0;
- debug_return;
+ debug_return;
}
-static void
+static bool
sudo_sss_rulecpy(struct sss_sudo_rule *dst, const struct sss_sudo_rule *src)
{
- unsigned int i;
- debug_decl(sudo_sss_rulecpy, SUDOERS_DEBUG_SSSD)
+ unsigned int i;
+ debug_decl(sudo_sss_rulecpy, SUDOERS_DEBUG_SSSD)
- sudo_debug_printf(SUDO_DEBUG_DEBUG, "dst=%p, src=%p", dst, src);
- sudo_debug_printf(SUDO_DEBUG_INFO, "sudo_emalloc: cnt=%d", src->num_attrs);
+ sudo_debug_printf(SUDO_DEBUG_DEBUG, "dst=%p, src=%p", dst, src);
+ sudo_debug_printf(SUDO_DEBUG_INFO, "malloc: cnt=%d", src->num_attrs);
- dst->num_attrs = src->num_attrs;
- dst->attrs = sudo_emallocarray(dst->num_attrs, sizeof(struct sss_sudo_attr));
+ dst->num_attrs = 0;
+ dst->attrs = reallocarray(NULL, src->num_attrs, sizeof(struct sss_sudo_attr));
+ if (dst->attrs == NULL) {
+ sudo_warnx(U_("unable to allocate memory"));
+ debug_return_bool(false);
+ }
- for (i = 0; i < dst->num_attrs; ++i)
- sudo_sss_attrcpy(dst->attrs + i, src->attrs + i);
+ for (i = 0; i < src->num_attrs; ++i) {
+ if (!sudo_sss_attrcpy(dst->attrs + i, src->attrs + i)) {
+ sudo_warnx(U_("unable to allocate memory"));
+ dst->num_attrs = i;
+ sudo_sss_rulefree(dst);
+ debug_return_bool(false);
+ }
+ }
+ dst->num_attrs = i;
- debug_return;
+ debug_return_bool(true);
}
#define SUDO_SSS_FILTER_INCLUDE 0
if (in_res == NULL)
debug_return_ptr(NULL);
- sudo_debug_printf(SUDO_DEBUG_DEBUG, "sudo_emalloc: cnt=%d", in_res->num_rules);
+ sudo_debug_printf(SUDO_DEBUG_DEBUG, "malloc: cnt=%d", in_res->num_rules);
- out_res = sudo_emalloc(sizeof(struct sss_sudo_result));
- out_res->rules = in_res->num_rules > 0 ?
- sudo_emallocarray(in_res->num_rules, sizeof(struct sss_sudo_rule)) : NULL;
- out_res->num_rules = 0;
+ if ((out_res = calloc(1, sizeof(struct sss_sudo_result))) == NULL) {
+ sudo_warnx(U_("unable to allocate memory"));
+ debug_return_ptr(NULL);
+ }
+ if (in_res->num_rules > 0) {
+ out_res->rules =
+ reallocarray(NULL, in_res->num_rules, sizeof(struct sss_sudo_rule));
+ if (out_res->rules == NULL) {
+ sudo_warnx(U_("unable to allocate memory"));
+ free(out_res);
+ debug_return_ptr(NULL);
+ }
+ }
for (i = l = 0; i < in_res->num_rules; ++i) {
r = filterp(handle, in_res->rules + i, filterp_arg);
act == SUDO_SSS_FILTER_EXCLUDE ? "not excluded" : "included",
in_res->rules, i, out_res->rules, l, in_res->rules + i);
- sudo_sss_rulecpy(out_res->rules + l, in_res->rules + i);
+ if (!sudo_sss_rulecpy(out_res->rules + l, in_res->rules + i)) {
+ while (l--) {
+ sudo_sss_rulefree(out_res->rules + l);
+ }
+ free(out_res->rules);
+ free(out_res);
+ debug_return_ptr(NULL);
+ }
++l;
}
}
"reallocating result: %p (count: %u -> %u)", out_res->rules,
in_res->num_rules, l);
if (l > 0) {
- out_res->rules =
- sudo_ereallocarray(out_res->rules, l, sizeof(struct sss_sudo_rule));
+ struct sss_sudo_rule *rules =
+ reallocarray(out_res->rules, l, sizeof(struct sss_sudo_rule));
+ if (out_res->rules == NULL) {
+ sudo_warnx(U_("unable to allocate memory"));
+ while (l--) {
+ sudo_sss_rulefree(out_res->rules + l);
+ }
+ free(out_res->rules);
+ free(out_res);
+ debug_return_ptr(NULL);
+ }
+ out_res->rules = rules;
} else {
- sudo_efree(out_res->rules);
+ free(out_res->rules);
out_res->rules = NULL;
}
}
/* sudo_nss implementation */
// ok
-static int sudo_sss_open(struct sudo_nss *nss)
+static int
+sudo_sss_open(struct sudo_nss *nss)
{
struct sudo_sss_handle *handle;
static const char path[] = _PATH_SSSD_LIB"/libsss_sudo.so";
debug_decl(sudo_sss_open, SUDOERS_DEBUG_SSSD);
/* Create a handle container. */
- handle = sudo_emalloc(sizeof(struct sudo_sss_handle));
+ handle = malloc(sizeof(struct sudo_sss_handle));
+ if (handle == NULL) {
+ sudo_warnx(U_("unable to allocate memory"));
+ debug_return_int(ENOMEM);
+ }
/* Load symbols */
handle->ssslib = sudo_dso_load(path, SUDO_DSO_LAZY);
if (handle->ssslib == NULL) {
sudo_warnx(U_("unable to load %s: %s"), path, sudo_dso_strerror());
sudo_warnx(U_("unable to initialize SSS source. Is SSSD installed on your machine?"));
+ free(handle);
debug_return_int(EFAULT);
}
if (handle->fn_send_recv == NULL) {
sudo_warnx(U_("unable to find symbol \"%s\" in %s"), path,
"sss_sudo_send_recv");
+ free(handle);
debug_return_int(EFAULT);
}
if (handle->fn_send_recv_defaults == NULL) {
sudo_warnx(U_("unable to find symbol \"%s\" in %s"), path,
"sss_sudo_send_recv_defaults");
+ free(handle);
debug_return_int(EFAULT);
}
if (handle->fn_free_result == NULL) {
sudo_warnx(U_("unable to find symbol \"%s\" in %s"), path,
"sss_sudo_free_result");
+ free(handle);
debug_return_int(EFAULT);
}
if (handle->fn_get_values == NULL) {
sudo_warnx(U_("unable to find symbol \"%s\" in %s"), path,
"sss_sudo_get_values");
+ free(handle);
debug_return_int(EFAULT);
}
if (handle->fn_free_values == NULL) {
sudo_warnx(U_("unable to find symbol \"%s\" in %s"), path,
"sss_sudo_free_values");
+ free(handle);
debug_return_int(EFAULT);
}
}
// ok
-static int sudo_sss_close(struct sudo_nss *nss)
+static int
+sudo_sss_close(struct sudo_nss *nss)
{
struct sudo_sss_handle *handle;
debug_decl(sudo_sss_close, SUDOERS_DEBUG_SSSD);
if (nss && nss->handle) {
handle = nss->handle;
sudo_dso_unload(handle->ssslib);
- sudo_efree(nss->handle);
+ free(nss->handle);
}
debug_return_int(0);
}
// ok
-static int sudo_sss_parse(struct sudo_nss *nss)
+static int
+sudo_sss_parse(struct sudo_nss *nss)
{
debug_decl(sudo_sss_parse, SUDOERS_DEBUG_SSSD);
debug_return_int(0);
}
-static int sudo_sss_setdefs(struct sudo_nss *nss)
+static int
+sudo_sss_setdefs(struct sudo_nss *nss)
{
struct sudo_sss_handle *handle = nss->handle;
-
struct sss_sudo_result *sss_result;
struct sss_sudo_rule *sss_rule;
uint32_t sss_error;
"handle->fn_send_recv_defaults: != 0, sss_error=%u", sss_error);
debug_return_int(-1);
}
-
- if (sss_error == ENOENT) {
- sudo_debug_printf(SUDO_DEBUG_INFO, "The user was not found in SSSD.");
- debug_return_int(0);
- } else if(sss_error != 0) {
+ if (sss_error != 0) {
+ if (sss_error == ENOENT) {
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "The user was not found in SSSD.");
+ goto done;
+ }
sudo_debug_printf(SUDO_DEBUG_INFO, "sss_error=%u\n", sss_error);
- debug_return_int(-1);
+ goto bad;
}
for (i = 0; i < sss_result->num_rules; ++i) {
sudo_debug_printf(SUDO_DEBUG_DIAG,
"Parsing cn=defaults, %d/%d", i, sss_result->num_rules);
sss_rule = sss_result->rules + i;
- sudo_sss_parse_options(handle, sss_rule);
+ if (!sudo_sss_parse_options(handle, sss_rule))
+ goto bad;
}
+done:
handle->fn_free_result(sss_result);
debug_return_int(0);
+bad:
+ handle->fn_free_result(sss_result);
+ debug_return_int(-1);
}
-static int sudo_sss_checkpw(struct sudo_nss *nss, struct passwd *pw)
+static int
+sudo_sss_checkpw(struct sudo_nss *nss, struct passwd *pw)
{
struct sudo_sss_handle *handle = nss->handle;
debug_decl(sudo_sss_checkpw, SUDOERS_DEBUG_SSSD);
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++;
/* 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 */
*/
ret = foundbang ? false : true;
}
+ if (allowed_args != NULL)
+ allowed_args[-1] = ' '; /* restore val */
sudo_debug_printf(SUDO_DEBUG_INFO, "sssd/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);
}
handle->fn_free_values(val_array); /* more cleanup */
debug_return_int(ret);
}
-static void
+static bool
sudo_sss_parse_options(struct sudo_sss_handle *handle, struct sss_sudo_rule *rule)
{
int i;
+ bool ret = false;
char op, *v, *val;
char **val_array = NULL;
debug_decl(sudo_sss_parse_options, SUDOERS_DEBUG_SSSD);
if (rule == NULL)
- debug_return;
+ debug_return_bool(true);
switch (handle->fn_get_values(rule, "sudoOption", &val_array)) {
case 0:
break;
case ENOENT:
sudo_debug_printf(SUDO_DEBUG_INFO, "No result.");
- debug_return;
+ debug_return_bool(true);
default:
sudo_debug_printf(SUDO_DEBUG_INFO, "handle->fn_get_values(sudoOption): != 0");
- debug_return;
+ debug_return_bool(false);
}
/* walk through options */
for (i = 0; val_array[i] != NULL; i++) {
sudo_debug_printf(SUDO_DEBUG_INFO, "sssd/ldap sudoOption: '%s'",
val_array[i]);
- v = sudo_estrdup(val_array[i]);
+ if ((v = strdup(val_array[i])) == NULL) {
+ sudo_warnx(U_("unable to allocate memory"));
+ goto done;
+ }
/* check for equals sign past first char */
val = strchr(v, '=');
/* case var Boolean True */
set_default(v, NULL, true);
}
- sudo_efree(v);
+ free(v);
}
+ ret = true;
+done:
handle->fn_free_values(val_array);
- debug_return;
+ debug_return_bool(ret);
}
static int
/* Apply entry-specific options. */
if (setenv_implied)
def_setenv = true;
- sudo_sss_parse_options(handle, rule);
+ if (sudo_sss_parse_options(handle, rule)) {
#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/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);