Determining a user's remote port in a VFS module
Constantine Vetoshev
gepardcv at yahoo.com
Fri Jun 29 22:35:59 GMT 2007
Constantine Vetoshev <gepardcv at yahoo.com> writes:
> > I think the poster was looking for an API call from
> > Samba VFS layer. But I unclear as to whether the Q was
> > about the port to which the client connected or the
> > src port used by the client.
>
> I meant the latter. connection_struct in smb.h has a client_address field, but no corresponding
> client_port. I looked in util_sock.c, and I see that remote port information isn't being retrieved or
> set. client_socket_port() seems to return the local port on the Samba server (typically 445). I'm not
> terribly fluent in socket programming issues---is the remote port even readily available with POSIX
> APIs? What about low-level kernel calls?
I think I figured it out. Here's a patch against v3-0 in git (thank you so much for making a git repository, by the way---makes life way easier than Subversion).
Comments?
[PATCH] Added the ability retrieve the remote port of the current connection.
It's occasionally useful to be able to determine the remote port of
the current connection. The util_sock collection of code currently has
a way to determine the remote IP, but the remote port was mysteriously
missing.
connection_struct now has a new field, client_port, to match client_addr.
---
source/include/smb.h | 1 +
source/lib/util_sock.c | 28 ++++++++++++++++++++++++++++
source/smbd/service.c | 1 +
3 files changed, 30 insertions(+), 0 deletions(-)
diff --git a/source/include/smb.h b/source/include/smb.h
index 9c7b32f..f5faf0a 100644
--- a/source/include/smb.h
+++ b/source/include/smb.h
@@ -647,6 +647,7 @@ typedef struct connection_struct {
uid_t uid; /* uid of user who *opened* this connection */
gid_t gid; /* gid of user who *opened* this connection */
char client_address[18]; /* String version of client IP address. */
+ int client_port; /* remote port on the client's side of this connection */
uint16 vuid; /* vuid of user who *opened* this connection, or UID_FIELD_INVALID */
diff --git a/source/lib/util_sock.c b/source/lib/util_sock.c
index d102e57..88ca03f 100644
--- a/source/lib/util_sock.c
+++ b/source/lib/util_sock.c
@@ -85,6 +85,11 @@ char *client_addr(void)
return get_peer_addr(client_fd);
}
+int client_port(void)
+{
+ return get_peer_port(client_fd);
+}
+
char *client_socket_addr(void)
{
return get_socket_addr(client_fd);
@@ -1270,6 +1275,29 @@ char *get_peer_addr(int fd)
}
/*******************************************************************
+ Return the port of the remote end of a socket as an int.
+ ******************************************************************/
+
+int get_peer_port(int fd)
+{
+ struct sockaddr sa;
+ struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
+ socklen_t length = sizeof(sa);
+ static fstring addr_buf;
+
+ if (fd == -1) {
+ return -1;
+ }
+
+ if (getpeername(fd, &sa, &length) < 0) {
+ DEBUG(0,("getpeername failed. Error was %s\n", strerror(errno) ));
+ return -1;
+ }
+
+ return ntohs(sockin->sin_port);
+}
+
+/*******************************************************************
Create protected unix domain socket.
Some unixes cannot set permissions on a ux-dom-sock, so we
diff --git a/source/smbd/service.c b/source/smbd/service.c
index 2b84223..9adc9d0 100644
--- a/source/smbd/service.c
+++ b/source/smbd/service.c
@@ -767,6 +767,7 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
safe_strcpy(conn->client_address, client_addr(),
sizeof(conn->client_address)-1);
+ conn->client_port = client_port();
conn->num_files_open = 0;
conn->lastused = conn->lastused_count = time(NULL);
conn->used = True;
--
1.5.2
Thanks,
CV
____________________________________________________________________________________
Get the Yahoo! toolbar and be alerted to new email wherever you're surfing.
http://new.toolbar.yahoo.com/toolbar/features/mail/index.php
More information about the samba-technical
mailing list