1#include <sys/types.h> 2#include <unistd.h> 3#include <dirent.h> 4#include <errno.h> 5#include <stdio.h> 6#include <string.h> 7#include <popt.h> 8#include <stdlib.h> 9#include <libsmbclient.h> 10#include "get_auth_data_fn.h" 11 12static void 13no_auth_data_fn(const char * pServer, 14 const char * pShare, 15 char * pWorkgroup, 16 int maxLenWorkgroup, 17 char * pUsername, 18 int maxLenUsername, 19 char * pPassword, 20 int maxLenPassword); 21 22static void browse(char * path, 23 int scan, 24 int indent); 25 26 27static void 28get_auth_data_with_context_fn(SMBCCTX * context, 29 const char * pServer, 30 const char * pShare, 31 char * pWorkgroup, 32 int maxLenWorkgroup, 33 char * pUsername, 34 int maxLenUsername, 35 char * pPassword, 36 int maxLenPassword); 37 38int 39main(int argc, char * argv[]) 40{ 41 int debug = 0; 42 int debug_stderr = 0; 43 int no_auth = 0; 44 int context_auth = 0; 45 int scan = 0; 46 int iterations = -1; 47 int again; 48 int opt; 49 char * p; 50 char * q; 51 char buf[1024]; 52 poptContext pc; 53 SMBCCTX * context; 54 struct poptOption long_options[] = 55 { 56 POPT_AUTOHELP 57 { 58 "debug", 'd', POPT_ARG_INT, &debug, 59 0, "Set debug level", "integer" 60 }, 61 { 62 "stderr", 'e', POPT_ARG_NONE, &debug_stderr, 63 0, "Debug log to stderr instead of stdout", "integer" 64 }, 65 { 66 "scan", 's', POPT_ARG_NONE, &scan, 67 0, "Scan for servers and shares", "integer" 68 }, 69 { 70 "iterations", 'i', POPT_ARG_INT, &iterations, 71 0, "Iterations", "integer" 72 }, 73 { 74 "noauth", 'A', POPT_ARG_NONE, &no_auth, 75 0, "Do not request authentication data", "integer" 76 }, 77 { 78 "contextauth", 'C', POPT_ARG_NONE, &context_auth, 79 0, "Use new authentication function with context", "integer" 80 }, 81 { 82 NULL 83 } 84 }; 85 86 setbuf(stdout, NULL); 87 88 pc = poptGetContext("opendir", argc, (const char **)argv, long_options, 0); 89 90 poptSetOtherOptionHelp(pc, ""); 91 92 while ((opt = poptGetNextOpt(pc)) != -1) { 93 printf("Got option %d = %c\n", opt, opt); 94 switch (opt) { 95 } 96 } 97 98 /* Allocate a new context */ 99 context = smbc_new_context(); 100 if (!context) { 101 printf("Could not allocate new smbc context\n"); 102 return 1; 103 } 104 105 /* If we're scanning, do no requests for authentication data */ 106 if (scan) { 107 no_auth = 1; 108 } 109 110 /* Set mandatory options (is that a contradiction in terms?) */ 111 smbc_setDebug(context, debug); 112 if (context_auth) { 113 smbc_setFunctionAuthDataWithContext(context, 114 get_auth_data_with_context_fn); 115 smbc_setOptionUserData(context, "hello world"); 116 } else { 117 smbc_setFunctionAuthData(context, get_auth_data_fn); 118 } 119 120 smbc_setOptionUseKerberos(context, 1); 121 smbc_setOptionFallbackAfterKerberos(context, 1); 122 123 /* If we've been asked to log to stderr instead of stdout, ... */ 124 if (debug_stderr) { 125 /* ... then set the option to do so */ 126 smbc_setOptionDebugToStderr(context, 1); 127 } 128 129 /* Initialize the context using the previously specified options */ 130 if (!smbc_init_context(context)) { 131 smbc_free_context(context, 0); 132 printf("Could not initialize smbc context\n"); 133 return 1; 134 } 135 136 /* Tell the compatibility layer to use this context */ 137 smbc_set_context(context); 138 139 if (scan) 140 { 141 for (; 142 iterations == -1 || iterations > 0; 143 iterations = (iterations == -1 ? iterations : --iterations)) 144 { 145 snprintf(buf, sizeof(buf), "smb://"); 146 browse(buf, scan, 0); 147 } 148 } 149 else 150 { 151 for (; 152 iterations == -1 || iterations > 0; 153 iterations = (iterations == -1 ? iterations : --iterations)) 154 { 155 fputs("url: ", stdout); 156 p = fgets(buf, sizeof(buf), stdin); 157 if (! p) 158 { 159 break; 160 } 161 162 if ((p = strchr(buf, '\n')) != NULL) 163 { 164 *p = '\0'; 165 } 166 167 browse(buf, scan, 0); 168 } 169 } 170 171 exit(0); 172} 173 174 175static void 176no_auth_data_fn(const char * pServer, 177 const char * pShare, 178 char * pWorkgroup, 179 int maxLenWorkgroup, 180 char * pUsername, 181 int maxLenUsername, 182 char * pPassword, 183 int maxLenPassword) 184{ 185 return; 186} 187 188 189static void 190get_auth_data_with_context_fn(SMBCCTX * context, 191 const char * pServer, 192 const char * pShare, 193 char * pWorkgroup, 194 int maxLenWorkgroup, 195 char * pUsername, 196 int maxLenUsername, 197 char * pPassword, 198 int maxLenPassword) 199{ 200 printf("Authenticating with context %p", context); 201 if (context != NULL) { 202 char *user_data = smbc_getOptionUserData(context); 203 printf(" with user data %s", user_data); 204 } 205 printf("\n"); 206 207 get_auth_data_fn(pServer, pShare, pWorkgroup, maxLenWorkgroup, 208 pUsername, maxLenUsername, pPassword, maxLenPassword); 209} 210 211static void browse(char * path, int scan, int indent) 212{ 213 char * p; 214 char buf[1024]; 215 int dir; 216 struct stat stat; 217 struct smbc_dirent * dirent; 218 219 if (! scan) 220 { 221 printf("Opening (%s)...\n", path); 222 } 223 224 if ((dir = smbc_opendir(path)) < 0) 225 { 226 printf("Could not open directory [%s] (%d:%s)\n", 227 path, errno, strerror(errno)); 228 return; 229 } 230 231 while ((dirent = smbc_readdir(dir)) != NULL) 232 { 233 printf("%*.*s%-30s", indent, indent, "", dirent->name); 234 235 switch(dirent->smbc_type) 236 { 237 case SMBC_WORKGROUP: 238 printf("WORKGROUP"); 239 break; 240 241 case SMBC_SERVER: 242 printf("SERVER"); 243 break; 244 245 case SMBC_FILE_SHARE: 246 printf("FILE_SHARE"); 247 break; 248 249 case SMBC_PRINTER_SHARE: 250 printf("PRINTER_SHARE"); 251 break; 252 253 case SMBC_COMMS_SHARE: 254 printf("COMMS_SHARE"); 255 break; 256 257 case SMBC_IPC_SHARE: 258 printf("IPC_SHARE"); 259 break; 260 261 case SMBC_DIR: 262 printf("DIR"); 263 break; 264 265 case SMBC_FILE: 266 printf("FILE"); 267 268 p = path + strlen(path); 269 strcat(p, "/"); 270 strcat(p+1, dirent->name); 271 if (smbc_stat(path, &stat) < 0) 272 { 273 printf(" unknown size (reason %d: %s)", 274 errno, strerror(errno)); 275 } 276 else 277 { 278 printf(" size %lu", (unsigned long) stat.st_size); 279 } 280 *p = '\0'; 281 282 break; 283 284 case SMBC_LINK: 285 printf("LINK"); 286 break; 287 } 288 289 printf("\n"); 290 291 if (scan && 292 (dirent->smbc_type == SMBC_WORKGROUP || 293 dirent->smbc_type == SMBC_SERVER)) 294 { 295 /* 296 * don't append server name to workgroup; what we want is: 297 * 298 * smb://workgroup_name 299 * or 300 * smb://server_name 301 * 302 */ 303 snprintf(buf, sizeof(buf), "smb://%s", dirent->name); 304 browse(buf, scan, indent + 2); 305 } 306 } 307 308 smbc_closedir(dir); 309} 310 311