Пример #1
0
//=============================================================================
char*
ListFilesInDirectory(
const char* DirName ) ///< name of a directory
{
  if ( DirName == NULL ) return NULL;
    
  DIR *directory = opendir(DirName);
  
  if ( directory == NULL ) return NULL;
  
  // entry in the directory
  struct dirent *entry;
  
  // initialize file list to empty
  char* FileList = StringDuplicate("");

  // loop over entries
  while( (entry = readdir(directory)) != NULL )
  {
    // filter . and .. entries
    if ( StringCompare(entry->d_name,".") || 
         StringCompare(entry->d_name,"..") ) continue;
    
    // append file name and separator to list
    StringAppend(&FileList,entry->d_name);
    StringAppend(&FileList," ");
  }
  
  // close directory
  assert_error( closedir(directory) == 0, "Failed to close directory");
  
  return FileList;
}
Пример #2
0
static bool SetAccountLockExpiration(const char *puser, bool lock)
{
    if (!PlatformSupportsExpirationLock())
    {
        return true;
    }

    char cmd[CF_BUFSIZE + strlen(puser)];

    strcpy (cmd, USERMOD);
    StringAppend(cmd, " -e \"", sizeof(cmd));
    if (lock)
    {
        StringAppend(cmd, GetPlatformSpecificExpirationDate(), sizeof(cmd));
    }
    StringAppend(cmd, "\" ", sizeof(cmd));
    StringAppend(cmd, puser, sizeof(cmd));

    Log(LOG_LEVEL_VERBOSE, "%s user '%s' by setting expiry date. (command: '%s')",
        lock ? "Locking" : "Unlocking", puser, cmd);

    int status;
    status = system(cmd);
    if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
    {
        Log(LOG_LEVEL_ERR, "Command returned error while %s user '%s'. (Command line: '%s')",
            lock ? "locking" : "unlocking", puser, cmd);
        return false;
    }

    return true;
}
Пример #3
0
TString *USBStandardHubGetDeviceNames (TUSBDevice *pDevice)
{
	assert (pDevice != 0);

	TString *pResult = (TString *) malloc (sizeof (TString));
	assert (pResult != 0);
	String (pResult);

	for (unsigned nSelector = DeviceNameVendor; nSelector < DeviceNameUnknown; nSelector++)
	{
		TString *pName = USBDeviceGetName (pDevice, (TDeviceNameSelector) nSelector);
		assert (pName != 0);

		if (StringCompare (pName, "unknown") != 0)
		{
			if (StringGetLength (pResult) > 0)
			{
				StringAppend (pResult, ", ");
			}

			StringAppend (pResult, StringGet (pName));
		}

		_String (pName);
		free (pName);
	}

	if (StringGetLength (pResult) == 0)
	{
		StringSet (pResult, "unknown");
	}

	return pResult;
}
Пример #4
0
void HttpRequest::AppendStartLineToString(std::string* result) const {
    CHECK_NE(m_method, METHOD_UNKNOWN);
    StringAppend(result, GetMethodName(m_method), " ", m_uri);
    HttpVersion version = Version();
    if (!version.IsEmpty()) {
        StringAppend(result, " ", "HTTP/", version.Major(), ".", version.Minor());
    }
}
Пример #5
0
static bool SetAccountLocked(const char *puser, const char *hash, bool lock)
{
    char cmd[CF_BUFSIZE + strlen(hash)];

    strcpy (cmd, USERMOD);
    StringAppend(cmd, " -e \"", sizeof(cmd));

    if (lock)
    {
        if (hash[0] != '!')
        {
            char new_hash[strlen(hash) + 2];
            sprintf(new_hash, "!%s", hash);
            if (!ChangePassword(puser, new_hash, PASSWORD_FORMAT_HASH))
            {
                return false;
            }
        }
        StringAppend(cmd, GetPlatformSpecificExpirationDate(), sizeof(cmd));
    }
    else
    {
        // Important to check. Password may already have been changed if that was also
        // specified in the policy.
        if (hash[0] == '!')
        {
            if (!ChangePassword(puser, &hash[1], PASSWORD_FORMAT_HASH))
            {
                return false;
            }
        }
    }

    StringAppend(cmd, "\" ", sizeof(cmd));
    StringAppend(cmd, puser, sizeof(cmd));

    Log(LOG_LEVEL_VERBOSE, "%s user '%s' by setting expiry date. (command: '%s')",
        lock ? "Locking" : "Unlocking", puser, cmd);

    int status;
    status = system(cmd);
    if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
    {
        Log(LOG_LEVEL_ERR, "Command returned error while %s user '%s'. (Command line: '%s')",
            lock ? "locking" : "unlocking", puser, cmd);
        return false;
    }

    return true;
}
/*
 * Below function copies a file owned and managed by a user to a secured location so that it can be accessed securely.
 */
