sk-unix: dump/restore a file permissions

Signed-off-by: Andrey Vagin <avagin@openvz.org>
Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
This commit is contained in:
Andrey Vagin 2013-01-30 03:28:01 +04:00 committed by Pavel Emelyanov
parent a27f0e5cb0
commit f3cd454cd4
2 changed files with 49 additions and 0 deletions

View file

@ -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;
}

View file

@ -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;