mirror of
https://github.com/samba-team/samba.git
synced 2024-12-23 17:34:34 +03:00
c8519003a3
Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Andrew Bartlett <abartlet@samba.org>
285 lines
7.7 KiB
C
285 lines
7.7 KiB
C
#include <sys/types.h>
|
|
#include <unistd.h>
|
|
#include <dirent.h>
|
|
#include <errno.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <popt.h>
|
|
#include <stdlib.h>
|
|
#include <libsmbclient.h>
|
|
#include "get_auth_data_fn.h"
|
|
|
|
static void browse(char * path,
|
|
int scan,
|
|
int indent);
|
|
|
|
|
|
static void
|
|
get_auth_data_with_context_fn(SMBCCTX * context,
|
|
const char * pServer,
|
|
const char * pShare,
|
|
char * pWorkgroup,
|
|
int maxLenWorkgroup,
|
|
char * pUsername,
|
|
int maxLenUsername,
|
|
char * pPassword,
|
|
int maxLenPassword);
|
|
|
|
int main(int argc, const char *argv[])
|
|
{
|
|
int debug = 0;
|
|
int debug_stderr = 0;
|
|
int no_auth = 0;
|
|
int context_auth = 0;
|
|
int scan = 0;
|
|
int iterations = -1;
|
|
int opt;
|
|
char * p;
|
|
char buf[1024];
|
|
poptContext pc;
|
|
SMBCCTX * context;
|
|
struct poptOption long_options[] =
|
|
{
|
|
POPT_AUTOHELP
|
|
{
|
|
"debug", 'd', POPT_ARG_INT, &debug,
|
|
0, "Set debug level", "integer"
|
|
},
|
|
{
|
|
"stderr", 'e', POPT_ARG_NONE, &debug_stderr,
|
|
0, "Debug log to stderr instead of stdout", "integer"
|
|
},
|
|
{
|
|
"scan", 's', POPT_ARG_NONE, &scan,
|
|
0, "Scan for servers and shares", "integer"
|
|
},
|
|
{
|
|
"iterations", 'i', POPT_ARG_INT, &iterations,
|
|
0, "Iterations", "integer"
|
|
},
|
|
{
|
|
"noauth", 'A', POPT_ARG_NONE, &no_auth,
|
|
0, "Do not request authentication data", "integer"
|
|
},
|
|
{
|
|
"contextauth", 'C', POPT_ARG_NONE, &context_auth,
|
|
0, "Use new authentication function with context", "integer"
|
|
},
|
|
{
|
|
NULL
|
|
}
|
|
};
|
|
|
|
setbuf(stdout, NULL);
|
|
|
|
pc = poptGetContext("opendir", argc, argv, long_options, 0);
|
|
|
|
poptSetOtherOptionHelp(pc, "");
|
|
|
|
while ((opt = poptGetNextOpt(pc)) != -1) {
|
|
printf("Got option %d = %c\n", opt, opt);
|
|
switch (opt) {
|
|
}
|
|
}
|
|
|
|
/* Allocate a new context */
|
|
context = smbc_new_context();
|
|
if (!context) {
|
|
printf("Could not allocate new smbc context\n");
|
|
return 1;
|
|
}
|
|
|
|
/* If we're scanning, do no requests for authentication data */
|
|
if (scan) {
|
|
no_auth = 1;
|
|
}
|
|
|
|
/* Set mandatory options (is that a contradiction in terms?) */
|
|
smbc_setDebug(context, debug);
|
|
if (context_auth) {
|
|
smbc_setFunctionAuthDataWithContext(context,
|
|
get_auth_data_with_context_fn);
|
|
smbc_setOptionUserData(context, strdup("hello world"));
|
|
} else {
|
|
smbc_setFunctionAuthData(context, get_auth_data_fn);
|
|
}
|
|
|
|
smbc_setOptionUseKerberos(context, 1);
|
|
smbc_setOptionFallbackAfterKerberos(context, 1);
|
|
|
|
/* If we've been asked to log to stderr instead of stdout, ... */
|
|
if (debug_stderr) {
|
|
/* ... then set the option to do so */
|
|
smbc_setOptionDebugToStderr(context, 1);
|
|
}
|
|
|
|
/* Initialize the context using the previously specified options */
|
|
if (!smbc_init_context(context)) {
|
|
smbc_free_context(context, 0);
|
|
printf("Could not initialize smbc context\n");
|
|
return 1;
|
|
}
|
|
|
|
/* Tell the compatibility layer to use this context */
|
|
smbc_set_context(context);
|
|
|
|
if (scan)
|
|
{
|
|
for (; iterations != 0;) {
|
|
if (iterations > 0) {
|
|
iterations--;
|
|
}
|
|
|
|
snprintf(buf, sizeof(buf), "smb://");
|
|
browse(buf, scan, 0);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (; iterations != 0;) {
|
|
if (iterations > 0) {
|
|
iterations--;
|
|
}
|
|
|
|
fputs("url: ", stdout);
|
|
p = fgets(buf, sizeof(buf), stdin);
|
|
if (! p)
|
|
{
|
|
break;
|
|
}
|
|
|
|
if ((p = strchr(buf, '\n')) != NULL)
|
|
{
|
|
*p = '\0';
|
|
}
|
|
|
|
browse(buf, scan, 0);
|
|
}
|
|
}
|
|
|
|
exit(0);
|
|
}
|
|
|
|
static void
|
|
get_auth_data_with_context_fn(SMBCCTX * context,
|
|
const char * pServer,
|
|
const char * pShare,
|
|
char * pWorkgroup,
|
|
int maxLenWorkgroup,
|
|
char * pUsername,
|
|
int maxLenUsername,
|
|
char * pPassword,
|
|
int maxLenPassword)
|
|
{
|
|
printf("Authenticating with context %p", context);
|
|
if (context != NULL) {
|
|
char *user_data = smbc_getOptionUserData(context);
|
|
printf(" with user data %s", user_data);
|
|
}
|
|
printf("\n");
|
|
|
|
get_auth_data_fn(pServer, pShare, pWorkgroup, maxLenWorkgroup,
|
|
pUsername, maxLenUsername, pPassword, maxLenPassword);
|
|
}
|
|
|
|
static void browse(char * path, int scan, int indent)
|
|
{
|
|
char * p;
|
|
char buf[1024];
|
|
int dir;
|
|
struct stat st;
|
|
struct smbc_dirent * dirent;
|
|
|
|
if (! scan)
|
|
{
|
|
printf("Opening (%s)...\n", path);
|
|
}
|
|
|
|
if ((dir = smbc_opendir(path)) < 0)
|
|
{
|
|
printf("Could not open directory [%s] (%d:%s)\n",
|
|
path, errno, strerror(errno));
|
|
return;
|
|
}
|
|
|
|
while ((dirent = smbc_readdir(dir)) != NULL)
|
|
{
|
|
printf("%*.*s%-30s", indent, indent, "", dirent->name);
|
|
|
|
switch(dirent->smbc_type)
|
|
{
|
|
case SMBC_WORKGROUP:
|
|
printf("WORKGROUP");
|
|
break;
|
|
|
|
case SMBC_SERVER:
|
|
printf("SERVER");
|
|
break;
|
|
|
|
case SMBC_FILE_SHARE:
|
|
printf("FILE_SHARE");
|
|
break;
|
|
|
|
case SMBC_PRINTER_SHARE:
|
|
printf("PRINTER_SHARE");
|
|
break;
|
|
|
|
case SMBC_COMMS_SHARE:
|
|
printf("COMMS_SHARE");
|
|
break;
|
|
|
|
case SMBC_IPC_SHARE:
|
|
printf("IPC_SHARE");
|
|
break;
|
|
|
|
case SMBC_DIR:
|
|
printf("DIR");
|
|
break;
|
|
|
|
case SMBC_FILE:
|
|
printf("FILE");
|
|
|
|
p = path + strlen(path);
|
|
strcat(p, "/");
|
|
strcat(p+1, dirent->name);
|
|
if (smbc_stat(path, &st) < 0)
|
|
{
|
|
printf(" unknown size (reason %d: %s)",
|
|
errno, strerror(errno));
|
|
}
|
|
else
|
|
{
|
|
printf(" size %lu", (unsigned long) st.st_size);
|
|
}
|
|
*p = '\0';
|
|
|
|
break;
|
|
|
|
case SMBC_LINK:
|
|
printf("LINK");
|
|
break;
|
|
}
|
|
|
|
printf("\n");
|
|
|
|
if (scan &&
|
|
(dirent->smbc_type == SMBC_WORKGROUP ||
|
|
dirent->smbc_type == SMBC_SERVER))
|
|
{
|
|
/*
|
|
* don't append server name to workgroup; what we want is:
|
|
*
|
|
* smb://workgroup_name
|
|
* or
|
|
* smb://server_name
|
|
*
|
|
*/
|
|
snprintf(buf, sizeof(buf), "smb://%s", dirent->name);
|
|
browse(buf, scan, indent + 2);
|
|
}
|
|
}
|
|
|
|
smbc_closedir(dir);
|
|
}
|
|
|