Changed the way a VFS is initialised. The vfs_init() function is
authorTim Potter <tpot@samba.org>
Tue, 20 Apr 1999 03:37:11 +0000 (03:37 +0000)
committerTim Potter <tpot@samba.org>
Tue, 20 Apr 1999 03:37:11 +0000 (03:37 +0000)
executed from the VFS object file and it returns a pointer to a
vfs_ops structure.  If any of the function pointers in vfs_ops are
NULL, then they are replaced with the standard disk functions.  This
should allow disk-related VFS modules to be easily added.  I've
written an auditing VFS module which logs various calls (connect,
disconnect, mkdir, rmdir, open and a few others) to syslog in a couple
of pages of code.

Thanks to tridge for various useful suggestions.
(This used to be commit 346c78d7078d87bc95abc274f2bc66476aeee54c)

source3/smbd/service.c

index 5c7929d1b6e25fed82c9255b599c8590d506001a..7628f9c8f0f3a3dfcf093eb0bf787a04a45d40c0 100644 (file)
@@ -354,7 +354,7 @@ connection_struct *make_connection(char *service,char *user,char *password, int
 
            /* Loadable object file */
 
-           if (vfs_init_custom(conn) < 0) {
+           if (!vfs_init_custom(conn)) {
                return NULL;
            }
 #else
@@ -516,7 +516,7 @@ connection_struct *make_connection(char *service,char *user,char *password, int
                extern int Client;
                
                dbgtext( "%s (%s) ", remote_machine, client_addr(Client) );
-               dbgtext( "connect to service %s ", lp_servicename(SNUM(conn)) );
+               dbgtext( "connect to service %s ", lp_servicename(SNUM(conn)));
                dbgtext( "as user %s ", user );
                dbgtext( "(uid=%d, gid=%d) ", (int)conn->uid, (int)conn->gid );
                dbgtext( "(pid %d)\n", (int)getpid() );
@@ -525,7 +525,42 @@ connection_struct *make_connection(char *service,char *user,char *password, int
        /* Invoke make connection hook */
 
        if (conn->vfs_ops.connect) {
-           if (conn->vfs_ops.connect(conn, service, user) < 0) {
+           struct vfs_connection_struct *vconn;
+
+           vconn = (struct vfs_connection_struct *)
+               malloc(sizeof(struct vfs_connection_struct));
+
+           if (vconn == NULL) {
+               DEBUG(0, ("No memory to create vfs_connection_struct"));
+               return NULL;
+           }
+
+           ZERO_STRUCTP(vconn);
+
+           /* Copy across relevant data from connection struct */
+
+           vconn->printer = conn->printer;
+           vconn->ipc = conn->ipc;
+           vconn->read_only = conn->read_only;
+           vconn->admin_user = conn->admin_user;
+
+           pstrcpy(vconn->dirpath, conn->dirpath);
+           pstrcpy(vconn->connectpath, conn->connectpath);
+           pstrcpy(vconn->origpath, conn->origpath);
+
+           pstrcpy(vconn->user, conn->user);
+           vconn->uid = conn->uid;
+           vconn->gid = conn->gid;
+           vconn->ngroups = conn->ngroups;
+           vconn->groups = (gid_t *)malloc(conn->ngroups * sizeof(gid_t));
+           if (vconn->groups != NULL) {
+               memcpy(vconn->groups, conn->groups, 
+                      conn->ngroups * sizeof(gid_t));
+           }
+
+           /* Call connect hook */
+           
+           if (conn->vfs_ops.connect(vconn, service, user) < 0) {
                return NULL;
            }
        }
@@ -549,7 +584,19 @@ void close_cnum(connection_struct *conn, uint16 vuid)
                                 lp_servicename(SNUM(conn))));
 
        if (conn->vfs_ops.disconnect != NULL) {
-         conn->vfs_ops.disconnect(conn, lp_servicename(SNUM(conn)));
+
+           /* Call disconnect hook */
+           
+           conn->vfs_ops.disconnect();
+           
+           /* Free vfs_connection_struct */
+           
+           if (conn->vfs_conn != NULL) {
+               if (conn->vfs_conn->groups != NULL) {
+                   free(conn->vfs_conn->groups);
+               }
+               free(conn->vfs_conn);
+           }
        }
 
        yield_connection(conn,