Open Files 5.3.0
Multi-Platform Event-Driven Application Framework
SMB Applications

ConnectSMB also comes with a set of SMB Applications that can either be used as examples on how to integrate the SMB APIs into customer applications or they can be used as binaries that can be integrated as system calls into a deployed system.

The SMBCP applications are maintained as a separate git repo:

https://github.com/connectedway/smbcp.git

The smbcp applications require ConnectSMB SMB client libraries to be installed first. There are 4 applications:

The smbcp applications are dynamically linked. The applications themselves are built seperately from the ConnectSMB framework and they are simply linked with the framework on the target system.


Command Overview

The syntax and decription of the ConnectSMB SMB commands are describe here.


smbcp

Copy a file to a destination file. The syntax of smbcp is:

$ smbcp [-a] <source> <destination>

Where -a signifies that the copy operation should be done asynchronously using multiple overlapped buffers. The absense of -a specifies that the copy is done synchronously. Only one I/O is outstanding at a time in synchronous mode.

The target file must be fully specified. In other words, you must provide the target file name. Simply specifying the target directory is not sufficient.

ConnectSMB can operate in one of two authentication mode: Active Directory and NTLM. Active Directory authentication requires a kerberos stack preinstalled on your target system and active domain controllers with users and target computers. Before running any of the smbcp applications in Active Directory mode, you must first obtain a user ticket. On linux this can be done with the kinit kerberos utility.

$ kinit <user>@<domain>

The utility will prompt for your domain password.

smbcp can copy a file from local or remote locations to a file that resides locally or remotely. A file specification is of the form:

