import HEAD into svn+ssh://svn.samba.org/home/svn/samba/trunk
[metze/old/v3-2-winbind-ndr.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 /****************************************************************************
24  Open a file with a share mode.
25 ****************************************************************************/
26 files_struct *open_fake_file_shared1(enum FAKE_FILE_TYPE fake_file_type, connection_struct *conn,char *fname,
27                                 SMB_STRUCT_STAT *psbuf, 
28                                 uint32 desired_access, 
29                                 int share_mode,int ofun, uint32 new_dos_attr, int oplock_request, 
30                                 int *Access,int *action)
31 {
32         extern struct current_user current_user;
33         int flags=0;
34         files_struct *fsp = NULL;
35
36         if (fake_file_type == 0) {
37                 return open_file_shared1(conn,fname,psbuf,desired_access,
38                                         share_mode,ofun,new_dos_attr,
39                                         oplock_request,Access,action);  
40         }
41
42         /* access check */
43         if (conn->admin_user != True) {
44                 DEBUG(1,("access_denied to service[%s] file[%s] user[%s]\n",
45                         lp_servicename(SNUM(conn)),fname,conn->user));
46                 errno = EACCES;
47                 return NULL;
48         }
49
50         fsp = file_new(conn);
51         if(!fsp)
52                 return NULL;
53
54         DEBUG(5,("open_fake_file_shared1: fname = %s, FID = %d, share_mode = %x, ofun = %x, oplock request = %d\n",
55                 fname, fsp->fnum, share_mode, ofun, oplock_request ));
56
57         if (!check_name(fname,conn)) {
58                 file_free(fsp);
59                 return NULL;
60         } 
61
62         fsp->fd = -1;
63         fsp->mode = psbuf->st_mode;
64         fsp->inode = psbuf->st_ino;
65         fsp->dev = psbuf->st_dev;
66         fsp->vuid = current_user.vuid;
67         fsp->size = psbuf->st_size;
68         fsp->pos = -1;
69         fsp->can_lock = True;
70         fsp->can_read = ((flags & O_WRONLY)==0);
71         fsp->can_write = ((flags & (O_WRONLY|O_RDWR))!=0);
72         fsp->share_mode = 0;
73         fsp->desired_access = desired_access;
74         fsp->print_file = False;
75         fsp->modified = False;
76         fsp->oplock_type = NO_OPLOCK;
77         fsp->sent_oplock_break = NO_BREAK_SENT;
78         fsp->is_directory = False;
79         fsp->is_stat = False;
80         fsp->directory_delete_on_close = False;
81         fsp->conn = conn;
82         string_set(&fsp->fsp_name,fname);
83         fsp->wcp = NULL; /* Write cache pointer. */
84         
85         fsp->fake_file_handle = init_fake_file_handle(fake_file_type);
86         
87         if (fsp->fake_file_handle==NULL) {
88                 file_free(fsp);
89                 return NULL;
90         }
91
92         conn->num_files_open++;
93         return fsp;
94 }
95
96 static FAKE_FILE fake_files[] = {
97 #ifdef WITH_QUOTAS
98         {FAKE_FILE_NAME_QUOTA,  FAKE_FILE_TYPE_QUOTA,   init_quota_handle,      destroy_quota_handle},
99 #endif /* WITH_QUOTAS */
100         {NULL,                  FAKE_FILE_TYPE_NONE,    NULL,                   NULL }
101 };
102
103 int is_fake_file(char *fname)
104 {
105         int i;
106
107         if (!fname)
108                 return 0;
109
110         for (i=0;fake_files[i].name!=NULL;i++) {
111                 if (strncmp(fname,fake_files[i].name,strlen(fake_files[i].name))==0) {
112                         DEBUG(5,("is_fake_file: [%s] is a fake file\n",fname));
113                         return fake_files[i].type;
114                 }
115         }
116
117         return FAKE_FILE_TYPE_NONE;
118 }
119
120 struct _FAKE_FILE_HANDLE *init_fake_file_handle(enum FAKE_FILE_TYPE type)
121 {
122         TALLOC_CTX *mem_ctx = NULL;
123         FAKE_FILE_HANDLE *fh = NULL;
124         int i;
125
126         for (i=0;fake_files[i].name!=NULL;i++) {
127                 if (fake_files[i].type==type) {
128                         DEBUG(5,("init_fake_file_handle: for [%s]\n",fake_files[i].name));
129
130                         if ((mem_ctx=talloc_init("fake_file_handle"))==NULL) {
131                                 DEBUG(0,("talloc_init(fake_file_handle) failed.\n"));
132                                 return NULL;    
133                         }
134
135                         if ((fh =(FAKE_FILE_HANDLE *)talloc_zero(mem_ctx, sizeof(FAKE_FILE_HANDLE)))==NULL) {
136                                 DEBUG(0,("talloc_zero() failed.\n"));
137                                 talloc_destroy(mem_ctx);
138                                 return NULL;
139                         }
140
141                         fh->type = type;
142                         fh->mem_ctx = mem_ctx;
143
144                         if (fake_files[i].init_pd)
145                                 fh->pd = fake_files[i].init_pd(fh->mem_ctx);
146
147                         fh->free_pd = fake_files[i].free_pd;
148
149                         return fh;
150                 }
151         }
152
153         return NULL;    
154 }
155
156 void destroy_fake_file_handle(FAKE_FILE_HANDLE **fh)
157 {
158         if (!fh||!(*fh))
159                 return ;
160
161         if ((*fh)->free_pd)
162                 (*fh)->free_pd(&(*fh)->pd);             
163
164         talloc_destroy((*fh)->mem_ctx);
165         (*fh) = NULL;
166 }