su.c revision 7341494707810f709855ea85ce03a8ec3ac8dbaf
1/*
2**
3** Copyright 2008, The Android Open Source Project
4**
5** Licensed under the Apache License, Version 2.0 (the "License");
6** you may not use this file except in compliance with the License.
7** You may obtain a copy of the License at
8**
9**     http://www.apache.org/licenses/LICENSE-2.0
10**
11** Unless required by applicable law or agreed to in writing, software
12** distributed under the License is distributed on an "AS IS" BASIS,
13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14** See the License for the specific language governing permissions and
15** limitations under the License.
16*/
17
18#include <stdio.h>
19#include <stdlib.h>
20#include <string.h>
21#include <sys/types.h>
22#include <dirent.h>
23#include <errno.h>
24
25#include <unistd.h>
26#include <time.h>
27
28#include <pwd.h>
29
30/*
31 * SU can be given a specific command to exec. UID _must_ be
32 * specified for this (ie argc => 3). Full path of file must be specified.
33 *
34 * Usage:
35 * su 1000
36 * su 1000 /system/bin/ls -l
37 */
38int main(int argc, char **argv)
39{
40    struct passwd *pw;
41    int uid, gid;
42
43    if(argc < 2) {
44        uid = gid = 0;
45    } else {
46        pw = getpwnam(argv[1]);
47
48        if(pw == 0) {
49            uid = gid = atoi(argv[1]);
50        } else {
51            uid = pw->pw_uid;
52            gid = pw->pw_gid;
53        }
54    }
55
56    if(setgid(gid) || setuid(uid)) {
57        fprintf(stderr,"su: permission denied\n");
58        return 1;
59    }
60
61    /* User specified command for exec. */
62    if (argc == 3 ) {
63        if (execlp(argv[2], argv[2], NULL) < 0) {
64            fprintf(stderr, "su: exec failed for %s Error:%s\n", argv[2],
65                    strerror(errno));
66            return -errno;
67        }
68    } else if (argc > 3) {
69        /* Copy the rest of the args from main. */
70        char *exec_args[argc - 1];
71        memset(exec_args, 0, sizeof(exec_args));
72        memcpy(exec_args, &argv[2], sizeof(exec_args));
73        if (execv(argv[2], exec_args) < 0) {
74            fprintf(stderr, "su: exec failed for %s Error:%s\n", argv[2],
75                    strerror(errno));
76            return -errno;
77        }
78    }
79
80    /* Default exec shell. */
81    execlp("/system/bin/sh", "sh", NULL);
82
83    fprintf(stderr, "su: exec failed\n");
84    return 1;
85}
86
87