[//username:password:domain@server/share/]path.../file

If authenticated with Active Directory (or samba ad/dc), you will not need to specify a username or password in the URL. And if using Active Directory the domain portion of the URL is used to specify the path to the kerberos ticket cache to use. If not specified, the default cache is used.

If authenticating with NTLM (this is called standalone authentication), the username and password is required. The domain portion is optional but allows the target to authenticate the user against the specified domain.

Path can be any depth as long as the total file path is less than 256 bytes. For example:

$ smbcp //me:secret@remote/share/subdirectory/picture.jpg ./picture.jpg

This command will access the server named 'remote' and log in using the username 'me' and the password 'secret'. It will implicitly mount the remote share named 'share' and will access the file 'subdirectory/picture.jpg' relative to the share. It will copy the file locally to the filename picture.jpg.

The source path and destination path can be either local or remote so copies from a remote to a local, from a local to a remote, from a local to a local, and from a remote to a remote are all possible.


smbfree

Find the freespace of the target file system. The syntax of smbfree is:

$ smbfree <target>

Where target is a path that include a remote share. The format of the URL is the same as described in the smbcp command.


smbls

List the contents of a target directory. The syntax of smbls is:

$ smbls <directory>

Where directory is a path that is a path to a directory. The format of the URL is the same as described in the smbcp command.


smbrm

Delete a target file. The syntax of smbrm is:

$ smbrm <path>

Where path is a path that is a path to a file. The format of the URL is the same as described in the smbcp command.


Building the smbcp application

If you are building a yocto based distribution using the of_manifests repo configuration, the smbcp application will be built and included in your distribution.

If you are deploying ConnectSMB in a Linux environment, you will need to clone, build, and install smbcp on your Linux machine.


Cloning the smbcp repository

To clone the repo, simply issue:

$ git clone https://github.com/connectedway/smbcp.git
$ cd smbcp

Building the smbcp Application

Note that if you wish to build the smbcp application, you will have had to successfully build and installed the ConnectSMB Framework. You can find more here and here.

Then simply issue:

$ make

Installing the smbcp Application

You can install the application into your system directories by issuing:

$ sudo make install

The application will be install, by default, in /usr/local/bin/openfiles. You may wish to add this to your path variable:

$ export PATH=$PATH:/usr/local/bin/openfiles

Update your shell startup scripts accordingly

The following applications will be installed:

  • /usr/local/bin/openfiles/smbcp
  • /usr/local/bin/openfiles/smbfree
  • /usr/local/bin/openfiles/smbls
  • /usr/local/bin/openfiles/smbrm

Uninstalling the smbcp Application

You can uninstall the application from your system directories by issuing:

$ sudo make uninstall

Cleaning your build directory

You can clean up build artifacts from your build directory by issuing:

$ make clean

Running the smbcp application

You can run the application by following the description in this document.


smbcp Implementation

The implementatoin of the smbcp application is relevant for integrating customer applications with the Linux based ConnectSMB framework.


smbcp Makefile

The makefile is a basic make. The smbcp application consists of one object file for each utility: smbcp.o, smbfree.o, smbls.o and smbrm.o. The object file is compiled using default CFLAGS which includes a specification of the sysroot which will contain the necessary ConnectSMB header files. The executable is linked with five shared libraries:

  • libof_smb_shared
  • libof_core_shared
  • libssl
  • libkrb5
  • libgssapi_krb5

The makefile, as written, links with the openssl crypto libraries. Open Files supports opensl, mbedtl, and gnutls. See the (see config) if you wish to uses a different crypto library and update this Makefile accordingly.

We specify the linker option --no-as-needed which directs the linker to include the libraries whether they are explicity referenced in the object files or not. This is needed if we wish to utilize implicit library constructors. As a conveniece to openfile application developers, we will initialize the stack implicitly upon library load rather than requiring the developer to initialize the stack within the application itself.


smbcp Source Code

This readme will walk through the implemenation of the smbcp.c application. The other applications will have similar APIs and are not described here.

This readme will not go through line by line within the smbcp.c source file. Rather, we'll call out relevant sections.

An ConnectSMB application can use standard C libraries and with respect to smbcp, we use five. The wchar.h file is included so we can convert ASCII characters to wide characters used as part of the ConnectSMB API. NOTE that ConnectSMB exposes an ascii API as well but wide characters is recommended.

There are seven ConnectSMB header files used by this application. ConnectSMB provides a robust set of APIs for many services. We recommend viewing the /ref openiles documentation for more detail. The ConnectSMB recipe and makefiles installs a subset of the available APIs into the yocto sysroot. If you find that particular headers are not available in your sysroot, Connected Way support will be glad to export them for you.

A brief description of the headers used:

  • ofc/config.h - This provides constants that the ConnectSMB framework was built with. This will have defines for the maximum buffer size, whether smb I/O is supported and more.
  • ofc/handle.h - This defines a generic handle type used to refer to openfile objects. Handles are used throughout ConnectSMB and can refer to files, queues, events, sockets and more.
  • ofc/types.h - This defines the basic types used by ConnectSMB.
  • ofc/file.h - The API used by the ConnectSMB file system.
  • ofc/waitset.h - This allows aggregation of waitable objects. This is used by the asynchronous file copy to manage asynchronous completion of multiple buffers.
  • ofc/queue.h - This is a robust abstraction of a doubly linked list. It is purely a convenience facility but is heavily used throughout the ConnectSMB framework and within the smbcp application to maintain lists of buffers.
  • of_smb/framework.h - This is generally not needed. For smbcp, we include it to expose the API for setting DFS bootstrap DCs. This should not be necesary but is provided or example only.

In the simple case, this is the full set of APIs needed to interact with the ConnectSMB framework. The main set of APIs is contained in the header file.h. For the most part, the file API of ConnectSMB is based on the Windows File APIs.

The smbcp.c source file contains code for both the asynchronous file copy and synchronous file copy modes.

The synchronous file copy is simple. It simply opens up the source and destination files and then enters a loop where a buffer is read from the read file, and written to the write file. The loop continues till an eof on the read file or an error on either. The entry point of the synchronous copy is:

static OFC_DWORD copy_sync(OFC_CTCHAR *rfilename, OFC_CTCHAR *wfilename)

Pseudo code for the simple file copy follows. Also see: smbcp.c

Begin

    Open the Read File as read_file

    Open the Write File as write_fil

    while Read from read_file into buffer and length is True

        Write to write_file from buffer and length

    Close write_file

    Close read_file

Done

The asynchronous code supports arbitrary queue depth of arbitrary buffer size (up to a max of OFC_MAX_IO). If you have questions on the operation of the asynchrous copy, please contact Connected Way support. The buffer management of the asynchronous copy is where most of the complication to this utility lies. The buffer management utilizes the ConnectSMB framework, thus the need for the ConnectSMB headers.

The entry point to the asynchronous file copy is

static OFC_DWORD copy_async(OFC_CTCHAR *rfilename, OFC_CTCHAR *wfilename)

The main entry point parses the arguments, converts the ascii file names into wide character file names and calls the respective asynchronous or synchronous entry points.

The APIs used by smbcp are:

APIs for Synchronous File Copy:

  • OfcCreateFile - Create or Open a Local or Remote file.
  • OfcReadFile - Read from a Local or Remote File
  • OfcWriteFile - Write to a Local or Remote File
  • OfcGetLasstError - Get the last error code encountered
  • OfcCloseHandle - Close a Local or Remote File
  • ofc_get_error_string - Convert a last error into a string

APIs for Asynchronous File Copy:

  • OfcSetOverlappedOffset - Set the offset for an overlapped buffer
  • OfcGetOverlappedResult - Get the result of an overlapped i/o
  • OfcDestroyOverlapped - Destroy an overlapped buffer
  • OfcCreateOverlapped - Create an overlapped buffer
  • OfcReadFile - Read from a local or remote file
  • OfcWriteFile - Write to a local or remote file
  • OfcCreateFile - Create or Open a local or remote file
  • OfcCloseHandle - Close a local or remote file
  • OfcGetLastError - Get the last error code encountered
  • ofc_waitset_add - Add an object to a list of waitable objects
  • ofc_waitset_remove - Remove an object from a list of waitable objects
  • ofc_waitset_destroy - Destroy the list of waitable objects
  • ofc_waitset_create - Create a list of waitable objects
  • ofc_waitset_wait - Wait for a buffer completion
  • ofc_handle_get_app - Get a buffer association
  • ofc_dequeue - Dequeue a buffer from a buffer list
  • ofc_queue_create - Create a buffer list
  • ofc_enqueue - Queue a buffer to a buffer list
  • ofc_queue_first - Get the first item on the buffer list
  • ofc_queue_next - Get the subsequent item on a buffer list
  • ofc_get_error_string - Convert a last error into a string

It is clear from the list of APIs used between synchronous and asynchronous file copy that the asynchronous mode is more complex but it can offer considerable performance improvements

This is the full list of APIs required for either mode. This should help in understanding the level of effort in integrating ConnectSMB with a customer application.

There are a few features of ConnectSMB which allow this simple set of APIs:

  • Implicit Framework Initialization and Destruction. No explicit initialization required although explicit and static initialization is supported.
  • Implicit Remote Connections. Connections to remotes do not need to be explicitly established. Remote URLs are examined and if the URL is to a remote that does not have a connection, a connection will be established and authenticated. Connections are closed when idle.
  • Implicit Share Mounting. Mounting of a share is performed implicity when accessing a file through the URL. No explicit mounting or unmounting of a share is required. Shares are dismounted when idle.
  • Integrated local and remote file APIs. No need to be aware of whether a file is local or remote. The framework handles the difference internally.