int main(int ac, char **av) { int lc; tst_parse_opts(ac, av, NULL, NULL); setup(); for (lc = 0; TEST_LOOPING(lc); lc++) { tst_count = 0; TEST(CHOWN(cleanup, fname, uid, gid)); if (TEST_RETURN == -1) { tst_resm(TFAIL | TTERRNO, "chown(%s, %d,%d) failed", fname, uid, gid); } else { tst_resm(TPASS, "chown(%s, %d,%d) returned %ld", fname, uid, gid, TEST_RETURN); } } cleanup(); tst_exit(); }
int chown3d(const char* path, uid_t uid, gid_t gid) { register char* sp; register int r; #if FS register Mount_t* mp; if (!fscall(NiL, MSG_chown, 0, path, uid, gid)) return(state.ret); mp = monitored(); #endif if (!(sp = pathreal(path, P_SAFE|P_TOP, NiL))) return(-1); r = CHOWN(sp, uid, gid); #if FS if (!r) { if (mp) fscall(mp, MSG_chown, 0, path, uid, gid); for (mp = state.global; mp; mp = mp->global) if (fssys(mp, MSG_chown)) fscall(mp, MSG_chown, 0, path, uid, gid); } #endif return(r); }
int main(int ac, char **av) { struct stat stat_buf; /* stat(2) struct contents */ int lc; const char *msg; uid_t user_id; /* Owner id of the test file. */ gid_t group_id; /* Group id of the test file. */ if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL) tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); setup(); for (lc = 0; TEST_LOOPING(lc); lc++) { tst_count = 0; UID16_CHECK((user_id = geteuid()), "chown", cleanup) GID16_CHECK((group_id = getegid()), "chown", cleanup) TEST(CHOWN(cleanup, TESTFILE, -1, group_id)); if (TEST_RETURN == -1) { tst_resm(TFAIL | TTERRNO, "chown(%s, ..) failed", TESTFILE); continue; } if (stat(TESTFILE, &stat_buf) == -1) tst_brkm(TFAIL | TERRNO, cleanup, "stat failed"); if (stat_buf.st_uid != user_id || stat_buf.st_gid != group_id) tst_resm(TFAIL, "%s: Incorrect ownership" "set to %d %d, Expected %d %d", TESTFILE, stat_buf.st_uid, stat_buf.st_gid, user_id, group_id); if (stat_buf.st_mode != (NEW_PERMS & ~(S_ISUID | S_ISGID))) tst_resm(TFAIL, "%s: incorrect mode permissions" " %#o, Expected %#o", TESTFILE, stat_buf.st_mode, NEW_PERMS & ~(S_ISUID | S_ISGID)); else tst_resm(TPASS, "chown(%s, ..) was successful", TESTFILE); } cleanup(); tst_exit(); }
int main(int ac, char **av) { struct stat stat_buf; /* stat(2) struct contents */ int lc; int i; uid_t user_id; /* user id of the user set for testfile */ gid_t group_id; /* group id of the user set for testfile */ tst_parse_opts(ac, av, NULL, NULL); setup(); for (lc = 0; TEST_LOOPING(lc); lc++) { tst_count = 0; for (i = 0; i < TST_TOTAL; i++) { user_id = test_cases[i].user_id; group_id = test_cases[i].group_id; TEST(CHOWN(cleanup, TESTFILE, user_id, group_id)); if (TEST_RETURN == -1) { tst_resm(TFAIL | TTERRNO, "chown failed"); continue; } if (stat(TESTFILE, &stat_buf) == -1) tst_brkm(TFAIL, cleanup, "stat failed"); if (user_id == -1) user_id = test_cases[i - 1].user_id; if (group_id == -1) group_id = test_cases[i - 1].group_id; if (stat_buf.st_uid != user_id || stat_buf.st_gid != group_id) tst_resm(TFAIL, "%s: incorrect " "ownership set, Expected %d " "%d", TESTFILE, user_id, group_id); else tst_resm(TPASS, "chown succeeded"); } } cleanup(); tst_exit(); }
/* * chgrpr() - recursive chown() * * Recursively chowns the input directory then its contents. rflag must * have been set if chgrpr() is called. The input directory should not * be a sym link (this is handled in the calling routine). In * addition, the calling routine should have already added the input * directory to the search tree so we do not get into endless loops. * Note: chgrpr() doesn't need a return value as errors are reported * through the global "status" variable. */ static void chgrpr(char *dir, gid_t gid) { struct dirent *dp; DIR *dirp; struct stat st, st2; char savedir[1024]; if (getcwd(savedir, 1024) == 0) { (void) fprintf(stderr, "chgrp: "); (void) fprintf(stderr, gettext("%s\n"), savedir); exit(255); } /* * Attempt to chown the directory, however don't return if we * can't as we still may be able to chown the contents of the * directory. Note: the calling routine resets the SUID bits * on this directory so we don't have to perform an extra 'stat'. */ CHOWN(dir, -1, gid); if (chdir(dir) < 0) { status += Perror(dir); return; } if ((dirp = opendir(".")) == NULL) { status += Perror(dir); return; } for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) { if ((strcmp(dp->d_name, ".") == 0) || (strcmp(dp->d_name, "..") == 0)) { continue; /* skip "." and ".." */ } if (lstat(dp->d_name, &st) < 0) { status += Perror(dp->d_name); continue; } if ((st.st_mode & S_IFMT) == S_IFLNK) { if (hflag || Pflag) { /* * Change the group id of the symbolic link * encountered while traversing the * directory. Don't follow the symbolic * link to any other part of the file * hierarchy. */ LCHOWN(dp->d_name, -1, gid); } else { if (stat(dp->d_name, &st2) < 0) { status += Perror(dp->d_name); continue; } /* * We know that we are to change the * group of the file referenced by the * symlink encountered while traversing * the directory. Now check to see if we * are to follow the symlink to any other * part of the file hierarchy. */ if (FOLLOW_D_LINKS) { if ((st2.st_mode & S_IFMT) == S_IFDIR) { /* * We are following symlinks so * traverse into the directory. * Add this node to the search * tree so we don't get into an * endless loop. */ int rc; if ((rc = add_tnode(&tree, st2.st_dev, st2.st_ino)) == 1) { chgrpr(dp->d_name, gid); /* * Restore SET[UG]ID * bits. */ SETUGID_PRESERVE( dp->d_name, st2.st_mode & ~S_IFMT); } else if (rc == 0) { /* already visited */ continue; } else { /* * An error occurred * while trying to add * the node to the tree. */ status += Perror( dp->d_name); continue; } } else { /* * Change the group id of the * file referenced by the * symbolic link. */ CHOWN(dp->d_name, -1, gid); } } else { /* * Change the group id of the file * referenced by the symbolic link. */ CHOWN(dp->d_name, -1, gid); if ((st2.st_mode & S_IFMT) == S_IFDIR) { /* Restore SET[UG]ID bits. */ SETUGID_PRESERVE(dp->d_name, st2.st_mode & ~S_IFMT); } } } } else if ((st.st_mode & S_IFMT) == S_IFDIR) { /* * Add this node to the search tree so we don't * get into a endless loop. */ int rc; if ((rc = add_tnode(&tree, st.st_dev, st.st_ino)) == 1) { chgrpr(dp->d_name, gid); /* Restore the SET[UG]ID bits. */ SETUGID_PRESERVE(dp->d_name, st.st_mode & ~S_IFMT); } else if (rc == 0) { /* already visited */ continue; } else { /* * An error occurred while trying * to add the node to the search tree. */ status += Perror(dp->d_name); continue; } } else { CHOWN(dp->d_name, -1, gid); } } (void) closedir(dirp); if (chdir(savedir) < 0) { (void) fprintf(stderr, "chgrp: "); (void) fprintf(stderr, gettext("can't change back to %s\n"), savedir); exit(255); } }
int main(int argc, char *argv[]) { int c; /* set the locale for only the messages system (all else is clean) */ (void) setlocale(LC_ALL, ""); #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */ #endif (void) textdomain(TEXT_DOMAIN); while ((c = getopt(argc, argv, "RhfHLPs")) != EOF) switch (c) { case 'R': rflag++; break; case 'h': hflag++; break; case 'f': fflag++; break; case 'H': /* * If more than one of -H, -L, and -P * are specified, only the last option * specified determines the behavior of * chgrp. In addition, make [-H|-L] * mutually exclusive of -h. */ Lflag = Pflag = 0; Hflag++; break; case 'L': Hflag = Pflag = 0; Lflag++; break; case 'P': Hflag = Lflag = 0; Pflag++; break; case 's': sflag++; break; default: usage(); } /* * Set Pflag by default for recursive operations * if no other options were specified. */ if (rflag && !(Lflag || Hflag || Pflag || hflag)) { Pflag = 1; } /* * Check for sufficient arguments * or a usage error. */ argc -= optind; argv = &argv[optind]; if ((argc < 2) || ((Hflag || Lflag || Pflag) && !rflag) || ((Hflag || Lflag || Pflag) && hflag)) { usage(); } if (sflag) { if (sid_to_id(argv[0], B_FALSE, &gid)) { (void) fprintf(stderr, gettext( "chgrp: invalid group sid %s\n"), argv[0]); exit(2); } } else if ((gr = getgrnam(argv[0])) != NULL) { gid = gr->gr_gid; } else { if (isnumber(argv[0])) { errno = 0; /* gid is an int */ gid = (gid_t)strtoul(argv[0], NULL, 10); if (errno != 0) { if (errno == ERANGE) { (void) fprintf(stderr, gettext( "chgrp: group id is too large\n")); exit(2); } else { (void) fprintf(stderr, gettext( "chgrp: invalid group id\n")); exit(2); } } } else { (void) fprintf(stderr, "chgrp: "); (void) fprintf(stderr, gettext("unknown group: %s\n"), argv[0]); exit(2); } } for (c = 1; c < argc; c++) { tree = NULL; if (lstat(argv[c], &stbuf) < 0) { status += Perror(argv[c]); continue; } if (rflag && ((stbuf.st_mode & S_IFMT) == S_IFLNK)) { if (hflag || Pflag) { /* * Change the group id of the symbolic link * specified on the command line. * Don't follow the symbolic link to * any other part of the file hierarchy. */ LCHOWN(argv[c], -1, gid); } else { if (stat(argv[c], &stbuf2) < 0) { status += Perror(argv[c]); continue; } /* * We know that we are to change the * group of the file referenced by the * symlink specified on the command line. * Now check to see if we are to follow * the symlink to any other part of the * file hierarchy. */ if (FOLLOW_CL_LINKS) { if ((stbuf2.st_mode & S_IFMT) == S_IFDIR) { /* * We are following symlinks so * traverse into the directory. * Add this node to the search * tree so we don't get into an * endless loop. */ if (add_tnode(&tree, stbuf2.st_dev, stbuf2.st_ino) == 1) { chgrpr(argv[c], gid); /* * Try to restore the * SET[UG]ID bits. */ SETUGID_PRESERVE( argv[c], stbuf2.st_mode & ~S_IFMT); } else { /* * Error occurred. * rc can't be 0 * as this is the first * node to be added to * the search tree. */ status += Perror( argv[c]); } } else { /* * Change the group id of the * file referenced by the * symbolic link. */ CHOWN(argv[c], -1, gid); } } else { /* * Change the group id of the file * referenced by the symbolic link. */ CHOWN(argv[c], -1, gid); if ((stbuf2.st_mode & S_IFMT) == S_IFDIR) { /* Reset the SET[UG]ID bits. */ SETUGID_PRESERVE(argv[c], stbuf2.st_mode & ~S_IFMT); } } } } else if (rflag && ((stbuf.st_mode & S_IFMT) == S_IFDIR)) { /* * Add this node to the search tree so we don't * get into a endless loop. */ if (add_tnode(&tree, stbuf.st_dev, stbuf.st_ino) == 1) { chgrpr(argv[c], gid); /* Restore the SET[UG]ID bits. */ SETUGID_PRESERVE(argv[c], stbuf.st_mode & ~S_IFMT); } else { /* * An error occurred while trying * to add the node to the tree. * Continue on with next file * specified. Note: rc shouldn't * be 0 as this was the first node * being added to the search tree. */ status += Perror(argv[c]); } } else { if (hflag || Pflag) { LCHOWN(argv[c], -1, gid); } else { CHOWN(argv[c], -1, gid); } /* If a directory, reset the SET[UG]ID bits. */ if ((stbuf.st_mode & S_IFMT) == S_IFDIR) { SETUGID_PRESERVE(argv[c], stbuf.st_mode & ~S_IFMT); } } } return (status); }
int main(int ac, char **av) { struct stat stat_buf; /* stat(2) struct contents */ int lc; const char *msg; int i; uid_t user_id; /* user id of the user set for testfile */ gid_t group_id; /* group id of the user set for testfile */ int test_flag; /* test condition specific flag variable */ char *file_name; /* ptr. for test file name */ if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL) tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); setup(); for (lc = 0; TEST_LOOPING(lc); lc++) { tst_count = 0; for (i = 0; i < TST_TOTAL; i++) { file_name = test_cases[i].pathname; user_id = test_cases[i].user_id; group_id = test_cases[i].group_id; test_flag = test_cases[i].test_flag; /* * Call chown(2) with different user id and * group id (numeric values) to set it on testfile. */ TEST(CHOWN(cleanup, file_name, user_id, group_id)); if (TEST_RETURN == -1) { tst_resm(TFAIL | TTERRNO, "chown(%s, ..) failed", file_name); continue; } /* * Get the testfile information using stat(2). */ if (stat(file_name, &stat_buf) < 0) { tst_brkm(TFAIL, cleanup, "stat(2) of " "%s failed, errno:%d", file_name, TEST_ERRNO); } /* * Check for expected Ownership ids * set on testfile. */ if (stat_buf.st_uid != user_id || stat_buf.st_gid != group_id) { tst_brkm(TFAIL, cleanup, "%s: incorrect" " ownership set, Expected %d " "%d", file_name, user_id, group_id); } /* * Verify that S_ISUID/S_ISGID bits set on the * testfile(s) in setup()s are cleared by * chown(). */ if (test_flag == 1 && (stat_buf.st_mode & (S_ISUID | S_ISGID)) != 0) { tst_resm(TFAIL, "%s: incorrect mode " "permissions %#o, Expected " "%#o", file_name, NEW_PERMS1, EXP_PERMS); } else if (test_flag == 2 && (stat_buf.st_mode & S_ISGID) == 0) { tst_resm(TFAIL, "%s: Incorrect mode " "permissions %#o, Expected " "%#o", file_name, stat_buf.st_mode, NEW_PERMS2); } else { tst_resm(TPASS, "chown(%s, ..) succeeded", file_name); } } } cleanup(); tst_exit(); }