su.c revision ab8beedeb70c6941e0ff68014d8db64cee4ef15d
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). 33 * 34 * Usage: 35 * su 1000 36 * su 1000 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 (execvp(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