@ -36,11 +36,14 @@ static int perm_set (struct passwd *, struct group *);
static int authenticate ( const char * ) ;
static struct passwd * user_to_passwd ( const char * ) ;
static struct group * group_to_grp ( const char * ) ;
//static int execvpe(const char *, char *const *, char *const *);
// FIXME: misc_conv is a separate library, should stick to plain PAM or make
// our own pam module
static struct pam_conv conv = { misc_conv , NULL } ;
extern char * * environ ;
int main ( int argc , char * argv [ ] )
{
// TODO: Add arguments
@ -48,9 +51,9 @@ int main (int argc, char *argv[])
char * t_usr = " root " , * t_grp = NULL ;
struct passwd * t_pw ;
struct group * t_gr ;
int opt ;
int shellflag = 0 ;
while ( ( opt = getopt ( argc , argv , " A:u:g:C:s " ) ) ! = - 1 ) {
int opt , err ;
int shellflag = 0 , envflag = 0 ;
while ( ( opt = getopt ( argc , argv , " A:u:g:C:se " ) ) ! = - 1 ) {
switch ( opt ) {
case ' A ' :
printf ( " -A is not yet implemented \n " ) ;
@ -69,6 +72,9 @@ int main (int argc, char *argv[])
case ' s ' :
shellflag = 1 ;
break ;
case ' e ' :
envflag = 1 ;
break ;
case ' ? ' :
usage ( ) ;
exit ( EINVAL ) ;
@ -134,10 +140,53 @@ int main (int argc, char *argv[])
c_argv [ c_argc ] = NULL ;
/* Authenticate */
// FIXME: move this up
if ( authenticate ( uname ) ! = PAM_SUCCESS )
exit ( EXIT_FAILURE ) ;
// TODO: clean up env
struct env_elem {
char * name ;
char * value ;
} ;
struct env_elem env_keep [ ] = {
{ " PATH " , NULL } ,
{ " TERM " , NULL } ,
{ " EDITOR " , NULL } ,
{ " VISUAL " , NULL } ,
{ " DISPLAY " , NULL } ,
{ " XAUTHORITY " , NULL } ,
{ NULL , NULL }
} ;
struct env_elem env_mod [ ] = {
{ " USER " , t_pw - > pw_name } ,
{ " LOGNAME " , t_pw - > pw_name } ,
{ " SHELL " , t_pw - > pw_shell } ,
{ " HOME " , t_pw - > pw_dir } ,
{ NULL , NULL }
} ;
if ( envflag ) { /* clear env */
for ( int i = 0 ; env_keep [ i ] . name ; i + + )
env_keep [ i ] . value = strdup ( getenv ( env_keep [ i ] . name ) ) ;
environ = NULL ; // in place of clearenv
}
for ( int i = 0 ; env_mod [ i ] . name ; i + + ) {
// TODO: check err value
err = setenv ( env_mod [ i ] . name , env_mod [ i ] . value , 1 ) ;
}
if ( envflag ) {
for ( int i = 0 ; env_keep [ i ] . name ; i + + ) {
// TODO: check err value
if ( env_keep [ i ] . value )
err = setenv ( env_keep [ i ] . name , env_keep [ i ] . value , 1 ) ;
}
}
// do not override, we might be under more levels of 'us'
err = setenv ( " US_USER " , my_pw - > pw_name , 0 ) ;
errno = 0 ;
/* Set permissions */
@ -147,7 +196,6 @@ int main (int argc, char *argv[])
}
/* Execute the command */
int err ;
err = execvp ( c_argv [ 0 ] , c_argv ) ;
if ( err = = - 1 )
fprintf ( stderr , " execl: %s \n " , strerror ( errno ) ) ;
@ -171,7 +219,7 @@ static inline void usage (void)
// -c [file]: manually select config file
// something about environment
// something about non interactiveness
printf ( " usage: us [-s] [-u user] [-g group] command [args] \n " ) ;
printf ( " usage: us [-se ] [-u user] [-g group] command [args] \n " ) ;
}
static int perm_set ( struct passwd * pw , struct group * gr )
@ -305,3 +353,42 @@ static struct group* group_to_grp (const char *group)
}
return gr ;
}
/*
static int execvpe ( const char * file , char * const argv [ ] , char * const envp [ ] )
{
const char * p , * z , * path = getenv ( " PATH " ) ;
size_t l , k ;
errno = ENOENT ;
if ( ! * file ) return - 1 ;
if ( strchr ( file , ' / ' ) )
return execve ( file , argv , envp ) ;
if ( ! path ) path = " /usr/local/bin:/bin:/usr/bin " ;
k = strnlen ( file , NAME_MAX + 1 ) ;
if ( k > NAME_MAX ) {
errno = ENAMETOOLONG ;
return - 1 ;
}
l = strnlen ( path , PATH_MAX - 1 ) + 1 ;
for ( p = path ; ; p = z ) {
char b [ l + k + 1 ] ;
z = strchr ( p , ' : ' ) ;
if ( ! z ) z = p + strlen ( p ) ;
if ( ( size_t ) ( z - p ) > = l ) {
if ( ! * z + + ) break ;
continue ;
}
memcpy ( b , p , z - p ) ;
b [ z - p ] = ' / ' ;
memcpy ( b + ( z - p ) + ( z > p ) , file , k + 1 ) ;
execve ( b , argv , envp ) ;
if ( errno ! = ENOENT ) return - 1 ;
if ( ! * z + + ) break ;
}
return - 1 ;
}
*/