1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-11 05:18:09 +03:00
samba-mirror/source3/utils/smbtree.c
Volker Lendecke 595e3f2566 utils: Convert smbtree to use libsmbclient
We have the domain browsing functionality in libsmbclient, don't
duplicate it in smbtree with special code. Not too much gain in lines
of code, but the new code is much more regular and reuses
functionality provided elsewhere.

This removes the "-b" option from smbtree, libsmbclient always does
that.

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
2020-04-18 02:29:34 +00:00

269 lines
6.0 KiB
C

/*
Unix SMB/CIFS implementation.
Network neighbourhood browser.
Copyright (C) Tim Potter 2000
Copyright (C) Jelmer Vernooij 2003
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
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, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
#include "popt_common_cmdline.h"
#include "rpc_client/cli_pipe.h"
#include "../librpc/gen_ndr/ndr_srvsvc_c.h"
#include "libsmb/libsmb.h"
#include "libsmb/namequery.h"
#include "libsmb/clirap.h"
#include "../libcli/smb/smbXcli_base.h"
#include "nameserv.h"
#include "libsmbclient.h"
/* How low can we go? */
enum tree_level {LEV_WORKGROUP, LEV_SERVER, LEV_SHARE};
static enum tree_level level = LEV_SHARE;
static void get_auth_data_with_context_fn(
SMBCCTX *context,
const char *server,
const char *share,
char *domain,
int domain_len,
char *user,
int user_len,
char *password,
int password_len)
{
struct user_auth_info *auth = popt_get_cmdline_auth_info();
size_t len;
if (auth == NULL) {
return;
}
len = strlcpy(domain, get_cmdline_auth_info_domain(auth), domain_len);
if ((int)len >= domain_len) {
return;
}
len = strlcpy(
user, get_cmdline_auth_info_username(auth), user_len);
if ((int)len >= user_len) {
return;
}
len = strlcpy(
password, get_cmdline_auth_info_password(auth), password_len);
if ((int)len >= password_len) {
/* pointless, but what can you do... */
return;
}
}
/****************************************************************************
main program
****************************************************************************/
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
{
.longName = "domains",
.shortName = 'D',
.argInfo = POPT_ARG_VAL,
.arg = &level,
.val = LEV_WORKGROUP,
.descrip = "List only domains (workgroups) of tree" ,
},
{
.longName = "servers",
.shortName = 'S',
.argInfo = POPT_ARG_VAL,
.arg = &level,
.val = LEV_SERVER,
.descrip = "List domains(workgroups) and servers of tree" ,
},
POPT_COMMON_SAMBA
POPT_COMMON_CREDENTIALS
POPT_TABLEEND
};
poptContext pc;
SMBCCTX *ctx = NULL;
SMBCFILE *workgroups = NULL;
struct smbc_dirent *dirent = NULL;
bool ok;
int ret, result = 1;
int debuglevel;
/* Initialise samba stuff */
smb_init_locale();
setlinebuf(stdout);
setup_logging(argv[0], DEBUG_STDERR);
popt_common_credentials_set_ignore_missing_conf();
pc = poptGetContext("smbtree", argc, argv_const, long_options,
POPT_CONTEXT_KEEP_FIRST);
while(poptGetNextOpt(pc) != -1);
popt_burn_cmdline_password(argc, argv);
debuglevel = DEBUGLEVEL;
ctx = smbc_new_context();
if (ctx == NULL) {
perror("smbc_new_context");
goto fail;
}
ret = smbc_setConfiguration(ctx, get_dyn_CONFIGFILE());
if (ret == -1) {
perror("smbc_setConfiguration");
goto fail;
}
smbc_setDebug(ctx, debuglevel);
ok = smbc_setOptionProtocols(ctx, NULL, "NT1");
if (!ok) {
perror("smbc_setOptionProtocols");
goto fail;
}
smbc_setFunctionAuthDataWithContext(
ctx, get_auth_data_with_context_fn);
ok = smbc_init_context(ctx);
if (!ok) {
perror("smbc_init_context");
goto fail;
}
workgroups = smbc_getFunctionOpendir(ctx)(ctx, "smb://");
if (workgroups == NULL) {
perror("smbc_opendir");
goto fail;
}
while ((dirent = smbc_getFunctionReaddir(ctx)(ctx, workgroups))
!= NULL) {
char *url = NULL;
SMBCFILE *servers = NULL;
if (dirent->smbc_type != SMBC_WORKGROUP) {
continue;
}
printf("%s\n", dirent->name);
if (level == LEV_WORKGROUP) {
continue;
}
url = talloc_asprintf(
talloc_tos(), "smb://%s/", dirent->name);
if (url == NULL) {
perror("talloc_asprintf");
goto fail;
}
servers = smbc_getFunctionOpendir(ctx)(ctx, url);
if (servers == NULL) {
perror("smbc_opendir");
goto fail;
}
TALLOC_FREE(url);
while ((dirent = smbc_getFunctionReaddir(ctx)(ctx, servers))
!= NULL) {
SMBCFILE *shares = NULL;
char *servername = NULL;
if (dirent->smbc_type != SMBC_SERVER) {
continue;
}
printf("\t\\\\%-15s\t\t%s\n",
dirent->name,
dirent->comment);
if (level == LEV_SERVER) {
continue;
}
/*
* The subsequent readdir for shares will
* overwrite the "server" readdir
*/
servername = talloc_strdup(talloc_tos(), dirent->name);
if (servername == NULL) {
continue;
}
url = talloc_asprintf(
talloc_tos(), "smb://%s/", servername);
if (url == NULL) {
perror("talloc_asprintf");
goto fail;
}
shares = smbc_getFunctionOpendir(ctx)(ctx, url);
if (shares == NULL) {
perror("smbc_opendir");
goto fail;
}
while ((dirent = smbc_getFunctionReaddir(
ctx)(ctx, shares))
!= NULL) {
printf("\t\t\\\\%s\\%-15s\t%s\n",
servername,
dirent->name,
dirent->comment);
}
ret = smbc_getFunctionClosedir(ctx)(ctx, shares);
if (ret == -1) {
perror("smbc_closedir");
goto fail;
}
TALLOC_FREE(servername);
TALLOC_FREE(url);
}
ret = smbc_getFunctionClosedir(ctx)(ctx, servers);
if (ret == -1) {
perror("smbc_closedir");
goto fail;
}
}
ret = smbc_getFunctionClosedir(ctx)(ctx, workgroups);
if (ret == -1) {
perror("smbc_closedir");
goto fail;
}
popt_free_cmdline_auth_info();
result = 0;
fail:
if (ctx != NULL) {
smbc_free_context(ctx, 0);
ctx = NULL;
}
poptFreeContext(pc);
TALLOC_FREE(frame);
return result;
}