static int _secure_file_path( const char ** path,const char * source )
{
	int fd_source ;
	int fd_temp ;
	char buffer[ SIZE ] ;
	size_t len ;
	const char * temp_path ;
	struct stat ststr ;

	string_t st_path = _create_work_directory() ;

	StringAppend( st_path,"0-" ) ;
	temp_path = StringAppendInt( st_path,syscall( SYS_gettid ) ) ;

	zuluCryptSecurityDropElevatedPrivileges() ;

	fd_source = open( source,O_RDONLY ) ;

	if( fd_source == -1 ){
		StringDelete( &st_path ) ;
		return 0 ;
	}

	fstat( fd_source,&ststr ) ;

	if( ststr.st_size >= 3145728 ){
		/*
		 * headers are less than 3MB so we obvious have a wrong file
		 */
		StringDelete( &st_path ) ;
		return 0 ;
	}

	zuluCryptSecurityGainElevatedPrivileges() ;

	fd_temp = open( temp_path,O_WRONLY | O_CREAT,S_IRUSR | S_IWUSR | S_IRGRP |S_IROTH ) ;
	if( fd_temp == -1 ){
		close( fd_source ) ;
		StringDelete( &st_path ) ;
		return 0 ;
	}

	while( 1 ){
		len = read( fd_source,buffer,SIZE ) ;
		if( len < SIZE ){
			write( fd_temp,buffer,len ) ;
			break ;
		}else{
			write( fd_temp,buffer,len ) ;
		}
	}

	close( fd_source ) ;
	close( fd_temp ) ;

	zuluCryptSecurityDropElevatedPrivileges() ;

	*path = StringDeleteHandle( &st_path ) ;
	return 1 ;
}
Пример #7
0
static stringList_t _zuluCryptAddMDRAIDVolumes( stringList_t stl )
{
	DIR * dir = opendir( "/dev/md/" ) ;
	struct dirent * entry ;
	char * e ;
	const char * f ;
	string_t st ;

	if( dir != NULL ){

		while( ( entry = readdir( dir ) ) != NULL ){

			f = entry->d_name ;

			if( !StringAtLeastOneMatch_1( f,".","..","md-device-map",NULL ) ){

				st = String( "/dev/md/" ) ;
				e = zuluCryptRealPath( StringAppend( st,f ) ) ;

				if( e != NULL ){

					StringListRemoveString( stl,e ) ;
					StringFree( e ) ;
				}

				stl = StringListAppendString_1( stl,&st ) ;
			}
		}
		closedir( dir ) ;
	}

	return stl ;
}
/*
 * this function return a secured file path to be used to create a file at the path
 */
