| 186 | */ |
| 187 | |
| 188 | login_cap_t * |
| 189 | login_getclassbyname(char const *name, const struct passwd *pwd) |
| 190 | { |
| 191 | login_cap_t *lc; |
| 192 | |
| 193 | if ((lc = malloc(sizeof(login_cap_t))) != NULL) { |
| 194 | int r, me, i = 0; |
| 195 | uid_t euid = 0; |
| 196 | gid_t egid = 0; |
| 197 | const char *msg = NULL; |
| 198 | const char *dir; |
| 199 | char userpath[MAXPATHLEN]; |
| 200 | |
| 201 | static char *login_dbarray[] = { NULL, NULL, NULL }; |
| 202 | |
| 203 | me = (name != NULL && strcmp(name, LOGIN_MECLASS) == 0); |
| 204 | dir = (!me || pwd == NULL) ? NULL : pwd->pw_dir; |
| 205 | /* |
| 206 | * Switch to user mode before checking/reading its ~/.login_conf |
| 207 | * - some NFSes have root read access disabled. |
| 208 | * |
| 209 | * XXX: This fails to configure additional groups. |
| 210 | */ |
| 211 | if (dir) { |
| 212 | euid = geteuid(); |
| 213 | egid = getegid(); |
| 214 | (void)setegid(pwd->pw_gid); |
| 215 | (void)seteuid(pwd->pw_uid); |
| 216 | } |
| 217 | |
| 218 | if (dir && snprintf(userpath, MAXPATHLEN, "%s/%s", dir, |
| 219 | _FILE_LOGIN_CONF) < MAXPATHLEN) { |
| 220 | if (_secure_path(userpath, pwd->pw_uid, pwd->pw_gid) != -1) |
| 221 | login_dbarray[i++] = userpath; |
| 222 | } |
| 223 | /* |
| 224 | * XXX: Why to add the system database if the class is `me'? |
| 225 | */ |
| 226 | if (_secure_path(path_login_conf, 0, 0) != -1) |
| 227 | login_dbarray[i++] = path_login_conf; |
| 228 | login_dbarray[i] = NULL; |
| 229 | |
| 230 | memset(lc, 0, sizeof(login_cap_t)); |
| 231 | lc->lc_cap = lc->lc_class = lc->lc_style = NULL; |
| 232 | |
| 233 | if (name == NULL || *name == '\0') |
| 234 | name = LOGIN_DEFCLASS; |
| 235 | |
| 236 | switch (cgetent(&lc->lc_cap, login_dbarray, name)) { |
| 237 | case -1: /* Failed, entry does not exist */ |
| 238 | if (me) |
| 239 | break; /* Don't retry default on 'me' */ |
| 240 | if (i == 0) |
| 241 | r = -1; |
| 242 | else if ((r = open(login_dbarray[0], O_RDONLY | O_CLOEXEC)) >= 0) |
| 243 | close(r); |
| 244 | /* |
| 245 | * If there's at least one login class database, |
no test coverage detected