1/* 2 * Unix SMB/CIFS implementation. 3 * Provide a connection to GPFS specific features 4 * Copyright (C) Volker Lendecke 2005 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#ifdef HAVE_GPFS 24 25#include "gpfs_gpl.h" 26 27static void *libgpfs_handle = NULL; 28 29static int (*gpfs_set_share_fn)(int fd, unsigned int allow, unsigned int deny); 30static int (*gpfs_set_lease_fn)(int fd, unsigned int leaseType); 31static int (*gpfs_getacl_fn)(char *pathname, int flags, void *acl); 32static int (*gpfs_putacl_fn)(char *pathname, int flags, void *acl); 33 34 35BOOL set_gpfs_sharemode(files_struct *fsp, uint32 access_mask, 36 uint32 share_access) 37{ 38 unsigned int allow = GPFS_SHARE_NONE; 39 unsigned int deny = GPFS_DENY_NONE; 40 int result; 41 42 if (gpfs_set_share_fn == NULL) { 43 return False; 44 } 45 46 if ((fsp == NULL) || (fsp->fh == NULL) || (fsp->fh->fd < 0)) { 47 /* No real file, don't disturb */ 48 return True; 49 } 50 51 allow |= (access_mask & (FILE_WRITE_DATA|FILE_APPEND_DATA| 52 DELETE_ACCESS)) ? GPFS_SHARE_WRITE : 0; 53 allow |= (access_mask & (FILE_READ_DATA|FILE_EXECUTE)) ? 54 GPFS_SHARE_READ : 0; 55 56 if (allow == GPFS_SHARE_NONE) { 57 DEBUG(10, ("special case am=no_access:%x\n",access_mask)); 58 } 59 else { 60 deny |= (share_access & FILE_SHARE_WRITE) ? 61 0 : GPFS_DENY_WRITE; 62 deny |= (share_access & (FILE_SHARE_READ)) ? 63 0 : GPFS_DENY_READ; 64 } 65 DEBUG(10, ("am=%x, allow=%d, sa=%x, deny=%d\n", 66 access_mask, allow, share_access, deny)); 67 68 result = gpfs_set_share_fn(fsp->fh->fd, allow, deny); 69 if (result != 0) { 70 if (errno == ENOSYS) { 71 DEBUG(5, ("VFS module vfs_gpfs loaded, but no gpfs " 72 "support has been compiled into Samba. Allowing access\n")); 73 return True; 74 } else { 75 DEBUG(10, ("gpfs_set_share failed: %s\n", 76 strerror(errno))); 77 } 78 } 79 80 return (result == 0); 81} 82 83int set_gpfs_lease(int fd, int leasetype) 84{ 85 int gpfs_type = GPFS_LEASE_NONE; 86 87 if (gpfs_set_lease_fn == NULL) { 88 errno = EINVAL; 89 return -1; 90 } 91 92 if (leasetype == F_RDLCK) { 93 gpfs_type = GPFS_LEASE_READ; 94 } 95 if (leasetype == F_WRLCK) { 96 gpfs_type = GPFS_LEASE_WRITE; 97 } 98 return gpfs_set_lease_fn(fd, gpfs_type); 99} 100 101int smbd_gpfs_getacl(char *pathname, int flags, void *acl) 102{ 103 if (gpfs_getacl_fn == NULL) { 104 errno = ENOSYS; 105 return -1; 106 } 107 108 return gpfs_getacl_fn(pathname, flags, acl); 109} 110 111int smbd_gpfs_putacl(char *pathname, int flags, void *acl) 112{ 113 if (gpfs_putacl_fn == NULL) { 114 errno = ENOSYS; 115 return -1; 116 } 117 118 return gpfs_putacl_fn(pathname, flags, acl); 119} 120 121void init_gpfs(void) 122{ 123 if (libgpfs_handle != NULL) { 124 return; 125 } 126 127 libgpfs_handle = sys_dlopen("libgpfs_gpl.so", RTLD_LAZY); 128 129 if (libgpfs_handle == NULL) { 130 DEBUG(10, ("sys_dlopen for libgpfs_gpl failed: %s\n", 131 strerror(errno))); 132 return; 133 } 134 135 DEBUG(10, ("libgpfs_gpl.so loaded\n")); 136 137 gpfs_set_share_fn = sys_dlsym(libgpfs_handle, "gpfs_set_share"); 138 if (gpfs_set_share_fn == NULL) { 139 DEBUG(3, ("libgpfs_gpl.so does not contain the symbol " 140 "'gpfs_set_share'\n")); 141 sys_dlclose(libgpfs_handle); 142 143 /* leave libgpfs_handle != NULL around, no point 144 in trying twice */ 145 gpfs_set_share_fn = NULL; 146 gpfs_set_lease_fn = NULL; 147 gpfs_getacl_fn = NULL; 148 gpfs_putacl_fn = NULL; 149 return; 150 } 151 152 gpfs_set_lease_fn = sys_dlsym(libgpfs_handle, "gpfs_set_lease"); 153 if (gpfs_set_lease_fn == NULL) { 154 DEBUG(3, ("libgpfs_gpl.so does not contain the symbol " 155 "'gpfs_set_lease'\n")); 156 sys_dlclose(libgpfs_handle); 157 158 /* leave libgpfs_handle != NULL around, no point 159 in trying twice */ 160 gpfs_set_share_fn = NULL; 161 gpfs_set_lease_fn = NULL; 162 gpfs_getacl_fn = NULL; 163 gpfs_putacl_fn = NULL; 164 return; 165 } 166 167 gpfs_getacl_fn = sys_dlsym(libgpfs_handle, "gpfs_getacl"); 168 if (gpfs_getacl_fn == NULL) { 169 DEBUG(3, ("libgpfs_gpl.so does not contain the symbol " 170 "'gpfs_getacl'\n")); 171 sys_dlclose(libgpfs_handle); 172 173 /* leave libgpfs_handle != NULL around, no point 174 in trying twice */ 175 gpfs_set_share_fn = NULL; 176 gpfs_set_lease_fn = NULL; 177 gpfs_getacl_fn = NULL; 178 gpfs_putacl_fn = NULL; 179 return; 180 } 181 182 gpfs_putacl_fn = sys_dlsym(libgpfs_handle, "gpfs_putacl"); 183 if (gpfs_putacl_fn == NULL) { 184 DEBUG(3, ("libgpfs_gpl.so does not contain the symbol " 185 "'gpfs_putacl'\n")); 186 sys_dlclose(libgpfs_handle); 187 188 /* leave libgpfs_handle != NULL around, no point 189 in trying twice */ 190 gpfs_set_share_fn = NULL; 191 gpfs_set_lease_fn = NULL; 192 gpfs_getacl_fn = NULL; 193 gpfs_putacl_fn = NULL; 194 return; 195 } 196 197} 198 199#else 200 201int set_gpfs_lease(int snum, int leasetype) 202{ 203 DEBUG(0, ("'VFS module smbgpfs loaded, without gpfs support compiled\n")); 204 205 /* We need to indicate that no GPFS is around by returning ENOSYS, so 206 * that the normal linux kernel oplock code is called. */ 207 errno = ENOSYS; 208 return -1; 209} 210 211BOOL set_gpfs_sharemode(files_struct *fsp, uint32 access_mask, 212 uint32 share_access) 213{ 214 DEBUG(0, ("VFS module - smbgpfs.so loaded, without gpfs support compiled\n")); 215 /* Don't disturb but complain */ 216 return True; 217} 218 219int smbd_gpfs_getacl(char *pathname, int flags, void *acl) 220{ 221 errno = ENOSYS; 222 return -1; 223} 224 225int smbd_gpfs_putacl(char *pathname, int flags, void *acl) 226{ 227 errno = ENOSYS; 228 return -1; 229} 230 231void init_gpfs(void) 232{ 233 return; 234} 235 236#endif /* HAVE_GPFS */ 237