r12080: r10673@cabra: derrell | 2005-12-05 13:22:34 -0500
authorDerrell Lipman <derrell@samba.org>
Mon, 5 Dec 2005 23:30:40 +0000 (23:30 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 16:05:44 +0000 (11:05 -0500)
 Correct some memory and file descriptor leaks.

 This should fix bugs 3257, 3267 and 3273.
(This used to be commit c5781c9cf5f1f8297e084fbe2c4a22257420a447)

examples/libsmbclient/testbrowse.c
source3/libsmb/libsmbclient.c

index 27d6a6973882e377f6b4429d7ac14d742408872f..6fa70eab414c97372bd5c17251a8f8ade49ab51a 100644 (file)
@@ -9,24 +9,34 @@
 #include <libsmbclient.h>
 #include "get_auth_data_fn.h"
 
-void error_message(char * pMessage)
-{
-    printf("ERROR: %s\n", pMessage);
-}
+static void
+no_auth_data_fn(const char * pServer,
+                const char * pShare,
+                char * pWorkgroup,
+                int maxLenWorkgroup,
+                char * pUsername,
+                int maxLenUsername,
+                char * pPassword,
+                int maxLenPassword);
+
+static void browse(char * path,
+                   int scan,
+                   int indent);
+
 
 
 int
 main(int argc, char * argv[])
 {
     int                         debug = 0;
+    int                         scan = 0;
+    int                         iterations = -1;
+    int                         again;
     int                         opt;
     char *                      p;
     char *                      q;
     char                        buf[1024];
-    int                         dir;
-    struct stat                 stat;
-    struct smbc_dirent *        dirent;
-    poptContext pc;
+    poptContext                 pc;
     struct poptOption           long_options[] =
         {
             POPT_AUTOHELP
@@ -34,6 +44,14 @@ main(int argc, char * argv[])
                 "debug", 'd', POPT_ARG_INT, &debug,
                 0, "Set debug level", "integer"
             },
+            {
+                "scan", 's', POPT_ARG_NONE, &scan,
+                0, "Scan for servers and shares", "integer"
+            },
+            {
+                "iterations", 'i', POPT_ARG_INT, &iterations,
+                0, "Iterations", "integer"
+            },
             {
                 NULL
             }
@@ -51,94 +69,164 @@ main(int argc, char * argv[])
         }
     }
 
-    if (smbc_init(get_auth_data_fn, debug) != 0)
+    if (scan)
     {
-        printf("Could not initialize smbc_ library\n");
-        return 1;
+        if (smbc_init(no_auth_data_fn, debug) != 0)
+        {
+            printf("Could not initialize smbc_ library\n");
+            return 1;
+        }
+
+        for (;
+             iterations == -1 || iterations > 0;
+             iterations = (iterations == -1 ? iterations : --iterations))
+        {
+            snprintf(buf, sizeof(buf), "smb://");
+            browse(buf, scan, 0);
+        }
     }
-    
-    for (fputs("url: ", stdout), p = fgets(buf, sizeof(buf), stdin);
-         p != NULL && *p != '\n' && *p != '\0';
-         fputs("url: ", stdout), p = fgets(buf, sizeof(buf), stdin))
+    else
     {
-        if ((p = strchr(buf, '\n')) != NULL)
+        if (smbc_init(get_auth_data_fn, debug) != 0)
         {
-            *p = '\0';
+            printf("Could not initialize smbc_ library\n");
+            return 1;
         }
-        
-        printf("Opening (%s)...\n", buf);
-        
-        if ((dir = smbc_opendir(buf)) < 0)
+    
+        for (;
+             iterations == -1 || iterations > 0;
+             iterations = (iterations == -1 ? iterations : --iterations))
         {
-            printf("Could not open directory [%s] (%d:%s)\n",
-                   buf, errno, strerror(errno));
-            continue;
+            fputs("url: ", stdout);
+            p = fgets(buf, sizeof(buf), stdin);
+            if (! p)
+            {
+                break;
+            }
+
+            if ((p = strchr(buf, '\n')) != NULL)
+            {
+                *p = '\0';
+            }
+            
+            browse(buf, scan, 0);
         }
+    }
 
-        while ((dirent = smbc_readdir(dir)) != NULL)
-        {
-            printf("%-30s", dirent->name);
-            printf("%-30s", dirent->comment);
+    exit(0);
+}
 
