varlink: add new helper varlink_get_peer_pidref() for getting PidRef of peer

This commit is contained in:
Lennart Poettering
2024-01-02 17:57:35 +01:00
parent da5e0c442b
commit 0eccf7259e
2 changed files with 55 additions and 0 deletions
+53
View File
@@ -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);
+2
View File
@@ -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);