Beispiel #1
0
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;
}
Beispiel #2
0
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);
}