5454#include <csv_writer.h>
5555#include <cf-agent-enterprise-stubs.h>
5656#include <cf-windows-functions.h>
57+ #include <cf3.defs.h>
5758
5859/* Called structure:
5960
@@ -115,7 +116,7 @@ static PromiseResult VerifyPromisedPatch(EvalContext *ctx, const Attributes *a,
115116
116117static char * GetDefaultArch (const char * command );
117118
118- static bool ExecPackageCommand (EvalContext * ctx , char * command , int verify , int setCmdClasses , const Attributes * a , const Promise * pp , PromiseResult * result );
119+ static bool ExecPackageCommand (EvalContext * ctx , const char * command , int verify , int setCmdClasses , const Attributes * a , const Promise * pp , PromiseResult * result );
119120
120121static bool PrependPatchItem (EvalContext * ctx , PackageItem * * list , char * item , PackageItem * chklist , const char * default_arch , const Attributes * a , const Promise * pp );
121122static bool PrependMultiLinePackageItem (EvalContext * ctx , PackageItem * * list , char * item , int reset , const char * default_arch , const Attributes * a , const Promise * pp );
@@ -2578,35 +2579,9 @@ static bool ExecuteSchedule(EvalContext *ctx, const PackageManager *schedule, Pa
25782579 continue ;
25792580 }
25802581
2581- size_t estimated_size = 0 ;
2582-
2583- for (const PackageItem * pi = pm -> pack_list ; pi != NULL ; pi = pi -> next )
2584- {
2585- size_t size = strlen (pi -> name ) + strlen (" " );
2586-
2587- switch (pm -> policy )
2588- {
2589- case PACKAGE_ACTION_POLICY_INDIVIDUAL :
2590-
2591- if (size > estimated_size )
2592- {
2593- estimated_size = size + CF_MAXVARSIZE ;
2594- }
2595- break ;
2596-
2597- case PACKAGE_ACTION_POLICY_BULK :
2598-
2599- estimated_size += size + CF_MAXVARSIZE ;
2600- break ;
2601-
2602- default :
2603- break ;
2604- }
2605- }
2606-
26072582 const Promise * const pp = pm -> pack_list -> pp ;
26082583 Attributes a = GetPackageAttributes (ctx , pp );
2609- char * command_string = NULL ;
2584+ Buffer * command_buffer = BufferNew () ;
26102585
26112586 switch (action )
26122587 {
@@ -2617,14 +2592,12 @@ static bool ExecuteSchedule(EvalContext *ctx, const PackageManager *schedule, Pa
26172592 if (a .packages .package_add_command == NULL )
26182593 {
26192594 ProgrammingError ("Package add command undefined" );
2595+ BufferDestroy (command_buffer );
26202596 return false;
26212597 }
26222598
26232599 Log (LOG_LEVEL_INFO , "Installing %-.39s..." , pp -> promiser );
2624-
2625- estimated_size += strlen (a .packages .package_add_command ) + 2 ;
2626- command_string = xmalloc (estimated_size );
2627- strcpy (command_string , a .packages .package_add_command );
2600+ BufferAppendString (command_buffer , a .packages .package_add_command );
26282601 break ;
26292602
26302603 case PACKAGE_ACTION_DELETE :
@@ -2634,14 +2607,12 @@ static bool ExecuteSchedule(EvalContext *ctx, const PackageManager *schedule, Pa
26342607 if (a .packages .package_delete_command == NULL )
26352608 {
26362609 ProgrammingError ("Package delete command undefined" );
2610+ BufferDestroy (command_buffer );
26372611 return false;
26382612 }
26392613
26402614 Log (LOG_LEVEL_INFO , "Deleting %-.39s..." , pp -> promiser );
2641-
2642- estimated_size += strlen (a .packages .package_delete_command ) + 2 ;
2643- command_string = xmalloc (estimated_size );
2644- strcpy (command_string , a .packages .package_delete_command );
2615+ BufferAppendString (command_buffer , a .packages .package_delete_command );
26452616 break ;
26462617
26472618 case PACKAGE_ACTION_UPDATE :
@@ -2651,14 +2622,12 @@ static bool ExecuteSchedule(EvalContext *ctx, const PackageManager *schedule, Pa
26512622 if (a .packages .package_update_command == NULL )
26522623 {
26532624 ProgrammingError ("Package update command undefined" );
2625+ BufferDestroy (command_buffer );
26542626 return false;
26552627 }
26562628
26572629 Log (LOG_LEVEL_INFO , "Updating %-.39s..." , pp -> promiser );
2658-
2659- estimated_size += strlen (a .packages .package_update_command ) + 2 ;
2660- command_string = xcalloc (1 , estimated_size );
2661- strcpy (command_string , a .packages .package_update_command );
2630+ BufferAppendString (command_buffer , a .packages .package_update_command );
26622631 break ;
26632632
26642633 case PACKAGE_ACTION_VERIFY :
@@ -2668,33 +2637,32 @@ static bool ExecuteSchedule(EvalContext *ctx, const PackageManager *schedule, Pa
26682637 if (a .packages .package_verify_command == NULL )
26692638 {
26702639 ProgrammingError ("Package verify command undefined" );
2640+ BufferDestroy (command_buffer );
26712641 return false;
26722642 }
26732643
2674- estimated_size += strlen (a .packages .package_verify_command ) + 2 ;
2675- command_string = xmalloc (estimated_size );
2676- strcpy (command_string , a .packages .package_verify_command );
2644+ BufferAppendString (command_buffer , a .packages .package_verify_command );
26772645
26782646 verify = true;
26792647 break ;
26802648
26812649 default :
26822650 ProgrammingError ("Unknown action attempted" );
2651+ BufferDestroy (command_buffer );
26832652 return false;
26842653 }
26852654
26862655 /* if the command ends with $ then we assume the package manager does not accept package names */
2687-
2688- if (* (command_string + strlen (command_string ) - 1 ) == '$' )
2656+ if (BufferData (command_buffer )[BufferSize (command_buffer ) - 1 ] == '$' )
26892657 {
2690- * ( command_string + strlen ( command_string ) - 1 ) = '\0' ;
2658+ BufferTrimToMaxLength ( command_buffer , BufferSize ( command_buffer ) - 1 );
26912659 Log (LOG_LEVEL_VERBOSE , "Command does not allow arguments" );
26922660 PromiseResult result = PROMISE_RESULT_NOOP ;
26932661
26942662 EvalContextStackPushPromiseFrame (ctx , pp );
26952663 if (EvalContextStackPushPromiseIterationFrame (ctx , NULL ))
26962664 {
2697- if (ExecPackageCommand (ctx , command_string , verify , true, & a , pp , & result ))
2665+ if (ExecPackageCommand (ctx , BufferData ( command_buffer ) , verify , true, & a , pp , & result ))
26982666 {
26992667 Log (LOG_LEVEL_VERBOSE , "Package schedule execution ok (outcome cannot be promised by cf-agent)" );
27002668 }
@@ -2711,9 +2679,9 @@ static bool ExecuteSchedule(EvalContext *ctx, const PackageManager *schedule, Pa
27112679 }
27122680 else
27132681 {
2714- strcat ( command_string , " " );
2682+ BufferAppendChar ( command_buffer , ' ' );
27152683
2716- Log (LOG_LEVEL_VERBOSE , "Command prefix '%s'" , command_string );
2684+ Log (LOG_LEVEL_VERBOSE , "Command prefix '%s'" , BufferData ( command_buffer ) );
27172685
27182686 if (pm -> policy == PACKAGE_ACTION_POLICY_INDIVIDUAL )
27192687 {
@@ -2723,15 +2691,14 @@ static bool ExecuteSchedule(EvalContext *ctx, const PackageManager *schedule, Pa
27232691 const Promise * const ppi = pi -> pp ;
27242692 Attributes a = GetPackageAttributes (ctx , ppi );
27252693
2726- const size_t command_len = strlen (command_string );
2727- char * offset = command_string + command_len ;
2694+ const size_t offset = BufferSize (command_buffer );
27282695
27292696 if ((a .packages .package_file_repositories ) && ((action == PACKAGE_ACTION_ADD ) || (action == PACKAGE_ACTION_UPDATE )))
27302697 {
27312698 const char * sp = PrefixLocalRepository (a .packages .package_file_repositories , pi -> name );
27322699 if (sp != NULL )
27332700 {
2734- strlcat ( offset , sp , estimated_size - command_len );
2701+ BufferAppendString ( command_buffer , sp );
27352702 }
27362703 else
27372704 {
@@ -2740,14 +2707,26 @@ static bool ExecuteSchedule(EvalContext *ctx, const PackageManager *schedule, Pa
27402707 }
27412708 else
27422709 {
2743- strcat (offset , pi -> name );
2710+ if (a .packages .package_commands_useshell )
2711+ {
2712+ /* Put single quotes around package name and escape
2713+ * any pre-existing single quotes to prevent shell
2714+ * injection. */
2715+ char * escaped = EscapeCharCopy (pi -> name , '\'' , '\\' );
2716+ BufferAppendF (command_buffer , "'%s'" , escaped );
2717+ free (escaped );
2718+ }
2719+ else
2720+ {
2721+ BufferAppendString (command_buffer , pi -> name );
2722+ }
27442723 }
27452724
27462725 PromiseResult result = PROMISE_RESULT_NOOP ;
27472726 EvalContextStackPushPromiseFrame (ctx , ppi );
27482727 if (EvalContextStackPushPromiseIterationFrame (ctx , NULL ))
27492728 {
2750- bool ok = ExecPackageCommand (ctx , command_string , verify , true, & a , ppi , & result );
2729+ bool ok = ExecPackageCommand (ctx , BufferData ( command_buffer ) , verify , true, & a , ppi , & result );
27512730
27522731 if (StringEqual (pi -> name , PACKAGE_IGNORED_CFE_INTERNAL ))
27532732 {
@@ -2770,7 +2749,7 @@ static bool ExecuteSchedule(EvalContext *ctx, const PackageManager *schedule, Pa
27702749
27712750 EvalContextLogPromiseIterationOutcome (ctx , ppi , result );
27722751
2773- * offset = '\0' ;
2752+ BufferTrimToMaxLength ( command_buffer , offset ) ;
27742753 }
27752754 }
27762755 else if (pm -> policy == PACKAGE_ACTION_POLICY_BULK )
@@ -2779,17 +2758,14 @@ static bool ExecuteSchedule(EvalContext *ctx, const PackageManager *schedule, Pa
27792758 {
27802759 if (pi -> name )
27812760 {
2782- const size_t command_len = strlen (command_string );
2783- char * offset = command_string + command_len ;
2784-
27852761 if (a .packages .package_file_repositories &&
27862762 (action == PACKAGE_ACTION_ADD ||
27872763 action == PACKAGE_ACTION_UPDATE ))
27882764 {
27892765 const char * sp = PrefixLocalRepository (a .packages .package_file_repositories , pi -> name );
27902766 if (sp != NULL )
27912767 {
2792- strlcpy ( offset , sp , estimated_size - command_len );
2768+ BufferAppendString ( command_buffer , sp );
27932769 }
27942770 else
27952771 {
@@ -2798,18 +2774,29 @@ static bool ExecuteSchedule(EvalContext *ctx, const PackageManager *schedule, Pa
27982774 }
27992775 else
28002776 {
2801- strcpy (offset , pi -> name );
2777+ if (a .packages .package_commands_useshell )
2778+ {
2779+ /* Put single quotes around package name and escape
2780+ * any pre-existing single quotes to prevent shell
2781+ * injection. */
2782+ char * escaped = EscapeCharCopy (pi -> name , '\'' , '\\' );
2783+ BufferAppendF (command_buffer , "'%s'" , escaped );
2784+ free (escaped );
2785+ }
2786+ else
2787+ {
2788+ BufferAppendString (command_buffer , pi -> name );
2789+ }
28022790 }
2803-
2804- strcat (command_string , " " );
2791+ BufferAppendChar (command_buffer , ' ' );
28052792 }
28062793 }
28072794
28082795 PromiseResult result = PROMISE_RESULT_NOOP ;
28092796 EvalContextStackPushPromiseFrame (ctx , pp );
28102797 if (EvalContextStackPushPromiseIterationFrame (ctx , NULL ))
28112798 {
2812- bool ok = ExecPackageCommand (ctx , command_string , verify , true, & a , pp , & result );
2799+ bool ok = ExecPackageCommand (ctx , BufferData ( command_buffer ) , verify , true, & a , pp , & result );
28132800
28142801 for (const PackageItem * pi = pm -> pack_list ; pi != NULL ; pi = pi -> next )
28152802 {
@@ -2837,10 +2824,7 @@ static bool ExecuteSchedule(EvalContext *ctx, const PackageManager *schedule, Pa
28372824 }
28382825 }
28392826
2840- if (command_string )
2841- {
2842- free (command_string );
2843- }
2827+ BufferDestroy (command_buffer );
28442828 }
28452829
28462830/* We have performed some modification operation on packages, our cache is invalid */
@@ -3245,14 +3229,14 @@ const char *PrefixLocalRepository(const Rlist *repositories, const char *package
32453229 return NULL ;
32463230}
32473231
3248- bool ExecPackageCommand (EvalContext * ctx , char * command , int verify , int setCmdClasses , const Attributes * a ,
3232+ bool ExecPackageCommand (EvalContext * ctx , const char * command , int verify , int setCmdClasses , const Attributes * a ,
32493233 const Promise * pp , PromiseResult * result )
32503234{
32513235 assert (a != NULL );
32523236 assert (pp != NULL ); // Dereferenced by cfPS macros
32533237
32543238 bool retval = true;
3255- char * cmd ;
3239+ const char * cmd ;
32563240 FILE * pfp ;
32573241 int packmanRetval = 0 ;
32583242
0 commit comments