NTSTATUS pdb_init_plugin(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location) { void * dl_handle; char *plugin_location, *plugin_name, *p; pdb_init_function plugin_init; int (*plugin_version)(void); if (location == NULL) { DEBUG(0, ("The plugin module needs an argument!\n")); return NT_STATUS_UNSUCCESSFUL; } plugin_name = smb_xstrdup(location); p = strchr(plugin_name, ':'); if (p) { *p = 0; plugin_location = p+1; trim_char(plugin_location, ' ', ' '); } else { plugin_location = NULL; } trim_char(plugin_name, ' ', ' '); DEBUG(5, ("Trying to load sam plugin %s\n", plugin_name)); dl_handle = sys_dlopen(plugin_name, RTLD_NOW ); if (!dl_handle) { DEBUG(0, ("Failed to load sam plugin %s using sys_dlopen (%s)\n", plugin_name, sys_dlerror())); return NT_STATUS_UNSUCCESSFUL; } plugin_version = sys_dlsym(dl_handle, "pdb_version"); if (!plugin_version) { sys_dlclose(dl_handle); DEBUG(0, ("Failed to find function 'pdb_version' using sys_dlsym in sam plugin %s (%s)\n", plugin_name, sys_dlerror())); return NT_STATUS_UNSUCCESSFUL; } if (plugin_version() != PASSDB_INTERFACE_VERSION) { sys_dlclose(dl_handle); DEBUG(0, ("Wrong PASSDB_INTERFACE_VERSION! sam plugin has version %d and version %d is needed! Please update!\n", plugin_version(),PASSDB_INTERFACE_VERSION)); return NT_STATUS_UNSUCCESSFUL; } plugin_init = sys_dlsym(dl_handle, "pdb_init"); if (!plugin_init) { sys_dlclose(dl_handle); DEBUG(0, ("Failed to find function 'pdb_init' using sys_dlsym in sam plugin %s (%s)\n", plugin_name, sys_dlerror())); return NT_STATUS_UNSUCCESSFUL; } DEBUG(5, ("Starting sam plugin %s with location %s\n", plugin_name, plugin_location)); return plugin_init(pdb_context, pdb_method, plugin_location); }
bool load_auth_module(struct auth_context *auth_context, const char *module, auth_methods **ret) { static bool initialised_static_modules = False; struct auth_init_function_entry *entry; char *module_name = smb_xstrdup(module); char *module_params = NULL; char *p; bool good = False; /* Initialise static modules if not done so yet */ if(!initialised_static_modules) { static_init_auth; initialised_static_modules = True; } DEBUG(5,("load_auth_module: Attempting to find an auth method to match %s\n", module)); p = strchr(module_name, ':'); if (p) { *p = 0; module_params = p+1; trim_char(module_params, ' ', ' '); } trim_char(module_name, ' ', ' '); entry = auth_find_backend_entry(module_name); if (entry == NULL) { if (NT_STATUS_IS_OK(smb_probe_module("auth", module_name))) { entry = auth_find_backend_entry(module_name); } } if (entry != NULL) { if (!NT_STATUS_IS_OK(entry->init(auth_context, module_params, ret))) { DEBUG(0,("load_auth_module: auth method %s did not correctly init\n", module_name)); } else { DEBUG(5,("load_auth_module: auth method %s has a valid init\n", module_name)); good = True; } } else { DEBUG(0,("load_auth_module: can't find auth method %s!\n", module_name)); } SAFE_FREE(module_name); return good; }
/**************************************************************************** Check for existance of a dir. ****************************************************************************/ BOOL cli_chkpath(struct cli_state *cli, const char *path) { pstring path2; char *p; pstrcpy(path2,path); trim_char(path2,'\0','\\'); if (!*path2) *path2 = '\\'; memset(cli->outbuf,'\0',smb_size); set_message(cli->outbuf,0,0,True); SCVAL(cli->outbuf,smb_com,SMBchkpth); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); p = smb_buf(cli->outbuf); *p++ = 4; p += clistr_push(cli, p, path2, -1, STR_TERMINATE); cli_setup_bcc(cli, p); cli_send_smb(cli); if (!cli_receive_smb(cli)) { return False; } if (cli_is_error(cli)) return False; return True; }
static int expect(int master, char *issue, char *expected) { pstring buffer; int attempts, timeout, nread, len; BOOL match = False; for (attempts = 0; attempts < 2; attempts++) { if (!strequal(issue, ".")) { if (lp_passwd_chat_debug()) DEBUG(100, ("expect: sending [%s]\n", issue)); if ((len = write(master, issue, strlen(issue))) != strlen(issue)) { DEBUG(2,("expect: (short) write returned %d\n", len )); return False; } } if (strequal(expected, ".")) return True; /* Initial timeout. */ timeout = lp_passwd_chat_timeout() * 1000; nread = 0; buffer[nread] = 0; while ((len = read_socket_with_timeout(master, buffer + nread, 1, sizeof(buffer) - nread - 1, timeout)) > 0) { nread += len; buffer[nread] = 0; { /* Eat leading/trailing whitespace before match. */ pstring str; pstrcpy( str, buffer); trim_char( str, ' ', ' '); if ((match = (unix_wild_match(expected, str) == 0))) { /* Now data has started to return, lower timeout. */ timeout = lp_passwd_chat_timeout() * 100; } } } if (lp_passwd_chat_debug()) DEBUG(100, ("expect: expected [%s] received [%s] match %s\n", expected, buffer, match ? "yes" : "no" )); if (match) break; if (len < 0) { DEBUG(2, ("expect: %s\n", strerror(errno))); return False; } } DEBUG(10,("expect: returning %s\n", match ? "True" : "False" )); return match; }
//trim path withi " " and "/" slash a then remove duplicate slashes (string is modifed) char * remove_slashes(char *path) { char *r_path = trim(trim_char(path, isslash)); char *res = malloc(strlen(path) + 1); char *p = r_path; char *d = res; int prev_slash = 0; while(*p != 0) { if(*p != '/') { *d = *p; d++; prev_slash = 0; } else if(*p == '/') { if(!prev_slash) { *d = *p; d++; } prev_slash = 1; } p++; } *d = *p; strcpy(path, res); free(res); return path; }
void sub_set_smb_name(const char *name) { fstring tmp; int len; BOOL is_machine_account = False; /* don't let anonymous logins override the name */ if (! *name) return; fstrcpy( tmp, name ); trim_char( tmp, ' ', ' ' ); strlower_m( tmp ); len = strlen( tmp ); if ( len == 0 ) return; /* long story but here goes....we have to allow usernames ending in '$' as they are valid machine account names. So check for a machine account and re-add the '$' at the end after the call to alpha_strcpy(). --jerry */ if ( tmp[len-1] == '$' ) is_machine_account = True; alpha_strcpy( smb_user_name, tmp, SAFE_NETBIOS_CHARS, sizeof(smb_user_name)-1 ); if ( is_machine_account ) { len = strlen( smb_user_name ); smb_user_name[len-1] = '$'; } }
void set_local_machine_name(const char* local_name, BOOL perm) { static BOOL already_perm = False; fstring tmp_local_machine; /* * Windows NT/2k uses "*SMBSERVER" and XP uses "*SMBSERV" * arrggg!!! */ if (strequal(local_name, "*SMBSERVER")) return; if (strequal(local_name, "*SMBSERV")) return; if (already_perm) return; already_perm = perm; fstrcpy(tmp_local_machine,local_name); trim_char(tmp_local_machine,' ',' '); alpha_strcpy(local_machine,tmp_local_machine,SAFE_NETBIOS_CHARS,sizeof(local_machine)-1); strlower_m(local_machine); }
/* load a msg file into the tdb */ static BOOL load_msg(const char *msg_file) { char **lines; int num_lines, i; char *msgid, *msgstr; TDB_DATA key, data; lines = file_lines_load(msg_file, &num_lines); if (!lines) { return False; } if (tdb_lockall(tdb) != 0) return False; /* wipe the db */ tdb_traverse(tdb, tdb_traverse_delete_fn, NULL); msgid = NULL; for (i=0;i<num_lines;i++) { if (strncmp(lines[i], "msgid \"", 7) == 0) { msgid = lines[i] + 7; } if (msgid && strncmp(lines[i], "msgstr \"", 8) == 0) { msgstr = lines[i] + 8; trim_char(msgid, '\0', '\"'); trim_char(msgstr, '\0', '\"'); if (*msgstr == 0) { msgstr = msgid; } all_string_sub(msgid, "\\n", "\n", 0); all_string_sub(msgstr, "\\n", "\n", 0); key.dptr = msgid; key.dsize = strlen(msgid)+1; data.dptr = msgstr; data.dsize = strlen(msgstr)+1; tdb_store(tdb, key, data, 0); msgid = NULL; } } file_lines_free(lines); tdb_unlockall(tdb); return True; }
/* load a msg file into the tdb */ static bool load_msg(const char *msg_file) { char **lines; int num_lines, i; char *msgid, *msgstr; TDB_DATA data; lines = file_lines_load(msg_file, &num_lines, 0, NULL); if (!lines) { return False; } if (tdb_lockall(tdb) != 0) { TALLOC_FREE(lines); return False; } /* wipe the db */ tdb_wipe_all(tdb); msgid = NULL; for (i=0;i<num_lines;i++) { if (strncmp(lines[i], "msgid \"", 7) == 0) { msgid = lines[i] + 7; } if (msgid && strncmp(lines[i], "msgstr \"", 8) == 0) { msgstr = lines[i] + 8; trim_char(msgid, '\0', '\"'); trim_char(msgstr, '\0', '\"'); if (*msgstr == 0) { msgstr = msgid; } all_string_sub(msgid, "\\n", "\n", 0); all_string_sub(msgstr, "\\n", "\n", 0); data = string_term_tdb_data(msgstr); tdb_store_bystring(tdb, msgid, data, 0); msgid = NULL; } } TALLOC_FREE(lines); tdb_unlockall(tdb); return True; }
char *nv_trim_char_strict(char *string, char trim) { int count; char *trimmed; trimmed = trim_char(string, trim, &count); if (count == 0 || count == 2) { return trimmed; } return NULL; }
static BOOL init_reply_dfs_info_3(TALLOC_CTX *ctx, struct junction_map* j, NETDFS_DFS_INFO3* dfs3) { int ii; pstring str; dfs3->ptr0_path = 1; if (j->volume_name[0] == '\0') slprintf(str, sizeof(pstring)-1, "\\\\%s\\%s", global_myname(), j->service_name); else slprintf(str, sizeof(pstring)-1, "\\\\%s\\%s\\%s", global_myname(), j->service_name, j->volume_name); init_unistr2(&dfs3->path, str, UNI_STR_TERMINATE); dfs3->ptr0_comment = 1; init_unistr2(&dfs3->comment, j->comment, UNI_STR_TERMINATE); dfs3->state = 1; dfs3->num_stores = dfs3->size_stores = j->referral_count; /* also enumerate the stores */ if (j->referral_count) { dfs3->stores = TALLOC_ARRAY(ctx, NETDFS_DFS_STORAGEINFO, j->referral_count); if (!dfs3->stores) return False; memset(dfs3->stores, '\0', j->referral_count * sizeof(NETDFS_DFS_STORAGEINFO)); dfs3->ptr0_stores = 1; } else { dfs3->stores = NULL; dfs3->ptr0_stores = 0; } for(ii=0;ii<j->referral_count;ii++) { char* p; pstring path; NETDFS_DFS_STORAGEINFO* stor = &(dfs3->stores[ii]); struct referral* ref = &(j->referral_list[ii]); pstrcpy(path, ref->alternate_path); trim_char(path,'\\','\0'); p = strrchr_m(path,'\\'); if(p==NULL) { DEBUG(4,("init_reply_dfs_info_3: invalid path: no \\ found in %s\n",path)); continue; } *p = '\0'; DEBUG(5,("storage %d: %s.%s\n",ii,path,p+1)); stor->state = 2; /* set all stores as ONLINE */ init_unistr2(&stor->server, path, UNI_STR_TERMINATE); init_unistr2(&stor->share, p+1, UNI_STR_TERMINATE); stor->ptr0_server = stor->ptr0_share = 1; } return True; }
void sub_set_smb_name(const char *name) { fstring tmp; /* don't let anonymous logins override the name */ if (! *name) return; fstrcpy(tmp,name); trim_char(tmp,' ',' '); strlower_m(tmp); alpha_strcpy(smb_user_name,tmp,SAFE_NETBIOS_CHARS,sizeof(smb_user_name)-1); }
void set_remote_machine_name(const char* remote_name, BOOL perm) { static BOOL already_perm = False; fstring tmp_remote_machine; if (already_perm) return; already_perm = perm; fstrcpy(tmp_remote_machine,remote_name); trim_char(tmp_remote_machine,' ',' '); alpha_strcpy(remote_machine,tmp_remote_machine,SAFE_NETBIOS_CHARS,sizeof(remote_machine)-1); strlower_m(remote_machine); }
char *nv_trim_char(char *string, char trim) { return trim_char(string, trim, NULL); }
static NTSTATUS idmap_ldap_db_init(struct idmap_domain *dom) { NTSTATUS ret; struct idmap_ldap_context *ctx = NULL; char *config_option = NULL; const char *tmp = NULL; /* Only do init if we are online */ if (idmap_is_offline()) { return NT_STATUS_FILE_IS_OFFLINE; } ctx = talloc_zero(dom, struct idmap_ldap_context); if ( ! ctx) { DEBUG(0, ("Out of memory!\n")); return NT_STATUS_NO_MEMORY; } config_option = talloc_asprintf(ctx, "idmap config %s", dom->name); if (!config_option) { DEBUG(0, ("Out of memory!\n")); ret = NT_STATUS_NO_MEMORY; goto done; } tmp = lp_parm_const_string(-1, config_option, "ldap_url", NULL); if ( ! tmp) { DEBUG(1, ("ERROR: missing idmap ldap url\n")); ret = NT_STATUS_UNSUCCESSFUL; goto done; } ctx->url = talloc_strdup(ctx, tmp); trim_char(ctx->url, '\"', '\"'); tmp = lp_parm_const_string(-1, config_option, "ldap_base_dn", NULL); if ( ! tmp || ! *tmp) { tmp = lp_ldap_idmap_suffix(talloc_tos()); if ( ! tmp) { DEBUG(1, ("ERROR: missing idmap ldap suffix\n")); ret = NT_STATUS_UNSUCCESSFUL; goto done; } } ctx->suffix = talloc_strdup(ctx, tmp); CHECK_ALLOC_DONE(ctx->suffix); ctx->rw_ops = talloc_zero(ctx, struct idmap_rw_ops); CHECK_ALLOC_DONE(ctx->rw_ops); ctx->rw_ops->get_new_id = idmap_ldap_allocate_id_internal; ctx->rw_ops->set_mapping = idmap_ldap_set_mapping; /* get_credentials deals with setting up creds */ ret = smbldap_init(ctx, winbind_event_context(), ctx->url, false, NULL, NULL, &ctx->smbldap_state); if (!NT_STATUS_IS_OK(ret)) { DEBUG(1, ("ERROR: smbldap_init (%s) failed!\n", ctx->url)); goto done; } ret = get_credentials( ctx, ctx->smbldap_state, config_option, dom, &ctx->user_dn ); if ( !NT_STATUS_IS_OK(ret) ) { DEBUG(1,("idmap_ldap_db_init: Failed to get connection " "credentials (%s)\n", nt_errstr(ret))); goto done; } /* * Set the destructor on the context, so that resources are * properly freed when the context is released. */ talloc_set_destructor(ctx, idmap_ldap_close_destructor); dom->private_data = ctx; ret = verify_idpool(dom); if (!NT_STATUS_IS_OK(ret)) { DEBUG(1, ("idmap_ldap_db_init: failed to verify ID pool (%s)\n", nt_errstr(ret))); goto done; } talloc_free(config_option); return NT_STATUS_OK; /*failed */ done: talloc_free(ctx); return ret; }
WERROR _dfs_Remove(struct pipes_struct *p, struct dfs_Remove *r) { struct junction_map *jn = NULL; bool self_ref = False; int consumedcnt = 0; bool found = False; TALLOC_CTX *ctx = talloc_tos(); char *altpath = NULL; NTSTATUS status; if (p->session_info->unix_token->uid != sec_initial_uid()) { DEBUG(10,("_dfs_remove: uid != 0. Access denied.\n")); return WERR_ACCESS_DENIED; } jn = talloc_zero(ctx, struct junction_map); if (!jn) { return WERR_NOT_ENOUGH_MEMORY; } if (r->in.servername && r->in.sharename) { altpath = talloc_asprintf(ctx, "%s\\%s", r->in.servername, r->in.sharename); if (!altpath) { return WERR_NOT_ENOUGH_MEMORY; } if (!strlower_m(altpath)) { return WERR_INVALID_PARAMETER; } DEBUG(5,("init_reply_dfs_remove: Request to remove %s -> %s\\%s.\n", r->in.dfs_entry_path, r->in.servername, r->in.sharename)); } status = get_referred_path(ctx, r->in.dfs_entry_path, true, /*allow_broken_path */ jn, &consumedcnt, &self_ref); if(!NT_STATUS_IS_OK(status)) { return WERR_NERR_DFSNOSUCHVOLUME; } /* if no server-share pair given, remove the msdfs link completely */ if(!r->in.servername && !r->in.sharename) { if(!remove_msdfs_link(jn)) { return WERR_NERR_DFSNOSUCHVOLUME; } } else { int i=0; /* compare each referral in the list with the one to remove */ DEBUG(10,("altpath: .%s. refcnt: %d\n", altpath, jn->referral_count)); for(i=0;i<jn->referral_count;i++) { char *refpath = talloc_strdup(ctx, jn->referral_list[i].alternate_path); if (!refpath) { return WERR_NOT_ENOUGH_MEMORY; } trim_char(refpath, '\\', '\\'); DEBUG(10,("_dfs_remove: refpath: .%s.\n", refpath)); if(strequal(refpath, altpath)) { *(jn->referral_list[i].alternate_path)='\0'; DEBUG(10,("_dfs_remove: Removal request matches referral %s\n", refpath)); found = True; } } if(!found) { return WERR_NERR_DFSNOSUCHSHARE; } /* Only one referral, remove it */ if(jn->referral_count == 1) { if(!remove_msdfs_link(jn)) { return WERR_NERR_DFSNOSUCHVOLUME; } } else { if(!create_msdfs_link(jn)) { return WERR_NERR_DFSCANTCREATEJUNCTIONPOINT; } } } return WERR_OK; }
BOOL vfs_init_custom(connection_struct *conn, const char *vfs_object) { vfs_op_tuple *ops; char *module_name = NULL; char *module_param = NULL, *p; int i; vfs_handle_struct *handle; struct vfs_init_function_entry *entry; if (!conn||!vfs_object||!vfs_object[0]) { DEBUG(0,("vfs_init_custon() called with NULL pointer or emtpy vfs_object!\n")); return False; } if(!backends) { static_init_vfs; } DEBUG(3, ("Initialising custom vfs hooks from [%s]\n", vfs_object)); module_name = smb_xstrdup(vfs_object); p = strchr_m(module_name, ':'); if (p) { *p = 0; module_param = p+1; trim_char(module_param, ' ', ' '); } trim_char(module_name, ' ', ' '); /* First, try to load the module with the new module system */ if((entry = vfs_find_backend_entry(module_name)) || (NT_STATUS_IS_OK(smb_probe_module("vfs", module_name)) && (entry = vfs_find_backend_entry(module_name)))) { DEBUGADD(5,("Successfully loaded vfs module [%s] with the new modules system\n", vfs_object)); if ((ops = entry->vfs_op_tuples) == NULL) { DEBUG(0, ("entry->vfs_op_tuples==NULL for [%s] failed\n", vfs_object)); SAFE_FREE(module_name); return False; } } else { DEBUG(0,("Can't find a vfs module [%s]\n",vfs_object)); SAFE_FREE(module_name); return False; } handle = TALLOC_ZERO_P(conn->mem_ctx,vfs_handle_struct); if (!handle) { DEBUG(0,("TALLOC_ZERO() failed!\n")); SAFE_FREE(module_name); return False; } memcpy(&handle->vfs_next, &conn->vfs, sizeof(struct vfs_ops)); handle->conn = conn; if (module_param) { handle->param = talloc_strdup(conn->mem_ctx, module_param); } DLIST_ADD(conn->vfs_handles, handle); for(i=0; ops[i].op != NULL; i++) { DEBUG(5, ("Checking operation #%d (type %d, layer %d)\n", i, ops[i].type, ops[i].layer)); if(ops[i].layer == SMB_VFS_LAYER_OPAQUE) { /* If this operation was already made opaque by different module, it * will be overridden here. */ DEBUGADD(5, ("Making operation type %d opaque [module %s]\n", ops[i].type, vfs_object)); vfs_set_operation(&conn->vfs_opaque, ops[i].type, handle, ops[i].op); } /* Change current VFS disposition*/ DEBUGADD(5, ("Accepting operation type %d from module %s\n", ops[i].type, vfs_object)); vfs_set_operation(&conn->vfs, ops[i].type, handle, ops[i].op); } SAFE_FREE(module_name); return True; }
static ssize_t vfs_my_module_pwrite(vfs_handle_struct *handle, files_struct *fsp, const void *data, size_t n, off_t offset) { connection_struct *conn = handle->conn; char *path_name = NULL; char *temp_name = NULL; char *final_name = NULL; const struct smb_filename *smb_fname = fsp->fsp_name; struct smb_filename *smb_fname_final = NULL; const char *base; char *repository,*repositoryTemp = NULL; int i = 1; SMB_OFF_T maxsize, minsize; SMB_OFF_T file_size; /* space_avail; */ bool exist; NTSTATUS status; ssize_t rc = -1; int count = 0; const char *share = "/mnt/share"; repository = talloc_sub_advanced(NULL, lp_servicename(SNUM(conn)), conn->session_info->unix_name, conn->connectpath, conn->session_info->utok.gid, conn->session_info->sanitized_username, conn->session_info->info3->base.domain.string, sharevolume(handle)); ALLOC_CHECK(repository, done); trim_char(repository, '\0', '/'); if(!repository || *(repository) == '\0') { rc = SMB_VFS_NEXT_PWRITE(handle, fsp,data,n,offset); goto done; } file_size = vfs_my_module_get_file_size(handle, smb_fname); maxsize = vfs_my_module_maxsize(handle); if(maxsize > 0 && file_size > maxsize){ repository = talloc_sub_advanced(NULL, lp_servicename(SNUM(conn)), conn->session_info->unix_name, conn->connectpath, conn->session_info->utok.gid, conn->session_info->sanitized_username, conn->session_info->info3->base.domain.string, stripevolume(handle)); ALLOC_CHECK(repository, done); trim_char(repository, '\0', '/'); if(!repository || *(repository) == '\0') { rc = SMB_VFS_NEXT_PWRITE(handle, fsp,data,n,offset); goto done; } } if (strncmp(smb_fname->base_name, repository, strlen(repository)) == 0) { rc = SMB_VFS_NEXT_PWRITE(handle, fsp,data,n,offset); goto done; } base = strrchr(smb_fname->base_name, '/'); if (base == NULL) { base = smb_fname->base_name; path_name = SMB_STRDUP("/"); ALLOC_CHECK(path_name, done); } else { path_name = SMB_STRDUP(smb_fname->base_name); ALLOC_CHECK(path_name, done); path_name[base - smb_fname->base_name] = '\0'; base++; } /* original filename with path */ DEBUG(10, ("file transaction: fname = %s\n", smb_fname_str_dbg(smb_fname))); /* original path */ DEBUG(10, ("file transaction: fpath = %s\n", path_name)); /* filename without path */ DEBUG(10, ("file transaction: base = %s\n", base)); if (vfs_my_module_keep_dir_tree(handle) == True) { if (asprintf(&temp_name, "%s/%s", repository, path_name) == -1) { ALLOC_CHECK(temp_name, done); } } else { temp_name = SMB_STRDUP(repository); } ALLOC_CHECK(temp_name, done); exist = vfs_my_module_directory_exist(handle, temp_name); if (exist) { DEBUG(10, ("file transaction: Directory already exists\n")); } else { DEBUG(10, ("file transaction: Creating directory %s\n", temp_name)); count = vfs_my_module_create_dir(handle, temp_name, smb_fname); } if (asprintf(&final_name, "%s/%s", temp_name, base) == -1) { ALLOC_CHECK(final_name, done); } /* Create smb_fname with final base name and orig stream name. */ status = create_synthetic_smb_fname(talloc_tos(), final_name, smb_fname->stream_name, NULL, &smb_fname_final); if (!NT_STATUS_IS_OK(status)) { rc = SMB_VFS_NEXT_PWRITE(handle, fsp,data,n,offset); goto done; } TALLOC_FREE(smb_fname_final->base_name); smb_fname_final->base_name = talloc_strdup(smb_fname_final, final_name); if (smb_fname_final->base_name == NULL) { rc = SMB_VFS_NEXT_PWRITE(handle, fsp,data,n,offset); goto done; } SMB_VFS_NEXT_RENAME(handle, smb_fname, smb_fname_final); rc = SMB_VFS_NEXT_PWRITE(handle, fsp,data,n,offset); if (rc != 0) { rc = SMB_VFS_NEXT_PWRITE(handle, fsp,data,n,offset); goto done; } done: vfs_my_module_delete_dir(handle,path_name,smb_fname); while(count !=0){ vfs_my_module_delete_dir(handle,path_name,smb_fname); SMB_VFS_NEXT_RMDIR(handle, path_name); count--; } SAFE_FREE(path_name); SAFE_FREE(temp_name); SAFE_FREE(final_name); TALLOC_FREE(smb_fname_final); TALLOC_FREE(repository); return rc; }
WERROR _dfs_Remove(pipes_struct *p, NETDFS_Q_DFS_REMOVE *q_u, NETDFS_R_DFS_REMOVE *r_u) { struct current_user user; struct junction_map jn; BOOL self_ref = False; int consumedcnt = 0; BOOL found = False; pstring dfspath, servername, sharename; pstring altpath; get_current_user(&user,p); if (user.ut.uid != 0) { DEBUG(10,("_dfs_remove: uid != 0. Access denied.\n")); return WERR_ACCESS_DENIED; } unistr2_to_ascii(dfspath, &q_u->path, sizeof(dfspath)-1); if(q_u->ptr0_server) { unistr2_to_ascii(servername, &q_u->server, sizeof(servername)-1); } if(q_u->ptr0_share) { unistr2_to_ascii(sharename, &q_u->share, sizeof(sharename)-1); } if(q_u->ptr0_server && q_u->ptr0_share) { pstrcpy(altpath, servername); pstrcat(altpath, "\\"); pstrcat(altpath, sharename); strlower_m(altpath); } DEBUG(5,("init_reply_dfs_remove: Request to remove %s -> %s\\%s.\n", dfspath, servername, sharename)); if(!NT_STATUS_IS_OK(get_referred_path(p->mem_ctx, dfspath, &jn, &consumedcnt, &self_ref))) { return WERR_DFS_NO_SUCH_VOL; } /* if no server-share pair given, remove the msdfs link completely */ if(!q_u->ptr0_server && !q_u->ptr0_share) { if(!remove_msdfs_link(&jn)) { vfs_ChDir(p->conn,p->conn->connectpath); return WERR_DFS_NO_SUCH_VOL; } vfs_ChDir(p->conn,p->conn->connectpath); } else { int i=0; /* compare each referral in the list with the one to remove */ DEBUG(10,("altpath: .%s. refcnt: %d\n", altpath, jn.referral_count)); for(i=0;i<jn.referral_count;i++) { pstring refpath; pstrcpy(refpath,jn.referral_list[i].alternate_path); trim_char(refpath, '\\', '\\'); DEBUG(10,("_dfs_remove: refpath: .%s.\n", refpath)); if(strequal(refpath, altpath)) { *(jn.referral_list[i].alternate_path)='\0'; DEBUG(10,("_dfs_remove: Removal request matches referral %s\n", refpath)); found = True; } } if(!found) { return WERR_DFS_NO_SUCH_SHARE; } /* Only one referral, remove it */ if(jn.referral_count == 1) { if(!remove_msdfs_link(&jn)) { vfs_ChDir(p->conn,p->conn->connectpath); return WERR_DFS_NO_SUCH_VOL; } } else { if(!create_msdfs_link(&jn, True)) { vfs_ChDir(p->conn,p->conn->connectpath); return WERR_DFS_CANT_CREATE_JUNCT; } } vfs_ChDir(p->conn,p->conn->connectpath); } return WERR_OK; }
/** * Check if file should be recycled **/ static int recycle_unlink(vfs_handle_struct *handle, connection_struct *conn, const char *file_name) { char *path_name = NULL; char *temp_name = NULL; char *final_name = NULL; const char *base; char *repository = NULL; int i = 1; int maxsize; SMB_OFF_T file_size; /* space_avail; */ BOOL exist; int rc = -1; repository = alloc_sub_conn(conn, recycle_repository(handle)); ALLOC_CHECK(repository, done); /* shouldn't we allow absolute path names here? --metze */ trim_char(repository, '/', '/'); if(!repository || *(repository) == '\0') { DEBUG(3, ("recycle: repository path not set, purging %s...\n", file_name)); rc = SMB_VFS_NEXT_UNLINK(handle, conn, file_name); goto done; } /* we don't recycle the recycle bin... */ if (strncmp(file_name, repository, strlen(repository)) == 0) { DEBUG(3, ("recycle: File is within recycling bin, unlinking ...\n")); rc = SMB_VFS_NEXT_UNLINK(handle, conn, file_name); goto done; } file_size = recycle_get_file_size(handle, file_name); /* it is wrong to purge filenames only because they are empty imho * --- simo * if(fsize == 0) { DEBUG(3, ("recycle: File %s is empty, purging...\n", file_name)); rc = SMB_VFS_NEXT_UNLINK(handle,conn,file_name); goto done; } */ /* FIXME: this is wrong, we should check the hole size of the recycle bin is * not greater then maxsize, not the size of the single file, also it is better * to remove older files */ maxsize = recycle_maxsize(handle); if(maxsize > 0 && file_size > maxsize) { DEBUG(3, ("recycle: File %s exceeds maximum recycle size, purging... \n", file_name)); rc = SMB_VFS_NEXT_UNLINK(handle, conn, file_name); goto done; } /* FIXME: this is wrong: moving files with rename does not change the disk space * allocation * space_avail = SMB_VFS_NEXT_DISK_FREE(handle, conn, ".", True, &bsize, &dfree, &dsize) * 1024L; DEBUG(5, ("space_avail = %Lu, file_size = %Lu\n", space_avail, file_size)); if(space_avail < file_size) { DEBUG(3, ("recycle: Not enough diskspace, purging file %s\n", file_name)); rc = SMB_VFS_NEXT_UNLINK(handle, conn, file_name); goto done; } */ /* extract filename and path */ base = strrchr(file_name, '/'); if (base == NULL) { base = file_name; path_name = SMB_STRDUP("/"); ALLOC_CHECK(path_name, done); } else { path_name = SMB_STRDUP(file_name); ALLOC_CHECK(path_name, done); path_name[base - file_name] = '\0'; base++; } DEBUG(10, ("recycle: fname = %s\n", file_name)); /* original filename with path */ DEBUG(10, ("recycle: fpath = %s\n", path_name)); /* original path */ DEBUG(10, ("recycle: base = %s\n", base)); /* filename without path */ if (matchparam(recycle_exclude(handle), base)) { DEBUG(3, ("recycle: file %s is excluded \n", base)); rc = SMB_VFS_NEXT_UNLINK(handle, conn, file_name); goto done; } /* FIXME: this check will fail if we have more than one level of directories, * we shoud check for every level 1, 1/2, 1/2/3, 1/2/3/4 .... * ---simo */ if (checkparam(recycle_exclude_dir(handle), path_name)) { DEBUG(3, ("recycle: directory %s is excluded \n", path_name)); rc = SMB_VFS_NEXT_UNLINK(handle, conn, file_name); goto done; } if (recycle_keep_dir_tree(handle) == True) { asprintf(&temp_name, "%s/%s", repository, path_name); } else { temp_name = SMB_STRDUP(repository); } ALLOC_CHECK(temp_name, done); exist = recycle_directory_exist(handle, temp_name); if (exist) { DEBUG(10, ("recycle: Directory already exists\n")); } else { DEBUG(10, ("recycle: Creating directory %s\n", temp_name)); if (recycle_create_dir(handle, temp_name) == False) { DEBUG(3, ("recycle: Could not create directory, purging %s...\n", file_name)); rc = SMB_VFS_NEXT_UNLINK(handle, conn, file_name); goto done; } } asprintf(&final_name, "%s/%s", temp_name, base); ALLOC_CHECK(final_name, done); DEBUG(10, ("recycle: recycled file name: %s\n", final_name)); /* new filename with path */ /* check if we should delete file from recycle bin */ if (recycle_file_exist(handle, final_name)) { if (recycle_versions(handle) == False || matchparam(recycle_noversions(handle), base) == True) { DEBUG(3, ("recycle: Removing old file %s from recycle bin\n", final_name)); if (SMB_VFS_NEXT_UNLINK(handle, conn, final_name) != 0) { DEBUG(1, ("recycle: Error deleting old file: %s\n", strerror(errno))); } } } /* rename file we move to recycle bin */ i = 1; while (recycle_file_exist(handle, final_name)) { SAFE_FREE(final_name); asprintf(&final_name, "%s/Copy #%d of %s", temp_name, i++, base); } DEBUG(10, ("recycle: Moving %s to %s\n", file_name, final_name)); rc = SMB_VFS_NEXT_RENAME(handle, conn, file_name, final_name); if (rc != 0) { DEBUG(3, ("recycle: Move error %d (%s), purging file %s (%s)\n", errno, strerror(errno), file_name, final_name)); rc = SMB_VFS_NEXT_UNLINK(handle, conn, file_name); goto done; } /* touch access date of moved file */ if (recycle_touch(handle) == True ) recycle_do_touch(handle, final_name); done: SAFE_FREE(path_name); SAFE_FREE(temp_name); SAFE_FREE(final_name); SAFE_FREE(repository); return rc; }
static void get_domain_master_name_node_status_success(struct subnet_record *subrec, struct userdata_struct *userdata, struct res_rec *answers, struct in_addr from_ip) { struct work_record *work; unstring server_name; server_name[0] = 0; if( DEBUGLVL( 3 ) ) { dbgtext( "get_domain_master_name_node_status_success:\n" ); dbgtext( "Success in node status from ip %s\n", inet_ntoa(from_ip) ); } /* * Go through the list of names found at answers->rdata and look for * the first WORKGROUP<0x1b> name. */ if(answers->rdata != NULL) { char *p = answers->rdata; int numnames = CVAL(p, 0); p += 1; while (numnames--) { unstring qname; uint16 nb_flags; int name_type; pull_ascii_nstring(qname, sizeof(qname), p); name_type = CVAL(p,15); nb_flags = get_nb_flags(&p[16]); trim_char(qname,'\0',' '); p += 18; if(!(nb_flags & NB_GROUP) && (name_type == 0x00) && server_name[0] == 0) { /* this is almost certainly the server netbios name */ unstrcpy(server_name, qname); continue; } if(!(nb_flags & NB_GROUP) && (name_type == 0x1b)) { if( DEBUGLVL( 5 ) ) { dbgtext( "get_domain_master_name_node_status_success:\n" ); dbgtext( "%s(%s) ", server_name, inet_ntoa(from_ip) ); dbgtext( "is a domain master browser for workgroup " ); dbgtext( "%s. Adding this name.\n", qname ); } /* * If we don't already know about this workgroup, add it * to the workgroup list on the unicast_subnet. */ if((work = find_workgroup_on_subnet( subrec, qname)) == NULL) { struct nmb_name nmbname; /* * Add it - with an hour in the cache. */ if(!(work= create_workgroup_on_subnet(subrec, qname, 60*60))) return; /* remember who the master is */ unstrcpy(work->local_master_browser_name, server_name); make_nmb_name(&nmbname, server_name, 0x20); work->dmb_name = nmbname; work->dmb_addr = from_ip; } break; } } } else if( DEBUGLVL( 0 ) ) { dbgtext( "get_domain_master_name_node_status_success:\n" ); dbgtext( "Failed to find a WORKGROUP<0x1b> name in reply from IP " ); dbgtext( "%s.\n", inet_ntoa(from_ip) ); } }
static void domain_master_node_status_success(struct subnet_record *subrec, struct userdata_struct *userdata, struct res_rec *answers, struct in_addr from_ip) { struct work_record *work = find_workgroup_on_subnet( subrec, userdata->data); if( work == NULL ) { if( DEBUGLVL( 0 ) ) { dbgtext( "domain_master_node_status_success:\n" ); dbgtext( "Unable to find workgroup " ); dbgtext( "%s on subnet %s.\n", userdata->data, subrec->subnet_name ); } return; } if( DEBUGLVL( 3 ) ) { dbgtext( "domain_master_node_status_success:\n" ); dbgtext( "Success in node status for workgroup " ); dbgtext( "%s from ip %s\n", work->work_group, inet_ntoa(from_ip) ); } /* Go through the list of names found at answers->rdata and look for the first SERVER<0x20> name. */ if(answers->rdata != NULL) { char *p = answers->rdata; int numnames = CVAL(p, 0); p += 1; while (numnames--) { unstring qname; uint16 nb_flags; int name_type; pull_ascii_nstring(qname, sizeof(qname), p); name_type = CVAL(p,15); nb_flags = get_nb_flags(&p[16]); trim_char(qname,'\0',' '); p += 18; if(!(nb_flags & NB_GROUP) && (name_type == 0x20)) { struct nmb_name nmbname; make_nmb_name(&nmbname, qname, name_type); /* Copy the dmb name and IP address into the workgroup struct. */ work->dmb_name = nmbname; putip((char *)&work->dmb_addr, &from_ip); /* Do the local master browser announcement to the domain master browser name and IP. */ announce_local_master_browser_to_domain_master_browser( work ); /* Now synchronise lists with the domain master browser. */ sync_with_dmb(work); break; } } } else if( DEBUGLVL( 0 ) ) { dbgtext( "domain_master_node_status_success:\n" ); dbgtext( "Failed to find a SERVER<0x20> name in reply from IP " ); dbgtext( "%s.\n", inet_ntoa(from_ip) ); } }
/**************************************************************************** initialise smb perf counters ****************************************************************************/ static bool smb_load_perfcount_module(const char *name) { char *module_path = NULL; char *module_name = NULL; char *module_param = NULL, *p; const struct smb_perfcount_module *entry; DEBUG(3, ("Initialising perfcounter module [%s]\n", name)); if (g_smb_perfcount_handlers) { DEBUG(3,("Only 1 perfcount handler may be registered in " "smb.conf\n")); return true; } module_path = smb_xstrdup(name); p = strchr_m(module_path, ':'); if (p) { *p = 0; module_param = p+1; trim_char(module_param, ' ', ' '); } trim_char(module_path, ' ', ' '); module_name = smb_xstrdup(module_path); if (module_name[0] == '/') { /* * Extract the module name from the path. Just use the base * name of the last path component. */ SAFE_FREE(module_name); module_name = smb_xstrdup(strrchr_m(module_path, '/')+1); p = strchr_m(module_name, '.'); if (p != NULL) { *p = '\0'; } } /* load the perfcounter module */ if((entry = smb_perfcount_find_module(module_name)) || (NT_STATUS_IS_OK(smb_probe_module_absolute_path(module_path)) && (entry = smb_perfcount_find_module(module_name)))) { DEBUG(3,("Successfully loaded perfcounter module [%s] \n", name)); } else { DEBUG(0,("Can't find a perfcounter module [%s]\n",name)); goto fail; } g_smb_perfcount_handlers = entry->handlers; SAFE_FREE(module_path); SAFE_FREE(module_name); return True; fail: SAFE_FREE(module_path); SAFE_FREE(module_name); return False; }
static int expect(int master, char *issue, char *expected) { char buffer[1024]; int attempts, timeout, nread; size_t len; bool match = False; for (attempts = 0; attempts < 2; attempts++) { NTSTATUS status; if (!strequal(issue, ".")) { if (lp_passwd_chat_debug()) DEBUG(100, ("expect: sending [%s]\n", issue)); if ((len = sys_write(master, issue, strlen(issue))) != strlen(issue)) { DEBUG(2,("expect: (short) write returned %d\n", (int)len )); return False; } } if (strequal(expected, ".")) return True; /* Initial timeout. */ timeout = lp_passwd_chat_timeout() * 1000; nread = 0; buffer[nread] = 0; while (True) { status = read_fd_with_timeout( master, buffer + nread, 1, sizeof(buffer) - nread - 1, timeout, &len); if (!NT_STATUS_IS_OK(status)) { DEBUG(2, ("expect: read error %s\n", nt_errstr(status))); break; } nread += len; buffer[nread] = 0; { /* Eat leading/trailing whitespace before match. */ char *str = SMB_STRDUP(buffer); if (!str) { DEBUG(2,("expect: ENOMEM\n")); return False; } trim_char(str, ' ', ' '); if ((match = unix_wild_match(expected, str)) == True) { /* Now data has started to return, lower timeout. */ timeout = lp_passwd_chat_timeout() * 100; } SAFE_FREE(str); } } if (lp_passwd_chat_debug()) DEBUG(100, ("expect: expected [%s] received [%s] match %s\n", expected, buffer, match ? "yes" : "no" )); if (match) break; if (!NT_STATUS_IS_OK(status)) { DEBUG(2, ("expect: %s\n", nt_errstr(status))); return False; } } DEBUG(10,("expect: returning %s\n", match ? "True" : "False" )); return match; }
/** * Check if file should be recycled **/ static int recycle_unlink(vfs_handle_struct *handle, const struct smb_filename *smb_fname) { connection_struct *conn = handle->conn; char *path_name = NULL; char *temp_name = NULL; char *final_name = NULL; struct smb_filename *smb_fname_final = NULL; const char *base; char *repository = NULL; int i = 1; SMB_OFF_T maxsize, minsize; SMB_OFF_T file_size; /* space_avail; */ bool exist; NTSTATUS status; int rc = -1; repository = talloc_sub_advanced(NULL, lp_servicename(SNUM(conn)), conn->session_info->unix_name, conn->connectpath, conn->session_info->utok.gid, conn->session_info->sanitized_username, conn->session_info->info3->base.domain.string, recycle_repository(handle)); ALLOC_CHECK(repository, done); /* shouldn't we allow absolute path names here? --metze */ /* Yes :-). JRA. */ trim_char(repository, '\0', '/'); if(!repository || *(repository) == '\0') { DEBUG(3, ("recycle: repository path not set, purging %s...\n", smb_fname_str_dbg(smb_fname))); rc = SMB_VFS_NEXT_UNLINK(handle, smb_fname); goto done; } /* we don't recycle the recycle bin... */ if (strncmp(smb_fname->base_name, repository, strlen(repository)) == 0) { DEBUG(3, ("recycle: File is within recycling bin, unlinking ...\n")); rc = SMB_VFS_NEXT_UNLINK(handle, smb_fname); goto done; } file_size = recycle_get_file_size(handle, smb_fname); /* it is wrong to purge filenames only because they are empty imho * --- simo * if(fsize == 0) { DEBUG(3, ("recycle: File %s is empty, purging...\n", file_name)); rc = SMB_VFS_NEXT_UNLINK(handle,file_name); goto done; } */ /* FIXME: this is wrong, we should check the whole size of the recycle bin is * not greater then maxsize, not the size of the single file, also it is better * to remove older files */ maxsize = recycle_maxsize(handle); if(maxsize > 0 && file_size > maxsize) { DEBUG(3, ("recycle: File %s exceeds maximum recycle size, " "purging... \n", smb_fname_str_dbg(smb_fname))); rc = SMB_VFS_NEXT_UNLINK(handle, smb_fname); goto done; } minsize = recycle_minsize(handle); if(minsize > 0 && file_size < minsize) { DEBUG(3, ("recycle: File %s lowers minimum recycle size, " "purging... \n", smb_fname_str_dbg(smb_fname))); rc = SMB_VFS_NEXT_UNLINK(handle, smb_fname); goto done; } /* FIXME: this is wrong: moving files with rename does not change the disk space * allocation * space_avail = SMB_VFS_NEXT_DISK_FREE(handle, ".", True, &bsize, &dfree, &dsize) * 1024L; DEBUG(5, ("space_avail = %Lu, file_size = %Lu\n", space_avail, file_size)); if(space_avail < file_size) { DEBUG(3, ("recycle: Not enough diskspace, purging file %s\n", file_name)); rc = SMB_VFS_NEXT_UNLINK(handle, file_name); goto done; } */ /* extract filename and path */ base = strrchr(smb_fname->base_name, '/'); if (base == NULL) { base = smb_fname->base_name; path_name = SMB_STRDUP("/"); ALLOC_CHECK(path_name, done); } else { path_name = SMB_STRDUP(smb_fname->base_name); ALLOC_CHECK(path_name, done); path_name[base - smb_fname->base_name] = '\0'; base++; } /* original filename with path */ DEBUG(10, ("recycle: fname = %s\n", smb_fname_str_dbg(smb_fname))); /* original path */ DEBUG(10, ("recycle: fpath = %s\n", path_name)); /* filename without path */ DEBUG(10, ("recycle: base = %s\n", base)); if (matchparam(recycle_exclude(handle), base)) { DEBUG(3, ("recycle: file %s is excluded \n", base)); rc = SMB_VFS_NEXT_UNLINK(handle, smb_fname); goto done; } if (matchdirparam(recycle_exclude_dir(handle), path_name)) { DEBUG(3, ("recycle: directory %s is excluded \n", path_name)); rc = SMB_VFS_NEXT_UNLINK(handle, smb_fname); goto done; } if (recycle_keep_dir_tree(handle) == True) { if (asprintf(&temp_name, "%s/%s", repository, path_name) == -1) { ALLOC_CHECK(temp_name, done); } } else { temp_name = SMB_STRDUP(repository); } ALLOC_CHECK(temp_name, done); exist = recycle_directory_exist(handle, temp_name); if (exist) { DEBUG(10, ("recycle: Directory already exists\n")); } else { DEBUG(10, ("recycle: Creating directory %s\n", temp_name)); if (recycle_create_dir(handle, temp_name) == False) { DEBUG(3, ("recycle: Could not create directory, " "purging %s...\n", smb_fname_str_dbg(smb_fname))); rc = SMB_VFS_NEXT_UNLINK(handle, smb_fname); goto done; } } if (asprintf(&final_name, "%s/%s", temp_name, base) == -1) { ALLOC_CHECK(final_name, done); } /* Create smb_fname with final base name and orig stream name. */ status = create_synthetic_smb_fname(talloc_tos(), final_name, smb_fname->stream_name, NULL, &smb_fname_final); if (!NT_STATUS_IS_OK(status)) { rc = SMB_VFS_NEXT_UNLINK(handle, smb_fname); goto done; } /* new filename with path */ DEBUG(10, ("recycle: recycled file name: %s\n", smb_fname_str_dbg(smb_fname_final))); /* check if we should delete file from recycle bin */ if (recycle_file_exist(handle, smb_fname_final)) { if (recycle_versions(handle) == False || matchparam(recycle_noversions(handle), base) == True) { DEBUG(3, ("recycle: Removing old file %s from recycle " "bin\n", smb_fname_str_dbg(smb_fname_final))); if (SMB_VFS_NEXT_UNLINK(handle, smb_fname_final) != 0) { DEBUG(1, ("recycle: Error deleting old file: %s\n", strerror(errno))); } } } /* rename file we move to recycle bin */ i = 1; while (recycle_file_exist(handle, smb_fname_final)) { SAFE_FREE(final_name); if (asprintf(&final_name, "%s/Copy #%d of %s", temp_name, i++, base) == -1) { ALLOC_CHECK(final_name, done); } TALLOC_FREE(smb_fname_final->base_name); smb_fname_final->base_name = talloc_strdup(smb_fname_final, final_name); if (smb_fname_final->base_name == NULL) { rc = SMB_VFS_NEXT_UNLINK(handle, smb_fname); goto done; } } DEBUG(10, ("recycle: Moving %s to %s\n", smb_fname_str_dbg(smb_fname), smb_fname_str_dbg(smb_fname_final))); rc = SMB_VFS_NEXT_RENAME(handle, smb_fname, smb_fname_final); if (rc != 0) { DEBUG(3, ("recycle: Move error %d (%s), purging file %s " "(%s)\n", errno, strerror(errno), smb_fname_str_dbg(smb_fname), smb_fname_str_dbg(smb_fname_final))); rc = SMB_VFS_NEXT_UNLINK(handle, smb_fname); goto done; } /* touch access date of moved file */ if (recycle_touch(handle) == True || recycle_touch_mtime(handle)) recycle_do_touch(handle, smb_fname_final, recycle_touch_mtime(handle)); done: SAFE_FREE(path_name); SAFE_FREE(temp_name); SAFE_FREE(final_name); TALLOC_FREE(smb_fname_final); TALLOC_FREE(repository); return rc; }
static NTSTATUS parse_dfs_path(connection_struct *conn, const char *pathname, bool allow_wcards, bool allow_broken_path, struct dfs_path *pdp, /* MUST BE TALLOCED */ bool *ppath_contains_wcard) { char *pathname_local; char *p,*temp; char *servicename; char *eos_ptr; NTSTATUS status = NT_STATUS_OK; char sepchar; ZERO_STRUCTP(pdp); /* * This is the only talloc we should need to do * on the struct dfs_path. All the pointers inside * it should point to offsets within this string. */ pathname_local = talloc_strdup(pdp, pathname); if (!pathname_local) { return NT_STATUS_NO_MEMORY; } /* Get a pointer to the terminating '\0' */ eos_ptr = &pathname_local[strlen(pathname_local)]; p = temp = pathname_local; pdp->posix_path = (lp_posix_pathnames() && *pathname == '/'); sepchar = pdp->posix_path ? '/' : '\\'; if (allow_broken_path && (*pathname != sepchar)) { DEBUG(10,("parse_dfs_path: path %s doesn't start with %c\n", pathname, sepchar )); /* * Possibly client sent a local path by mistake. * Try and convert to a local path. */ pdp->hostname = eos_ptr; /* "" */ pdp->servicename = eos_ptr; /* "" */ /* We've got no info about separators. */ pdp->posix_path = lp_posix_pathnames(); p = temp; DEBUG(10,("parse_dfs_path: trying to convert %s to a " "local path\n", temp)); goto local_path; } /* * Safe to use on talloc'ed string as it only shrinks. * It also doesn't affect the eos_ptr. */ trim_char(temp,sepchar,sepchar); DEBUG(10,("parse_dfs_path: temp = |%s| after trimming %c's\n", temp, sepchar)); /* Now tokenize. */ /* Parse out hostname. */ p = strchr_m(temp,sepchar); if(p == NULL) { DEBUG(10,("parse_dfs_path: can't parse hostname from path %s\n", temp)); /* * Possibly client sent a local path by mistake. * Try and convert to a local path. */ pdp->hostname = eos_ptr; /* "" */ pdp->servicename = eos_ptr; /* "" */ p = temp; DEBUG(10,("parse_dfs_path: trying to convert %s " "to a local path\n", temp)); goto local_path; } *p = '\0'; pdp->hostname = temp; DEBUG(10,("parse_dfs_path: hostname: %s\n",pdp->hostname)); /* Parse out servicename. */ servicename = p+1; p = strchr_m(servicename,sepchar); if (p) { *p = '\0'; } /* Is this really our servicename ? */ if (conn && !( strequal(servicename, lp_servicename(talloc_tos(), SNUM(conn))) || (strequal(servicename, HOMES_NAME) && strequal(lp_servicename(talloc_tos(), SNUM(conn)), get_current_username()) )) ) { DEBUG(10,("parse_dfs_path: %s is not our servicename\n", servicename)); /* * Possibly client sent a local path by mistake. * Try and convert to a local path. */ pdp->hostname = eos_ptr; /* "" */ pdp->servicename = eos_ptr; /* "" */ /* Repair the path - replace the sepchar's we nulled out */ servicename--; *servicename = sepchar; if (p) { *p = sepchar; } p = temp; DEBUG(10,("parse_dfs_path: trying to convert %s " "to a local path\n", temp)); goto local_path; } pdp->servicename = servicename; DEBUG(10,("parse_dfs_path: servicename: %s\n",pdp->servicename)); if(p == NULL) { /* Client sent self referral \server\share. */ pdp->reqpath = eos_ptr; /* "" */ return NT_STATUS_OK; } p++; local_path: *ppath_contains_wcard = False; pdp->reqpath = p; /* Rest is reqpath. */ if (pdp->posix_path) { status = check_path_syntax_posix(pdp->reqpath); } else { if (allow_wcards) { status = check_path_syntax_wcard(pdp->reqpath, ppath_contains_wcard); } else { status = check_path_syntax(pdp->reqpath); } } if (!NT_STATUS_IS_OK(status)) { DEBUG(10,("parse_dfs_path: '%s' failed with %s\n", p, nt_errstr(status) )); return status; } DEBUG(10,("parse_dfs_path: rest of the path: %s\n",pdp->reqpath)); return NT_STATUS_OK; }
bool vfs_init_custom(connection_struct *conn, const char *vfs_object) { char *module_path = NULL; char *module_name = NULL; char *module_param = NULL, *p; vfs_handle_struct *handle; const struct vfs_init_function_entry *entry; if (!conn||!vfs_object||!vfs_object[0]) { DEBUG(0,("vfs_init_custon() called with NULL pointer or emtpy vfs_object!\n")); return False; } if(!backends) { static_init_vfs; } DEBUG(3, ("Initialising custom vfs hooks from [%s]\n", vfs_object)); module_path = smb_xstrdup(vfs_object); p = strchr_m(module_path, ':'); if (p) { *p = 0; module_param = p+1; trim_char(module_param, ' ', ' '); } trim_char(module_path, ' ', ' '); module_name = smb_xstrdup(module_path); if ((module_name[0] == '/') && (strcmp(module_path, DEFAULT_VFS_MODULE_NAME) != 0)) { /* * Extract the module name from the path. Just use the base * name of the last path component. */ SAFE_FREE(module_name); module_name = smb_xstrdup(strrchr_m(module_path, '/')+1); p = strchr_m(module_name, '.'); if (p != NULL) { *p = '\0'; } } /* First, try to load the module with the new module system */ entry = vfs_find_backend_entry(module_name); if (!entry) { NTSTATUS status; DEBUG(5, ("vfs module [%s] not loaded - trying to load...\n", vfs_object)); status = smb_probe_module("vfs", module_path); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("error probing vfs module '%s': %s\n", module_path, nt_errstr(status))); goto fail; } entry = vfs_find_backend_entry(module_name); if (!entry) { DEBUG(0,("Can't find a vfs module [%s]\n",vfs_object)); goto fail; } } DEBUGADD(5,("Successfully loaded vfs module [%s] with the new modules system\n", vfs_object)); handle = TALLOC_ZERO_P(conn, vfs_handle_struct); if (!handle) { DEBUG(0,("TALLOC_ZERO() failed!\n")); goto fail; } handle->conn = conn; handle->fns = entry->fns; if (module_param) { handle->param = talloc_strdup(conn, module_param); } DLIST_ADD(conn->vfs_handles, handle); SAFE_FREE(module_path); SAFE_FREE(module_name); return True; fail: SAFE_FREE(module_path); SAFE_FREE(module_name); return False; }