@@ -62,9 +62,6 @@ pub enum Error {
62
62
63
63
#[ snafu( display( "failed to write request" ) ) ]
64
64
WriteRequest { source : std:: io:: Error } ,
65
-
66
- #[ snafu( display( "failed to obtain stdin for child process" ) ) ]
67
- ChildStdin ,
68
65
}
69
66
70
67
/// Provisions a Kerberos Keytab based on the [`Request`].
@@ -86,7 +83,7 @@ pub async fn provision_keytab(krb5_config_path: &Path, req: &Request) -> Result<
86
83
// TGT that is obtained for the operation in the memory of the short lives process
87
84
// spawned by `Command::new` above - this way it'll be wiped from memory once this exits
88
85
// 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)
90
87
. env ( "KRB5CCNAME" , "MEMORY:" )
91
88
. stdin ( Stdio :: piped ( ) )
92
89
. stdout ( Stdio :: piped ( ) )
@@ -96,7 +93,10 @@ pub async fn provision_keytab(krb5_config_path: &Path, req: &Request) -> Result<
96
93
// Get a `ChildStdin` object for the spawned process and write the serialized request
97
94
// for a Principal into it in order for the child process to deserialize it and
98
95
// 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! " ) ;
100
100
stdin. write_all ( & req_str) . await . context ( WriteRequestSnafu ) ?;
101
101
stdin. flush ( ) . await . context ( WriteRequestSnafu ) ?;
102
102
drop ( stdin) ;
@@ -110,11 +110,21 @@ pub async fn provision_keytab(krb5_config_path: &Path, req: &Request) -> Result<
110
110
. await
111
111
. context ( WaitProvisionerSnafu ) ?;
112
112
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
+ }
120
130
}
0 commit comments