GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
+#include "popt_common.h"
+#include "rpc_client/cli_pipe.h"
+#include "../librpc/gen_ndr/ndr_srvsvc_c.h"
+#include "libsmb/libsmb.h"
+#include "libsmb/clirap.h"
-static BOOL use_bcast;
+static int use_bcast;
/* How low can we go? */
/* Holds a list of workgroups or servers */
-struct name_list {
- struct name_list *prev, *next;
- pstring name, comment;
- uint32 server_type;
+struct smb_name_list {
+ struct smb_name_list *prev, *next;
+ char *name, *comment;
+ uint32_t server_type;
};
-static struct name_list *workgroups, *servers, *shares;
+static struct smb_name_list *workgroups, *servers, *shares;
-static void free_name_list(struct name_list *list)
+static void free_name_list(struct smb_name_list *list)
{
while(list)
DLIST_REMOVE(list, list);
}
-static void add_name(const char *machine_name, uint32 server_type,
+static void add_name(const char *machine_name, uint32_t server_type,
const char *comment, void *state)
{
- struct name_list **name_list = (struct name_list **)state;
- struct name_list *new_name;
+ struct smb_name_list **name_list = (struct smb_name_list **)state;
+ struct smb_name_list *new_name;
- new_name = SMB_MALLOC_P(struct name_list);
+ new_name = SMB_MALLOC_P(struct smb_name_list);
if (!new_name)
return;
ZERO_STRUCTP(new_name);
- pstrcpy(new_name->name, machine_name);
- pstrcpy(new_name->comment, comment);
+ new_name->name = SMB_STRDUP(machine_name);
+ new_name->comment = SMB_STRDUP(comment);
new_name->server_type = server_type;
+ if (!new_name->name || !new_name->comment) {
+ SAFE_FREE(new_name->name);
+ SAFE_FREE(new_name->comment);
+ SAFE_FREE(new_name);
+ return;
+ }
+
DLIST_ADD(*name_list, new_name);
}
/****************************************************************************
display tree of smb workgroups, servers and shares
****************************************************************************/
-static BOOL get_workgroups(struct user_auth_info *user_info)
+static bool get_workgroups(const struct user_auth_info *user_info)
{
struct cli_state *cli;
- struct in_addr server_ip;
- pstring master_workgroup;
+ struct sockaddr_storage server_ss;
+ TALLOC_CTX *ctx = talloc_tos();
+ char *master_workgroup = NULL;
/* Try to connect to a #1d name of our current workgroup. If that
doesn't work broadcast for a master browser and then jump off
that workgroup. */
- pstrcpy(master_workgroup, lp_workgroup());
+ master_workgroup = talloc_strdup(ctx, lp_workgroup());
+ if (!master_workgroup) {
+ return false;
+ }
+
+ if (!use_bcast && !find_master_ip(lp_workgroup(), &server_ss)) {
+ DEBUG(4,("Unable to find master browser for workgroup %s, "
+ "falling back to broadcast\n",
+ master_workgroup));
+ use_bcast = true;
+ }
+
+ if (!use_bcast) {
+ char addr[INET6_ADDRSTRLEN];
- if (!use_bcast && !find_master_ip(lp_workgroup(), &server_ip)) {
- DEBUG(4, ("Unable to find master browser for workgroup %s, falling back to broadcast\n",
- master_workgroup));
- use_bcast = True;
- } else if(!use_bcast) {
- if (!(cli = get_ipc_connect(inet_ntoa(server_ip), &server_ip, user_info)))
- return False;
+ print_sockaddr(addr, sizeof(addr), &server_ss);
+
+ cli = get_ipc_connect(addr, &server_ss, user_info);
+ if (cli == NULL) {
+ return false;
}
-
- if (!(cli = get_ipc_connect_master_ip_bcast(master_workgroup, user_info))) {
+ } else {
+ cli = get_ipc_connect_master_ip_bcast(talloc_tos(),
+ user_info,
+ &master_workgroup);
+ if (cli == NULL) {
DEBUG(4, ("Unable to find master browser by "
"broadcast\n"));
- return False;
- }
+ return false;
+ }
+ }
- if (!cli_NetServerEnum(cli, master_workgroup,
+ if (!cli_NetServerEnum(cli, master_workgroup,
SV_TYPE_DOMAIN_ENUM, add_name, &workgroups))
return False;
/* Retrieve the list of servers for a given workgroup */
-static BOOL get_servers(char *workgroup, struct user_auth_info *user_info)
+static bool get_servers(char *workgroup, const struct user_auth_info *user_info)
{
struct cli_state *cli;
- struct in_addr server_ip;
+ struct sockaddr_storage server_ss;
+ char addr[INET6_ADDRSTRLEN];
/* Open an IPC$ connection to the master browser for the workgroup */
- if (!find_master_ip(workgroup, &server_ip)) {
+ if (!find_master_ip(workgroup, &server_ss)) {
DEBUG(4, ("Cannot find master browser for workgroup %s\n",
workgroup));
return False;
}
- if (!(cli = get_ipc_connect(inet_ntoa(server_ip), &server_ip, user_info)))
+ print_sockaddr(addr, sizeof(addr), &server_ss);
+ if (!(cli = get_ipc_connect(addr, &server_ss, user_info)))
return False;
- if (!cli_NetServerEnum(cli, workgroup, SV_TYPE_ALL, add_name,
+ if (!cli_NetServerEnum(cli, workgroup, SV_TYPE_ALL, add_name,
&servers))
return False;
return True;
}
-static BOOL get_rpc_shares(struct cli_state *cli,
- void (*fn)(const char *, uint32, const char *, void *),
+static bool get_rpc_shares(struct cli_state *cli,
+ void (*fn)(const char *, uint32_t, const char *, void *),
void *state)
{
NTSTATUS status;
- struct rpc_pipe_client *pipe_hnd;
+ struct rpc_pipe_client *pipe_hnd = NULL;
TALLOC_CTX *mem_ctx;
- uint32 enum_hnd;
+ WERROR werr;
+ struct srvsvc_NetShareInfoCtr info_ctr;
struct srvsvc_NetShareCtr1 ctr1;
- union srvsvc_NetShareCtr ctr;
- uint32 numentries;
int i;
- uint32 info_level = 1;
+ uint32_t resume_handle = 0;
+ uint32_t total_entries = 0;
+ struct dcerpc_binding_handle *b;
mem_ctx = talloc_new(NULL);
if (mem_ctx == NULL) {
return False;
}
- enum_hnd = 0;
- pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SRVSVC, &status);
+ status = cli_rpc_pipe_open_noauth(cli, &ndr_table_srvsvc,
+ &pipe_hnd);
- if (pipe_hnd == NULL) {
+ if (!NT_STATUS_IS_OK(status)) {
DEBUG(10, ("Could not connect to srvsvc pipe: %s\n",
nt_errstr(status)));
TALLOC_FREE(mem_ctx);
return False;
}
+ b = pipe_hnd->binding_handle;
+
+ ZERO_STRUCT(info_ctr);
ZERO_STRUCT(ctr1);
- level = 1;
- ctr.ctr1 = &ctr1;
- status = rpccli_srvsvc_NetShareEnum(pipe_hnd, mem_ctx, NULL,
- &info_level, &ctr,
- 0xffffffff, &numentries,
- &enum_hnd);
+ info_ctr.level = 1;
+ info_ctr.ctr.ctr1 = &ctr1;
- if (!NT_STATUS_IS_OK(status)) {
+ status = dcerpc_srvsvc_NetShareEnumAll(b, mem_ctx,
+ pipe_hnd->desthost,
+ &info_ctr,
+ 0xffffffff,
+ &total_entries,
+ &resume_handle,
+ &werr);
+
+ if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(werr)) {
TALLOC_FREE(mem_ctx);
- cli_rpc_pipe_close(pipe_hnd);
+ TALLOC_FREE(pipe_hnd);
return False;
}
- for (i=0; i<numentries; i++) {
- fn(ctr.ctr1->array[i].name, ctr.ctr1->array[i].type,
- ctr.ctr1->array[i].comment, state);
+ for (i=0; i < info_ctr.ctr.ctr1->count; i++) {
+ struct srvsvc_NetShareInfo1 info = info_ctr.ctr.ctr1->array[i];
+ fn(info.name, info.type, info.comment, state);
}
TALLOC_FREE(mem_ctx);
- cli_rpc_pipe_close(pipe_hnd);
+ TALLOC_FREE(pipe_hnd);
return True;
}
-static BOOL get_shares(char *server_name, struct user_auth_info *user_info)
+static bool get_shares(char *server_name, const struct user_auth_info *user_info)
{
struct cli_state *cli;
if (get_rpc_shares(cli, add_name, &shares))
return True;
-
+
if (!cli_RNetShareEnum(cli, add_name, &shares))
return False;
return True;
}
-static BOOL print_tree(struct user_auth_info *user_info)
+static bool print_tree(const struct user_auth_info *user_info)
{
- struct name_list *wg, *sv, *sh;
+ struct smb_name_list *wg, *sv, *sh;
/* List workgroups */
/****************************************************************************
main program
****************************************************************************/
- int main(int argc,char *argv[])
+int main(int argc, char *argv[])
{
+ TALLOC_CTX *frame = talloc_stackframe();
+ const char **argv_const = discard_const_p(const char *, argv);
struct poptOption long_options[] = {
POPT_AUTOHELP
{ "broadcast", 'b', POPT_ARG_VAL, &use_bcast, True, "Use broadcast instead of using the master browser" },
POPT_TABLEEND
};
poptContext pc;
-
+
/* Initialise samba stuff */
- load_case_tables();
+ smb_init_locale();
setlinebuf(stdout);
- dbf = x_stderr;
+ setup_logging(argv[0], DEBUG_STDERR);
- setup_logging(argv[0],True);
+ popt_common_credentials_set_ignore_missing_conf();
- pc = poptGetContext("smbtree", argc, (const char **)argv, long_options,
- POPT_CONTEXT_KEEP_FIRST);
+ pc = poptGetContext("smbtree", argc, argv_const, long_options,
+ POPT_CONTEXT_KEEP_FIRST);
while(poptGetNextOpt(pc) != -1);
poptFreeContext(pc);
-
- lp_load(dyn_CONFIGFILE,True,False,False,True);
- load_interfaces();
-
- /* Parse command line args */
-
- if (!cmdline_auth_info.got_pass) {
- char *pass = getpass("Password: ");
- if (pass) {
- pstrcpy(cmdline_auth_info.password, pass);
- }
- cmdline_auth_info.got_pass = True;
- }
+ popt_burn_cmdline_password(argc, argv);
/* Now do our stuff */
- if (!print_tree(&cmdline_auth_info))
+ if (!print_tree(popt_get_cmdline_auth_info())) {
+ TALLOC_FREE(frame);
return 1;
+ }
+ popt_free_cmdline_auth_info();
+ TALLOC_FREE(frame);
return 0;
}