Add talloc versions of all the next_token() functions.
authorJeremy Allison <jra@samba.org>
Fri, 30 Nov 2007 21:09:04 +0000 (13:09 -0800)
committerJeremy Allison <jra@samba.org>
Fri, 30 Nov 2007 21:09:04 +0000 (13:09 -0800)
Now I can really start removing fixed length strings...
Jeremy.
(This used to be commit 0ae61e26547e594e94037d4474a008221e5df8cf)

source3/lib/util_str.c
source3/libsmb/libsmbclient.c

index f5a50b360e5afa3934c4c4487cff8a3d21816c06..886ae2a0436af165a73963c0b14e1e9794bd6fa1 100644 (file)
@@ -85,6 +85,73 @@ static bool next_token_internal(const char **ptr,
        return(true);
 }
 
+static bool next_token_internal_talloc(TALLOC_CTX *ctx,
+                               const char **ptr,
+                                char **pp_buff,
+                                const char *sep,
+                                bool ltrim)
+{
+       char *s;
+       char *pbuf;
+       bool quoted;
+       size_t len=1;
+
+       *pp_buff = NULL;
+       if (!ptr) {
+               return(false);
+       }
+
+       s = (char *)*ptr;
+
+       /* default to simple separators */
+       if (!sep) {
+               sep = " \t\n\r";
+       }
+
+       /* find the first non sep char, if left-trimming is requested */
+       if (ltrim) {
+               while (*s && strchr_m(sep,*s))
+                       s++;
+       }
+
+       /* nothing left? */
+       if (!*s) {
+               return(false);
+       }
+
+       /* Work out the length needed. */
+       for (quoted = false; *s &&
+                       (quoted || !strchr_m(sep,*s)); s++) {
+               if (*s == '\"') {
+                       quoted = !quoted;
+               } else {
+                       len++;
+               }
+       }
+
+       /* We started with len = 1 so we have space for the nul. */
+       *pp_buff = TALLOC_ARRAY(ctx, char, len);
+       if (!*pp_buff) {
+               return false;
+       }
+
+       /* copy over the token */
+       pbuf = *pp_buff;
+       for (quoted = false; *s &&
+                       (quoted || !strchr_m(sep,*s)); s++) {
+               if ( *s == '\"' ) {
+                       quoted = !quoted;
+               } else {
+                       *pbuf++ = *s;
+               }
+       }
+
+       *ptr = (*s) ? s+1 : s;
+       *pbuf = 0;
+
+       return true;
+}
+
 /*
  * Get the next token from a string, return false if none found.  Handles
  * double-quotes.  This version trims leading separator characters before
@@ -92,7 +159,15 @@ static bool next_token_internal(const char **ptr,
  */
 bool next_token(const char **ptr, char *buff, const char *sep, size_t bufsize)
 {
-    return next_token_internal(ptr, buff, sep, bufsize, true);
+       return next_token_internal(ptr, buff, sep, bufsize, true);
+}
+
+bool next_token_talloc(TALLOC_CTX *ctx,
+                       const char **ptr,
+                       char **pp_buff,
+                       const char *sep)
+{
+       return next_token_internal_talloc(ctx, ptr, pp_buff, sep, true);
 }
 
 /*
@@ -105,7 +180,15 @@ bool next_token_no_ltrim(const char **ptr,
                          const char *sep,
                          size_t bufsize)
 {
-    return next_token_internal(ptr, buff, sep, bufsize, false);
+       return next_token_internal(ptr, buff, sep, bufsize, false);
+}
+
+bool next_token_no_ltrim_talloc(TALLOC_CTX *ctx,
+                       const char **ptr,
+                       char **pp_buff,
+                       const char *sep)
+{
+       return next_token_internal_talloc(ctx, ptr, pp_buff, sep, false);
 }
 
 /**
@@ -119,14 +202,30 @@ static const char *last_ptr=NULL;
 bool next_token_nr(const char **ptr,char *buff, const char *sep, size_t bufsize)
 {
        bool ret;
-       if (!ptr)
+       if (!ptr) {
                ptr = &last_ptr;
+       }
 
        ret = next_token(ptr, buff, sep, bufsize);
        last_ptr = *ptr;
        return ret;
 }
 
+bool next_token_nr_talloc(TALLOC_CTX *ctx,
+                               const char **ptr,
+                               char **pp_buff,
+                               const char *sep)
+{
+       bool ret;
+       if (!ptr) {
+               ptr = &last_ptr;
+       }
+
+       ret = next_token_talloc(ctx, ptr, pp_buff, sep);
+       last_ptr = *ptr;
+       return ret;
+}
+
 void set_first_token(char *ptr)
 {
        last_ptr = ptr;
index b20b1cadaf8b240229aa2a2a156bbd922e5fac1c..c81002b9cca8212ade81ce92fc6c32861d592e48 100644 (file)
@@ -132,6 +132,7 @@ hex2int( unsigned int _char )
 
 /*
  * smbc_urldecode()
+ * and smbc_urldecode_talloc() (internal fn.)
  *
  * Convert strings of %xx to their single character equivalent.  Each 'x' must
  * be a valid hexadecimal digit, or that % sequence is left undecoded.
@@ -141,53 +142,87 @@ hex2int( unsigned int _char )
  * Returns the number of % sequences which could not be converted due to lack
  * of two following hexadecimal digits.
  */
