[Samba] programming libsmbclient

Henrik Zagerholm henke at mac.se
Thu May 10 16:58:20 GMT 2007


10 maj 2007 kl. 17:22 skrev Mattieu Puel:

> hi all,
> I have a strange problem using the libsmbclient api..
>
> retrieving or stating files named with percents in is for some
> of them impossible. Example: a file located at "smb://test/test/% 
> 7C2.txt" cannot be retrieved
> with my code, smbc_open fails with the code  
> NT_STATUS_OBJECT_NAME_INVALID.
>
> I am not sure but, url encoding/decoding that would escape strings  
> with "percent" in should be 'internals'
> of samba right ?
> At the same time under the same constraints, a file named 'whatever- 
> you-want-except-with-percent'
> is correctly stated, opened, read.
> I tested the code on several distributions (debian, gentoo..) with  
> the same results. I tried
> with several CIFS servers too (Win Xp, linux...).
>
> Attached: the source and the trace given by smbc_init with debug = 9.
>
> Anyone any idea ?
>

 From libsmbclinet.h

the smbc_
                  * functions expect a URL which must be url- 
encoded.  Those
                  * functions decode the URL.  If, for example,  
smbc_readdir()
                  * returned a file name of "abc%20def.txt", passing  
a path
                  * with this file name attached to smbc_open() would  
cause
                  * smbc_open to attempt to open the file "abc  
def.txt" since
                  * the %20 is decoded into a space.


and
/*
  * Convert any characters not specifically allowed in a URL into  
their %xx
  * equivalent.
  *
  * @param dest      A pointer to a buffer in which the resulting  
encoded
  *                  string should be placed.  Unlike smbc_urldecode 
(), this
  *                  must be a buffer unique from src.
  *
  * @param src       A pointer to the buffer containing the string to  
be encoded.
  *                  Any character not specifically allowed in a URL  
is converted
  *                  into its hexadecimal value and encoded as %xx.
  *
  * @param max_dest_len
  *                  The size of the buffer pointed to by dest_segment.
  *
  * @returns         The remaining buffer length.
  */
#ifdef __cplusplus
extern "C" {
#endif
int
smbc_urlencode(char * dest, char * src, int max_dest_len);


So you need to encode % :)

Good luck!

>
> the code:
>
>
> ---------------------------------------------------------------------- 
> ----------------
> #include <sys/types.h>
> #include <stdio.h>
> #include <unistd.h>
> #include <string.h>
> #include <time.h>
> #include <errno.h>
> #include <libsmbclient.h>
>
> static void
> get_auth_data_fn(const char * pServer,
>                  const char * pShare,
>                  char * pWorkgroup,
>                  int maxLenWorkgroup,
>                  char * pUsername,
>                  int maxLenUsername,
>                  char * pPassword,
>                  int maxLenPassword)
> {
>     sprintf( pWorkgroup, "%s", "WG" );
>     sprintf( pUsername, "%s", "test" );
>     sprintf( pPassword, "%s", "test" );
> }
>
>
> int main(int argc, char * argv[])
> {
>     int             fd;
>     int             ret;
>     int             debug = 9;
>     int             savedErrno;
>     char            buffer[2048];
>     char *          pSmbPath = NULL;
>
>     if (argc == 2)
>     {
>         pSmbPath = argv[1];
>     }
>     else
>     {
>         printf("usage: "
>                "%s [ smb://path/to/file ]\n",
>                argv[0]);
>         return 1;
>     }
>
>     smbc_init(get_auth_data_fn, debug);
>
>     printf("Open file %s\n", pSmbPath);
>
>     if ((fd = smbc_open(pSmbPath, O_RDONLY, 0)) < 0)
>     {
>         perror("smbc_open");
>         return 1;
>     }
>
>     do
>     {
>         ret = smbc_read(fd, buffer, sizeof(buffer));
>         savedErrno = errno;
>         if (ret > 0) fwrite(buffer, 1, ret, stdout);
>     } while (ret > 0);
>
>     smbc_close(fd);
>
>     if (ret < 0)
>     {
>         errno = savedErrno;
>         perror("read");
>         return 1;
>     }
>
>
>     return 0;
> }
>
> ---------------------------------------------------------------------- 
> --------
>
> the tail of the trace:
>
> Server connect ok: //regis/dossier: 0x8050508
> write_socket(4,88)
> write_socket(4,88) wrote 88
> size=35
> smb_com=0x2d
> smb_rcls=51
> smb_reh=0
> smb_err=49152
> smb_flg=136
> smb_flg2=51201
> smb_tid=2048
> smb_pid=13079
> smb_uid=2048
> smb_mid=5
> smt_wct=0
> smb_bcc=0
> smbc errno NT_STATUS_OBJECT_NAME_INVALID -> 22
> smbc_open: Argument invalide
> Open file smb://regis/dossier/a%7C2.txt
>
>
>
>
> -- 
> Mattieu PUEL
> Recherche & développement
> --
> Intradot Labs SAS
> +33 4 78 80 87 90 | www.intradot.com
> --
> Intradot a déménagé !
> Notez bien notre nouvelle adresse :
> 97 rue Racine - 69100 Villeurbanne
> <trace>
> -- 
> To unsubscribe from this list go to the following URL and read the
> instructions:  https://lists.samba.org/mailman/listinfo/samba



More information about the samba mailing list