summaryrefslogtreecommitdiff
path: root/qa/src/chkacc4.c
diff options
context:
space:
mode:
Diffstat (limited to 'qa/src/chkacc4.c')
-rw-r--r--qa/src/chkacc4.c198
1 files changed, 198 insertions, 0 deletions
diff --git a/qa/src/chkacc4.c b/qa/src/chkacc4.c
new file mode 100644
index 0000000..3c25825
--- /dev/null
+++ b/qa/src/chkacc4.c
@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) 2013 Red Hat.
+ *
+ * Exercise basic user access control checking APIs.
+ * (non-Win32 variant of the test, uses uid_t/gid_t)
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+#if defined(HAVE_PWD_H)
+#include <pwd.h>
+#endif
+#if defined(HAVE_GRP_H)
+#include <grp.h>
+#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;
+}