-            switch(dirent->smbc_type)
-            {
-            case SMBC_WORKGROUP:
-                printf("WORKGROUP");
-                break;
+
+static void
+no_auth_data_fn(const char * pServer,
+                const char * pShare,
+                char * pWorkgroup,
+                int maxLenWorkgroup,
+                char * pUsername,
+                int maxLenUsername,
+                char * pPassword,
+                int maxLenPassword)
+{
+    return;
+}
+
+static void browse(char * path, int scan, int indent)
+{
+    char *                      p;
+    char                        buf[1024];
+    int                         dir;
+    struct stat                 stat;
+    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_SERVER:
+            printf("SERVER");
+            break;
             
-            case SMBC_FILE_SHARE:
-                printf("FILE_SHARE");
-                break;
+        case SMBC_FILE_SHARE:
+            printf("FILE_SHARE");
+            break;
             
-            case SMBC_PRINTER_SHARE:
-                printf("PRINTER_SHARE");
-                break;
+        case SMBC_PRINTER_SHARE:
+            printf("PRINTER_SHARE");
+            break;
             
-            case SMBC_COMMS_SHARE:
-                printf("COMMS_SHARE");
-                break;
+        case SMBC_COMMS_SHARE:
+            printf("COMMS_SHARE");
+            break;
             
-            case SMBC_IPC_SHARE:
-                printf("IPC_SHARE");
-                break;
+        case SMBC_IPC_SHARE:
+            printf("IPC_SHARE");
+            break;
             
-            case SMBC_DIR:
-                printf("DIR");
-                break;
+        case SMBC_DIR:
+            printf("DIR");
+            break;
             
-            case SMBC_FILE:
-                printf("FILE");
-
-                q = buf + strlen(buf);
-                strcat(q, "/");
-                strcat(q+1, dirent->name);
-                if (smbc_stat(buf, &stat) < 0)
-                {
-                    printf(" unknown size (reason %d: %s)",
-                           errno, strerror(errno));
-                }
-                else
-                {
-                    printf(" size %lu", (unsigned long) stat.st_size);
-                }
-                *p = '\0';
+        case SMBC_FILE:
+            printf("FILE");
 
-                break;
-            
-            case SMBC_LINK:
-                printf("LINK");
-                break;
+            p = path + strlen(path);
+            strcat(p, "/");
+            strcat(p+1, dirent->name);
+            if (smbc_stat(path, &stat) < 0)
+            {
+                printf(" unknown size (reason %d: %s)",
+                       errno, strerror(errno));
             }
+            else
+            {
+                printf(" size %lu", (unsigned long) stat.st_size);
+            }
+            *p = '\0';
 
-            printf("\n");
+            break;
+            
+        case SMBC_LINK:
+            printf("LINK");
+            break;
         }
 
-        smbc_closedir(dir);
+        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);
+        }
     }
 
-    exit(0);
+    smbc_closedir(dir);
 }
+    
index f180072a70cf42e099aee90041ff47715c39550c..f482c9584f8d6207d9f4434bc4c074ca51ad19bc 100644 (file)
@@ -584,9 +584,25 @@ SMBCSRV *smbc_server(SMBCCTX *context,
                return NULL;
        }
 
+#if 0 /* choice 1 */
+        /* Look for a cached connection, using the provided authinfo */
         srv = find_server(context, server, share,
                           workgroup, username, password);
 
+        /* If we didn't find one... */
+        if (! srv)
+        {
+            /* ... then see if there's one using anonymous login */
+            fstring anonymous = "";
+            srv = find_server(context, server, share,
+                              workgroup, anonymous, password);
+        }
+#else
+        /* Look for a cached connection */
+        srv = find_server(context, server, share,
+                          workgroup, username, password);
+#endif
+        
         /*
          * If we found a connection and we're only allowed one share per
          * server...
@@ -780,7 +796,11 @@ SMBCSRV *smbc_server(SMBCCTX *context,
        /* now add it to the cache (internal or external)  */
        /* Let the cache function set errno if it wants to */
        errno = 0;
+#if 0 /* choice 2 */
        if (context->callbacks.add_cached_srv_fn(context, srv, server, share, workgroup, username_used)) {
+#else
+       if (context->callbacks.add_cached_srv_fn(context, srv, server, share, workgroup, username)) {
+#endif
                int saved_errno = errno;
                DEBUG(3, (" Failed to add server to cache\n"));
                errno = saved_errno;
@@ -2169,6 +2189,7 @@ list_unique_wg_fn(const char *name, uint32 type, const char *comment, void *stat
                         /* Found the end of the list.  Remove it. */
                         dir->dir_end = dir_list;
                         free(dir_list->next);
+                        free(dirent);
                         dir_list->next = NULL;
                         break;
                 }
@@ -2337,7 +2358,11 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname)
                  * a single master browser.
                  */
 
+                ip_list = NULL;
                 if (!name_resolve_bcast(MSBROWSE, 1, &ip_list, &count)) {
+
+                        SAFE_FREE(ip_list);
+
                         if (!find_master_ip(workgroup, &server_addr.ip)) {
 
                                 errno = ENOENT;
@@ -2383,9 +2408,16 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname)
                         if (!cli_NetServerEnum(&srv->cli, workgroup, SV_TYPE_DOMAIN_ENUM, list_unique_wg_fn,
                                                (void *)dir)) {
                                 
+                                if (dir) {
+                                        SAFE_FREE(dir->fname);
+                                        SAFE_FREE(dir);
+                                }
+
                                 continue;
                         }
                 }
+
+                SAFE_FREE(ip_list);
         } else { 
                 /*
                  * Server not an empty string ... Check the rest and see what