/* * Copyright (c) 2013 Red Hat. * * Exercise basic user access control checking APIs. * (non-Win32 variant of the test, uses uid_t/gid_t) */ #include #include #if defined(HAVE_PWD_H) #include #endif #if defined(HAVE_GRP_H) #include #endif gid_t gid; struct group *grp, *groups; int ngroups; uid_t uid; struct passwd *usr, *users; int nusers; unsigned int op; int check_users(void) { int c, s, sts = 0; for (c = 0; c < nusers; c++) { usr = &users[c]; if ((s = __pmAccAddUser(usr->pw_name, 1 << c, 1 << c, 0)) < 0) { printf("cannot add user for op%d: %s\n", c, pmErrStr(s)); sts = s; } } if (sts < 0) return 1; putc('\n', stderr); __pmAccDumpUsers(stderr); putc('\n', stderr); for (c = 0; c < WORD_BIT; c++) { usr = &users[c % nusers]; sts = __pmAccAddAccount(usr->pw_name, NULL, &op); if (sts < 0) { printf("add user #%d (%s): %s\n", c, usr->pw_name, pmErrStr(sts)); continue; } else if (op != (1 << c)) printf("account %d: __pmAccAddAccount returns denyOpsResult 0x%x (expected 0x%x)\n", c, op, 1 << c); } putc('\n', stderr); __pmAccDumpUsers(stderr); putc('\n', stderr); return 0; } int check_groups(void) { int c, s, sts = 0; for (c = 0; c < ngroups; c++) { grp = &groups[c]; if ((s = __pmAccAddGroup(grp->gr_name, 1 << c, 1 << c, 0)) < 0) { printf("cannot add group for op%d: %s\n", c, pmErrStr(s)); sts = s; } } if (sts < 0) return 1; putc('\n', stderr); __pmAccDumpGroups(stderr); putc('\n', stderr); for (c = 0; c < WORD_BIT; c++) { grp = &groups[c % ngroups]; sts = __pmAccAddAccount(NULL, grp->gr_name, &op); if (sts < 0) { printf("add group #%d (%s): %s\n", c, grp->gr_name, pmErrStr(sts)); continue; } else if (op != (1 << c)) printf("account %d: __pmAccAddAccount returns denyOpsResult 0x%x (expected 0x%x)\n", c, op, 1 << c); } putc('\n', stderr); __pmAccDumpGroups(stderr); putc('\n', stderr); return 0; } int main(int argc, char **argv) { int c, sts; int errflag = 0; char *name; size_t size; __pmSetProgname(argv[0]); while ((c = getopt(argc, argv, "D:u:g:?")) != EOF) { switch (c) { case 'D': /* debug flag */ if ((sts = __pmParseDebug(optarg)) < 0) { fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n", pmProgname, optarg); errflag++; } else pmDebug |= sts; break; case 'g': /* another group ID */ gid = atoi(optarg); if ((grp = getgrgid(gid)) == NULL) { fprintf(stderr, "%s: getgrgid: unknown group identifier (%s)\n", pmProgname, optarg); errflag++; break; } size = (ngroups + 1) * sizeof(*grp); if ((groups = realloc(groups, size)) == NULL) __pmNoMem("gid realloc", size, PM_FATAL_ERR); groups[ngroups] = *grp; for (c = 0, name = grp->gr_mem[0]; name; c++, name++) groups[ngroups].gr_mem[c] = strdup(name); ngroups++; break; case 'u': /* another user ID */ uid = atoi(optarg); if ((usr = getpwuid(uid)) == NULL) { fprintf(stderr, "%s: getpwuid: unknown user identifier (%s)\n", pmProgname, optarg); errflag++; break; } size = (nusers + 1) * sizeof(*usr); if ((users = realloc(users, size)) == NULL) __pmNoMem("uid realloc", size, PM_FATAL_ERR); memset(&users[nusers], 0, sizeof(*usr)); users[nusers].pw_name = strdup(usr->pw_name); users[nusers].pw_uid = usr->pw_uid; users[nusers].pw_gid = usr->pw_gid; nusers++; break; case '?': default: errflag++; break; } } if (errflag) { fprintf(stderr, "Usage: %s [options] uid ...\n\ \n\ Options:\n\ -D pmdebug set debugging diagnostics flag\n\ -u uid add numeric user ID to set used in testing\n\ -g gid add numeric group ID to set used in testing\n", pmProgname); return 1; } sts = 0; for (op = 0; op < WORD_BIT; op++) { if ((c = __pmAccAddOp(1 << op)) < 0) { printf("Bad op %d: %s\n", op, pmErrStr(c)); sts = c; } if ((c = __pmAccAddOp(1 << op)) >= 0) { printf("duplicate op test failed for op %d\n", op); sts = -EINVAL; } } if (sts < 0) return 1; if (nusers) if ((sts = check_users()) != 0) return sts; if (ngroups) if ((sts = check_groups()) != 0) return sts; return 0; }