@@ -71,24 +71,44 @@ pub async fn provision_keytab(krb5_config_path: &Path, req: &Request) -> Result<
7171 let req_str = serde_json:: to_vec ( & req) . context ( SerializeRequestSnafu ) ?;
7272
7373 let mut child = Command :: new ( "stackable-krb5-provision-keytab" )
74+ // make sure the process is killed if we error out of this fn somewhere due to
75+ // an error when writing to stdin or getting stdout
7476 . kill_on_drop ( true )
7577 . env ( "KRB5_CONFIG" , krb5_config_path)
7678 // ldap3 uses the default client keytab to authenticate to the LDAP server
7779 . env ( "KRB5_CLIENT_KTNAME" , & req. admin_keytab_path )
78- // avoid leaking credentials between secret volumes/secretclasses
80+ // avoid leaking credentials between secret volumes/secretclasses by only storing the
81+ // TGT that is obtained for the operation in the memory of the short lives process
82+ // spawned by `Command::new` above - this way it'll be wiped from memory once this exits
83+ // With any shared or persistent ticket cache this might stick around and potentially be
84+ // reused by later runs
7985 . env ( "KRB5CCNAME" , "MEMORY:" )
8086 . stdin ( Stdio :: piped ( ) )
8187 . stdout ( Stdio :: piped ( ) )
8288 . spawn ( )
8389 . context ( SpawnProvisionerSnafu ) ?;
90+
91+ // Get a `ChildStdin` object for the spawned process and write the serialized request
92+ // for a Principal into it in order for the child process to deserialize it and
93+ // process the request
8494 let mut stdin = child. stdin . take ( ) . unwrap ( ) ;
8595 stdin. write_all ( & req_str) . await . context ( WriteRequestSnafu ) ?;
8696 stdin. flush ( ) . await . context ( WriteRequestSnafu ) ?;
8797 drop ( stdin) ;
98+
99+ // Wait for the process to finish and capture output
100+ // This will always return Ok(...) regardless of exit code or output of the child process
101+ // Failure here means that something went wrong with connecting to the process or obtaining
102+ // exit code or output
88103 let output = child
89104 . wait_with_output ( )
90105 . await
91106 . context ( WaitProvisionerSnafu ) ?;
107+
108+ // Check for success of the operation by deserializing stdout of the process to a `Response`
109+ // struct - since `Response` is an empty struct with no fields this effectively means that
110+ // any output will fail to deserialize and cause an `Error::RunProvisioner` to be propagated
111+ // with the output of the child process
92112 serde_json:: from_slice :: < Result < Response , String > > ( & output. stdout )
93113 . context ( DeserializeResponseSnafu ) ?
94114 . map_err ( |msg| Error :: RunProvisioner { msg } )
0 commit comments