su.c revision 17928c8ab5e696517cd03969364f7288ab5b911c
1e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project/* 2e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project** 3e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project** Copyright 2008, The Android Open Source Project 4e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project** 5e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License"); 6e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project** you may not use this file except in compliance with the License. 7e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project** You may obtain a copy of the License at 8e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project** 9e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project** http://www.apache.org/licenses/LICENSE-2.0 10e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project** 11e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project** Unless required by applicable law or agreed to in writing, software 12e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project** distributed under the License is distributed on an "AS IS" BASIS, 13e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project** See the License for the specific language governing permissions and 15e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project** limitations under the License. 16e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project*/ 17e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 1826aaac4bf942c4f51de0f10ea85edf9751c234c8The Android Open Source Project#define LOG_TAG "su" 1926aaac4bf942c4f51de0f10ea85edf9751c234c8The Android Open Source Project 20e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <stdio.h> 21e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <stdlib.h> 22e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <string.h> 23e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <sys/types.h> 24e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <dirent.h> 25e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <errno.h> 26e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 27e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <unistd.h> 28e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <time.h> 29e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 30e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <pwd.h> 31e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 3226aaac4bf942c4f51de0f10ea85edf9751c234c8The Android Open Source Project#include <private/android_filesystem_config.h> 3326aaac4bf942c4f51de0f10ea85edf9751c234c8The Android Open Source Project 34e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project/* 35e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * SU can be given a specific command to exec. UID _must_ be 36e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * specified for this (ie argc => 3). 37e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * 38e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * Usage: 39e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * su 1000 40e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * su 1000 ls -l 41e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project */ 42e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectint main(int argc, char **argv) 43e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project{ 44e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project struct passwd *pw; 4526aaac4bf942c4f51de0f10ea85edf9751c234c8The Android Open Source Project int uid, gid, myuid; 46e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 4717928c8ab5e696517cd03969364f7288ab5b911cNick Kralevich /* Until we have something better, only root and the shell can use su. */ 4817928c8ab5e696517cd03969364f7288ab5b911cNick Kralevich myuid = getuid(); 4917928c8ab5e696517cd03969364f7288ab5b911cNick Kralevich if (myuid != AID_ROOT && myuid != AID_SHELL) { 5017928c8ab5e696517cd03969364f7288ab5b911cNick Kralevich fprintf(stderr,"su: uid %d not allowed to su\n", myuid); 5117928c8ab5e696517cd03969364f7288ab5b911cNick Kralevich return 1; 5217928c8ab5e696517cd03969364f7288ab5b911cNick Kralevich } 5317928c8ab5e696517cd03969364f7288ab5b911cNick Kralevich 54e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project if(argc < 2) { 55e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project uid = gid = 0; 56e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } else { 57e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project pw = getpwnam(argv[1]); 58e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 59e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project if(pw == 0) { 60e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project uid = gid = atoi(argv[1]); 61e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } else { 62e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project uid = pw->pw_uid; 63e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project gid = pw->pw_gid; 64e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 65e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 66e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 67e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project if(setgid(gid) || setuid(uid)) { 68e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project fprintf(stderr,"su: permission denied\n"); 69e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project return 1; 70e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 71e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 72e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project /* User specified command for exec. */ 73e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project if (argc == 3 ) { 74e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project if (execlp(argv[2], argv[2], NULL) < 0) { 75e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project fprintf(stderr, "su: exec failed for %s Error:%s\n", argv[2], 76e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project strerror(errno)); 77e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project return -errno; 78e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 79e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } else if (argc > 3) { 80e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project /* Copy the rest of the args from main. */ 81e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project char *exec_args[argc - 1]; 82e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project memset(exec_args, 0, sizeof(exec_args)); 83e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project memcpy(exec_args, &argv[2], sizeof(exec_args)); 84e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project if (execvp(argv[2], exec_args) < 0) { 85e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project fprintf(stderr, "su: exec failed for %s Error:%s\n", argv[2], 86e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project strerror(errno)); 87e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project return -errno; 88e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 89e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 90e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 91e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project /* Default exec shell. */ 92e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project execlp("/system/bin/sh", "sh", NULL); 93e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 94e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project fprintf(stderr, "su: exec failed\n"); 95e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project return 1; 96e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project} 97