varlink: add new helper varlink_get_peer_pidref() for getting PidRef of peer
This commit is contained in:
@@ -171,6 +171,7 @@ struct Varlink {
|
||||
JsonVariant *current;
|
||||
VarlinkSymbol *current_method;
|
||||
|
||||
int peer_pidfd;
|
||||
struct ucred ucred;
|
||||
bool ucred_acquired:1;
|
||||
|
||||
@@ -361,6 +362,8 @@ static int varlink_new(Varlink **ret) {
|
||||
.timeout = VARLINK_DEFAULT_TIMEOUT_USEC,
|
||||
|
||||
.af = -1,
|
||||
|
||||
.peer_pidfd = -EBADF,
|
||||
};
|
||||
|
||||
*ret = v;
|
||||
@@ -638,6 +641,8 @@ static void varlink_clear(Varlink *v) {
|
||||
sigterm_wait(v->exec_pid);
|
||||
v->exec_pid = 0;
|
||||
}
|
||||
|
||||
v->peer_pidfd = safe_close(v->peer_pidfd);
|
||||
}
|
||||
|
||||
static Varlink* varlink_destroy(Varlink *v) {
|
||||
@@ -2591,6 +2596,54 @@ int varlink_get_peer_pid(Varlink *v, pid_t *ret) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int varlink_acquire_pidfd(Varlink *v) {
|
||||
assert(v);
|
||||
|
||||
if (v->peer_pidfd >= 0)
|
||||
return 0;
|
||||
|
||||
v->peer_pidfd = getpeerpidfd(v->fd);
|
||||
if (v->peer_pidfd < 0)
|
||||
return v->peer_pidfd;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int varlink_get_peer_pidref(Varlink *v, PidRef *ret) {
|
||||
int r;
|
||||
|
||||
assert_return(v, -EINVAL);
|
||||
assert_return(ret, -EINVAL);
|
||||
|
||||
/* Returns r > 0 if we acquired the pidref via SO_PEERPIDFD (i.e. if we can use it for
|
||||
* authentication). Returns == 0 if we didn't, and the pidref should not be used for
|
||||
* authentication. */
|
||||
|
||||
r = varlink_acquire_pidfd(v);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (v->peer_pidfd < 0) {
|
||||
pid_t pid;
|
||||
|
||||
r = varlink_get_peer_pid(v, &pid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = pidref_set_pid(ret, pid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return 0; /* didn't get pidfd securely */
|
||||
}
|
||||
|
||||
r = pidref_set_pidfd(ret, v->peer_pidfd);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return 1; /* got pidfd securely */
|
||||
}
|
||||
|
||||
int varlink_set_relative_timeout(Varlink *v, usec_t timeout) {
|
||||
assert_return(v, -EINVAL);
|
||||
assert_return(timeout > 0, -EINVAL);
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "sd-event.h"
|
||||
|
||||
#include "json.h"
|
||||
#include "pidref.h"
|
||||
#include "time-util.h"
|
||||
#include "varlink-idl.h"
|
||||
|
||||
@@ -139,6 +140,7 @@ void* varlink_get_userdata(Varlink *v);
|
||||
|
||||
int varlink_get_peer_uid(Varlink *v, uid_t *ret);
|
||||
int varlink_get_peer_pid(Varlink *v, pid_t *ret);
|
||||
int varlink_get_peer_pidref(Varlink *v, PidRef *ret);
|
||||
|
||||
int varlink_set_relative_timeout(Varlink *v, usec_t usec);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user