Home | History | Annotate | Download | only in su
      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 #define LOG_TAG "su"
     19 
     20 #include <stdio.h>
     21 #include <stdlib.h>
     22 #include <string.h>
     23 #include <sys/types.h>
     24 #include <dirent.h>
     25 #include <errno.h>
     26 
     27 #include <unistd.h>
     28 #include <time.h>
     29 
     30 #include <pwd.h>
     31 
     32 #include <private/android_filesystem_config.h>
     33 
     34 /*
     35  * SU can be given a specific command to exec. UID _must_ be
     36  * specified for this (ie argc => 3).
     37  *
     38  * Usage:
     39  * su 1000
     40  * su 1000 ls -l
     41  */
     42 int main(int argc, char **argv)
     43 {
     44     struct passwd *pw;
     45     int uid, gid, myuid;
     46 
     47     if(argc < 2) {
     48         uid = gid = 0;
     49     } else {
     50         pw = getpwnam(argv[1]);
     51 
     52         if(pw == 0) {
     53             uid = gid = atoi(argv[1]);
     54         } else {
     55             uid = pw->pw_uid;
     56             gid = pw->pw_gid;
     57         }
     58     }
     59 
     60     /* Until we have something better, only root and the shell can use su. */
     61     myuid = getuid();
     62     if (myuid != AID_ROOT && myuid != AID_SHELL) {
     63         fprintf(stderr,"su: uid %d not allowed to su\n", myuid);
     64         return 1;
     65     }
     66 
     67     if(setgid(gid) || setuid(uid)) {
     68         fprintf(stderr,"su: permission denied\n");
     69         return 1;
     70     }
     71 
     72     /* User specified command for exec. */
     73     if (argc == 3 ) {
     74         if (execlp(argv[2], argv[2], NULL) < 0) {
     75             fprintf(stderr, "su: exec failed for %s Error:%s\n", argv[2],
     76                     strerror(errno));
     77             return -errno;
     78         }
     79     } else if (argc > 3) {
     80         /* Copy the rest of the args from main. */
     81         char *exec_args[argc - 1];
     82         memset(exec_args, 0, sizeof(exec_args));
     83         memcpy(exec_args, &argv[2], sizeof(exec_args));
     84         if (execvp(argv[2], exec_args) < 0) {
     85             fprintf(stderr, "su: exec failed for %s Error:%s\n", argv[2],
     86                     strerror(errno));
     87             return -errno;
     88         }
     89     }
     90 
     91     /* Default exec shell. */
     92     execlp("/system/bin/sh", "sh", NULL);
     93 
     94     fprintf(stderr, "su: exec failed\n");
     95     return 1;
     96 }
     97