int main(int argc, char** argv) { int fd; int flags = 0; mode_t mode = 0644; char *fname = NULL; int mode_set = 0; int flag_set = 0; int c; int save_errno = 0; int print_usage = 0; char *cloned_flags = NULL; if (argc == 1) Usage_and_abort(); while ((c = getopt (argc, argv, "f:m:")) != -1) { switch (c) { case 'f': { char *tmp; cloned_flags = (char *)malloc(strlen(optarg)+1); if (cloned_flags == NULL) { fprintf(stderr, "Insufficient memory.\n"); save_errno = -1; goto out; } strncpy(cloned_flags, optarg, strlen(optarg)+1); flags = atoi(cloned_flags); if (flags > 0) { flag_set = 1; #ifdef DEBUG printf("flags = %d\n",flags); #endif break; } else flags = 0; for (tmp = strtok(cloned_flags, ":|"); tmp; tmp = strtok(NULL, ":|")) { int i = 0; #ifdef DEBUG printf("flags = %s\n",tmp); #endif flag_set = 1; for (i = 0; flag_table[i].flag != -1; i++) { if (!strcmp(tmp, flag_table[i].string)){ flags |= flag_table[i].flag; break; } } if (flag_table[i].flag == -1) { fprintf(stderr, "No such flag: %s\n", tmp); save_errno = -1; goto out; } } #ifdef DEBUG printf("flags = %x\n", flags); #endif break; } case 'm': #ifdef DEBUG printf("mode = %s\n", optarg); #endif mode = strtol(optarg, NULL, 8); mode_set = 1; #ifdef DEBUG printf("mode = %o\n", mode); #endif break; default: fprintf(stderr, "Bad parameters.\n"); print_usage = 1; goto out; } } if (optind == argc) { fprintf(stderr, "Bad parameters.\n"); print_usage = 1; goto out; } fname = argv[optind]; if (!flag_set) { fprintf(stderr, "Missing flag or file-name\n"); save_errno = -1; goto out; } if (flags & O_CREAT) fd = open(fname, flags, mode); else fd = open(fname, flags); save_errno = errno; if (fd != -1) { printf("Succeed in opening file \"%s\"(flags=%s", fname, cloned_flags); if (mode_set) printf(", mode=%o", mode); printf(")\n"); close(fd); } else { fprintf(stderr, "Error in opening file \"%s\"(flags=%s", fname, cloned_flags); if (mode_set) fprintf(stderr, ", mode=%o", mode); fprintf(stderr, ") %d: %s\n", save_errno, strerror(save_errno)); } out: if (cloned_flags) free(cloned_flags); if (print_usage) Usage_and_abort(); return save_errno; }
int main(int argc, char **argv) { char **my_argv, *name = argv[0], *grp; int status, c, i; int gid_is_set = 0, uid_is_set = 0, num_supp = -1; uid_t user_id = 0; gid_t grp_id = 0, supp_groups[NGROUPS_MAX] = { 0 }; int euid_is_set = 0, egid_is_set = 0; uid_t euid = 0; gid_t egid = 0; if (argc == 1) { fprintf(stderr, "No parameter count\n"); Usage_and_abort(name); } // get UID and GID while ((c = getopt(argc, argv, "+u:g:v:j:hG::")) != -1) { switch (c) { case 'u': if (!isdigit(optarg[0])) { struct passwd *pw = getpwnam(optarg); if (pw == NULL) { fprintf(stderr, "parameter '%s' bad\n", optarg); Usage_and_abort(name); } user_id = pw->pw_uid; } else { user_id = (uid_t)atoi(optarg); } uid_is_set = 1; if (!gid_is_set) grp_id = user_id; break; case 'g': if (!isdigit(optarg[0])) { struct group *gr = getgrnam(optarg); if (gr == NULL) { fprintf(stderr, "getgrname %s failed\n", optarg); Usage_and_abort(name); } grp_id = gr->gr_gid; } else { grp_id = (gid_t)atoi(optarg); } gid_is_set = 1; break; case 'v': if (!isdigit(optarg[0])) { struct passwd *pw = getpwnam(optarg); if (pw == NULL) { fprintf(stderr, "parameter '%s' bad\n", optarg); Usage_and_abort(name); } euid = pw->pw_uid; } else { euid = (uid_t)atoi(optarg); } euid_is_set = 1; break; case 'j': if (!isdigit(optarg[0])) { struct group *gr = getgrnam(optarg); if (gr == NULL) { fprintf(stderr, "getgrname %s failed\n", optarg); Usage_and_abort(name); } egid = gr->gr_gid; } else { egid = (gid_t)atoi(optarg); } egid_is_set = 1; break; case 'G': num_supp = 0; if (optarg == NULL || !isdigit(optarg[0])) break; while ((grp = strsep(&optarg, ",")) != NULL) { printf("adding supp group %d\n", atoi(grp)); supp_groups[num_supp++] = atoi(grp); if (num_supp >= NGROUPS_MAX) break; } break; default: case 'h': Usage_and_abort(name); break; } } if (!uid_is_set) { fprintf(stderr, "Must specify uid to run.\n"); Usage_and_abort(name); } if (optind == argc) { fprintf(stderr, "Must specify command to run.\n"); Usage_and_abort(name); } // assemble the command my_argv = (char**)malloc(sizeof(char*)*(argc+1-optind)); if (my_argv == NULL) { fprintf(stderr, "Error in allocating memory. (%s)\n", strerror(errno)); exit(-1); } for (i = optind; i < argc; i++) { my_argv[i-optind] = argv[i]; //printf("%s\n",my_argv[i-optind]); } my_argv[i-optind] = NULL; #if DEBUG system("whoami"); #endif // set GID if (!egid_is_set) egid = grp_id; status = setregid(grp_id, egid); if (status == -1) { fprintf(stderr, "Cannot change gid to %d/%d, errno=%d (%s)\n", grp_id, egid, errno, strerror(errno) ); exit(-1); } if (num_supp >= 0) { status = setgroups(num_supp, supp_groups); if (status == -1) { perror("setting supplementary groups"); exit(-1); } } // set UID if (!euid_is_set) euid = user_id; status = setreuid(user_id, euid); if(status == -1) { fprintf(stderr,"Cannot change uid to %d/%d, errno=%d (%s)\n", user_id, euid, errno, strerror(errno) ); exit(-1); } fprintf(stderr, "running as uid/gid/euid/egid %d/%d/%d/%d, groups:", user_id, grp_id, euid, egid); for (i = 0; i < num_supp; i++) fprintf(stderr, " %d", supp_groups[i]); fprintf(stderr, "\n"); for (i = 0; i < argc - optind; i++) fprintf(stderr, " [%s]", my_argv[i]); fprintf(stderr, "\n"); fflush(stderr); // The command to be run execvp(my_argv[0], my_argv); fprintf(stderr, "execvp fails running %s (%d): %s\n", my_argv[0], errno, strerror(errno)); exit(-1); }