b27e7493a0097b7863ee388d56a501c6e11faa3e
[jelmer/samba4-debian.git] / source / ntvfs / posix / vfs_posix.c
1 /* 
2    Unix SMB/CIFS implementation.
3    POSIX NTVFS backend
4    Copyright (C) Andrew Tridgell 1992-2003
5    Copyright (C) Andrew Bartlett      2001
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21 /*
22   this implements most of the POSIX NTVFS backend
23   This is the default backend
24 */
25
26 #include "includes.h"
27
28 /*
29   connect to a share - used when a tree_connect operation comes
30   in. For a disk based backend we needs to ensure that the base
31   directory exists (tho it doesn't need to be accessible by the user,
32   that comes later)
33 */
34 static NTSTATUS pvfs_connect(struct ntvfs_context *ctx, const char *sharename)
35 {
36         struct stat st;
37         struct connection_struct *conn = ctx->conn;
38         NTSTATUS status;
39
40         /* the directory must exist */
41         if (stat(conn->connectpath, &st) != 0 || !S_ISDIR(st.st_mode)) {
42                 DEBUG(0,("'%s' is not a directory, when connecting to [%s]\n", 
43                          conn->connectpath, lp_servicename(SNUM(conn))));
44                 return NT_STATUS_BAD_NETWORK_NAME;
45         }
46
47         /* Initialise old VFS function pointers */
48         if (!smbd_vfs_init(conn)) {
49                 DEBUG(0, ("vfs_init failed for service %s\n", lp_servicename(SNUM(conn))));
50                 return NT_STATUS_BAD_NETWORK_NAME;
51         }
52
53         /* become the user for the rest */
54         status = ntvfs_change_to_user(ctx);
55         if (!NT_STATUS_IS_OK(status)) {
56                 return status;
57         }
58
59         /* the posix backend can do preexec */
60         status = ntvfs_connect_preexec(ctx);
61         if (!NT_STATUS_IS_OK(status)) {
62                 return status;
63         }
64
65         /* Invoke the old POSIX VFS make connection hook */
66         if (conn->vfs_ops.connect && 
67             conn->vfs_ops.connect(conn, lp_servicename(snum), user) < 0) {
68                         DEBUG(0,("make_connection: POSIX VFS make connection failed!\n"));
69                         return NT_STATUS_UNSUCCESSFUL;
70                 }
71         }
72
73
74         /*
75          * Print out the 'connected as' stuff here as we need
76          * to know the effective uid and gid we will be using
77          * (at least initially).
78          */
79         if( DEBUGLVL( IS_IPC(conn) ? 3 : 1 ) ) {
80                 dbgtext( "%s (%s) ", get_remote_machine_name(), conn->client_address );
81                 dbgtext( "connect to service %s ", lp_servicename(SNUM(conn)) );
82                 dbgtext( "initially as user %s ", user );
83                 dbgtext( "(uid=%d, gid=%d) ", (int)geteuid(), (int)getegid() );
84                 dbgtext( "(pid %d)\n", (int)sys_getpid() );
85         }
86         
87         return NT_STATUS_OK;
88 }
89
90 /*
91   disconnect from a share
92 */
93 static NTSTATUS pvfs_disconnect(struct ntvfs_context *ctx)
94 {
95         return NT_STATUS_OK;
96 }
97
98 /*
99   delete a file - the dirtype specifies the file types to include in the search. 
100   The name can contain CIFS wildcards, but rarely does (except with OS/2 clients)
101 */
102 static NTSTATUS pvfs_unlink(struct ntvfs_context *ctx, const char *name, uint16 dirtype)
103 {
104         NTSTATUS status;
105
106         if (ntvfs_dfs_redirect(ctx, name)) {
107                 return NT_STATUS_PATH_NOT_COVERED;
108         }
109         
110         status = unlink_internals(ctx->conn, dirtype, name);
111         if (!NT_STATUS_IS_OK(status)) {
112                 return status;
113         }
114
115         ntvfs_run_change_notify_queue();
116         
117         return NT_STATUS_OK;
118 }
119
120
121
122
123
124
125
126 /*
127   initialialise the POSIX disk backend, registering ourselves with the ntvfs subsystem
128  */
129 BOOL posix_vfs_init(void)
130 {
131         BOOL ret;
132         struct ntvfs_ops ops;
133
134         ZERO_STRUCT(ops);
135         
136         /* fill in all the operations */
137         ops.connect = pvfs_connect;
138         ops.disconnect = pvfs_disconnect;
139         ops.unlink = pvfs_unlink;
140
141         /* register ourselves with the NTVFS subsystem. We register under the name 'default'
142            as we wish to be the default backend */
143         ret = ntvfs_register("default", NTVFS_DISK, &ops);
144
145         if (!ret) {
146                 DEBUG(0,("Failed to register POSIX backend!\n"));
147                 return False;
148         }
149
150         return True;
151 }