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 23extern struct current_user current_user; 24 25static FAKE_FILE fake_files[] = { 26#ifdef WITH_QUOTAS 27 {FAKE_FILE_NAME_QUOTA_UNIX, FAKE_FILE_TYPE_QUOTA, init_quota_handle, destroy_quota_handle}, 28#endif /* WITH_QUOTAS */ 29 {NULL, FAKE_FILE_TYPE_NONE, NULL, NULL } 30}; 31 32/**************************************************************************** 33 Create a fake file handle 34****************************************************************************/ 35 36static struct _FAKE_FILE_HANDLE *init_fake_file_handle(enum FAKE_FILE_TYPE type) 37{ 38 TALLOC_CTX *mem_ctx = NULL; 39 FAKE_FILE_HANDLE *fh = NULL; 40 int i; 41 42 for (i=0;fake_files[i].name!=NULL;i++) { 43 if (fake_files[i].type==type) { 44 DEBUG(5,("init_fake_file_handle: for [%s]\n",fake_files[i].name)); 45 46 if ((mem_ctx=talloc_init("fake_file_handle"))==NULL) { 47 DEBUG(0,("talloc_init(fake_file_handle) failed.\n")); 48 return NULL; 49 } 50 51 if ((fh =TALLOC_ZERO_P(mem_ctx, FAKE_FILE_HANDLE))==NULL) { 52 DEBUG(0,("TALLOC_ZERO() failed.\n")); 53 talloc_destroy(mem_ctx); 54 return NULL; 55 } 56 57 fh->type = type; 58 fh->mem_ctx = mem_ctx; 59 60 if (fake_files[i].init_pd) { 61 fh->pd = fake_files[i].init_pd(fh->mem_ctx); 62 } 63 64 fh->free_pd = fake_files[i].free_pd; 65 66 return fh; 67 } 68 } 69 70 return NULL; 71} 72 73/**************************************************************************** 74 Does this name match a fake filename ? 75****************************************************************************/ 76 77enum FAKE_FILE_TYPE is_fake_file(const char *fname) 78{ 79#ifdef HAVE_SYS_QUOTAS 80 int i; 81#endif 82 83 if (!fname) { 84 return FAKE_FILE_TYPE_NONE; 85 } 86 87#ifdef HAVE_SYS_QUOTAS 88 for (i=0;fake_files[i].name!=NULL;i++) { 89 if (strncmp(fname,fake_files[i].name,strlen(fake_files[i].name))==0) { 90 DEBUG(5,("is_fake_file: [%s] is a fake file\n",fname)); 91 return fake_files[i].type; 92 } 93 } 94#endif 95 96 return FAKE_FILE_TYPE_NONE; 97} 98 99 100/**************************************************************************** 101 Open a fake quota file with a share mode. 102****************************************************************************/ 103 104NTSTATUS open_fake_file(connection_struct *conn, 105 enum FAKE_FILE_TYPE fake_file_type, 106 const char *fname, 107 uint32 access_mask, 108 files_struct **result) 109{ 110 files_struct *fsp = NULL; 111 NTSTATUS status; 112 113 /* access check */ 114 if (current_user.ut.uid != 0) { 115 DEBUG(1,("open_fake_file_shared: access_denied to service[%s] file[%s] user[%s]\n", 116 lp_servicename(SNUM(conn)),fname,conn->user)); 117 return NT_STATUS_ACCESS_DENIED; 118 119 } 120 121 status = file_new(conn, &fsp); 122 if(!NT_STATUS_IS_OK(status)) { 123 return status; 124 } 125 126 DEBUG(5,("open_fake_file_shared: fname = %s, FID = %d, access_mask = 0x%x\n", 127 fname, fsp->fnum, (unsigned int)access_mask)); 128 129 fsp->conn = conn; 130 fsp->fh->fd = -1; 131 fsp->vuid = current_user.vuid; 132 fsp->fh->pos = -1; 133 fsp->can_lock = False; /* Should this be true ? - No, JRA */ 134 fsp->access_mask = access_mask; 135 string_set(&fsp->fsp_name,fname); 136 137 fsp->fake_file_handle = init_fake_file_handle(fake_file_type); 138 139 if (fsp->fake_file_handle==NULL) { 140 file_free(fsp); 141 return NT_STATUS_NO_MEMORY; 142 } 143 144 conn->num_files_open++; 145 *result = fsp; 146 return NT_STATUS_OK; 147} 148 149void destroy_fake_file_handle(FAKE_FILE_HANDLE **fh) 150{ 151 if (!fh||!(*fh)) { 152 return; 153 } 154 155 if ((*fh)->free_pd) { 156 (*fh)->free_pd(&(*fh)->pd); 157 } 158 159 talloc_destroy((*fh)->mem_ctx); 160 (*fh) = NULL; 161} 162 163NTSTATUS close_fake_file(files_struct *fsp) 164{ 165 file_free(fsp); 166 return NT_STATUS_OK; 167} 168