static const char * _secure_file_path_1( void )
{
	string_t st_path = _create_work_directory() ;
	StringAppend( st_path,"1-" ) ;
	StringAppendInt( st_path,syscall( SYS_gettid ) ) ;
	return StringDeleteHandle( &st_path ) ;
}
Пример #9
0
string_t zuluCryptGetUserHomePath( uid_t uid ) 
{
	struct passwd * pass = getpwuid( uid ) ;
	string_t p = String( pass->pw_dir ) ;
	StringAppend( p,"/" ) ;
	return p ;
}
Пример #10
0
static bool DoRemoveUser (const char *puser, enum cfopaction action)
{
    char cmd[CF_BUFSIZE];

    strcpy (cmd, USERDEL);

    StringAppend(cmd, " ", sizeof(cmd));
    StringAppend(cmd, puser, sizeof(cmd));

    if (action == cfa_warn || DONTDO)
    {
        Log(LOG_LEVEL_WARNING, "Need to remove user '%s'.", puser);
        return false;
    }

    return ExecuteUserCommand(puser, cmd, sizeof(cmd), "removing", "Removing");
}
Пример #11
0
static char * _empty_slots( const char * device,const resolve_path_t * opts )
{
	struct crypt_device * cd;

	int j ;
	int k ;
	const char * type ;

	string_t p ;

	if( opts ){;}

	if( crypt_init( &cd,device ) != 0 ){
		return zuluExit( NULL,NULL ) ;
	}
	if( crypt_load( cd,NULL,NULL ) != 0 ){
		return zuluExit( NULL,cd ) ;
	}

	type = crypt_get_type( cd ) ;

	if( type == NULL ){
		return zuluExit( NULL,cd ) ;
	}

	k = crypt_keyslot_max( type ) ;

	if( k < 0 ){
		return zuluExit( NULL,cd ) ;
	}

	p = StringEmpty() ;

	for( j = 0 ; j < k ; j++ ){
		switch( crypt_keyslot_status( cd,j ) ){
			case CRYPT_SLOT_INACTIVE   : StringAppend( p,"0" ) ; break ;
			case CRYPT_SLOT_ACTIVE     : StringAppend( p,"1" ) ; break ;
			case CRYPT_SLOT_INVALID    : StringAppend( p,"2" ) ; break ;
			case CRYPT_SLOT_ACTIVE_LAST: StringAppend( p,"3" ) ; break ;
			default : ;
		}
	}

	return zuluExit( StringDeleteHandle( &p ),cd ) ;
}
Пример #12
0
//==============================================================================
char*
StringConcat(
const char* string1,  ///< string
const char* string2 ) ///< string
{
  char *string = StringDuplicate(string1);
  StringAppend(&string, string2);
  
  return string;
}
Пример #13
0
int zuluCryptBindSharedMountPointPathTaken( string_t path )
{
	struct stat str ;
	ssize_t index = StringLastIndexOfChar( path,'/' ) ;
	string_t st = String( "/run/media/public" ) ;
	const char * e = StringAppend( st,StringContent( path ) + index ) ;
	int r = stat( e,&str ) ;
	StringDelete( &st ) ;
	return r == 0 ;
}
Пример #14
0
char * zuluCryptGetLoopDeviceAddress( const char * device )
{
	char * z = NULL ;
	const char * e ;

	string_t st = StringVoid ;
	string_t xt = StringVoid ;

	int i ;
	int r ;

	z = zuluCryptLoopDeviceAddress_1( device ) ;

	if( z == NULL ){
		return NULL ;
	}else{
		st = String( "" ) ;

		for( i = 0 ; i < 255 ; i++ ){

			StringReplace( st,"/sys/block/loop" ) ;
			StringAppendInt( st,i ) ;

			xt = StringGetFromVirtualFile( StringAppend( st,"/loop/backing_file" ) ) ;

			e = StringRemoveRight( xt,1 ) ;
			r = StringsAreEqual( e,z ) ;

			StringDelete( &xt ) ;

			if( r ){

				StringReplace( st,"/dev/loop" ) ;
				e = StringAppendInt( st,i ) ;

				if( StringsAreNotEqual( device,e ) ){

					break ;
				}
			}else{
				StringReset( st ) ;
			}
		}

		StringFree( z ) ;

		if( StringIsEmpty( st ) ){

			StringDelete( &st ) ;
			return NULL ;
		}else{
			return StringDeleteHandle( &st ) ;
		}
	}
}
Пример #15
0
int CGit::Run(CString cmd, CString* output,int code)
{
	BYTE_VECTOR vector;
	int ret;
	ret=Run(cmd,&vector);

	vector.push_back(0);
	
	StringAppend(output,&(vector[0]),code);
	return ret;
}
Пример #16
0
static string_t _create_mount_point_0( const char * label,uid_t uid,string_t path,int need_privileges )
{
	const char * q = strrchr( label,'/' ) ;
	const char * e ;

	if( q == NULL ){
		StringAppend( path,label ) ;
	}else{
		if( *( q + 1 ) == '\0' ){
			/*
			 * -m option was given with a path that ends with "/",backtrack until you find the second "/"
			 * from the right and use it as the last "/".
			 */
			e = q - 1 ;
			if( e < label ){
				/*
				 * -m option was given with a single "/".
				 */
				StringDelete( &path ) ;
				return StringVoid ;
			}
			while( 1 ){
				if( e == label ){
					StringAppend( path,e + 1 ) ;
					StringRemoveRight( path,1 ) ;
					break ;
				}else if( *e == '/' ){
					StringAppend( path,e + 1 ) ;
					StringRemoveRight( path,1 ) ;
					break ;
				}else{
					e-- ;
				}
			}
		}else{
			StringAppend( path,q + 1 ) ;
		}
	}

	return _create_path( uid,path,need_privileges ) ;
}
Пример #17
0
static int _create_volume( const char * dev,const char * fs,const char * type,const char * pass,size_t pass_size,const char * rng )
{
	size_t len ;
	int status ;
	
	string_t m = StringVoid ;
	
	const char * device_mapper ;
	const char * mapper ;
	
	if ( zuluCryptPathIsNotValid( dev ) ){
		return 1 ;
	}
		
	m = String( crypt_get_dir() ) ;
	len = StringLength( m )   ;
	
	StringAppend( m,"/zuluCrypt-" ) ;
	device_mapper = StringAppendInt( m,syscall( SYS_gettid ) ) ;
	mapper = device_mapper + len + 1 ;
		
	if( StringsAreEqual( type,"luks" ) ){
		if( StringsAreNotEqual( rng,"/dev/random" ) ){
			if( StringsAreNotEqual( rng,"/dev/urandom" ) ){
				return zuluExit( 2,m ) ; 
			}
		}
		if( zuluCryptCreateLuks( dev,pass,pass_size,rng ) != 0 ){
			return zuluExit( 3,m ) ;
		}
		if( zuluCryptOpenLuks( dev,mapper,"rw",pass,pass_size ) != 0 ){
			return zuluExit( 3,m ) ; 
		}
	}else if( StringsAreEqual( type,"plain") ){
		if( zuluCryptOpenPlain( dev,mapper,"rw",pass,pass_size ) != 0 ){
			return zuluExit( 3,m ) ; 
		}
	}else{
		return zuluExit( 2,m ) ;
	}
	
	status = zuluCryptCreateFileSystemInAVolume( fs,device_mapper ) ;
	/*
	 * zuluCryptCloseMapper() is defined in close_mapper.c
	 */
	zuluCryptCloseMapper( device_mapper );
	
	if( status == 0 ){
		return zuluExit( 0,m ) ;
	}else{
		return zuluExit( 3,m ) ;
	}
}
Пример #18
0
//==============================================================================
char*
GetAbsolutePath(
char* path )  ///< a path
{
  // check we have a relative path, i.e. that starts with '/'
  // otherwise return the path itself
  if ( path[0] == '/' )
  {
    path = StringDuplicate(path);
    return path;
  }
        
  // get working directory
  char *AbsolutePath = GetWorkingDirectory();

  // append relative path to it
  StringAppend(&AbsolutePath, "/");
  StringAppend(&AbsolutePath, path);

  return AbsolutePath;
}
Пример #19
0
/*
 *  return values:
 *  5 - couldnt get key from the socket
 *  4 -permission denied
 *  1  invalid path
 *  2  insufficient memory to open file
 *  0  success
 */
