@@ -62,9 +62,6 @@ pub enum Error {
6262
6363 #[ snafu( display( "failed to write request" ) ) ]
6464 WriteRequest { source : std:: io:: Error } ,
65-
66- #[ snafu( display( "failed to obtain stdin for child process" ) ) ]
67- ChildStdin ,
6865}
6966
7067/// Provisions a Kerberos Keytab based on the [`Request`].
@@ -86,7 +83,7 @@ pub async fn provision_keytab(krb5_config_path: &Path, req: &Request) -> Result<
8683 // TGT that is obtained for the operation in the memory of the short lives process
8784 // spawned by `Command::new` above - this way it'll be wiped from memory once this exits
8885 // With any shared or persistent ticket cache this might stick around and potentially be
89- // reused by later runs
86+ // reused by other volumes (which could cause privilege escalations and similar fun issues)
9087 . env ( "KRB5CCNAME" , "MEMORY:" )
9188 . stdin ( Stdio :: piped ( ) )
9289 . stdout ( Stdio :: piped ( ) )
@@ -96,7 +93,10 @@ pub async fn provision_keytab(krb5_config_path: &Path, req: &Request) -> Result<
9693 // Get a `ChildStdin` object for the spawned process and write the serialized request
9794 // for a Principal into it in order for the child process to deserialize it and
9895 // process the request
99- let mut stdin = child. stdin . take ( ) . context ( ChildStdinSnafu ) ?;
96+ let mut stdin = child
97+ . stdin
98+ . take ( )
99+ . expect ( "Failed to read from stdin of stackable-krb5-provision-keytab script! " ) ;
100100 stdin. write_all ( & req_str) . await . context ( WriteRequestSnafu ) ?;
101101 stdin. flush ( ) . await . context ( WriteRequestSnafu ) ?;
102102 drop ( stdin) ;
@@ -110,11 +110,21 @@ pub async fn provision_keytab(krb5_config_path: &Path, req: &Request) -> Result<
110110 . await
111111 . context ( WaitProvisionerSnafu ) ?;
112112
113- // Check for success of the operation by deserializing stdout of the process to a `Response`
114- // struct - since `Response` is an empty struct with no fields this effectively means that
115- // any output will fail to deserialize and cause an `Error::RunProvisioner` to be propagated
116- // with the output of the child process
117- serde_json:: from_slice :: < Result < Response , String > > ( & output. stdout )
118- . context ( DeserializeResponseSnafu ) ?
119- . map_err ( |msg| Error :: RunProvisioner { msg } )
113+ // Check if the spawned command returned 0 as return code
114+ if output. status . success ( ) {
115+ // Check for success of the operation by deserializing stdout of the process to a `Response`
116+ // struct - since `Response` is an empty struct with no fields this effectively means that
117+ // any output will fail to deserialize and cause an `Error::RunProvisioner` to be propagated
118+ // with the output of the child process
119+ serde_json:: from_slice :: < Result < Response , String > > ( & output. stdout )
120+ . context ( DeserializeResponseSnafu ) ?
121+ . map_err ( |msg| Error :: RunProvisioner { msg } )
122+ } else {
123+ Err ( Error :: RunProvisioner {
124+ msg : format ! (
125+ "Got non zero return code from stackable-krb5-provision-keytab: [{:?}]" ,
126+ output. status. code( )
127+ ) ,
128+ } )
129+ }
120130}
0 commit comments