WERROR _dfs_GetInfo(pipes_struct *p, NETDFS_Q_DFS_GETINFO *q_u, NETDFS_R_DFS_GETINFO *r_u) { UNISTR2* uni_path = &q_u->path; uint32 level = q_u->level; int consumedcnt = sizeof(pstring); pstring path; BOOL ret = False; BOOL self_ref = False; struct junction_map jn; unistr2_to_ascii(path, uni_path, sizeof(path)-1); if(!create_junction(path, &jn)) return WERR_DFS_NO_SUCH_SERVER; /* The following call can change the cwd. */ if(!NT_STATUS_IS_OK(get_referred_path(p->mem_ctx, path, &jn, &consumedcnt, &self_ref)) || consumedcnt < strlen(path)) { vfs_ChDir(p->conn,p->conn->connectpath); return WERR_DFS_NO_SUCH_VOL; } vfs_ChDir(p->conn,p->conn->connectpath); r_u->info.switch_value = level; r_u->info.ptr0 = 1; r_u->status = WERR_OK; switch (level) { case 1: ret = init_reply_dfs_info_1(&jn, &r_u->info.u.info1); break; case 2: ret = init_reply_dfs_info_2(&jn, &r_u->info.u.info2); break; case 3: ret = init_reply_dfs_info_3(p->mem_ctx, &jn, &r_u->info.u.info3); break; case 100: ret = init_reply_dfs_info_100(&jn, &r_u->info.u.info100); break; default: r_u->info.ptr0 = 1; r_u->info.switch_value = 0; r_u->status = WERR_OK; ret = True; break; } if (!ret) r_u->status = WERR_INVALID_PARAM; return r_u->status; }
WERROR _dfs_get_info(pipes_struct *p, DFS_Q_DFS_GET_INFO *q_u, DFS_R_DFS_GET_INFO *r_u) { UNISTR2* uni_path = &q_u->uni_path; uint32 level = q_u->level; pstring path; struct junction_map jn; unistr2_to_dos(path, uni_path, sizeof(path)-1); if(!create_junction(path, &jn)) return WERR_DFS_NO_SUCH_SERVER; if(!get_referred_path(path, &jn, NULL, NULL)) return WERR_DFS_NO_SUCH_VOL; r_u->level = level; r_u->ptr_ctr = 1; r_u->status = init_reply_dfs_ctr(p->mem_ctx, level, &r_u->ctr, &jn, 1); return r_u->status; }
WERROR _dfs_Add(struct pipes_struct *p, struct dfs_Add *r) { struct junction_map *jn = NULL; struct referral *old_referral_list = NULL; bool self_ref = False; int consumedcnt = 0; char *altpath = NULL; NTSTATUS status; TALLOC_CTX *ctx = talloc_tos(); if (p->session_info->unix_token->uid != sec_initial_uid()) { DEBUG(10,("_dfs_add: uid != 0. Access denied.\n")); return WERR_ACCESS_DENIED; } jn = talloc_zero(ctx, struct junction_map); if (!jn) { return WERR_NOT_ENOUGH_MEMORY; } DEBUG(5,("init_reply_dfs_add: Request to add %s -> %s\\%s.\n", r->in.path, r->in.server, r->in.share)); altpath = talloc_asprintf(ctx, "%s\\%s", r->in.server, r->in.share); if (!altpath) { return WERR_NOT_ENOUGH_MEMORY; } /* The following call can change the cwd. */ status = get_referred_path(ctx, r->in.path, true, /*allow_broken_path */ jn, &consumedcnt, &self_ref); if(!NT_STATUS_IS_OK(status)) { return ntstatus_to_werror(status); } jn->referral_count += 1; old_referral_list = jn->referral_list; if (jn->referral_count < 1) { return WERR_NOT_ENOUGH_MEMORY; } jn->referral_list = talloc_array(ctx, struct referral, jn->referral_count); if(jn->referral_list == NULL) { DEBUG(0,("init_reply_dfs_add: talloc failed for referral list!\n")); return WERR_NERR_DFSINTERNALERROR; } if(old_referral_list && jn->referral_list) { memcpy(jn->referral_list, old_referral_list, sizeof(struct referral)*jn->referral_count-1); } jn->referral_list[jn->referral_count-1].proximity = 0; jn->referral_list[jn->referral_count-1].ttl = REFERRAL_TTL; jn->referral_list[jn->referral_count-1].alternate_path = altpath; if(!create_msdfs_link(jn)) { return WERR_NERR_DFSCANTCREATEJUNCTIONPOINT; } return WERR_OK; }
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; }
WERROR _dfs_Add(pipes_struct *p, NETDFS_Q_DFS_ADD* q_u, NETDFS_R_DFS_ADD *r_u) { struct current_user user; struct junction_map jn; struct referral* old_referral_list = NULL; BOOL self_ref = False; int consumedcnt = 0; BOOL exists = False; pstring dfspath, servername, sharename; pstring altpath; get_current_user(&user,p); if (user.ut.uid != 0) { DEBUG(10,("_dfs_add: uid != 0. Access denied.\n")); return WERR_ACCESS_DENIED; } unistr2_to_ascii(dfspath, &q_u->path, sizeof(dfspath)-1); unistr2_to_ascii(servername, &q_u->server, sizeof(servername)-1); unistr2_to_ascii(sharename, &q_u->share, sizeof(sharename)-1); DEBUG(5,("init_reply_dfs_add: Request to add %s -> %s\\%s.\n", dfspath, servername, sharename)); pstrcpy(altpath, servername); pstrcat(altpath, "\\"); pstrcat(altpath, sharename); /* The following call can change the cwd. */ if(NT_STATUS_IS_OK(get_referred_path(p->mem_ctx, dfspath, &jn, &consumedcnt, &self_ref))) { exists = True; jn.referral_count += 1; old_referral_list = jn.referral_list; } else { jn.referral_count = 1; } vfs_ChDir(p->conn,p->conn->connectpath); jn.referral_list = TALLOC_ARRAY(p->mem_ctx, struct referral, jn.referral_count); if(jn.referral_list == NULL) { DEBUG(0,("init_reply_dfs_add: talloc failed for referral list!\n")); return WERR_DFS_INTERNAL_ERROR; } if(old_referral_list) { memcpy(jn.referral_list, old_referral_list, sizeof(struct referral)*jn.referral_count-1); } jn.referral_list[jn.referral_count-1].proximity = 0; jn.referral_list[jn.referral_count-1].ttl = REFERRAL_TTL; pstrcpy(jn.referral_list[jn.referral_count-1].alternate_path, altpath); if(!create_msdfs_link(&jn, exists)) { vfs_ChDir(p->conn,p->conn->connectpath); return WERR_DFS_CANT_CREATE_JUNCT; } vfs_ChDir(p->conn,p->conn->connectpath); return WERR_OK; }
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; }
WERROR _dfs_add(pipes_struct *p, DFS_Q_DFS_ADD* q_u, DFS_R_DFS_ADD *r_u) { struct current_user user; struct junction_map jn; struct referral* old_referral_list = NULL; BOOL exists = False; pstring dfspath, servername, sharename; pstring altpath; get_current_user(&user,p); if (user.uid != 0) { DEBUG(10,("_dfs_add: uid != 0. Access denied.\n")); return WERR_ACCESS_DENIED; } unistr2_to_dos(dfspath, &q_u->DfsEntryPath, sizeof(dfspath)-1); unistr2_to_dos(servername, &q_u->ServerName, sizeof(servername)-1); unistr2_to_dos(sharename, &q_u->ShareName, sizeof(sharename)-1); DEBUG(5,("init_reply_dfs_add: Request to add %s -> %s\\%s.\n", dfspath, servername, sharename)); pstrcpy(altpath, servername); pstrcat(altpath, "\\"); pstrcat(altpath, sharename); if(get_referred_path(dfspath, &jn, NULL, NULL)) { exists = True; jn.referral_count += 1; old_referral_list = jn.referral_list; } else jn.referral_count = 1; jn.referral_list = (struct referral*) talloc(p->mem_ctx, jn.referral_count * sizeof(struct referral)); if(jn.referral_list == NULL) { DEBUG(0,("init_reply_dfs_add: talloc failed for referral list!\n")); return WERR_DFS_INTERNAL_ERROR; } if(old_referral_list) { memcpy(jn.referral_list, old_referral_list, sizeof(struct referral)*jn.referral_count-1); SAFE_FREE(old_referral_list); } jn.referral_list[jn.referral_count-1].proximity = 0; jn.referral_list[jn.referral_count-1].ttl = REFERRAL_TTL; pstrcpy(jn.referral_list[jn.referral_count-1].alternate_path, altpath); if(!create_msdfs_link(&jn, exists)) return WERR_DFS_CANT_CREATE_JUNCT; return WERR_OK; }
WERROR _dfs_remove(pipes_struct *p, DFS_Q_DFS_REMOVE *q_u, DFS_R_DFS_REMOVE *r_u) { struct current_user user; struct junction_map jn; BOOL found = False; pstring dfspath, servername, sharename; pstring altpath; get_current_user(&user,p); if (user.uid != 0) { DEBUG(10,("_dfs_remove: uid != 0. Access denied.\n")); return WERR_ACCESS_DENIED; } unistr2_to_dos(dfspath, &q_u->DfsEntryPath, sizeof(dfspath)-1); if(q_u->ptr_ServerName) unistr2_to_dos(servername, &q_u->ServerName, sizeof(servername)-1); if(q_u->ptr_ShareName) unistr2_to_dos(sharename, &q_u->ShareName, sizeof(sharename)-1); if(q_u->ptr_ServerName && q_u->ptr_ShareName) { pstrcpy(altpath, servername); pstrcat(altpath, "\\"); pstrcat(altpath, sharename); strlower(altpath); } DEBUG(5,("init_reply_dfs_remove: Request to remove %s -> %s\\%s.\n", dfspath, servername, sharename)); if(!get_referred_path(dfspath, &jn, NULL, NULL)) return WERR_DFS_NO_SUCH_VOL; /* if no server-share pair given, remove the msdfs link completely */ if(!q_u->ptr_ServerName && !q_u->ptr_ShareName) { if(!remove_msdfs_link(&jn)) return WERR_DFS_NO_SUCH_VOL; } 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_string(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)) return WERR_DFS_NO_SUCH_VOL; } else { if(!create_msdfs_link(&jn, True)) return WERR_DFS_CANT_CREATE_JUNCT; } } return WERR_OK; }