-int
-smbc_urldecode(char *dest, char * src, size_t max_dest_len)
+static int
+smbc_urldecode_talloc(TALLOC_CTX *ctx, char **pp_dest, const char *src)
 {
-        int old_length = strlen(src);
-        int i = 0;
-        int err_count = 0;
-        pstring temp;
-        char * p;
+       int old_length = strlen(src);
+       int i = 0;
+       int err_count = 0;
+       size_t newlen = 1;
+       char *p, *dest;
+
+       *pp_dest = NULL;
+       if (old_length == 0) {
+               return 0;
+       }
 
-        if ( old_length == 0 ) {
-                return 0;
-        }
+       for (i = 0; i < old_length; ) {
+               unsigned char character = src[i++];
+
+               if (character == '%') {
+                       int a = i+1 < old_length ? hex2int(src[i]) : -1;
+                       int b = i+1 < old_length ? hex2int(src[i+1]) : -1;
 
-        p = temp;
-        while ( i < old_length ) {
-                unsigned char character = src[ i++ ];
+                       /* Replace valid sequence */
+                       if (a != -1 && b != -1) {
+                               /* Replace valid %xx sequence with %dd */
+                               character = (a * 16) + b;
+                               if (character == '\0') {
+                                       break; /* Stop at %00 */
+                               }
+                               i += 2;
+                       } else {
+                               err_count++;
+                       }
+               }
+               newlen++;
+       }
+
+       dest = TALLOC_ARRAY(ctx, char, newlen);
+       if (!dest) {
+               return err_count;
+       }
+
+       err_count = 0;
+       for (p = dest, i = 0; i < old_length; ) {
+                unsigned char character = src[i++];
 
                 if (character == '%') {
-                        int a = i+1 < old_length ? hex2int( src[i] ) : -1;
-                        int b = i+1 < old_length ? hex2int( src[i+1] ) : -1;
+                        int a = i+1 < old_length ? hex2int(src[i]) : -1;
+                        int b = i+1 < old_length ? hex2int(src[i+1]) : -1;
 
                         /* Replace valid sequence */
                         if (a != -1 && b != -1) {
-
                                 /* Replace valid %xx sequence with %dd */
                                 character = (a * 16) + b;
-
                                 if (character == '\0') {
                                         break; /* Stop at %00 */
                                 }
-
                                 i += 2;
                         } else {
-
                                 err_count++;
                         }
                 }
-
                 *p++ = character;
         }
 
         *p = '\0';
+       *pp_dest = dest;
+        return err_count;
+}
 
-        strncpy(dest, temp, max_dest_len - 1);
-        dest[max_dest_len - 1] = '\0';
+int
+smbc_urldecode(char *dest, char *src, size_t max_dest_len)
+{
+       TALLOC_CTX *frame = talloc_stackframe();
+       char *pdest;
+       int ret = smbc_urldecode_talloc(frame, &pdest, src);
 
-        return err_count;
+       if (pdest) {
+               strlcpy(dest, pdest, max_dest_len);
+       }
+       TALLOC_FREE(frame);
+       return ret;
 }
 
 /*
@@ -199,7 +234,7 @@ smbc_urldecode(char *dest, char * src, size_t max_dest_len)
  * Returns the remaining buffer length.
  */
 int
-smbc_urlencode(char * dest, char * src, int max_dest_len)
+smbc_urlencode(char *dest, char *src, int max_dest_len)
 {
         char hex[] = "0123456789ABCDEF";
 
@@ -226,7 +261,7 @@ smbc_urlencode(char * dest, char * src, int max_dest_len)
 
         *dest++ = '\0';
         max_dest_len--;
-        
+
         return max_dest_len;
 }
 
@@ -270,37 +305,46 @@ smbc_urlencode(char * dest, char * src, int max_dest_len)
 static const char *smbc_prefix = "smb:";
 
 static int
-smbc_parse_path(SMBCCTX *context,
+smbc_parse_path(TALLOC_CTX *ctx,
+               SMBCCTX *context,
                 const char *fname,
-                char *workgroup, int workgroup_len,
-                char *server, int server_len,
-                char *share, int share_len,
-                char *path, int path_len,
-               char *user, int user_len,
-                char *password, int password_len,
-                char *options, int options_len)
+                char **pp_workgroup,
+                char **pp_server,
+                char **pp_share,
+                char **pp_path,
+               char **pp_user,
+                char **pp_password,
+                char **pp_options)
 {
-       static pstring s;
-       pstring userinfo;
+       char *s;
        const char *p;
        char *q, *r;
        int len;
 
-       server[0] = share[0] = path[0] = user[0] = password[0] = (char)0;
+       /* Ensure these returns are at least valid pointers. */
+       *pp_server = talloc_strdup(ctx, "");
+       *pp_share = talloc_strdup(ctx, "");
+       *pp_path = talloc_strdup(ctx, "");
+       *pp_user = talloc_strdup(ctx, "");
+       *pp_password = talloc_strdup(ctx, "");
+
+       if (!*pp_server || !*pp_share || !*pp_path ||
+                       !*pp_user || !*pp_password) {
+               return -1;
+       }
 
         /*
          * Assume we wont find an authentication domain to parse, so default
          * to the workgroup in the provided context.
          */
-        if (workgroup != NULL) {
-                strncpy(workgroup, context->workgroup, workgroup_len - 1);
-                workgroup[workgroup_len - 1] = '\0';
-        }
+       if (pp_workgroup != NULL) {
+               *pp_workgroup = talloc_strdup(ctx, context->workgroup);
+       }
 
-        if (options != NULL && options_len > 0) {
-                options[0] = (char)0;
-        }
-       pstrcpy(s, fname);
+       if (pp_options) {
+               *pp_options = talloc_strdup(ctx, "");
+       }
+       s = talloc_strdup(ctx, fname);
 
        /* see if it has the right prefix */
        len = strlen(smbc_prefix);
@@ -313,10 +357,8 @@ smbc_parse_path(SMBCCTX *context,
        /* Watch the test below, we are testing to see if we should exit */
 
        if (strncmp(p, "//", 2) && strncmp(p, "\\\\", 2)) {
-
                 DEBUG(1, ("Invalid path (does not begin with smb://"));
                return -1;
-
        }
 
        p += 2;  /* Skip the double slash */
@@ -325,17 +367,19 @@ smbc_parse_path(SMBCCTX *context,
         if ((q = strrchr(p, '?')) != NULL ) {
                 /* There are options.  Null terminate here and point to them */
                 *q++ = '\0';
-                
+
                 DEBUG(4, ("Found options '%s'", q));
 
-                /* Copy the options */
-                if (options != NULL && options_len > 0) {
-                        safe_strcpy(options, q, options_len - 1);
-                }
-        }
+               /* Copy the options */
+               if (*pp_options != NULL) {
+                       TALLOC_FREE(*pp_options);
+                       *pp_options = talloc_strdup(ctx, q);
+               }
+       }
 
-       if (*p == (char)0)
-           goto decoding;
+       if (*p == '\0') {
+               goto decoding;
+       }
 
        if (*p == '/') {
                int wl = strlen(context->workgroup);
@@ -344,13 +388,16 @@ smbc_parse_path(SMBCCTX *context,
                        wl = 16;
                }
 
-               strncpy(server, context->workgroup, wl);
-                server[wl] = '\0';
+               *pp_server = talloc_strdup(ctx, context->workgroup);
+               if (!*pp_server) {
+                       return -1;
+               }
+                       *pp_server[wl] = '\0';
                return 0;
        }
 
        /*
-        * ok, its for us. Now parse out the server, share etc. 
+        * ok, its for us. Now parse out the server, share etc.
         *
         * However, we want to parse out [[domain;]user[:password]@] if it
         * exists ...
@@ -360,81 +407,78 @@ smbc_parse_path(SMBCCTX *context,
        q = strchr_m(p, '@');
        r = strchr_m(p, '/');
        if (q && (!r || q < r)) {
-               pstring username, passwd, domain;
-               const char *u = userinfo;
-
-               next_token_no_ltrim(&p, userinfo, "@", sizeof(fstring));
+               char *userinfo = NULL;
+               const char *u;
 
-               username[0] = passwd[0] = domain[0] = 0;
+               next_token_no_ltrim_talloc(ctx, &p, &userinfo, "@");
+               if (!userinfo) {
+                       return -1;
+               }
+               u = userinfo;
 
                if (strchr_m(u, ';')) {
-      
-                       next_token_no_ltrim(&u, domain, ";", sizeof(fstring));
-
+                       char *workgroup;
+                       next_token_no_ltrim_talloc(ctx, &u, &workgroup, ";");
+                       if (!workgroup) {
+                               return -1;
+                       }
+                       if (pp_workgroup) {
+                               *pp_workgroup = workgroup;
+                       }
                }
 
                if (strchr_m(u, ':')) {
-
-                       next_token_no_ltrim(&u, username, ":", sizeof(fstring));
-
-                       pstrcpy(passwd, u);
-
-               }
-               else {
-
-                       pstrcpy(username, u);
-
+                       next_token_no_ltrim_talloc(ctx, &u, pp_user, ":");
+                       if (!*pp_user) {
+                               return -1;
+                       }
+                       *pp_password = talloc_strdup(ctx, u);
+                       if (!*pp_password) {
+                               return -1;
+                       }
+               } else {
+                       *pp_user = talloc_strdup(ctx, u);
+                       if (!*pp_user) {
+                               return -1;
+                       }
                }
-
-                if (domain[0] && workgroup) {
-                        strncpy(workgroup, domain, workgroup_len - 1);
-                        workgroup[workgroup_len - 1] = '\0';
-                }
-
-               if (username[0]) {
-                       strncpy(user, username, user_len - 1);
-                        user[user_len - 1] = '\0';
-                }
-
-               if (passwd[0]) {
-                       strncpy(password, passwd, password_len - 1);
-                        password[password_len - 1] = '\0';
-                }
-
        }
 
-       if (!next_token(&p, server, "/", sizeof(fstring))) {
-
+       if (!next_token_talloc(ctx, &p, pp_server, "/")) {
                return -1;
-
        }
 
-       if (*p == (char)0) goto decoding;  /* That's it ... */
-  
-       if (!next_token(&p, share, "/", sizeof(fstring))) {
+       if (*p == (char)0) {
+               goto decoding;  /* That's it ... */
+       }
 
+       if (!next_token_talloc(ctx, &p, pp_share, "/")) {
                return -1;
-
        }
 
         /*
          * Prepend a leading slash if there's a file path, as required by
          * NetApp filers.
          */
-        *path = '\0';
         if (*p != '\0') {
-                *path = '/';
-                safe_strcpy(path + 1, p, path_len - 2);
-        }
-
-       all_string_sub(path, "/", "\\", 0);
+               *pp_path = talloc_asprintf(ctx,
+                                       "\\%s",
+                                       p);
+        } else {
+               *pp_path = talloc_strdup(ctx, "");
+       }
+       if (!*pp_path) {
+               return -1;
+       }
+       string_replace(*pp_path, '/', '\\');
 
  decoding:
-       (void) smbc_urldecode(path, path, path_len);
-       (void) smbc_urldecode(server, server, server_len);
-       (void) smbc_urldecode(share, share, share_len);
-       (void) smbc_urldecode(user, user, user_len);
-       (void) smbc_urldecode(password, password, password_len);
+
+       (void) smbc_urldecode_talloc(ctx, pp_path, *pp_path);
+       (void) smbc_urldecode_talloc(ctx, pp_server, *pp_server);
+       (void) smbc_urldecode_talloc(ctx, pp_share, *pp_share);
+       (void) smbc_urldecode_talloc(ctx, pp_user, *pp_user);
+       (void) smbc_urldecode_talloc(ctx, pp_password, *pp_password);
 
        return 0;
 }
@@ -558,7 +602,7 @@ find_server(SMBCCTX *context,
 {
         SMBCSRV *srv;
         int auth_called = 0;
-        
+
  check_server_cache:
 
        srv = (context->callbacks.get_cached_srv_fn)(context, server, share, 
@@ -646,7 +690,6 @@ smbc_server(SMBCCTX *context,
        struct cli_state *c;
        struct nmb_name called, calling;
        const char *server_n = server;
-       pstring ipenv;
        struct sockaddr_storage ss;
        int tried_reverse = 0;
         int port_try_first;
@@ -740,7 +783,6 @@ smbc_server(SMBCCTX *context,
        DEBUG(4,(" -> server_n=[%s] server=[%s]\n", server_n, server));
 
  again:
-       slprintf(ipenv,sizeof(ipenv)-1,"HOST_%s", server_n);
 
        zero_addr(&ss);
 
@@ -1053,8 +1095,8 @@ smbc_open_ctx(SMBCCTX *context,
               int flags,
               mode_t mode)
 {
-       fstring server, share, user, password, workgroup;
-       pstring path;
+       char *server, *share, *user, *password, *workgroup;
+       char *path;
        char *targetpath = NULL;
        struct cli_state *targetcli;
        SMBCSRV *srv   = NULL;
@@ -1079,30 +1121,37 @@ smbc_open_ctx(SMBCCTX *context,
 
        }
 
-       if (smbc_parse_path(context, fname,
-                            workgroup, sizeof(workgroup),
-                            server, sizeof(server),
-                            share, sizeof(share),
-                            path, sizeof(path),
-                            user, sizeof(user),
-                            password, sizeof(password),
-                            NULL, 0)) {
-                errno = EINVAL;
+       if (smbc_parse_path(frame,
+                               context,
+                               fname,
+                               &workgroup,
+                               &server,
+                               &share,
+                               &path,
+                               &user,
+                               &password,
+                               NULL)) {
+               errno = EINVAL;
                TALLOC_FREE(frame);
-                return NULL;
+               return NULL;
         }
 
-       if (user[0] == (char)0) fstrcpy(user, context->user);
+       if (!user || user[0] == (char)0) {
+               user = talloc_strdup(frame, context->user);
+               if (!user) {
+                       errno = ENOMEM;
+                       TALLOC_FREE(frame);
+                       return NULL;
+               }
+       }
 
        srv = smbc_server(context, True,
                           server, share, workgroup, user, password);
 
        if (!srv) {
-
                if (errno == EPERM) errno = EACCES;
                TALLOC_FREE(frame);
                return NULL;  /* smbc_server sets errno */
-
        }
 
        /* Hmmm, the test for a directory is suspect here ... FIXME */
@@ -1113,18 +1162,15 @@ smbc_open_ctx(SMBCCTX *context,
                file = SMB_MALLOC_P(SMBCFILE);
 
                if (!file) {
-
                        errno = ENOMEM;
                        TALLOC_FREE(frame);
                        return NULL;
-
                }
 
                ZERO_STRUCTP(file);
 
                /*d_printf(">>>open: resolving %s\n", path);*/
-               if (!cli_resolve_path(frame, "", srv->cli, path, &targetcli, &targetpath))
-               {
+               if (!cli_resolve_path(frame, "", srv->cli, path, &targetcli, &targetpath)) {
                        d_printf("Could not resolve %s\n", path);
                        SAFE_FREE(file);
                        TALLOC_FREE(frame);
@@ -1243,8 +1289,8 @@ smbc_read_ctx(SMBCCTX *context,
               size_t count)
 {
        int ret;
-       fstring server, share, user, password;
-       pstring path;
+       char *server, *share, *user, *password;
+       char *path;
        char *targetpath = NULL;
        struct cli_state *targetcli;
        TALLOC_CTX *frame = talloc_stackframe();
@@ -1262,7 +1308,6 @@ smbc_read_ctx(SMBCCTX *context,
 
        if (!context || !context->internal ||
            !context->internal->_initialized) {
-
                errno = EINVAL;
                TALLOC_FREE(frame);
                return -1;
@@ -1272,7 +1317,6 @@ smbc_read_ctx(SMBCCTX *context,
        DEBUG(4, ("smbc_read(%p, %d)\n", file, (int)count));
 
        if (!file || !DLIST_CONTAINS(context->internal->_files, file)) {
-
                errno = EBADF;
                TALLOC_FREE(frame);
                return -1;
@@ -1284,7 +1328,6 @@ smbc_read_ctx(SMBCCTX *context,
        /* Check that the buffer exists ... */
 
        if (buf == NULL) {
-
                errno = EINVAL;
                TALLOC_FREE(frame);
                return -1;
@@ -1292,14 +1335,16 @@ smbc_read_ctx(SMBCCTX *context,
        }
 
        /*d_printf(">>>read: parsing %s\n", file->fname);*/
-       if (smbc_parse_path(context, file->fname,
-                            NULL, 0,
-                            server, sizeof(server),
-                            share, sizeof(share),
-                            path, sizeof(path),
-                            user, sizeof(user),
-                            password, sizeof(password),
-                            NULL, 0)) {
+       if (smbc_parse_path(frame,
+                               context,
+                               file->fname,
+                               NULL,
+                               &server,
+                               &share,
+                               &path,
+                               &user,
+                               &password,
+                               NULL)) {
                 errno = EINVAL;
                TALLOC_FREE(frame);
                 return -1;
@@ -1307,8 +1352,7 @@ smbc_read_ctx(SMBCCTX *context,
 
        /*d_printf(">>>read: resolving %s\n", path);*/
        if (!cli_resolve_path(frame, "", file->srv->cli, path,
-                              &targetcli, &targetpath))
-       {
+                              &targetcli, &targetpath)) {
                d_printf("Could not resolve %s\n", path);
                TALLOC_FREE(frame);
                return -1;
@@ -1346,8 +1390,8 @@ smbc_write_ctx(SMBCCTX *context,
 {
        int ret;
         off_t offset;
-       fstring server, share, user, password;
-       pstring path;
+       char *server, *share, *user, *password;
+       char *path;
        char *targetpath = NULL;
        struct cli_state *targetcli;
        TALLOC_CTX *frame = talloc_stackframe();
@@ -1380,14 +1424,16 @@ smbc_write_ctx(SMBCCTX *context,
         offset = file->offset; /* See "offset" comment in smbc_read_ctx() */
 
        /*d_printf(">>>write: parsing %s\n", file->fname);*/
-       if (smbc_parse_path(context, file->fname,
-                            NULL, 0,
-                            server, sizeof(server),
-                            share, sizeof(share),
-                            path, sizeof(path),
-                            user, sizeof(user),
-                            password, sizeof(password),
-                            NULL, 0)) {
+       if (smbc_parse_path(frame,
+                               context,
+                               file->fname,
+                               NULL,
+                               &server,
+                               &share,
+                               &path,
+                               &user,
+                               &password,
+                               NULL)) {
                 errno = EINVAL;
                TALLOC_FREE(frame);
                 return -1;
@@ -1426,8 +1472,8 @@ smbc_close_ctx(SMBCCTX *context,
                SMBCFILE *file)
 {
         SMBCSRV *srv;
-       fstring server, share, user, password;
-       pstring path;
+       char *server, *share, *user, *password;
+       char *path;
        char *targetpath = NULL;
        struct cli_state *targetcli;
        TALLOC_CTX *frame = talloc_stackframe();
@@ -1438,32 +1484,31 @@ smbc_close_ctx(SMBCCTX *context,
                errno = EINVAL;
                TALLOC_FREE(frame);
                return -1;
-
        }
 
        if (!file || !DLIST_CONTAINS(context->internal->_files, file)) {
                errno = EBADF;
                TALLOC_FREE(frame);
                return -1;
-
        }
 
        /* IS a dir ... */
        if (!file->file) {
                TALLOC_FREE(frame);
                return (context->closedir)(context, file);
-
        }
 
        /*d_printf(">>>close: parsing %s\n", file->fname);*/
-       if (smbc_parse_path(context, file->fname,
-                            NULL, 0,
-                            server, sizeof(server),
-                            share, sizeof(share),
-                            path, sizeof(path),
-                            user, sizeof(user),
-                            password, sizeof(password),
-                            NULL, 0)) {
+       if (smbc_parse_path(frame,
+                               context,
+                               file->fname,
+                               NULL,
+                               &server,
+                               &share,
+                               &path,
+                               &user,
+                               &password,
+                               NULL)) {
                 errno = EINVAL;
                TALLOC_FREE(frame);
                 return -1;
@@ -1510,16 +1555,16 @@ smbc_close_ctx(SMBCCTX *context,
 static bool
 smbc_getatr(SMBCCTX * context,
             SMBCSRV *srv,
-            char *path, 
+            char *path,
             uint16 *mode,
-            SMB_OFF_T *size, 
+            SMB_OFF_T *size,
             struct timespec *create_time_ts,
             struct timespec *access_time_ts,
             struct timespec *write_time_ts,
             struct timespec *change_time_ts,
             SMB_INO_T *ino)
 {
-       pstring fixedpath;
+       char *fixedpath;
        char *targetpath = NULL;
        struct cli_state *targetcli;
        time_t write_time;
@@ -1533,11 +1578,20 @@ smbc_getatr(SMBCCTX * context,
        }
 
        /* path fixup for . and .. */
-       if (strequal(path, ".") || strequal(path, ".."))
-               pstrcpy(fixedpath, "\\");
-       else
-       {
-               pstrcpy(fixedpath, path);
+       if (strequal(path, ".") || strequal(path, "..")) {
+               fixedpath = talloc_strdup(frame, "\\");
+               if (!fixedpath) {
+                       errno = ENOMEM;
+                       TALLOC_FREE(frame);
+                       return -1;
+               }
+       } else {
+               fixedpath = talloc_strdup(frame, path);
+               if (!fixedpath) {
+                       errno = ENOMEM;
+                       TALLOC_FREE(frame);
+                       return -1;
+               }
                trim_string(fixedpath, NULL, "\\..");
                trim_string(fixedpath, NULL, "\\.");
        }
@@ -1696,8 +1750,8 @@ static int
 smbc_unlink_ctx(SMBCCTX *context,
                 const char *fname)
 {
-       fstring server, share, user, password, workgroup;
-       pstring path;
+       char *server, *share, *user, *password, *workgroup;
+       char *path;
        char *targetpath;
        struct cli_state *targetcli;
        SMBCSRV *srv = NULL;
@@ -1705,7 +1759,6 @@ smbc_unlink_ctx(SMBCCTX *context,
 
        if (!context || !context->internal ||
            !context->internal->_initialized) {
-
                errno = EINVAL;  /* Best I can think of ... */
                TALLOC_FREE(frame);
                return -1;
@@ -1713,33 +1766,40 @@ smbc_unlink_ctx(SMBCCTX *context,
        }
 
        if (!fname) {
-
                errno = EINVAL;
                TALLOC_FREE(frame);
                return -1;
 
        }
 
-       if (smbc_parse_path(context, fname,
-                            workgroup, sizeof(workgroup),
-                            server, sizeof(server),
-                            share, sizeof(share),
-                            path, sizeof(path),
-                            user, sizeof(user),
-                            password, sizeof(password),
-                            NULL, 0)) {
+       if (smbc_parse_path(frame,
+                               context,
+                               fname,
+                               &workgroup,
+                               &server,
+                               &share,
+                               &path,
+                               &user,
+                               &password,
+                               NULL)) {
                 errno = EINVAL;
                TALLOC_FREE(frame);
                 return -1;
         }
 
-       if (user[0] == (char)0) fstrcpy(user, context->user);
+       if (!user || user[0] == (char)0) {
+               user = talloc_strdup(frame, context->user);
+               if (!user) {
+                       errno = ENOMEM;
+                       TALLOC_FREE(frame);
+                       return -1;
+               }
+       }
 
        srv = smbc_server(context, True,
                           server, share, workgroup, user, password);
 
        if (!srv) {
-
                TALLOC_FREE(frame);
                return -1;  /* smbc_server sets errno */
 
@@ -1812,17 +1872,17 @@ smbc_rename_ctx(SMBCCTX *ocontext,
                 SMBCCTX *ncontext,
                 const char *nname)
 {
-       fstring server1;
-        fstring share1;
-        fstring server2;
-        fstring share2;
-        fstring user1;
-        fstring user2;
-        fstring password1;
-        fstring password2;
-        fstring workgroup;
-       pstring path1;
-        pstring path2;
+       char *server1;
+        char *share1;
+        char *server2;
+        char *share2;
+        char *user1;
+        char *user2;
+        char *password1;
+        char *password2;
+        char *workgroup;
+       char *path1;
+        char *path2;
         char *targetpath1;
         char *targetpath2;
        struct cli_state *targetcli1;
@@ -1834,43 +1894,66 @@ smbc_rename_ctx(SMBCCTX *ocontext,
            !ocontext->internal || !ncontext->internal ||
            !ocontext->internal->_initialized ||
            !ncontext->internal->_initialized) {
-
                errno = EINVAL;  /* Best I can think of ... */
                TALLOC_FREE(frame);
                return -1;
-
        }
 
        if (!oname || !nname) {
                errno = EINVAL;
                TALLOC_FREE(frame);
                return -1;
-
        }
 
        DEBUG(4, ("smbc_rename(%s,%s)\n", oname, nname));
 
-       smbc_parse_path(ocontext, oname,
-                        workgroup, sizeof(workgroup),
-                        server1, sizeof(server1),
-                        share1, sizeof(share1),
-                        path1, sizeof(path1),
-                        user1, sizeof(user1),
-                        password1, sizeof(password1),
-                        NULL, 0);
+       if (smbc_parse_path(frame,
+                       ocontext,
+                       oname,
+                       &workgroup,
+                       &server1,
+                       &share1,
+                       &path1,
+                       &user1,
+                       &password1,
+                        NULL)) {
+                errno = EINVAL;
+               TALLOC_FREE(frame);
+               return -1;
+       }
 
-       if (user1[0] == (char)0) fstrcpy(user1, ocontext->user);
+       if (!user1 || user1[0] == (char)0) {
+               user1 = talloc_strdup(frame, ocontext->user);
+               if (!user1) {
+                       errno = ENOMEM;
+                       TALLOC_FREE(frame);
+                       return -1;
+               }
+       }
 
-       smbc_parse_path(ncontext, nname,
-                        NULL, 0,
-                        server2, sizeof(server2),
-                        share2, sizeof(share2),
-                        path2, sizeof(path2),
-                        user2, sizeof(user2),
-                        password2, sizeof(password2),
-                        NULL, 0);
+       if (smbc_parse_path(frame,
+                               ncontext,
+                               nname,
+                               NULL,
+                               &server2,
+                               &share2,
+                               &path2,
+                               &user2,
+                               &password2,
+                               NULL)) {
+                errno = EINVAL;
+               TALLOC_FREE(frame);
+                return -1;
+       }
 
-       if (user2[0] == (char)0) fstrcpy(user2, ncontext->user);
+       if (!user2 || user2[0] == (char)0) {
+               user2 = talloc_strdup(frame, ncontext->user);
+               if (!user2) {
+                       errno = ENOMEM;
+                       TALLOC_FREE(frame);
+                       return -1;
+               }
+       }
 
        if (strcmp(server1, server2) || strcmp(share1, share2) ||
            strcmp(user1, user2)) {
@@ -1878,13 +1961,11 @@ smbc_rename_ctx(SMBCCTX *ocontext,
                errno = EXDEV;
                TALLOC_FREE(frame);
                return -1;
-
        }
 
        srv = smbc_server(ocontext, True,
                           server1, share1, workgroup, user1, password1);
        if (!srv) {
-
                TALLOC_FREE(frame);
                return -1;
 
@@ -1945,8 +2026,8 @@ smbc_lseek_ctx(SMBCCTX *context,
                int whence)
 {
        SMB_OFF_T size;
-       fstring server, share, user, password;
-       pstring path;
+       char *server, *share, *user, *password;
+       char *path;
        char *targetpath;
        struct cli_state *targetcli;
        TALLOC_CTX *frame = talloc_stackframe();
@@ -1985,18 +2066,20 @@ smbc_lseek_ctx(SMBCCTX *context,
 
        case SEEK_END:
                /*d_printf(">>>lseek: parsing %s\n", file->fname);*/
-               if (smbc_parse_path(context, file->fname,
-                                    NULL, 0,
-                                    server, sizeof(server),
-                                    share, sizeof(share),
-                                    path, sizeof(path),
-                                    user, sizeof(user),
-                                    password, sizeof(password),
-                                    NULL, 0)) {
-                                       errno = EINVAL;
-                                       TALLOC_FREE(frame);
-                                       return -1;
-                       }
+               if (smbc_parse_path(frame,
+                                       context,
+                                       file->fname,
+                                       NULL,
+                                       &server,
+                                       &share,
+                                       &path,
+                                       &user,
+                                       &password,
+                                       NULL)) {
+                       errno = EINVAL;
+                       TALLOC_FREE(frame);
+                       return -1;
+               }
 
                /*d_printf(">>>lseek: resolving %s\n", path);*/
                if (!cli_resolve_path(frame, "", file->srv->cli, path,
@@ -2117,12 +2200,12 @@ smbc_stat_ctx(SMBCCTX *context,
               struct stat *st)
 {
        SMBCSRV *srv;
-       fstring server;
-        fstring share;
-        fstring user;
-        fstring password;
-        fstring workgroup;
-       pstring path;
+       char *server;
+       char *share;
+       char *user;
+       char *password;
+       char *workgroup;
+       char *path;
        struct timespec write_time_ts;
         struct timespec access_time_ts;
         struct timespec change_time_ts;
@@ -2137,33 +2220,39 @@ smbc_stat_ctx(SMBCCTX *context,
                errno = EINVAL;  /* Best I can think of ... */
                TALLOC_FREE(frame);
                return -1;
-    
        }
 
        if (!fname) {
-
                errno = EINVAL;
                TALLOC_FREE(frame);
                return -1;
-
        }
-  
+
        DEBUG(4, ("smbc_stat(%s)\n", fname));
 
-       if (smbc_parse_path(context, fname,
-                            workgroup, sizeof(workgroup),
-                            server, sizeof(server),
-                            share, sizeof(share),
-                            path, sizeof(path),
-                            user, sizeof(user),
-                            password, sizeof(password),
-                            NULL, 0)) {
-                errno = EINVAL;
+       if (smbc_parse_path(frame,
+                               context,
+                               fname,
+                               &workgroup,
+                               &server,
+                               &share,
+                               &path,
+                               &user,
+                               &password,
+                               NULL)) {
+               errno = EINVAL;
                TALLOC_FREE(frame);
                 return -1;
         }
 
-       if (user[0] == (char)0) fstrcpy(user, context->user);
+       if (!user || user[0] == (char)0) {
+               user = talloc_strdup(frame,context->user);
+               if (!user) {
+                       errno = ENOMEM;
+                       TALLOC_FREE(frame);
+                       return -1;
+               }
+       }
 
        srv = smbc_server(context, True,
                           server, share, workgroup, user, password);
@@ -2173,17 +2262,15 @@ smbc_stat_ctx(SMBCCTX *context,
                return -1;  /* errno set by smbc_server */
        }
 
-       if (!smbc_getatr(context, srv, path, &mode, &size, 
+       if (!smbc_getatr(context, srv, path, &mode, &size,
                         NULL,
                          &access_time_ts,
                          &write_time_ts,
                          &change_time_ts,
                          &ino)) {
-
                errno = smbc_errno(context, srv->cli);
                TALLOC_FREE(frame);
                return -1;
-               
        }
 
        st->st_ino = ino;
@@ -2214,11 +2301,11 @@ smbc_fstat_ctx(SMBCCTX *context,
         struct timespec write_time_ts;
        SMB_OFF_T size;
        uint16 mode;
-       fstring server;
-        fstring share;
-        fstring user;
-        fstring password;
-       pstring path;
+       char *server;
+       char *share;
+       char *user;
+       char *password;
+       char *path;
         char *targetpath;
        struct cli_state *targetcli;
        SMB_INO_T ino = 0;
@@ -2229,31 +2316,30 @@ smbc_fstat_ctx(SMBCCTX *context,
                errno = EINVAL;
                TALLOC_FREE(frame);
                return -1;
-
        }
 
        if (!file || !DLIST_CONTAINS(context->internal->_files, file)) {
                errno = EBADF;
                TALLOC_FREE(frame);
                return -1;
-
        }
 
        if (!file->file) {
                TALLOC_FREE(frame);
                return (context->fstatdir)(context, file, st);
-
        }
 
        /*d_printf(">>>fstat: parsing %s\n", file->fname);*/
-       if (smbc_parse_path(context, file->fname,
-                            NULL, 0,
-                            server, sizeof(server),
-                            share, sizeof(share),
-                            path, sizeof(path),
-                            user, sizeof(user),
-                            password, sizeof(password),
-                            NULL, 0)) {
+       if (smbc_parse_path(frame,
+                               context,
+                               file->fname,
+                               NULL,
+                               &server,
+                               &share,
+                               &path,
+                               &user,
+                               &password,
+                               NULL)) {
                 errno = EINVAL;
                TALLOC_FREE(frame);
                 return -1;
@@ -2467,14 +2553,13 @@ list_fn(const char *name,
          * Disk share     = 0x00000000
          * Print share    = 0x00000001
          * Comms share    = 0x00000002 (obsolete?)
-         * IPC$ share     = 0x00000003 
+         * IPC$ share     = 0x00000003
          *
          * administrative shares:
          * ADMIN$, IPC$, C$, D$, E$ ...  are type |= 0x80000000
          */
-        
+
        if (dir->dir_type == SMBC_FILE_SHARE) {
-               
                switch (type) {
                 case 0 | 0x80000000:
                case 0:
@@ -2604,9 +2689,9 @@ smbc_opendir_ctx(SMBCCTX *context,
                  const char *fname)
 {
         int saved_errno;
-       fstring server, share, user, password, options;
-       pstring workgroup;
-       pstring path;
+       char *server, *share, *user, *password, *options;
+       char *workgroup;
+       char *path;
         uint16 mode;
         char *p;
        SMBCSRV *srv  = NULL;
@@ -2631,14 +2716,16 @@ smbc_opendir_ctx(SMBCCTX *context,
                return NULL;
        }
 
-       if (smbc_parse_path(context, fname,
-                            workgroup, sizeof(workgroup),
-                            server, sizeof(server),
-                            share, sizeof(share),
-                            path, sizeof(path),
-                            user, sizeof(user),
-                            password, sizeof(password),
-                            options, sizeof(options))) {
+       if (smbc_parse_path(frame,
+                               context,
+                               fname,
+                               &workgroup,
+                               &server,
+                               &share,
+                               &path,
+                               &user,
+                               &password,
+                               &options)) {
                DEBUG(4, ("no valid path\n"));
                errno = EINVAL + 8194;
                TALLOC_FREE(frame);
@@ -3314,7 +3401,7 @@ smbc_getdents_ctx(SMBCCTX *context,
 
        if (rem == count)
                return 0;
-       else 
+       else
                return count - rem;
 
 }
@@ -3329,12 +3416,12 @@ smbc_mkdir_ctx(SMBCCTX *context,
                mode_t mode)
 {
        SMBCSRV *srv;
-       fstring server;
-        fstring share;
-        fstring user;
-        fstring password;
-        fstring workgroup;
-       pstring path;
+       char *server;
+        char *share;
+        char *user;
+        char *password;
+        char *workgroup;
+       char *path;
        char *targetpath;
        struct cli_state *targetcli;
        TALLOC_CTX *frame = talloc_stackframe();
@@ -3344,32 +3431,39 @@ smbc_mkdir_ctx(SMBCCTX *context,
                errno = EINVAL;
                TALLOC_FREE(frame);
                return -1;
-
        }
 
        if (!fname) {
                errno = EINVAL;
                TALLOC_FREE(frame);
                return -1;
-
        }
 
        DEBUG(4, ("smbc_mkdir(%s)\n", fname));
 
-       if (smbc_parse_path(context, fname,
-                            workgroup, sizeof(workgroup),
-                            server, sizeof(server),
-                            share, sizeof(share),
-                            path, sizeof(path),
-                            user, sizeof(user),
-                            password, sizeof(password),
-                            NULL, 0)) {
+       if (smbc_parse_path(frame,
+                               context,
+                               fname,
+                               &workgroup,
+                               &server,
+                               &share,
+                               &path,
+                               &user,
+                               &password,
+                               NULL)) {
                 errno = EINVAL;
                TALLOC_FREE(frame);
-                return -1;
+               return -1;
         }
 
-       if (user[0] == (char)0) fstrcpy(user, context->user);
+       if (!user || user[0] == (char)0) {
+               user = talloc_strdup(frame, context->user);
+               if (!user) {
+                       errno = ENOMEM;
+                       TALLOC_FREE(frame);
+                       return -1;
+               }
+       }
 
        srv = smbc_server(context, True,
                           server, share, workgroup, user, password);
@@ -3417,7 +3511,6 @@ rmdir_list_fn(const char *mnt,
 {
        if (strncmp(finfo->name, ".", 1) != 0 &&
             strncmp(finfo->name, "..", 2) != 0) {
-                
                smbc_rmdir_dirempty = False;
         }
 }
@@ -3431,12 +3524,12 @@ smbc_rmdir_ctx(SMBCCTX *context,
                const char *fname)
 {
        SMBCSRV *srv;
-       fstring server;
-        fstring share;
-        fstring user;
-        fstring password;
-        fstring workgroup;
-       pstring path;
+       char *server;
+        char *share;
+        char *user;
+        char *password;
+        char *workgroup;
+       char *path;
         char *targetpath;
        struct cli_state *targetcli;
        TALLOC_CTX *frame = talloc_stackframe();
@@ -3446,33 +3539,39 @@ smbc_rmdir_ctx(SMBCCTX *context,
                errno = EINVAL;
                TALLOC_FREE(frame);
                return -1;
-
        }
 
        if (!fname) {
                errno = EINVAL;
                TALLOC_FREE(frame);
                return -1;
-
        }
 
        DEBUG(4, ("smbc_rmdir(%s)\n", fname));
 
-       if (smbc_parse_path(context, fname,
-                            workgroup, sizeof(workgroup),
-                            server, sizeof(server),
-                            share, sizeof(share),
-                            path, sizeof(path),
-                            user, sizeof(user),
-                            password, sizeof(password),
-                            NULL, 0))
-        {
+       if (smbc_parse_path(frame,
+                               context,
+                               fname,
+                               &workgroup,
+                               &server,
+                               &share,
+                               &path,
+                               &user,
+                               &password,
+                               NULL)) {
                 errno = EINVAL;
                TALLOC_FREE(frame);
-                return -1;
+               return -1;
         }
 
-       if (user[0] == (char)0) fstrcpy(user, context->user);
+       if (!user || user[0] == (char)0) {
+               user = talloc_strdup(frame, context->user);
+               if (!user) {
+                       errno = ENOMEM;
+                       TALLOC_FREE(frame);
+                       return -1;
+               }
+       }
 
        srv = smbc_server(context, True,
                           server, share, workgroup, user, password);
@@ -3501,12 +3600,17 @@ smbc_rmdir_ctx(SMBCCTX *context,
                if (errno == EACCES) {  /* Check if the dir empty or not */
 
                         /* Local storage to avoid buffer overflows */
-                       pstring lpath; 
+                       char *lpath;
 
                        smbc_rmdir_dirempty = True;  /* Make this so ... */
 
-                       pstrcpy(lpath, targetpath);
-                       pstrcat(lpath, "\\*");
+                       lpath = talloc_asprintf(frame, "%s\\*",
+                                               targetpath);
+                       if (!lpath) {
+                               errno = ENOMEM;
+                               TALLOC_FREE(frame);
+                               return -1;
+                       }
 
                        if (cli_list(targetcli, lpath,
                                      aDIR | aSYSTEM | aHIDDEN,
@@ -3514,7 +3618,7 @@ smbc_rmdir_ctx(SMBCCTX *context,
 
                                /* Fix errno to ignore latest error ... */
                                DEBUG(5, ("smbc_rmdir: "
-                                          "cli_list returned an error: %d\n", 
+                                          "cli_list returned an error: %d\n",
                                          smbc_errno(context, targetcli)));
                                errno = EACCES;
 
@@ -3668,18 +3772,15 @@ smbc_lseekdir_ctx(SMBCCTX *context,
        /* This may need to be changed if we change the format of the list */
 
        if ((list_ent = smbc_check_dir_ent(dir->dir_list, dirent)) == NULL) {
-
                errno = EINVAL;   /* Bad entry */
                TALLOC_FREE(frame);
                return -1;
-
        }
 
        dir->dir_next = list_ent;
 
        TALLOC_FREE(frame);
-       return 0; 
-
+       return 0;
 }
 
 /*
@@ -3692,18 +3793,14 @@ smbc_fstatdir_ctx(SMBCCTX *context,
                   struct stat *st)
 {
 
-       if (!context || !context->internal || 
+       if (!context || !context->internal ||
            !context->internal->_initialized) {
-
                errno = EINVAL;
                return -1;
-
        }
 
        /* No code yet ... */
-
        return 0;
-
 }
 
 static int
@@ -3712,48 +3809,53 @@ smbc_chmod_ctx(SMBCCTX *context,
                mode_t newmode)
 {
         SMBCSRV *srv;
-       fstring server;
-        fstring share;
-        fstring user;
-        fstring password;
-        fstring workgroup;
-       pstring path;
+       char *server;
+        char *share;
+        char *user;
+        char *password;
+        char *workgroup;
+       char *path;
        uint16 mode;
        TALLOC_CTX *frame = talloc_stackframe();
 
        if (!context || !context->internal ||
            !context->internal->_initialized) {
-
                errno = EINVAL;  /* Best I can think of ... */
                TALLOC_FREE(frame);
                return -1;
-    
        }
 
        if (!fname) {
-
                errno = EINVAL;
                TALLOC_FREE(frame);
                return -1;
-
        }
-  
+
        DEBUG(4, ("smbc_chmod(%s, 0%3o)\n", fname, newmode));
 
-       if (smbc_parse_path(context, fname,
-                            workgroup, sizeof(workgroup),
-                            server, sizeof(server),
-                            share, sizeof(share),
-                            path, sizeof(path),
-                            user, sizeof(user),
-                            password, sizeof(password),
-                            NULL, 0)) {
+       if (smbc_parse_path(frame,
+                               context,
+                               fname,
+                               &workgroup,
+                               &server,
+                               &share,
+                               &path,
+                               &user,
+                               &password,
+                               NULL)) {
                 errno = EINVAL;
                TALLOC_FREE(frame);
-                return -1;
+               return -1;
         }
 
-       if (user[0] == (char)0) fstrcpy(user, context->user);
+       if (!user || user[0] == (char)0) {
+               user = talloc_strdup(frame, context->user);
+               if (!user) {
+                       errno = ENOMEM;
+                       TALLOC_FREE(frame);
+                       return -1;
+               }
+       }
 
        srv = smbc_server(context, True,
                           server, share, workgroup, user, password);
@@ -3775,7 +3877,7 @@ smbc_chmod_ctx(SMBCCTX *context,
                TALLOC_FREE(frame);
                return -1;
        }
-       
+
        TALLOC_FREE(frame);
         return 0;
 }
@@ -3786,33 +3888,29 @@ smbc_utimes_ctx(SMBCCTX *context,
                 struct timeval *tbuf)
 {
         SMBCSRV *srv;
-       fstring server;
-        fstring share;
-        fstring user;
-        fstring password;
-        fstring workgroup;
-       pstring path;
+       char *server;
+       char *share;
+       char *user;
+       char *password;
+       char *workgroup;
+       char *path;
         time_t access_time;
         time_t write_time;
        TALLOC_CTX *frame = talloc_stackframe();
 
        if (!context || !context->internal ||
            !context->internal->_initialized) {
-
                errno = EINVAL;  /* Best I can think of ... */
                TALLOC_FREE(frame);
                return -1;
-    
        }
 
        if (!fname) {
-
                errno = EINVAL;
                TALLOC_FREE(frame);
                return -1;
-
        }
-  
+
         if (tbuf == NULL) {
                 access_time = write_time = time(NULL);
         } else {
@@ -3820,8 +3918,7 @@ smbc_utimes_ctx(SMBCCTX *context,
                 write_time = tbuf[1].tv_sec;
         }
 
-        if (DEBUGLVL(4)) 
-        {
+        if (DEBUGLVL(4)) {
                 char *p;
                 char atimebuf[32];
                 char mtimebuf[32];
@@ -3842,20 +3939,29 @@ smbc_utimes_ctx(SMBCCTX *context,
                         fname, atimebuf, mtimebuf);
         }
 
-       if (smbc_parse_path(context, fname,
-                            workgroup, sizeof(workgroup),
-                            server, sizeof(server),
-                            share, sizeof(share),
-                            path, sizeof(path),
-                            user, sizeof(user),
-                            password, sizeof(password),
-                            NULL, 0)) {
-                errno = EINVAL;
+       if (smbc_parse_path(frame,
+                               context,
+                               fname,
+                               &workgroup,
+                               &server,
+                               &share,
+                               &path,
+                               &user,
+                               &password,
+                               NULL)) {
+               errno = EINVAL;
                TALLOC_FREE(frame);
-                return -1;
+               return -1;
         }
 
-       if (user[0] == (char)0) fstrcpy(user, context->user);
+       if (!user || user[0] == (char)0) {
+               user = talloc_strdup(frame, context->user);
+               if (!user) {
+                       errno = ENOMEM;
+                       TALLOC_FREE(frame);
+                       return -1;
+               }
+       }
 
        srv = smbc_server(context, True,
                           server, share, workgroup, user, password);
@@ -3944,7 +4050,7 @@ ace_compare(SEC_ACE *ace1,
          * referenced MS document).  We'll now sort by characteristics that
          * just seems reasonable.
          */
-        
+
        if (ace1->type != ace2->type) {
                return ace2->type - ace1->type;
         }
@@ -4010,17 +4116,17 @@ convert_sid_to_string(struct cli_state *ipc_cli,
        if (numeric) {
                return;     /* no lookup desired */
        }
-       
+
        if (!pipe_hnd) {
                return;
        }
+
        /* Ask LSA to convert the sid to a name */
 
        ctx = talloc_stackframe();
 
        if (!NT_STATUS_IS_OK(rpccli_lsa_lookup_sids(pipe_hnd, ctx,
-                                                pol, 1, sid, &domains, 
+                                                pol, 1, sid, &domains,
                                                 &names, &types)) ||
            !domains || !domains[0] || !names || !names[0]) {
                TALLOC_FREE(ctx);
@@ -4064,8 +4170,8 @@ convert_string_to_sid(struct cli_state *ipc_cli,
 
        ctx = talloc_stackframe();
        if (!NT_STATUS_IS_OK(rpccli_lsa_lookup_names(pipe_hnd, ctx,
-                                                 pol, 1, &str, NULL, 1, &sids, 
-                                                 &types))) {
+                                         pol, 1, &str, NULL, 1, &sids,
+                                         &types))) {
                result = False;
                goto done;
        }
@@ -4372,7 +4478,7 @@ dos_attr_query(SMBCCTX *context,
         uint16 mode = 0;
        SMB_INO_T inode = 0;
         DOS_ATTR_DESC *ret;
-    
+
         ret = TALLOC_P(ctx, DOS_ATTR_DESC);
         if (!ret) {
                 errno = ENOMEM;
@@ -4381,19 +4487,17 @@ dos_attr_query(SMBCCTX *context,
 
         /* Obtain the DOS attributes */
         if (!smbc_getatr(context, srv, CONST_DISCARD(char *, filename),
-                         &mode, &size, 
+                         &mode, &size,
                          &create_time_ts,
                          &access_time_ts,
                          &write_time_ts,
-                         &change_time_ts, 
+                         &change_time_ts,
                          &inode)) {
-        
                 errno = smbc_errno(context, srv->cli);
                 DEBUG(5, ("dos_attr_query Failed to query old attributes\n"));
                 return NULL;
-        
         }
-                
+
         ret->mode = mode;
         ret->size = size;
         ret->create_time = convert_timespec_to_time_t(create_time_ts);
@@ -4495,7 +4599,7 @@ dos_attr_parse(SMBCCTX *context,
        }
 }
 
-/***************************************************** 
+/*****************************************************
  Retrieve the acls for a file.
 *******************************************************/
 
@@ -4735,7 +4839,7 @@ cacl_get(SMBCCTX *context,
                                                      sd->revision);
                                 }
                         }
-        
+
                         if (!determine_size && n > bufsize) {
                                 errno = ERANGE;
                                 return -1;
@@ -4947,10 +5051,10 @@ cacl_get(SMBCCTX *context,
                                  &write_time_ts,
                                  &change_time_ts,
                                  &ino)) {
-                        
+
                         errno = smbc_errno(context, srv->cli);
                         return -1;
-                        
+
                 }
 
                 create_time = convert_timespec_to_time_t(create_time_ts);
@@ -4995,7 +5099,7 @@ cacl_get(SMBCCTX *context,
                                                      "0x%x", mode);
                                 }
                         }
-        
+
                         if (!determine_size && n > bufsize) {
                                 errno = ERANGE;
                                 return -1;
@@ -5040,7 +5144,7 @@ cacl_get(SMBCCTX *context,
                                                      (double)size);
                                 }
                         }
-        
+
                         if (!determine_size && n > bufsize) {
                                 errno = ERANGE;
                                 return -1;
@@ -5083,7 +5187,7 @@ cacl_get(SMBCCTX *context,
                                                      "%lu", create_time);
                                 }
                         }
-        
+
                         if (!determine_size && n > bufsize) {
                                 errno = ERANGE;
                                 return -1;
@@ -5125,7 +5229,7 @@ cacl_get(SMBCCTX *context,
                                                      "%lu", access_time);
                                 }
                         }
-        
+
                         if (!determine_size && n > bufsize) {
                                 errno = ERANGE;
                                 return -1;
@@ -5167,7 +5271,7 @@ cacl_get(SMBCCTX *context,
                                                      "%lu", write_time);
                                 }
                         }
-        
+
                         if (!determine_size && n > bufsize) {
                                 errno = ERANGE;
                                 return -1;
@@ -5209,7 +5313,7 @@ cacl_get(SMBCCTX *context,
                                                      "%lu", change_time);
                                 }
                         }
-        
+
                         if (!determine_size && n > bufsize) {
                                 errno = ERANGE;
                                 return -1;
@@ -5254,7 +5358,7 @@ cacl_get(SMBCCTX *context,
                                                      (double) ino);
                                 }
                         }
-        
+
                         if (!determine_size && n > bufsize) {
                                 errno = ERANGE;
                                 return -1;
@@ -5277,8 +5381,7 @@ cacl_get(SMBCCTX *context,
        return n_used;
 }
 
-
-/***************************************************** 
+/*****************************************************
 set the ACLs on a file given an ascii description
 *******************************************************/
 static int
@@ -5295,7 +5398,7 @@ cacl_set(TALLOC_CTX *ctx,
         int err = 0;
        SEC_DESC *sd = NULL, *old;
         SEC_ACL *dacl = NULL;
-       DOM_SID *owner_sid = NULL; 
+       DOM_SID *owner_sid = NULL;
        DOM_SID *group_sid = NULL;
        uint32 i, j;
        size_t sd_size;
@@ -5410,7 +5513,7 @@ cacl_set(TALLOC_CTX *ctx,
                                 ret = -1;
                                 goto failed;
                        }
-                        
+
                         for (i=0;sd->dacl && i<sd->dacl->num_aces;i++) {
                                 add_ace(&old->dacl, &sd->dacl->aces[i], ctx);
                         }
@@ -5438,7 +5541,7 @@ cacl_set(TALLOC_CTX *ctx,
        sort_acl(old->dacl);
 
        /* Create new security descriptor and set it */
-       sd = make_sec_desc(ctx, old->revision, SEC_DESC_SELF_RELATIVE, 
+       sd = make_sec_desc(ctx, old->revision, SEC_DESC_SELF_RELATIVE,
                           owner_sid, group_sid, NULL, dacl, &sd_size);
 
        fnum = cli_nt_create(cli, filename,
@@ -5464,7 +5567,7 @@ cacl_set(TALLOC_CTX *ctx,
         if (err != 0) {
                 errno = err;
         }
-        
+
        return ret;
 }
 
@@ -5481,12 +5584,12 @@ smbc_setxattr_ctx(SMBCCTX *context,
         int ret2;
         SMBCSRV *srv;
         SMBCSRV *ipc_srv;
-       fstring server;
-        fstring share;
-        fstring user;
-        fstring password;
-        fstring workgroup;
-       pstring path;
+       char *server;
+       char *share;
+       char *user;
+       char *password;
+       char *workgroup;
+       char *path;
         POLICY_HND pol;
         DOS_ATTR_DESC *dad;
         struct {
@@ -5499,38 +5602,43 @@ smbc_setxattr_ctx(SMBCCTX *context,
 
        if (!context || !context->internal ||
            !context->internal->_initialized) {
-
                errno = EINVAL;  /* Best I can think of ... */
                TALLOC_FREE(frame);
                return -1;
-    
        }
 
        if (!fname) {
-
                errno = EINVAL;
                TALLOC_FREE(frame);
                return -1;
-
        }
-  
+
        DEBUG(4, ("smbc_setxattr(%s, %s, %.*s)\n",
                   fname, name, (int) size, (const char*)value));
 
-       if (smbc_parse_path(context, fname,
-                            workgroup, sizeof(workgroup),
-                            server, sizeof(server),
-                            share, sizeof(share),
-                            path, sizeof(path),
-                            user, sizeof(user),
-                            password, sizeof(password),
-                            NULL, 0)) {
-                errno = EINVAL;
+       if (smbc_parse_path(frame,
+                               context,
+                               fname,
+                               &workgroup,
+                               &server,
+                               &share,
+                               &path,
+                               &user,
+                               &password,
+                               NULL)) {
+               errno = EINVAL;
                TALLOC_FREE(frame);
-                return -1;
+               return -1;
         }
 
-       if (user[0] == (char)0) fstrcpy(user, context->user);
+       if (!user || user[0] == (char)0) {
+               user = talloc_strdup(frame, context->user);
+               if (!user) {
+                       errno = ENOMEM;
+                       TALLOC_FREE(frame);
+                       return -1;
+               }
+       }
 
        srv = smbc_server(context, True,
                           server, share, workgroup, user, password);
@@ -5549,7 +5657,7 @@ smbc_setxattr_ctx(SMBCCTX *context,
         } else {
                 ipc_srv = NULL;
         }
-        
+
         /*
          * Are they asking to set the entire set of known attributes?
          */
@@ -5655,7 +5763,6 @@ smbc_setxattr_ctx(SMBCCTX *context,
                                         name+19, (const char *) value);
 
                 if (! ipc_srv) {
-                        
                         ret = -1; /* errno set by smbc_server() */
                 }
                 else if (! namevalue) {
@@ -5775,12 +5882,12 @@ smbc_getxattr_ctx(SMBCCTX *context,
         int ret;
         SMBCSRV *srv;
         SMBCSRV *ipc_srv;
-        fstring server;
-        fstring share;
-        fstring user;
-        fstring password;
-        fstring workgroup;
-        pstring path;
+       char *server;
+       char *share;
+       char *user;
+       char *password;
+       char *workgroup;
+       char *path;
         POLICY_HND pol;
         struct {
                 const char * create_time_attr;
@@ -5792,37 +5899,42 @@ smbc_getxattr_ctx(SMBCCTX *context,
 
         if (!context || !context->internal ||
             !context->internal->_initialized) {
-
                 errno = EINVAL;  /* Best I can think of ... */
                TALLOC_FREE(frame);
                 return -1;
-    
         }
 
         if (!fname) {
-
                 errno = EINVAL;
                TALLOC_FREE(frame);
                 return -1;
-
         }
-  
+
         DEBUG(4, ("smbc_getxattr(%s, %s)\n", fname, name));
 
-        if (smbc_parse_path(context, fname,
-                            workgroup, sizeof(workgroup),
-                            server, sizeof(server),
-                            share, sizeof(share),
-                            path, sizeof(path),
-                            user, sizeof(user),
-                            password, sizeof(password),
-                            NULL, 0)) {
-                errno = EINVAL;
+        if (smbc_parse_path(frame,
+                               context,
+                               fname,
+                               &workgroup,
+                               &server,
+                               &share,
+                               &path,
+                               &user,
+                               &password,
+                               NULL)) {
+               errno = EINVAL;
                TALLOC_FREE(frame);
-                return -1;
+               return -1;
         }
 
-        if (user[0] == (char)0) fstrcpy(user, context->user);
+        if (!user || user[0] == (char)0) {
+               user = talloc_strdup(frame, context->user);
+               if (!user) {
+                       errno = ENOMEM;
+                       TALLOC_FREE(frame);
+                       return -1;
+               }
+       }
 
         srv = smbc_server(context, True,
                           server, share, workgroup, user, password);
@@ -5841,7 +5953,7 @@ smbc_getxattr_ctx(SMBCCTX *context,
         } else {
                 ipc_srv = NULL;
         }
-        
+
         /* Determine whether to use old-style or new-style attribute names */
         if (context->internal->_full_time_names) {
                 /* new-style names */
@@ -5912,48 +6024,53 @@ smbc_removexattr_ctx(SMBCCTX *context,
         int ret;
         SMBCSRV *srv;
         SMBCSRV *ipc_srv;
-        fstring server;
-        fstring share;
-        fstring user;
-        fstring password;
-        fstring workgroup;
-        pstring path;
+       char *server;
+       char *share;
+       char *user;
+       char *password;
+       char *workgroup;
+       char *path;
         POLICY_HND pol;
        TALLOC_CTX *frame = talloc_stackframe();
 
         if (!context || !context->internal ||
             !context->internal->_initialized) {
-
                 errno = EINVAL;  /* Best I can think of ... */
                TALLOC_FREE(frame);
                 return -1;
-    
         }
 
         if (!fname) {
-
                 errno = EINVAL;
                TALLOC_FREE(frame);
                 return -1;
-
         }
-  
+
         DEBUG(4, ("smbc_removexattr(%s, %s)\n", fname, name));
 
-        if (smbc_parse_path(context, fname,
-                            workgroup, sizeof(workgroup),
-                            server, sizeof(server),
-                            share, sizeof(share),
-                            path, sizeof(path),
-                            user, sizeof(user),
-                            password, sizeof(password),
-                            NULL, 0)) {
-                errno = EINVAL;
+       if (smbc_parse_path(frame,
+                               context,
+                               fname,
+                               &workgroup,
+                               &server,
+                               &share,
+                               &path,
+                               &user,
+                               &password,
+                               NULL)) {
+               errno = EINVAL;
                TALLOC_FREE(frame);
-                return -1;
+               return -1;
         }
 
-        if (user[0] == (char)0) fstrcpy(user, context->user);
+        if (!user || user[0] == (char)0) {
+               user = talloc_strdup(frame, context->user);
+               if (!user) {
+                       errno = ENOMEM;
+                       TALLOC_FREE(frame);
+                       return -1;
+               }
+       }
 
         srv = smbc_server(context, True,
                           server, share, workgroup, user, password);
@@ -5972,7 +6089,7 @@ smbc_removexattr_ctx(SMBCCTX *context,
         } else {
                 ipc_srv = NULL;
         }
-        
+
         if (! ipc_srv) {
                TALLOC_FREE(frame);
                 return -1; /* errno set by smbc_attr_server */
@@ -6097,40 +6214,38 @@ static SMBCFILE *
 smbc_open_print_job_ctx(SMBCCTX *context,
                         const char *fname)
 {
-        fstring server;
-        fstring share;
-        fstring user;
-        fstring password;
-        pstring path;
+       char *server;
+       char *share;
+       char *user;
+       char *password;
+       char *path;
        TALLOC_CTX *frame = talloc_stackframe();
-        
+
         if (!context || !context->internal ||
             !context->internal->_initialized) {
-
                 errno = EINVAL;
                TALLOC_FREE(frame);
                 return NULL;
-    
         }
 
         if (!fname) {
-
                 errno = EINVAL;
                TALLOC_FREE(frame);
                 return NULL;
-
         }
-  
+
         DEBUG(4, ("smbc_open_print_job_ctx(%s)\n", fname));
 
-        if (smbc_parse_path(context, fname,
-                            NULL, 0,
-                            server, sizeof(server),
-                            share, sizeof(share),
-                            path, sizeof(path),
-                            user, sizeof(user),
-                            password, sizeof(password),
-                            NULL, 0)) {
+        if (smbc_parse_path(frame,
+                               context,
+                               fname,
+                               NULL,
+                               &server,
+                               &share,
+                               &path,
+                               &user,
+                               &password,
+                               NULL)) {
                 errno = EINVAL;
                TALLOC_FREE(frame);
                 return NULL;
@@ -6140,7 +6255,6 @@ smbc_open_print_job_ctx(SMBCCTX *context,
 
        TALLOC_FREE(frame);
         return (context->open)(context, fname, O_WRONLY, 666);
-
 }
 
 /*
@@ -6184,11 +6298,9 @@ smbc_print_file_ctx(SMBCCTX *c_file,
         /* Try to open the file for reading ... */
 
         if ((long)(fid1 = (c_file->open)(c_file, fname, O_RDONLY, 0666)) < 0) {
-                
                 DEBUG(3, ("Error, fname=%s, errno=%i\n", fname, errno));
                TALLOC_FREE(frame);
                 return -1;  /* smbc_open sets errno */
-                
         }
 
         /* Now, try to open the printer file for writing */
@@ -6245,68 +6357,69 @@ smbc_list_print_jobs_ctx(SMBCCTX *context,
                          const char *fname,
                          smbc_list_print_job_fn fn)
 {
-        SMBCSRV *srv;
-        fstring server;
-        fstring share;
-        fstring user;
-        fstring password;
-        fstring workgroup;
-        pstring path;
+       SMBCSRV *srv;
+       char *server;
+       char *share;
+       char *user;
+       char *password;
+       char *workgroup;
+       char *path;
        TALLOC_CTX *frame = talloc_stackframe();
 
         if (!context || !context->internal ||
             !context->internal->_initialized) {
-
                 errno = EINVAL;
                TALLOC_FREE(frame);
                 return -1;
-
         }
 
         if (!fname) {
-                
                 errno = EINVAL;
                TALLOC_FREE(frame);
                 return -1;
-
         }
-  
+
         DEBUG(4, ("smbc_list_print_jobs(%s)\n", fname));
 
-        if (smbc_parse_path(context, fname,
-                            workgroup, sizeof(workgroup),
-                            server, sizeof(server),
-                            share, sizeof(share),
-                            path, sizeof(path),
-                            user, sizeof(user),
-                            password, sizeof(password),
-                            NULL, 0)) {
-                errno = EINVAL;
+        if (smbc_parse_path(frame,
+                               context,
+                               fname,
+                               &workgroup,
+                               &server,
+                               &share,
+                               &path,
+                               &user,
+                               &password,
+                               NULL)) {
+               errno = EINVAL;
                TALLOC_FREE(frame);
-                return -1;
+               return -1;
         }
 
-        if (user[0] == (char)0) fstrcpy(user, context->user);
-        
+        if (!user || user[0] == (char)0) {
+               user = talloc_strdup(frame, context->user);
+               if (!user) {
+                       errno = ENOMEM;
+                       TALLOC_FREE(frame);
+                       return -1;
+               }
+       }
+
         srv = smbc_server(context, True,
                           server, share, workgroup, user, password);
 
         if (!srv) {
-
                TALLOC_FREE(frame);
                 return -1;  /* errno set by smbc_server */
-
         }
 
         if (cli_print_queue(srv->cli,
                             (void (*)(struct print_job_info *))fn) < 0) {
-
                 errno = smbc_errno(context, srv->cli);
                TALLOC_FREE(frame);
                 return -1;
-
         }
-        
+
        TALLOC_FREE(frame);
         return 0;
 
@@ -6321,49 +6434,54 @@ smbc_unlink_print_job_ctx(SMBCCTX *context,
                           const char *fname,
                           int id)
 {
-        SMBCSRV *srv;
-        fstring server;
-        fstring share;
-        fstring user;
-        fstring password;
-        fstring workgroup;
-        pstring path;
+       SMBCSRV *srv;
+       char *server;
+       char *share;
+       char *user;
+       char *password;
+       char *workgroup;
+       char *path;
         int err;
        TALLOC_CTX *frame = talloc_stackframe();
 
         if (!context || !context->internal ||
             !context->internal->_initialized) {
-
                 errno = EINVAL;
                TALLOC_FREE(frame);
                 return -1;
-
         }
 
         if (!fname) {
-
                 errno = EINVAL;
                TALLOC_FREE(frame);
                 return -1;
-
         }
-  
+
         DEBUG(4, ("smbc_unlink_print_job(%s)\n", fname));
 
-        if (smbc_parse_path(context, fname,
-                            workgroup, sizeof(workgroup),
-                            server, sizeof(server),
-                            share, sizeof(share),
-                            path, sizeof(path),
-                            user, sizeof(user),
-                            password, sizeof(password),
-                            NULL, 0)) {
-                errno = EINVAL;
+        if (smbc_parse_path(frame,
+                               context,
+                               fname,
+                               &workgroup,
+                               &server,
+                               &share,
+                               &path,
+                               &user,
+                               &password,
+                               NULL)) {
+               errno = EINVAL;
                TALLOC_FREE(frame);
-                return -1;
+               return -1;
         }
 
-        if (user[0] == (char)0) fstrcpy(user, context->user);
+        if (!user || user[0] == (char)0) {
+               user = talloc_strdup(frame, context->user);
+               if (!user) {
+                       errno = ENOMEM;
+                       TALLOC_FREE(frame);
+                       return -1;
+               }
+       }
 
         srv = smbc_server(context, True,
                           server, share, workgroup, user, password);
@@ -6392,7 +6510,7 @@ smbc_unlink_print_job_ctx(SMBCCTX *context,
 }
 
 /*
- * Get a new empty handle to fill in with your own info 
+ * Get a new empty handle to fill in with your own info
  */
 SMBCCTX *
 smbc_new_context(void)
@@ -6416,7 +6534,6 @@ smbc_new_context(void)
 
         ZERO_STRUCTP(context->internal);
 
-        
         /* ADD REASONABLE DEFAULTS */
         context->debug            = 0;
         context->timeout          = 20000; /* 20 seconds */
@@ -6465,10 +6582,10 @@ smbc_new_context(void)
         return context;
 }
 
-/* 
+/*
  * Free a context
  *
- * Returns 0 on success. Otherwise returns 1, the SMBCCTX is _not_ freed 
+ * Returns 0 on success. Otherwise returns 1, the SMBCCTX is _not_ freed
  * and thus you'll be leaking memory if not handled properly.
  *
  */
@@ -6480,11 +6597,11 @@ smbc_free_context(SMBCCTX *context,
                 errno = EBADF;
                 return 1;
         }
-        
+
         if (shutdown_ctx) {
                 SMBCFILE * f;
                 DEBUG(1,("Performing aggressive shutdown.\n"));
-                
+
                 f = context->internal->_files;
                 while (f) {
                         (context->close_fn)(context, f);
@@ -6514,7 +6631,7 @@ smbc_free_context(SMBCCTX *context,
                 }
         }
         else {
-                /* This is the polite way */    
+                /* This is the polite way */
                 if ((context->callbacks.purge_cached_fn)(context)) {
                         DEBUG(1, ("Could not purge all servers, "
                                   "free_context failed.\n"));
@@ -6532,14 +6649,14 @@ smbc_free_context(SMBCCTX *context,
                                   "free_context failed.\n"));
                         errno = EBUSY;
                         return 1;
-                }               
+                }
         }
 
         /* Things we have to clean up */
         SAFE_FREE(context->workgroup);
         SAFE_FREE(context->netbios_name);
         SAFE_FREE(context->user);
-        
+
         DEBUG(3, ("Context %p succesfully freed\n", context));
         SAFE_FREE(context->internal);
         SAFE_FREE(context);
@@ -6669,7 +6786,7 @@ smbc_option_get(SMBCCTX *context,
 
 
 /*
- * Initialise the library etc 
+ * Initialise the library etc
  *
  * We accept a struct containing handle information.
  * valid values for info->debug from 0 to 100,
@@ -6678,7 +6795,6 @@ smbc_option_get(SMBCCTX *context,
 SMBCCTX *
 smbc_init_context(SMBCCTX *context)
 {
-        pstring conf;
         int pid;
         char *user = NULL;
         char *home = NULL;
@@ -6689,7 +6805,7 @@ smbc_init_context(SMBCCTX *context)
         }
 
         /* Do not initialise the same client twice */
-        if (context->internal->_initialized) { 
+        if (context->internal->_initialized) {
                 return 0;
         }
 
@@ -6712,7 +6828,7 @@ smbc_init_context(SMBCCTX *context)
 
                 /* Set this to what the user wants */
                 DEBUGLEVEL = context->debug;
-                
+
                 load_case_tables();
 
                 setup_logging("libsmbclient", True);
@@ -6722,20 +6838,23 @@ smbc_init_context(SMBCCTX *context)
                 }
 
                 /* Here we would open the smb.conf file if needed ... */
-                
+
                 in_client = True; /* FIXME, make a param */
 
                 home = getenv("HOME");
                if (home) {
-                       slprintf(conf, sizeof(conf), "%s/.smb/smb.conf", home);
-                       if (lp_load(conf, True, False, False, True)) {
-                               conf_loaded = True;
-                       } else {
-                                DEBUG(5, ("Could not load config file: %s\n",
-                                          conf));
+                               char *conf = NULL;
+                       if (asprintf(&conf, "%s/.smb/smb.conf", home) > 0) {
+                               if (lp_load(conf, True, False, False, True)) {
+                                       conf_loaded = True;
+                               } else {
+                                       DEBUG(5, ("Could not load config file: %s\n",
+                                               conf));
+                               }
+                               SAFE_FREE(conf);
                        }
                        }
+
                if (!conf_loaded) {
                         /*
                          * Well, if that failed, try the dyn_CONFIGFILE
@@ -6748,40 +6867,44 @@ smbc_init_context(SMBCCTX *context)
                                 DEBUG(5, ("Could not load config file: %s\n",
                                           dyn_CONFIGFILE));
                         } else if (home) {
+                               char *conf;
                                 /*
                                  * We loaded the global config file.  Now lets
                                  * load user-specific modifications to the
                                  * global config.
                                  */
-                                slprintf(conf, sizeof(conf),
-                                         "%s/.smb/smb.conf.append", home);
-                                if (!lp_load(conf, True, False, False, False)) {
-                                        DEBUG(10,
-                                              ("Could not append config file: "
-                                               "%s\n",
-                                               conf));
-                                }
+                               if (asprintf(&conf,
+                                               "%s/.smb/smb.conf.append",
+                                               home) > 0) {
+                                       if (!lp_load(conf, True, False, False, False)) {
+                                               DEBUG(10,
+                                               ("Could not append config file: "
+                                               "%s\n",
+                                               conf));
+                                       }
+                                       SAFE_FREE(conf);
+                               }
                         }
                 }
 
                 load_interfaces();  /* Load the list of interfaces ... */
-                
+
                 reopen_logs();  /* Get logging working ... */
-        
-                /* 
-                 * Block SIGPIPE (from lib/util_sock.c: write())  
-                 * It is not needed and should not stop execution 
+
+                /*
+                 * Block SIGPIPE (from lib/util_sock.c: write())
+                 * It is not needed and should not stop execution
                  */
                 BlockSignals(True, SIGPIPE);
-                
+
                 /* Done with one-time initialisation */
-                smbc_initialized = 1; 
+                smbc_initialized = 1;
 
         }
-        
+
         if (!context->user) {
                 /*
-                 * FIXME: Is this the best way to get the user info? 
+                 * FIXME: Is this the best way to get the user info?
                  */
                 user = getenv("USER");
                 /* walk around as "guest" if no username can be found */
@@ -6827,17 +6950,17 @@ smbc_init_context(SMBCCTX *context)
         }
 
         DEBUG(1, ("Using workgroup %s.\n", context->workgroup));
-                                        
+
         /* shortest timeout is 1 second */
-        if (context->timeout > 0 && context->timeout < 1000) 
+        if (context->timeout > 0 && context->timeout < 1000)
                 context->timeout = 1000;
 
         /*
-         * FIXME: Should we check the function pointers here? 
+         * FIXME: Should we check the function pointers here?
          */
 
         context->internal->_initialized = True;
-        
+
         return context;
 }