r6225: get rid of warnings from my compiler about nested externs
[kai/samba-autobuild/.git] / source / smbd / fake_file.c
1 /* 
2    Unix SMB/CIFS implementation.
3    FAKE FILE suppport, for faking up special files windows want access to
4    Copyright (C) Stefan (metze) Metzmacher      2003
5    
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2 of the License, or
9    (at your option) any later version.
10    
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15    
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #include "includes.h"
22
23 extern struct current_user current_user;
24
25 /****************************************************************************
26  Open a file with a share mode.
27 ****************************************************************************/
28 files_struct *open_fake_file_shared1(enum FAKE_FILE_TYPE fake_file_type, connection_struct *conn,char *fname,
29                                 SMB_STRUCT_STAT *psbuf, 
30                                 uint32 desired_access, 
31                                 int share_mode,int ofun, uint32 new_dos_attr, int oplock_request, 
32                                 int *Access,int *action)
33 {
34         int flags=0;
35         files_struct *fsp = NULL;
36
37         if (fake_file_type == 0) {
38                 return open_file_shared1(conn,fname,psbuf,desired_access,
39                                         share_mode,ofun,new_dos_attr,
40                                         oplock_request,Access,action);  
41         }
42
43         /* access check */
44         if (current_user.uid != 0) {
45                 DEBUG(1,("access_denied to service[%s] file[%s] user[%s]\n",
46                         lp_servicename(SNUM(conn)),fname,conn->user));
47                 errno = EACCES;
48                 return NULL;
49         }
50
51         fsp = file_new(conn);
52         if(!fsp)
53                 return NULL;
54
55         DEBUG(5,("open_fake_file_shared1: fname = %s, FID = %d, share_mode = %x, ofun = %x, oplock request = %d\n",
56                 fname, fsp->fnum, share_mode, ofun, oplock_request ));
57
58         if (!check_name(fname,conn)) {
59                 file_free(fsp);
60                 return NULL;
61         } 
62
63         fsp->fd = -1;
64         fsp->mode = psbuf->st_mode;
65         fsp->inode = psbuf->st_ino;
66         fsp->dev = psbuf->st_dev;
67         fsp->vuid = current_user.vuid;
68         fsp->size = psbuf->st_size;
69         fsp->pos = -1;
70         fsp->can_lock = True;
71         fsp->can_read = ((flags & O_WRONLY)==0);
72         fsp->can_write = ((flags & (O_WRONLY|O_RDWR))!=0);
73         fsp->share_mode = 0;
74         fsp->desired_access = desired_access;
75         fsp->print_file = False;
76         fsp->modified = False;
77         fsp->oplock_type = NO_OPLOCK;
78         fsp->sent_oplock_break = NO_BREAK_SENT;
79         fsp->is_directory = False;
80         fsp->is_stat = False;
81         fsp->directory_delete_on_close = False;
82         fsp->conn = conn;
83         string_set(&fsp->fsp_name,fname);
84         fsp->wcp = NULL; /* Write cache pointer. */
85         
86         fsp->fake_file_handle = init_fake_file_handle(fake_file_type);
87         
88         if (fsp->fake_file_handle==NULL) {
89                 file_free(fsp);
90                 return NULL;
91         }
92
93         conn->num_files_open++;
94         return fsp;
95 }
96
97 static FAKE_FILE fake_files[] = {
98 #ifdef WITH_QUOTAS
99         {FAKE_FILE_NAME_QUOTA_UNIX,     FAKE_FILE_TYPE_QUOTA,   init_quota_handle,      destroy_quota_handle},
100 #endif /* WITH_QUOTAS */
101         {NULL,                          FAKE_FILE_TYPE_NONE,    NULL,                   NULL }
102 };
103
104 int is_fake_file(char *fname)
105 {
106         int i;
107
108         if (!fname)
109                 return 0;
110
111         for (i=0;fake_files[i].name!=NULL;i++) {
112                 if (strncmp(fname,fake_files[i].name,strlen(fake_files[i].name))==0) {
113                         DEBUG(5,("is_fake_file: [%s] is a fake file\n",fname));
114                         return fake_files[i].type;
115                 }
116         }
117
118         return FAKE_FILE_TYPE_NONE;
119 }
120
121 struct _FAKE_FILE_HANDLE *init_fake_file_handle(enum FAKE_FILE_TYPE type)
122 {
123         TALLOC_CTX *mem_ctx = NULL;
124         FAKE_FILE_HANDLE *fh = NULL;
125         int i;
126
127         for (i=0;fake_files[i].name!=NULL;i++) {
128                 if (fake_files[i].type==type) {
129                         DEBUG(5,("init_fake_file_handle: for [%s]\n",fake_files[i].name));
130
131                         if ((mem_ctx=talloc_init("fake_file_handle"))==NULL) {
132                                 DEBUG(0,("talloc_init(fake_file_handle) failed.\n"));
133                                 return NULL;    
134                         }
135
136                         if ((fh =TALLOC_ZERO_P(mem_ctx, FAKE_FILE_HANDLE))==NULL) {
137                                 DEBUG(0,("talloc_zero() failed.\n"));
138                                 talloc_destroy(mem_ctx);
139                                 return NULL;
140                         }
141
142                         fh->type = type;
143                         fh->mem_ctx = mem_ctx;
144
145                         if (fake_files[i].init_pd)
146                                 fh->pd = fake_files[i].init_pd(fh->mem_ctx);
147
148                         fh->free_pd = fake_files[i].free_pd;
149
150                         return fh;
151                 }
152         }
153
154         return NULL;    
155 }
156
157 void destroy_fake_file_handle(FAKE_FILE_HANDLE **fh)
158 {
159         if (!fh||!(*fh))
160                 return;
161
162         if ((*fh)->free_pd)
163                 (*fh)->free_pd(&(*fh)->pd);             
164
165         talloc_destroy((*fh)->mem_ctx);
166         (*fh) = NULL;
167 }