From f3cd454cd4de5787a70ee589ade6f56d42980558 Mon Sep 17 00:00:00 2001 From: Andrey Vagin Date: Wed, 30 Jan 2013 03:28:01 +0400 Subject: [PATCH] sk-unix: dump/restore a file permissions Signed-off-by: Andrey Vagin Signed-off-by: Pavel Emelyanov --- protobuf/sk-unix.proto | 8 ++++++++ sk-unix.c | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/protobuf/sk-unix.proto b/protobuf/sk-unix.proto index 9a18eaa5a..bbe25882d 100644 --- a/protobuf/sk-unix.proto +++ b/protobuf/sk-unix.proto @@ -1,6 +1,12 @@ import "fown.proto"; import "sk-opts.proto"; +message file_perms_entry { + required uint32 mode = 1; + required uint32 uid = 2; + required uint32 gid = 3; +} + message unix_sk_entry { /* * Few words about why we need both -- id and ino. @@ -31,4 +37,6 @@ message unix_sk_entry { required bytes name = 11; optional sk_shutdown shutdown = 12; + + optional file_perms_entry file_perms = 13; } diff --git a/sk-unix.c b/sk-unix.c index ce37dbc33..4905cd10d 100644 --- a/sk-unix.c +++ b/sk-unix.c @@ -37,6 +37,11 @@ struct unix_sk_desc { unsigned int nr_icons; unsigned int *icons; unsigned char shutdown; + + mode_t mode; + uid_t uid; + gid_t gid; + struct list_head list; }; @@ -108,6 +113,7 @@ static int dump_one_unix_fd(int lfd, u32 id, const struct fd_parms *p) struct unix_sk_desc *sk; UnixSkEntry ue = UNIX_SK_ENTRY__INIT; SkOptsEntry skopts = SK_OPTS_ENTRY__INIT; + FilePermsEntry perms = FILE_PERMS_ENTRY__INIT; sk = (struct unix_sk_desc *)lookup_socket(p->stat.st_ino, PF_UNIX); if (!sk) @@ -132,6 +138,14 @@ static int dump_one_unix_fd(int lfd, u32 id, const struct fd_parms *p) ue.opts = &skopts; ue.uflags = 0; + if (sk->namelen && *sk->name) { + ue.file_perms = &perms; + + perms.mode = sk->mode; + perms.uid = sk->uid; + perms.gid = sk->gid; + } + sk_encode_shutdown(&ue, sk->shutdown); if (ue.peer) { @@ -323,6 +337,10 @@ static int unix_collect_one(const struct unix_diag_msg *m, len = 0; name = NULL; } + + d->mode = st.st_mode; + d->uid = st.st_uid; + d->gid = st.st_gid; } d->namelen = len; @@ -564,6 +582,29 @@ static int bind_unix_sk(int sk, struct unix_sk_info *ui) return -1; } + if (ui->ue->name.len && *ui->name && ui->ue->file_perms) { + FilePermsEntry *perms = ui->ue->file_perms; + char fname[PATH_MAX]; + + if (ui->ue->name.len >= sizeof(fname)) { + pr_err("The file name is too long\n"); + return -1; + } + + memcpy(fname, ui->name, ui->ue->name.len); + fname[ui->ue->name.len] = '\0'; + + if (chown(fname, perms->uid, perms->gid) == -1) { + pr_perror("Unable to change file owner and group"); + return -1; + } + + if (chmod(fname, perms->mode) == -1) { + pr_perror("Unable to change file mode bits"); + return -1; + } + } + futex_set_and_wake(&ui->bound, 1); done: return 0;