1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.hosted.node.admin.task.util.fs;
import com.yahoo.vespa.hosted.node.admin.nodeagent.UserNamespace;
import java.io.IOException;
import java.nio.file.attribute.GroupPrincipal;
import java.nio.file.attribute.UserPrincipal;
import java.nio.file.attribute.UserPrincipalLookupService;
import java.nio.file.attribute.UserPrincipalNotFoundException;
import java.util.Objects;
/**
* @author valerijf
*/
class ContainerUserPrincipalLookupService extends UserPrincipalLookupService {
private final UserPrincipalLookupService baseFsUserPrincipalLookupService;
private final UserNamespace userNamespace;
ContainerUserPrincipalLookupService(UserPrincipalLookupService baseFsUserPrincipalLookupService, UserNamespace userNamespace) {
this.baseFsUserPrincipalLookupService = Objects.requireNonNull(baseFsUserPrincipalLookupService);
this.userNamespace = Objects.requireNonNull(userNamespace);
}
public int userIdOnHost(int containerUid) { return userNamespace.userIdOnHost(containerUid); }
public int groupIdOnHost(int containerGid) { return userNamespace.groupIdOnHost(containerGid); }
public int userIdInContainer(int hostUid) { return userNamespace.userIdInContainer(hostUid); }
public int groupIdInContainer(int hostGid) { return userNamespace.groupIdInContainer(hostGid); }
@Override
public ContainerUserPrincipal lookupPrincipalByName(String name) throws IOException {
int containerUid = resolveName(name, userNamespace.vespaUser(), userNamespace.vespaUserId());
String user = resolveId(containerUid, userNamespace.vespaUser(), userNamespace.vespaUserId());
String hostUid = String.valueOf(userIdOnHost(containerUid));
return new ContainerUserPrincipal(containerUid, user, baseFsUserPrincipalLookupService.lookupPrincipalByName(hostUid));
}
@Override
public ContainerGroupPrincipal lookupPrincipalByGroupName(String group) throws IOException {
int containerGid = resolveName(group, userNamespace.vespaGroup(), userNamespace.vespaGroupId());
String name = resolveId(containerGid, userNamespace.vespaGroup(), userNamespace.vespaGroupId());
String hostGid = String.valueOf(groupIdOnHost(containerGid));
return new ContainerGroupPrincipal(containerGid, name, baseFsUserPrincipalLookupService.lookupPrincipalByGroupName(hostGid));
}
public ContainerUserPrincipal userPrincipal(int uid, UserPrincipal baseFsPrincipal) {
String name = resolveId(uid, userNamespace.vespaUser(), userNamespace.vespaUserId());
return new ContainerUserPrincipal(uid, name, baseFsPrincipal);
}
public ContainerGroupPrincipal groupPrincipal(int gid, GroupPrincipal baseFsPrincipal) {
String name = resolveId(gid, userNamespace.vespaGroup(), userNamespace.vespaGroupId());
return new ContainerGroupPrincipal(gid, name, baseFsPrincipal);
}
private String resolveId(int id, String vespaName, int vespaId) {
if (id == 0) return "root";
if (id == vespaId) return vespaName;
return String.valueOf(id);
}
private int resolveName(String name, String vespaName, int vespaId) throws UserPrincipalNotFoundException {
if (name.equals("root")) return 0;
if (name.equals(vespaName)) return vespaId;
try {
return Integer.parseInt(name);
} catch (NumberFormatException ignored) {
throw new UserPrincipalNotFoundException(name);
}
}
private abstract static class NamedPrincipal implements UserPrincipal {
private final int id;
private final String name;
private final UserPrincipal baseFsPrincipal;
private NamedPrincipal(int id, String name, UserPrincipal baseFsPrincipal) {
this.id = id;
this.name = Objects.requireNonNull(name);
this.baseFsPrincipal = Objects.requireNonNull(baseFsPrincipal);
}
@Override
public final String getName() {
return name;
}
public int id() {
return id;
}
public UserPrincipal baseFsPrincipal() {
return baseFsPrincipal;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
NamedPrincipal that = (NamedPrincipal) o;
return id == that.id && baseFsPrincipal.equals(that.baseFsPrincipal);
}
@Override
public int hashCode() {
return Objects.hash(id, baseFsPrincipal);
}
@Override
public String toString() {
return "{id=" + id + ", baseFsPrincipal=" + baseFsPrincipal + '}';
}
}
static final class ContainerUserPrincipal extends NamedPrincipal {
private ContainerUserPrincipal(int id, String name, UserPrincipal baseFsPrincipal) { super(id, name, baseFsPrincipal); }
}
static final class ContainerGroupPrincipal extends NamedPrincipal implements GroupPrincipal {
private ContainerGroupPrincipal(int id, String name, GroupPrincipal baseFsPrincipal) { super(id, name, baseFsPrincipal); }
@Override public GroupPrincipal baseFsPrincipal() { return (GroupPrincipal) super.baseFsPrincipal(); }
}
}
|