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+
5467struct 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+
114154static 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+
189261static 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