int factor;
};
+#ifdef HAVE_SETAUTHDB
+static char saved_authsys[16]; /* 15 chars plus NUL as per setauthdb(3) */
+#endif
+
static struct aix_limit aix_limits[] = {
{ RLIMIT_FSIZE, S_UFSIZE, S_UFSIZE_HARD, 512 },
{ RLIMIT_CPU, S_UCPU, S_UCPU_HARD, 1 },
return(0);
}
-void
+static void
aix_setlimits(user)
char *user;
{
rlim64_t val;
int n;
+ if (setuserdb(S_READ) != 0)
+ error(1, "unable to open userdb");
+
/*
* For each resource limit, get the soft/hard values for the user
* and set those values via setrlimit64(). Must be run as euid 0.
}
(void)setrlimit64(aix_limits[n].resource, &rlim);
}
+ enduserdb();
}
+#ifdef HAVE_SETAUTHDB
+/*
+ * 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).
+ */
+void
+aix_setauthdb(char *user)
+{
+ char *authsys;
+
+ if (user != NULL) {
+ if (setuserdb(S_READ) != 0)
+ error(1, "unable to open userdb");
+ if (getuserattr(user, S_AUTHSYSTEM, &authsys, SEC_CHAR) == 0) {
+ if (setauthdb(authsys, saved_authsys) != 0)
+ error(1, "unable to switch to authsystem \"%s\" for %s",
+ authsys, user);
+ }
+ enduserdb();
+ }
+}
+
+/*
+ * Restore the saved administrative domain, if any.
+ */
+void
+aix_restoreauthdb()
+{
+ if (saved_authsys[0]) {
+ if (setauthdb(saved_authsys, NULL) != 0)
+ error(1, "unable to restore authsystem \"%s\", saved_authsys);
+ saved_authsys[0] = '\0';
+ }
+}
+#endif
+
+void
+aix_prep_user(user)
+ char *user;
+{
+ char *info;
+ int len;
+
+ /* set usrinfo, like login(1) does */
+ /* XXX - should NAME field be pw_gecos? */
+ len = easprintf(&info, "NAME=%s%cLOGIN=%s%cLOGNAME=%s%cTTY=%s%c",
+ user, '\0', user, '\0', user, '\0', user_ttypath ? user_ttypath : "");
+ (void)usrinfo(SETUINFO, info, len);
+ efree(info);
+
+#ifdef HAVE_SETAUTHDB
+ /* set administrative domain */
+ aix_setauthdb(user);
+#endif
+
+ /* set resource limits */
+ aix_setlimits(user);
+}
#endif /* HAVE_GETUSERATTR */
key.pw_uid = uid;
if ((node = rbfind(pwcache_byuid, &key)) != NULL) {
pw = (struct passwd *) node->data;
- return(pw->pw_name != NULL ? pw : NULL);
+ goto done;
}
/*
* Cache passwd db entry if it exists or a negative response if not.
*/
+#ifdef HAVE_SETAUTHDB
+ aix_setauthdb(IDtouser(uid));
+#endif
if ((pw = getpwuid(uid)) != NULL) {
pw = sudo_pwdup(pw);
cp = sudo_getepw(pw); /* get shadow password */
if (rbinsert(pwcache_byuid, (void *) pw) != NULL)
errorx(1, "unable to cache uid %lu (%s), already exists",
uid, pw->pw_name);
- return(pw);
} else {
pw = emalloc(sizeof(*pw));
zero_bytes(pw, sizeof(*pw));
pw->pw_uid = uid;
if (rbinsert(pwcache_byuid, (void *) pw) != NULL)
errorx(1, "unable to cache uid %lu, already exists", uid);
- return(NULL);
}
+#ifdef HAVE_SETAUTHDB
+ aix_restoreauthdb();
+#endif
+done:
+ return(pw->pw_name != NULL ? pw : NULL);
}
/*
key.pw_name = (char *) name;
if ((node = rbfind(pwcache_byname, &key)) != NULL) {
pw = (struct passwd *) node->data;
- return(pw->pw_uid != (uid_t) -1 ? pw : NULL);
+ goto done;
}
/*
* Cache passwd db entry if it exists or a negative response if not.
*/
+#ifdef HAVE_SETAUTHDB
+ aix_setauthdb(user);
+#endif
if ((pw = getpwnam(name)) != NULL) {
pw = sudo_pwdup(pw);
cp = sudo_getepw(pw); /* get shadow password */
pw->pw_passwd = cp;
if (rbinsert(pwcache_byname, (void *) pw) != NULL)
errorx(1, "unable to cache user %s, already exists", name);
- return(pw);
} else {
len = strlen(name) + 1;
cp = emalloc(sizeof(*pw) + len);
pw->pw_uid = (uid_t) -1;
if (rbinsert(pwcache_byname, (void *) pw) != NULL)
errorx(1, "unable to cache user %s, already exists", name);
- return(NULL);
}
+#ifdef HAVE_SETAUTHDB
+ aix_restoreauthdb();
+#endif
+done:
+ return(pw->pw_uid != (uid_t) -1 ? pw : NULL);
}
/*
key.gr_gid = gid;
if ((node = rbfind(grcache_bygid, &key)) != NULL) {
gr = (struct group *) node->data;
- return(gr->gr_name != NULL ? gr : NULL);
+ goto done;
}
/*
* Cache group db entry if it exists or a negative response if not.
if (rbinsert(grcache_bygid, (void *) gr) != NULL)
errorx(1, "unable to cache gid %lu (%s), already exists",
gid, gr->gr_name);
- return(gr);
} else {
gr = emalloc(sizeof(*gr));
zero_bytes(gr, sizeof(*gr));
gr->gr_gid = gid;
if (rbinsert(grcache_bygid, (void *) gr) != NULL)
errorx(1, "unable to cache gid %lu, already exists, gid");
- return(NULL);
}
+done:
+ return(gr->gr_name != NULL ? gr : NULL);
}
/*
key.gr_name = (char *) name;
if ((node = rbfind(grcache_byname, &key)) != NULL) {
gr = (struct group *) node->data;
- return(gr->gr_gid != (gid_t) -1 ? gr : NULL);
+ goto done;
}
/*
* Cache group db entry if it exists or a negative response if not.
gr = sudo_grdup(gr);
if (rbinsert(grcache_byname, (void *) gr) != NULL)
errorx(1, "unable to cache group %s, already exists", name);
- return(gr);
} else {
len = strlen(name) + 1;
cp = emalloc(sizeof(*gr) + len);
gr->gr_gid = (gid_t) -1;
if (rbinsert(grcache_byname, (void *) gr) != NULL)
errorx(1, "unable to cache group %s, already exists", name);
- return(NULL);
}
+done:
+ return(gr->gr_gid != (gid_t) -1 ? gr : NULL);
}
void
#endif
struct group *grp;
- if ((grp = sudo_getgrnam(group)) == NULL)
+#ifdef HAVE_SETAUTHDB
+ aix_setauthdb(pw->pw_user);
+#endif
+ grp = sudo_getgrnam(group);
+#ifdef HAVE_SETAUTHDB
+ aix_restoreauthdb();
+#endif
+ if (grp == NULL)
return(FALSE);
/* check against user's primary (passwd file) gid */