The Samba-Bugzilla – Attachment 8772 Details for
Bug 9776
core dump when renaming folder on windows 7 only happens over VPN
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
vfs module src
vfs_egnyte_samba4.c (text/plain), 67.55 KB, created by
sanved
on 2013-04-14 22:03:00 UTC
(
hide
)
Description:
vfs module src
Filename:
MIME Type:
Creator:
sanved
Created:
2013-04-14 22:03:00 UTC
Size:
67.55 KB
patch
obsolete
>/* > * egnyte vfs module > * Copied template skeleton VFS module (skel_transparent.c)from samba4 examples and made changes >*/ > > >#include "../source3/include/includes.h" >#include "lib/util/tevent_unix.h" >#include <poll.h> >#include <sys/stat.h> >#include <sys/acl.h> >#include <sys/time.h> >#include <linux/limits.h> >#include "vfs_macros.h" >#include "version.h" // samba version >#include <regex.h> >#include <stdint.h> >#include <string.h> >#include <signal.h> >#include <pwd.h> > >#include <sys/ipc.h> >#include <sys/sem.h> >#include <sys/shm.h> >#include <sys/stat.h> >#include <sys/types.h> >#include <sys/un.h> >#include <sys/socket.h> >#include <unistd.h> > >#include "../libcli/security/security.h" >#include "../lib/util/samba_modules.h" > >#include "regex_parser.h" >#include "egnyte_utils.h" >#include "samba.pb-c.h" >#include "egnyte_vfs_fs.h" //egnyte permission be >#include "egnyte_perms.h" //egnyte permissions >#include "perm_utils.h" > > > >// define debug class per debug.h >#undef DBGC_CLASS >#define DBGC_CLASS DBGC_VFS > >/* > * When we figure out how to distinguish between RW and RWD we will undefine this > * and the special handling will go into effect > */ >#define VFSPERMS_RWISRWD > >/* Function prototypes */ >static int read_egnyte_config(void); >static int read_and_compile_patterns(void); >char *get_full_path(char *folder, const char *path); >static int is_deletable_file(char *fname); >static void free_compiled_patterns(void); > >/* regex pattern buffer */ >extern e_regex_matchres_t match_regex_string (char *pattern, char *string); >extern e_regex_matchres_t get_regex_matchbuf(char *pattern, regex_t **reg_buf); >extern e_regex_matchres_t match_string_with_regex_buf(char *strng, regex_t *regbuf); > >pattern_buf_t pattern_buf; > >typedef struct sig_handle_ctx_s { > uid_t myeuid; >} sig_handle_ctx_t; > >TALLOC_CTX *egnyte_eventmem_ctx = NULL; >struct event_context *egnyte_event_ctx = NULL; >sig_handle_ctx_t *sighandle_private_data = NULL; > >uid_t reserved_user_uid = -1; > >static int is_amove(char *src_fsobj, char *dst_fsobj) >{ > char *parent_src = NULL; > char *parent_dst = NULL; > path_array_t *src = NULL; > path_array_t *dst = NULL; > int ret = 0; > int cnt = 0; > > //short circuit here > return 0; > > DEBUG(0, ("egnyte:%s\n",__func__)); > > if (!src_fsobj || !dst_fsobj) { > DEBUG(0,("Invalid sourc or destination name src %s dst %s\n", > (src_fsobj == NULL ? "Null" : src_fsobj), > (dst_fsobj == NULL ? "NULL": dst_fsobj))); > return -1; > } > parent_src = parent_dir_from_path(src_fsobj); > if (!parent_src) { > DEBUG(0, ("Invalid parent %s\n",src_fsobj)); > return -1; > } > parent_dst = parent_dir_from_path(dst_fsobj); > if (!parent_dst) { > DEBUG(0, ("Invalid parent %s\n",dst_fsobj)); > free(parent_src); > return -1; > } > get_path_elem_smb4((char*)parent_src, (unsigned int)strlen(parent_src),&src); > if (!src) { > DEBUG(0, ("Could not convert path %s\n", parent_src)); > free(parent_src); > free(parent_dst); > return -1; > } > PERR("%s: get_path_elem_smb4: src=%p num_elements=%d\n",__func__,src,src->num_elems); > get_path_elem_smb4((char*)parent_dst, (unsigned int)strlen(parent_dst),&dst); > if (!dst) { > free(parent_src); > free(parent_dst); > cleanup_path_array_smb4(&src); > DEBUG(0, ("Could not convert path %s\n", parent_dst)); > return -1; > } > PERR("%s: get_path_elem_smb4: dst=%p num_elements=%d\n",__func__,dst,dst->num_elems); > > > > if (src->num_elems != dst->num_elems) > ret = 1; > > > //short circuit here > // free(parent_src); > // free(parent_dst); > // cleanup_path_array_smb4(&src); > // cleanup_path_array_smb4(&dst); > // return 0; > //end short circuit > > for(cnt =0; cnt < src->num_elems; cnt ++) { > if(src->elems[cnt]->hashval != dst->elems[cnt]->hashval) { > ret = 1; > break; > } > if (src->elems[cnt]->len != dst->elems[cnt]->len) { > ret = 1; > break; > } > //if (StrnCaseCmp(src->elems[cnt]->name_elem, > // dst->elems[cnt]->name_elem, dst->elems[cnt]->len) != 0) { > if (strncasecmp_m(src->elems[cnt]->name_elem, > dst->elems[cnt]->name_elem, dst->elems[cnt]->len) != 0) { > ret = 1; > break; > } > ret = 0; > } > > free(parent_src); > free(parent_dst); > cleanup_path_array_smb4(&src); > cleanup_path_array_smb4(&dst); > return ret; >} > >void set_reserved_user_uid(void) >{ > struct passwd pswd; > struct passwd *tmppswd; > char pwdbuffer[512]; > int pwdbuflen = sizeof(pwdbuffer); > > if ((getpwnam_r(EGNYTE_RESERVED_USER, &pswd, pwdbuffer, > pwdbuflen, &tmppswd)) != 0) { > DEBUG(0,("Error: Could not determine egnyte reserved user %s info\n", > EGNYTE_RESERVED_USER)); > } else { > reserved_user_uid = pswd.pw_uid; > } > return; >} > >/* Populate a VFS event with PID, UID, and timestamp. */ >int _pop_vfs_event(VFSEvent *ve) >{ > struct timeval tv; > > ve->client_pid = (int) getpid(); > ve->uid = (int) geteuid(); > gettimeofday(&tv, NULL); > ve->time_sec = (int) tv.tv_sec; > ve->time_usec = (int) tv.tv_usec; > DEBUG(0,("Time stamp is %lu sec %lu msces\n",ve->time_sec,ve->time_usec)); > return 0; >} > >/* Write the VFS event to shared mem/disk, etc */ >int _write_vfs_event(VFSEvent *ve) >{ > PERR("%s: ENTRY\n",__func__); > int len; > void *buf; /* stores the serialization of the buffer */ > staging_data_t *dat; > > if (ve == NULL) { > PERR("vfsevent is null\n"); > return -1; > } > > /* reserved uid or root user changes are not recorded */ > if ((ve->uid == reserved_user_uid) || (ve->uid ==0)) { > DEBUG(0,("Ignoring reserved user events [%s] pid %d\n", ve->path, getpid())); > return 0; > } > len = vfsevent__get_packed_size(ve); > buf = calloc(len,sizeof(char)); > if (!buf) { > PERR("could not allocate vfs buffer. errno = %d(%s)\n", errno, strerror(errno)); > return -1; > } > vfsevent__pack(ve, buf); > > dat = (staging_data_t *)alloc_staging_data(len); > if (dat == NULL) { > PERR("could not allocate staging data. errno = %d(%s)\n", errno, strerror(errno)); > free(buf); buf = NULL; > return -1; > } > memcpy(dat->buffer, buf, len); > dat->size = len; > DEBUG(0,("event %d [%s]\n", len, dat->buffer)); > write_to_staging_buffer(dat); > > free(buf); buf = NULL; > free(dat); dat = NULL; >} > >/* > * OPENMODE_READ and OPENMODE_WRITE applies only to OPTYPE_OPEN. Rest should be > * OPENMODE_INVALID. > */ >typedef enum e_open_mode { > OPENMODE_INVALID, > OPENMODE_READ, > OPENMODE_WRITE, > OPENMODE_CREATE, > OPENMODE_CHATTR >} e_open_mode_t; > >static e_open_mode_t mode2egnytemode(int flags) >{ > e_open_mode_t ret = OPENMODE_READ; > > if (flags & O_TRUNC) > DEBUG(0,("mode2egnytemode O_TRUNC set returning OPENMODE_WRITE\n")); > //return OPENMODE_CHATTR; > return OPENMODE_WRITE; > > if (flags & O_CREAT) > return OPENMODE_CREATE; > > if (flags & (O_APPEND | O_WRONLY | O_RDWR)) { > ret = OPENMODE_WRITE; > } > return ret; >} > >global_param_t *global_params = NULL; >#define DEFAULT_USER_ID 0 >#define DEFAULT_GROUP_ID 0 >uid_t get_default_owner() >{ > if (global_params[PARAM_DEFAULT_USER_ID].value.intval >= 0) > return (uid_t)global_params[DEFAULT_USER_ID].value.intval; > else > return (uid_t)DEFAULT_USER_ID; >} > >gid_t get_default_owning_group() >{ > if (global_params[PARAM_DEFAULT_GROUP_ID].value.intval >= 0) > return (gid_t)global_params[DEFAULT_GROUP_ID].value.intval; > else > return (gid_t)DEFAULT_GROUP_ID; >} > >/* > * Change this path if you want to relocate the fifo > */ >#define EGNYTE_AUTH_FIFO_NAME "/dev/egnyte_auth_dm_fifo" > >/* XXX: obsolete? */ >/* > * In this version the temp FIFO is unused yet sent in the packet. Ignore it > */ >#define EGNYTE_TMPFIFO_PERMPREFIX "/var/run/egnyte_permtmp_" >#define EGNYTE_IGNORE_EGNYTE_VERDICT 1 /* undef this if you need to wait for egnyte return */ >/* > filename is <EGNYTE_TMPFIFO_PERMPREFIX>pid.randomint > <max 4 integers> for pid and 4 integers for randomint > caller frees > */ >#define EGNYTE_TMPFIFO_SIZE 32 > >/* XXX: obsolete? */ >int int2str4digits(char *str, int buff_sz, int val) >{ > int t = 0; > int h = 0; > int te = 0; > int o = 0; > > if (!str) > return -1; > > memset(str, '\0', buff_sz); > t = val / 1000; > h = (val - t * 1000) / 100; > te = (val - t * 1000 - h * 100) / 10; > o = (val - t * 1000 - h * 100 - te * 10); > > str[0] = (char) ('0' + (unsigned char) t); > str[1] = (char) ('0' + (unsigned char) h); > str[2] = (char) ('0' + (unsigned char) te); > str[3] = (char) ('0' + (unsigned char) o); >} > >/* XXX: obsolete? */ >static inline char *get_permfifo_name() >{ > char *ret; > int x; > x = asprintf(&ret, "%s%d.%d", EGNYTE_TMPFIFO_PERMPREFIX, getpid() % 9999, > random() % 9999); > return ret; >} > >static char *child_from_path(const char *path) >{ > const char *pname = path; > char *c; > char *bf; > > if (!pname) > return NULL; > if(!strrchr(pname,'/')) { > asprintf(&bf,"%s",pname); > return bf; > } > c = (char *)pname + strlen(pname) - 1; > while (c && *c == '/') { > c--; > } > while (c && *c != '/') { > c--; > if (c == pname) { > break; > } > } > c++; > asprintf(&bf, "%s", c); > c = bf + strlen(bf) - 1; > while (c && *c == '/') { > *c='\0'; > c--; > } > return bf; >} > >/* > * * Is this ELC share? > * */ > >#define EGNYTE_SHARE_NAME "ELC" > >int is_ELC_Share(const char *share_name) >{ > PERR("%s: ENTRY\n",__func__); > char *shname; > int ret = 0; > DEBUG(0, ("egnyte:%s\n",__func__)); > if (!share_name) > return 0; > if ((shname = child_from_path(share_name)) == NULL) { > DEBUG(0, ("Err in getting child %s\n", share_name)); > return 0; > } > if (!strcmp(shname,EGNYTE_SHARE_NAME)) { > DEBUG(0, ("Egnyte share %s child %s\n", share_name, shname)); > ret = 1; > } > free(shname); > return ret; >} > > >/* XXX: obsolete ??? */ >#define POLLTIMER 1000 >#define ADMIN_USER_NAME_STR "admin" >static int is_admin_or_root(uid_t uid) >{ > PERR("%s: ENTRY\n",__func__); > struct passwd p; > struct passwd *pptr = &p; > struct passwd *tmppptr = NULL; > char pwstrings[256]; > int pwstrings_size = sizeof(pwstrings); > > DEBUG(0, ("egnyte:%s\n",__func__)); > if (uid == 0) > return 1; > > if ((getpwuid_r(uid, pptr, pwstrings, pwstrings_size, &tmppptr)) != 0) { > PERR("error in getpwuid for uid %d. errno = %d(%s)\n", uid, errno, strerror(errno)); > } > > if (strcmp(ADMIN_USER_NAME_STR, p.pw_name) == 0) { > return 1; > } > > return 0; >} > > >/* Returns a new null-terminated string folder/path. > * Caller MUST free this string */ >char *get_full_path(char *folder, const char *path) >{ > PERR("%s: ENTRY\n",__func__); > char *full_path; > int path_size; > > DEBUG(0, ("egnyte:%s\n",__func__)); > > path_size = strlen(folder) + strlen(path) + 4; > full_path = (char *)calloc(path_size,sizeof(char)); > if (full_path == NULL) { > PERR("calloc failed. errno = %d(%s)\n", errno, strerror(errno)); > return NULL; > } > //memset(full_path, '\0', path_size); > //snprintf(full_path, path_size, "%s/%s\0", folder, path); > snprintf(full_path, path_size, "%s/%s", folder, path); > return full_path; >} > >char *get_nullterminated_str(char *str, int len) >{ > char *buf = NULL; > > DEBUG(0, ("egnyte:%s\n",__func__)); > > if ((!str) || (!len)) { > DEBUG(0, ("Cannot convert NULL string\n")); > return NULL; > } > buf = (char *)calloc(len+2,sizeof(char)); > if (!buf) { > DEBUG(0, ("Malloc error\n")); > return NULL; > } > //memset(buf,'\0',len+2); > //return StrnCpy_fn(NULL, 0, buf,str,len); > return StrnCpy(buf,str,len); >} > > >#define VFS_TLB_SIZE 128 > >/* > * The cache is comprised of several components: > * - an array of pathnames > * - an array of sets of 4 numbers > * - an array of indices into the first 2 arrays > * > * For the array of sets of 4 numbers: > * > * The first 2 numbers are a bitmap with the operation enum value as the index. > * If the bit is set then a permission value has been set for that operation. > * > * The second 2 numbers are also a bitmap index by operation. If the > * bit is set then permission is allowed, otherwise it is denied. > * > * 2 sets of 32 bits each are used for both the set indication and the value, > * to allow for up to 64 operations. > * > * The 64 set bits indicate the operations for which a value is set. > * The 64 value bits provide the values for operations that are set. > * > * The ordering of the cache is that the 0 slot contains the most > * recently updated or accessed path, the 1 slot contains the next most > * recently updated or accessed path, and so on. An addition to a full > * cache results in the new path in slot 0, other paths moved down a > * slot, and the path in the last slot removed from the cache. > */ > >static char *tlb_paths[VFS_TLB_SIZE]; >static int tlb_index_table[VFS_TLB_SIZE]; >// 21 means flush the tlb, 9 means do not. These values make it easier >// to track down inintended changes to this variable than 0 and 1. >static int flush_tlb = 9; > >static struct { > uint32_t set[2]; > uint32_t value[2]; >} tlb_perms[VFS_TLB_SIZE]; > >/* the value of the next available slot, or VFS_TLB_SIZE if full */ >static int vfs_tlb_end; > > >/* signal handler to flush the tbl when permissions change */ >static void flush_perms_handler(int signal, uid_t myeuid) >{ > PERR("%s: ENTRY\n",__func__); > struct passwd pd; > struct passwd* pwdptr=&pd; > struct passwd* tempPwdPtr = NULL; > char *pwdbuffer = NULL; > int buffsize = 0; > uid_t euid; > uid_t uid; > int ngroups = 0; > > DEBUG(0, ("egnyte:%s\n",__func__)); > DEBUG(0, ("Caught SIGUSR1 %d\n", getpid())); > if (signal == SIGUSR1) { > flush_tlb = 21; // 21 means flush the buffer > DEBUG(0,("USR1 signal caught %d, flush_tlb: %d, flush_tlb addr: %p\n", getpid(), flush_tlb, &flush_tlb)); > /* > * Reset user group membership > */ > euid = myeuid; > uid = getuid(); > DEBUG(0,("Resetting groups for uid %d euid %d\n", uid, euid)); > buffsize = sysconf(_SC_GETPW_R_SIZE_MAX); > if (buffsize == -1) > buffsize = 16384; > pwdbuffer = (char *)calloc(buffsize+1,sizeof(char)); > if (!pwdbuffer) { > DEBUG(0, ("Cannot allocate memory of size %d\n", buffsize)); > return; > } > //memset(pwdbuffer, '0', buffsize); > if ((getpwuid_r(euid,pwdptr,pwdbuffer,buffsize,&tempPwdPtr)) != 0) { > DEBUG(0,("Cannot get username for uid %d to update user's groups: %s\n", euid, strerror(errno))); > } else if (tempPwdPtr == NULL) { > DEBUG(0,("No user with uid %d\n", euid)); > } else { > DEBUG(0,("password struct retrieved with euid %u for %s, gid %u\n", geteuid(), pd.pw_name, pd.pw_gid)); > DEBUG(0,("getting group list count using %d\n", ngroups)); > if (getgrouplist(pd.pw_name, pd.pw_gid, NULL, &ngroups) == -1) { > gid_t *groupbuf = NULL; > > DEBUG(0,("There are %d group(s) for user %s\n", ngroups, pd.pw_name)); > groupbuf = (gid_t *)malloc(ngroups * sizeof(gid_t)); > if (!groupbuf) { > DEBUG(0, ("Cannot allocate memory to retrieve grouplist\n")); > } else { > if (getgrouplist(pd.pw_name, pd.pw_gid, groupbuf, &ngroups) == -1) { > DEBUG(0,("getgrouplist(%s, %u, %d) failed with errno %s\n", pd.pw_name, pd.pw_gid, ngroups, strerror(errno))); > } else { > DEBUG(0,("retrieved group list, setting group list\n")); > become_root(); > setgid(pd.pw_gid); > if (setgroups(ngroups, groupbuf) == -1) { > DEBUG(0,("Cannot get group list to update user %s's groups: %s\n", pd.pw_name, strerror(errno))); > } > unbecome_root(); > DEBUG(0,("Reset group list for user %s\n", pd.pw_name)); > } > free(groupbuf); > } > > } else { > DEBUG(0,("Cannot retrieve the number of groups for user %d error %s\n", > euid, strerror(errno))); > } > } > free(pwdbuffer); > } else { > DEBUG(0,("Unexpected signal %d caught \n", signal)); > } > > return; >} > > >static void egnyte_sigusr1_handler( > struct tevent_context *ev, > struct tevent_signal *se, > int signum, > int count, > void *siginfo, > void *private_data) >{ > PERR("%s: ENTRY\n",__func__); > uid_t myeuid = -1; > DEBUG(0, ("egnyte:%s\n",__func__)); > sig_handle_ctx_t *sigctx = talloc_get_type(private_data, > sig_handle_ctx_t); > > > if (!sigctx) { > DEBUG(0,("Could not get signal context\n")); > return; > } > myeuid = sigctx->myeuid; > > flush_perms_handler(SIGUSR1, myeuid); > return; >} > >void init_tlb() >{ > int i; > > DEBUG(0, ("egnyte:%s\n",__func__)); > for (i = 0; i < VFS_TLB_SIZE; i++) { > DEBUG(0,("TLB Init %d \n", i)); > tlb_index_table[i] = i; > tlb_paths[i] = NULL; > tlb_perms[i].set[0] = 0; > tlb_perms[i].set[1] = 0; > tlb_perms[i].value[0] = 0; > tlb_perms[i].value[1] = 0; > } > vfs_tlb_end = 0; > return; >} > >void destroy_tlb() >{ > PERR("%s: ENTRY\n",__func__); > int i; > > for (i = 0; i < VFS_TLB_SIZE; i++) { > DEBUG(0,("TLB Destroy %d \n", i)); > tlb_index_table[i] = i; > if (tlb_paths[i]) > free(tlb_paths[i]); > tlb_paths[i] = NULL; > tlb_perms[i].set[0] = 0; > tlb_perms[i].set[1] = 0; > tlb_perms[i].value[0] = 0; > tlb_perms[i].value[1] = 0; > } > vfs_tlb_end = 0; > return; >} > >/* > * Update the tlb order with the input hit. > * Currently we place it at the top. > */ >static int _update_tlb_hit(int slot) >{ > PERR("%s: ENTRY\n",__func__); > int i; > int tmp = tlb_index_table[slot]; > > DEBUG(0, ("egnyte:%s\n",__func__)); > DEBUG(0,("TLB: Updating slot %d\n", slot)); > > for (i = slot; i > 0; i--) > tlb_index_table[i] = tlb_index_table[i-1]; > > tlb_index_table[0] = tmp; > return 0; >} > >/* return the slot of the path, or -1 if not found */ >static int _tlb_lookup_path(char *path) >{ > int i; > > DEBUG(0, ("egnyte:%s\n",__func__)); > > for (i = 0; i < vfs_tlb_end; i++) > if (!strncmp(path, tlb_paths[tlb_index_table[i]], PATH_MAX)) > return i; > > return -1; >} > >/* > * Update the op and value pair for the existing entry slot in the table. > * > * The input slot must be an existing value in the populated range of the table. > */ >static void update_tlb_entry(int slot, e_fsop_type_t op, e_vfs_enforce_perms_t value) >{ > PERR("%s: ENTRY\n",__func__); > int op_index; > int which; > int op_bit; > int perm_bit; > > DEBUG(0, ("egnyte:%s\n",__func__)); > > assert(slot >= 0 && slot < vfs_tlb_end); > > /* ops start at 1 so index 0 is never used */ > assert(op != 0); > op_index = op % (sizeof(uint32_t)*8); > if (op_index == op) > which = 0; > else > which = 1; > > op_bit = (1 << op_index); /* convert the op to a bit position */ > > if (value == EGPERMS_HAS_PERMS) { > perm_bit = 1; > perm_bit <<= op_index; > } > else { > perm_bit = 0; > } > > tlb_perms[slot].set[which] |= op_bit; /* mark the bit as set */ > tlb_perms[slot].value[which] &= ~op_bit; /* clear the perm bit */ > tlb_perms[slot].value[which] |= perm_bit;/* set the corresponding value */ > > return; >} > >/* > * Delete the path/op entry from the tlb. > */ >static void del_tlb_entry(char *path) >{ > int slot; > int index; > int i; > > PERR("%s: ENTRY\n",__func__); > > PERR("%s: Deleting path %s\n", __func__,path); > > slot = _tlb_lookup_path(path); > if (slot == -1) /* not found, just return */ > { > PERR("%s: did not find path %s\n",__func__,path); > return; > } > index = tlb_index_table[slot]; > > free(tlb_paths[index]); /* clear the old values */ > tlb_paths[index] = NULL; > tlb_perms[index].set[0] = 0; > tlb_perms[index].set[1] = 0; > tlb_perms[index].value[0] = 0; > tlb_perms[index].value[1] = 0; > /* move everything up */ > for (i = slot; i + 1 < vfs_tlb_end; i++) > tlb_index_table[i] = tlb_index_table[i+1]; > tlb_index_table[i] = tlb_index_table[slot]; > > vfs_tlb_end--; > > PERR("%s: EXIT\n",__func__); > > return; >} > > >/* > * Add the path/op/value entry into the provided slot. > */ >static void add_tlb_entry(char *path, int slot, e_fsop_type_t op, e_vfs_enforce_perms_t value) >{ > PERR("%s: ENTRY\n",__func__); > int op_index; > int which; > int index; > int op_bit; > int perm_bit; > int len; > > DEBUG(0, ("egnyte:%s\n",__func__)); > > if (slot == -1) { /* new cache entry */ > if (vfs_tlb_end < VFS_TLB_SIZE) { > vfs_tlb_end++; > index = tlb_index_table[vfs_tlb_end-1]; > assert(tlb_paths[index] == NULL); > } > else { > index = tlb_index_table[vfs_tlb_end-1]; > free(tlb_paths[index]); > } > > len = strlen(path)+1; > tlb_paths[index] = malloc(len); > if (tlb_paths[index] == NULL) { > DEBUG(0,("Cannot create path for TLB cache, out of memory\n")); > return; > } > snprintf(tlb_paths[index], len, "%s", path); > > tlb_perms[index].set[0] = 0; > tlb_perms[index].set[1] = 0; > tlb_perms[index].value[0] = 0; > tlb_perms[index].value[1] = 0; > > slot = vfs_tlb_end-1; > } > else { /* existing cache entry */ > index = tlb_index_table[slot]; > } > > /* ops start at 1 so index 0 is never used */ > assert(op != 0); > op_index = op % (sizeof(uint32_t)*8); > if (op_index == op) > which = 0; > else > which = 1; > > op_bit = (1 << op_index); /* convert the op to a bit position */ > > if (value == EGPERMS_HAS_PERMS) { > perm_bit = 1; > perm_bit <<= op_index; > } > else { > perm_bit = 0; > } > > tlb_perms[index].set[which] |= op_bit; /* mark the bit as set */ > tlb_perms[index].value[which] |= perm_bit; /* set the corresponding value */ > > (void) _update_tlb_hit(slot); > > return; >} > >/* > * Check whether the path/operation is in the cache > * > * Returns: > * EGPERMS_HAS_PERMS or EGPERMS_NO_PERM on a cache hit > * EGPERMS_NOT_FOUND if the path is not in the cache > * EGPERMS_NOT_SET if the path is in the cache but the input operation is > * not set, in which case the index is returned > */ >static e_vfs_enforce_perms_t check_tlb(char *path, e_fsop_type_t op, int *index) >{ > PERR("%s: ENTRY\n",__func__); > int slot; > int op_index; > int which; > e_vfs_enforce_perms_t retval; > int op_bit; > > DEBUG(0, ("egnyte:%s\n",__func__)); > >#if 0 > DEBUG(0,("Setting signal handler \n")); > if (CatchSignal(SIGUSR1, SIGNAL_CAST flush_perms_handler) == SIG_ERR) > DEBUG(0,("Setting of signal handler failed \n")); >#endif > *index = -1; > > DEBUG(0,("flush_tlb value: %d, flush_tlb addr: %p\n", flush_tlb, &flush_tlb)); > if (flush_tlb == 21) { // 21 means flush the buffer > DEBUG(0,("Flushing and rebuilding tlb \n")); > destroy_tlb(); > init_tlb(); > flush_tlb = 9; // 21 means do not flush the buffer > } > > slot = _tlb_lookup_path(path); > if (slot == -1) > return EGPERMS_NOT_FOUND; > > op_index = op % (sizeof(uint32_t)*8); > if (op_index == op) > which = 0; > else > which = 1; > > op_bit = (1 << op_index); /* convert the op to a bit position */ > > /* if value is set - a cache hit - return the value */ > if (tlb_perms[tlb_index_table[slot]].set[which] & op_bit) { > > if (tlb_perms[tlb_index_table[slot]].value[which] & op_bit) > retval = EGPERMS_HAS_PERMS; > else > retval = EGPERMS_NO_PERM; > > *index = _update_tlb_hit(slot); > return retval; > } > *index = slot; > return EGPERMS_NOT_SET; >} > > >static int check_perms(char *shareroot, const char *path, e_fsop_type_t op, process_trustees_t *in_pts) >{ > PERR("%s: ENTRY\n",__func__); > int retval; > e_fsop_type_t ret_tlb; > int slot; > char *clean_path; > char *nlpath = NULL; > > DEBUG(0, ("egnyte:%s\n",__func__)); > > /* > * normalize_path() needs to take care of any special pathname handling > * including samba's terminating 0 instead of '\0', or 0x80 to indicate > * extended characters, so that no subsequent calls need to deal with it > */ > clean_path = normalize_path(path); > if (!clean_path) { > if (errno == ENOMEM) { > DEBUG(0,("path normalization failed %s: %s\n", path, strerror(errno))); > return EGPERMS_MALLOC_ERR; > } > else if (errno == ENOENT) { > /* samba attempts operations such as 'stat("./..")' */ > DEBUG(0,("returning HAS_PERMS, path normalization returned an unusable path %s: %s\n", path, strerror(errno))); > return EGPERMS_HAS_PERMS; > } > else { > DEBUG(0,("path normalization failed for %s: code=%d (%s)\n", path, errno, strerror(errno))); > assert(0); > return EGPERMS_SYSTEM_ERR; > } > } > DEBUG(0,("%s normalized to %s\n", path, clean_path)); > > ret_tlb = check_tlb(clean_path, op, &slot); > if (ret_tlb == EGPERMS_HAS_PERMS || ret_tlb == EGPERMS_NO_PERM) { > DEBUG(0,("TLB: Cache hit for %s, op %d, perms %d, slot %d\n", path, op, ret_tlb, slot)); > free(clean_path); > return(ret_tlb); > } > > retval = vfs_enforce_perms(shareroot, clean_path, op, in_pts); > if (retval == EGPERMS_NO_PERM || retval == EGPERMS_HAS_PERMS) { > if (ret_tlb == EGPERMS_NOT_FOUND) { > add_tlb_entry(clean_path, slot, op, retval); > DEBUG(0,("TLB: Adding entry for %s, op %d, perms %d, slot %d\n", path, op, retval, slot)); > } > else if (ret_tlb == EGPERMS_NOT_SET) { > DEBUG(0,("TLB: Updating entry for %s, op %d, perms %d, slot %d\n", path, op, retval, slot)); > > update_tlb_entry(slot, op, retval); > } > else { > assert(0); > } > } > free(clean_path); > > return retval; >} > > > >/* Implementation of vfs_ops. Pass everything on to the default > operation but log event first. */ > >static int egnyte_connect(vfs_handle_struct *handle, const char *svc, const char *user) >{ > PERR("%s: ENTRY\n",__func__); > struct tevent_signal *se; > uid_t my_euid; > struct passwd pd; > struct passwd* tempPwdPtr; > char pwdbuf[1024]; > > //flush_tlb = 21; > DEBUG(0,("Calling init_tlb \n")); > init_tlb(); > DEBUG(0,("After calling init_tlb \n")); > read_egnyte_config(); > DEBUG(0,("After Calling config \n")); >#ifndef VFSPERMS_RWISRWD > read_and_compile_patterns(); > DEBUG(0,("After calling patterns \n")); >#endif > > if (init_perm_map_semaphore() == -1) > return -1; > > DEBUG(0,("After calling init_perm_map_semaphore \n")); > if (egnyte_eventmem_ctx != NULL) { > talloc_free(egnyte_eventmem_ctx); > } > egnyte_eventmem_ctx = talloc_new(NULL); > if (egnyte_eventmem_ctx == NULL) { > return ENOMEM; > } > if ((getpwnam_r(user, &pd, pwdbuf, 1024, &tempPwdPtr))!=0) { > DEBUG(0,("Error: cound not resolve user %s",user)); > return -1; > } > > egnyte_event_ctx = tevent_context_init(egnyte_eventmem_ctx); > if (egnyte_event_ctx == NULL) { > DEBUG(0,("Cannot allocate event_context\n")); > return ENOMEM; > } > sighandle_private_data = talloc(egnyte_eventmem_ctx,sig_handle_ctx_t); > if (sighandle_private_data == NULL) { > DEBUG(0,("Memory error: Cannot allocate signal handler private data\n")); > return ENOMEM; > } > sighandle_private_data->myeuid = pd.pw_uid; > DEBUG(0, ("Set sighandler uid %d\n", sighandle_private_data->myeuid)); > > se = tevent_add_signal( > egnyte_event_ctx, > sighandle_private_data, > SIGUSR1, 0, > egnyte_sigusr1_handler, > sighandle_private_data); > > if (!se) { > DEBUG(0, ("Failed to set up SIGUSR1 signal handler")); > } >#if 0 > if (CatchSignal(SIGUSR1, SIGNAL_CAST flush_perms_handler) == SIG_ERR) > DEBUG(0,("Setting of signal handler failed \n")); >#endif > set_reserved_user_uid(); > return SMB_VFS_NEXT_CONNECT(handle, svc, user); >} > > >static void egnyte_disconnect(vfs_handle_struct *handle) >{ > PERR("%s: ENTRY\n",__func__); > //flush_tlb = 21; > free_compiled_patterns(); > destroy_tlb(); > flush_staging_buffer(); > SMB_VFS_NEXT_DISCONNECT(handle); >} > > >static DIR *egnyte_opendir(vfs_handle_struct *handle, const char *fname, const char *mask, uint32 attr) >{ > PERR("%s: ENTRY\n",__func__); > > //flush_tlb = 21; > char *full_path; > DIR *ret = 0; > int retval; > char *nlpath = NULL; > DEBUG(0, ("egnyte:%s\n",__func__)); > > /* resolve full path */ > full_path = get_full_path(handle->conn->connectpath, fname); > if(!full_path) { > PERR("%s: unable to allocate full_path\n",__func__); > return NULL; > } > > nlpath = get_nullterminated_str((char *)fname,strlen(fname)); > if (!nlpath) { > free(full_path); > return NULL; > } > > retval = vfs_enforce_perms(handle->conn->connectpath, nlpath, FSOP_OPENDIR, NULL); > free(nlpath); > if (retval != EGPERMS_HAS_PERMS) { > free(full_path); > errno = EACCES; > return NULL; > } > > free(full_path); > become_root(); > ret = SMB_VFS_NEXT_OPENDIR(handle, fname, mask, attr); > unbecome_root(); > return ret; >} > >static int egnyte_mkdir(vfs_handle_struct *handle, const char *path, mode_t mode) >{ > PERR("%s: ENTRY\n",__func__); > int result; > char *full_path; > int path_size; > VFSEvent ve; > char *nlpath = NULL; > int became_root = 0; > > //flush_tlb = 21; > PERR("egnyte:%s handle->conn->connectpath=%s path=%s\n",__func__,handle->conn->connectpath,path); > > full_path = get_full_path(handle->conn->connectpath, path); > if (!full_path) { > errno = ENOMEM; > return -1; > } > > nlpath = get_nullterminated_str(path,strlen(path)); > if (!nlpath) { > free(full_path); > return ENOMEM; > } > > > //For test short circuit here > // become_root(); > //result = SMB_VFS_NEXT_MKDIR(handle, path, mode); > // unbecome_root(); > //free(full_path); > //free(nlpath); > //return result; > //Remove the above lines later > > > result = vfs_enforce_perms(handle->conn->connectpath, nlpath, FSOP_MKDIR, NULL); > free(nlpath); > if (result != EGPERMS_HAS_PERMS) { > free(full_path); > errno = EACCES; > return -1; > } > > //become_root(); > result = SMB_VFS_NEXT_MKDIR(handle, path, mode); > //unbecome_root(); > > if (result < 0) { > /* operation failed, dont log event */ > DEBUG(0,("(%s:%d) Failed event \n",__FUNCTION__,__LINE__)); > return result; > } else { > /* resolve full path */ > path_size = strlen(full_path); > vfsevent__init(&ve); > ve.path = (char *)calloc(path_size + 1,sizeof(char)); > ve.rename_path = NULL; > _pop_vfs_event(&ve); > ve.optype = VFSEVENT__OP_TYPE__OPTYPE_MKDIR; > strncpy(ve.path, full_path, path_size); > ve.fselem_type = VFSEVENT__FS_ELEM_TYPE__FSELEMTYPE_DIR; > PERR("%s(%d) calls _write_vfs_event\n",__FUNCTION__,__LINE__); > _write_vfs_event(&ve); > DEBUG(0,("%s(%d):wrote VFS event open =================> %s\n",__FUNCTION__,__LINE__, ve.path)); > free(ve.path); > > } > > free(full_path); > return result; >} > >static int egnyte_rmdir(vfs_handle_struct *handle, const char *path) >{ > PERR("%s: ENTRY param=%s read_only=%d \n",__func__,handle->param,handle->conn->read_only); > int result; > char *full_path = NULL; > int path_size; > VFSEvent ve; > char *nlpath = NULL; > > //flush_tlb = 21; > full_path = get_full_path(handle->conn->connectpath, path); > if (!full_path) { > errno = ENOMEM; > return -1; > } > nlpath = get_nullterminated_str(path,strlen(path)); > if (!nlpath) { > free(full_path); > errno = ENOMEM; > return -1; > } >#ifndef VFSPERMS_RWISRWD > result = vfs_enforce_perms(handle->conn->connectpath, nlpath, FSOP_RMDIR, NULL); >#else > //RW => RWD > //result = vfs_enforce_perms(handle->conn->connectpath, nlpath, FSOP_OPEN_WRITE, NULL); > //changed for test > PERR("%s: calls vfs_enforce_perms op=%d \n",__func__,FSOP_MKDIR); > result = vfs_enforce_perms(handle->conn->connectpath, nlpath, FSOP_MKDIR, NULL); > //PERR("%s: calls del_tlb_entry for path_nl=%s path_full=%s\n",__func__,nlpath,full_path); > //del_tlb_entry(nlpath); > PERR("%s: calls vfs_enforce_perms op=%d result=%d\n",__func__,FSOP_MKDIR,result); > >#endif > > free(nlpath); > if (result != EGPERMS_HAS_PERMS) { > //PERR("%s: calls del_tlb_entry for path_nl=%s path_full=%s\n",__func__,nlpath,full_path); > //del_tlb_entry(nlpath); > free(full_path); > errno = EPERM; > return -1; > //return EPERM; > } > become_root(); > result = SMB_VFS_NEXT_RMDIR(handle, path); > unbecome_root(); > > if (result < 0) { > /* operation failed, dont log event */ > DEBUG(0,("(%s:%d) Failed event \n",__FUNCTION__,__LINE__)); > free(full_path); > return result; > } else { > /* resolve full path */ > path_size = strlen(full_path); > /* report results to shared memory */ > vfsevent__init(&ve); > ve.path = (char *)calloc(path_size + 1,sizeof(char)); > ve.rename_path = NULL; > _pop_vfs_event(&ve); > ve.optype = VFSEVENT__OP_TYPE__OPTYPE_RMDIR; > strncpy(ve.path,full_path, path_size); > ve.fselem_type = VFSEVENT__FS_ELEM_TYPE__FSELEMTYPE_DIR; > _write_vfs_event(&ve); > DEBUG(0,("%s(%d):wrote VFS event open =================> %s\n",__FUNCTION__,__LINE__, ve.path)); > free(ve.path); > } > > free(full_path); > return result; >} > > > >static int egnyte_open(vfs_handle_struct *handle, struct smb_filename *fname, files_struct *fsp, int flags, mode_t mode) >{ > PERR("%s: ENTRY\n",__func__); > int result; > int fsop; > e_open_mode_t open_mode; > char *full_path; > int path_size; > VFSEvent ve; > e_fsop_type_t op = FSOP_INVAL; > char *nlpath = NULL; > > //flush_tlb = 21; > open_mode = mode2egnytemode(flags); > DEBUG(0,("Got open mode %d for flags %d\n",open_mode, flags)); > full_path = get_full_path(handle->conn->connectpath, fname->base_name); > if (!full_path) { > errno = ENOMEM; > return -1; > } > > switch (open_mode) { > case OPENMODE_READ: > op = FSOP_OPEN_READ; > break; > case OPENMODE_WRITE: > op = FSOP_OPEN_WRITE; > break; > case OPENMODE_CREATE: > open_mode = OPENMODE_WRITE; > op = FSOP_CREATE; > break; > case OPENMODE_CHATTR: > open_mode = OPENMODE_WRITE; > op = FSOP_OPEN_CHATTR; > break; > default: > errno = EACCES; > free(full_path); > return -1; > }; > > DEBUG(0,("Got open mode %d for flags %d and op %d\n",open_mode, flags, op)); > nlpath = get_nullterminated_str(fname->base_name,strlen(fname->base_name)); > DEBUG(0, ("After null path path %s len %d nlpath %s len %d\n", > fname->base_name, strlen(fname->base_name), nlpath, strlen(nlpath))); > > if (!nlpath) { > free(full_path); > return ENOMEM; > } > //result = check_perms(handle->conn->connectpath, nlpath, op, NULL); > result = vfs_enforce_perms(handle->conn->connectpath, nlpath, op, NULL); > free(nlpath); > if (result != EGPERMS_HAS_PERMS) { > free(full_path); > errno = EACCES; > return -1; > } > > if (open_mode != OPENMODE_WRITE) { > // if in read mode, dont process > become_root(); > result = SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode); > unbecome_root(); > free(full_path); > return result; > } > > become_root(); > result = SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode); > unbecome_root(); > if (result < 0) { > /* operation failed, dont log event */ > DEBUG(0,("(%s:%d) Failed event \n",__FUNCTION__,__LINE__)); > } else { > > if(!fsp->is_directory) { > struct stat st; > //Sometimes while browing folders for some reason the fsp->is_directory is still set to false for folders also so checking it again > int err_stat = stat(full_path,&st); > if(err_stat == 0) { > if (S_ISDIR(st.st_mode)) { > PERR("%s(%d) stat path=%s is a directory will not write to events file\n",__FUNCTION__,__LINE__,full_path); > free(full_path); > return result; > } > else { > PERR("%s(%d) stat path=%s is not a directory will write to events file\n",__FUNCTION__,__LINE__,full_path); > } > } > else { > PERR("%s(%d) stat path=%s failed\n",__FUNCTION__,__LINE__,full_path); > //let it just continue despite failure > } > > > /* resolve full path */ > path_size = strlen(full_path); > /* report results to shared memory */ > vfsevent__init(&ve); > ve.path = (char *)calloc(path_size + 1,sizeof(char)); > ve.rename_path = NULL; > _pop_vfs_event(&ve); > ve.optype = VFSEVENT__OP_TYPE__OPTYPE_OPEN; > //strncpy(ve.path, full_path, path_size + 1); > strncpy(ve.path, full_path, path_size); > ve.fselem_type = VFSEVENT__FS_ELEM_TYPE__FSELEMTYPE_FILE; > PERR("%s(%d) calls _write_vfs_event path=%s is_directory=%d\n",__FUNCTION__,__LINE__,full_path,fsp->is_directory); > _write_vfs_event(&ve); > DEBUG(0,("%s(%d):wrote VFS event open =================> %s\n",__FUNCTION__,__LINE__, ve.path)); > free(ve.path); > } > else { > if(full_path) > DEBUG(0,("%s(%d): egnyte_open path=%s is a directory will not write to events file\n",__FUNCTION__,__LINE__,full_path)); > else > DEBUG(0,("%s(%d): egnyte_open path is a directory will not write to events file\n",__FUNCTION__,__LINE__)); > > } > } > free(full_path); > return result; >} > >static int egnyte_close(vfs_handle_struct *handle, files_struct *fsp) >{ > > PERR("%s: ENTRY\n",__func__); > > //flush_tlb = 21; > struct timeval tv; > gettimeofday(&tv, NULL); > if ( fsp->access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA | FILE_WRITE_EA | FILE_WRITE_ATTRIBUTES)) > { > /* > * Not all files are closed with the name. But files are guaranteed to > * be closed with a file descriptor > */ > int closefd; > char *mpath = NULL; > char *proc_path = NULL; > int became_root = 0; > int retlnk = 0; > > if (fsp && fsp->fh) { > closefd = fsp->fh->fd; > if (closefd > 0) { > mpath = (char *)calloc(PATH_MAX+1,sizeof(char)); > if (!mpath) { > DEBUG(0,("Cannot allocate memory\n")); > goto bail_out; > } > proc_path = (char *)calloc(PATH_MAX+1,sizeof(char)); > if (!proc_path) { > free(mpath); > DEBUG(0,("Cannot allocate memory\n")); > goto bail_out; > } > > snprintf(proc_path, PATH_MAX, "/proc/%d/fd/%d", getpid(), closefd); > if (geteuid() != 0) { > become_root(); > became_root = 1; > } > if ((retlnk = readlink(proc_path, mpath, PATH_MAX)) <= 0) { > DEBUG(0,("Readlink operation on %s failed %s\n", > proc_path, strerror(errno))); > } > if (became_root == 1) > unbecome_root(); > if (retlnk > 0) { > VFSEvent ve; > int path_size; > > path_size = strlen(mpath); > /* report results to shared memory */ > vfsevent__init(&ve); > ve.path = (char *)calloc(path_size + 1,sizeof(char)); > ve.rename_path = NULL; > ve.fselem_type = VFSEVENT__FS_ELEM_TYPE__FSELEMTYPE_FILE; > _pop_vfs_event(&ve); > ve.optype = VFSEVENT__OP_TYPE__OPTYPE_OPEN; > strncpy(ve.path, mpath, path_size); > PERR("%s(%d) calls _write_vfs_event\n",__FUNCTION__,__LINE__); > _write_vfs_event(&ve); > DEBUG(0,("%s(%d):wrote VFS event open (close)=================> %s\n", > __FUNCTION__,__LINE__, ve.path)); > free(ve.path); > } > free(proc_path); > free(mpath); > } else { > DEBUG(0, ("invalid file descriptor %d in fsp\n", closefd)); > } > } else { > /* > * This is being overly parannoid but safe. How samba would > * close a file without a filedescriptor is yet to be seen > * But thats samba's problem > */ > DEBUG(0,("Missed event due to missing file descriptor in fsp\n")); > } > } >bail_out: > return SMB_VFS_NEXT_CLOSE(handle, fsp); >} > > > >static int egnyte_rename(vfs_handle_struct *handle, const struct smb_filename *oldname, const struct smb_filename *newname) >{ > PERR("%s: ENTRY\n",__func__); > int result; > char *old_full_path, *new_full_path; > int old_path_size, new_path_size; > VFSEvent ve; > char *nlpath = NULL; > char *nlpath_dst = NULL; > int ap_ret = 0; > int isdir = 0; > int deletable = 0; > e_fsop_type_t src_op; > int mvret = 0; > DEBUG(0, ("egnyte:%s\n",__func__)); > DEBUG(8,("Rename case encountered\n")); > > //flush_tlb = 21; >#ifndef VFSPERMS_RWISRWD > > DEBUG(0,("Checking rename permissions regex conf %d \n", > global_params[PARAM_CHECK_REGEX_UNLINK].value.intval)); > if (global_params[PARAM_CHECK_REGEX_UNLINK].value.intval > 0) { > DEBUG(0,("Chehcking regex for %s\n",oldname->base_name)); > deletable = is_deletable_file(oldname->base_name); > } else { > DEBUG(0,("Implying delete for %s\n",oldname->base_name)); > deletable = 1; //check only RW permissions for delete for rename src > } > DEBUG(0,("Checking rename permissions regex conf %d deletable %d \n", > global_params[PARAM_CHECK_REGEX_UNLINK].value.intval, deletable)); >#else > e_fsop_type_t dst_op; >#endif > DEBUG(8,("Getting old full path\n")); > old_full_path = get_full_path(handle->conn->connectpath, oldname->base_name); > if (!old_full_path) { > errno = ENOMEM; > return -1; > } else { > > struct stat st; > int became_root = 0; > > if (geteuid() != 0) { > become_root(); > became_root = 1; > } > DEBUG(8,("Calling stat\n")); > if (stat(old_full_path, &st) != 0) { > //rename source does not exist. > DEBUG(0,("Rename source %s does not exist err %s\n",old_full_path, strerror(errno))); > errno = ENOENT; > if (became_root) { > unbecome_root(); > } > return -1; > } else { > DEBUG(8,("stat successful\n")); > if (S_ISDIR(st.st_mode)) { > DEBUG(8,("path is a dir\n")); > isdir = 1; > } else { > DEBUG(8,("path is not a dir\n")); > isdir = 0; > } > } > if (became_root) { > unbecome_root(); > } > } > > DEBUG(8,("Getting new full path\n")); > new_full_path = get_full_path(handle->conn->connectpath, newname->base_name); > if (!new_full_path) { > errno = ENOMEM; > free(old_full_path); > return -1; > } > nlpath = get_nullterminated_str(oldname->base_name,strlen(oldname->base_name)); > if (!nlpath) { > free(new_full_path); > free(old_full_path); > return ENOMEM; > } > > nlpath_dst = get_nullterminated_str(newname->base_name,strlen(newname->base_name)); > if (!nlpath_dst) { > free(new_full_path); > free(old_full_path); > free(nlpath); > errno = ENOMEM; > return -1; > } >#ifndef VFSPERMS_RWISRWD > mvret = is_amove(nlpath, nlpath_dst); > if (mvret < 0) { > DEBUG(0,("Could not assess whether move or rename. Assuming move src %s dst %s\n", > oldname->base_name, newname->base_name)); > src_op = FSOP_MOVE_SRC; > dst_op = FSOP_MOVE_DEST; > } else if (mvret == 1) { > src_op = FSOP_MOVE_SRC; > dst_op = FSOP_MOVE_DEST; > DEBUG(0, ("This is a move src %s dst %s\n", > oldname->base_name, newname->base_name)); > } else { > src_op = FSOP_RENAME_SRC; > dst_op = FSOP_RENAME_DEST; > } > if (deletable) { > DEBUG(0, ("Found a deletable file %s\n",oldname->base_name)); > result = vfs_enforce_perms(handle->conn->connectpath, nlpath, FSOP_OPEN_WRITE, NULL); > } else > DEBUG(0, ("Is not a deletable file %s\n",oldname->base_name)); > result = vfs_enforce_perms(handle->conn->connectpath, nlpath, src_op, NULL); > } >#else > /* > * RW implies the delete permission flag > */ > src_op = FSOP_OPEN_WRITE; > dst_op = FSOP_RENAME_DEST; > // sync-611: for folder moves enforce permissions > DEBUG(8,("isdir is %d\n", isdir)); > if (isdir) { > DEBUG(8,("Checking whether a move\n")); > mvret = is_amove(nlpath, nlpath_dst); > if (mvret < 0) { > DEBUG(0,("Could not tell whether move or rename, denying...\n")); > free(nlpath); > free(old_full_path); > free(new_full_path); > free(nlpath_dst); > errno = EACCES; > return -1; > } > DEBUG(8,("mvret is %d\n", mvret)); > if (mvret == 1) { > src_op = FSOP_MOVE_SRC; > dst_op = FSOP_MOVE_DEST; > DEBUG(8, ("This is a move folder src %s dst %s\n", > oldname->base_name, newname->base_name)); > } > else { > DEBUG(8, ("This is not a move folder src %s dst %s\n", > oldname->base_name, newname->base_name)); > } > } > DEBUG(8, ("Checking source perms for %s, op %d\n", nlpath, src_op)); > result = vfs_enforce_perms(handle->conn->connectpath, nlpath, src_op, NULL); > >#endif > free(nlpath); > if (result != EGPERMS_HAS_PERMS) { > DEBUG(8, ("Permission denied for source %s\n",oldname->base_name)); > free(old_full_path); > free(new_full_path); > free(nlpath_dst); > errno = EACCES; > return -1; > } > result = vfs_enforce_perms(handle->conn->connectpath, nlpath_dst, dst_op, NULL); > free(nlpath_dst); > if (result != EGPERMS_HAS_PERMS) { > free(old_full_path); > free(new_full_path); > errno = EACCES; > return -1; > } > /* > * Distinguish between the move and the rename > */ > become_root(); > result = SMB_VFS_NEXT_RENAME(handle, oldname, newname); > unbecome_root(); > if (result < 0) { > /* operation failed, dont log event */ > DEBUG(0,("(%s:%d) Failed event \n",__FUNCTION__,__LINE__)); > return result; > } else { > old_path_size = strlen(old_full_path); > new_path_size = strlen(new_full_path); > > /* report results to shared memory */ > vfsevent__init(&ve); > ve.path = (char *)calloc(old_path_size + 1,sizeof(char)); > ve.rename_path = (char *)calloc(new_path_size + 1,sizeof(char)); > _pop_vfs_event(&ve); > ve.optype = VFSEVENT__OP_TYPE__OPTYPE_RENAME; > strncpy(ve.path, old_full_path, old_path_size); > strncpy(ve.rename_path, new_full_path, new_path_size); > if (isdir) { > ve.fselem_type = VFSEVENT__FS_ELEM_TYPE__FSELEMTYPE_DIR; > } else { > ve.fselem_type = VFSEVENT__FS_ELEM_TYPE__FSELEMTYPE_FILE; > } > PERR("%s(%d) calls _write_vfs_event\n",__FUNCTION__,__LINE__); > _write_vfs_event(&ve); > DEBUG(0,("%s(%d):wrote VFS event open =================> %s\n", > __FUNCTION__,__LINE__, ve.path)); > free(ve.path); > free(ve.rename_path); > } > > free(old_full_path); > free(new_full_path); > return result; >} > > >static int egnyte_stat(vfs_handle_struct *handle, > struct smb_filename *smb_fname) >{ > PERR("%s: ENTRY\n",__func__); > int result; > char *nlpath = NULL; > > //flush_tlb = 21; > nlpath = get_nullterminated_str(smb_fname->base_name,strlen(smb_fname->base_name)); > if (!nlpath) { > errno = ENOMEM; > return -1; > } > > result = check_perms(handle->conn->connectpath, nlpath, FSOP_STAT, NULL); > //result = vfs_enforce_perms(handle->conn->connectpath, nlpath, FSOP_STAT, NULL); > free(nlpath); > DEBUG(0,("Back from enforce perms\n")); > if (result != EGPERMS_HAS_PERMS) { > //errno = EACCES; > errno = EPERM; > return -1; > } > become_root(); > result = SMB_VFS_NEXT_STAT(handle, smb_fname); > unbecome_root(); > DEBUG(0,("Back from next stat, result is: %d\n", result)); > smb_fname->st.st_ex_mode |= S_IRWXO; //fake that others have rwx perms > return result; >} > >static int egnyte_lstat(vfs_handle_struct *handle, struct smb_filename *path) >{ > PERR("%s: ENTRY\n",__func__); > DEBUG(0, ("egnyte:%s\n",__func__)); > int ret = -1; > char *full_path; > int result; > char *nlpath = NULL; > > //flush_tlb = 21; > full_path = get_full_path(handle->conn->connectpath, path->base_name); > if (!full_path) { > errno = ENOMEM; > return -1; > } > nlpath = get_nullterminated_str(path->base_name,strlen(path->base_name)); > if (!nlpath) { > free(full_path); > return ENOMEM; > } > //result = check_perms(handle->conn->connectpath, nlpath, FSOP_LSTAT, NULL); > result = vfs_enforce_perms(handle->conn->connectpath, nlpath, FSOP_LSTAT, NULL); > free(nlpath); > if (result != EGPERMS_HAS_PERMS) { > free(full_path); > errno = EACCES; > return -1; > } > > free(full_path); > become_root(); > ret = SMB_VFS_NEXT_LSTAT(handle, path); > unbecome_root(); > if (!is_ELC_Share(handle->conn->connectpath)) { > DEBUG(0,("(%s:%d) Failed event \n",__FUNCTION__,__LINE__)); > path->st.st_ex_mode |= S_IRWXO; > return ret; > } > DEBUG (0, ("In egnyte lstat for path %s ret %d\n", path->base_name, ret)); > if (ret == 0) { > path->st.st_ex_mode |= S_IRWXO; > } > > return ret; >} > >static int egnyte_unlink(vfs_handle_struct *handle, const struct smb_filename *path) >{ > PERR("%s: ENTRY\n",__func__); > int result; > char *full_path = NULL; > int path_size; > VFSEvent ve; > char *nlpath = NULL; > > //flush_tlb = 21; > > /* resolve full path */ > full_path = get_full_path(handle->conn->connectpath, path->base_name); > if (!full_path) { > errno = ENOMEM; > return -1; > } > > nlpath = get_nullterminated_str(path->base_name,strlen(path->base_name)); > if (!nlpath) { > free(full_path); > return ENOMEM; > } >#ifndef VFSPERMS_RWISRWD > /* > * Check explicit unlink look out for the delete on close flag > * Enforce unlink permissions on the delete on close flag > */ > { > struct file_id id; > struct share_mode_lock *lck = NULL; > struct timespec old_write_time = path->st.st_ex_mtime; > > id = vfs_file_id_from_sbuf(handle->conn, &path->st); > lck = get_share_mode_lock(talloc_tos(), id, handle->conn->connectpath, path, > &old_write_time); > if (lck == NULL) { > DEBUG(0,("Could not get share mode lock\n")); > free(full_path); > free(nlpath); > nlpath = NULL; > errno = EACCES; > return -1; > } else { > DEBUG(0,("Checking unlink permissions delete on close %d regex conf %d \n", > lck->delete_on_close, global_params[PARAM_CHECK_REGEX_UNLINK].value.intval)); > if (lck->delete_on_close) { > /*enforce D perm */ > result = vfs_enforce_perms(handle->conn->connectpath, nlpath, FSOP_UNLINK, NULL); > DEBUG(0,("Delete on close is set for %s\n",nlpath)); > } else { > /* > * If a process has RW permissions D permissions is implicit for unlink for > * temporary files > */ > if (global_params[PARAM_CHECK_REGEX_UNLINK].value.intval > 0) { > DEBUG(0,("Chehcking regex for %s\n",nlpath)); > if (is_deletable_file(nlpath)) { > result = vfs_enforce_perms(handle->conn->connectpath, nlpath, FSOP_OPEN_WRITE, NULL); > } else { > result = vfs_enforce_perms(handle->conn->connectpath, nlpath, FSOP_UNLINK, NULL); > } > } else { > DEBUG(0,("Implying Delete for %s\n",nlpath)); > result = vfs_enforce_perms(handle->conn->connectpath, nlpath, FSOP_OPEN_WRITE, NULL); > } > DEBUG(0,("Delete on close is not set set for %s\n", nlpath)); > } > free(nlpath); > nlpath = NULL; > } > TALLOC_FREE(lck); > } >#else > /* > * RW implies RWD > */ > result = vfs_enforce_perms(handle->conn->connectpath, nlpath, FSOP_OPEN_WRITE, NULL); > free(nlpath); > nlpath = NULL; >#endif > if (result != EGPERMS_HAS_PERMS) { > free(full_path); > if(nlpath) > free(nlpath); > errno = EACCES; > return -1; > } > > become_root(); > result = SMB_VFS_NEXT_UNLINK(handle, path); > unbecome_root(); > if (result < 0) { > DEBUG(0,("(%s:%d) Failed event \n",__FUNCTION__,__LINE__)); > /* operation failed, dont log event */ > return result; > } else { > /* report results to shared memory */ > path_size = strlen(full_path); > vfsevent__init(&ve); > ve.path = (char *)calloc(path_size + 1,sizeof(char)); > ve.rename_path = NULL; > _pop_vfs_event(&ve); > ve.optype = VFSEVENT__OP_TYPE__OPTYPE_UNLINK; > strncpy(ve.path, full_path,path_size); > ve.fselem_type = VFSEVENT__FS_ELEM_TYPE__FSELEMTYPE_FILE; > PERR("%s(%d) calls _write_vfs_event\n",__FUNCTION__,__LINE__); > _write_vfs_event(&ve); > DEBUG(0,("%s(%d):wrote VFS event unlink =================> %s\n", > __FUNCTION__,__LINE__, ve.path)); > free(ve.path); > } > > free(full_path); > return result; >} > >/* >static int egnyte_chmod(vfs_handle_struct *handle, const char *path, > mode_t mode) >{ > PERR("%s: ENTRY\n",__func__); > int result; > //flush_tlb = 21; > DEBUG(0, ("egnyte:%s\n",__func__)); > // permission changes have little impact on permissions now :) > result = SMB_VFS_NEXT_CHMOD(handle, path, mode); > if (result == 0) { > DEBUG(0, ("Permission set did not succeed %d\n", errno)); > } > return 0; >} > > >static int egnyte_fchmod(vfs_handle_struct *handle, files_struct *fsp, mode_t mode) >{ > PERR("%s: ENTRY\n",__func__); > int result; > DEBUG(0, ("egnyte:%s\n",__func__)); > //flush_tlb = 21; > // permission changes have little impact on permissions now :) > result = SMB_VFS_NEXT_FCHMOD(handle, fsp, mode); > if (result == 0) { > DEBUG(0, ("Permission set did not succeed %d\n", errno)); > } > return 0; >} >*/ > >static int egnyte_chmod_acl(vfs_handle_struct *handle, const char *path, mode_t mode) >{ > PERR("%s: ENTRY\n",__func__); > //flush_tlb = 21; > return 0; >} > > >static int egnyte_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, mode_t mode) >{ > PERR("%s: ENTRY\n",__func__); > //flush_tlb = 21; > return 0; >} > > > > >static egnyte_acl_set_file(vfs_handle_struct *conn, const char *to, > SMB_ACL_TYPE_T type, SMB_ACL_T acl) >{ > PERR("%s: ENTRY\n",__func__); > DEBUG(0, ("Silently failing permissions to set perms %s\n", __FUNCTION__)); > return 0; >} > >static egnyte_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp, SMB_ACL_T acl) >{ > PERR("%s: ENTRY\n",__func__); > DEBUG(0, ("egnyte:%s\n",__func__)); > DEBUG(0, ("silently failing permissions to set perms %s\n", __FUNCTION__)); > return 0; >} > >static int egnyte_chdir(vfs_handle_struct *handle, > const char *path) >{ > PERR("%s: ENTRY\n",__func__); > int result; > int retval; > char *nlpath = NULL; > > //flush_tlb = 21; > > nlpath = get_nullterminated_str(path,strlen(path)); > if (!nlpath) { > return ENOMEM; > } > //retval = check_perms(handle->conn->connectpath, nlpath, FSOP_CHDIR, NULL); > retval = vfs_enforce_perms(handle->conn->connectpath, nlpath, FSOP_CHDIR, NULL); > if (retval != EGPERMS_HAS_PERMS) { > errno = EACCES; > free(nlpath); > return -1; > } > DEBUG(0,("Enabled chdir for '%s'\n",nlpath)); > free(nlpath); > become_root(); > result = SMB_VFS_NEXT_CHDIR(handle, path); > unbecome_root(); > return result; >} > >static int egnyte_statvfs(struct vfs_handle_struct *handle, > const char *path, > struct vfs_statvfs_struct *statbuf) >{ > PERR("%s: ENTRY\n",__func__); > DEBUG(0, ("egnyte:%s\n",__func__)); > int result; > char *full_path; > int retval; > char *nlpath = NULL; > > //flush_tlb = 21; > > full_path = get_full_path(handle->conn->connectpath, path); > if (!full_path) { > errno = ENOMEM; > return -1; > } > nlpath = get_nullterminated_str(path,strlen(path)); > if (!nlpath) { > free(full_path); > return ENOMEM; > } > //retval = check_perms(handle->conn->connectpath, nlpath, FSOP_STATVFS, NULL); > retval = vfs_enforce_perms(handle->conn->connectpath, nlpath, FSOP_STATVFS, NULL); > free(nlpath); > if (retval != EGPERMS_HAS_PERMS) { > free(full_path); > errno = EACCES; > return -1; > } > DEBUG(0,("Enabled statvfs for %s\n",full_path)); > > free(full_path); > > become_root(); > result = SMB_VFS_NEXT_STATVFS(handle, path, statbuf); > unbecome_root(); > return result; >} > >/* >static ssize_t egnyte_getxattr(struct vfs_handle_struct *handle, > const char *path, > const char *name, void *value, size_t size) >{ > PERR("%s: ENTRY\n",__func__); > ssize_t result; > int became_root = 0; > > //flush_tlb = 21; > if (geteuid() != 0) { > become_root(); > became_root = 1; > } > result = SMB_VFS_NEXT_GETXATTR(handle, path, name, value, size); > if(became_root) { > unbecome_root(); > } > return result; >} > > > >static int egnyte_setxattr(struct vfs_handle_struct *handle, > const char *path, > const char *name, const void *value, size_t size, > int flags) >{ > PERR("%s: ENTRY\n",__func__); > DEBUG(0, ("egnyte:%s\n",__func__)); > //flush_tlb = 21; > int result; > int became_root = 0; > > if (geteuid() != 0) { > become_root(); > became_root = 1; > } > result = SMB_VFS_NEXT_SETXATTR(handle, path, name, value, size, > flags); > > if(became_root) { > unbecome_root(); > } > return result; >} >*/ > >/* >static uint64_t egnyte_disk_free(vfs_handle_struct *handle, > const char *path, > bool small_query, uint64_t *bsize, > uint64_t *dfree, uint64_t *dsize) >{ > DEBUG(0, ("egnyte:%s\n",__func__)); > uint64_t result; > int became_root = 0; > > if(geteuid() != 0) { > become_root(); > became_root =1; > } > result = SMB_VFS_NEXT_DISK_FREE(handle, path, small_query, bsize, dfree, dsize); > if (became_root == 1) { > unbecome_root(); > } > return result; >} >*/ > >static int egnyte_ntimes(vfs_handle_struct *handle, > const struct smb_filename *smb_fname, > struct smb_file_time *ft) >{ > PERR("%s: ENTRY\n",__func__); > int result; > char *full_path = NULL; > int path_size; > VFSEvent ve; > int became_root = 0; > > DEBUG(0, ("egnyte:%s\n",__func__)); > //flush_tlb = 21; > /* No need to report time changes on dirs */ > if (S_ISDIR(smb_fname->st.st_ex_mode)) { > if (geteuid() != 0) { > become_root(); > became_root = 1; > } > result = SMB_VFS_NEXT_NTIMES(handle, smb_fname, ft); > if (became_root == 1) { > unbecome_root(); > } > return result; > } > > full_path = get_full_path(handle->conn->connectpath, smb_fname->base_name); > if (!full_path) { > errno = ENOMEM; > return -1; > } > if (geteuid() != 0) { > become_root(); > became_root = 1; > } > result = SMB_VFS_NEXT_NTIMES(handle, smb_fname, ft); > if (became_root == 1) { > unbecome_root(); > } > if (result < 0) { > /* operation failed, dont log event */ > DEBUG(0,("(%s:%d) Failed event \n",__FUNCTION__,__LINE__)); > } else { > /* resolve full path */ > path_size = strlen(full_path); > /* report results to shared memory */ > vfsevent__init(&ve); > ve.path = (char *)calloc(path_size + 1,sizeof(char)); > ve.rename_path = NULL; > _pop_vfs_event(&ve); > ve.optype = VFSEVENT__OP_TYPE__OPTYPE_OPEN; > strncpy(ve.path, full_path,path_size); > ve.fselem_type = VFSEVENT__FS_ELEM_TYPE__FSELEMTYPE_FILE; > PERR("%s(%d) calls _write_vfs_event\n",__FUNCTION__,__LINE__); > _write_vfs_event(&ve); > DEBUG(0,("%s(%d):wrote VFS event ntimes =================> %s\n", > __FUNCTION__,__LINE__, ve.path)); > free(ve.path); > } > > free(full_path); > return result; >} > > >static char *egnyte_realpath(vfs_handle_struct *handle,const char *path) >{ > PERR("%s: ENTRY\n",__func__); > DEBUG(0, ("egnyte:%s\n",__func__)); > char *result; > >#if 0 > char *full_path; > int retval; > full_path = get_full_path(handle->conn->connectpath, path); > if (full_path == NULL ) { > errno = ENOMEM; > return NULL; > } > > DEBUG(0,("Checking realpath for %s\n",full_path)); > retval = vfs_enforce_perms(path, FSOP_REALPATH, NULL); > if (retval != EGPERMS_HAS_PERMS) { > free(full_path); > errno = EACCES; > return NULL; > } > > free(full_path); >#endif > become_root(); > result = SMB_VFS_NEXT_REALPATH(handle, path); > unbecome_root(); > return result; >} > >static void egnyte_doctor_acl(struct security_descriptor **ppdesc) >{ > PERR("%s: ENTRY\n",__func__); > DEBUG(0, ("egnyte:%s\n",__func__)); > struct security_ace *ace = NULL; > struct security_acl *theACL = NULL; > struct security_descriptor *pdesc; > int num_aces =0; > > pdesc = *ppdesc; > if (pdesc == NULL) { > DEBUG(0, ("No DACL\n")); > return; > } > theACL = pdesc->dacl; > if (!theACL) { > DEBUG(0, ("No DACL present\n")); > return; > } > if (theACL->num_aces == 0) { > DEBUG(0, ("No ACES in DACL \n")); > return; > } > > for (num_aces = 0; num_aces < theACL->num_aces; num_aces ++) { > ace = &(theACL->aces[num_aces]); > if (ace->type == SEC_ACE_TYPE_ACCESS_ALLOWED) { > DEBUG(0,("Setting ACE perms old %0x new %0x\n",ace->access_mask, UNIX_ACCESS_RWX)); > ace->access_mask = UNIX_ACCESS_RWX; > } > } > return; >} > > >static NTSTATUS egnyte_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp, > uint32 security_info,TALLOC_CTX *mem_ctx,struct security_descriptor **ppdesc) >{ > PERR("%s: ENTRY\n",__func__); > NTSTATUS result; > DEBUG(0, ("egnyte:%s\n",__func__)); > //flush_tlb = 21; > become_root(); > result = SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, security_info, mem_ctx,ppdesc); > egnyte_doctor_acl(ppdesc); > unbecome_root(); > return result; >} > > > >static NTSTATUS egnyte_get_nt_acl(vfs_handle_struct *handle, > const char *name, > uint32 security_info, > TALLOC_CTX *mem_ctx, > struct security_descriptor **ppdesc) >{ > PERR("%s: ENTRY\n",__func__); > NTSTATUS result; > > DEBUG(0, ("egnyte:%s\n",__func__)); > //flush_tlb = 21; > become_root(); > result = SMB_VFS_NEXT_GET_NT_ACL(handle, name, security_info, mem_ctx,ppdesc); > egnyte_doctor_acl(ppdesc); > unbecome_root(); > return result; >} > > >static int read_egnyte_config(void) >{ > PERR("%s: ENTRY\n",__func__); > DEBUG(0, ("egnyte:%s\n",__func__)); > key_t shmk; > int shmid; > void *addr = NULL; > size_t len; > > /* > * Allocate the memory to workaround a problem with the shared memory > * appearing to get detached by a child process. This memory is not > * freed on disconnect in case a connect/connect/disconnect/disconnect > * sequence occurs #63985. It will be freed when the process exits. > */ > len = sizeof(global_param_t)*PARAM_MAX_INDEX; > global_params = (global_param_t *)realloc(global_params, len); > if (!global_params) { > PERR("could not allocate global_params buffer\n"); > return -1; > } > > if ((shmk = ftok(CONFIG_SHM_PATH, CONFIG_SHM_PROJECT)) == (key_t)-1) { > PERR("cannot create sema key for shm. errno = %d(%s)\n", errno, strerror(errno)); > return -1; > } > > if ((shmid = shmget(shmk, len, IPC_CREAT|0666)) < 0) { > PERR("cannot create shared memory for global param. errno = %d(%s)\n", errno, strerror(errno)); > return -1; > } > > if ((addr = shmat(shmid, 0, 0)) == (void *)-1) { > PERR("cannot attach to shm. errno = %d(%s)\n", errno, strerror(errno)); > return -1; > } > > memset((void *)global_params, '\0', len); > memcpy((void *)global_params, addr, len); > shmdt(addr); >} > > > >/* VFS operations structure */ >static struct vfs_fn_pointers vfs_egnyte_fns = { > .connect_fn = egnyte_connect, > .disconnect_fn = egnyte_disconnect, > .opendir_fn = egnyte_opendir, > .mkdir_fn = egnyte_mkdir, > .rmdir_fn = egnyte_rmdir, > .open_fn = egnyte_open, > .close_fn = egnyte_close, > .rename_fn = egnyte_rename, > .unlink_fn = egnyte_unlink, >// .chmod_fn = egnyte_chmod, >// .fchmod_fn = egnyte_fchmod, > .chmod_acl_fn = egnyte_chmod_acl, > .sys_acl_set_fd_fn = egnyte_acl_set_fd, > .sys_acl_set_file_fn = egnyte_acl_set_file, >// .setxattr_fn = egnyte_setxattr, > // .getxattr_fn = egnyte_getxattr, > .stat_fn = egnyte_stat, > .lstat_fn = egnyte_lstat, > .realpath_fn = egnyte_realpath, > .fget_nt_acl_fn = egnyte_fget_nt_acl, > .get_nt_acl_fn = egnyte_get_nt_acl, > .chdir_fn = egnyte_chdir, >// .disk_free_fn = egnyte_disk_free, > .ntimes_fn = egnyte_ntimes >}; > > > >#define vfs_egnyte_init init_samba_module > >static void free_compiled_patterns(void) >{ > DEBUG(0, ("egnyte:%s\n",__func__)); > int cnt; > > for(cnt = 0; cnt < pattern_buf.num_elems; cnt ++) { > if (pattern_buf.elems[cnt].pattern) { > free(pattern_buf.elems[cnt].pattern); > } > } >} > >static int read_and_compile_patterns(void) >{ > DEBUG(0, ("egnyte:%s\n",__func__)); > FILE* fp; > struct stat st; > char *buf; > size_t bufsize=1024; > int indx=0; > > if (global_params[PARAM_REGEX_FILE_NAME].value.strval[0] == '\0') { > PERR("no regex file specified\n"); > return -1; > } > if (stat(global_params[PARAM_REGEX_FILE_NAME].value.strval, &st) != 0) { > PERR("regular expression file does not exist\n"); > return -1; > } > if ((fp = fopen(global_params[PARAM_REGEX_FILE_NAME].value.strval, "r")) == NULL) { > PERR("cannot open regular expression file\n"); > return -1; > } > buf = (char*)calloc(bufsize,sizeof(char)); > > pattern_buf.num_elems = 0; > while (getline(&buf, &bufsize, fp) > 0) { > if (indx < MAX_REGEX_PATTERNS) { > //precompute the pattern buffers for matching > pattern_buf.elems[indx].compiled_pattern = NULL; > pattern_buf.elems[indx].pattern = (char *)malloc(strlen(buf)+1); > memset(pattern_buf.elems[indx].pattern, '\0', strlen(buf)+1); > strncpy(pattern_buf.elems[indx].pattern, buf, strlen(buf)-1); > if (get_regex_matchbuf(pattern_buf.elems[indx].pattern, > &pattern_buf.elems[indx].compiled_pattern) > == REGEX_ERROR) { > free(pattern_buf.elems[indx].pattern); > continue; > } > PDBG("read pattern %s\n", pattern_buf.elems[indx].pattern); > } > > pattern_buf.num_elems ++; > indx++; > memset(buf, '\0', bufsize); > } > free(buf); >} > >/* > * return 1 if match, 0 if mismatch > */ > >static int is_deletable_file(char *fname) >{ > int indx; > > DEBUG(0, ("Checking for deletable file\n")); > for (indx = 0; indx < pattern_buf.num_elems; indx++) { > if (match_string_with_regex_buf(fname, pattern_buf.elems[indx].compiled_pattern) == REGEX_TRUE) { > DEBUG(0, ("Found deletable file %s\n",fname)); > return 1; > } > } > return 0; >} > > >NTSTATUS vfs_egnyte_init(void) >{ > PERR("Loading egnyte module...\n"); > // since we chown everything to root, we do not want umask as 022. > umask(0); > return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "egnyte", &vfs_egnyte_fns); >} > > >NTSTATUS samba_init_module(void) >{ > PERR("%s: ENTRY\n",__func__); > return vfs_egnyte_init(); >}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 9776
:
8739
| 8772