# include <stdlib.h>
# endif
#endif /* STDC_HEADERS */
+#include <errno.h>
#include <usersec.h>
#include <uinfo.h>
* Look up administrative domain for user (SYSTEM in /etc/security/user) and
* set it as the default for the process. This ensures that password and
* group lookups are made against the correct source (files, NIS, LDAP, etc).
+ * Does not modify errno even on error since callers do not check rval.
*/
int
aix_setauthdb_v1(char *user)
{
char *registry;
+ int serrno = errno;
+ int rval = -1;
debug_decl(aix_setauthdb, SUDO_DEBUG_UTIL)
if (user != NULL) {
if (setuserdb(S_READ) != 0) {
sudo_warn(U_("unable to open userdb"));
- debug_return_int(-1);
+ goto done;
}
if (getuserattr(user, S_REGISTRY, ®istry, SEC_CHAR) == 0) {
if (setauthdb(registry, NULL) != 0) {
sudo_warn(U_("unable to switch to registry \"%s\" for %s"),
registry, user);
- debug_return_int(-1);
+ goto done;
}
}
enduserdb();
}
- debug_return_int(0);
+ rval = 0;
+done:
+ errno = serrno;
+ debug_return_int(rval);
}
/*
* Restore the saved administrative domain, if any.
+ * Does not modify errno even on error since callers do not check rval.
*/
int
aix_restoreauthdb_v1(void)
{
+ int serrno = errno;
+ int rval = 0;
debug_decl(aix_setauthdb, SUDO_DEBUG_UTIL)
if (setauthdb(NULL, NULL) != 0) {
sudo_warn(U_("unable to restore registry"));
- debug_return_int(-1);
+ rval = -1;
}
- debug_return_int(0);
+ errno = serrno;
+ debug_return_int(rval);
}
#endif
#ifdef HAVE_SETAUTHDB
# include <usersec.h>
#endif /* HAVE_SETAUTHDB */
+#include <errno.h>
#include <pwd.h>
#include <grp.h>
debug_decl(sudo_pw_delref_item, SUDOERS_DEBUG_NSS)
if (--item->refcnt == 0)
- sudo_efree(item);
+ free(item);
debug_return;
}
aix_setauthdb(IDtouser(uid));
#endif
item = sudo_make_pwitem(uid, NULL);
+#ifdef HAVE_SETAUTHDB
+ aix_restoreauthdb();
+#endif
if (item == NULL) {
- item = calloc(1, sizeof(*item));
- if (item == NULL) {
+ if (errno != ENOENT || (item = calloc(1, sizeof(*item))) == NULL) {
sudo_warnx(U_("unable to cache uid %u, out of memory"),
(unsigned int) uid);
debug_return_ptr(NULL);
item->refcnt = 0;
break;
}
-#ifdef HAVE_SETAUTHDB
- aix_restoreauthdb();
-#endif
done:
item->refcnt++;
debug_return_ptr(item->d.pw);
{
struct cache_item key, *item;
struct rbnode *node;
- size_t len;
debug_decl(sudo_getpwnam, SUDOERS_DEBUG_NSS)
key.k.name = (char *) name;
aix_setauthdb((char *) name);
#endif
item = sudo_make_pwitem((uid_t)-1, name);
+#ifdef HAVE_SETAUTHDB
+ aix_restoreauthdb();
+#endif
if (item == NULL) {
- len = strlen(name) + 1;
- item = calloc(1, sizeof(*item) + len);
- if (item == NULL) {
+ const size_t len = strlen(name) + 1;
+ if (errno != ENOENT || (item = calloc(1, sizeof(*item) + len)) == NULL) {
sudo_warnx(U_("unable to cache user %s, out of memory"), name);
debug_return_ptr(NULL);
}
item->refcnt = 0;
break;
}
-#ifdef HAVE_SETAUTHDB
- aix_restoreauthdb();
-#endif
done:
item->refcnt++;
debug_return_ptr(item->d.pw);
struct rbtree *pwcache;
struct rbnode *node;
- pwitem = sudo_ecalloc(1, len);
+ pwitem = calloc(1, len);
+ if (pwitem == NULL) {
+ sudo_warnx(U_("unable to cache user %s, out of memory"), user);
+ debug_return_ptr(NULL);
+ }
pw = &pwitem->pw;
pw->pw_uid = uid;
pw->pw_gid = gid;
item = node->data = &pwitem->cache;
} else {
/* Good entry, discard our fake one. */
- sudo_efree(pwitem);
+ free(pwitem);
}
break;
case -1:
debug_decl(sudo_gr_delref_item, SUDOERS_DEBUG_NSS)
if (--item->refcnt == 0)
- sudo_efree(item);
+ free(item);
debug_return;
}
*/
item = sudo_make_gritem(gid, NULL);
if (item == NULL) {
- item = sudo_ecalloc(1, sizeof(*item));
+ if (errno != ENOENT || (item = calloc(1, sizeof(*item))) == NULL) {
+ sudo_warnx(U_("unable to cache gid %u, out of memory"),
+ (unsigned int) gid);
+ debug_return_ptr(NULL);
+ }
item->refcnt = 1;
item->k.gid = gid;
/* item->d.gr = NULL; */
{
struct cache_item key, *item;
struct rbnode *node;
- size_t len;
debug_decl(sudo_getgrnam, SUDOERS_DEBUG_NSS)
key.k.name = (char *) name;
*/
item = sudo_make_gritem((gid_t)-1, name);
if (item == NULL) {
- len = strlen(name) + 1;
- item = sudo_ecalloc(1, sizeof(*item) + len);
+ const size_t len = strlen(name) + 1;
+ if (errno != ENOENT || (item = calloc(1, sizeof(*item) + len)) == NULL) {
+ sudo_warnx(U_("unable to cache group %s, out of memory"), name);
+ debug_return_ptr(NULL);
+ }
item->refcnt = 1;
item->k.name = (char *) item + sizeof(*item);
memcpy(item->k.name, name, len);
struct rbtree *grcache;
struct rbnode *node;
- gritem = sudo_ecalloc(1, len);
+ gritem = calloc(1, len);
+ if (gritem == NULL) {
+ sudo_warnx(U_("unable to cache group %s, out of memory"), group);
+ debug_return_ptr(NULL);
+ }
gr = &gritem->gr;
gr->gr_gid = (gid_t) sudo_strtoid(group + 1, NULL, NULL, &errstr);
gr->gr_name = (char *)(gritem + 1);
if (errstr != NULL) {
sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_DIAG,
"gid %s %s", group, errstr);
- sudo_efree(gritem);
+ free(gritem);
debug_return_ptr(NULL);
}
item = node->data = &gritem->cache;
} else {
/* Good entry, discard our fake one. */
- sudo_efree(gritem);
+ free(gritem);
}
break;
case -1:
debug_decl(sudo_gr_delref_item, SUDOERS_DEBUG_NSS)
if (--item->refcnt == 0)
- sudo_efree(item);
+ free(item);
debug_return;
}
{
struct cache_item key, *item;
struct rbnode *node;
- size_t len;
debug_decl(sudo_get_grlist, SUDOERS_DEBUG_NSS)
key.k.name = pw->pw_name;
*/
item = sudo_make_grlist_item(pw, NULL, NULL);
if (item == NULL) {
- /* Should not happen. */
- len = strlen(pw->pw_name) + 1;
- item = sudo_ecalloc(1, sizeof(*item) + len);
- item->refcnt = 1;
- item->k.name = (char *) item + sizeof(*item);
- memcpy(item->k.name, pw->pw_name, len);
- /* item->d.grlist = NULL; */
+ /* Out of memory? */
+ debug_return_ptr(NULL);
}
switch (rbinsert(grlist_cache, item, NULL)) {
case 1:
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif /* HAVE_UNISTD_H */
+#include <errno.h>
#include <limits.h>
#include <pwd.h>
#include <grp.h>
* Dynamically allocate space for a struct item plus the key and data
* elements. If name is non-NULL it is used as the key, else the
* uid is the key. Fills in datum from struct password.
+ * Returns NULL on malloc error or unknown name/id, setting errno
+ * to ENOMEM or ENOENT respectively.
*/
struct cache_item *
sudo_make_pwitem(uid_t uid, const char *name)
/* Look up by name or uid. */
pw = name ? getpwnam(name) : getpwuid(uid);
- if (pw == NULL)
+ if (pw == NULL) {
+ errno = ENOENT;
debug_return_ptr(NULL);
+ }
/* If shell field is empty, expand to _PATH_BSHELL. */
pw_shell = (pw->pw_shell == NULL || pw->pw_shell[0] == '\0')
total += strlen(name) + 1;
/* Allocate space for struct item, struct passwd and the strings. */
- pwitem = sudo_ecalloc(1, total);
+ if ((pwitem = calloc(1, total)) == NULL)
+ debug_return_ptr(NULL);
newpw = &pwitem->pw;
/*
* Dynamically allocate space for a struct item plus the key and data
* elements. If name is non-NULL it is used as the key, else the
* gid is the key. Fills in datum from struct group.
+ * Returns NULL on malloc error or unknown name/id, setting errno
+ * to ENOMEM or ENOENT respectively.
*/
struct cache_item *
sudo_make_gritem(gid_t gid, const char *name)
/* Look up by name or gid. */
gr = name ? getgrnam(name) : getgrgid(gid);
- if (gr == NULL)
+ if (gr == NULL) {
+ errno = ENOENT;
debug_return_ptr(NULL);
+ }
/* Allocate in one big chunk for easy freeing. */
nsize = psize = nmem = 0;
if (name != NULL)
total += strlen(name) + 1;
- gritem = sudo_ecalloc(1, total);
+ if ((gritem = calloc(1, total)) == NULL)
+ debug_return_ptr(NULL);
/*
* Copy in group contents and make strings relative to space
struct cache_item_grlist *grlitem;
struct group_list *grlist;
GETGROUPS_T *gids;
- struct group *grp;
+ struct group *grp = NULL;
int i, ngids, groupname_len;
debug_decl(sudo_make_grlist_item, SUDOERS_DEBUG_NSS)
} else {
if (sudo_user.max_groups > 0) {
ngids = sudo_user.max_groups;
- gids = sudo_emallocarray(ngids, sizeof(GETGROUPS_T));
+ gids = reallocarray(NULL, ngids, sizeof(GETGROUPS_T));
+ if (gids == NULL)
+ debug_return_ptr(NULL);
(void)getgrouplist(pw->pw_name, pw->pw_gid, gids, &ngids);
} else {
ngids = (int)sysconf(_SC_NGROUPS_MAX) * 2;
if (ngids < 0)
ngids = NGROUPS_MAX * 2;
- gids = sudo_emallocarray(ngids, sizeof(GETGROUPS_T));
+ gids = reallocarray(NULL, ngids, sizeof(GETGROUPS_T));
+ if (gids == NULL)
+ debug_return_ptr(NULL);
if (getgrouplist(pw->pw_name, pw->pw_gid, gids, &ngids) == -1) {
- sudo_efree(gids);
- gids = sudo_emallocarray(ngids, sizeof(GETGROUPS_T));
+ free(gids);
+ gids = reallocarray(NULL, ngids, sizeof(GETGROUPS_T));
+ if (gids == NULL)
+ debug_return_ptr(NULL);
if (getgrouplist(pw->pw_name, pw->pw_gid, gids, &ngids) == -1)
ngids = -1;
}
}
}
if (ngids <= 0) {
- sudo_efree(gids);
+ free(gids);
+ errno = ENOENT;
debug_return_ptr(NULL);
}
-#ifdef HAVE_SETAUTHDB
- aix_setauthdb((char *) pw->pw_name);
-#endif
-
#ifdef _SC_LOGIN_NAME_MAX
groupname_len = MAX((int)sysconf(_SC_LOGIN_NAME_MAX), 32);
#else
total += groupname_len * ngids;
again:
- grlitem = sudo_ecalloc(1, total);
+ if ((grlitem = calloc(1, total)) == NULL) {
+ free(gids);
+ debug_return_ptr(NULL);
+ }
/*
* Copy in group list and make pointers relative to space
/*
* Resolve and store group names by ID.
*/
+#ifdef HAVE_SETAUTHDB
+ if (grp == NULL)
+ aix_setauthdb((char *) pw->pw_name);
+#endif
ngroups = 0;
for (i = 0; i < ngids; i++) {
if ((grp = sudo_getgrgid(gids[i])) != NULL) {
len = strlen(grp->gr_name) + 1;
if (cp - (char *)grlitem + len > total) {
total += len + groupname_len;
- sudo_efree(grlitem);
+ free(grlitem);
sudo_gr_delref(grp);
goto again;
}
}
}
grlist->ngroups = ngroups;
- sudo_efree(gids);
+ free(gids);
#ifdef HAVE_SETAUTHDB
aix_restoreauthdb();