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_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_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; }