Skip to content

Commit 2a9d04a

Browse files
committed
mountd: add UMNT and UMNTALL support
Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
1 parent ff3ab57 commit 2a9d04a

File tree

1 file changed

+93
-23
lines changed

1 file changed

+93
-23
lines changed

servers/nfsd/mountd.c

Lines changed: 93 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,19 @@
5151
(*list) = (item); \
5252
} while (0);
5353

54+
#define LIST_REMOVE(list, item, nxt) \
55+
if ((*list) == (item)) { \
56+
(*list) = (item)->nxt; \
57+
} else { \
58+
void *head = (*list); \
59+
while ((*list)->nxt && (*list)->nxt != (item)) \
60+
(*list) = (*list)->nxt; \
61+
if ((*list)->nxt != NULL) { \
62+
(*list)->nxt = (*list)->nxt->nxt; \
63+
} \
64+
(*list) = head; \
65+
}
66+
5467
struct mountd_export *mountd_add_export(struct mountd_state *mountd, char *path, int fh_len, char *fh)
5568
{
5669
struct mountd_export *export;
@@ -111,18 +124,44 @@ static int mount3_export_proc(struct rpc_context *rpc, struct rpc_msg *call, voi
111124
return rc;
112125
}
113126

127+
static char *client_address(struct rpc_context *rpc)
128+
{
129+
struct sockaddr_storage *ss, tcp_ss;
130+
static char addr[64] = {0};
131+
132+
if (rpc_is_udp_socket(rpc)) {
133+
ss = (struct sockaddr_storage *)rpc_get_udp_src_sockaddr(rpc);
134+
} else {
135+
socklen_t ss_len;
136+
137+
if (getpeername(rpc_get_fd(rpc), (struct sockaddr *)&tcp_ss, &ss_len)) {
138+
return NULL;
139+
}
140+
ss = &tcp_ss;
141+
}
142+
switch (ss->ss_family) {
143+
case AF_INET:
144+
inet_ntop(ss->ss_family, &((struct sockaddr_in *)ss)->sin_addr, addr, sizeof(addr));
145+
break;
146+
case AF_INET6:
147+
inet_ntop(ss->ss_family, &((struct sockaddr_in6 *)ss)->sin6_addr, addr, sizeof(addr));
148+
break;
149+
}
150+
151+
return addr;
152+
}
153+
114154
static int mount3_mnt_proc(struct rpc_context *rpc, struct rpc_msg *call, void *opaque)
115155
{
116156
struct mountd_state *mountd = (struct mountd_state *)opaque;
117157
MOUNT3MNTargs *args = call->body.cbody.args;
118158
MOUNT3MNTres res;
119159
struct mountd_client *client;
120160
struct mountd_export *e;
121-
static char addr[64] = {0};
122-
struct sockaddr_storage *ss, tcp_ss;
123161
int rc;
124162
uint32_t auth_flavors[] = { AUTH_UNIX };
125163
memset(&res, 0, sizeof(res));
164+
char *addr;
126165

127166
client = talloc(mountd, struct mountd_client);
128167
if (client == NULL) {
@@ -140,24 +179,10 @@ static int mount3_mnt_proc(struct rpc_context *rpc, struct rpc_msg *call, void *
140179
goto out;
141180
}
142181

143-
if (rpc_is_udp_socket(rpc)) {
144-
ss = (struct sockaddr_storage *)rpc_get_udp_src_sockaddr(rpc);
145-
} else {
146-
socklen_t ss_len;
147-
148-
if (getpeername(rpc_get_fd(rpc), (struct sockaddr *)&tcp_ss, &ss_len)) {
149-
res.fhs_status = MNT3ERR_SERVERFAULT;
150-
goto out;
151-
}
152-
ss = &tcp_ss;
153-
}
154-
switch (ss->ss_family) {
155-
case AF_INET:
156-
inet_ntop(ss->ss_family, &((struct sockaddr_in *)ss)->sin_addr, addr, sizeof(addr));
157-
break;
158-
case AF_INET6:
159-
inet_ntop(ss->ss_family, &((struct sockaddr_in6 *)ss)->sin6_addr, addr, sizeof(addr));
160-
break;
182+
addr = client_address(rpc);
183+
if (addr == NULL) {
184+
res.fhs_status = MNT3ERR_SERVERFAULT;
185+
goto out;
161186
}
162187

163188
client->client = talloc_strdup(client, addr);
@@ -186,6 +211,53 @@ static int mount3_mnt_proc(struct rpc_context *rpc, struct rpc_msg *call, void *
186211
}
187212

188213

214+
static int mount3_umnt_proc(struct rpc_context *rpc, struct rpc_msg *call, void *opaque)
215+
{
216+
struct mountd_state *mountd = (struct mountd_state *)opaque;
217+
MOUNT3UMNTargs *args = call->body.cbody.args;
218+
struct mountd_client *c;
219+
char *addr;
220+
int rc;
221+
222+
addr = client_address(rpc);
223+
if (addr == NULL) {
224+
return rpc_send_reply(rpc, call, NULL, (zdrproc_t)zdr_void, 0);
225+
}
226+
227+
for (c = mountd->clients; c; c = c->next) {
228+
if (!strcmp(c->client, addr) && !strcmp(c->path, *args)) {
229+
LIST_REMOVE(&mountd->clients, c, next);
230+
talloc_free(c);
231+
return rpc_send_reply(rpc, call, NULL, (zdrproc_t)zdr_void, 0);
232+
}
233+
}
234+
return rpc_send_reply(rpc, call, NULL, (zdrproc_t)zdr_void, 0);
235+
}
236+
237+
static int mount3_umntall_proc(struct rpc_context *rpc, struct rpc_msg *call, void *opaque)
238+
{
239+
struct mountd_state *mountd = (struct mountd_state *)opaque;
240+
struct mountd_client *c, *nl = NULL;
241+
char *addr;
242+
int rc;
243+
244+
addr = client_address(rpc);
245+
if (addr == NULL) {
246+
return rpc_send_reply(rpc, call, NULL, (zdrproc_t)zdr_void, 0);
247+
}
248+
249+
for (c = mountd->clients; c; c = c->next) {
250+
LIST_REMOVE(&mountd->clients, c, next);
251+
if (!strcmp(c->client, addr)) {
252+
talloc_free(c);
253+
}
254+
LIST_ADD(&nl, c, next);
255+
}
256+
mountd->clients = nl;
257+
return rpc_send_reply(rpc, call, NULL, (zdrproc_t)zdr_void, 0);
258+
}
259+
260+
189261
static int mount3_dump_proc(struct rpc_context *rpc, struct rpc_msg *call, void *opaque)
190262
{
191263
struct mountd_state *mountd = (struct mountd_state *)opaque;
@@ -228,12 +300,10 @@ struct mountd_state *mountd_init(TALLOC_CTX *ctx, struct tevent_context *tevent)
228300
(zdrproc_t)zdr_MOUNT3MNTargs, sizeof(MOUNT3MNTargs), NULL},
229301
{MOUNT3_DUMP, mount3_dump_proc,
230302
(zdrproc_t)zdr_void, 0, NULL},
231-
#if 0
232303
{MOUNT3_UMNT, mount3_umnt_proc,
233304
(zdrproc_t)zdr_MOUNT3UMNTargs, sizeof(MOUNT3UMNTargs), NULL},
234305
{MOUNT3_UMNTALL, mount3_umntall_proc,
235-
(zdrproc_t)zdr_MOUNT3_UMNTALLargs, sizeof(MOUNT3_UMNTALLargs), NULL},
236-
#endif
306+
(zdrproc_t)zdr_void, 0, NULL},
237307
{MOUNT3_EXPORT, mount3_export_proc,
238308
(zdrproc_t)zdr_void, 0, NULL},
239309
};

0 commit comments

Comments
 (0)