summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/proto.h5
-rw-r--r--source3/libsmb/clientgen.c2
-rw-r--r--source3/libsmb/namequery.c41
-rw-r--r--source3/smbwrapper/smbw.c31
-rw-r--r--source3/smbwrapper/smbw_dir.c27
5 files changed, 96 insertions, 10 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h
index f2b484ceec..86792a2245 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -365,7 +365,7 @@ BOOL cli_api(struct cli_state *cli,
BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation);
BOOL cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, const char *));
BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype,
- void (*fn)(char *, uint32, char *));
+ void (*fn)(const char *, uint32, const char *));
BOOL cli_session_setup(struct cli_state *cli,
char *user,
char *pass, int passlen,
@@ -405,7 +405,7 @@ BOOL cli_oem_change_password(struct cli_state *cli, char *user, char *new_passwo
char *old_password);
BOOL cli_negprot(struct cli_state *cli);
BOOL cli_session_request(struct cli_state *cli,
- struct nmb_name *calling, struct nmb_name *called);
+ struct nmb_name *calling, struct nmb_name *called);
BOOL cli_connect(struct cli_state *cli, char *host, struct in_addr *ip);
BOOL cli_initialise(struct cli_state *cli);
void cli_shutdown(struct cli_state *cli);
@@ -448,6 +448,7 @@ FILE *startlmhosts(char *fname);
BOOL getlmhostsent( FILE *fp, char *name, int *name_type, struct in_addr *ipaddr);
void endlmhosts(FILE *fp);
BOOL resolve_name(char *name, struct in_addr *return_ip);
+BOOL find_master(char *group, struct in_addr *master_ip);
/*The following definitions come from libsmb/nmblib.c */
diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c
index 20c0c36166..6b07eb65b3 100644
--- a/source3/libsmb/clientgen.c
+++ b/source3/libsmb/clientgen.c
@@ -535,7 +535,7 @@ The callback function takes 3 arguments: the machine name, the server type and
the comment.
****************************************************************************/
BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype,
- void (*fn)(char *, uint32, char *))
+ void (*fn)(const char *, uint32, const char *))
{
char *rparam = NULL;
char *rdata = NULL;
diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c
index f988504bba..a9da735f36 100644
--- a/source3/libsmb/namequery.c
+++ b/source3/libsmb/namequery.c
@@ -420,7 +420,6 @@ void endlmhosts(FILE *fp)
or NetBIOS name. This uses the name switch in the
smb.conf to determine the order of name resolution.
*********************************************************/
-
BOOL resolve_name(char *name, struct in_addr *return_ip)
{
int i;
@@ -573,3 +572,43 @@ BOOL resolve_name(char *name, struct in_addr *return_ip)
return False;
}
+
+
+
+/********************************************************
+find the IP address of the master browser for a workgroup
+*********************************************************/
+BOOL find_master(char *group, struct in_addr *master_ip)
+{
+ int sock;
+ struct in_addr *iplist = NULL;
+ int count, i;
+ int num_interfaces = iface_count();
+
+ sock = open_socket_in( SOCK_DGRAM, 0, 3,
+ interpret_addr(lp_socket_address()) );
+
+ if (sock == -1) return False;
+
+ set_socket_options(sock,"SO_BROADCAST");
+
+ /*
+ * Lookup the name on all the interfaces, return on
+ * the first successful match.
+ */
+ for( i = 0; i < num_interfaces; i++) {
+ struct in_addr sendto_ip;
+ /* Done this way to fix compiler error on IRIX 5.x */
+ sendto_ip = *iface_bcast(*iface_n_ip(i));
+ iplist = name_query(sock, group, 0x1D, True, False,
+ sendto_ip, &count, NULL);
+ if(iplist != NULL) {
+ *master_ip = iplist[0];
+ free((char *)iplist);
+ close(sock);
+ return True;
+ }
+ }
+ close(sock);
+ return False;
+}
diff --git a/source3/smbwrapper/smbw.c b/source3/smbwrapper/smbw.c
index 054b694c41..650d0a08f5 100644
--- a/source3/smbwrapper/smbw.c
+++ b/source3/smbwrapper/smbw.c
@@ -207,7 +207,7 @@ char *smbw_parse_path(const char *fname, char *server, char *share, char *path)
{
static pstring s;
char *p, *p2;
- int len;
+ int len = strlen(SMBW_PREFIX)-1;
*server = *share = *path = 0;
@@ -221,9 +221,12 @@ char *smbw_parse_path(const char *fname, char *server, char *share, char *path)
DEBUG(5,("cleaned %s (fname=%s cwd=%s)\n",
s, fname, smb_cwd));
- if (strncmp(s,SMBW_PREFIX,strlen(SMBW_PREFIX))) return s;
+ if (strncmp(s,SMBW_PREFIX,len) ||
+ (s[len] != '/' && s[len] != 0)) return s;
+
+ p = s + len;
+ if (*p == '/') p++;
- p = s + strlen(SMBW_PREFIX);
p2 = strchr(p,'/');
if (p2) {
@@ -239,6 +242,11 @@ char *smbw_parse_path(const char *fname, char *server, char *share, char *path)
p = p2;
if (!p) {
+ if (len == 0) {
+ char *workgroup = getenv("SMBW_WORKGROUP");
+ if (!workgroup) workgroup = lp_workgroup();
+ slprintf(server,sizeof(fstring)-1, "%s#1D", workgroup);
+ }
fstrcpy(share,"IPC$");
pstrcpy(path,"");
goto ok;
@@ -336,6 +344,8 @@ struct smbw_server *smbw_server(char *server, char *share)
char *password;
char *workgroup;
struct nmb_name called, calling;
+ char *p, *server_n = server;
+ fstring group;
ZERO_STRUCT(c);
@@ -364,8 +374,21 @@ struct smbw_server *smbw_server(char *server, char *share)
make_nmb_name(&called , server, 0x20, "");
again:
+ if ((p=strchr(server_n,'#'))) {
+ struct in_addr ip;
+ fstrcpy(group, server_n);
+ p = strchr(group,'#');
+ *p = 0;
+ if (!find_master(group, &ip)) {
+ errno = ENOENT;
+ return NULL;
+ }
+ fstrcpy(group, inet_ntoa(ip));
+ server_n = group;
+ }
+
/* have to open a new connection */
- if (!cli_initialise(&c) || !cli_connect(&c, server, NULL)) {
+ if (!cli_initialise(&c) || !cli_connect(&c, server_n, NULL)) {
errno = ENOENT;
return NULL;
}
diff --git a/source3/smbwrapper/smbw_dir.c b/source3/smbwrapper/smbw_dir.c
index 3fdaebec5a..d794944b1a 100644
--- a/source3/smbwrapper/smbw_dir.c
+++ b/source3/smbwrapper/smbw_dir.c
@@ -113,6 +113,23 @@ static void smbw_share_add(const char *share, uint32 type, const char *comment)
/*****************************************************
+add a server to a directory listing
+*******************************************************/
+static void smbw_server_add(const char *name, uint32 type,
+ const char *comment)
+{
+ struct file_info finfo;
+
+ ZERO_STRUCT(finfo);
+
+ pstrcpy(finfo.name, name);
+ finfo.mode = aRONLY | aDIR;
+
+ smbw_dir_add(&finfo);
+}
+
+
+/*****************************************************
add a entry to a directory listing
*******************************************************/
static void smbw_printjob_add(struct print_job_info *job)
@@ -145,7 +162,7 @@ int smbw_dir_open(const char *fname)
struct smbw_dir *dir=NULL;
pstring mask;
int fd;
- char *s;
+ char *s, *p;
DEBUG(4,("%s\n", __FUNCTION__));
@@ -181,7 +198,13 @@ int smbw_dir_open(const char *fname)
slprintf(mask, sizeof(mask)-1, "%s\\*", path);
string_sub(mask,"\\\\","\\");
- if (strcmp(srv->cli.dev,"IPC") == 0) {
+ if ((p=strstr(srv->server_name,"#1D"))) {
+ DEBUG(4,("doing NetServerEnum\n"));
+ *p = 0;
+ cli_NetServerEnum(&srv->cli, srv->server_name, SV_TYPE_ALL,
+ smbw_server_add);
+ *p = '#';
+ } else if (strcmp(srv->cli.dev,"IPC") == 0) {
DEBUG(4,("doing NetShareEnum\n"));
if (cli_RNetShareEnum(&srv->cli, smbw_share_add) < 0) {
errno = smbw_errno(&srv->cli);