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 /* Until we have something better, only root and the shell can use su. */ 48 myuid = getuid(); 49 if (myuid != AID_ROOT && myuid != AID_SHELL) { 50 fprintf(stderr,"su: uid %d not allowed to su\n", myuid); 51 return 1; 52 } 53 54 if(argc < 2) { 55 uid = gid = 0; 56 } else { 57 pw = getpwnam(argv[1]); 58 59 if(pw == 0) { 60 uid = gid = atoi(argv[1]); 61 } else { 62 uid = pw->pw_uid; 63 gid = pw->pw_gid; 64 } 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