summaryrefslogtreecommitdiff
path: root/source4/ntvfs/posix/vfs_posix.c
blob: b27e7493a0097b7863ee388d56a501c6e11faa3e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/* 
   Unix SMB/CIFS implementation.
   POSIX NTVFS backend
   Copyright (C) Andrew Tridgell 1992-2003
   Copyright (C) Andrew Bartlett      2001

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.
   
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
   
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
  this implements most of the POSIX NTVFS backend
  This is the default backend
*/

#include "includes.h"

/*
  connect to a share - used when a tree_connect operation comes
  in. For a disk based backend we needs to ensure that the base
  directory exists (tho it doesn't need to be accessible by the user,
  that comes later)
*/
static NTSTATUS pvfs_connect(struct ntvfs_context *ctx, const char *sharename)
{
	struct stat st;
	struct connection_struct *conn = ctx->conn;
	NTSTATUS status;

	/* the directory must exist */
	if (stat(conn->connectpath, &st) != 0 || !S_ISDIR(st.st_mode)) {
		DEBUG(0,("'%s' is not a directory, when connecting to [%s]\n", 
			 conn->connectpath, lp_servicename(SNUM(conn))));
		return NT_STATUS_BAD_NETWORK_NAME;
	}

	/* Initialise old VFS function pointers */
	if (!smbd_vfs_init(conn)) {
		DEBUG(0, ("vfs_init failed for service %s\n", lp_servicename(SNUM(conn))));
		return NT_STATUS_BAD_NETWORK_NAME;
	}

	/* become the user for the rest */
	status = ntvfs_change_to_user(ctx);
	if (!NT_STATUS_IS_OK(status)) {
		return status;
	}

	/* the posix backend can do preexec */
	status = ntvfs_connect_preexec(ctx);
	if (!NT_STATUS_IS_OK(status)) {
		return status;
	}

	/* Invoke the old POSIX VFS make connection hook */
	if (conn->vfs_ops.connect && 
	    conn->vfs_ops.connect(conn, lp_servicename(snum), user) < 0) {
			DEBUG(0,("make_connection: POSIX VFS make connection failed!\n"));
			return NT_STATUS_UNSUCCESSFUL;
		}
	}


	/*
	 * Print out the 'connected as' stuff here as we need
	 * to know the effective uid and gid we will be using
	 * (at least initially).
	 */
	if( DEBUGLVL( IS_IPC(conn) ? 3 : 1 ) ) {
		dbgtext( "%s (%s) ", get_remote_machine_name(), conn->client_address );
		dbgtext( "connect to service %s ", lp_servicename(SNUM(conn)) );
		dbgtext( "initially as user %s ", user );
		dbgtext( "(uid=%d, gid=%d) ", (int)geteuid(), (int)getegid() );
		dbgtext( "(pid %d)\n", (int)sys_getpid() );
	}
	
	return NT_STATUS_OK;
}

/*
  disconnect from a share
*/
static NTSTATUS pvfs_disconnect(struct ntvfs_context *ctx)
{
	return NT_STATUS_OK;
}

/*
  delete a file - the dirtype specifies the file types to include in the search. 
  The name can contain CIFS wildcards, but rarely does (except with OS/2 clients)
*/
static NTSTATUS pvfs_unlink(struct ntvfs_context *ctx, const char *name, uint16 dirtype)
{
	NTSTATUS status;

	if (ntvfs_dfs_redirect(ctx, name)) {
		return NT_STATUS_PATH_NOT_COVERED;
	}
	
	status = unlink_internals(ctx->conn, dirtype, name);
	if (!NT_STATUS_IS_OK(status)) {
		return status;
	}

	ntvfs_run_change_notify_queue();
	
	return NT_STATUS_OK;
}







/*
  initialialise the POSIX disk backend, registering ourselves with the ntvfs subsystem
 */
BOOL posix_vfs_init(void)
{
	BOOL ret;
	struct ntvfs_ops ops;

	ZERO_STRUCT(ops);
	
	/* fill in all the operations */
	ops.connect = pvfs_connect;
	ops.disconnect = pvfs_disconnect;
	ops.unlink = pvfs_unlink;

	/* register ourselves with the NTVFS subsystem. We register under the name 'default'
	   as we wish to be the default backend */
	ret = ntvfs_register("default", NTVFS_DISK, &ops);

	if (!ret) {
		DEBUG(0,("Failed to register POSIX backend!\n"));
		return False;
	}

	return True;
}