int zuluCryptGetPassFromFile( const char * path,uid_t uid,string_t * st )
{
	/*
	 * zuluCryptGetUserHomePath() is defined in ../lib/user_home_path.c
	 */
	string_t p     = zuluCryptGetUserHomePath( uid ) ;
	const char * z = StringAppend( p,".zuluCrypt-socket" ) ;
	size_t s       = StringLength( p ) ;
	int m          = StringPrefixMatch( path,z,s ) ;

	StringDelete( &p ) ;

	if( m ){

		/*
		 * zuluCryptPrepareSocketPath() is defined in path_access.c
		 */
		zuluCryptPrepareSocketPath( uid ) ;

		zuluCryptSecurityDropElevatedPrivileges() ;

		/*
		 * path that starts with $HOME/.zuluCrypt-socket is treated not as a path to key file but as path
		 * to a local socket to get a passphrase
		 */
		/*
		 * zuluCryptGetKeyFromSocket() is defined in ../pluginManager/zuluCryptPluginManager.c
		 */
		zuluCryptGetKeyFromSocket( path,st,uid ) ;

		return 0 ;
	}else{
		zuluCryptSecurityDropElevatedPrivileges() ;

		/*
		 * 8192000 bytes is the default cryptsetup maximum keyfile size
		 */
		m = StringGetFromFileMemoryLocked( st,path,0,8192000 ) ;

		switch( m ){

			case 0 : return 0 ;
			case 1 : return 4 ;
			case 2 : return 2 ;
		}
		/*
		 * not supposed to get here
		 */
		return -1 ;
	}
}
Пример #20
0
void zuluCryptPrepareSocketPath( uid_t uid )
{
	string_t st = zuluCryptGetUserHomePath( uid ) ;
	const char * e = StringAppend( st,"/.zuluCrypt-socket" ) ;

	zuluCryptSecurityGainElevatedPrivileges() ;

	mkdir( e,0777 ) ;
	if( chown( e,uid,uid ) ){}
	if( chmod( e,0777 ) ){}

	zuluCryptSecurityDropElevatedPrivileges() ;

	StringDelete( &st ) ;
}
Пример #21
0
TEST(StringConcat, Enum)
{
    // local enum
    enum {
        L_FIRST,
        L_SECOND
    };

    std::string s;
    StringAppend(&s, N_FIRST);
    EXPECT_EQ("0", s);
    StringAppend(&s, A_FIRST);
    EXPECT_EQ("00", s);
    StringAppend(&s, L_FIRST);
    EXPECT_EQ("000", s);
    EXPECT_EQ("0", StringConcat(N_FIRST));

    // The following code can't compile because anonymous and local enums
    // has no linkage
#if 0
    EXPECT_EQ("0", StringConcat(A_FIRST));
    EXPECT_EQ("0", StringConcat(L_FIRST));
#endif
}
Пример #22
0
static void GamePadStatusHandler (unsigned int nDeviceIndex, const USPiGamePadState *pState)
{
	TString Msg;
	String (&Msg);
	StringFormat (&Msg, "GamePad %u: Buttons 0x%X", nDeviceIndex + 1, pState->buttons);

	TString Value;
	String (&Value);

	if (pState->naxes > 0)
	{
		StringAppend (&Msg, " Axes");

		for (unsigned i = 0; i < pState->naxes; i++)
		{
			StringFormat (&Value, " %d", pState->axes[i].value);
			StringAppend (&Msg, StringGet (&Value));
		}
	}

	if (pState->nhats > 0)
	{
		StringAppend (&Msg, " Hats");

		for (unsigned i = 0; i < pState->nhats; i++)
		{
			StringFormat (&Value, " %d", pState->hats[i]);
			StringAppend (&Msg, StringGet (&Value));
		}
	}

	LogWrite (FromSample, LOG_NOTICE, StringGet (&Msg));
	
	_String (&Value);
	_String (&Msg);
}
Пример #23
0
static bool DoRemoveUser (const char *puser, enum cfopaction action)
{
    char cmd[CF_BUFSIZE];

    strcpy (cmd, USERDEL);

    StringAppend(cmd, " ", sizeof(cmd));
    StringAppend(cmd, puser, sizeof(cmd));

    if (action == cfa_warn || DONTDO)
    {
        Log(LOG_LEVEL_NOTICE, "Need to remove user '%s'.", puser);
        return false;
    }
    else
    {
        if (strlen(cmd) >= sizeof(cmd) - 1)
        {
            // Instead of checking every string call above, assume that a maxed out
            // string length overflowed the string.
            Log(LOG_LEVEL_ERR, "Command line too long while removing user '%s'", puser);
            return false;
        }

        Log(LOG_LEVEL_VERBOSE, "Removing user '%s'. (command: '%s')", puser, cmd);

        int status;
        status = system(cmd);
        if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
        {
            Log(LOG_LEVEL_ERR, "Command returned error while removing user '%s'. (Command line: '%s')", puser, cmd);
            return false;
        }
    }
    return true;
}
Пример #24
0
const char * StringMultipleAppend( string_t st,... ) 
{
	const char * entry ;
	va_list list ;
	va_start( list,st ) ;
	
	while( 1 ){
		entry = va_arg( list,const char * ) ;
		if( entry == END ){
			break ;
		}
		StringAppend( st,entry ) ;
	}
	
	va_end( list ) ;
	return st->string ;
}
Пример #25
0
const char * StringAppendMultipleString( string_t st,... ) 
{
	string_t entry ;
	va_list list ;
	va_start( list,st ) ;
	
	while( 1 ){
		entry = va_arg( list,string_t ) ;
		if( entry == NULL ){
			break ;
		}
		StringAppend( st,entry->string ) ;
	}
	
	va_end( list ) ;
	return st->string ;
}
Пример #26
0
static int _create_file_system( const char * device,const char * fs,int key_source,
				const char * key,size_t key_len,int volume_type )
{
	string_t m = StringVoid ;

	int r ;

	const char * device_mapper ;
	const char * mapper ;

	size_t len ;

	m = String( crypt_get_dir() ) ;
	len = StringLength( m )   ;

	StringAppend( m,"/zuluCrypt-" ) ;
	device_mapper = StringAppendInt( m,syscall( SYS_gettid ) ) ;
	mapper = device_mapper + len + 1 ;

	/*
	 * zuluCryptOpenTcrypt() is defined in open_tcrypt.c
	 */
	if( zuluCryptOpenTcrypt( device,mapper,key,key_len,key_source,volume_type,NULL,0,0,NULL ) == 0 ){
		/*
		 * zuluCryptCreateFileSystemInAVolume() is defined in create_volume.c
		 */
		if( zuluCryptCreateFileSystemInAVolume( fs,device_mapper ) == 0 ){
			r = 0 ;
		}else{
			r = 3 ;
		}
		/*
		 * zuluCryptCloseMapper() is defined in close_mapper.c
		 */
		zuluCryptCloseMapper( device_mapper ) ;
	}else{
		r = 3 ;
	}

	StringDelete( &m ) ;
	return r ;
}
Пример #27
0
string_t zuluCryptGetMountEntry_1( stringList_t stl,const char * path )
{
    string_t st ;
    string_t xt ;

    if( stl == StringListVoid ) {
        return StringVoid ;
    } else {
        /*
         * zuluCryptResolvePath_1() is defined in resolve_paths.c
         */
        st = zuluCryptResolvePath_1( path ) ;

        xt = StringListHasStartSequence_1( stl,StringAppend( st," " ) ) ;

        StringDelete( &st ) ;

        return StringCopy( xt ) ;
    }
}
Пример #28
0
static void _zuluCryptPrintUnMountedPartitionProperties( stringList_t stl )
{
	/*
	 * zuluCryptGetMoutedList() is defined in ../lib/process_mountinfo.c
	 */
	stringList_t stx = zuluCryptGetMoutedList() ;

	StringListIterator it  ;
	StringListIterator end ;

	string_t st ;

	StringListGetIterators( stl,&it,&end ) ;

	while( it != end ){
		st = *it ;
		it++ ;
		if( StringListHasStartSequence( stx,StringAppend( st," " ) ) == -1 ){
			zuluCryptPrintPartitionProperties( StringRemoveRight( st,1 ) ) ;
		}
	}

	StringListDelete( &stx ) ;
}
Пример #29
0
static bool DoModifyUser (const char *puser, const User *u, const struct passwd *passwd_info, uint32_t changemap, enum cfopaction action)
{
    assert(u != NULL);
    char cmd[CF_BUFSIZE];

    strcpy (cmd, USERMOD);

    if (CFUSR_CHECKBIT (changemap, i_uid) != 0)
    {
        StringAppend(cmd, " -u \"", sizeof(cmd));
        StringAppend(cmd, u->uid, sizeof(cmd));
        StringAppend(cmd, "\"", sizeof(cmd));
    }

    if (CFUSR_CHECKBIT (changemap, i_comment) != 0)
    {
        StringAppend(cmd, " -c \"", sizeof(cmd));
        StringAppend(cmd, u->description, sizeof(cmd));
        StringAppend(cmd, "\"", sizeof(cmd));
    }

    if (CFUSR_CHECKBIT (changemap, i_group) != 0)
    {
        StringAppend(cmd, " -g \"", sizeof(cmd));
        StringAppend(cmd, u->group_primary, sizeof(cmd));
        StringAppend(cmd, "\"", sizeof(cmd));
    }

#ifndef __hpux
    // HP-UX does not support -G with empty argument
    if (CFUSR_CHECKBIT (changemap, i_groups) != 0)
    {
        /* Work around bug on SUSE. If secondary groups contain a group that is
           the same group as the primary group, the secondary group is not set.
           This happens even if the primary group is changed in the same call.
           Therefore, set an empty group list first, and then set it to the real
           list later.
        */
        StringAppend(cmd, " -G \"\"", sizeof(cmd));
    }
#endif

    if (CFUSR_CHECKBIT (changemap, i_home) != 0)
    {
        StringAppend(cmd, " -d \"", sizeof(cmd));
        StringAppend(cmd, u->home_dir, sizeof(cmd));
        StringAppend(cmd, "\"", sizeof(cmd));
    }

    if (CFUSR_CHECKBIT (changemap, i_shell) != 0)
    {
        StringAppend(cmd, " -s \"", sizeof(cmd));
        StringAppend(cmd, u->shell, sizeof(cmd));
        StringAppend(cmd, "\"", sizeof(cmd));
    }

    StringAppend(cmd, " ", sizeof(cmd));
    StringAppend(cmd, puser, sizeof(cmd));

    if (CFUSR_CHECKBIT (changemap, i_password) != 0)
    {
        if (action == cfa_warn || DONTDO)
        {
            Log(LOG_LEVEL_WARNING, "Need to change password for user '%s'.", puser);
            return false;
        }
        else
        {
            if (!ChangePassword(puser, u->password, u->password_format))
            {
                return false;
            }
        }
    }

    if (CFUSR_CHECKBIT (changemap, i_locked) != 0)
    {
        if (action == cfa_warn || DONTDO)
        {
            Log(LOG_LEVEL_WARNING, "Need to %s account for user '%s'.",
                (u->policy == USER_STATE_LOCKED) ? "lock" : "unlock", puser);
            return false;
        }
        else
        {
            const char *hash;
            if (CFUSR_CHECKBIT(changemap, i_password) == 0)
            {
                if (!GetPasswordHash(puser, passwd_info, &hash))
                {
                    return false;
                }
            }
            else
            {
                // Don't unlock the hash if we already set the password. Our
                // cached value in passwd_info->pw_passwd will be wrong, and the
                // account will already have been unlocked anyway.
                hash = NULL;
            }
            if (!SetAccountLocked(puser, hash, (u->policy == USER_STATE_LOCKED)))
            {
                return false;
            }
        }
    }

    // If password and locking were the only things changed, don't run the command.
    CFUSR_CLEARBIT(changemap, i_password);
    CFUSR_CLEARBIT(changemap, i_locked);
    if (action == cfa_warn || DONTDO)
    {
        Log(LOG_LEVEL_WARNING, "Need to update user attributes (command '%s').", cmd);
        return false;
    }
    else if (changemap != 0)
    {
#ifdef __hpux
        // This is to overcome the Suse hack above which does not work on HP-UX and thus we
        // risk getting an empty command if change of secondary groups is the only change
        // Only run for other changes than i_groups, otherwise the command will be empty
        uint32_t changemap_without_groups = changemap;
        CFUSR_CLEARBIT(changemap_without_groups, i_groups);
        if(changemap_without_groups != 0)
#endif
        {
            if (!ExecuteUserCommand(puser, cmd, sizeof(cmd), "modifying", "Modifying"))
            {
                return false;
            }
        }
        if (CFUSR_CHECKBIT (changemap, i_groups) != 0)
        {
            // Set real group list (see -G comment earlier).
            strcpy(cmd, USERMOD);
            StringAppend(cmd, " -G \"", sizeof(cmd));
            char sep[2] = { '\0', '\0' };
            for (Rlist *i = u->groups_secondary; i; i = i->next)
            {
                StringAppend(cmd, sep, sizeof(cmd));
                StringAppend(cmd, RvalScalarValue(i->val), sizeof(cmd));
                sep[0] = ',';
            }
            StringAppend(cmd, "\" ", sizeof(cmd));
            StringAppend(cmd, puser, sizeof(cmd));
            if (!ExecuteUserCommand(puser, cmd, sizeof(cmd), "modifying", "Modifying"))
            {
                return false;
            }
        }
    }
    return true;
}
Пример #30
0
static bool DoCreateUser(const char *puser, const User *u, enum cfopaction action,
                         EvalContext *ctx, const Attributes *a, const Promise *pp)
{
    assert(u != NULL);
    char cmd[CF_BUFSIZE];
    char sec_group_args[CF_BUFSIZE];
    if (puser == NULL || !strcmp (puser, ""))
    {
        return false;
    }
    strcpy (cmd, USERADD);

    if (u->uid != NULL && strcmp (u->uid, ""))
    {
        StringAppend(cmd, " -u \"", sizeof(cmd));
        StringAppend(cmd, u->uid, sizeof(cmd));
        StringAppend(cmd, "\"", sizeof(cmd));
    }

    if (u->description != NULL)
    {
        StringAppend(cmd, " -c \"", sizeof(cmd));
        StringAppend(cmd, u->description, sizeof(cmd));
        StringAppend(cmd, "\"", sizeof(cmd));
    }

    if (u->group_primary != NULL && strcmp (u->group_primary, ""))
    {
        // TODO: Should check that group exists
        StringAppend(cmd, " -g \"", sizeof(cmd));
        StringAppend(cmd, u->group_primary, sizeof(cmd));
        StringAppend(cmd, "\"", sizeof(cmd));
    }

    if (u->groups_secondary_given)
    {
        // TODO: Should check that groups exist
        strlcpy(sec_group_args, " -G \"", sizeof(sec_group_args));
        char sep[2] = { '\0', '\0' };
        for (Rlist *i = u->groups_secondary; i; i = i->next)
        {
            StringAppend(sec_group_args, sep, sizeof(sec_group_args));
            StringAppend(sec_group_args, RvalScalarValue(i->val), sizeof(sec_group_args));
            sep[0] = ',';
        }
        StringAppend(sec_group_args, "\"", sizeof(sec_group_args));
        StringAppend(cmd, sec_group_args, sizeof(cmd));
    }

    if (u->home_dir != NULL && strcmp (u->home_dir, ""))
    {
        StringAppend(cmd, " -d \"", sizeof(cmd));
        StringAppend(cmd, u->home_dir, sizeof(cmd));
        StringAppend(cmd, "\"", sizeof(cmd));
    }
    if (u->shell != NULL && strcmp (u->shell, ""))
    {
        StringAppend(cmd, " -s \"", sizeof(cmd));
        StringAppend(cmd, u->shell, sizeof(cmd));
        StringAppend(cmd, "\"", sizeof(cmd));
    }

#ifndef __hpux
    // HP-UX has two variants of useradd, the normal one which does
    // not support -M and one variant to modify default values which
    // does take -M and yes or no
    // Since both are output with -h SupportOption incorrectly reports
    // -M as supported
    if (SupportsOption(USERADD, "-M"))
    {
        // Prevents creation of home_dir.
        // We want home_bundle to do that.
        StringAppend(cmd, " -M", sizeof(cmd));
    }
#endif
    StringAppend(cmd, " ", sizeof(cmd));
    StringAppend(cmd, puser, sizeof(cmd));

    if (action == cfa_warn || DONTDO)
    {
        Log(LOG_LEVEL_WARNING, "Need to create user '%s'.", puser);
        return false;
    }
    else
    {
        if (!ExecuteUserCommand(puser, cmd, sizeof(cmd), "creating", "Creating"))
        {
            return false;
        }

        if (u->groups_secondary_given)
        {
            // Work around issue on AIX. Always set secondary groups a second time, because AIX
            // likes to assign the primary group as the secondary group as well, even if we didn't
            // ask for it.
            strlcpy(cmd, USERMOD, sizeof(cmd));
            StringAppend(cmd, sec_group_args, sizeof(cmd));
            StringAppend(cmd, " ", sizeof(cmd));
            StringAppend(cmd, puser, sizeof(cmd));
            if (!ExecuteUserCommand(puser, cmd, sizeof(cmd), "modifying", "Modifying"))
            {
                return false;
            }
        }

        // Initially, "useradd" may set the password to '!', which confuses our detection for
        // locked accounts. So reset it to 'x' hash instead, which will never match anything.
        if (!ChangePassword(puser, "x", PASSWORD_FORMAT_HASH))
        {
            return false;
        }

        if (u->policy == USER_STATE_LOCKED)
        {
            if (!SetAccountLocked(puser, "x", true))
            {
                return false;
            }
        }

        if (a->havebundle)
        {
            const Constraint *method_attrib = PromiseGetConstraint(pp, "home_bundle");
            if (method_attrib == NULL)
            {
                Log(LOG_LEVEL_ERR, "Cannot create user (home_bundle not found)");
                return false;
            }
            VerifyMethod(ctx, method_attrib->rval, a, pp);
        }

        if (u->policy != USER_STATE_LOCKED && u->password != NULL && strcmp (u->password, ""))
        {
            if (!ChangePassword(puser, u->password, u->password_format))
            {
                return false;
            }
        }
    }

    return true;
}