From 1970c92c0a56672308314d39718f994302c95c95 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 4 Oct 1998 11:25:06 +0000 Subject: support NetServerEnum in smbwrapper. You can now do a ls in /smb/ and it will list all servers in your workgroup. You can set your workgroup with the SMBW_WORKGROUP environment variable. (This used to be commit 64699810e2d94e8648a0a3341b1cc826d4e8bfd9) --- source3/include/proto.h | 5 +++-- source3/libsmb/clientgen.c | 2 +- source3/libsmb/namequery.c | 41 ++++++++++++++++++++++++++++++++++++++++- source3/smbwrapper/smbw.c | 31 +++++++++++++++++++++++++++---- source3/smbwrapper/smbw_dir.c | 27 +++++++++++++++++++++++++-- 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 @@ -112,6 +112,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 *******************************************************/ @@ -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); -- cgit